steep 1.2.0 → 1.3.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|