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