steep 0.28.0 → 0.32.0
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 +27 -0
- data/bin/steep-prof +1 -2
- data/lib/steep.rb +5 -3
- data/lib/steep/annotation_parser.rb +2 -4
- data/lib/steep/ast/builtin.rb +9 -1
- data/lib/steep/ast/types/factory.rb +177 -53
- data/lib/steep/ast/types/logic.rb +63 -0
- data/lib/steep/interface/method_type.rb +14 -4
- data/lib/steep/module_helper.rb +25 -0
- data/lib/steep/project.rb +25 -0
- data/lib/steep/project/completion_provider.rb +57 -58
- data/lib/steep/project/file_loader.rb +7 -2
- data/lib/steep/project/hover_content.rb +92 -83
- data/lib/steep/project/signature_file.rb +33 -0
- data/lib/steep/project/{file.rb → source_file.rb} +24 -54
- data/lib/steep/project/target.rb +31 -12
- data/lib/steep/server/code_worker.rb +30 -46
- data/lib/steep/server/interaction_worker.rb +42 -38
- data/lib/steep/server/master.rb +13 -30
- data/lib/steep/server/utils.rb +46 -13
- data/lib/steep/server/worker_process.rb +4 -2
- data/lib/steep/signature/validator.rb +3 -3
- data/lib/steep/source.rb +58 -1
- data/lib/steep/subtyping/check.rb +5 -7
- data/lib/steep/subtyping/constraints.rb +8 -0
- data/lib/steep/type_construction.rb +204 -207
- data/lib/steep/type_inference/constant_env.rb +2 -5
- data/lib/steep/type_inference/logic_type_interpreter.rb +225 -0
- data/lib/steep/type_inference/type_env.rb +2 -2
- data/lib/steep/version.rb +1 -1
- data/smoke/toplevel/Steepfile +5 -0
- data/smoke/toplevel/a.rb +4 -0
- data/smoke/toplevel/a.rbs +3 -0
- data/smoke/type_case/a.rb +0 -7
- data/steep.gemspec +2 -2
- metadata +18 -14
- data/lib/steep/ast/method_type.rb +0 -126
- data/lib/steep/ast/namespace.rb +0 -80
- data/lib/steep/names.rb +0 -86
@@ -0,0 +1,63 @@
|
|
1
|
+
module Steep
|
2
|
+
module AST
|
3
|
+
module Types
|
4
|
+
module Logic
|
5
|
+
class Base
|
6
|
+
attr_reader :location
|
7
|
+
|
8
|
+
def subst(s)
|
9
|
+
self
|
10
|
+
end
|
11
|
+
|
12
|
+
def free_variables
|
13
|
+
@fvs ||= Set[]
|
14
|
+
end
|
15
|
+
|
16
|
+
def hash
|
17
|
+
self.class.hash
|
18
|
+
end
|
19
|
+
|
20
|
+
def ==(other)
|
21
|
+
other.class ==self.class
|
22
|
+
end
|
23
|
+
|
24
|
+
alias eql? ==
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"<% #{self.class} %>"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class Not < Base
|
32
|
+
def initialize(location: nil)
|
33
|
+
@location = location
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class ReceiverIsNil < Base
|
38
|
+
def initialize(location: nil)
|
39
|
+
@location = location
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class ReceiverIsNotNil < Base
|
44
|
+
def initialize(location: nil)
|
45
|
+
@location = location
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
class ReceiverIsArg < Base
|
50
|
+
def initialize(location: nil)
|
51
|
+
@location = location
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class ArgIsReceiver < Base
|
56
|
+
def initialize(location: nil)
|
57
|
+
@location = location
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -775,13 +775,15 @@ module Steep
|
|
775
775
|
attr_reader :block
|
776
776
|
attr_reader :return_type
|
777
777
|
attr_reader :location
|
778
|
+
attr_reader :method_def
|
778
779
|
|
779
|
-
def initialize(type_params:, params:, block:, return_type:, location:)
|
780
|
+
def initialize(type_params:, params:, block:, return_type:, location:, method_def:)
|
780
781
|
@type_params = type_params
|
781
782
|
@params = params
|
782
783
|
@block = block
|
783
784
|
@return_type = return_type
|
784
785
|
@location = location
|
786
|
+
@method_def = method_def
|
785
787
|
end
|
786
788
|
|
787
789
|
def ==(other)
|
@@ -790,6 +792,7 @@ module Steep
|
|
790
792
|
other.params == params &&
|
791
793
|
other.block == block &&
|
792
794
|
other.return_type == return_type &&
|
795
|
+
(!other.method_def || !method_def || other.method_def == method_def) &&
|
793
796
|
(!other.location || !location || other.location == location)
|
794
797
|
end
|
795
798
|
|
@@ -821,6 +824,7 @@ module Steep
|
|
821
824
|
params: params.subst(s_),
|
822
825
|
block: block&.subst(s_),
|
823
826
|
return_type: return_type.subst(s_),
|
827
|
+
method_def: method_def,
|
824
828
|
location: location
|
825
829
|
)
|
826
830
|
end
|
@@ -843,14 +847,16 @@ module Steep
|
|
843
847
|
params: params.subst(s),
|
844
848
|
block: block&.subst(s),
|
845
849
|
return_type: return_type.subst(s),
|
846
|
-
location: location
|
850
|
+
location: location,
|
851
|
+
method_def: method_def)
|
847
852
|
end
|
848
853
|
|
849
|
-
def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, location: self.location)
|
854
|
+
def with(type_params: self.type_params, params: self.params, block: self.block, return_type: self.return_type, location: self.location, method_def: self.method_def)
|
850
855
|
self.class.new(type_params: type_params,
|
851
856
|
params: params,
|
852
857
|
block: block,
|
853
858
|
return_type: return_type,
|
859
|
+
method_def: method_def,
|
854
860
|
location: location)
|
855
861
|
end
|
856
862
|
|
@@ -867,7 +873,8 @@ module Steep
|
|
867
873
|
params: params.map_type(&block),
|
868
874
|
block: self.block&.yield_self {|blk| blk.map_type(&block) },
|
869
875
|
return_type: yield(return_type),
|
870
|
-
location: location
|
876
|
+
location: location,
|
877
|
+
method_def: method_def)
|
871
878
|
end
|
872
879
|
|
873
880
|
# Returns a new method type which can be used for the method implementation type of both `self` and `other`.
|
@@ -895,6 +902,7 @@ module Steep
|
|
895
902
|
return_type: AST::Types::Union.build(
|
896
903
|
types: [return_type.subst(s1),other.return_type.subst(s2)]
|
897
904
|
),
|
905
|
+
method_def: method_def,
|
898
906
|
location: nil
|
899
907
|
)
|
900
908
|
end
|
@@ -950,6 +958,7 @@ module Steep
|
|
950
958
|
block: block,
|
951
959
|
return_type: return_type,
|
952
960
|
type_params: type_params,
|
961
|
+
method_def: nil,
|
953
962
|
location: nil
|
954
963
|
)
|
955
964
|
end
|
@@ -997,6 +1006,7 @@ module Steep
|
|
997
1006
|
block: block,
|
998
1007
|
return_type: return_type,
|
999
1008
|
type_params: type_params,
|
1009
|
+
method_def: nil,
|
1000
1010
|
location: nil
|
1001
1011
|
)
|
1002
1012
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Steep
|
2
|
+
module ModuleHelper
|
3
|
+
def module_name_from_node(node)
|
4
|
+
case node.type
|
5
|
+
when :const, :casgn
|
6
|
+
namespace = namespace_from_node(node.children[0]) or return
|
7
|
+
name = node.children[1]
|
8
|
+
RBS::TypeName.new(name: name, namespace: namespace)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def namespace_from_node(node)
|
13
|
+
case node&.type
|
14
|
+
when nil
|
15
|
+
RBS::Namespace.empty
|
16
|
+
when :cbase
|
17
|
+
RBS::Namespace.root
|
18
|
+
when :const
|
19
|
+
namespace_from_node(node.children[0])&.yield_self do |parent|
|
20
|
+
parent.append(node.children[1])
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/steep/project.rb
CHANGED
@@ -24,6 +24,31 @@ module Steep
|
|
24
24
|
(base_dir + path).cleanpath
|
25
25
|
end
|
26
26
|
|
27
|
+
def target_for_source_path(path)
|
28
|
+
targets.find do |target|
|
29
|
+
target.possible_source_file?(path)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def targets_for_path(path)
|
34
|
+
if target = target_for_source_path(path)
|
35
|
+
[target, []]
|
36
|
+
else
|
37
|
+
[
|
38
|
+
nil,
|
39
|
+
targets.select do |target|
|
40
|
+
target.possible_signature_file?(path)
|
41
|
+
end
|
42
|
+
]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def all_source_files
|
47
|
+
targets.each.with_object(Set[]) do |target, paths|
|
48
|
+
paths.merge(target.source_files.keys)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
27
52
|
def type_of_node(path:, line:, column:)
|
28
53
|
source_file = targets.map {|target| target.source_files[path] }.compact[0]
|
29
54
|
|
@@ -10,13 +10,9 @@ module Steep
|
|
10
10
|
|
11
11
|
InstanceVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
12
12
|
LocalVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
13
|
-
MethodNameItem = Struct.new(:identifier, :range, :
|
14
|
-
def method_type
|
15
|
-
def_type.type
|
16
|
-
end
|
17
|
-
|
13
|
+
MethodNameItem = Struct.new(:identifier, :range, :method_def, :method_type, :inherited_method, keyword_init: true) do
|
18
14
|
def comment
|
19
|
-
|
15
|
+
method_def&.comment
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
@@ -33,11 +29,13 @@ module Steep
|
|
33
29
|
@subtyping = subtyping
|
34
30
|
end
|
35
31
|
|
36
|
-
def type_check!(text)
|
32
|
+
def type_check!(text, line:, column:)
|
37
33
|
@modified_text = text
|
38
34
|
|
39
35
|
Steep.measure "parsing" do
|
40
|
-
@source = SourceFile
|
36
|
+
@source = SourceFile
|
37
|
+
.parse(text, path: path, factory: subtyping.factory)
|
38
|
+
.without_unrelated_defs(line: line, column: column)
|
41
39
|
end
|
42
40
|
|
43
41
|
Steep.measure "typechecking" do
|
@@ -57,7 +55,7 @@ module Steep
|
|
57
55
|
begin
|
58
56
|
Steep.logger.tagged "completion_provider#run(line: #{line}, column: #{column})" do
|
59
57
|
Steep.measure "type_check!" do
|
60
|
-
type_check!(source_text)
|
58
|
+
type_check!(source_text, line: line, column: column)
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
@@ -70,11 +68,11 @@ module Steep
|
|
70
68
|
case possible_trigger
|
71
69
|
when "."
|
72
70
|
source_text[index-1] = " "
|
73
|
-
type_check!(source_text)
|
71
|
+
type_check!(source_text, line: line, column: column)
|
74
72
|
items_for_dot(position: position)
|
75
73
|
when "@"
|
76
74
|
source_text[index-1] = " "
|
77
|
-
type_check!(source_text)
|
75
|
+
type_check!(source_text, line: line, column: column)
|
78
76
|
items_for_atmark(position: position)
|
79
77
|
else
|
80
78
|
[]
|
@@ -90,7 +88,9 @@ module Steep
|
|
90
88
|
end
|
91
89
|
|
92
90
|
def at_end?(pos, of:)
|
93
|
-
|
91
|
+
if of
|
92
|
+
of.last_line == pos.line && of.last_column == pos.column
|
93
|
+
end
|
94
94
|
end
|
95
95
|
|
96
96
|
def range_for(position, prefix: "")
|
@@ -194,21 +194,25 @@ module Steep
|
|
194
194
|
return [] unless node
|
195
195
|
|
196
196
|
if at_end?(shift_pos, of: node.loc)
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
197
|
+
begin
|
198
|
+
context = typing.context_at(line: position.line, column: position.column)
|
199
|
+
receiver_type = case (type = typing.type_of(node: node))
|
200
|
+
when AST::Types::Self
|
201
|
+
context.self_type
|
202
|
+
else
|
203
|
+
type
|
204
|
+
end
|
205
|
+
|
206
|
+
items = []
|
207
|
+
method_items_for_receiver_type(receiver_type,
|
208
|
+
include_private: false,
|
209
|
+
prefix: "",
|
210
|
+
position: position,
|
211
|
+
items: items)
|
212
|
+
items
|
213
|
+
rescue Typing::UnknownNodeError
|
214
|
+
[]
|
215
|
+
end
|
212
216
|
else
|
213
217
|
[]
|
214
218
|
end
|
@@ -217,50 +221,40 @@ module Steep
|
|
217
221
|
def items_for_atmark(position:)
|
218
222
|
# @ ←
|
219
223
|
shift_pos = position-1
|
220
|
-
node, *
|
224
|
+
node, *_ = source.find_nodes(line: shift_pos.line, column: shift_pos.column)
|
221
225
|
node ||= source.node
|
222
226
|
|
223
227
|
return [] unless node
|
224
228
|
|
225
229
|
context = typing.context_at(line: position.line, column: position.column)
|
226
230
|
items = []
|
227
|
-
instance_variable_items_for_context(context, prefix: "", position: position, items: items)
|
231
|
+
instance_variable_items_for_context(context, prefix: "@", position: position, items: items)
|
228
232
|
items
|
229
233
|
end
|
230
234
|
|
231
235
|
def method_items_for_receiver_type(type, include_private:, prefix:, position:, items:)
|
232
236
|
range = range_for(position, prefix: prefix)
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
if include_private || method.public?
|
250
|
-
if name.to_s.start_with?(prefix)
|
251
|
-
if word_name?(name.to_s)
|
252
|
-
method.defs.each do |def_type|
|
253
|
-
items << MethodNameItem.new(identifier: name,
|
254
|
-
range: range,
|
255
|
-
definition: method,
|
256
|
-
def_type: def_type,
|
257
|
-
inherited_method: inherited_method?(method, definition))
|
258
|
-
end
|
259
|
-
end
|
237
|
+
interface = subtyping.factory.interface(type, self_type: type, private: include_private)
|
238
|
+
|
239
|
+
interface.methods.each do |name, method_entry|
|
240
|
+
next if disallowed_method?(name)
|
241
|
+
|
242
|
+
if name.to_s.start_with?(prefix)
|
243
|
+
if word_name?(name.to_s)
|
244
|
+
method_entry.method_types.each do |method_type|
|
245
|
+
items << MethodNameItem.new(
|
246
|
+
identifier: name,
|
247
|
+
range: range,
|
248
|
+
method_def: method_type.method_def,
|
249
|
+
method_type: method_type.method_def&.type || subtyping.factory.method_type_1(method_type, self_type: type),
|
250
|
+
inherited_method: inherited_method?(method_type.method_def, type)
|
251
|
+
)
|
260
252
|
end
|
261
253
|
end
|
262
254
|
end
|
263
255
|
end
|
256
|
+
rescue
|
257
|
+
# nop
|
264
258
|
end
|
265
259
|
|
266
260
|
def word_name?(name)
|
@@ -304,8 +298,13 @@ module Steep
|
|
304
298
|
index
|
305
299
|
end
|
306
300
|
|
307
|
-
def inherited_method?(
|
308
|
-
|
301
|
+
def inherited_method?(method_def, type)
|
302
|
+
case type
|
303
|
+
when AST::Types::Name::Instance, AST::Types::Name::Singleton, AST::Types::Name::Interface
|
304
|
+
method_def.implemented_in != type.name
|
305
|
+
else
|
306
|
+
false
|
307
|
+
end
|
309
308
|
end
|
310
309
|
|
311
310
|
def disallowed_method?(name)
|
@@ -28,15 +28,20 @@ module Steep
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def load_sources(command_line_patterns)
|
31
|
+
loaded_paths = Set[]
|
32
|
+
|
31
33
|
project.targets.each do |target|
|
32
34
|
Steep.logger.tagged "target=#{target.name}" do
|
33
35
|
target_patterns = command_line_patterns.empty? ? target.source_patterns : command_line_patterns
|
34
36
|
|
35
|
-
each_path_in_patterns
|
37
|
+
each_path_in_patterns(target_patterns, ".rb") do |path|
|
36
38
|
if target.possible_source_file?(path)
|
37
|
-
|
39
|
+
if loaded_paths.include?(path)
|
40
|
+
Steep.logger.warn { "Skipping #{target} while loading #{path}... (Already loaded to another target.)" }
|
41
|
+
else
|
38
42
|
Steep.logger.info { "Adding source file: #{path}" }
|
39
43
|
target.add_source path, project.absolute_path(path).read
|
44
|
+
loaded_paths << path
|
40
45
|
end
|
41
46
|
end
|
42
47
|
end
|
@@ -21,9 +21,7 @@ module Steep
|
|
21
21
|
@project = project
|
22
22
|
end
|
23
23
|
|
24
|
-
def method_definition_for(factory,
|
25
|
-
type_name = factory.type_name_1(module_name)
|
26
|
-
|
24
|
+
def method_definition_for(factory, type_name, singleton_method: nil, instance_method: nil)
|
27
25
|
case
|
28
26
|
when instance_method
|
29
27
|
factory.definition_builder.build_instance(type_name).methods[instance_method]
|
@@ -38,102 +36,113 @@ module Steep
|
|
38
36
|
end
|
39
37
|
end
|
40
38
|
|
39
|
+
def typecheck(target, path:, line:, column:)
|
40
|
+
target.type_check(target_sources: [], validate_signatures: false)
|
41
|
+
|
42
|
+
case (status = target.status)
|
43
|
+
when Project::Target::TypeCheckStatus
|
44
|
+
subtyping = status.subtyping
|
45
|
+
source = SourceFile
|
46
|
+
.parse(target.source_files[path].content, path: path, factory: subtyping.factory)
|
47
|
+
.without_unrelated_defs(line: line, column: column)
|
48
|
+
SourceFile.type_check(source, subtyping: subtyping)
|
49
|
+
end
|
50
|
+
rescue
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
|
41
54
|
def content_for(path:, line:, column:)
|
42
|
-
target = project.
|
55
|
+
target = project.target_for_source_path(path)
|
43
56
|
|
44
57
|
if target
|
45
|
-
|
46
|
-
|
58
|
+
typing = typecheck(target, path: path, line: line, column: column) or return
|
59
|
+
|
60
|
+
node, *parents = typing.source.find_nodes(line: line, column: column)
|
47
61
|
|
48
|
-
|
49
|
-
|
50
|
-
|
62
|
+
if node
|
63
|
+
case node.type
|
64
|
+
when :lvar
|
65
|
+
var_name = node.children[0]
|
66
|
+
context = typing.context_at(line: line, column: column)
|
67
|
+
var_type = context.lvar_env[var_name.name] || AST::Types::Any.new(location: nil)
|
51
68
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
var_type = context.lvar_env[var_name.name] || AST::Types::Any.new(location: nil)
|
69
|
+
VariableContent.new(node: node, name: var_name.name, type: var_type, location: node.location.name)
|
70
|
+
when :lvasgn
|
71
|
+
var_name, rhs = node.children
|
72
|
+
context = typing.context_at(line: line, column: column)
|
73
|
+
type = context.lvar_env[var_name.name] || typing.type_of(node: rhs)
|
58
74
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
context = status.typing.context_at(line: line, column: column)
|
63
|
-
type = context.lvar_env[var_name.name] || status.typing.type_of(node: rhs)
|
75
|
+
VariableContent.new(node: node, name: var_name.name, type: type, location: node.location.name)
|
76
|
+
when :send
|
77
|
+
receiver, method_name, *_ = node.children
|
64
78
|
|
65
|
-
VariableContent.new(node: node, name: var_name.name, type: type, location: node.location.name)
|
66
|
-
when :send
|
67
|
-
receiver, method_name, *_ = node.children
|
68
79
|
|
80
|
+
result_node = if parents[0]&.type == :block
|
81
|
+
parents[0]
|
82
|
+
else
|
83
|
+
node
|
84
|
+
end
|
69
85
|
|
70
|
-
|
71
|
-
|
86
|
+
context = typing.context_at(line: line, column: column)
|
87
|
+
|
88
|
+
receiver_type = if receiver
|
89
|
+
typing.type_of(node: receiver)
|
72
90
|
else
|
73
|
-
|
91
|
+
context.self_type
|
74
92
|
end
|
75
93
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
when AST::Types::Name::Instance
|
87
|
-
method_definition = method_definition_for(factory, receiver_type.name, instance_method: method_name)
|
88
|
-
if method_definition&.defined_in
|
89
|
-
owner_name = factory.type_name(method_definition.defined_in)
|
90
|
-
[
|
91
|
-
InstanceMethodName.new(owner_name, method_name),
|
92
|
-
method_definition
|
93
|
-
]
|
94
|
-
end
|
95
|
-
when AST::Types::Name::Singleton
|
96
|
-
method_definition = method_definition_for(factory, receiver_type.name, singleton_method: method_name)
|
97
|
-
if method_definition&.defined_in
|
98
|
-
owner_name = factory.type_name(method_definition.defined_in)
|
99
|
-
[
|
100
|
-
SingletonMethodName.new(owner_name, method_name),
|
101
|
-
method_definition
|
102
|
-
]
|
103
|
-
end
|
104
|
-
else
|
105
|
-
nil
|
94
|
+
factory = context.type_env.subtyping.factory
|
95
|
+
method_name, definition = case receiver_type
|
96
|
+
when AST::Types::Name::Instance
|
97
|
+
method_definition = method_definition_for(factory, receiver_type.name, instance_method: method_name)
|
98
|
+
if method_definition&.defined_in
|
99
|
+
owner_name = method_definition.defined_in
|
100
|
+
[
|
101
|
+
InstanceMethodName.new(owner_name, method_name),
|
102
|
+
method_definition
|
103
|
+
]
|
106
104
|
end
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
105
|
+
when AST::Types::Name::Singleton
|
106
|
+
method_definition = method_definition_for(factory, receiver_type.name, singleton_method: method_name)
|
107
|
+
if method_definition&.defined_in
|
108
|
+
owner_name = method_definition.defined_in
|
109
|
+
[
|
110
|
+
SingletonMethodName.new(owner_name, method_name),
|
111
|
+
method_definition
|
112
|
+
]
|
113
|
+
end
|
114
|
+
else
|
115
|
+
nil
|
116
|
+
end
|
117
|
+
|
118
|
+
MethodCallContent.new(
|
119
|
+
node: node,
|
120
|
+
method_name: method_name,
|
121
|
+
type: typing.type_of(node: result_node),
|
122
|
+
definition: definition,
|
123
|
+
location: result_node.location.expression
|
124
|
+
)
|
125
|
+
when :def, :defs
|
126
|
+
context = typing.context_at(line: line, column: column)
|
127
|
+
method_context = context.method_context
|
128
|
+
|
129
|
+
if method_context && method_context.method
|
130
|
+
DefinitionContent.new(
|
132
131
|
node: node,
|
133
|
-
|
134
|
-
|
132
|
+
method_name: method_context.name,
|
133
|
+
method_type: method_context.method_type,
|
134
|
+
definition: method_context.method,
|
135
|
+
location: node.loc.expression
|
135
136
|
)
|
136
137
|
end
|
138
|
+
else
|
139
|
+
type = typing.type_of(node: node)
|
140
|
+
|
141
|
+
TypeContent.new(
|
142
|
+
node: node,
|
143
|
+
type: type,
|
144
|
+
location: node.location.expression
|
145
|
+
)
|
137
146
|
end
|
138
147
|
end
|
139
148
|
end
|