typeprof 0.21.11 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +15 -31
- data/bin/typeprof +5 -0
- data/doc/doc.ja.md +134 -0
- data/doc/doc.md +136 -0
- data/lib/typeprof/cli/cli.rb +178 -0
- data/lib/typeprof/cli.rb +3 -133
- data/lib/typeprof/code_range.rb +112 -0
- data/lib/typeprof/core/ast/base.rb +263 -0
- data/lib/typeprof/core/ast/call.rb +259 -0
- data/lib/typeprof/core/ast/const.rb +126 -0
- data/lib/typeprof/core/ast/control.rb +433 -0
- data/lib/typeprof/core/ast/meta.rb +150 -0
- data/lib/typeprof/core/ast/method.rb +339 -0
- data/lib/typeprof/core/ast/misc.rb +263 -0
- data/lib/typeprof/core/ast/module.rb +123 -0
- data/lib/typeprof/core/ast/pattern.rb +140 -0
- data/lib/typeprof/core/ast/sig_decl.rb +471 -0
- data/lib/typeprof/core/ast/sig_type.rb +663 -0
- data/lib/typeprof/core/ast/value.rb +319 -0
- data/lib/typeprof/core/ast/variable.rb +315 -0
- data/lib/typeprof/core/ast.rb +472 -0
- data/lib/typeprof/core/builtin.rb +146 -0
- data/lib/typeprof/core/env/method.rb +137 -0
- data/lib/typeprof/core/env/method_entity.rb +55 -0
- data/lib/typeprof/core/env/module_entity.rb +408 -0
- data/lib/typeprof/core/env/static_read.rb +155 -0
- data/lib/typeprof/core/env/type_alias_entity.rb +27 -0
- data/lib/typeprof/core/env/value_entity.rb +32 -0
- data/lib/typeprof/core/env.rb +366 -0
- data/lib/typeprof/core/graph/box.rb +998 -0
- data/lib/typeprof/core/graph/change_set.rb +224 -0
- data/lib/typeprof/core/graph/filter.rb +155 -0
- data/lib/typeprof/core/graph/vertex.rb +225 -0
- data/lib/typeprof/core/service.rb +514 -0
- data/lib/typeprof/core/type.rb +352 -0
- data/lib/typeprof/core/util.rb +81 -0
- data/lib/typeprof/core.rb +31 -0
- data/lib/typeprof/diagnostic.rb +35 -0
- data/lib/typeprof/lsp/messages.rb +415 -0
- data/lib/typeprof/lsp/server.rb +203 -0
- data/lib/typeprof/lsp/text.rb +69 -0
- data/lib/typeprof/lsp/util.rb +51 -0
- data/lib/typeprof/lsp.rb +4 -907
- data/lib/typeprof/version.rb +1 -1
- data/lib/typeprof.rb +4 -18
- data/typeprof.gemspec +5 -7
- metadata +47 -33
- data/.github/dependabot.yml +0 -6
- data/.github/workflows/main.yml +0 -39
- data/.gitignore +0 -9
- data/Gemfile +0 -17
- data/Gemfile.lock +0 -41
- data/Rakefile +0 -10
- data/exe/typeprof +0 -10
- data/lib/typeprof/analyzer.rb +0 -2598
- data/lib/typeprof/arguments.rb +0 -414
- data/lib/typeprof/block.rb +0 -176
- data/lib/typeprof/builtin.rb +0 -893
- data/lib/typeprof/code-range.rb +0 -177
- data/lib/typeprof/config.rb +0 -158
- data/lib/typeprof/container-type.rb +0 -912
- data/lib/typeprof/export.rb +0 -589
- data/lib/typeprof/import.rb +0 -852
- data/lib/typeprof/insns-def.rb +0 -65
- data/lib/typeprof/iseq.rb +0 -864
- data/lib/typeprof/method.rb +0 -355
- data/lib/typeprof/type.rb +0 -1140
- data/lib/typeprof/utils.rb +0 -212
- data/tools/coverage.rb +0 -14
- data/tools/setup-insns-def.rb +0 -30
- data/typeprof-lsp +0 -3
data/lib/typeprof/arguments.rb
DELETED
@@ -1,414 +0,0 @@
|
|
1
|
-
module TypeProf
|
2
|
-
# Arguments from caller side
|
3
|
-
class ActualArguments
|
4
|
-
def initialize(lead_tys, rest_ty, kw_tys, blk_ty)
|
5
|
-
@lead_tys = lead_tys
|
6
|
-
raise unless lead_tys
|
7
|
-
@rest_ty = rest_ty
|
8
|
-
@kw_tys = kw_tys # kw_tys should be {:key1 => Type, :key2 => Type, ...} or {nil => Type}
|
9
|
-
raise if !kw_tys.is_a?(::Hash)
|
10
|
-
@blk_ty = blk_ty
|
11
|
-
raise unless blk_ty
|
12
|
-
end
|
13
|
-
|
14
|
-
def for_method_missing(mid)
|
15
|
-
ActualArguments.new([mid] + @lead_tys, @rest_ty, @kw_tys, @blk_ty)
|
16
|
-
end
|
17
|
-
|
18
|
-
attr_reader :lead_tys, :rest_ty, :kw_tys, :blk_ty
|
19
|
-
attr_accessor :node_id
|
20
|
-
|
21
|
-
def globalize(caller_env, visited, depth)
|
22
|
-
lead_tys = @lead_tys.map {|ty| ty.globalize(caller_env, visited, depth) }
|
23
|
-
rest_ty = @rest_ty.globalize(caller_env, visited, depth) if @rest_ty
|
24
|
-
kw_tys = @kw_tys.to_h do |key, ty|
|
25
|
-
[key, ty.globalize(caller_env, visited, depth)]
|
26
|
-
end
|
27
|
-
ActualArguments.new(lead_tys, rest_ty, kw_tys, @blk_ty)
|
28
|
-
end
|
29
|
-
|
30
|
-
def limit_size(limit)
|
31
|
-
self
|
32
|
-
end
|
33
|
-
|
34
|
-
def consistent_with_method_signature?(msig)
|
35
|
-
aargs = @lead_tys.dup
|
36
|
-
|
37
|
-
# aargs: lead_tys, rest_ty
|
38
|
-
# msig: lead_tys, opt_tys, rest_ty, post_tys
|
39
|
-
if @rest_ty
|
40
|
-
lower_bound = [0, msig.lead_tys.size + msig.post_tys.size - aargs.size].max
|
41
|
-
upper_bound = [0, lower_bound + msig.opt_tys.size].max
|
42
|
-
(lower_bound..upper_bound).each do |n|
|
43
|
-
# BUG: @rest_ty is an Array, so need to squash
|
44
|
-
tmp_aargs = ActualArguments.new(@lead_tys + [@rest_ty] * n, nil, @kw_tys, @blk_ty)
|
45
|
-
subst = tmp_aargs.consistent_with_method_signature?(msig) # XXX: wrong subst handling in the loop!
|
46
|
-
return subst if subst
|
47
|
-
end
|
48
|
-
return nil
|
49
|
-
end
|
50
|
-
|
51
|
-
subst = {}
|
52
|
-
if msig.rest_ty
|
53
|
-
return nil if aargs.size < msig.lead_tys.size + msig.post_tys.size
|
54
|
-
aargs.shift(msig.lead_tys.size).zip(msig.lead_tys) do |aarg, farg|
|
55
|
-
return nil unless subst2 = Type.match?(aarg, farg)
|
56
|
-
subst = Type.merge_substitution(subst, subst2)
|
57
|
-
end
|
58
|
-
aargs.pop(msig.post_tys.size).zip(msig.post_tys) do |aarg, farg|
|
59
|
-
return nil unless subst2 = Type.match?(aarg, farg)
|
60
|
-
subst = Type.merge_substitution(subst, subst2)
|
61
|
-
end
|
62
|
-
msig.opt_tys.each do |farg|
|
63
|
-
break if aargs.empty?
|
64
|
-
aarg = aargs.shift
|
65
|
-
return nil unless subst2 = Type.match?(aarg, farg)
|
66
|
-
subst = Type.merge_substitution(subst, subst2)
|
67
|
-
end
|
68
|
-
aargs.each do |aarg|
|
69
|
-
return nil unless subst2 = Type.match?(aarg, msig.rest_ty)
|
70
|
-
subst = Type.merge_substitution(subst, subst2)
|
71
|
-
end
|
72
|
-
else
|
73
|
-
return nil if aargs.size < msig.lead_tys.size + msig.post_tys.size
|
74
|
-
return nil if aargs.size > msig.lead_tys.size + msig.post_tys.size + msig.opt_tys.size
|
75
|
-
aargs.shift(msig.lead_tys.size).zip(msig.lead_tys) do |aarg, farg|
|
76
|
-
return nil unless subst2 = Type.match?(aarg, farg)
|
77
|
-
subst = Type.merge_substitution(subst, subst2)
|
78
|
-
end
|
79
|
-
aargs.pop(msig.post_tys.size).zip(msig.post_tys) do |aarg, farg|
|
80
|
-
return nil unless subst2 = Type.match?(aarg, farg)
|
81
|
-
subst = Type.merge_substitution(subst, subst2)
|
82
|
-
end
|
83
|
-
aargs.zip(msig.opt_tys) do |aarg, farg|
|
84
|
-
return nil unless subst2 = Type.match?(aarg, farg)
|
85
|
-
subst = Type.merge_substitution(subst, subst2)
|
86
|
-
end
|
87
|
-
end
|
88
|
-
# XXX: msig.keyword_tys
|
89
|
-
|
90
|
-
case msig.blk_ty
|
91
|
-
when Type::Proc
|
92
|
-
return nil if @blk_ty == Type.nil
|
93
|
-
when Type.nil
|
94
|
-
return nil if @blk_ty != Type.nil
|
95
|
-
when Type::Any
|
96
|
-
else
|
97
|
-
raise "unknown type of formal block signature"
|
98
|
-
end
|
99
|
-
|
100
|
-
subst
|
101
|
-
end
|
102
|
-
|
103
|
-
def argument_error(given, exp_lower, exp_upper)
|
104
|
-
case
|
105
|
-
when !exp_upper then exp = "#{ exp_lower }+"
|
106
|
-
when exp_lower == exp_upper then exp = "#{ exp_lower }"
|
107
|
-
else exp = "#{ exp_lower }..#{ exp_upper }"
|
108
|
-
end
|
109
|
-
"wrong number of arguments (given #{ given }, expected #{ exp })"
|
110
|
-
end
|
111
|
-
|
112
|
-
def to_block_signature
|
113
|
-
if @rest_ty
|
114
|
-
rest_ty = Type.bot
|
115
|
-
@rest_ty.each_child_global do |ty|
|
116
|
-
if ty.is_a?(Type::Array)
|
117
|
-
rest_ty = rest_ty.union(ty.elems.squash)
|
118
|
-
else
|
119
|
-
# XXX: to_ary?
|
120
|
-
rest_ty = rest_ty.union(ty)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
BlockSignature.new(@lead_tys, [], rest_ty, @blk_ty)
|
125
|
-
end
|
126
|
-
|
127
|
-
def setup_formal_arguments(kind, locals, fargs_format)
|
128
|
-
lead_num = fargs_format[:lead_num] || 0
|
129
|
-
post_num = fargs_format[:post_num] || 0
|
130
|
-
post_index = fargs_format[:post_start]
|
131
|
-
rest_index = fargs_format[:rest_start]
|
132
|
-
keyword = fargs_format[:keyword]
|
133
|
-
kw_index = fargs_format[:kwbits] - keyword.size if keyword
|
134
|
-
kwrest_index = fargs_format[:kwrest]
|
135
|
-
block_index = fargs_format[:block_start]
|
136
|
-
opt = fargs_format[:opt] || [0]
|
137
|
-
ambiguous_param0 = fargs_format[:ambiguous_param0]
|
138
|
-
|
139
|
-
lead_tys = @lead_tys
|
140
|
-
rest_ty = @rest_ty
|
141
|
-
|
142
|
-
if kind == :block
|
143
|
-
# The rule of passing arguments to block:
|
144
|
-
#
|
145
|
-
# Let A is actual arguments and F is formal arguments.
|
146
|
-
# If F is NOT ambiguous_param0, and if length(A) == 1, and if A[0] is an Array,
|
147
|
-
# then replace A with A[0]. And then, F[i] = A[i] for all 0 <= i < length(F).
|
148
|
-
|
149
|
-
# Handling the special case
|
150
|
-
if !ambiguous_param0
|
151
|
-
if lead_tys.size == 1 && !rest_ty && @kw_tys.empty? # length(A) == 1
|
152
|
-
ty = lead_tys[0]
|
153
|
-
case ty
|
154
|
-
when Type::Array
|
155
|
-
lead_tys = ty.elems.lead_tys
|
156
|
-
rest_ty = ty.elems.rest_ty
|
157
|
-
when Type::Union
|
158
|
-
if ty.elems
|
159
|
-
other_elems = {}
|
160
|
-
ty.elems.each do |(container_kind, base_type), elems|
|
161
|
-
if container_kind == Type::Array
|
162
|
-
rest_ty = rest_ty ? rest_ty.union(elems.squash) : elems.squash
|
163
|
-
else
|
164
|
-
other_elems[[container_kind, base_type]] = elems
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
lead_tys = [Type::Union.new(ty.types, other_elems)]
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
# Normal case: copy actual args to formal args
|
175
|
-
if rest_ty
|
176
|
-
ty = Type.bot
|
177
|
-
additional_lead_size = nil
|
178
|
-
rest_ty.each_child_global do |ty0|
|
179
|
-
if ty0.is_a?(Type::Array)
|
180
|
-
additional_lead_size = [additional_lead_size, ty0.elems.lead_tys.size].compact.min
|
181
|
-
else
|
182
|
-
additional_lead_size = 0
|
183
|
-
end
|
184
|
-
end
|
185
|
-
additional_lead_tys = [Type.bot] * (additional_lead_size || 0)
|
186
|
-
rest_ty.each_child_global do |ty0|
|
187
|
-
if ty0.is_a?(Type::Array)
|
188
|
-
tys, new_rest_ty = ty0.elems.take_first(additional_lead_size)
|
189
|
-
tys.each_with_index do |ty00, i|
|
190
|
-
additional_lead_tys[i] = additional_lead_tys[i].union(ty00)
|
191
|
-
end
|
192
|
-
ty = ty.union(new_rest_ty.elems.squash)
|
193
|
-
else
|
194
|
-
# XXX: to_ary?
|
195
|
-
ty = ty.union(ty0)
|
196
|
-
end
|
197
|
-
end
|
198
|
-
lead_tys += additional_lead_tys
|
199
|
-
rest_ty = ty
|
200
|
-
|
201
|
-
# XXX: Strictly speaking, this is needed, but it brings false positives. Which is better?
|
202
|
-
#rest_ty = rest_ty.union(Type.nil)
|
203
|
-
|
204
|
-
if rest_index
|
205
|
-
# foo(a0, a1, a2, ...(rest_ty)) -->
|
206
|
-
# def foo(l0, l1, o0=, o1=, *rest, p0, p1)
|
207
|
-
# lead_ty argc == 0: - - - - - - -
|
208
|
-
# lead_ty argc == 1: a0 - - - - - -
|
209
|
-
# lead_ty argc == 2: a0 a1 - - - - -
|
210
|
-
# lead_ty argc == 3: a0 a1 - - - a2 -
|
211
|
-
# lead_ty argc == 4: a0 a1 - - - a2 a3
|
212
|
-
# lead_ty argc == 5: a0 a1 a2 - - a3 a4
|
213
|
-
# lead_ty argc == 6: a0 a1 a2 a3 - a4 a5
|
214
|
-
# lead_ty argc == 7: a0 a1 a2 a3 a4 a5 a6
|
215
|
-
# lead_ty argc == 8: a0 a1 a2 a3 a4|a5 a6 a7
|
216
|
-
#
|
217
|
-
# l0 = a0
|
218
|
-
# l1 = a1
|
219
|
-
# o0 = a2
|
220
|
-
# o1 = a3
|
221
|
-
# rest = a4|a5|...|rest_ty (= cum_lead_tys[4])
|
222
|
-
# p0 = a2|a3|...|rest_ty (= cum_lead_tys[2])
|
223
|
-
# p1 = a3|a4|...|rest_ty (= cum_lead_tys[3])
|
224
|
-
|
225
|
-
cum_lead_tys = []
|
226
|
-
ty = rest_ty
|
227
|
-
lead_tys.reverse_each do |ty0|
|
228
|
-
cum_lead_tys.unshift(ty = ty.union(ty0))
|
229
|
-
end
|
230
|
-
|
231
|
-
# l1, l2, o1, o2
|
232
|
-
(lead_num + opt.size - 1).times {|i| locals[i] = lead_tys[i] || rest_ty }
|
233
|
-
opt_count = opt.size - 1
|
234
|
-
|
235
|
-
# rest
|
236
|
-
ty = cum_lead_tys[lead_num + opt.size - 1] || rest_ty
|
237
|
-
locals[rest_index] = Type::Array.new(Type::Array::Elements.new([], ty), Type::Instance.new(Type::Builtin[:ary]))
|
238
|
-
|
239
|
-
# p0, p1
|
240
|
-
off = [lead_num, lead_tys.size - post_num].max
|
241
|
-
post_num.times {|i| locals[post_index + i] = cum_lead_tys[off + i] || rest_ty }
|
242
|
-
else
|
243
|
-
# foo(a0, a1, a2, ...(rest_ty)) -->
|
244
|
-
# def foo(l0, l1, o0=, o1=, p0, p1)
|
245
|
-
# lead_ty argc == 0: - - - - - -
|
246
|
-
# lead_ty argc == 1: a0 - - - - -
|
247
|
-
# lead_ty argc == 2: a0 a1 - - - -
|
248
|
-
# lead_ty argc == 3: a0 a1 - - a2 -
|
249
|
-
# lead_ty argc == 4: a0 a1 - - a2 a3
|
250
|
-
# lead_ty argc == 5: a0 a1 a2 - a3 a4
|
251
|
-
# lead_ty argc == 6: a0 a1 a2 a3 a4 a5
|
252
|
-
# lead_ty argc == 7: a0 a1 a2 a3 a4 a5 (if there is a6, report error if kind is method, or ignore if kind is block)
|
253
|
-
#
|
254
|
-
# l0 = a0
|
255
|
-
# l1 = a1
|
256
|
-
# o0 = a2
|
257
|
-
# o1 = a3
|
258
|
-
# p0 = a2|a3|a4
|
259
|
-
# p1 = a3|a4|a5
|
260
|
-
|
261
|
-
if kind == :method && lead_num + opt.size - 1 + post_num < lead_tys.size
|
262
|
-
return argument_error(lead_tys.size, lead_num + post_num, lead_num + post_num + opt.size - 1)
|
263
|
-
end
|
264
|
-
|
265
|
-
# l1, l2, o1, o2
|
266
|
-
(lead_num + opt.size - 1).times {|i| locals[i] = lead_tys[i] || rest_ty }
|
267
|
-
opt_count = opt.size - 1
|
268
|
-
|
269
|
-
# p0, p1
|
270
|
-
post_num.times do |i|
|
271
|
-
candidates = lead_tys[lead_num, opt.size] || []
|
272
|
-
candidates << rest_ty if candidates.size < opt.size
|
273
|
-
locals[post_index + i] = candidates.inject(&:union)
|
274
|
-
end
|
275
|
-
end
|
276
|
-
else
|
277
|
-
if rest_index
|
278
|
-
# foo(a0, a1, a2) -->
|
279
|
-
# def foo(l0, l1, o0=, o1=, *rest, p0, p1)
|
280
|
-
# lead_ty argc == 0: - - - - - - - (error if kind is method)
|
281
|
-
# lead_ty argc == 1: a0 - - - - - - (error if kind is method)
|
282
|
-
# lead_ty argc == 2: a0 a1 - - - - - (error if kind is method)
|
283
|
-
# lead_ty argc == 3: a0 a1 - - - a2 - (error if kind is method)
|
284
|
-
# lead_ty argc == 4: a0 a1 - - - a2 a3
|
285
|
-
# lead_ty argc == 5: a0 a1 a2 - - a3 a4
|
286
|
-
# lead_ty argc == 6: a0 a1 a2 a3 - a4 a5
|
287
|
-
# lead_ty argc == 7: a0 a1 a2 a3 a4 a5 a6
|
288
|
-
# lead_ty argc == 8: a0 a1 a2 a3 a4|a5 a6 a7
|
289
|
-
#
|
290
|
-
# len(a) < 4 -> error
|
291
|
-
#
|
292
|
-
# l0 = a0
|
293
|
-
# l1 = a1
|
294
|
-
# o0 = a2
|
295
|
-
# o1 = a3
|
296
|
-
# rest = a4|a5|...|a[[4,len(a)-3].max]
|
297
|
-
# p0 = a[[2,len(a)-2].max]
|
298
|
-
# p1 = a[[3,len(a)-1].max]
|
299
|
-
|
300
|
-
if kind == :method && lead_tys.size < lead_num + post_num
|
301
|
-
return argument_error(lead_tys.size, lead_num + post_num, nil)
|
302
|
-
end
|
303
|
-
|
304
|
-
# l0, l1
|
305
|
-
lead_num.times {|i| locals[i] = lead_tys[i] || Type.nil }
|
306
|
-
|
307
|
-
# o0, o1
|
308
|
-
opt_count = (lead_tys.size - lead_num - post_num).clamp(0, opt.size - 1)
|
309
|
-
(opt.size - 1).times {|i| locals[lead_num + i] = i < opt_count ? lead_tys[lead_num + i] : Type.nil }
|
310
|
-
|
311
|
-
# rest
|
312
|
-
rest_b = lead_num + opt_count
|
313
|
-
rest_e = [0, lead_tys.size - post_num].max
|
314
|
-
locals[rest_index] = Type::Array.new(Type::Array::Elements.new(lead_tys[rest_b...rest_e] || [], Type.bot), Type::Instance.new(Type::Builtin[:ary]))
|
315
|
-
|
316
|
-
# p0, p1
|
317
|
-
off = [lead_num, lead_tys.size - post_num].max
|
318
|
-
post_num.times {|i| locals[post_index + i] = lead_tys[off + i] || Type.nil }
|
319
|
-
else
|
320
|
-
# yield a0, a1, a2 -->
|
321
|
-
# do |l0, l1, o0=, o1=, p0, p1|
|
322
|
-
# lead_ty argc == 0: - - - - - - (error if kind is method)
|
323
|
-
# lead_ty argc == 1: a0 - - - - - (error if kind is method)
|
324
|
-
# lead_ty argc == 2: a0 a1 - - - - (error if kind is method)
|
325
|
-
# lead_ty argc == 3: a0 a1 - - a2 - (error if kind is method)
|
326
|
-
# lead_ty argc == 4: a0 a1 - - a2 a3
|
327
|
-
# lead_ty argc == 5: a0 a1 a2 - a3 a4
|
328
|
-
# lead_ty argc == 6: a0 a1 a2 a3 a4 a5
|
329
|
-
# lead_ty argc == 7: a0 a1 a2 a3 a4 a5 (if there is a6, report error if kind is method, or ignore if kind is block)
|
330
|
-
#
|
331
|
-
# l0 = a0
|
332
|
-
# l1 = a1
|
333
|
-
# o0 = a2
|
334
|
-
# o1 = a3
|
335
|
-
# p0 = a2|a3|a4
|
336
|
-
# p1 = a3|a4|a5
|
337
|
-
|
338
|
-
if kind == :method && (lead_tys.size < lead_num + post_num || lead_num + opt.size - 1 + post_num < lead_tys.size)
|
339
|
-
return argument_error(lead_tys.size, lead_num + post_num, lead_num + post_num + opt.size - 1)
|
340
|
-
end
|
341
|
-
|
342
|
-
# l0, l1
|
343
|
-
lead_num.times {|i| locals[i] = lead_tys[i] || Type.nil }
|
344
|
-
|
345
|
-
# o0, o1
|
346
|
-
opt_count = (lead_tys.size - lead_num - post_num).clamp(0, opt.size - 1)
|
347
|
-
(opt.size - 1).times {|i| locals[lead_num + i] = i < opt_count ? lead_tys[lead_num + i] : Type.nil }
|
348
|
-
|
349
|
-
# p0, p1
|
350
|
-
off = lead_num + opt_count
|
351
|
-
post_num.times {|i| locals[post_index + i] = lead_tys[off + i] || Type.nil }
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
kw_tys = @kw_tys.dup
|
356
|
-
if keyword
|
357
|
-
keyword.each_with_index do |kw, i|
|
358
|
-
case
|
359
|
-
when kw.is_a?(Symbol) # required keyword
|
360
|
-
key = kw
|
361
|
-
req = true
|
362
|
-
when kw.size == 2 # optional keyword (default value is a literal)
|
363
|
-
key, default_ty = *kw
|
364
|
-
default_ty = Type.guess_literal_type(default_ty)
|
365
|
-
default_ty = default_ty.base_type if default_ty.is_a?(Type::Literal)
|
366
|
-
req = false
|
367
|
-
else # optional keyword (default value is an expression)
|
368
|
-
key, = kw
|
369
|
-
req = false
|
370
|
-
end
|
371
|
-
|
372
|
-
if kw_tys.key?(key)
|
373
|
-
ty = kw_tys.delete(key)
|
374
|
-
else
|
375
|
-
ty = kw_tys[nil] || Type.bot
|
376
|
-
end
|
377
|
-
|
378
|
-
if ty == Type.bot && req
|
379
|
-
return "no argument for required keywords"
|
380
|
-
end
|
381
|
-
|
382
|
-
ty = ty.union(default_ty) if default_ty
|
383
|
-
locals[kw_index + i] = ty
|
384
|
-
end
|
385
|
-
end
|
386
|
-
|
387
|
-
if kwrest_index
|
388
|
-
if kw_tys.key?(nil)
|
389
|
-
kw_rest_ty = Type.gen_hash {|h| h[Type.any] = kw_tys[nil] }
|
390
|
-
else
|
391
|
-
kw_rest_ty = Type.gen_hash do |h|
|
392
|
-
kw_tys.each do |key, ty|
|
393
|
-
sym = Type::Symbol.new(key, Type::Instance.new(Type::Builtin[:sym]))
|
394
|
-
h[sym] = ty
|
395
|
-
end
|
396
|
-
end
|
397
|
-
end
|
398
|
-
locals[kwrest_index] = kw_rest_ty
|
399
|
-
else
|
400
|
-
if !kw_tys.empty?
|
401
|
-
return "unknown keyword: #{ kw_tys.keys.join(", ") }"
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
if block_index
|
406
|
-
locals[block_index] = @blk_ty
|
407
|
-
end
|
408
|
-
|
409
|
-
start_pcs = opt[0..opt_count]
|
410
|
-
|
411
|
-
return @blk_ty, start_pcs
|
412
|
-
end
|
413
|
-
end
|
414
|
-
end
|
data/lib/typeprof/block.rb
DELETED
@@ -1,176 +0,0 @@
|
|
1
|
-
module TypeProf
|
2
|
-
class Block
|
3
|
-
include Utils::StructuralEquality
|
4
|
-
end
|
5
|
-
|
6
|
-
class ISeqBlock < Block
|
7
|
-
def initialize(iseq, ep)
|
8
|
-
@iseq = iseq
|
9
|
-
@outer_ep = ep
|
10
|
-
end
|
11
|
-
|
12
|
-
attr_reader :iseq, :outer_ep
|
13
|
-
|
14
|
-
def inspect
|
15
|
-
"#<ISeqBlock: #{ @outer_ep.source_location }>"
|
16
|
-
end
|
17
|
-
|
18
|
-
def consistent?(other)
|
19
|
-
if other.is_a?(ISeqBlock)
|
20
|
-
self == other
|
21
|
-
else
|
22
|
-
true # XXX
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def substitute(_subst, _depth)
|
27
|
-
self
|
28
|
-
end
|
29
|
-
|
30
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
31
|
-
blk_env = scratch.return_envs[@outer_ep]
|
32
|
-
if replace_recv_ty
|
33
|
-
replace_recv_ty = scratch.globalize_type(replace_recv_ty, caller_env, caller_ep)
|
34
|
-
blk_env = blk_env.replace_recv_ty(replace_recv_ty)
|
35
|
-
end
|
36
|
-
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
37
|
-
|
38
|
-
scratch.add_block_signature!(self, aargs.to_block_signature)
|
39
|
-
|
40
|
-
locals = [Type.nil] * @iseq.locals.size
|
41
|
-
|
42
|
-
blk_ty, start_pcs = aargs.setup_formal_arguments(:block, locals, @iseq.fargs_format)
|
43
|
-
if blk_ty.is_a?(String)
|
44
|
-
scratch.error(caller_ep, blk_ty)
|
45
|
-
ctn[Type.any, caller_ep, caller_env]
|
46
|
-
return
|
47
|
-
end
|
48
|
-
|
49
|
-
cref = replace_cref || @outer_ep.ctx.cref
|
50
|
-
nctx = Context.new(@iseq, cref, nil)
|
51
|
-
callee_ep = ExecutionPoint.new(nctx, 0, @outer_ep)
|
52
|
-
nenv = Env.new(blk_env.static_env, locals, [], nil)
|
53
|
-
alloc_site = AllocationSite.new(callee_ep)
|
54
|
-
locals.each_with_index do |ty, i|
|
55
|
-
alloc_site2 = alloc_site.add_id(i)
|
56
|
-
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
57
|
-
nenv = nenv.local_update(i, ty)
|
58
|
-
end
|
59
|
-
|
60
|
-
start_pcs.each do |start_pc|
|
61
|
-
scratch.merge_env(ExecutionPoint.new(nctx, start_pc, @outer_ep), nenv)
|
62
|
-
end
|
63
|
-
|
64
|
-
scratch.add_block_to_ctx!(self, callee_ep.ctx)
|
65
|
-
scratch.add_callsite!(callee_ep.ctx, caller_ep, caller_env, &ctn)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
class TypedBlock < Block
|
70
|
-
def initialize(msig, ret_ty)
|
71
|
-
@msig = msig
|
72
|
-
@ret_ty = ret_ty
|
73
|
-
end
|
74
|
-
|
75
|
-
attr_reader :msig, :ret_ty
|
76
|
-
|
77
|
-
def consistent?(other)
|
78
|
-
if other.is_a?(ISeqBlock)
|
79
|
-
raise "assert false"
|
80
|
-
else
|
81
|
-
self == other
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def substitute(subst, depth)
|
86
|
-
msig = @msig.substitute(subst, depth)
|
87
|
-
ret_ty = @ret_ty.substitute(subst, depth)
|
88
|
-
TypedBlock.new(msig, ret_ty)
|
89
|
-
end
|
90
|
-
|
91
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
92
|
-
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
93
|
-
subst = aargs.consistent_with_method_signature?(@msig)
|
94
|
-
unless subst
|
95
|
-
scratch.warn(caller_ep, "The arguments is not compatible to RBS block")
|
96
|
-
end
|
97
|
-
# check?
|
98
|
-
#subst = { Type::Var.new(:self) => caller_env.static_env.recv_ty }
|
99
|
-
# XXX: Update type vars
|
100
|
-
ret_ty = @ret_ty.remove_type_vars
|
101
|
-
ctn[ret_ty, caller_ep, caller_env]
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
class SymbolBlock < Block
|
106
|
-
def initialize(sym)
|
107
|
-
@sym = sym
|
108
|
-
end
|
109
|
-
|
110
|
-
attr_reader :iseq, :outer_ep
|
111
|
-
|
112
|
-
def inspect
|
113
|
-
"#<SymbolBlock: #{ @sym }>"
|
114
|
-
end
|
115
|
-
|
116
|
-
def consistent?(other)
|
117
|
-
true # XXX
|
118
|
-
end
|
119
|
-
|
120
|
-
def substitute(_subst, _depth)
|
121
|
-
self
|
122
|
-
end
|
123
|
-
|
124
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
125
|
-
if aargs.lead_tys.size >= 1
|
126
|
-
recv = aargs.lead_tys[0]
|
127
|
-
recv = Type.any if recv == Type.bot
|
128
|
-
aargs = ActualArguments.new(aargs.lead_tys[1..], aargs.rest_ty, aargs.kw_tys, aargs.blk_ty)
|
129
|
-
elsif aargs.rest_ty
|
130
|
-
recv = aargs.rest_ty.elems.squash_or_any # XXX: need to shift
|
131
|
-
else
|
132
|
-
recv = Type.any
|
133
|
-
end
|
134
|
-
|
135
|
-
scratch.add_block_signature!(self, aargs.to_block_signature)
|
136
|
-
|
137
|
-
recv.each_child do |recv|
|
138
|
-
scratch.do_send(recv, @sym, aargs, caller_ep, caller_env, &ctn)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
class CustomBlock < Block
|
144
|
-
def initialize(caller_ep, mid, &blk)
|
145
|
-
@caller_ep = caller_ep
|
146
|
-
@mid = mid
|
147
|
-
@blk = blk
|
148
|
-
end
|
149
|
-
|
150
|
-
def inspect
|
151
|
-
"#<CustomBlock>"
|
152
|
-
end
|
153
|
-
|
154
|
-
def consistent?(other)
|
155
|
-
true # XXX
|
156
|
-
end
|
157
|
-
|
158
|
-
def substitute(_subst, _depth)
|
159
|
-
self
|
160
|
-
end
|
161
|
-
|
162
|
-
def do_call(aargs, caller_ep, caller_env, scratch, replace_recv_ty:, replace_cref:, &ctn)
|
163
|
-
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
164
|
-
|
165
|
-
dummy_ctx = TypedContext.new(@caller_ep, @mid)
|
166
|
-
|
167
|
-
scratch.add_block_signature!(self, aargs.to_block_signature)
|
168
|
-
scratch.add_block_to_ctx!(self, dummy_ctx)
|
169
|
-
|
170
|
-
@blk.call(aargs, caller_ep, caller_env, scratch, replace_recv_ty: replace_recv_ty, replace_cref: replace_cref) do |ret_ty, ep, env|
|
171
|
-
scratch.add_return_value!(dummy_ctx, ret_ty)
|
172
|
-
ctn[ret_ty, ep, env]
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|