typeprof 0.6.0 → 0.9.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/Gemfile.lock +7 -5
- data/doc/doc.ja.md +3 -4
- data/doc/doc.md +3 -4
- data/lib/typeprof/analyzer.rb +214 -133
- data/lib/typeprof/arguments.rb +14 -6
- data/lib/typeprof/block.rb +6 -2
- data/lib/typeprof/builtin.rb +223 -71
- data/lib/typeprof/cli.rb +33 -34
- data/lib/typeprof/config.rb +6 -4
- data/lib/typeprof/container-type.rb +154 -99
- data/lib/typeprof/export.rb +23 -17
- data/lib/typeprof/import.rb +49 -42
- data/lib/typeprof/iseq.rb +23 -7
- data/lib/typeprof/method.rb +63 -147
- data/lib/typeprof/type.rb +63 -7
- data/lib/typeprof/version.rb +1 -1
- data/smoke/alias.rb +5 -4
- data/smoke/alias2.rb +4 -4
- data/smoke/any1.rb +2 -1
- data/smoke/any2.rb +3 -2
- data/smoke/arguments.rb +3 -2
- data/smoke/arguments2.rb +11 -10
- data/smoke/array-each.rb +2 -1
- data/smoke/array-each2.rb +2 -1
- data/smoke/array-each3.rb +2 -1
- data/smoke/array-ltlt.rb +2 -1
- data/smoke/array-ltlt2.rb +2 -1
- data/smoke/array-map.rb +2 -1
- data/smoke/array-map2.rb +2 -1
- data/smoke/array-map3.rb +4 -3
- data/smoke/array-mul.rb +3 -2
- data/smoke/array-plus1.rb +2 -1
- data/smoke/array-plus2.rb +2 -2
- data/smoke/array-pop.rb +2 -1
- data/smoke/array-range-aref.rb +71 -0
- data/smoke/array-replace.rb +2 -1
- data/smoke/array-s-aref.rb +2 -1
- data/smoke/array1.rb +6 -5
- data/smoke/array10.rb +2 -1
- data/smoke/array11.rb +2 -1
- data/smoke/array12.rb +4 -3
- data/smoke/array13.rb +5 -4
- data/smoke/array14.rb +2 -1
- data/smoke/array15.rb +16 -0
- data/smoke/array2.rb +4 -3
- data/smoke/array3.rb +4 -4
- data/smoke/array4.rb +2 -1
- data/smoke/array5.rb +2 -1
- data/smoke/array6.rb +3 -2
- data/smoke/array7.rb +2 -1
- data/smoke/array8.rb +1 -1
- data/smoke/array9.rb +2 -1
- data/smoke/attr-module.rb +26 -0
- data/smoke/attr.rb +5 -5
- data/smoke/autoload.rb +14 -0
- data/smoke/backtrace.rb +4 -3
- data/smoke/block-ambiguous.rb +9 -8
- data/smoke/block-args1-rest.rb +12 -11
- data/smoke/block-args1.rb +11 -10
- data/smoke/block-args2-rest.rb +12 -11
- data/smoke/block-args2.rb +11 -10
- data/smoke/block-args3-rest.rb +14 -13
- data/smoke/block-args3.rb +13 -12
- data/smoke/block-blockarg.rb +5 -4
- data/smoke/block-kwarg.rb +11 -10
- data/smoke/block1.rb +2 -1
- data/smoke/block10.rb +2 -1
- data/smoke/block11.rb +6 -5
- data/smoke/block12.rb +3 -2
- data/smoke/block14.rb +3 -2
- data/smoke/block2.rb +2 -1
- data/smoke/block3.rb +3 -3
- data/smoke/block4.rb +3 -2
- data/smoke/block5.rb +3 -2
- data/smoke/block6.rb +3 -2
- data/smoke/block7.rb +2 -1
- data/smoke/block8.rb +4 -3
- data/smoke/block9.rb +2 -1
- data/smoke/blown.rb +2 -1
- data/smoke/break1.rb +3 -2
- data/smoke/break2.rb +2 -1
- data/smoke/break3.rb +13 -0
- data/smoke/case.rb +2 -1
- data/smoke/case2.rb +2 -1
- data/smoke/case3.rb +17 -0
- data/smoke/class-hierarchy.rb +5 -5
- data/smoke/class-hierarchy2.rb +3 -3
- data/smoke/class-new.rb +15 -0
- data/smoke/class_instance_var.rb +1 -1
- data/smoke/class_method.rb +2 -2
- data/smoke/class_method2.rb +2 -2
- data/smoke/class_method3.rb +4 -2
- data/smoke/constant1.rb +6 -6
- data/smoke/constant2.rb +5 -4
- data/smoke/constant3.rb +2 -1
- data/smoke/constant4.rb +2 -1
- data/smoke/context-sensitive1.rb +2 -1
- data/smoke/cvar.rb +6 -5
- data/smoke/cvar2.rb +2 -2
- data/smoke/define_method.rb +16 -0
- data/smoke/define_method2.rb +18 -0
- data/smoke/define_method3.rb +13 -0
- data/smoke/define_method3.rbs +3 -0
- data/smoke/define_method4.rb +15 -0
- data/smoke/define_method4.rbs +3 -0
- data/smoke/define_method5.rb +12 -0
- data/smoke/demo.rb +7 -6
- data/smoke/demo1.rb +2 -1
- data/smoke/demo10.rb +3 -2
- data/smoke/demo11.rb +2 -1
- data/smoke/demo2.rb +2 -1
- data/smoke/demo3.rb +2 -1
- data/smoke/demo4.rb +3 -3
- data/smoke/demo5.rb +1 -1
- data/smoke/demo6.rb +3 -3
- data/smoke/demo7.rb +2 -1
- data/smoke/demo8.rb +3 -2
- data/smoke/demo9.rb +3 -2
- data/smoke/dummy-execution1.rb +3 -2
- data/smoke/dummy-execution2.rb +2 -2
- data/smoke/dummy_element.rb +14 -0
- data/smoke/ensure1.rb +3 -2
- data/smoke/enumerator.rb +3 -2
- data/smoke/expandarray1.rb +2 -1
- data/smoke/expandarray2.rb +2 -1
- data/smoke/fib.rb +2 -2
- data/smoke/flip-flop.rb +28 -0
- data/smoke/flow1.rb +2 -1
- data/smoke/flow2.rb +2 -1
- data/smoke/flow3.rb +2 -1
- data/smoke/flow5.rb +2 -1
- data/smoke/flow6.rb +2 -1
- data/smoke/flow7.rb +2 -1
- data/smoke/flow8.rb +2 -1
- data/smoke/flow9.rb +12 -0
- data/smoke/freeze.rb +2 -1
- data/smoke/function.rb +3 -2
- data/smoke/gvar.rb +3 -2
- data/smoke/gvar2.rb +3 -2
- data/smoke/hash-bot.rb +12 -0
- data/smoke/hash-fetch.rb +4 -3
- data/smoke/hash-merge-bang.rb +2 -1
- data/smoke/hash1.rb +3 -2
- data/smoke/hash2.rb +2 -1
- data/smoke/hash3.rb +2 -1
- data/smoke/hash4.rb +2 -1
- data/smoke/hash5.rb +1 -1
- data/smoke/inheritance.rb +4 -4
- data/smoke/inheritance2.rb +2 -2
- data/smoke/initialize.rb +6 -5
- data/smoke/instance_eval.rb +2 -2
- data/smoke/instance_eval2.rb +10 -0
- data/smoke/instance_eval3.rb +25 -0
- data/smoke/int_times.rb +2 -1
- data/smoke/integer.rb +2 -1
- data/smoke/ivar.rb +5 -4
- data/smoke/ivar2.rb +4 -4
- data/smoke/ivar3.rb +2 -2
- data/smoke/ivar4.rb +20 -0
- data/smoke/kernel-class.rb +2 -1
- data/smoke/keyword1.rb +2 -1
- data/smoke/keyword2.rb +2 -1
- data/smoke/keyword3.rb +2 -1
- data/smoke/keyword4.rb +2 -1
- data/smoke/keyword5.rb +2 -1
- data/smoke/kwrest.rb +12 -0
- data/smoke/kwrest.rbs +3 -0
- data/smoke/kwsplat1.rb +5 -4
- data/smoke/kwsplat2.rb +2 -1
- data/smoke/lit-complex.rb +10 -0
- data/smoke/lit-encoding.rb +10 -0
- data/smoke/manual-rbs.rb +4 -3
- data/smoke/manual-rbs2.rb +2 -1
- data/smoke/manual-rbs3.rb +2 -2
- data/smoke/masgn1.rb +2 -1
- data/smoke/masgn2.rb +3 -2
- data/smoke/masgn3.rb +2 -1
- data/smoke/method_in_branch.rb +3 -2
- data/smoke/method_missing.rb +28 -0
- data/smoke/module1.rb +2 -2
- data/smoke/module2.rb +1 -1
- data/smoke/module3.rb +2 -2
- data/smoke/module4.rb +2 -2
- data/smoke/module5.rb +17 -0
- data/smoke/module6.rb +40 -0
- data/smoke/module_function1.rb +3 -3
- data/smoke/module_function2.rb +3 -3
- data/smoke/multiple-include.rb +1 -1
- data/smoke/multiple-superclass.rb +1 -1
- data/smoke/next1.rb +3 -2
- data/smoke/next2.rb +2 -1
- data/smoke/object-send1.rb +4 -3
- data/smoke/object-send2.rb +10 -0
- data/smoke/object-send3.rb +18 -0
- data/smoke/once.rb +2 -1
- data/smoke/optional1.rb +2 -1
- data/smoke/optional2.rb +2 -1
- data/smoke/optional3.rb +2 -1
- data/smoke/parameterizedd-self.rb +3 -2
- data/smoke/parameterizedd-self2.rb +1 -1
- data/smoke/pathname1.rb +2 -1
- data/smoke/pathname2.rb +2 -1
- data/smoke/pattern-match1.rb +2 -1
- data/smoke/pattern-match2.rb +2 -1
- data/smoke/printf.rb +2 -2
- data/smoke/proc.rb +3 -2
- data/smoke/proc2.rb +2 -1
- data/smoke/proc3.rb +2 -1
- data/smoke/proc4.rb +2 -1
- data/smoke/proc5.rb +19 -0
- data/smoke/public.rb +34 -0
- data/smoke/range.rb +2 -1
- data/smoke/rbs-alias.rb +2 -1
- data/smoke/rbs-attr.rb +6 -5
- data/smoke/rbs-attr2.rb +11 -0
- data/smoke/rbs-attr2.rbs +3 -0
- data/smoke/rbs-extend.rb +2 -1
- data/smoke/rbs-interface.rb +5 -4
- data/smoke/rbs-module.rb +26 -0
- data/smoke/rbs-module.rbs +4 -0
- data/smoke/rbs-opt-and-rest.rb +10 -0
- data/smoke/rbs-opt-and-rest.rbs +3 -0
- data/smoke/rbs-proc1.rb +2 -1
- data/smoke/rbs-proc2.rb +3 -2
- data/smoke/rbs-proc3.rb +2 -1
- data/smoke/rbs-record.rb +3 -2
- data/smoke/rbs-tyvar.rb +3 -2
- data/smoke/rbs-tyvar2.rb +3 -2
- data/smoke/rbs-tyvar3.rb +3 -2
- data/smoke/rbs-tyvar4.rb +3 -3
- data/smoke/rbs-tyvar5.rb +2 -1
- data/smoke/rbs-tyvar6.rb +4 -3
- data/smoke/rbs-tyvar7.rb +12 -0
- data/smoke/rbs-tyvar7.rbs +7 -0
- data/smoke/rbs-vars.rb +7 -8
- data/smoke/redo1.rb +3 -2
- data/smoke/redo2.rb +3 -2
- data/smoke/req-keyword.rb +2 -1
- data/smoke/rescue1.rb +3 -2
- data/smoke/rescue2.rb +3 -2
- data/smoke/rescue3.rb +19 -0
- data/smoke/rescue4.rb +17 -0
- data/smoke/respond_to.rb +2 -1
- data/smoke/rest-farg.rb +2 -1
- data/smoke/rest1.rb +3 -2
- data/smoke/rest2.rb +2 -1
- data/smoke/rest3.rb +7 -6
- data/smoke/rest4.rb +3 -2
- data/smoke/rest5.rb +2 -1
- data/smoke/rest6.rb +2 -1
- data/smoke/retry1.rb +3 -2
- data/smoke/return.rb +2 -1
- data/smoke/singleton_method.rb +1 -1
- data/smoke/step.rb +4 -3
- data/smoke/string-split.rb +2 -1
- data/smoke/struct-keyword_init.rb +20 -0
- data/smoke/struct.rb +1 -1
- data/smoke/struct2.rb +5 -4
- data/smoke/struct3.rb +2 -2
- data/smoke/struct4.rb +7 -0
- data/smoke/struct5.rb +16 -0
- data/smoke/struct6.rb +15 -0
- data/smoke/struct7.rb +17 -0
- data/smoke/stub-keyword.rb +10 -0
- data/smoke/super1.rb +5 -4
- data/smoke/super2.rb +1 -1
- data/smoke/super3.rb +3 -3
- data/smoke/super4.rb +5 -5
- data/smoke/super5.rb +4 -4
- data/smoke/svar1.rb +2 -1
- data/smoke/symbol-proc-attr.rb +22 -0
- data/smoke/symbol-proc-attr2.rb +15 -0
- data/smoke/symbol-proc-bot.rb +13 -0
- data/smoke/symbol-proc.rb +4 -3
- data/smoke/tap1.rb +3 -2
- data/smoke/toplevel.rb +2 -1
- data/smoke/two-map.rb +3 -2
- data/smoke/type_var.rb +2 -1
- data/smoke/typed_method.rb +2 -1
- data/smoke/uninitialize-var.rb +2 -1
- data/smoke/union-recv.rb +2 -2
- data/smoke/user-demo.rb +3 -3
- data/smoke/wrong-extend.rb +2 -2
- data/smoke/wrong-include.rb +2 -2
- data/smoke/wrong-include2.rb +17 -0
- data/typeprof.gemspec +1 -1
- metadata +56 -5
- data/tools/stackprof-wrapper.rb +0 -10
data/lib/typeprof/export.rb
CHANGED
@@ -72,7 +72,7 @@ module TypeProf
|
|
72
72
|
gvars.dump.each do |gvar_name, entry|
|
73
73
|
next if entry.type == Type.bot
|
74
74
|
s = entry.rbs_declared ? "#" : ""
|
75
|
-
output.puts s + "#{ gvar_name }
|
75
|
+
output.puts s + "#{ gvar_name }: #{ entry.type.screen_name(scratch) }"
|
76
76
|
end
|
77
77
|
output.puts
|
78
78
|
end
|
@@ -135,11 +135,12 @@ module TypeProf
|
|
135
135
|
method_name = ctx.mid
|
136
136
|
method_name = "self.#{ method_name }" if singleton
|
137
137
|
|
138
|
-
iseq_methods[method_name] ||= []
|
139
|
-
iseq_methods[method_name]
|
138
|
+
iseq_methods[method_name] ||= [true, []]
|
139
|
+
iseq_methods[method_name][0] &&= mdef.pub_meth
|
140
|
+
iseq_methods[method_name][1] << @scratch.show_method_signature(ctx)
|
140
141
|
end
|
141
142
|
when AttrMethodDef
|
142
|
-
next if Config.check_dir_filter(mdef.absolute_path) == :exclude
|
143
|
+
next if !mdef.absolute_path || Config.check_dir_filter(mdef.absolute_path) == :exclude
|
143
144
|
mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
|
144
145
|
method_name = mid
|
145
146
|
method_name = "self.#{ mid }" if singleton
|
@@ -168,12 +169,14 @@ module TypeProf
|
|
168
169
|
next unless var.to_s.start_with?("@")
|
169
170
|
var = "self.#{ var }" if singleton
|
170
171
|
next if attr_methods[[singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]
|
171
|
-
|
172
|
+
next if entry.rbs_declared
|
173
|
+
[var, ty.screen_name(@scratch)]
|
172
174
|
end.compact
|
173
175
|
|
174
176
|
cvars = cvars.map do |var, entry|
|
175
177
|
next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
|
176
|
-
|
178
|
+
next if entry.rbs_declared
|
179
|
+
[var, entry.type.screen_name(@scratch)]
|
177
180
|
end.compact
|
178
181
|
|
179
182
|
if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
|
@@ -266,7 +269,7 @@ module TypeProf
|
|
266
269
|
output.puts indent + "#{ class_data.kind } #{ name }#{ superclass }"
|
267
270
|
first = true
|
268
271
|
class_data.consts.each do |name, ty|
|
269
|
-
output.puts indent + " #{ name }
|
272
|
+
output.puts indent + " #{ name }: #{ ty }"
|
270
273
|
first = false
|
271
274
|
end
|
272
275
|
class_data.included_mods.sort.each do |mod|
|
@@ -277,28 +280,31 @@ module TypeProf
|
|
277
280
|
output.puts indent + " extend #{ mod }"
|
278
281
|
first = false
|
279
282
|
end
|
280
|
-
class_data.ivars.each do |var, ty
|
281
|
-
|
282
|
-
output.puts indent + s + "#{ var } : #{ ty }" unless var.start_with?("_")
|
283
|
+
class_data.ivars.each do |var, ty|
|
284
|
+
output.puts indent + " #{ var }: #{ ty }" unless var.start_with?("_")
|
283
285
|
first = false
|
284
286
|
end
|
285
|
-
class_data.cvars.each do |var, ty
|
286
|
-
|
287
|
-
output.puts indent + s + "#{ var } : #{ ty }"
|
287
|
+
class_data.cvars.each do |var, ty|
|
288
|
+
output.puts indent + " #{ var }: #{ ty }"
|
288
289
|
first = false
|
289
290
|
end
|
290
291
|
class_data.attr_methods.each do |(method_name, hidden), (kind, ty)|
|
291
|
-
output.puts indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }
|
292
|
+
output.puts indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }"
|
292
293
|
first = false
|
293
294
|
end
|
294
295
|
class_data.explicit_methods.each do |method_name, sigs|
|
295
296
|
sigs = sigs.sort.join("\n" + indent + "#" + " " * (method_name.size + 6) + "| ")
|
296
|
-
output.puts indent + "# def #{ method_name }
|
297
|
+
output.puts indent + "# def #{ method_name }: #{ sigs }"
|
297
298
|
first = false
|
298
299
|
end
|
299
|
-
|
300
|
+
prev_pub_meth = true
|
301
|
+
class_data.iseq_methods.each do |method_name, (pub_meth, sigs)|
|
300
302
|
sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 7) + "| ")
|
301
|
-
|
303
|
+
if prev_pub_meth != pub_meth
|
304
|
+
output.puts indent + " #{ pub_meth ? "public" : "private" }"
|
305
|
+
prev_pub_meth = pub_meth
|
306
|
+
end
|
307
|
+
output.puts indent + " def #{ method_name }: #{ sigs }"
|
302
308
|
first = false
|
303
309
|
end
|
304
310
|
show_class_hierarchy(depth + 1, class_data.inner_classes, output, first)
|
data/lib/typeprof/import.rb
CHANGED
@@ -26,6 +26,13 @@ module TypeProf
|
|
26
26
|
def load_library(lib)
|
27
27
|
loader = RBS::EnvironmentLoader.new(core_root: nil)
|
28
28
|
loader.add(library: lib)
|
29
|
+
|
30
|
+
case lib
|
31
|
+
when "yaml"
|
32
|
+
loader.add(library: "pstore")
|
33
|
+
loader.add(library: "dbm")
|
34
|
+
end
|
35
|
+
|
29
36
|
new_decls = loader.load(env: @env).map {|decl,| decl }
|
30
37
|
RBSReader.load_rbs(@env, new_decls)
|
31
38
|
end
|
@@ -112,6 +119,7 @@ module TypeProf
|
|
112
119
|
included_modules = []
|
113
120
|
extended_modules = []
|
114
121
|
methods = {}
|
122
|
+
attr_methods = {}
|
115
123
|
ivars = {}
|
116
124
|
cvars = {}
|
117
125
|
rbs_sources = {}
|
@@ -147,15 +155,15 @@ module TypeProf
|
|
147
155
|
end
|
148
156
|
when RBS::AST::Members::AttrReader
|
149
157
|
ty = conv_type(member.type)
|
150
|
-
|
158
|
+
attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
|
151
159
|
when RBS::AST::Members::AttrWriter
|
152
160
|
ty = conv_type(member.type)
|
153
|
-
|
161
|
+
attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
|
154
162
|
when RBS::AST::Members::AttrAccessor
|
155
163
|
ty = conv_type(member.type)
|
156
|
-
|
157
|
-
methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
|
164
|
+
attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
|
158
165
|
when RBS::AST::Members::Alias
|
166
|
+
# XXX: an alias to attr methods?
|
159
167
|
if member.instance?
|
160
168
|
method_def = methods[[false, member.old_name]]
|
161
169
|
methods[[false, member.new_name]] = method_def if method_def
|
@@ -211,6 +219,7 @@ module TypeProf
|
|
211
219
|
included_modules: included_modules,
|
212
220
|
extended_modules: extended_modules,
|
213
221
|
methods: methods,
|
222
|
+
attr_methods: attr_methods,
|
214
223
|
ivars: ivars,
|
215
224
|
cvars: cvars,
|
216
225
|
rbs_sources: rbs_sources,
|
@@ -237,7 +246,7 @@ module TypeProf
|
|
237
246
|
@all_env.class_decls[name].decls.each do |decl|
|
238
247
|
decl = decl.decl
|
239
248
|
next if decl.is_a?(RBS::AST::Declarations::Module)
|
240
|
-
|
249
|
+
each_reference(decl) {|name| queue << [:visit, name] }
|
241
250
|
end
|
242
251
|
queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
|
243
252
|
end
|
@@ -252,13 +261,20 @@ module TypeProf
|
|
252
261
|
end
|
253
262
|
end
|
254
263
|
|
255
|
-
def
|
264
|
+
def each_reference(decl, &blk)
|
256
265
|
yield decl.name
|
257
|
-
|
266
|
+
if decl.super_class
|
267
|
+
name = decl.super_class.name
|
268
|
+
else
|
269
|
+
name = RBS::BuiltinNames::Object.name
|
270
|
+
end
|
258
271
|
return if decl.name == RBS::BuiltinNames::BasicObject.name
|
259
|
-
return if decl.name ==
|
260
|
-
@all_env.class_decls[
|
261
|
-
|
272
|
+
return if decl.name == name
|
273
|
+
decls = @all_env.class_decls[name]
|
274
|
+
if decls
|
275
|
+
decls.decls.each do |decl|
|
276
|
+
each_reference(decl.decl, &blk)
|
277
|
+
end
|
262
278
|
end
|
263
279
|
end
|
264
280
|
|
@@ -297,7 +313,7 @@ module TypeProf
|
|
297
313
|
opt_kw_tys = func.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
298
314
|
req_kw_tys = func.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
299
315
|
rest_kw_ty = func.rest_keywords
|
300
|
-
|
316
|
+
rest_kw_ty = conv_type(rest_kw_ty.type) if rest_kw_ty
|
301
317
|
|
302
318
|
ret_ty = conv_type(func.return_type)
|
303
319
|
|
@@ -314,32 +330,12 @@ module TypeProf
|
|
314
330
|
}
|
315
331
|
end
|
316
332
|
|
317
|
-
def
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
req_kw_tys: {},
|
324
|
-
opt_kw_tys: {},
|
325
|
-
rest_kw_ty: nil,
|
326
|
-
blk: nil,
|
327
|
-
ret_ty: ty,
|
328
|
-
}]
|
329
|
-
end
|
330
|
-
|
331
|
-
def attr_writer_def(ty)
|
332
|
-
[{
|
333
|
-
type_params: [],
|
334
|
-
lead_tys: [ty],
|
335
|
-
opt_tys: [],
|
336
|
-
rest_ty: nil,
|
337
|
-
req_kw_tys: {},
|
338
|
-
opt_kw_tys: {},
|
339
|
-
rest_kw_ty: nil,
|
340
|
-
blk: nil,
|
341
|
-
ret_ty: ty,
|
342
|
-
}]
|
333
|
+
def attr_method_def(kind, name, ty)
|
334
|
+
{
|
335
|
+
kind: kind,
|
336
|
+
ivar: name,
|
337
|
+
ty: ty,
|
338
|
+
}
|
343
339
|
end
|
344
340
|
|
345
341
|
def conv_block(rbs_block)
|
@@ -452,6 +448,8 @@ module TypeProf
|
|
452
448
|
json = scratch.rbs_reader.load_library(feature)
|
453
449
|
rescue RBS::EnvironmentLoader::UnknownLibraryError
|
454
450
|
return nil
|
451
|
+
rescue RBS::DuplicatedDeclarationError
|
452
|
+
return true
|
455
453
|
end
|
456
454
|
# need cache?
|
457
455
|
Import.new(scratch, json).import
|
@@ -483,8 +481,7 @@ module TypeProf
|
|
483
481
|
|
484
482
|
klass = @scratch.get_constant(base_klass, name)
|
485
483
|
if klass.is_a?(Type::Any)
|
486
|
-
|
487
|
-
klass = @scratch.new_class(base_klass, name, type_params, superclass, superclass_type_args, nil)
|
484
|
+
klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
|
488
485
|
|
489
486
|
# There builtin classes are needed to interpret RBS declarations
|
490
487
|
case classpath
|
@@ -500,13 +497,15 @@ module TypeProf
|
|
500
497
|
end
|
501
498
|
end
|
502
499
|
|
503
|
-
[klass, members]
|
500
|
+
[klass, superclass_type_args, members]
|
504
501
|
end
|
505
502
|
|
506
|
-
classes.each do |klass, members|
|
503
|
+
classes.each do |klass, superclass_type_args, members|
|
504
|
+
@scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
|
507
505
|
included_modules = members[:included_modules]
|
508
506
|
extended_modules = members[:extended_modules]
|
509
507
|
methods = members[:methods]
|
508
|
+
attr_methods = members[:attr_methods]
|
510
509
|
ivars = members[:ivars]
|
511
510
|
cvars = members[:cvars]
|
512
511
|
rbs_sources = members[:rbs_sources]
|
@@ -527,6 +526,14 @@ module TypeProf
|
|
527
526
|
@scratch.add_method(klass, method_name, singleton, mdef)
|
528
527
|
end
|
529
528
|
|
529
|
+
attr_methods.each do |(singleton, method_name), mdef|
|
530
|
+
kind = mdef[:kind]
|
531
|
+
ivar = mdef[:ivar]
|
532
|
+
ty = conv_type(mdef[:ty]).remove_type_vars
|
533
|
+
@scratch.add_attr_method(klass, nil, ivar, :"@#{ ivar }", kind)
|
534
|
+
@scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
|
535
|
+
end
|
536
|
+
|
530
537
|
ivars.each do |ivar_name, ty|
|
531
538
|
ty = conv_type(ty).remove_type_vars
|
532
539
|
@scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
|
@@ -593,7 +600,7 @@ module TypeProf
|
|
593
600
|
req, lead_tys, opt_tys, ret_ty = blk
|
594
601
|
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
595
602
|
opt_tys = opt_tys.map {|ty| conv_type(ty) }
|
596
|
-
msig = MethodSignature.new(lead_tys, opt_tys, nil,
|
603
|
+
msig = MethodSignature.new(lead_tys, opt_tys, nil, [], {}, nil, Type.nil)
|
597
604
|
ret_ty = conv_type(ret_ty)
|
598
605
|
ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
|
599
606
|
ret << Type.nil unless req
|
data/lib/typeprof/iseq.rb
CHANGED
@@ -49,10 +49,18 @@ module TypeProf
|
|
49
49
|
insns[i, 0] = [[:_iseq_body_start]]
|
50
50
|
end
|
51
51
|
|
52
|
+
# rescue/ensure clauses need to have a dedicated return addresses
|
53
|
+
# because they requires to be virtually called.
|
54
|
+
# So, this preprocess adds "nop" to make a new insn for their return addresses
|
55
|
+
special_labels = {}
|
56
|
+
catch_table.map do |type, iseq, first, last, cont, stack_depth|
|
57
|
+
special_labels[cont] = true if type == :rescue || type == :ensure
|
58
|
+
end
|
59
|
+
|
52
60
|
@insns = []
|
53
61
|
@linenos = []
|
54
62
|
|
55
|
-
labels = setup_iseq(insns)
|
63
|
+
labels = setup_iseq(insns, special_labels)
|
56
64
|
|
57
65
|
# checkmatch->branch
|
58
66
|
# send->branch
|
@@ -60,7 +68,8 @@ module TypeProf
|
|
60
68
|
@catch_table = []
|
61
69
|
catch_table.map do |type, iseq, first, last, cont, stack_depth|
|
62
70
|
iseq = iseq ? ISeq.new(iseq) : nil
|
63
|
-
|
71
|
+
target = labels[special_labels[cont] ? :"#{ cont }_special" : cont]
|
72
|
+
entry = [type, iseq, target, stack_depth]
|
64
73
|
labels[first].upto(labels[last]) do |i|
|
65
74
|
@catch_table[i] ||= []
|
66
75
|
@catch_table[i] << entry
|
@@ -76,19 +85,26 @@ module TypeProf
|
|
76
85
|
@id <=> other.id
|
77
86
|
end
|
78
87
|
|
79
|
-
def setup_iseq(insns)
|
88
|
+
def setup_iseq(insns, special_labels)
|
80
89
|
i = 0
|
81
90
|
labels = {}
|
91
|
+
ninsns = []
|
82
92
|
insns.each do |e|
|
83
93
|
if e.is_a?(Symbol) && e.to_s.start_with?("label")
|
94
|
+
if special_labels[e]
|
95
|
+
labels[:"#{ e }_special"] = i
|
96
|
+
ninsns << [:nop]
|
97
|
+
i += 1
|
98
|
+
end
|
84
99
|
labels[e] = i
|
85
|
-
|
86
|
-
i += 1
|
100
|
+
else
|
101
|
+
i += 1 if e.is_a?(Array)
|
102
|
+
ninsns << e
|
87
103
|
end
|
88
104
|
end
|
89
105
|
|
90
106
|
lineno = 0
|
91
|
-
|
107
|
+
ninsns.each do |e|
|
92
108
|
case e
|
93
109
|
when Integer # lineno
|
94
110
|
lineno = e
|
@@ -209,7 +225,7 @@ module TypeProf
|
|
209
225
|
end
|
210
226
|
end
|
211
227
|
send_branch_list.each do |i, j|
|
212
|
-
next if (i + 1 .. j).any? {|i| branch_targets[i] }
|
228
|
+
next if (i + 1 .. j + 1).any? {|i| branch_targets[i] }
|
213
229
|
_insn, getlocal_operands = @insns[i]
|
214
230
|
_insn, send_operands = @insns[j]
|
215
231
|
_insn, branch_operands = @insns[j + 1]
|
data/lib/typeprof/method.rb
CHANGED
@@ -4,12 +4,16 @@ module TypeProf
|
|
4
4
|
end
|
5
5
|
|
6
6
|
class ISeqMethodDef < MethodDef
|
7
|
-
def initialize(iseq, cref)
|
7
|
+
def initialize(iseq, cref, outer_ep, pub_meth)
|
8
8
|
@iseq = iseq
|
9
9
|
raise if iseq.nil?
|
10
10
|
@cref = cref
|
11
|
+
@outer_ep = outer_ep
|
12
|
+
@pub_meth = pub_meth
|
11
13
|
end
|
12
14
|
|
15
|
+
attr_accessor :pub_meth
|
16
|
+
|
13
17
|
def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
14
18
|
recv = recv.base_type while recv.respond_to?(:base_type)
|
15
19
|
recv = scratch.globalize_type(recv, caller_env, caller_ep)
|
@@ -25,8 +29,8 @@ module TypeProf
|
|
25
29
|
end
|
26
30
|
|
27
31
|
nctx = Context.new(@iseq, @cref, mid)
|
28
|
-
callee_ep = ExecutionPoint.new(nctx, 0,
|
29
|
-
nenv = Env.new(StaticEnv.new(recv, blk_ty, false), locals, [], Utils::HashWrapper.new({}))
|
32
|
+
callee_ep = ExecutionPoint.new(nctx, 0, @outer_ep)
|
33
|
+
nenv = Env.new(StaticEnv.new(recv, blk_ty, false, true), locals, [], Utils::HashWrapper.new({}))
|
30
34
|
alloc_site = AllocationSite.new(callee_ep)
|
31
35
|
locals.each_with_index do |ty, i|
|
32
36
|
alloc_site2 = alloc_site.add_id(i)
|
@@ -44,6 +48,14 @@ module TypeProf
|
|
44
48
|
end
|
45
49
|
|
46
50
|
def do_check_send(msig, recv, mid, ep, scratch)
|
51
|
+
klass, singleton = recv.method_dispatch_info
|
52
|
+
cur_subst = {}
|
53
|
+
direct_method = true
|
54
|
+
scratch.adjust_substitution(klass, singleton, mid, self, recv.generate_substitution) do |subst, direct|
|
55
|
+
direct_method &&= direct
|
56
|
+
cur_subst = Type.merge_substitution(cur_subst, subst)
|
57
|
+
end
|
58
|
+
|
47
59
|
lead_num = @iseq.fargs_format[:lead_num] || 0
|
48
60
|
post_num = @iseq.fargs_format[:post_num] || 0
|
49
61
|
rest_start = @iseq.fargs_format[:rest_start]
|
@@ -67,63 +79,75 @@ module TypeProf
|
|
67
79
|
post_start = @iseq.fargs_format[:post_start]
|
68
80
|
rest_start = @iseq.fargs_format[:rest_start]
|
69
81
|
kw_start = @iseq.fargs_format[:kwbits]
|
70
|
-
|
82
|
+
keyword = @iseq.fargs_format[:keyword]
|
83
|
+
kw_start -= keyword.size if kw_start
|
71
84
|
kw_rest = @iseq.fargs_format[:kwrest]
|
72
85
|
block_start = @iseq.fargs_format[:block_start]
|
73
86
|
|
74
87
|
# XXX: need to check .rbs msig and .rb fargs
|
75
88
|
|
76
89
|
ctx = Context.new(@iseq, @cref, mid)
|
77
|
-
callee_ep = ExecutionPoint.new(ctx, 0,
|
90
|
+
callee_ep = ExecutionPoint.new(ctx, 0, @outer_ep)
|
78
91
|
|
79
92
|
locals = [Type.nil] * @iseq.locals.size
|
80
|
-
nenv = Env.new(StaticEnv.new(recv, msig.blk_ty, false), locals, [], Utils::HashWrapper.new({}))
|
93
|
+
nenv = Env.new(StaticEnv.new(recv, msig.blk_ty, false, true), locals, [], Utils::HashWrapper.new({}))
|
81
94
|
alloc_site = AllocationSite.new(callee_ep)
|
82
95
|
idx = 0
|
83
96
|
msig.lead_tys.each_with_index do |ty, i|
|
84
97
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
85
|
-
|
86
|
-
nenv, ty =
|
98
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
99
|
+
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
87
100
|
nenv = nenv.local_update(i, ty)
|
88
101
|
end
|
89
102
|
if msig.opt_tys
|
90
103
|
msig.opt_tys.each_with_index do |ty, i|
|
91
104
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
92
|
-
|
105
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
106
|
+
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
93
107
|
nenv = nenv.local_update(lead_num + i, ty)
|
94
108
|
end
|
95
109
|
end
|
96
110
|
if msig.rest_ty
|
97
111
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
98
112
|
ty = Type::Array.new(Type::Array::Elements.new([], msig.rest_ty), Type::Instance.new(Type::Builtin[:ary]))
|
99
|
-
|
113
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
114
|
+
nenv, rest_ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
100
115
|
nenv = nenv.local_update(rest_start, rest_ty)
|
101
116
|
end
|
102
117
|
if msig.post_tys
|
103
118
|
msig.post_tys.each_with_index do |ty, i|
|
104
119
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
105
|
-
|
120
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
121
|
+
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
106
122
|
nenv = nenv.local_update(post_start + i, ty)
|
107
123
|
end
|
108
124
|
end
|
109
|
-
if msig.kw_tys
|
110
|
-
msig.kw_tys.
|
125
|
+
if msig.kw_tys && keyword # TODO: support the case where RBS writes kw_tys and RB method accepts **kwrest
|
126
|
+
msig.kw_tys.each do |_, key, ty|
|
127
|
+
i = keyword.index {|callee_key,| callee_key == key }
|
128
|
+
unless i
|
129
|
+
# warn
|
130
|
+
next
|
131
|
+
end
|
111
132
|
alloc_site2 = alloc_site.add_id(key)
|
112
|
-
|
133
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
134
|
+
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
113
135
|
nenv = nenv.local_update(kw_start + i, ty)
|
114
136
|
end
|
115
137
|
end
|
116
138
|
if msig.kw_rest_ty
|
117
139
|
ty = msig.kw_rest_ty
|
118
140
|
alloc_site2 = alloc_site.add_id(:**)
|
119
|
-
|
141
|
+
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
142
|
+
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
120
143
|
nenv = nenv.local_update(kw_rest, ty)
|
121
144
|
end
|
122
145
|
nenv = nenv.local_update(block_start, msig.blk_ty) if block_start
|
123
146
|
|
124
147
|
opt.each do |start_pc|
|
125
|
-
scratch.merge_env(
|
148
|
+
scratch.merge_env(callee_ep.jump(start_pc), nenv)
|
126
149
|
end
|
150
|
+
scratch.add_executed_iseq(@iseq)
|
127
151
|
|
128
152
|
ctx
|
129
153
|
end
|
@@ -142,8 +166,8 @@ module TypeProf
|
|
142
166
|
case @kind
|
143
167
|
when :reader
|
144
168
|
if aargs.lead_tys.size == 0
|
145
|
-
scratch.
|
146
|
-
ctn[ty, caller_ep,
|
169
|
+
scratch.add_ivar_read!(recv, @ivar, caller_ep) do |ty, _ep|
|
170
|
+
ctn[ty, caller_ep, caller_env]
|
147
171
|
end
|
148
172
|
else
|
149
173
|
ctn[Type.any, caller_ep, caller_env]
|
@@ -171,30 +195,11 @@ module TypeProf
|
|
171
195
|
def do_send(recv_orig, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
172
196
|
recv = scratch.globalize_type(recv_orig, caller_env, caller_ep)
|
173
197
|
|
174
|
-
tmp_subst = {}
|
175
|
-
case
|
176
|
-
when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
|
177
|
-
tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
|
178
|
-
tyvars.zip(recv.elems.elems) do |tyvar, elem|
|
179
|
-
if tmp_subst[tyvar]
|
180
|
-
tmp_subst[tyvar] = tmp_subst[tyvar].union(elem)
|
181
|
-
else
|
182
|
-
tmp_subst[tyvar] = elem
|
183
|
-
end
|
184
|
-
end
|
185
|
-
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
186
|
-
tmp_subst = { Type::Var.new(:Elem) => recv.elems.squash }
|
187
|
-
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
188
|
-
tyvar_k = Type::Var.new(:K)
|
189
|
-
tyvar_v = Type::Var.new(:V)
|
190
|
-
k_ty0, v_ty0 = recv.elems.squash
|
191
|
-
# XXX: need to heuristically replace ret type Hash[K, V] with self, instead of conversative type?
|
192
|
-
tmp_subst = { tyvar_k => k_ty0, tyvar_v => v_ty0 }
|
193
|
-
end
|
194
|
-
|
195
198
|
klass, singleton = recv_orig.method_dispatch_info
|
196
199
|
cur_subst = {}
|
197
|
-
|
200
|
+
direct_method = true
|
201
|
+
scratch.adjust_substitution(klass, singleton, mid, self, recv.generate_substitution) do |subst, direct|
|
202
|
+
direct_method &&= direct
|
198
203
|
cur_subst = Type.merge_substitution(cur_subst, subst)
|
199
204
|
end
|
200
205
|
|
@@ -206,45 +211,15 @@ module TypeProf
|
|
206
211
|
# XXX: support self type in msig
|
207
212
|
subst = aargs.consistent_with_method_signature?(msig)
|
208
213
|
next unless subst
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
# XXX: This should be skipped when the called methods belongs to superclass
|
213
|
-
tyvars.each_with_index do |tyvar, idx|
|
214
|
-
ty = subst[tyvar]
|
215
|
-
if ty
|
216
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
217
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
218
|
-
elems.update(idx, ty)
|
219
|
-
end
|
220
|
-
end
|
221
|
-
end
|
222
|
-
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
223
|
-
tyvar_elem = Type::Var.new(:Elem)
|
224
|
-
if subst[tyvar_elem]
|
225
|
-
ty = subst[tyvar_elem]
|
226
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
227
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
228
|
-
elems.update(nil, ty)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
232
|
-
tyvar_k = Type::Var.new(:K)
|
233
|
-
tyvar_v = Type::Var.new(:V)
|
234
|
-
if subst[tyvar_k] && subst[tyvar_v]
|
235
|
-
k_ty = subst[tyvar_k]
|
236
|
-
v_ty = subst[tyvar_v]
|
237
|
-
alloc_site = AllocationSite.new(caller_ep)
|
238
|
-
ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
|
239
|
-
ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
|
240
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
241
|
-
elems.update(k_ty, v_ty)
|
242
|
-
end
|
243
|
-
end
|
214
|
+
|
215
|
+
if direct_method && recv_orig.is_a?(Type::Local)
|
216
|
+
ncaller_env = recv_orig.update_container_elem_type(subst, ncaller_env, caller_ep, scratch)
|
244
217
|
end
|
218
|
+
|
245
219
|
subst = Type.merge_substitution(subst, cur_subst)
|
246
220
|
# need to check self tyvar?
|
247
221
|
subst[Type::Var.new(:self)] = recv
|
222
|
+
|
248
223
|
found = true
|
249
224
|
if aargs.blk_ty.is_a?(Type::Proc)
|
250
225
|
#raise NotImplementedError unless aargs.blk_ty.block_body.is_a?(ISeqBlock) # XXX
|
@@ -252,91 +227,33 @@ module TypeProf
|
|
252
227
|
dummy_ep = ExecutionPoint.new(dummy_ctx, -1, caller_ep)
|
253
228
|
s_recv = recv
|
254
229
|
s_recv = s_recv.base_type while s_recv.respond_to?(:base_type)
|
255
|
-
dummy_env = Env.new(StaticEnv.new(s_recv, msig.blk_ty, false), [], [], Utils::HashWrapper.new({}))
|
230
|
+
dummy_env = Env.new(StaticEnv.new(s_recv, msig.blk_ty, false, true), [], [], Utils::HashWrapper.new({}))
|
256
231
|
if msig.blk_ty.is_a?(Type::Proc)
|
257
232
|
scratch.add_callsite!(dummy_ctx, caller_ep, ncaller_env, &ctn)
|
258
|
-
|
233
|
+
bsig = msig.blk_ty.block_body.msig
|
259
234
|
alloc_site = AllocationSite.new(caller_ep).add_id(self)
|
260
|
-
nlead_tys = (
|
261
|
-
|
262
|
-
|
263
|
-
ty = ty.substitute(subst.merge({ tyvar_elem => recv.elems.squash_or_any }), Config.options[:type_depth_limit])
|
264
|
-
else
|
265
|
-
ty = ty.substitute(subst, Config.options[:type_depth_limit])
|
266
|
-
end
|
267
|
-
ty = ty.remove_type_vars
|
268
|
-
alloc_site2 = alloc_site.add_id(i)
|
269
|
-
dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site2)
|
235
|
+
nlead_tys = (bsig.lead_tys + bsig.opt_tys).map.with_index do |ty, i|
|
236
|
+
ty = ty.substitute(subst, Config.options[:type_depth_limit]).remove_type_vars
|
237
|
+
dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site.add_id(i))
|
270
238
|
ty
|
271
239
|
end
|
272
|
-
0.upto(
|
273
|
-
naargs = ActualArguments.new(nlead_tys[0,
|
240
|
+
0.upto(bsig.opt_tys.size) do |n|
|
241
|
+
naargs = ActualArguments.new(nlead_tys[0, bsig.lead_tys.size + n], nil, {}, Type.nil) # XXX: support block to block?
|
274
242
|
scratch.do_invoke_block(aargs.blk_ty, naargs, dummy_ep, dummy_env) do |blk_ret_ty, _ep, _env|
|
275
243
|
subst2 = Type.match?(blk_ret_ty, msig.blk_ty.block_body.ret_ty)
|
276
244
|
if subst2
|
277
245
|
subst2 = Type.merge_substitution(subst, subst2)
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
tyvars.each_with_index do |tyvar, idx|
|
282
|
-
ty = subst2[tyvar]
|
283
|
-
if ty
|
284
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
285
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
286
|
-
elems.update(idx, ty)
|
287
|
-
end
|
288
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
289
|
-
end
|
290
|
-
end
|
291
|
-
tyvars.zip(recv.elems.elems) do |tyvar, elem|
|
292
|
-
if subst2[tyvar]
|
293
|
-
subst2[tyvar] = subst2[tyvar].union(elem)
|
294
|
-
else
|
295
|
-
subst2[tyvar] = elem
|
296
|
-
end
|
297
|
-
end
|
298
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
299
|
-
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
300
|
-
tyvar_elem = Type::Var.new(:Elem)
|
301
|
-
if subst2[tyvar_elem]
|
302
|
-
ty = subst2[tyvar_elem]
|
303
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
304
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
305
|
-
elems.update(nil, ty)
|
306
|
-
end
|
307
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
308
|
-
end
|
309
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
310
|
-
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
311
|
-
tyvar_k = Type::Var.new(:K)
|
312
|
-
tyvar_v = Type::Var.new(:V)
|
313
|
-
k_ty0, v_ty0 = recv.elems.squash
|
314
|
-
if subst2[tyvar_k] && subst2[tyvar_v]
|
315
|
-
k_ty = subst2[tyvar_k]
|
316
|
-
v_ty = subst2[tyvar_v]
|
317
|
-
k_ty0 = k_ty0.union(k_ty)
|
318
|
-
v_ty0 = v_ty0.union(v_ty)
|
319
|
-
alloc_site = AllocationSite.new(caller_ep)
|
320
|
-
ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
|
321
|
-
ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
|
322
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
323
|
-
elems.update(k_ty, v_ty)
|
324
|
-
end
|
325
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
326
|
-
end
|
327
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
328
|
-
else
|
329
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
246
|
+
if direct_method && recv_orig.is_a?(Type::Local)
|
247
|
+
ncaller_env = recv_orig.update_container_elem_type(subst2, ncaller_env, caller_ep, scratch)
|
248
|
+
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
330
249
|
end
|
250
|
+
ret_ty2 = ret_ty.substitute(subst2, Config.options[:type_depth_limit]).remove_type_vars
|
331
251
|
else
|
332
|
-
|
333
|
-
# XXX: need warning
|
334
|
-
ret_ty = Type.any
|
252
|
+
ret_ty2 = Type.any
|
335
253
|
end
|
336
|
-
ret_ty = ret_ty.remove_type_vars
|
337
254
|
# XXX: check the return type from the block
|
338
255
|
# sig.blk_ty.block_body.ret_ty.eql?(_ret_ty) ???
|
339
|
-
scratch.add_return_value!(dummy_ctx,
|
256
|
+
scratch.add_return_value!(dummy_ctx, ret_ty2)
|
340
257
|
end
|
341
258
|
# scratch.add_return_value!(dummy_ctx, ret_ty) ?
|
342
259
|
# This makes `def foo; 1.times { return "str" }; end` return Integer|String
|
@@ -374,7 +291,6 @@ module TypeProf
|
|
374
291
|
end
|
375
292
|
|
376
293
|
def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
377
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(caller_env) : caller_env } # for Kernel#lambda
|
378
294
|
@impl[recv, mid, aargs, caller_ep, caller_env, scratch, &ctn]
|
379
295
|
end
|
380
296
|
end
|