steep 1.8.0.dev.1 → 1.8.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 +33 -0
- data/README.md +3 -2
- data/bin/mem_graph.rb +67 -0
- data/bin/mem_prof.rb +102 -0
- data/bin/stackprof_test.rb +19 -0
- data/bin/steep-check.rb +251 -0
- data/guides/src/gem-rbs-collection/gem-rbs-collection.md +1 -1
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/builtin.rb +5 -5
- data/lib/steep/ast/node/type_application.rb +7 -6
- data/lib/steep/ast/types/any.rb +1 -9
- data/lib/steep/ast/types/boolean.rb +8 -16
- data/lib/steep/ast/types/bot.rb +2 -10
- data/lib/steep/ast/types/class.rb +1 -13
- data/lib/steep/ast/types/factory.rb +101 -85
- data/lib/steep/ast/types/instance.rb +1 -13
- data/lib/steep/ast/types/intersection.rb +8 -15
- data/lib/steep/ast/types/literal.rb +2 -8
- data/lib/steep/ast/types/logic.rb +3 -24
- data/lib/steep/ast/types/name.rb +5 -16
- data/lib/steep/ast/types/nil.rb +3 -12
- data/lib/steep/ast/types/proc.rb +4 -13
- data/lib/steep/ast/types/record.rb +21 -12
- data/lib/steep/ast/types/self.rb +1 -13
- data/lib/steep/ast/types/shared_instance.rb +11 -0
- data/lib/steep/ast/types/top.rb +1 -9
- data/lib/steep/ast/types/tuple.rb +4 -10
- data/lib/steep/ast/types/union.rb +10 -15
- data/lib/steep/ast/types/var.rb +4 -13
- data/lib/steep/ast/types/void.rb +2 -10
- data/lib/steep/diagnostic/ruby.rb +10 -10
- data/lib/steep/drivers/check.rb +11 -14
- data/lib/steep/drivers/checkfile.rb +8 -10
- data/lib/steep/drivers/stats.rb +17 -13
- data/lib/steep/drivers/utils/driver_helper.rb +24 -3
- data/lib/steep/drivers/watch.rb +3 -3
- data/lib/steep/interface/builder.rb +162 -138
- data/lib/steep/interface/method_type.rb +12 -20
- data/lib/steep/interface/shape.rb +66 -10
- data/lib/steep/interface/substitution.rb +2 -0
- data/lib/steep/interface/type_param.rb +20 -7
- data/lib/steep/located_value.rb +20 -0
- data/lib/steep/server/change_buffer.rb +5 -7
- data/lib/steep/server/custom_methods.rb +61 -0
- data/lib/steep/server/delay_queue.rb +8 -1
- data/lib/steep/server/interaction_worker.rb +13 -6
- data/lib/steep/server/lsp_formatter.rb +8 -6
- data/lib/steep/server/master.rb +195 -142
- data/lib/steep/server/type_check_worker.rb +25 -22
- data/lib/steep/server/work_done_progress.rb +64 -0
- data/lib/steep/server/worker_process.rb +1 -1
- data/lib/steep/services/completion_provider.rb +32 -24
- data/lib/steep/services/goto_service.rb +3 -2
- data/lib/steep/services/hover_provider/ruby.rb +30 -17
- data/lib/steep/services/signature_help_provider.rb +9 -7
- data/lib/steep/services/signature_service.rb +1 -1
- data/lib/steep/services/type_check_service.rb +19 -9
- data/lib/steep/signature/validator.rb +17 -20
- data/lib/steep/source.rb +47 -1
- data/lib/steep/subtyping/check.rb +105 -55
- data/lib/steep/subtyping/constraints.rb +13 -17
- data/lib/steep/type_construction.rb +106 -100
- data/lib/steep/type_inference/block_params.rb +8 -5
- data/lib/steep/type_inference/logic_type_interpreter.rb +11 -7
- data/lib/steep/type_inference/method_call.rb +3 -3
- data/lib/steep/type_inference/method_params.rb +1 -1
- data/lib/steep/type_inference/send_args.rb +1 -1
- data/lib/steep/typing.rb +164 -106
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +29 -4
- data/steep.gemspec +2 -2
- metadata +16 -9
- data/lib/steep/type_inference/context_array.rb +0 -112
@@ -11,9 +11,7 @@ module Steep
|
|
11
11
|
TypeCheckCodeJob = _ = Struct.new(:guid, :path, keyword_init: true)
|
12
12
|
ValidateAppSignatureJob = _ = Struct.new(:guid, :path, keyword_init: true)
|
13
13
|
ValidateLibrarySignatureJob = _ = Struct.new(:guid, :path, keyword_init: true)
|
14
|
-
GotoJob
|
15
|
-
# @implements GotoJob
|
16
|
-
|
14
|
+
class GotoJob < Struct.new(:id, :kind, :params, keyword_init: true)
|
17
15
|
def self.implementation(id:, params:)
|
18
16
|
new(
|
19
17
|
kind: :implementation,
|
@@ -57,7 +55,6 @@ module Steep
|
|
57
55
|
super(project: project, reader: reader, writer: writer)
|
58
56
|
|
59
57
|
@assignment = assignment
|
60
|
-
@service = Services::TypeCheckService.new(project: project)
|
61
58
|
@buffered_changes = {}
|
62
59
|
@mutex = Mutex.new()
|
63
60
|
@queue = Queue.new
|
@@ -65,30 +62,35 @@ module Steep
|
|
65
62
|
@current_type_check_guid = nil
|
66
63
|
end
|
67
64
|
|
65
|
+
def service
|
66
|
+
@service ||= Services::TypeCheckService.new(project: project)
|
67
|
+
end
|
68
|
+
|
68
69
|
def handle_request(request)
|
69
70
|
case request[:method]
|
70
71
|
when "initialize"
|
71
|
-
load_files(project: project, commandline_args: commandline_args)
|
72
72
|
writer.write({ id: request[:id], result: nil})
|
73
73
|
|
74
74
|
when "textDocument/didChange"
|
75
75
|
collect_changes(request)
|
76
76
|
|
77
|
-
when
|
78
|
-
|
79
|
-
|
77
|
+
when CustomMethods::FileLoad::METHOD
|
78
|
+
input = request[:params][:content]
|
79
|
+
load_files(input)
|
80
|
+
|
81
|
+
when CustomMethods::FileReset::METHOD
|
82
|
+
params = request[:params] #: CustomMethods::FileReset::params
|
83
|
+
uri = params[:uri]
|
84
|
+
text = params[:content]
|
80
85
|
reset_change(uri: uri, text: text)
|
81
86
|
|
82
87
|
when "workspace/symbol"
|
83
88
|
query = request[:params][:query]
|
84
89
|
queue << WorkspaceSymbolJob.new(id: request[:id], query: query)
|
85
|
-
when
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
when "$/typecheck/start"
|
91
|
-
params = request[:params]
|
90
|
+
when CustomMethods::Stats::METHOD
|
91
|
+
queue << StatsJob.new(id: request[:id])
|
92
|
+
when CustomMethods::TypeCheck__Start::METHOD
|
93
|
+
params = request[:params] #: CustomMethods::TypeCheck__Start::params
|
92
94
|
enqueue_typecheck_jobs(params)
|
93
95
|
when "textDocument/definition"
|
94
96
|
queue << GotoJob.definition(id: request[:id], params: request[:params])
|
@@ -173,7 +175,9 @@ module Steep
|
|
173
175
|
method: :"textDocument/publishDiagnostics",
|
174
176
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
175
177
|
uri: Steep::PathHelper.to_uri(job.path).to_s,
|
176
|
-
diagnostics: diagnostics.map {|diagnostic|
|
178
|
+
diagnostics: diagnostics.map {|diagnostic|
|
179
|
+
_ = formatter.format(diagnostic)
|
180
|
+
}.uniq
|
177
181
|
)
|
178
182
|
)
|
179
183
|
end
|
@@ -191,7 +195,7 @@ module Steep
|
|
191
195
|
method: :"textDocument/publishDiagnostics",
|
192
196
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
193
197
|
uri: Steep::PathHelper.to_uri(job.path).to_s,
|
194
|
-
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
198
|
+
diagnostics: diagnostics.map {|diagnostic| _ = formatter.format(diagnostic) }.uniq.compact
|
195
199
|
)
|
196
200
|
)
|
197
201
|
end
|
@@ -210,7 +214,9 @@ module Steep
|
|
210
214
|
method: :"textDocument/publishDiagnostics",
|
211
215
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
212
216
|
uri: Steep::PathHelper.to_uri(job.path).to_s,
|
213
|
-
diagnostics: diagnostics.map {|diagnostic|
|
217
|
+
diagnostics: diagnostics.map {|diagnostic|
|
218
|
+
_ = formatter.format(diagnostic)
|
219
|
+
}.uniq.compact
|
214
220
|
)
|
215
221
|
)
|
216
222
|
end
|
@@ -237,10 +243,7 @@ module Steep
|
|
237
243
|
end
|
238
244
|
|
239
245
|
def typecheck_progress(guid:, path:)
|
240
|
-
writer.write(
|
241
|
-
method: "$/typecheck/progress",
|
242
|
-
params: { guid: guid, path: path }
|
243
|
-
)
|
246
|
+
writer.write(CustomMethods::TypeCheck__Progress.notification({ guid: guid, path: path.to_s }))
|
244
247
|
end
|
245
248
|
|
246
249
|
def workspace_symbol_result(query)
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Steep
|
2
|
+
module Server
|
3
|
+
class WorkDoneProgress
|
4
|
+
attr_reader :sender, :guid, :percentage
|
5
|
+
|
6
|
+
def initialize(guid, &block)
|
7
|
+
@sender = block
|
8
|
+
@guid = guid
|
9
|
+
@percentage = 0
|
10
|
+
end
|
11
|
+
|
12
|
+
def begin(title, message = nil, request_id:)
|
13
|
+
sender.call(
|
14
|
+
{
|
15
|
+
id: request_id,
|
16
|
+
method: "window/workDoneProgress/create",
|
17
|
+
params: { token: guid }
|
18
|
+
}
|
19
|
+
)
|
20
|
+
|
21
|
+
value = { kind: "begin", cancellable: false, title: title, percentage: percentage }
|
22
|
+
value[:message] = message if message
|
23
|
+
|
24
|
+
sender.call(
|
25
|
+
{
|
26
|
+
method: "$/progress",
|
27
|
+
params: { token: guid, value: value }
|
28
|
+
}
|
29
|
+
)
|
30
|
+
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def report(percentage, message = nil)
|
35
|
+
@percentage = percentage
|
36
|
+
value = { kind: "report", percentage: percentage }
|
37
|
+
value[:message] = message if message
|
38
|
+
|
39
|
+
sender.call(
|
40
|
+
{
|
41
|
+
method: "$/progress",
|
42
|
+
params: { token: guid, value: value }
|
43
|
+
}
|
44
|
+
)
|
45
|
+
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
def end(message = nil)
|
50
|
+
value = { kind: "end" }
|
51
|
+
value[:message] = message if message
|
52
|
+
|
53
|
+
sender.call(
|
54
|
+
{
|
55
|
+
method: "$/progress",
|
56
|
+
params: { token: guid, value: value }
|
57
|
+
}
|
58
|
+
)
|
59
|
+
|
60
|
+
self
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -132,7 +132,7 @@ module Steep
|
|
132
132
|
new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread, name: name, index: index&.[](1))
|
133
133
|
end
|
134
134
|
|
135
|
-
def self.start_typecheck_workers(steepfile:, args:, steep_command:, count: [Etc.nprocessors - 1, 1].max, delay_shutdown: false)
|
135
|
+
def self.start_typecheck_workers(steepfile:, args:, steep_command:, count: [Etc.nprocessors - 1, 1].max || raise, delay_shutdown: false)
|
136
136
|
count.times.map do |i|
|
137
137
|
start_worker(
|
138
138
|
:typecheck,
|
@@ -183,8 +183,9 @@ module Steep
|
|
183
183
|
end
|
184
184
|
|
185
185
|
Steep.measure "typechecking" do
|
186
|
+
location = source.buffer.loc_to_pos([line, column])
|
186
187
|
resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
|
187
|
-
@typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver)
|
188
|
+
@typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: location)
|
188
189
|
end
|
189
190
|
end
|
190
191
|
|
@@ -348,7 +349,7 @@ module Steep
|
|
348
349
|
|
349
350
|
items = [] #: Array[item]
|
350
351
|
|
351
|
-
context = typing.
|
352
|
+
context = typing.cursor_context.context or raise
|
352
353
|
|
353
354
|
case
|
354
355
|
when node.type == :send && node.children[0] == nil && at_end?(position, of: (_ = node.loc).selector)
|
@@ -469,7 +470,7 @@ module Steep
|
|
469
470
|
|
470
471
|
if at_end?(shift_pos, of: node.loc)
|
471
472
|
begin
|
472
|
-
context = typing.
|
473
|
+
context = typing.cursor_context.context or raise
|
473
474
|
receiver_type =
|
474
475
|
case (type = typing.type_of(node: node))
|
475
476
|
when AST::Types::Self
|
@@ -499,7 +500,7 @@ module Steep
|
|
499
500
|
|
500
501
|
if at_end?(shift_pos, of: node.loc)
|
501
502
|
begin
|
502
|
-
context = typing.
|
503
|
+
context = typing.cursor_context.context or raise
|
503
504
|
receiver_type =
|
504
505
|
case (type = typing.type_of(node: node))
|
505
506
|
when AST::Types::Self
|
@@ -529,11 +530,11 @@ module Steep
|
|
529
530
|
case node&.type
|
530
531
|
when :const
|
531
532
|
# Constant:: ←
|
532
|
-
context = typing.
|
533
|
+
context = typing.cursor_context.context or raise
|
533
534
|
constant_items_for_context(context, parent: node, position: position, items: items, prefix: "")
|
534
535
|
when nil
|
535
536
|
# :: ←
|
536
|
-
context = typing.
|
537
|
+
context = typing.cursor_context.context or raise
|
537
538
|
constant_items_for_context(context, parent: nil, position: position, items: items, prefix: "")
|
538
539
|
end
|
539
540
|
|
@@ -552,7 +553,7 @@ module Steep
|
|
552
553
|
|
553
554
|
return [] unless node
|
554
555
|
|
555
|
-
context = typing.
|
556
|
+
context = typing.cursor_context.context or raise
|
556
557
|
items = [] #: Array[item]
|
557
558
|
instance_variable_items_for_context(context, prefix: "@", position: position, items: items)
|
558
559
|
items
|
@@ -561,7 +562,7 @@ module Steep
|
|
561
562
|
def items_for_rbs(position:, buffer:)
|
562
563
|
items = [] #: Array[item]
|
563
564
|
|
564
|
-
context = typing.
|
565
|
+
context = typing.cursor_context.context or raise
|
565
566
|
completion = TypeNameCompletion.new(env: context.env, context: context.module_context.nesting, dirs: [])
|
566
567
|
prefix = TypeNameCompletion::Prefix.parse(buffer, line: position.line, column: position.column)
|
567
568
|
|
@@ -609,7 +610,7 @@ module Steep
|
|
609
610
|
|
610
611
|
def method_items_for_receiver_type(type, include_private:, prefix:, position:, items:)
|
611
612
|
range = range_for(position, prefix: prefix)
|
612
|
-
context = typing.
|
613
|
+
context = typing.cursor_context.context or raise
|
613
614
|
|
614
615
|
config =
|
615
616
|
if (module_type = context.module_context&.module_type) && (instance_type = context.module_context&.instance_type)
|
@@ -634,39 +635,40 @@ module Steep
|
|
634
635
|
case type
|
635
636
|
when AST::Types::Name::Instance, AST::Types::Name::Interface, AST::Types::Name::Singleton
|
636
637
|
# Simple method type
|
637
|
-
all_decls = Set.new(method_entry.
|
638
|
+
all_decls = Set.new(method_entry.overloads.flat_map {|overload| overload.method_decls(name) }).sort_by {|decl| decl.method_name.to_s }
|
638
639
|
all_members = Set.new(all_decls.flat_map {|decl| decl.method_def.member })
|
639
640
|
all_members.each do |member|
|
640
641
|
associated_decl = all_decls.find {|decl| decl.method_def.member == member } or next
|
641
|
-
|
642
|
+
overloads = method_entry.overloads.select {|overload| overload.method_defs.any? {|defn| defn.member == member }}
|
642
643
|
items << SimpleMethodNameItem.new(
|
643
644
|
identifier: name,
|
644
645
|
range: range,
|
645
646
|
receiver_type: type,
|
646
647
|
method_name: associated_decl.method_name,
|
647
|
-
method_types:
|
648
|
+
method_types: overloads.map {|overload| subtyping.factory.method_type_1(overload.method_type) },
|
648
649
|
method_member: member
|
649
650
|
)
|
650
651
|
end
|
651
652
|
else
|
652
|
-
|
653
|
+
generated_overloads, defined_overloads =
|
654
|
+
method_entry.overloads.partition {|overload| overload.method_defs.empty? }
|
653
655
|
|
654
|
-
unless
|
656
|
+
unless defined_overloads.empty?
|
655
657
|
items << ComplexMethodNameItem.new(
|
656
658
|
identifier: name,
|
657
659
|
range: range,
|
658
660
|
receiver_type: type,
|
659
|
-
method_types:
|
660
|
-
method_decls:
|
661
|
+
method_types: defined_overloads.map { subtyping.factory.method_type_1(_1.method_type) },
|
662
|
+
method_decls: defined_overloads.flat_map { _1.method_decls(name).to_a }.sort_by {|decl| decl.method_name.to_s }
|
661
663
|
)
|
662
664
|
end
|
663
665
|
|
664
|
-
unless
|
666
|
+
unless generated_overloads.empty?
|
665
667
|
items << GeneratedMethodNameItem.new(
|
666
668
|
identifier: name,
|
667
669
|
range: range,
|
668
670
|
receiver_type: type,
|
669
|
-
method_types:
|
671
|
+
method_types: generated_overloads.map { subtyping.factory.method_type_1(_1.method_type) }
|
670
672
|
)
|
671
673
|
end
|
672
674
|
end
|
@@ -725,27 +727,33 @@ module Steep
|
|
725
727
|
end
|
726
728
|
|
727
729
|
def keyword_argument_items_for_method(call_node:, send_node:, position:, prefix:, items:)
|
728
|
-
|
730
|
+
_receiver_node, _method_name, argument_nodes = deconstruct_send_node!(send_node)
|
729
731
|
|
730
732
|
call = typing.call_of(node: call_node)
|
731
733
|
|
732
734
|
case call
|
733
735
|
when TypeInference::MethodCall::Typed, TypeInference::MethodCall::Error
|
734
|
-
context = typing.
|
736
|
+
context = typing.cursor_context.context or raise
|
735
737
|
type = call.receiver_type
|
738
|
+
type = type.subst(Interface::Substitution.build([], self_type: context.self_type, module_type: context.module_context&.module_type, instance_type: context.module_context&.instance_type))
|
736
739
|
|
737
740
|
config = Interface::Builder::Config.new(self_type: type, variable_bounds: context.variable_context.upper_bounds)
|
738
741
|
if shape = subtyping.builder.shape(type, config)
|
739
742
|
shape = shape.public_shape if private_send?(call_node)
|
740
743
|
if method = shape.methods[call.method_name]
|
741
|
-
method.
|
742
|
-
defn =
|
744
|
+
method.overloads.each.with_index do |overload, i|
|
745
|
+
defn = overload.method_decls(call.method_name).to_a[0]&.method_def
|
743
746
|
if defn && defn.type.type
|
744
747
|
range = range_for(position, prefix: prefix)
|
745
748
|
kwargs = argument_nodes.find { |arg| arg.type == :kwargs }&.children || []
|
746
749
|
used_kwargs = kwargs.filter_map { |arg| arg.type == :pair && arg.children.first.children.first }
|
747
750
|
|
748
|
-
|
751
|
+
if defn.type.type.is_a?(RBS::Types::UntypedFunction)
|
752
|
+
kwargs = [] #: Array[Symbol]
|
753
|
+
else
|
754
|
+
kwargs = defn.type.type.required_keywords.keys + defn.type.type.optional_keywords.keys
|
755
|
+
end
|
756
|
+
|
749
757
|
kwargs.each do |name|
|
750
758
|
if name.to_s.start_with?(prefix) && !used_kwargs.include?(name)
|
751
759
|
items << KeywordArgumentItem.new(identifier: "#{name}:", range: range)
|
@@ -784,7 +792,7 @@ module Steep
|
|
784
792
|
def unwrap_optional(type)
|
785
793
|
if type.is_a?(AST::Types::Union) && type.types.include?(AST::Builtin.nil_type)
|
786
794
|
types = type.types.reject { |t| t == AST::Builtin.nil_type }
|
787
|
-
AST::Types::Union.new(types: types
|
795
|
+
AST::Types::Union.new(types: types)
|
788
796
|
else
|
789
797
|
type
|
790
798
|
end
|
@@ -176,7 +176,7 @@ module Steep
|
|
176
176
|
when :def, :defs
|
177
177
|
named_location = (_ = node.location) #: Parser::AST::_NamedLocation
|
178
178
|
if test_ast_location(named_location.name, line: line, column: column)
|
179
|
-
if method_context = typing.
|
179
|
+
if method_context = typing.cursor_context.context&.method_context
|
180
180
|
if method = method_context.method
|
181
181
|
method.defs.each do |defn|
|
182
182
|
singleton_method =
|
@@ -285,8 +285,9 @@ module Steep
|
|
285
285
|
source = Source.parse(content, path: path, factory: subtyping.factory)
|
286
286
|
source = source.without_unrelated_defs(line: line, column: column)
|
287
287
|
resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
|
288
|
+
loc = source.buffer.loc_to_pos([line, column])
|
288
289
|
[
|
289
|
-
Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver),
|
290
|
+
Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: loc),
|
290
291
|
signature_service
|
291
292
|
]
|
292
293
|
rescue
|
@@ -84,7 +84,8 @@ module Steep
|
|
84
84
|
source = Source.parse(content, path: path, factory: subtyping.factory)
|
85
85
|
source = source.without_unrelated_defs(line: line, column: column)
|
86
86
|
resolver = ::RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
|
87
|
-
|
87
|
+
pos = source.buffer.loc_to_pos([line, column])
|
88
|
+
Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: pos)
|
88
89
|
rescue
|
89
90
|
nil
|
90
91
|
end
|
@@ -118,17 +119,27 @@ module Steep
|
|
118
119
|
case node.type
|
119
120
|
when :lvar
|
120
121
|
var_name = node.children[0]
|
121
|
-
context = typing.
|
122
|
-
var_type = context.type_env[var_name] || AST::Types::Any.
|
122
|
+
context = typing.cursor_context.context or raise
|
123
|
+
var_type = context.type_env[var_name] || AST::Types::Any.instance()
|
123
124
|
|
124
|
-
return VariableContent.new(
|
125
|
+
return VariableContent.new(
|
126
|
+
node: node,
|
127
|
+
name: var_name,
|
128
|
+
type: var_type,
|
129
|
+
location: node.location.name # steep:ignore NoMethod
|
130
|
+
)
|
125
131
|
|
126
132
|
when :lvasgn
|
127
133
|
var_name, rhs = node.children
|
128
|
-
context = typing.
|
134
|
+
context = typing.cursor_context.context or raise
|
129
135
|
type = context.type_env[var_name] || typing.type_of(node: node)
|
130
136
|
|
131
|
-
return VariableContent.new(
|
137
|
+
return VariableContent.new(
|
138
|
+
node: node,
|
139
|
+
name: var_name,
|
140
|
+
type: type,
|
141
|
+
location: node.location.name # steep:ignore NoMethod
|
142
|
+
)
|
132
143
|
|
133
144
|
when :send, :csend
|
134
145
|
result_node =
|
@@ -149,27 +160,29 @@ module Steep
|
|
149
160
|
return MethodCallContent.new(
|
150
161
|
node: result_node,
|
151
162
|
method_call: call,
|
152
|
-
location: node.location.selector
|
163
|
+
location: node.location.selector # steep:ignore NoMethod
|
153
164
|
)
|
154
165
|
end
|
155
166
|
end
|
156
167
|
|
157
168
|
when :def, :defs
|
158
|
-
context = typing.
|
169
|
+
context = typing.cursor_context.context or raise
|
159
170
|
method_context = context.method_context
|
160
171
|
|
161
172
|
if method_context && method_context.method
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
173
|
+
if method_context.method_type
|
174
|
+
return DefinitionContent.new(
|
175
|
+
node: node,
|
176
|
+
method_name: method_name_from_method(method_context, builder: context.factory.definition_builder),
|
177
|
+
method_type: method_context.method_type,
|
178
|
+
definition: method_context.method,
|
179
|
+
location: node.loc.name # steep:ignore NoMethod
|
180
|
+
)
|
181
|
+
end
|
169
182
|
end
|
170
183
|
|
171
184
|
when :const, :casgn
|
172
|
-
context = typing.
|
185
|
+
context = typing.cursor_context.context or raise
|
173
186
|
|
174
187
|
type = typing.type_of(node: node)
|
175
188
|
const_name = typing.source_index.reference(constant_node: node)
|
@@ -178,7 +191,7 @@ module Steep
|
|
178
191
|
entry = context.env.constant_entry(const_name) or return
|
179
192
|
|
180
193
|
return ConstantContent.new(
|
181
|
-
location: node.location.name,
|
194
|
+
location: node.location.name, # steep:ignore NoMethod
|
182
195
|
full_name: const_name,
|
183
196
|
type: type,
|
184
197
|
decl: entry
|
@@ -11,7 +11,7 @@ module Steep
|
|
11
11
|
arguments = [] #: Array[String]
|
12
12
|
arguments.push(*method_type.type.required_positionals.map(&:to_s))
|
13
13
|
arguments.push(*method_type.type.optional_positionals.map {|p| "?#{p}"})
|
14
|
-
arguments.push("*#{
|
14
|
+
arguments.push("*#{method_type.type.rest_positionals}") if method_type.type.rest_positionals
|
15
15
|
arguments.push(*method_type.type.trailing_positionals.map(&:to_s))
|
16
16
|
arguments.push(*method_type.type.required_keywords.map {|name, param| "#{name}: #{param}" })
|
17
17
|
arguments.push(*method_type.type.optional_keywords.map {|name, param| "?#{name}: #{param}" })
|
@@ -76,7 +76,8 @@ module Steep
|
|
76
76
|
def type_check!(line:, column:)
|
77
77
|
source = self.source.without_unrelated_defs(line: line, column: column)
|
78
78
|
resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
|
79
|
-
|
79
|
+
pos = self.source.buffer.loc_to_pos([line, column])
|
80
|
+
TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: pos)
|
80
81
|
end
|
81
82
|
|
82
83
|
def last_argument_nodes_for(argument_nodes:, line:, column:)
|
@@ -99,7 +100,7 @@ module Steep
|
|
99
100
|
|
100
101
|
def signature_help_for(node, argument, last_argument, typing)
|
101
102
|
call = typing.call_of(node: node)
|
102
|
-
context = typing.
|
103
|
+
context = typing.cursor_context.context or raise
|
103
104
|
|
104
105
|
items = [] #: Array[Item]
|
105
106
|
index = nil #: Integer?
|
@@ -113,14 +114,14 @@ module Steep
|
|
113
114
|
shape = shape.public_shape if private_send?(node)
|
114
115
|
|
115
116
|
if method = shape.methods[call.method_name]
|
116
|
-
method.
|
117
|
-
defn =
|
117
|
+
method.overloads.each.with_index do |overload, i|
|
118
|
+
defn = overload.method_defs[0]
|
118
119
|
|
119
120
|
active_parameter = active_parameter_for(defn&.type, argument, last_argument, node)
|
120
|
-
items << Item.new(subtyping.factory.method_type_1(method_type), defn&.comment, active_parameter)
|
121
|
+
items << Item.new(subtyping.factory.method_type_1(overload.method_type), defn&.comment, active_parameter)
|
121
122
|
|
122
123
|
if call.is_a?(MethodCall::Typed)
|
123
|
-
if
|
124
|
+
if call.method_decls.intersect?(overload.method_decls(call.method_name).to_set)
|
124
125
|
index = i
|
125
126
|
end
|
126
127
|
end
|
@@ -136,6 +137,7 @@ module Steep
|
|
136
137
|
|
137
138
|
def active_parameter_for(method_type, argument_nodes, last_argument_nodes, node)
|
138
139
|
return unless method_type
|
140
|
+
return unless method_type.type.is_a?(RBS::Types::Function)
|
139
141
|
|
140
142
|
positionals = method_type.type.required_positionals.size + method_type.type.optional_positionals.size + (method_type.type.rest_positionals ? 1 : 0) + method_type.type.trailing_positionals.size
|
141
143
|
|
@@ -156,6 +156,7 @@ module Steep
|
|
156
156
|
old_text = files[path]&.content
|
157
157
|
content = cs.inject(old_text || "") {|text, change| change.apply_to(text) }
|
158
158
|
|
159
|
+
content ||= "" # It was not clear why `content` can be `nil`, but it happens with `master_test`.
|
159
160
|
buffer = RBS::Buffer.new(name: path, content: content)
|
160
161
|
|
161
162
|
update[path] =
|
@@ -228,7 +229,6 @@ module Steep
|
|
228
229
|
end
|
229
230
|
|
230
231
|
def update_env(updated_files, paths:)
|
231
|
-
|
232
232
|
Steep.logger.tagged "#update_env" do
|
233
233
|
errors = [] #: Array[RBS::BaseError]
|
234
234
|
new_decls = Set[].compare_by_identity #: Set[RBS::AST::Declarations::t]
|
@@ -139,8 +139,11 @@ module Steep
|
|
139
139
|
|
140
140
|
case service.status
|
141
141
|
when SignatureService::SyntaxErrorStatus, SignatureService::AncestorErrorStatus
|
142
|
-
service.status.diagnostics.group_by {|diag|
|
143
|
-
|
142
|
+
service.status.diagnostics.group_by {|diag| diag.location&.buffer&.name&.to_s }.each do |path_string, diagnostics|
|
143
|
+
if path_string
|
144
|
+
path = Pathname(path_string)
|
145
|
+
signature_diagnostics[path].push(*diagnostics)
|
146
|
+
end
|
144
147
|
end
|
145
148
|
when SignatureService::LoadedStatus
|
146
149
|
validation_diagnostics = signature_validation_diagnostics[target.name] || {}
|
@@ -230,6 +233,7 @@ module Steep
|
|
230
233
|
case service.status
|
231
234
|
when SignatureService::SyntaxErrorStatus
|
232
235
|
diagnostics = service.status.diagnostics.select do |diag|
|
236
|
+
diag.location or raise
|
233
237
|
Pathname(diag.location.buffer.name) == path &&
|
234
238
|
(diag.is_a?(Diagnostic::Signature::SyntaxError) || diag.is_a?(Diagnostic::Signature::UnexpectedError))
|
235
239
|
end
|
@@ -239,12 +243,15 @@ module Steep
|
|
239
243
|
end
|
240
244
|
|
241
245
|
when SignatureService::AncestorErrorStatus
|
242
|
-
diagnostics = service.status.diagnostics.select
|
246
|
+
diagnostics = service.status.diagnostics.select do |diag|
|
247
|
+
diag.location or raise
|
248
|
+
Pathname(diag.location.buffer.name) == path
|
249
|
+
end
|
243
250
|
accumulated_diagnostics.push(*diagnostics)
|
244
251
|
yield [path, accumulated_diagnostics]
|
245
252
|
|
246
253
|
when SignatureService::LoadedStatus
|
247
|
-
validator = Signature::Validator.new(checker: service.current_subtyping)
|
254
|
+
validator = Signature::Validator.new(checker: service.current_subtyping || raise)
|
248
255
|
type_names = service.type_names(paths: Set[path], env: service.latest_env).to_set
|
249
256
|
|
250
257
|
unless type_names.empty?
|
@@ -286,7 +293,10 @@ module Steep
|
|
286
293
|
end
|
287
294
|
end
|
288
295
|
|
289
|
-
diagnostics = validator.each_error.select
|
296
|
+
diagnostics = validator.each_error.select do |error|
|
297
|
+
error.location or raise
|
298
|
+
Pathname(error.location.buffer.name) == path
|
299
|
+
end
|
290
300
|
accumulated_diagnostics.push(*diagnostics)
|
291
301
|
yield [path, accumulated_diagnostics]
|
292
302
|
end
|
@@ -353,7 +363,7 @@ module Steep
|
|
353
363
|
def type_check_file(target:, subtyping:, path:, text:)
|
354
364
|
Steep.logger.tagged "#type_check_file(#{path}@#{target.name})" do
|
355
365
|
source = Source.parse(text, path: path, factory: subtyping.factory)
|
356
|
-
typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: yield)
|
366
|
+
typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: yield, cursor: nil)
|
357
367
|
ignores = Source::IgnoreRanges.new(ignores: source.ignores)
|
358
368
|
SourceFile.with_typing(path: path, content: text, node: source.node, typing: typing, ignores: ignores)
|
359
369
|
end
|
@@ -361,7 +371,7 @@ module Steep
|
|
361
371
|
error = Diagnostic::Ruby::SyntaxError.new(message: exn.message, location: exn.location)
|
362
372
|
SourceFile.with_syntax_error(path: path, content: text, error: error)
|
363
373
|
rescue ::Parser::SyntaxError => exn
|
364
|
-
error = Diagnostic::Ruby::SyntaxError.new(message: exn.message, location: exn.diagnostic.location)
|
374
|
+
error = Diagnostic::Ruby::SyntaxError.new(message: exn.message, location: (_ = exn).diagnostic.location)
|
365
375
|
SourceFile.with_syntax_error(path: path, content: text, error: error)
|
366
376
|
rescue EncodingError => exn
|
367
377
|
SourceFile.no_data(path: path, content: "")
|
@@ -370,7 +380,7 @@ module Steep
|
|
370
380
|
SourceFile.no_data(path: path, content: text)
|
371
381
|
end
|
372
382
|
|
373
|
-
def self.type_check(source:, subtyping:, constant_resolver:)
|
383
|
+
def self.type_check(source:, subtyping:, constant_resolver:, cursor:)
|
374
384
|
annotations = source.annotations(block: source.node, factory: subtyping.factory, context: nil)
|
375
385
|
|
376
386
|
definition = subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name)
|
@@ -408,7 +418,7 @@ module Steep
|
|
408
418
|
variable_context: TypeInference::Context::TypeVariableContext.empty
|
409
419
|
)
|
410
420
|
|
411
|
-
typing = Typing.new(source: source, root_context: context)
|
421
|
+
typing = Typing.new(source: source, root_context: context, cursor: cursor)
|
412
422
|
|
413
423
|
construction = TypeConstruction.new(
|
414
424
|
checker: subtyping,
|