typeprof 0.32.0 → 0.33.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/lib/typeprof/core/ast/base.rb +13 -0
- data/lib/typeprof/core/ast/call.rb +47 -30
- data/lib/typeprof/core/ast/const.rb +15 -7
- data/lib/typeprof/core/ast/control.rb +2 -2
- data/lib/typeprof/core/ast/meta.rb +96 -23
- data/lib/typeprof/core/ast/method.rb +18 -14
- data/lib/typeprof/core/ast/misc.rb +16 -7
- data/lib/typeprof/core/ast/module.rb +6 -2
- data/lib/typeprof/core/ast/pattern.rb +51 -23
- data/lib/typeprof/core/ast/sig_decl.rb +57 -4
- data/lib/typeprof/core/ast/sig_type.rb +36 -1
- data/lib/typeprof/core/ast/variable.rb +6 -0
- data/lib/typeprof/core/ast.rb +3 -0
- data/lib/typeprof/core/env/method.rb +192 -20
- data/lib/typeprof/core/env/module_entity.rb +61 -1
- data/lib/typeprof/core/env.rb +34 -6
- data/lib/typeprof/core/graph/box.rb +135 -17
- data/lib/typeprof/core/graph/change_set.rb +11 -6
- data/lib/typeprof/core/service.rb +24 -2
- data/lib/typeprof/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8dc7b580d84d82c2a49d4a2d24ddf32ddcafc938d4f9511fc4b6d4543f0b8e19
|
|
4
|
+
data.tar.gz: eed64be210440c2ea2627a7b21c95c7eedee374b760e9e6aa479dfa4c27df54f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b314eccaecb06cac94df1af7ab96084b06d1d70710c9ece6934c98ca5379ca98e82ab93838322081357d13c0200681beb24d6108f699aac4a8904952333a7d83
|
|
7
|
+
data.tar.gz: 7ebcd55f8c8d91b1eac583c7d585723de31a83da5fa85c7485cda77e520e24d09f1652b1dde7657db62c8151166cbfdc71d3563647ccd60871bb31e74fc6055a
|
|
@@ -118,6 +118,19 @@ module TypeProf::Core
|
|
|
118
118
|
raise "should override"
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
# Counterpart of install/install0 for pattern position; reuses the install
|
|
122
|
+
# machinery so @changes is reconciled the same way during incremental analysis.
|
|
123
|
+
def install_pattern(genv, subject)
|
|
124
|
+
@ret = install_pattern0(genv, subject)
|
|
125
|
+
@changes.reinstall(genv)
|
|
126
|
+
@ret
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# By default a pattern behaves as a plain expression, ignoring the matched value.
|
|
130
|
+
def install_pattern0(genv, subject)
|
|
131
|
+
install0(genv)
|
|
132
|
+
end
|
|
133
|
+
|
|
121
134
|
def uninstall(genv)
|
|
122
135
|
@changes.reinstall(genv)
|
|
123
136
|
each_subnode do |subnode|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
module TypeProf::Core
|
|
2
2
|
class AST
|
|
3
3
|
class CallBaseNode < Node
|
|
4
|
-
def initialize(raw_node, recv, mid,
|
|
4
|
+
def initialize(raw_node, recv, mid, mid_code_range_loc, raw_args, last_arg, raw_block, lenv, forwarding_arguments: false)
|
|
5
5
|
super(raw_node, lenv)
|
|
6
6
|
|
|
7
7
|
@recv = recv
|
|
8
8
|
@mid = mid
|
|
9
|
-
@
|
|
9
|
+
@mid_code_range_loc = mid_code_range_loc
|
|
10
10
|
|
|
11
11
|
# args
|
|
12
12
|
@positional_args = []
|
|
@@ -31,7 +31,7 @@ module TypeProf::Core
|
|
|
31
31
|
args << raw_arg.expression
|
|
32
32
|
@splat_flags << true
|
|
33
33
|
when Prism::ForwardingArgumentsNode
|
|
34
|
-
@forwarding_arguments =
|
|
34
|
+
@forwarding_arguments = :rest
|
|
35
35
|
else
|
|
36
36
|
args << raw_arg
|
|
37
37
|
@splat_flags << false
|
|
@@ -60,17 +60,24 @@ module TypeProf::Core
|
|
|
60
60
|
@block_multi_targets = {}
|
|
61
61
|
@block_f_args = case raw_block.parameters
|
|
62
62
|
when Prism::BlockParametersNode
|
|
63
|
+
# `{ || ... }` (empty pipes) and `{ |; x| ... }`
|
|
64
|
+
# (block-local-only) yield BlockParametersNode
|
|
65
|
+
# whose inner `parameters` is nil.
|
|
63
66
|
params = raw_block.parameters.parameters
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
if params
|
|
68
|
+
req = params.requireds.each_with_index.map do |n, i|
|
|
69
|
+
if n.is_a?(Prism::MultiTargetNode)
|
|
70
|
+
@block_multi_targets[i] = n
|
|
71
|
+
nil
|
|
72
|
+
else
|
|
73
|
+
n.name
|
|
74
|
+
end
|
|
70
75
|
end
|
|
76
|
+
opt = params.optionals.map {|n| n.name }
|
|
77
|
+
req + opt
|
|
78
|
+
else
|
|
79
|
+
[]
|
|
71
80
|
end
|
|
72
|
-
opt = params.optionals.map {|n| n.name }
|
|
73
|
-
req + opt
|
|
74
81
|
when Prism::NumberedParametersNode
|
|
75
82
|
1.upto(raw_block.parameters.maximum).map { |n| :"_#{n}" }
|
|
76
83
|
when Prism::ItParametersNode
|
|
@@ -83,7 +90,7 @@ module TypeProf::Core
|
|
|
83
90
|
ncref = CRef.new(lenv.cref.cpath, :instance, @mid, lenv.cref)
|
|
84
91
|
nlenv = LocalEnv.new(@lenv.file_context, ncref, {}, @lenv.return_boxes)
|
|
85
92
|
@block_opt_positional_defaults = []
|
|
86
|
-
if raw_block.parameters.is_a?(Prism::BlockParametersNode)
|
|
93
|
+
if raw_block.parameters.is_a?(Prism::BlockParametersNode) && raw_block.parameters.parameters
|
|
87
94
|
raw_block.parameters.parameters.optionals.each do |n|
|
|
88
95
|
@block_opt_positional_defaults << AST.create_node(n.value, nlenv)
|
|
89
96
|
end
|
|
@@ -95,7 +102,11 @@ module TypeProf::Core
|
|
|
95
102
|
@yield = raw_node.type == :yield_node
|
|
96
103
|
end
|
|
97
104
|
|
|
98
|
-
attr_reader :recv, :mid, :
|
|
105
|
+
attr_reader :recv, :mid, :yield
|
|
106
|
+
|
|
107
|
+
def mid_code_range
|
|
108
|
+
@mid_code_range ||= @lenv.code_range_from_node(@mid_code_range_loc) if @mid_code_range_loc
|
|
109
|
+
end
|
|
99
110
|
attr_reader :positional_args, :splat_flags, :keyword_args
|
|
100
111
|
attr_reader :block_tbl, :block_f_args, :block_opt_positional_defaults, :block_body, :block_pass, :anonymous_block_forwarding
|
|
101
112
|
attr_reader :block_multi_targets
|
|
@@ -113,10 +124,17 @@ module TypeProf::Core
|
|
|
113
124
|
end
|
|
114
125
|
|
|
115
126
|
if @forwarding_arguments
|
|
116
|
-
forward_a_args = (@lenv.forward_args || raise).to_actual_arguments(
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
127
|
+
forward_a_args = (@lenv.forward_args || raise).to_actual_arguments(
|
|
128
|
+
genv,
|
|
129
|
+
@changes,
|
|
130
|
+
self,
|
|
131
|
+
include_leading_positionals: @forwarding_arguments != :rest,
|
|
132
|
+
activation_required: @forwarding_arguments == :rest,
|
|
133
|
+
)
|
|
134
|
+
# An anonymous rest cannot appear here: `bar(*, ...)` is a syntax error
|
|
135
|
+
leading_args = @positional_args.map {|arg| arg.install(genv) }
|
|
136
|
+
a_args = forward_a_args.prepend_positionals(leading_args, @splat_flags)
|
|
137
|
+
a_args = a_args.with_keywords(@keyword_args.install(genv)) if @keyword_args
|
|
120
138
|
else
|
|
121
139
|
positional_args = @positional_args.map do |arg|
|
|
122
140
|
if arg.nil?
|
|
@@ -125,8 +143,7 @@ module TypeProf::Core
|
|
|
125
143
|
arg.install(genv)
|
|
126
144
|
end
|
|
127
145
|
end
|
|
128
|
-
|
|
129
|
-
keyword_args = @keyword_args ? @keyword_args.install(genv) : nil
|
|
146
|
+
a_args = ActualArguments.new(positional_args, @splat_flags, @keyword_args ? @keyword_args.install(genv) : nil, nil)
|
|
130
147
|
end
|
|
131
148
|
|
|
132
149
|
if @block_body
|
|
@@ -198,7 +215,11 @@ module TypeProf::Core
|
|
|
198
215
|
blk_ty = forward_a_args.block
|
|
199
216
|
end
|
|
200
217
|
|
|
201
|
-
|
|
218
|
+
if @forwarding_arguments
|
|
219
|
+
a_args = a_args.with_block(blk_ty, omittable: !@block_body && !@block_pass && !@anonymous_block_forwarding)
|
|
220
|
+
else
|
|
221
|
+
a_args = a_args.with_block(blk_ty)
|
|
222
|
+
end
|
|
202
223
|
box = @changes.add_method_call_box(genv, recv, @mid, a_args, !@recv)
|
|
203
224
|
|
|
204
225
|
block_body = @block_body
|
|
@@ -230,7 +251,7 @@ module TypeProf::Core
|
|
|
230
251
|
end
|
|
231
252
|
|
|
232
253
|
def retrieve_at(pos, &blk)
|
|
233
|
-
yield self if
|
|
254
|
+
yield self if mid_code_range&.include?(pos)
|
|
234
255
|
each_subnode do |subnode|
|
|
235
256
|
next unless subnode
|
|
236
257
|
subnode.retrieve_at(pos, &blk)
|
|
@@ -257,10 +278,9 @@ module TypeProf::Core
|
|
|
257
278
|
def initialize(raw_node, lenv)
|
|
258
279
|
recv = raw_node.receiver ? AST.create_node(raw_node.receiver, lenv) : nil
|
|
259
280
|
mid = raw_node.name
|
|
260
|
-
mid_code_range = lenv.code_range_from_node(raw_node.message_loc) if raw_node.message_loc
|
|
261
281
|
raw_args = raw_node.arguments
|
|
262
282
|
raw_block = raw_node.block
|
|
263
|
-
super(raw_node, recv, mid,
|
|
283
|
+
super(raw_node, recv, mid, raw_node.message_loc, raw_args, nil, raw_block, lenv)
|
|
264
284
|
end
|
|
265
285
|
|
|
266
286
|
def narrowings
|
|
@@ -317,7 +337,7 @@ module TypeProf::Core
|
|
|
317
337
|
def initialize(raw_node, lenv)
|
|
318
338
|
raw_args = nil
|
|
319
339
|
raw_block = raw_node.block
|
|
320
|
-
super(raw_node, nil, :"*super", nil, raw_args, nil, raw_block, lenv, forwarding_arguments:
|
|
340
|
+
super(raw_node, nil, :"*super", nil, raw_args, nil, raw_block, lenv, forwarding_arguments: :all)
|
|
321
341
|
end
|
|
322
342
|
end
|
|
323
343
|
|
|
@@ -331,9 +351,8 @@ module TypeProf::Core
|
|
|
331
351
|
class OperatorNode < CallBaseNode
|
|
332
352
|
def initialize(raw_node, recv, lenv)
|
|
333
353
|
mid = raw_node.binary_operator
|
|
334
|
-
mid_code_range = lenv.code_range_from_node(raw_node.binary_operator_loc)
|
|
335
354
|
last_arg = AST.create_node(raw_node.value, lenv)
|
|
336
|
-
super(raw_node, recv, mid,
|
|
355
|
+
super(raw_node, recv, mid, raw_node.binary_operator_loc, nil, last_arg, nil, lenv)
|
|
337
356
|
end
|
|
338
357
|
end
|
|
339
358
|
|
|
@@ -364,8 +383,7 @@ module TypeProf::Core
|
|
|
364
383
|
def initialize(raw_node, lenv)
|
|
365
384
|
recv = AST.create_node(raw_node.receiver, lenv)
|
|
366
385
|
mid = raw_node.read_name
|
|
367
|
-
|
|
368
|
-
super(raw_node, recv, mid, mid_code_range, nil, nil, nil, lenv)
|
|
386
|
+
super(raw_node, recv, mid, raw_node.message_loc, nil, nil, nil, lenv)
|
|
369
387
|
end
|
|
370
388
|
end
|
|
371
389
|
|
|
@@ -373,9 +391,8 @@ module TypeProf::Core
|
|
|
373
391
|
def initialize(raw_node, rhs, lenv)
|
|
374
392
|
recv = AST.create_node(raw_node.receiver, lenv)
|
|
375
393
|
mid = raw_node.is_a?(Prism::CallTargetNode) ? raw_node.name : raw_node.write_name
|
|
376
|
-
mid_code_range = lenv.code_range_from_node(raw_node.message_loc)
|
|
377
394
|
@rhs = rhs
|
|
378
|
-
super(raw_node, recv, mid,
|
|
395
|
+
super(raw_node, recv, mid, raw_node.message_loc, nil, rhs, nil, lenv)
|
|
379
396
|
end
|
|
380
397
|
|
|
381
398
|
attr_reader :rhs
|
|
@@ -8,7 +8,7 @@ module TypeProf::Core
|
|
|
8
8
|
@cbase = nil
|
|
9
9
|
@toplevel = false
|
|
10
10
|
@cname = raw_node.name
|
|
11
|
-
@
|
|
11
|
+
@cname_code_range_loc = raw_node.location
|
|
12
12
|
when :constant_path_node, :constant_path_target_node
|
|
13
13
|
if raw_node.parent
|
|
14
14
|
@cbase = AST.create_node(raw_node.parent, lenv)
|
|
@@ -18,14 +18,18 @@ module TypeProf::Core
|
|
|
18
18
|
@toplevel = true
|
|
19
19
|
end
|
|
20
20
|
@cname = raw_node.name
|
|
21
|
-
@
|
|
21
|
+
@cname_code_range_loc = raw_node.name_loc
|
|
22
22
|
else
|
|
23
23
|
raise raw_node.type.to_s
|
|
24
24
|
end
|
|
25
25
|
@strict_const_scope = lenv.strict_const_scope
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
attr_reader :cname, :cbase, :toplevel, :
|
|
28
|
+
attr_reader :cname, :cbase, :toplevel, :strict_const_scope
|
|
29
|
+
|
|
30
|
+
def cname_code_range
|
|
31
|
+
@cname_code_range ||= @lenv.code_range_from_node(@cname_code_range_loc) if @cname_code_range_loc
|
|
32
|
+
end
|
|
29
33
|
|
|
30
34
|
def attrs = { cname:, toplevel:, strict_const_scope: }
|
|
31
35
|
def subnodes = { cbase: }
|
|
@@ -57,24 +61,28 @@ module TypeProf::Core
|
|
|
57
61
|
# C = expr
|
|
58
62
|
@cpath = nil
|
|
59
63
|
@static_cpath = lenv.cref.cpath + [raw_node.name]
|
|
60
|
-
@
|
|
64
|
+
@cname_code_range_loc = raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node.location
|
|
61
65
|
when :constant_path_write_node, :constant_path_operator_write_node, :constant_path_or_write_node, :constant_path_and_write_node
|
|
62
66
|
# expr::C = expr
|
|
63
67
|
@cpath = AST.create_node(raw_node.target, lenv)
|
|
64
68
|
@static_cpath = AST.parse_cpath(raw_node.target, lenv.cref)
|
|
65
|
-
@
|
|
69
|
+
@cname_code_range_loc = raw_node.target.location
|
|
66
70
|
when :constant_path_target_node
|
|
67
71
|
# expr::C, * = ary
|
|
68
72
|
@cpath = ConstantReadNode.new(raw_node, lenv)
|
|
69
73
|
@static_cpath = AST.parse_cpath(raw_node, lenv.cref)
|
|
70
|
-
@
|
|
74
|
+
@cname_code_range_loc = raw_node.location
|
|
71
75
|
else
|
|
72
76
|
raise
|
|
73
77
|
end
|
|
74
78
|
@rhs = rhs
|
|
75
79
|
end
|
|
76
80
|
|
|
77
|
-
attr_reader :cpath, :rhs, :static_cpath
|
|
81
|
+
attr_reader :cpath, :rhs, :static_cpath
|
|
82
|
+
|
|
83
|
+
def cname_code_range
|
|
84
|
+
@cname_code_range ||= @lenv.code_range_from_node(@cname_code_range_loc) if @cname_code_range_loc
|
|
85
|
+
end
|
|
78
86
|
|
|
79
87
|
def subnodes = { cpath:, rhs: }
|
|
80
88
|
def attrs = { static_cpath: }
|
|
@@ -414,9 +414,9 @@ module TypeProf::Core
|
|
|
414
414
|
|
|
415
415
|
def install0(genv)
|
|
416
416
|
ret = Vertex.new(self)
|
|
417
|
-
@pivot
|
|
417
|
+
subject = @pivot ? @pivot.install(genv) : Source.new(genv.nil_type)
|
|
418
418
|
@patterns.zip(@clauses) do |pattern, clause|
|
|
419
|
-
pattern.
|
|
419
|
+
pattern.install_pattern(genv, subject)
|
|
420
420
|
@changes.add_edge(genv, clause.install(genv), ret)
|
|
421
421
|
end
|
|
422
422
|
@changes.add_edge(genv, @else_clause.install(genv), ret) if @else_clause
|
|
@@ -46,9 +46,56 @@ module TypeProf::Core
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
class ExtendMetaNode < Node
|
|
50
|
+
def initialize(raw_node, lenv)
|
|
51
|
+
super(raw_node, lenv)
|
|
52
|
+
# TODO: error for splat
|
|
53
|
+
@args = raw_node.arguments.arguments.map do |raw_arg|
|
|
54
|
+
next if raw_arg.is_a?(Prism::SplatNode)
|
|
55
|
+
lenv.use_strict_const_scope do
|
|
56
|
+
AST.create_node(raw_arg, lenv)
|
|
57
|
+
end
|
|
58
|
+
end.compact
|
|
59
|
+
# TODO: error for non-LIT
|
|
60
|
+
# TODO: fine-grained hover
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
attr_reader :args
|
|
64
|
+
|
|
65
|
+
def subnodes = { args: }
|
|
66
|
+
|
|
67
|
+
def define0(genv)
|
|
68
|
+
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
69
|
+
@args.each do |arg|
|
|
70
|
+
arg.define(genv)
|
|
71
|
+
if arg.static_ret
|
|
72
|
+
arg.static_ret.followers << mod
|
|
73
|
+
mod.add_extend_def(genv, arg)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def undefine0(genv)
|
|
79
|
+
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
80
|
+
@args.each do |arg|
|
|
81
|
+
if arg.static_ret
|
|
82
|
+
mod.remove_extend_def(genv, arg)
|
|
83
|
+
end
|
|
84
|
+
arg.undefine(genv)
|
|
85
|
+
end
|
|
86
|
+
super(genv)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def install0(genv)
|
|
90
|
+
@args.each {|arg| arg.install(genv) }
|
|
91
|
+
Source.new
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
49
95
|
class AttrReaderMetaNode < Node
|
|
50
96
|
def initialize(raw_node, lenv)
|
|
51
97
|
super(raw_node, lenv)
|
|
98
|
+
@singleton = lenv.cref.scope_level == :metaclass
|
|
52
99
|
@args = []
|
|
53
100
|
raw_node.arguments.arguments.each do |raw_arg|
|
|
54
101
|
@args << raw_arg.value.to_sym if raw_arg.type == :symbol_node
|
|
@@ -57,9 +104,9 @@ module TypeProf::Core
|
|
|
57
104
|
# TODO: fine-grained hover
|
|
58
105
|
end
|
|
59
106
|
|
|
60
|
-
attr_reader :args
|
|
107
|
+
attr_reader :singleton, :args
|
|
61
108
|
|
|
62
|
-
def attrs = { args: }
|
|
109
|
+
def attrs = { singleton:, args: }
|
|
63
110
|
|
|
64
111
|
def req_positionals = []
|
|
65
112
|
def opt_positionals = []
|
|
@@ -68,6 +115,7 @@ module TypeProf::Core
|
|
|
68
115
|
def req_keywords = []
|
|
69
116
|
def opt_keywords = []
|
|
70
117
|
def rest_keywords = nil
|
|
118
|
+
def no_keywords = false
|
|
71
119
|
|
|
72
120
|
def mname_code_range(name)
|
|
73
121
|
idx = @args.index(name.to_sym) # TODO: support string args
|
|
@@ -78,9 +126,9 @@ module TypeProf::Core
|
|
|
78
126
|
def install0(genv)
|
|
79
127
|
@args.each do |arg|
|
|
80
128
|
ivar_name = :"@#{ arg }"
|
|
81
|
-
ivar_box = @changes.add_ivar_read_box(genv, @lenv.cref.cpath,
|
|
129
|
+
ivar_box = @changes.add_ivar_read_box(genv, @lenv.cref.cpath, @singleton, ivar_name)
|
|
82
130
|
ret_box = @changes.add_escape_box(genv, ivar_box.ret)
|
|
83
|
-
@changes.add_method_def_box(genv, @lenv.cref.cpath,
|
|
131
|
+
@changes.add_method_def_box(genv, @lenv.cref.cpath, @singleton, arg, FormalArguments::Empty, [ret_box])
|
|
84
132
|
end
|
|
85
133
|
Source.new
|
|
86
134
|
end
|
|
@@ -89,15 +137,22 @@ module TypeProf::Core
|
|
|
89
137
|
class AttrWriterMetaNode < Node
|
|
90
138
|
def initialize(raw_node, lenv)
|
|
91
139
|
super(raw_node, lenv)
|
|
140
|
+
@singleton = lenv.cref.scope_level == :metaclass
|
|
92
141
|
@args = []
|
|
93
142
|
raw_node.arguments.arguments.each do |raw_arg|
|
|
94
143
|
@args << raw_arg.value.to_sym if raw_arg.type == :symbol_node
|
|
95
144
|
end
|
|
96
145
|
end
|
|
97
146
|
|
|
98
|
-
attr_reader :args
|
|
147
|
+
attr_reader :singleton, :args
|
|
99
148
|
|
|
100
|
-
def attrs = { args: }
|
|
149
|
+
def attrs = { singleton:, args: }
|
|
150
|
+
|
|
151
|
+
# Interface expected by MethodDefBox
|
|
152
|
+
def req_keywords = []
|
|
153
|
+
def opt_keywords = []
|
|
154
|
+
def rest_keywords = nil
|
|
155
|
+
def no_keywords = false
|
|
101
156
|
|
|
102
157
|
def mname_code_range(name)
|
|
103
158
|
idx = @args.index(name.to_sym)
|
|
@@ -107,7 +162,7 @@ module TypeProf::Core
|
|
|
107
162
|
|
|
108
163
|
def define0(genv)
|
|
109
164
|
@args.map do |arg|
|
|
110
|
-
mod = genv.resolve_ivar(lenv.cref.cpath,
|
|
165
|
+
mod = genv.resolve_ivar(lenv.cref.cpath, @singleton, :"@#{ arg }")
|
|
111
166
|
mod.add_def(self)
|
|
112
167
|
mod
|
|
113
168
|
end
|
|
@@ -115,7 +170,7 @@ module TypeProf::Core
|
|
|
115
170
|
|
|
116
171
|
def define_copy(genv)
|
|
117
172
|
@args.map do |arg|
|
|
118
|
-
mod = genv.resolve_ivar(lenv.cref.cpath,
|
|
173
|
+
mod = genv.resolve_ivar(lenv.cref.cpath, @singleton, :"@#{ arg }")
|
|
119
174
|
mod.add_def(self)
|
|
120
175
|
mod.remove_def(@prev_node)
|
|
121
176
|
mod
|
|
@@ -125,7 +180,7 @@ module TypeProf::Core
|
|
|
125
180
|
|
|
126
181
|
def undefine0(genv)
|
|
127
182
|
@args.each do |arg|
|
|
128
|
-
mod = genv.resolve_ivar(lenv.cref.cpath,
|
|
183
|
+
mod = genv.resolve_ivar(lenv.cref.cpath, @singleton, :"@#{ arg }")
|
|
129
184
|
mod.remove_def(self)
|
|
130
185
|
end
|
|
131
186
|
end
|
|
@@ -136,7 +191,7 @@ module TypeProf::Core
|
|
|
136
191
|
@changes.add_edge(genv, vtx, ive.vtx)
|
|
137
192
|
ret_box = @changes.add_escape_box(genv, vtx)
|
|
138
193
|
f_args = FormalArguments.new([vtx], [], nil, [], [], [], nil, nil)
|
|
139
|
-
@changes.add_method_def_box(genv, @lenv.cref.cpath,
|
|
194
|
+
@changes.add_method_def_box(genv, @lenv.cref.cpath, @singleton, :"#{ arg }=", f_args, [ret_box])
|
|
140
195
|
end
|
|
141
196
|
Source.new
|
|
142
197
|
end
|
|
@@ -145,6 +200,7 @@ module TypeProf::Core
|
|
|
145
200
|
class AttrAccessorMetaNode < Node
|
|
146
201
|
def initialize(raw_node, lenv)
|
|
147
202
|
super(raw_node, lenv)
|
|
203
|
+
@singleton = lenv.cref.scope_level == :metaclass
|
|
148
204
|
@args = []
|
|
149
205
|
raw_node.arguments.arguments.each do |raw_arg|
|
|
150
206
|
@args << raw_arg.value.to_sym if raw_arg.type == :symbol_node
|
|
@@ -153,9 +209,15 @@ module TypeProf::Core
|
|
|
153
209
|
# TODO: fine-grained hover
|
|
154
210
|
end
|
|
155
211
|
|
|
156
|
-
attr_reader :args
|
|
212
|
+
attr_reader :singleton, :args
|
|
157
213
|
|
|
158
|
-
def attrs = { args: }
|
|
214
|
+
def attrs = { singleton:, args: }
|
|
215
|
+
|
|
216
|
+
# Interface expected by MethodDefBox
|
|
217
|
+
def req_keywords = []
|
|
218
|
+
def opt_keywords = []
|
|
219
|
+
def rest_keywords = nil
|
|
220
|
+
def no_keywords = false
|
|
159
221
|
|
|
160
222
|
def mname_code_range(name)
|
|
161
223
|
idx = @args.index(name.to_sym) # TODO: support string args
|
|
@@ -165,7 +227,7 @@ module TypeProf::Core
|
|
|
165
227
|
|
|
166
228
|
def define0(genv)
|
|
167
229
|
@args.map do |arg|
|
|
168
|
-
mod = genv.resolve_ivar(lenv.cref.cpath,
|
|
230
|
+
mod = genv.resolve_ivar(lenv.cref.cpath, @singleton, :"@#{ arg }")
|
|
169
231
|
mod.add_def(self)
|
|
170
232
|
mod
|
|
171
233
|
end
|
|
@@ -173,7 +235,7 @@ module TypeProf::Core
|
|
|
173
235
|
|
|
174
236
|
def define_copy(genv)
|
|
175
237
|
@args.map do |arg|
|
|
176
|
-
mod = genv.resolve_ivar(lenv.cref.cpath,
|
|
238
|
+
mod = genv.resolve_ivar(lenv.cref.cpath, @singleton, :"@#{ arg }")
|
|
177
239
|
mod.add_def(self)
|
|
178
240
|
mod.remove_def(@prev_node)
|
|
179
241
|
mod
|
|
@@ -183,21 +245,21 @@ module TypeProf::Core
|
|
|
183
245
|
|
|
184
246
|
def undefine0(genv)
|
|
185
247
|
@args.each do |arg|
|
|
186
|
-
mod = genv.resolve_ivar(lenv.cref.cpath,
|
|
248
|
+
mod = genv.resolve_ivar(lenv.cref.cpath, @singleton, :"@#{ arg }")
|
|
187
249
|
mod.remove_def(self)
|
|
188
250
|
end
|
|
189
251
|
end
|
|
190
252
|
|
|
191
253
|
def install0(genv)
|
|
192
254
|
@args.zip(@static_ret) do |arg, ive|
|
|
193
|
-
ivar_box = @changes.add_ivar_read_box(genv, @lenv.cref.cpath,
|
|
255
|
+
ivar_box = @changes.add_ivar_read_box(genv, @lenv.cref.cpath, @singleton, :"@#{ arg }")
|
|
194
256
|
ret_box = @changes.add_escape_box(genv, ivar_box.ret)
|
|
195
|
-
@changes.add_method_def_box(genv, @lenv.cref.cpath,
|
|
257
|
+
@changes.add_method_def_box(genv, @lenv.cref.cpath, @singleton, arg, FormalArguments::Empty, [ret_box])
|
|
196
258
|
|
|
197
259
|
vtx = Vertex.new(self)
|
|
198
260
|
@changes.add_edge(genv, vtx, ive.vtx)
|
|
199
261
|
f_args = FormalArguments.new([vtx], [], nil, [], [], [], nil, nil)
|
|
200
|
-
@changes.add_method_def_box(genv, @lenv.cref.cpath,
|
|
262
|
+
@changes.add_method_def_box(genv, @lenv.cref.cpath, @singleton, :"#{ arg }=", f_args, [ret_box])
|
|
201
263
|
end
|
|
202
264
|
Source.new
|
|
203
265
|
end
|
|
@@ -234,6 +296,11 @@ module TypeProf::Core
|
|
|
234
296
|
|
|
235
297
|
attr_reader :static_cpath, :members, :kind, :block_body
|
|
236
298
|
|
|
299
|
+
# Not a valid constant name, so no Ruby code can refer to it
|
|
300
|
+
BASE_CNAME = :"<struct base>"
|
|
301
|
+
|
|
302
|
+
def struct_base_cpath = @static_cpath + [BASE_CNAME]
|
|
303
|
+
|
|
237
304
|
def subnodes = { block_body: }
|
|
238
305
|
def attrs = { static_cpath:, members:, kind: }
|
|
239
306
|
|
|
@@ -251,8 +318,9 @@ module TypeProf::Core
|
|
|
251
318
|
mod = genv.resolve_cpath(@static_cpath)
|
|
252
319
|
# add_module_def internally calls get_const(name).add_def(self)
|
|
253
320
|
cdef = mod.add_module_def(genv, self)
|
|
321
|
+
genv.resolve_cpath(struct_base_cpath).add_module_def(genv, self)
|
|
254
322
|
@members.each do |member|
|
|
255
|
-
ive = genv.resolve_ivar(
|
|
323
|
+
ive = genv.resolve_ivar(struct_base_cpath, false, member)
|
|
256
324
|
ive.add_def(self)
|
|
257
325
|
end
|
|
258
326
|
@block_body.define(genv) if @block_body
|
|
@@ -263,8 +331,11 @@ module TypeProf::Core
|
|
|
263
331
|
mod = genv.resolve_cpath(@static_cpath)
|
|
264
332
|
mod.add_module_def(genv, self)
|
|
265
333
|
mod.remove_module_def(genv, @prev_node)
|
|
334
|
+
base = genv.resolve_cpath(struct_base_cpath)
|
|
335
|
+
base.add_module_def(genv, self)
|
|
336
|
+
base.remove_module_def(genv, @prev_node)
|
|
266
337
|
@members.each do |member|
|
|
267
|
-
ive = genv.resolve_ivar(
|
|
338
|
+
ive = genv.resolve_ivar(struct_base_cpath, false, member)
|
|
268
339
|
ive.add_def(self)
|
|
269
340
|
ive.remove_def(@prev_node)
|
|
270
341
|
end
|
|
@@ -274,8 +345,9 @@ module TypeProf::Core
|
|
|
274
345
|
def undefine0(genv)
|
|
275
346
|
mod = genv.resolve_cpath(@static_cpath)
|
|
276
347
|
mod.remove_module_def(genv, self)
|
|
348
|
+
genv.resolve_cpath(struct_base_cpath).remove_module_def(genv, self)
|
|
277
349
|
@members.each do |member|
|
|
278
|
-
ive = genv.resolve_ivar(
|
|
350
|
+
ive = genv.resolve_ivar(struct_base_cpath, false, member)
|
|
279
351
|
ive.remove_def(self)
|
|
280
352
|
end
|
|
281
353
|
@block_body.undefine(genv) if @block_body
|
|
@@ -288,7 +360,7 @@ module TypeProf::Core
|
|
|
288
360
|
@changes.add_edge(genv, mod_val, @static_ret.vtx)
|
|
289
361
|
end
|
|
290
362
|
|
|
291
|
-
cpath =
|
|
363
|
+
cpath = struct_base_cpath
|
|
292
364
|
@members.each do |member|
|
|
293
365
|
# Use bare `:member` (not `:@member`) so the slot can't collide with a
|
|
294
366
|
# user-written @member ivar — Struct/Data fields are not real ivars.
|
|
@@ -325,7 +397,8 @@ module TypeProf::Core
|
|
|
325
397
|
|
|
326
398
|
# Struct.[] is an alias for Struct.new
|
|
327
399
|
if @kind == :struct
|
|
328
|
-
|
|
400
|
+
# Struct.[] builds the struct class itself, not the base class
|
|
401
|
+
self_ret = @changes.add_escape_box(genv, Source.new(Type::Instance.new(genv, genv.resolve_cpath(@static_cpath), [])))
|
|
329
402
|
@changes.add_method_def_box(genv, cpath, true, :[], init_f_args, [self_ret])
|
|
330
403
|
end
|
|
331
404
|
|
|
@@ -135,7 +135,7 @@ module TypeProf::Core
|
|
|
135
135
|
# TODO: warn "def self.foo" in a metaclass
|
|
136
136
|
singleton = !!raw_node.receiver || lenv.cref.scope_level == :metaclass
|
|
137
137
|
mid = raw_node.name
|
|
138
|
-
|
|
138
|
+
mid_code_range_loc = raw_node.name_loc
|
|
139
139
|
@tbl = raw_node.locals
|
|
140
140
|
raw_args = raw_node.parameters
|
|
141
141
|
raw_body = raw_node.body
|
|
@@ -144,7 +144,7 @@ module TypeProf::Core
|
|
|
144
144
|
|
|
145
145
|
@singleton = singleton
|
|
146
146
|
@mid = mid
|
|
147
|
-
@
|
|
147
|
+
@mid_code_range_loc = mid_code_range_loc
|
|
148
148
|
|
|
149
149
|
ncref = CRef.new(lenv.cref.cpath, @singleton ? :class : :instance, @mid, lenv.cref)
|
|
150
150
|
nlenv = LocalEnv.new(@lenv.file_context, ncref, {}, [])
|
|
@@ -177,7 +177,11 @@ module TypeProf::Core
|
|
|
177
177
|
@reusable = !use_result
|
|
178
178
|
end
|
|
179
179
|
|
|
180
|
-
attr_reader :singleton, :mid
|
|
180
|
+
attr_reader :singleton, :mid
|
|
181
|
+
|
|
182
|
+
def mid_code_range
|
|
183
|
+
@mid_code_range ||= @lenv.code_range_from_node(@mid_code_range_loc) if @mid_code_range_loc
|
|
184
|
+
end
|
|
181
185
|
attr_reader :tbl
|
|
182
186
|
attr_reader :req_positionals
|
|
183
187
|
attr_reader :opt_positionals
|
|
@@ -203,7 +207,6 @@ module TypeProf::Core
|
|
|
203
207
|
def attrs = {
|
|
204
208
|
singleton:,
|
|
205
209
|
mid:,
|
|
206
|
-
mid_code_range:,
|
|
207
210
|
tbl:,
|
|
208
211
|
req_positionals:,
|
|
209
212
|
opt_positionals:,
|
|
@@ -217,7 +220,7 @@ module TypeProf::Core
|
|
|
217
220
|
reusable:,
|
|
218
221
|
}
|
|
219
222
|
|
|
220
|
-
def mname_code_range(_name) =
|
|
223
|
+
def mname_code_range(_name) = mid_code_range
|
|
221
224
|
|
|
222
225
|
def define(genv) # NOT define0
|
|
223
226
|
return define_copy(genv) if @prev_node && @reusable
|
|
@@ -271,21 +274,22 @@ module TypeProf::Core
|
|
|
271
274
|
block = @body.lenv.new_var(:"*given_block", self)
|
|
272
275
|
end
|
|
273
276
|
|
|
274
|
-
forward_opt_positionals = @opt_positionals.map
|
|
275
|
-
|
|
276
|
-
[Source.new(genv.gen_ary_type(elem_vtx)), elem_vtx]
|
|
277
|
-
end
|
|
277
|
+
forward_opt_positionals = @opt_positionals.map { Vertex.new(self) }
|
|
278
|
+
forward_rest_positionals = @rest_positionals ? Vertex.new(self) : nil
|
|
278
279
|
forward_opt_keywords = @opt_keywords.map {|_name| Vertex.new(self) }
|
|
280
|
+
forward_rest_keywords = @rest_keywords ? Vertex.new(self) : nil
|
|
281
|
+
forward_block = Vertex.new(self)
|
|
282
|
+
forward_activation = Vertex.new(self)
|
|
279
283
|
@body.lenv.forward_args = ForwardingArguments.new(
|
|
280
284
|
req_positionals,
|
|
281
|
-
forward_opt_positionals
|
|
282
|
-
|
|
283
|
-
rest_positionals,
|
|
285
|
+
forward_opt_positionals,
|
|
286
|
+
forward_rest_positionals,
|
|
284
287
|
post_positionals,
|
|
285
288
|
@req_keywords.zip(req_keywords),
|
|
286
289
|
@opt_keywords.zip(forward_opt_keywords),
|
|
287
|
-
|
|
288
|
-
|
|
290
|
+
forward_rest_keywords,
|
|
291
|
+
forward_block,
|
|
292
|
+
forward_activation,
|
|
289
293
|
)
|
|
290
294
|
|
|
291
295
|
if @body
|