steep 1.2.0 → 1.3.0.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -2
- data/Gemfile.lock +14 -4
- data/Gemfile.steep +2 -2
- data/Gemfile.steep.lock +17 -5
- data/Steepfile +7 -9
- data/lib/steep/annotation_parser.rb +34 -28
- data/lib/steep/ast/annotation.rb +16 -5
- data/lib/steep/ast/node/type_application.rb +74 -0
- data/lib/steep/ast/node/type_assertion.rb +56 -0
- data/lib/steep/ast/types/factory.rb +5 -1
- data/lib/steep/diagnostic/helper.rb +2 -1
- data/lib/steep/diagnostic/lsp_formatter.rb +3 -1
- data/lib/steep/diagnostic/ruby.rb +70 -5
- data/lib/steep/diagnostic/signature.rb +21 -8
- data/lib/steep/drivers/check.rb +1 -1
- data/lib/steep/drivers/checkfile.rb +1 -1
- data/lib/steep/drivers/langserver.rb +2 -2
- data/lib/steep/drivers/stats.rb +1 -1
- data/lib/steep/drivers/watch.rb +1 -1
- data/lib/steep/drivers/worker.rb +0 -1
- data/lib/steep/server/lsp_formatter.rb +13 -3
- data/lib/steep/server/master.rb +4 -1
- data/lib/steep/server/worker_process.rb +86 -14
- data/lib/steep/services/hover_provider/rbs.rb +7 -7
- data/lib/steep/services/hover_provider/ruby.rb +19 -4
- data/lib/steep/services/signature_service.rb +7 -4
- data/lib/steep/signature/validator.rb +36 -13
- data/lib/steep/source.rb +189 -71
- data/lib/steep/type_construction.rb +232 -126
- data/lib/steep/type_inference/logic_type_interpreter.rb +31 -5
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +2 -0
- data/rbs_collection.steep.lock.yaml +52 -11
- data/rbs_collection.steep.yaml +1 -1
- data/sig/shims/exception.rbs +4 -0
- data/sig/shims/parser/comment.rbs +33 -0
- data/sig/shims/parser.rbs +30 -2
- data/sig/steep/annotation_parser.rbs +59 -0
- data/sig/steep/ast/annotation.rbs +21 -26
- data/sig/steep/ast/node/type_application.rbs +31 -0
- data/sig/steep/ast/node/type_assertion.rbs +26 -0
- data/sig/steep/ast/types/factory.rbs +0 -2
- data/sig/steep/diagnostic/helper.rbs +9 -3
- data/sig/steep/diagnostic/lsp_formatter.rbs +12 -8
- data/sig/steep/diagnostic/ruby.rbs +62 -8
- data/sig/steep/diagnostic/signature.rbs +118 -85
- data/sig/steep/drivers/worker.rbs +11 -13
- data/sig/steep/range_extension.rbs +7 -0
- data/sig/steep/server/lsp_formatter.rbs +14 -7
- data/sig/steep/server/worker_process.rbs +74 -12
- data/sig/steep/services/hover_provider/rbs.rbs +27 -7
- data/sig/steep/services/hover_provider/ruby.rbs +18 -4
- data/sig/steep/services/hover_provider/singleton_methods.rbs +1 -1
- data/sig/steep/signature/validator.rbs +76 -0
- data/sig/steep/source.rbs +54 -30
- data/sig/steep/type_construction.rbs +85 -27
- data/sig/steep/type_inference/method_call.rbs +1 -1
- data/smoke/diagnostics-rbs/inherit-module.rbs +2 -0
- data/smoke/diagnostics-rbs/test_expectations.yml +12 -0
- data/steep.gemspec +6 -1
- metadata +86 -6
@@ -773,6 +773,65 @@ module Steep
|
|
773
773
|
end
|
774
774
|
end
|
775
775
|
|
776
|
+
class FalseAssertion < Base
|
777
|
+
attr_reader :node, :assertion_type, :node_type
|
778
|
+
|
779
|
+
def initialize(node:, assertion_type:, node_type:)
|
780
|
+
super(node: node)
|
781
|
+
@assertion_type = assertion_type
|
782
|
+
@node_type = node_type
|
783
|
+
end
|
784
|
+
|
785
|
+
def header_line
|
786
|
+
"Assertion cannot hold: no relationship between infered type (`#{node_type.to_s}`) and asserted type (`#{assertion_type.to_s}`)"
|
787
|
+
end
|
788
|
+
end
|
789
|
+
|
790
|
+
class UnexpectedTypeArgument < Base
|
791
|
+
attr_reader :type_arg, :method_type
|
792
|
+
|
793
|
+
def initialize(type_arg:, method_type:)
|
794
|
+
super(node: nil, location: type_arg.location)
|
795
|
+
@type_arg = type_arg
|
796
|
+
@method_type = method_type
|
797
|
+
end
|
798
|
+
|
799
|
+
def header_line
|
800
|
+
"Unexpected type arg is given to method type `#{method_type.to_s}`"
|
801
|
+
end
|
802
|
+
end
|
803
|
+
|
804
|
+
class InsufficientTypeArgument < Base
|
805
|
+
attr_reader :type_args, :method_type
|
806
|
+
|
807
|
+
def initialize(node:, type_args:, method_type:)
|
808
|
+
super(node: node)
|
809
|
+
@type_args = type_args
|
810
|
+
@method_type = method_type
|
811
|
+
end
|
812
|
+
|
813
|
+
def header_line
|
814
|
+
"Requires #{method_type.type_params.size} types, but #{type_args.size} given: `#{method_type.to_s}`"
|
815
|
+
end
|
816
|
+
end
|
817
|
+
|
818
|
+
class TypeArgumentMismatchError < Base
|
819
|
+
attr_reader :type_argument, :type_parameter, :result
|
820
|
+
|
821
|
+
def initialize(type_arg:, type_param:, result:)
|
822
|
+
super(node: nil, location: type_arg.location)
|
823
|
+
@type_argument = type_arg
|
824
|
+
@type_parameter = type_param
|
825
|
+
@result = result
|
826
|
+
end
|
827
|
+
|
828
|
+
include ResultPrinter
|
829
|
+
|
830
|
+
def header_line
|
831
|
+
"Cannot pass a type `#{type_argument}` as a type parameter `#{type_parameter.to_s}`"
|
832
|
+
end
|
833
|
+
end
|
834
|
+
|
776
835
|
ALL = ObjectSpace.each_object(Class).with_object([]) do |klass, array|
|
777
836
|
if klass < Base
|
778
837
|
array << klass
|
@@ -781,24 +840,29 @@ module Steep
|
|
781
840
|
|
782
841
|
def self.all_error
|
783
842
|
@all_error ||= ALL.each.with_object({}) do |klass, hash|
|
843
|
+
# @type var hash: Hash[singleton(Base), LSPFormatter::severity]
|
784
844
|
hash[klass] = LSPFormatter::ERROR
|
785
845
|
end.freeze
|
786
846
|
end
|
787
847
|
|
788
848
|
def self.default
|
789
|
-
@default ||= all_error.merge(
|
849
|
+
@default ||= _ = all_error.merge(
|
790
850
|
{
|
791
851
|
ImplicitBreakValueMismatch => :warning,
|
792
852
|
FallbackAny => :information,
|
793
853
|
ElseOnExhaustiveCase => :warning,
|
794
854
|
UnknownConstant => :warning,
|
795
|
-
MethodDefinitionMissing => :information
|
855
|
+
MethodDefinitionMissing => :information,
|
856
|
+
FalseAssertion => :information,
|
857
|
+
UnexpectedTypeArgument => :information,
|
858
|
+
InsufficientTypeArgument => :information,
|
859
|
+
UnexpectedTypeArgument => :information
|
796
860
|
}
|
797
861
|
).freeze
|
798
862
|
end
|
799
863
|
|
800
864
|
def self.strict
|
801
|
-
@strict ||= all_error.merge(
|
865
|
+
@strict ||= _ = all_error.merge(
|
802
866
|
{
|
803
867
|
NoMethod => nil,
|
804
868
|
ImplicitBreakValueMismatch => nil,
|
@@ -811,7 +875,7 @@ module Steep
|
|
811
875
|
end
|
812
876
|
|
813
877
|
def self.lenient
|
814
|
-
@lenient ||= all_error.merge(
|
878
|
+
@lenient ||= _ = all_error.merge(
|
815
879
|
{
|
816
880
|
NoMethod => nil,
|
817
881
|
ImplicitBreakValueMismatch => nil,
|
@@ -819,7 +883,8 @@ module Steep
|
|
819
883
|
ElseOnExhaustiveCase => nil,
|
820
884
|
UnknownConstant => nil,
|
821
885
|
MethodDefinitionMissing => nil,
|
822
|
-
UnexpectedJump => nil
|
886
|
+
UnexpectedJump => nil,
|
887
|
+
FalseAssertion => :hint
|
823
888
|
}
|
824
889
|
).freeze
|
825
890
|
end
|
@@ -11,9 +11,7 @@ module Steep
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def header_line
|
14
|
-
|
15
|
-
puts io
|
16
|
-
end.string
|
14
|
+
raise
|
17
15
|
end
|
18
16
|
|
19
17
|
def detail_lines
|
@@ -25,7 +23,9 @@ module Steep
|
|
25
23
|
end
|
26
24
|
|
27
25
|
def path
|
28
|
-
location
|
26
|
+
if location
|
27
|
+
Pathname(location.buffer.name)
|
28
|
+
end
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -166,7 +166,6 @@ module Steep
|
|
166
166
|
class RecursiveAlias < Base
|
167
167
|
attr_reader :class_name
|
168
168
|
attr_reader :names
|
169
|
-
attr_reader :location
|
170
169
|
|
171
170
|
def initialize(class_name:, names:, location:)
|
172
171
|
super(location: location)
|
@@ -284,7 +283,6 @@ module Steep
|
|
284
283
|
|
285
284
|
class InstanceVariableTypeError < Base
|
286
285
|
attr_reader :name
|
287
|
-
attr_reader :variable
|
288
286
|
attr_reader :var_type
|
289
287
|
attr_reader :parent_type
|
290
288
|
|
@@ -318,7 +316,7 @@ module Steep
|
|
318
316
|
private
|
319
317
|
|
320
318
|
def mixin_name
|
321
|
-
case member
|
319
|
+
case mem = member
|
322
320
|
when RBS::AST::Members::Prepend
|
323
321
|
"prepend"
|
324
322
|
when RBS::AST::Members::Include
|
@@ -329,6 +327,19 @@ module Steep
|
|
329
327
|
end
|
330
328
|
end
|
331
329
|
|
330
|
+
class InheritModuleError < Base
|
331
|
+
attr_reader :super_class
|
332
|
+
|
333
|
+
def initialize(super_class)
|
334
|
+
super(location: super_class.location)
|
335
|
+
@super_class = super_class
|
336
|
+
end
|
337
|
+
|
338
|
+
def header_line
|
339
|
+
"Cannot inherit from a module `#{super_class.name}`"
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
332
343
|
class UnexpectedError < Base
|
333
344
|
attr_reader :message
|
334
345
|
|
@@ -427,7 +438,7 @@ module Steep
|
|
427
438
|
Diagnostic::Signature::RecursiveAlias.new(
|
428
439
|
class_name: error.type.name,
|
429
440
|
names: error.defs.map(&:name),
|
430
|
-
location: error.defs[0].original
|
441
|
+
location: error.defs[0].original&.location
|
431
442
|
)
|
432
443
|
when RBS::RecursiveAncestorError
|
433
444
|
Diagnostic::Signature::RecursiveAncestor.new(
|
@@ -462,6 +473,8 @@ module Steep
|
|
462
473
|
nonregular_type: factory.type(error.diagnostic.nonregular_type),
|
463
474
|
location: error.location
|
464
475
|
)
|
476
|
+
when RBS::InheritModuleError
|
477
|
+
Diagnostic::Signature::InheritModuleError.new(error.super_decl)
|
465
478
|
else
|
466
479
|
raise error
|
467
480
|
end
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -36,7 +36,7 @@ module Steep
|
|
36
36
|
server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
|
37
37
|
server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
|
38
38
|
|
39
|
-
typecheck_workers = Server::WorkerProcess.
|
39
|
+
typecheck_workers = Server::WorkerProcess.start_typecheck_workers(
|
40
40
|
steepfile: project.steepfile_path,
|
41
41
|
args: command_line_patterns,
|
42
42
|
delay_shutdown: true,
|
@@ -101,7 +101,7 @@ module Steep
|
|
101
101
|
|
102
102
|
Steep.logger.info { "Starting #{count} workers for #{files.size} files..." }
|
103
103
|
|
104
|
-
typecheck_workers = Server::WorkerProcess.
|
104
|
+
typecheck_workers = Server::WorkerProcess.start_typecheck_workers(
|
105
105
|
steepfile: project.steepfile_path,
|
106
106
|
args: [],
|
107
107
|
delay_shutdown: true,
|
@@ -35,8 +35,8 @@ module Steep
|
|
35
35
|
def run
|
36
36
|
@project = load_config()
|
37
37
|
|
38
|
-
interaction_worker = Server::WorkerProcess.
|
39
|
-
typecheck_workers = Server::WorkerProcess.
|
38
|
+
interaction_worker = Server::WorkerProcess.start_worker(:interaction, name: "interaction", steepfile: project.steepfile_path, steep_command: jobs_option.steep_command_value)
|
39
|
+
typecheck_workers = Server::WorkerProcess.start_typecheck_workers(steepfile: project.steepfile_path, args: [], steep_command: jobs_option.steep_command_value, count: jobs_option.jobs_count_value)
|
40
40
|
|
41
41
|
master = Server::Master.new(
|
42
42
|
project: project,
|
data/lib/steep/drivers/stats.rb
CHANGED
@@ -126,7 +126,7 @@ module Steep
|
|
126
126
|
server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
|
127
127
|
server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
|
128
128
|
|
129
|
-
typecheck_workers = Server::WorkerProcess.
|
129
|
+
typecheck_workers = Server::WorkerProcess.start_typecheck_workers(
|
130
130
|
steepfile: project.steepfile_path,
|
131
131
|
delay_shutdown: true,
|
132
132
|
args: command_line_patterns,
|
data/lib/steep/drivers/watch.rb
CHANGED
@@ -42,7 +42,7 @@ module Steep
|
|
42
42
|
server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
|
43
43
|
server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
|
44
44
|
|
45
|
-
typecheck_workers = Server::WorkerProcess.
|
45
|
+
typecheck_workers = Server::WorkerProcess.start_typecheck_workers(steepfile: project.steepfile_path, args: dirs.map(&:to_s), steep_command: jobs_option.steep_command_value, count: jobs_option.jobs_count_value)
|
46
46
|
|
47
47
|
master = Server::Master.new(
|
48
48
|
project: project,
|
data/lib/steep/drivers/worker.rb
CHANGED
@@ -17,6 +17,8 @@ module Steep
|
|
17
17
|
def to_s
|
18
18
|
unless @array.empty?
|
19
19
|
@array.join("\n\n----\n\n")
|
20
|
+
else
|
21
|
+
""
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -83,7 +85,7 @@ module Steep
|
|
83
85
|
#{decl.method_type}
|
84
86
|
```
|
85
87
|
|
86
|
-
#{
|
88
|
+
#{comment.string.gsub(/\A([ \t]*\n)+/, "")}
|
87
89
|
EOM
|
88
90
|
end
|
89
91
|
end
|
@@ -108,10 +110,10 @@ EOM
|
|
108
110
|
end
|
109
111
|
when HoverProvider::Ruby::ConstantContent
|
110
112
|
CommentBuilder.build do |builder|
|
111
|
-
if content.class_or_module?
|
113
|
+
if decl = content.class_or_module?
|
112
114
|
builder << <<EOM
|
113
115
|
```rbs
|
114
|
-
#{declaration_summary(
|
116
|
+
#{declaration_summary(decl.primary.decl)}
|
115
117
|
```
|
116
118
|
EOM
|
117
119
|
end
|
@@ -141,6 +143,14 @@ EOM
|
|
141
143
|
builder << comment.string
|
142
144
|
end
|
143
145
|
end
|
146
|
+
when HoverProvider::Ruby::TypeAssertionContent
|
147
|
+
CommentBuilder.build do |builder|
|
148
|
+
builder << <<-EOM
|
149
|
+
`#{content.asserted_type.to_s}`
|
150
|
+
|
151
|
+
↑ Converted from `#{content.original_type.to_s}`
|
152
|
+
EOM
|
153
|
+
end
|
144
154
|
when HoverProvider::RBS::ClassContent
|
145
155
|
CommentBuilder.build do |builder|
|
146
156
|
builder << <<EOM
|
data/lib/steep/server/master.rb
CHANGED
@@ -796,7 +796,10 @@ module Steep
|
|
796
796
|
|
797
797
|
Steep.logger.info "Sending $/typecheck/start notifications"
|
798
798
|
typecheck_workers.each do |worker|
|
799
|
-
assignment = Services::PathAssignment.new(
|
799
|
+
assignment = Services::PathAssignment.new(
|
800
|
+
max_index: typecheck_workers.size,
|
801
|
+
index: worker.index || raise
|
802
|
+
)
|
800
803
|
|
801
804
|
job_queue << SendMessageJob.to_worker(
|
802
805
|
worker,
|
@@ -18,48 +18,120 @@ module Steep
|
|
18
18
|
@index = index
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.
|
21
|
+
def self.start_worker(type, name:, steepfile:, steep_command: "steep", index: nil, delay_shutdown: false, patterns: [])
|
22
|
+
begin
|
23
|
+
fork_worker(
|
24
|
+
type,
|
25
|
+
name: name,
|
26
|
+
steepfile: steepfile,
|
27
|
+
index: index,
|
28
|
+
delay_shutdown: delay_shutdown,
|
29
|
+
patterns: patterns
|
30
|
+
)
|
31
|
+
rescue NotImplementedError
|
32
|
+
spawn_worker(
|
33
|
+
type,
|
34
|
+
name: name,
|
35
|
+
steepfile: steepfile,
|
36
|
+
steep_command: steep_command,
|
37
|
+
index: index,
|
38
|
+
delay_shutdown: delay_shutdown,
|
39
|
+
patterns: patterns
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.fork_worker(type, name:, steepfile:, index:, delay_shutdown:, patterns:)
|
45
|
+
stdin_in, stdin_out = IO.pipe
|
46
|
+
stdout_in, stdout_out = IO.pipe
|
47
|
+
|
48
|
+
worker = Drivers::Worker.new(stdout: stdout_out, stdin: stdin_in, stderr: STDERR)
|
49
|
+
|
50
|
+
worker.steepfile = steepfile
|
51
|
+
worker.worker_type = type
|
52
|
+
worker.worker_name = name
|
53
|
+
worker.delay_shutdown = delay_shutdown
|
54
|
+
if (max, this = index)
|
55
|
+
worker.max_index = max
|
56
|
+
worker.index = this
|
57
|
+
end
|
58
|
+
worker.commandline_args = patterns
|
59
|
+
|
60
|
+
pid = fork do
|
61
|
+
worker.run()
|
62
|
+
end
|
63
|
+
|
64
|
+
pid or raise
|
65
|
+
|
66
|
+
writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin_out)
|
67
|
+
reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout_in)
|
68
|
+
|
69
|
+
# @type var wait_thread: Thread & _ProcessWaitThread
|
70
|
+
wait_thread = _ = Thread.new { Process.waitpid(pid) }
|
71
|
+
wait_thread.define_singleton_method(:pid) { pid }
|
72
|
+
|
73
|
+
stdin_in.close
|
74
|
+
stdout_out.close
|
75
|
+
|
76
|
+
new(
|
77
|
+
reader: reader,
|
78
|
+
writer: writer,
|
79
|
+
stderr: STDERR,
|
80
|
+
wait_thread: wait_thread,
|
81
|
+
name: name,
|
82
|
+
index: index&.[](1)
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.spawn_worker(type, name:, steepfile:, steep_command:, index:, delay_shutdown:, patterns:)
|
22
87
|
args = ["--name=#{name}", "--steepfile=#{steepfile}"]
|
23
88
|
args << (%w(debug info warn error fatal unknown)[Steep.logger.level].yield_self {|log_level| "--log-level=#{log_level}" })
|
89
|
+
|
24
90
|
if Steep.log_output.is_a?(String)
|
25
91
|
args << "--log-output=#{Steep.log_output}"
|
26
92
|
end
|
93
|
+
|
94
|
+
if (max, this = index)
|
95
|
+
args << "--max-index=#{max}"
|
96
|
+
args << "--index=#{this}"
|
97
|
+
end
|
98
|
+
|
99
|
+
if delay_shutdown
|
100
|
+
args << "--delay-shutdown"
|
101
|
+
end
|
102
|
+
|
27
103
|
command = case type
|
28
104
|
when :interaction
|
29
|
-
[steep_command, "worker", "--interaction", *args, *
|
105
|
+
[steep_command, "worker", "--interaction", *args, *patterns]
|
30
106
|
when :typecheck
|
31
|
-
[steep_command, "worker", "--typecheck", *args, *
|
107
|
+
[steep_command, "worker", "--typecheck", *args, *patterns]
|
32
108
|
else
|
33
109
|
raise "Unknown type: #{type}"
|
34
110
|
end
|
35
111
|
|
36
|
-
if delay_shutdown
|
37
|
-
command << "--delay-shutdown"
|
38
|
-
end
|
39
|
-
|
40
112
|
stdin, stdout, thread = if Gem.win_platform?
|
41
|
-
Open3.popen2(*command, new_pgroup: true)
|
113
|
+
__skip__ = Open3.popen2(*command, new_pgroup: true)
|
42
114
|
else
|
43
|
-
Open3.popen2(*command, pgroup: true)
|
115
|
+
__skip__ = Open3.popen2(*command, pgroup: true)
|
44
116
|
end
|
45
117
|
stderr = nil
|
46
118
|
|
47
119
|
writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin)
|
48
120
|
reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout)
|
49
121
|
|
50
|
-
new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread, name: name, index: index)
|
122
|
+
new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread, name: name, index: index&.[](1))
|
51
123
|
end
|
52
124
|
|
53
|
-
def self.
|
125
|
+
def self.start_typecheck_workers(steepfile:, args:, steep_command: "steep", count: [Etc.nprocessors - 1, 1].max, delay_shutdown: false)
|
54
126
|
count.times.map do |i|
|
55
|
-
|
127
|
+
start_worker(
|
56
128
|
:typecheck,
|
57
129
|
name: "typecheck@#{i}",
|
58
130
|
steepfile: steepfile,
|
59
131
|
steep_command: steep_command,
|
60
|
-
|
132
|
+
index: [count, i],
|
133
|
+
patterns: args,
|
61
134
|
delay_shutdown: delay_shutdown,
|
62
|
-
index: i
|
63
135
|
)
|
64
136
|
end
|
65
137
|
end
|
@@ -2,9 +2,9 @@ module Steep
|
|
2
2
|
module Services
|
3
3
|
module HoverProvider
|
4
4
|
class RBS
|
5
|
-
TypeAliasContent = Struct.new(:location, :decl, keyword_init: true)
|
6
|
-
ClassContent = Struct.new(:location, :decl, keyword_init: true)
|
7
|
-
InterfaceContent = Struct.new(:location, :decl, keyword_init: true)
|
5
|
+
TypeAliasContent = _ = Struct.new(:location, :decl, keyword_init: true)
|
6
|
+
ClassContent = _ = Struct.new(:location, :decl, keyword_init: true)
|
7
|
+
InterfaceContent = _ = Struct.new(:location, :decl, keyword_init: true)
|
8
8
|
|
9
9
|
attr_reader :service
|
10
10
|
|
@@ -33,14 +33,14 @@ module Steep
|
|
33
33
|
alias_decl = service.latest_env.alias_decls[head.name]&.decl or raise
|
34
34
|
|
35
35
|
TypeAliasContent.new(
|
36
|
-
location: head.location,
|
36
|
+
location: head.location || raise,
|
37
37
|
decl: alias_decl
|
38
38
|
)
|
39
39
|
when ::RBS::Types::ClassInstance, ::RBS::Types::ClassSingleton
|
40
40
|
if loc_key == :name
|
41
41
|
env = service.latest_env
|
42
|
-
class_decl = env.class_decls[head.name]&.decls[0
|
43
|
-
location = head.location[:name
|
42
|
+
class_decl = env.class_decls[head.name]&.decls&.[](0)&.decl or raise
|
43
|
+
location = head.location&.[](:name) or raise
|
44
44
|
ClassContent.new(
|
45
45
|
location: location,
|
46
46
|
decl: class_decl
|
@@ -49,7 +49,7 @@ module Steep
|
|
49
49
|
when ::RBS::Types::Interface
|
50
50
|
env = service.latest_env
|
51
51
|
interface_decl = env.interface_decls[head.name]&.decl or raise
|
52
|
-
location = head.location[:name
|
52
|
+
location = head.location&.[](:name) or raise
|
53
53
|
|
54
54
|
InterfaceContent.new(
|
55
55
|
location: location,
|
@@ -4,6 +4,7 @@ module Steep
|
|
4
4
|
class Ruby
|
5
5
|
TypeContent = _ = Struct.new(:node, :type, :location, keyword_init: true)
|
6
6
|
VariableContent = _ = Struct.new(:node, :name, :type, :location, keyword_init: true)
|
7
|
+
TypeAssertionContent = _ = Struct.new(:node, :original_type, :asserted_type, :location, keyword_init: true)
|
7
8
|
MethodCallContent = _ = Struct.new(:node, :method_call, :location, keyword_init: true)
|
8
9
|
DefinitionContent = _ = Struct.new(:node, :method_name, :method_type, :definition, :location, keyword_init: true)
|
9
10
|
ConstantContent = _ = Struct.new(:location, :full_name, :type, :decl, keyword_init: true) do
|
@@ -33,11 +34,15 @@ module Steep
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def constant?
|
36
|
-
decl.is_a?(::RBS::Environment::SingleEntry)
|
37
|
+
if decl.is_a?(::RBS::Environment::SingleEntry)
|
38
|
+
decl
|
39
|
+
end
|
37
40
|
end
|
38
41
|
|
39
42
|
def class_or_module?
|
40
|
-
decl.is_a?(::RBS::Environment::MultiEntry)
|
43
|
+
if decl.is_a?(::RBS::Environment::MultiEntry)
|
44
|
+
decl
|
45
|
+
end
|
41
46
|
end
|
42
47
|
end
|
43
48
|
|
@@ -78,8 +83,9 @@ module Steep
|
|
78
83
|
end
|
79
84
|
|
80
85
|
def method_name_from_method(context, builder:)
|
81
|
-
|
82
|
-
|
86
|
+
context.method or raise
|
87
|
+
defined_in = context.method.defined_in or raise
|
88
|
+
method_name = context.name or raise
|
83
89
|
|
84
90
|
case
|
85
91
|
when defined_in.class?
|
@@ -171,6 +177,15 @@ module Steep
|
|
171
177
|
decl: decl
|
172
178
|
)
|
173
179
|
end
|
180
|
+
when :assertion
|
181
|
+
original_node, _ = node.children
|
182
|
+
|
183
|
+
original_type = typing.type_of(node: original_node)
|
184
|
+
asserted_type = typing.type_of(node: node)
|
185
|
+
|
186
|
+
if original_type != asserted_type
|
187
|
+
return TypeAssertionContent.new(node: node, original_type: original_type, asserted_type: asserted_type, location: node.location.expression)
|
188
|
+
end
|
174
189
|
end
|
175
190
|
|
176
191
|
TypeContent.new(
|
@@ -174,7 +174,7 @@ module Steep
|
|
174
174
|
file.decls
|
175
175
|
else
|
176
176
|
# factory is not used here because the error is a syntax error.
|
177
|
-
Diagnostic::Signature.from_rbs_error(file.decls, factory: nil)
|
177
|
+
Diagnostic::Signature.from_rbs_error(file.decls, factory: _ = nil)
|
178
178
|
end
|
179
179
|
diagnostics << diagnostic
|
180
180
|
end
|
@@ -214,6 +214,7 @@ module Steep
|
|
214
214
|
|
215
215
|
def update_env(updated_files, paths:)
|
216
216
|
Steep.logger.tagged "#update_env" do
|
217
|
+
# @type var errors: Array[RBS::BaseError]
|
217
218
|
errors = []
|
218
219
|
new_decls = Set[].compare_by_identity
|
219
220
|
|
@@ -230,7 +231,9 @@ module Steep
|
|
230
231
|
updated_files.each_value do |content|
|
231
232
|
case decls = content.decls
|
232
233
|
when RBS::BaseError
|
233
|
-
errors <<
|
234
|
+
errors << decls
|
235
|
+
when Diagnostic::Signature::UnexpectedError
|
236
|
+
return [decls]
|
234
237
|
else
|
235
238
|
begin
|
236
239
|
decls.each do |decl|
|
@@ -255,7 +258,7 @@ module Steep
|
|
255
258
|
unless errors.empty?
|
256
259
|
return errors.map {|error|
|
257
260
|
# Factory will not be used because of the possible error types.
|
258
|
-
Diagnostic::Signature.from_rbs_error(error, factory: nil)
|
261
|
+
Diagnostic::Signature.from_rbs_error(error, factory: _ = nil)
|
259
262
|
}
|
260
263
|
end
|
261
264
|
|
@@ -277,7 +280,7 @@ module Steep
|
|
277
280
|
|
278
281
|
unless errors.empty?
|
279
282
|
# Builder won't be used.
|
280
|
-
factory = AST::Types::Factory.new(builder: nil)
|
283
|
+
factory = AST::Types::Factory.new(builder: _ = nil)
|
281
284
|
return errors.map {|error| Diagnostic::Signature.from_rbs_error(error, factory: factory) }
|
282
285
|
end
|
283
286
|
|