steep 0.43.1 → 0.46.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +8 -0
- data/.github/workflows/ruby.yml +4 -2
- data/.gitignore +0 -1
- data/CHANGELOG.md +41 -0
- data/Gemfile +0 -1
- data/Gemfile.lock +77 -0
- data/bin/output_test.rb +8 -2
- data/lib/steep/ast/builtin.rb +7 -1
- data/lib/steep/ast/types/factory.rb +19 -25
- data/lib/steep/cli.rb +7 -1
- data/lib/steep/diagnostic/lsp_formatter.rb +59 -6
- data/lib/steep/diagnostic/ruby.rb +188 -60
- data/lib/steep/diagnostic/signature.rb +34 -0
- data/lib/steep/drivers/check.rb +3 -0
- data/lib/steep/drivers/init.rb +10 -3
- data/lib/steep/drivers/utils/driver_helper.rb +15 -0
- data/lib/steep/drivers/validate.rb +1 -1
- data/lib/steep/drivers/watch.rb +3 -0
- data/lib/steep/equatable.rb +21 -0
- data/lib/steep/index/source_index.rb +55 -5
- data/lib/steep/interface/block.rb +4 -0
- data/lib/steep/interface/function.rb +798 -579
- data/lib/steep/project/dsl.rb +105 -33
- data/lib/steep/project/options.rb +12 -53
- data/lib/steep/project/target.rb +21 -8
- data/lib/steep/server/interaction_worker.rb +239 -20
- data/lib/steep/server/master.rb +22 -1
- data/lib/steep/server/type_check_worker.rb +74 -9
- data/lib/steep/services/file_loader.rb +26 -19
- data/lib/steep/services/goto_service.rb +322 -0
- data/lib/steep/services/hover_content.rb +132 -80
- data/lib/steep/services/type_check_service.rb +25 -0
- data/lib/steep/source.rb +7 -10
- data/lib/steep/type_construction.rb +496 -518
- data/lib/steep/type_inference/block_params.rb +2 -5
- data/lib/steep/type_inference/method_params.rb +483 -0
- data/lib/steep/type_inference/send_args.rb +610 -128
- data/lib/steep/typing.rb +46 -21
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +4 -1
- data/sample/Steepfile +10 -3
- data/sig/steep/type_inference/send_args.rbs +42 -0
- data/smoke/alias/Steepfile +2 -1
- data/smoke/and/Steepfile +2 -1
- data/smoke/array/Steepfile +2 -1
- data/smoke/array/test_expectations.yml +3 -3
- data/smoke/block/Steepfile +2 -2
- data/smoke/block/c.rb +0 -1
- data/smoke/case/Steepfile +2 -1
- data/smoke/class/Steepfile +2 -1
- data/smoke/class/test_expectations.yml +12 -15
- data/smoke/const/Steepfile +2 -1
- data/smoke/const/test_expectations.yml +0 -10
- data/smoke/diagnostics/Steepfile +2 -1
- data/smoke/diagnostics/a.rbs +0 -4
- data/smoke/diagnostics/different_method_parameter_kind.rb +9 -0
- data/smoke/diagnostics/method_arity_mismatch.rb +2 -2
- data/smoke/diagnostics/method_parameter_mismatch.rb +10 -0
- data/smoke/diagnostics/test_expectations.yml +108 -57
- data/smoke/diagnostics-rbs/Steepfile +1 -1
- data/smoke/diagnostics-rbs/mixin-class-error.rbs +6 -0
- data/smoke/diagnostics-rbs/test_expectations.yml +12 -0
- data/smoke/diagnostics-rbs-duplicated/Steepfile +2 -1
- data/smoke/diagnostics-ruby-unsat/Steepfile +6 -0
- data/smoke/diagnostics-ruby-unsat/a.rbs +3 -0
- data/smoke/diagnostics-ruby-unsat/test_expectations.yml +27 -0
- data/smoke/{diagnostics → diagnostics-ruby-unsat}/unsatisfiable_constraint.rb +0 -1
- data/smoke/dstr/Steepfile +2 -1
- data/smoke/ensure/Steepfile +2 -1
- data/smoke/ensure/test_expectations.yml +3 -3
- data/smoke/enumerator/Steepfile +2 -1
- data/smoke/enumerator/test_expectations.yml +1 -1
- data/smoke/extension/Steepfile +2 -1
- data/smoke/hash/Steepfile +2 -1
- data/smoke/hello/Steepfile +2 -1
- data/smoke/if/Steepfile +2 -1
- data/smoke/implements/Steepfile +2 -1
- data/smoke/initialize/Steepfile +2 -1
- data/smoke/integer/Steepfile +2 -1
- data/smoke/interface/Steepfile +2 -1
- data/smoke/kwbegin/Steepfile +2 -1
- data/smoke/lambda/Steepfile +2 -1
- data/smoke/literal/Steepfile +2 -1
- data/smoke/literal/test_expectations.yml +2 -2
- data/smoke/map/Steepfile +2 -1
- data/smoke/method/Steepfile +2 -1
- data/smoke/method/test_expectations.yml +11 -10
- data/smoke/module/Steepfile +2 -1
- data/smoke/regexp/Steepfile +2 -1
- data/smoke/regression/Steepfile +2 -1
- data/smoke/regression/issue_372.rb +8 -0
- data/smoke/regression/issue_372.rbs +4 -0
- data/smoke/regression/test_expectations.yml +0 -12
- data/smoke/rescue/Steepfile +2 -1
- data/smoke/rescue/test_expectations.yml +3 -3
- data/smoke/self/Steepfile +2 -1
- data/smoke/skip/Steepfile +2 -1
- data/smoke/stdout/Steepfile +2 -1
- data/smoke/super/Steepfile +2 -1
- data/smoke/toplevel/Steepfile +2 -1
- data/smoke/toplevel/test_expectations.yml +3 -3
- data/smoke/tsort/Steepfile +4 -5
- data/smoke/tsort/test_expectations.yml +2 -2
- data/smoke/type_case/Steepfile +2 -1
- data/smoke/unexpected/Steepfile +2 -1
- data/smoke/yield/Steepfile +2 -1
- data/steep.gemspec +2 -2
- metadata +24 -10
data/lib/steep/server/master.rb
CHANGED
@@ -499,7 +499,11 @@ module Steep
|
|
499
499
|
trigger_characters: [".", "@"],
|
500
500
|
work_done_progress: true
|
501
501
|
),
|
502
|
-
workspace_symbol_provider: true
|
502
|
+
workspace_symbol_provider: true,
|
503
|
+
definition_provider: true,
|
504
|
+
declaration_provider: false,
|
505
|
+
implementation_provider: true,
|
506
|
+
type_definition_provider: false
|
503
507
|
)
|
504
508
|
)
|
505
509
|
}
|
@@ -584,6 +588,23 @@ module Steep
|
|
584
588
|
end
|
585
589
|
end
|
586
590
|
|
591
|
+
when "textDocument/definition", "textDocument/implementation"
|
592
|
+
result_controller << group_request do |group|
|
593
|
+
typecheck_workers.each do |worker|
|
594
|
+
group << send_request(method: message[:method], params: message[:params], worker: worker)
|
595
|
+
end
|
596
|
+
|
597
|
+
group.on_completion do |handlers|
|
598
|
+
links = handlers.flat_map(&:result)
|
599
|
+
job_queue << SendMessageJob.to_client(
|
600
|
+
message: {
|
601
|
+
id: message[:id],
|
602
|
+
result: links
|
603
|
+
}
|
604
|
+
)
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
587
608
|
when "$/typecheck"
|
588
609
|
request = controller.make_request(
|
589
610
|
guid: message[:params][:guid],
|
@@ -11,6 +11,31 @@ 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 = Struct.new(:id, :kind, :params, keyword_init: true) do
|
15
|
+
def self.implementation(id:, params:)
|
16
|
+
new(
|
17
|
+
kind: :implementation,
|
18
|
+
id: id,
|
19
|
+
params: params
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.definition(id:, params:)
|
24
|
+
new(
|
25
|
+
kind: :definition,
|
26
|
+
id: id,
|
27
|
+
params: params
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def implementation?
|
32
|
+
kind == :implementation
|
33
|
+
end
|
34
|
+
|
35
|
+
def definition?
|
36
|
+
kind == :definition
|
37
|
+
end
|
38
|
+
end
|
14
39
|
|
15
40
|
include ChangeBuffer
|
16
41
|
|
@@ -44,6 +69,10 @@ module Steep
|
|
44
69
|
when "$/typecheck/start"
|
45
70
|
params = request[:params]
|
46
71
|
enqueue_typecheck_jobs(params)
|
72
|
+
when "textDocument/definition"
|
73
|
+
queue << GotoJob.definition(id: request[:id], params: request[:params])
|
74
|
+
when "textDocument/implementation"
|
75
|
+
queue << GotoJob.implementation(id: request[:id], params: request[:params])
|
47
76
|
end
|
48
77
|
end
|
49
78
|
|
@@ -115,7 +144,7 @@ module Steep
|
|
115
144
|
if job.guid == current_type_check_guid
|
116
145
|
Steep.logger.info { "Processing ValidateAppSignature for guid=#{job.guid}, path=#{job.path}" }
|
117
146
|
service.validate_signature(path: project.relative_path(job.path)) do |path, diagnostics|
|
118
|
-
formatter = Diagnostic::LSPFormatter.new()
|
147
|
+
formatter = Diagnostic::LSPFormatter.new({})
|
119
148
|
|
120
149
|
writer.write(
|
121
150
|
method: :"textDocument/publishDiagnostics",
|
@@ -133,13 +162,13 @@ module Steep
|
|
133
162
|
if job.guid == current_type_check_guid
|
134
163
|
Steep.logger.info { "Processing ValidateLibrarySignature for guid=#{job.guid}, path=#{job.path}" }
|
135
164
|
service.validate_signature(path: job.path) do |path, diagnostics|
|
136
|
-
formatter = Diagnostic::LSPFormatter.new()
|
165
|
+
formatter = Diagnostic::LSPFormatter.new({})
|
137
166
|
|
138
167
|
writer.write(
|
139
168
|
method: :"textDocument/publishDiagnostics",
|
140
169
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
141
170
|
uri: URI.parse(job.path.to_s).tap {|uri| uri.scheme = "file"},
|
142
|
-
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq
|
171
|
+
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
143
172
|
)
|
144
173
|
)
|
145
174
|
end
|
@@ -151,17 +180,14 @@ module Steep
|
|
151
180
|
if job.guid == current_type_check_guid
|
152
181
|
Steep.logger.info { "Processing TypeCheckCodeJob for guid=#{job.guid}, path=#{job.path}" }
|
153
182
|
service.typecheck_source(path: project.relative_path(job.path)) do |path, diagnostics|
|
154
|
-
|
155
|
-
|
156
|
-
end
|
157
|
-
|
158
|
-
formatter = Diagnostic::LSPFormatter.new()
|
183
|
+
target = project.target_for_source_path(path)
|
184
|
+
formatter = Diagnostic::LSPFormatter.new(target&.code_diagnostics_config || {})
|
159
185
|
|
160
186
|
writer.write(
|
161
187
|
method: :"textDocument/publishDiagnostics",
|
162
188
|
params: LSP::Interface::PublishDiagnosticsParams.new(
|
163
189
|
uri: URI.parse(job.path.to_s).tap {|uri| uri.scheme = "file"},
|
164
|
-
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq
|
190
|
+
diagnostics: diagnostics.map {|diagnostic| formatter.format(diagnostic) }.uniq.compact
|
165
191
|
)
|
166
192
|
)
|
167
193
|
end
|
@@ -179,6 +205,11 @@ module Steep
|
|
179
205
|
id: job.id,
|
180
206
|
result: stats_result().map(&:as_json)
|
181
207
|
)
|
208
|
+
when GotoJob
|
209
|
+
writer.write(
|
210
|
+
id: job.id,
|
211
|
+
result: goto(job)
|
212
|
+
)
|
182
213
|
end
|
183
214
|
end
|
184
215
|
|
@@ -231,6 +262,40 @@ module Steep
|
|
231
262
|
end
|
232
263
|
end
|
233
264
|
end
|
265
|
+
|
266
|
+
def goto(job)
|
267
|
+
path = Pathname(URI.parse(job.params[:textDocument][:uri]).path)
|
268
|
+
line = job.params[:position][:line] + 1
|
269
|
+
column = job.params[:position][:character]
|
270
|
+
|
271
|
+
goto_service = Services::GotoService.new(type_check: service)
|
272
|
+
locations =
|
273
|
+
case
|
274
|
+
when job.definition?
|
275
|
+
goto_service.definition(path: path, line: line, column: column)
|
276
|
+
when job.implementation?
|
277
|
+
goto_service.implementation(path: path, line: line, column: column)
|
278
|
+
else
|
279
|
+
raise
|
280
|
+
end
|
281
|
+
|
282
|
+
locations.map do |loc|
|
283
|
+
path =
|
284
|
+
case loc
|
285
|
+
when RBS::Location
|
286
|
+
Pathname(loc.buffer.name)
|
287
|
+
else
|
288
|
+
Pathname(loc.source_buffer.name)
|
289
|
+
end
|
290
|
+
|
291
|
+
path = project.absolute_path(path)
|
292
|
+
|
293
|
+
{
|
294
|
+
uri: URI.parse(path.to_s).tap {|uri| uri.scheme = "file" }.to_s,
|
295
|
+
range: loc.as_lsp_range
|
296
|
+
}
|
297
|
+
end
|
298
|
+
end
|
234
299
|
end
|
235
300
|
end
|
236
301
|
end
|
@@ -8,29 +8,36 @@ module Steep
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def each_path_in_patterns(pattern, commandline_patterns = [])
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
11
|
+
if block_given?
|
12
|
+
pats = commandline_patterns.empty? ? pattern.patterns : commandline_patterns
|
13
|
+
|
14
|
+
pats.each do |path|
|
15
|
+
absolute_path = base_dir + path
|
16
|
+
|
17
|
+
if absolute_path.file?
|
18
|
+
if pattern =~ path
|
19
|
+
yield absolute_path.relative_path_from(base_dir)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
files = if absolute_path.directory?
|
23
|
+
Pathname.glob("#{absolute_path}/**/*#{pattern.ext}")
|
24
|
+
else
|
25
|
+
Pathname.glob(absolute_path)
|
26
|
+
end
|
27
|
+
|
28
|
+
files.sort.each do |source_path|
|
29
|
+
if source_path.file?
|
30
|
+
relative_path = source_path.relative_path_from(base_dir)
|
31
|
+
unless pattern.ignore?(relative_path)
|
32
|
+
yield relative_path
|
33
|
+
end
|
30
34
|
end
|
31
35
|
end
|
32
36
|
end
|
37
|
+
|
33
38
|
end
|
39
|
+
else
|
40
|
+
enum_for :each_path_in_patterns, pattern, commandline_patterns
|
34
41
|
end
|
35
42
|
end
|
36
43
|
|
@@ -0,0 +1,322 @@
|
|
1
|
+
module Steep
|
2
|
+
module Services
|
3
|
+
class GotoService
|
4
|
+
include ModuleHelper
|
5
|
+
|
6
|
+
module SourceHelper
|
7
|
+
def from_ruby?
|
8
|
+
from == :ruby
|
9
|
+
end
|
10
|
+
|
11
|
+
def from_rbs?
|
12
|
+
from == :rbs
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ConstantQuery = Struct.new(:name, :from, keyword_init: true) do
|
17
|
+
include SourceHelper
|
18
|
+
end
|
19
|
+
MethodQuery = Struct.new(:name, :from, keyword_init: true) do
|
20
|
+
include SourceHelper
|
21
|
+
end
|
22
|
+
TypeNameQuery = Struct.new(:name, keyword_init: true)
|
23
|
+
|
24
|
+
attr_reader :type_check
|
25
|
+
|
26
|
+
def initialize(type_check:)
|
27
|
+
@type_check = type_check
|
28
|
+
end
|
29
|
+
|
30
|
+
def project
|
31
|
+
type_check.project
|
32
|
+
end
|
33
|
+
|
34
|
+
def implementation(path:, line:, column:)
|
35
|
+
locations = []
|
36
|
+
|
37
|
+
relative_path = project.relative_path(path)
|
38
|
+
|
39
|
+
queries = query_at(path: path, line: line, column: column)
|
40
|
+
queries.uniq!
|
41
|
+
|
42
|
+
queries.each do |query|
|
43
|
+
case query
|
44
|
+
when ConstantQuery
|
45
|
+
constant_definition_in_ruby(query.name, locations: locations)
|
46
|
+
when MethodQuery
|
47
|
+
method_locations(query.name, locations: locations, in_ruby: true, in_rbs: false)
|
48
|
+
when TypeNameQuery
|
49
|
+
type_name_locations(query.name, locations: locations)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
locations.uniq
|
54
|
+
end
|
55
|
+
|
56
|
+
def definition(path:, line:, column:)
|
57
|
+
locations = []
|
58
|
+
|
59
|
+
relative_path = project.relative_path(path)
|
60
|
+
|
61
|
+
queries = query_at(path: path, line: line, column: column)
|
62
|
+
queries.uniq!
|
63
|
+
|
64
|
+
queries.each do |query|
|
65
|
+
case query
|
66
|
+
when ConstantQuery
|
67
|
+
constant_definition_in_rbs(query.name, locations: locations) if query.from_ruby?
|
68
|
+
constant_definition_in_ruby(query.name, locations: locations) if query.from_rbs?
|
69
|
+
when MethodQuery
|
70
|
+
method_locations(
|
71
|
+
query.name,
|
72
|
+
locations: locations,
|
73
|
+
in_ruby: query.from_rbs?,
|
74
|
+
in_rbs: query.from_ruby?
|
75
|
+
)
|
76
|
+
when TypeNameQuery
|
77
|
+
type_name_locations(query.name, locations: locations)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
locations.uniq
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_ast_location(loc, line:, column:)
|
85
|
+
return false if line < loc.line
|
86
|
+
return false if line == loc.line && column < loc.column
|
87
|
+
return false if loc.last_line < line
|
88
|
+
return false if line == loc.last_line && loc.last_column < column
|
89
|
+
true
|
90
|
+
end
|
91
|
+
|
92
|
+
def query_at(path:, line:, column:)
|
93
|
+
queries = []
|
94
|
+
|
95
|
+
relative_path = project.relative_path(path)
|
96
|
+
|
97
|
+
case
|
98
|
+
when target = type_check.source_file?(relative_path)
|
99
|
+
source = type_check.source_files[relative_path]
|
100
|
+
typing, signature = type_check_path(target: target, path: relative_path, content: source.content, line: line, column: column)
|
101
|
+
if typing
|
102
|
+
node, *parents = typing.source.find_nodes(line: line, column: column)
|
103
|
+
if node
|
104
|
+
case node.type
|
105
|
+
when :const, :casgn
|
106
|
+
if test_ast_location(node.location.name, line: line, column: column)
|
107
|
+
if module_context = typing.context_at(line: line, column: column).module_context
|
108
|
+
const_env = module_context.const_env
|
109
|
+
const = const_env.lookup_constant(module_name_from_node(node))
|
110
|
+
queries << ConstantQuery.new(name: const.name, from: :ruby)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
when :def, :defs
|
114
|
+
if test_ast_location(node.location.name, line: line, column: column)
|
115
|
+
if method_context = typing.context_at(line: line, column: column).method_context
|
116
|
+
type_name = method_context.method.defined_in
|
117
|
+
name =
|
118
|
+
if method_context.method.defs.any? {|defn| defn.member.singleton? }
|
119
|
+
SingletonMethodName.new(type_name: type_name, method_name: method_context.name)
|
120
|
+
else
|
121
|
+
InstanceMethodName.new(type_name: type_name, method_name: method_context.name)
|
122
|
+
end
|
123
|
+
queries << MethodQuery.new(name: name, from: :ruby)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
when :send
|
127
|
+
if test_ast_location(node.location.selector, line: line, column: column)
|
128
|
+
node = parents[0] if parents[0]&.type == :block
|
129
|
+
case call = typing.call_of(node: node)
|
130
|
+
when TypeInference::MethodCall::Typed, TypeInference::MethodCall::Error
|
131
|
+
call.method_decls.each do |decl|
|
132
|
+
queries << MethodQuery.new(name: decl.method_name, from: :ruby)
|
133
|
+
end
|
134
|
+
when TypeInference::MethodCall::Untyped
|
135
|
+
# nop
|
136
|
+
when TypeInference::MethodCall::NoMethodError
|
137
|
+
# nop
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
when target_names = type_check.signature_file?(path)
|
144
|
+
target_names.each do |target_name|
|
145
|
+
signature_service = type_check.signature_services[target_name]
|
146
|
+
decls = signature_service.latest_env.declarations.select do |decl|
|
147
|
+
buffer_path = Pathname(decl.location.buffer.name)
|
148
|
+
buffer_path == relative_path || buffer_path == path
|
149
|
+
end
|
150
|
+
|
151
|
+
locator = RBS::Locator.new(decls: decls)
|
152
|
+
last, nodes = locator.find2(line: line, column: column)
|
153
|
+
case nodes[0]
|
154
|
+
when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
|
155
|
+
if last == :name
|
156
|
+
queries << ConstantQuery.new(name: nodes[0].name, from: :rbs)
|
157
|
+
end
|
158
|
+
when RBS::AST::Declarations::Constant
|
159
|
+
if last == :name
|
160
|
+
queries << ConstantQuery.new(name: nodes[0].name, from: :rbs)
|
161
|
+
end
|
162
|
+
when RBS::AST::Members::MethodDefinition
|
163
|
+
if last == :name
|
164
|
+
type_name = nodes[1].name
|
165
|
+
method_name = nodes[0].name
|
166
|
+
if nodes[0].instance?
|
167
|
+
queries << MethodQuery.new(
|
168
|
+
name: InstanceMethodName.new(type_name: type_name, method_name: method_name),
|
169
|
+
from: :rbs
|
170
|
+
)
|
171
|
+
end
|
172
|
+
if nodes[0].singleton?
|
173
|
+
queries << MethodQuery.new(
|
174
|
+
name: SingletonMethodName.new(type_name: type_name, method_name: method_name),
|
175
|
+
from: :rbs
|
176
|
+
)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
when RBS::AST::Members::Include, RBS::AST::Members::Extend, RBS::AST::Members::Prepend
|
180
|
+
if last == :name
|
181
|
+
queries << TypeNameQuery.new(name: nodes[0].name)
|
182
|
+
end
|
183
|
+
when RBS::Types::ClassInstance, RBS::Types::ClassSingleton, RBS::Types::Interface, RBS::Types::Alias
|
184
|
+
if last == :name
|
185
|
+
queries << TypeNameQuery.new(name: nodes[0].name)
|
186
|
+
end
|
187
|
+
when RBS::AST::Declarations::Class::Super, RBS::AST::Declarations::Module::Self
|
188
|
+
if last == :name
|
189
|
+
queries << TypeNameQuery.new(name: nodes[0].name)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
queries
|
196
|
+
end
|
197
|
+
|
198
|
+
def type_check_path(target:, path:, content:, line:, column:)
|
199
|
+
signature_service = type_check.signature_services[target.name]
|
200
|
+
subtyping = signature_service.current_subtyping or return
|
201
|
+
source = Source.parse(content, path: path, factory: subtyping.factory)
|
202
|
+
source = source.without_unrelated_defs(line: line, column: column)
|
203
|
+
[
|
204
|
+
Services::TypeCheckService.type_check(source: source, subtyping: subtyping),
|
205
|
+
signature_service
|
206
|
+
]
|
207
|
+
rescue
|
208
|
+
nil
|
209
|
+
end
|
210
|
+
|
211
|
+
def constant_definition_in_rbs(name, locations:)
|
212
|
+
type_check.signature_services.each_value do |signature|
|
213
|
+
env = signature.latest_env
|
214
|
+
|
215
|
+
if entry = env.class_decls[name]
|
216
|
+
entry.decls.each do |d|
|
217
|
+
locations << d.decl.location[:name]
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
if entry = env.constant_decls[name]
|
222
|
+
locations << entry.decl.location[:name]
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
locations
|
227
|
+
end
|
228
|
+
|
229
|
+
def constant_definition_in_ruby(name, locations:)
|
230
|
+
type_check.source_files.each do |path, source|
|
231
|
+
if typing = source.typing
|
232
|
+
entry = typing.source_index.entry(constant: name)
|
233
|
+
entry.definitions.each do |node|
|
234
|
+
case node.type
|
235
|
+
when :class, :module
|
236
|
+
locations << node.children[0].location.expression
|
237
|
+
when :casgn
|
238
|
+
parent = node.children[0]
|
239
|
+
location =
|
240
|
+
if parent
|
241
|
+
parent.location.expression.join(node.location.name)
|
242
|
+
else
|
243
|
+
node.location.name
|
244
|
+
end
|
245
|
+
locations << location
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
locations
|
252
|
+
end
|
253
|
+
|
254
|
+
def method_locations(name, in_ruby:, in_rbs:, locations:)
|
255
|
+
if in_ruby
|
256
|
+
type_check.source_files.each do |path, source|
|
257
|
+
if typing = source.typing
|
258
|
+
entry = typing.source_index.entry(method: name)
|
259
|
+
|
260
|
+
if entry.definitions.empty?
|
261
|
+
if name.is_a?(SingletonMethodName) && name.method_name == :new
|
262
|
+
initialize = InstanceMethodName.new(method_name: :initialize, type_name: name.type_name)
|
263
|
+
entry = typing.source_index.entry(method: initialize)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
entry.definitions.each do |node|
|
268
|
+
case node.type
|
269
|
+
when :def
|
270
|
+
locations << node.location.name
|
271
|
+
when :defs
|
272
|
+
locations << node.location.name
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
if in_rbs
|
280
|
+
type_check.signature_services.each_value do |signature|
|
281
|
+
index = signature.latest_rbs_index
|
282
|
+
|
283
|
+
entry = index.entry(method_name: name)
|
284
|
+
|
285
|
+
if entry.declarations.empty?
|
286
|
+
if name.is_a?(SingletonMethodName) && name.method_name == :new
|
287
|
+
initialize = InstanceMethodName.new(method_name: :initialize, type_name: name.type_name)
|
288
|
+
entry = index.entry(method_name: initialize)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
entry.declarations.each do |decl|
|
293
|
+
case decl
|
294
|
+
when RBS::AST::Members::MethodDefinition
|
295
|
+
locations << decl.location[:name]
|
296
|
+
when RBS::AST::Members::Alias
|
297
|
+
locations << decl.location[:new_name]
|
298
|
+
when RBS::AST::Members::AttrAccessor, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter
|
299
|
+
locations << decl.location[:name]
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
locations
|
306
|
+
end
|
307
|
+
|
308
|
+
def type_name_locations(name, locations: [])
|
309
|
+
type_check.signature_services.each_value do |signature|
|
310
|
+
index = signature.latest_rbs_index
|
311
|
+
|
312
|
+
entry = index.entry(type_name: name)
|
313
|
+
entry.declarations.each do |decl|
|
314
|
+
locations << decl.location[:name]
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
locations
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|