typeprof 0.5.4 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 +308 -171
- data/lib/typeprof/arguments.rb +14 -6
- data/lib/typeprof/block.rb +6 -2
- data/lib/typeprof/builtin.rb +230 -67
- data/lib/typeprof/cli.rb +33 -34
- data/lib/typeprof/config.rb +6 -4
- data/lib/typeprof/container-type.rb +159 -104
- data/lib/typeprof/export.rb +28 -22
- data/lib/typeprof/import.rb +70 -53
- data/lib/typeprof/iseq.rb +23 -7
- data/lib/typeprof/method.rb +71 -138
- data/lib/typeprof/type.rb +73 -15
- 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/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 +15 -0
- 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 +18 -0
- data/smoke/rbs-tyvar6.rbs +12 -0
- 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 +43 -0
- data/smoke/super5.rb +36 -0
- 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 +61 -6
- 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
|
@@ -91,9 +91,9 @@ module TypeProf
|
|
91
91
|
def conv_class(namespace, class_def, inner_classes)
|
92
92
|
@scratch.namespace = namespace
|
93
93
|
|
94
|
-
if class_def.superclass
|
95
|
-
omit =
|
96
|
-
superclass = omit ? nil : @scratch.get_class_name(
|
94
|
+
if class_def.klass_obj.superclass != :__root__ && class_def.klass_obj.superclass
|
95
|
+
omit = class_def.klass_obj.superclass == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
|
96
|
+
superclass = omit ? nil : @scratch.get_class_name(class_def.klass_obj.superclass)
|
97
97
|
end
|
98
98
|
|
99
99
|
@scratch.namespace = class_def.name
|
@@ -105,12 +105,12 @@ module TypeProf
|
|
105
105
|
consts[name] = ty.screen_name(@scratch)
|
106
106
|
end
|
107
107
|
|
108
|
-
included_mods = class_def.modules[false].filter_map do |mod_def, absolute_paths|
|
108
|
+
included_mods = class_def.modules[false].filter_map do |mod_def, _type_args, absolute_paths|
|
109
109
|
next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
|
110
110
|
Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
|
111
111
|
end
|
112
112
|
|
113
|
-
extended_mods = class_def.modules[true].filter_map do |mod_def, absolute_paths|
|
113
|
+
extended_mods = class_def.modules[true].filter_map do |mod_def, _type_args, absolute_paths|
|
114
114
|
next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
|
115
115
|
Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
|
116
116
|
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
|
@@ -100,14 +107,19 @@ module TypeProf
|
|
100
107
|
json = {}
|
101
108
|
|
102
109
|
each_class_decl do |name, decls|
|
103
|
-
super_class_name = get_super_class_name(name, decls)
|
104
110
|
klass = conv_type_name(name)
|
105
|
-
|
111
|
+
super_class_name, super_class_args = get_super_class(name, decls)
|
112
|
+
if super_class_name
|
113
|
+
name = conv_type_name(super_class_name)
|
114
|
+
type_args = super_class_args.map {|type| conv_type(type) }
|
115
|
+
superclass = [name, type_args]
|
116
|
+
end
|
106
117
|
|
107
118
|
type_params = nil
|
108
119
|
included_modules = []
|
109
120
|
extended_modules = []
|
110
121
|
methods = {}
|
122
|
+
attr_methods = {}
|
111
123
|
ivars = {}
|
112
124
|
cvars = {}
|
113
125
|
rbs_sources = {}
|
@@ -143,15 +155,15 @@ module TypeProf
|
|
143
155
|
end
|
144
156
|
when RBS::AST::Members::AttrReader
|
145
157
|
ty = conv_type(member.type)
|
146
|
-
|
158
|
+
attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
|
147
159
|
when RBS::AST::Members::AttrWriter
|
148
160
|
ty = conv_type(member.type)
|
149
|
-
|
161
|
+
attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
|
150
162
|
when RBS::AST::Members::AttrAccessor
|
151
163
|
ty = conv_type(member.type)
|
152
|
-
|
153
|
-
methods[[false, :"#{ member.name }="]] = attr_writer_def(ty)
|
164
|
+
attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
|
154
165
|
when RBS::AST::Members::Alias
|
166
|
+
# XXX: an alias to attr methods?
|
155
167
|
if member.instance?
|
156
168
|
method_def = methods[[false, member.old_name]]
|
157
169
|
methods[[false, member.new_name]] = method_def if method_def
|
@@ -165,7 +177,8 @@ module TypeProf
|
|
165
177
|
name = member.name
|
166
178
|
if name.kind == :class
|
167
179
|
mod = conv_type_name(name)
|
168
|
-
|
180
|
+
type_args = member.args.map {|type| conv_type(type) }
|
181
|
+
included_modules << [mod, type_args]
|
169
182
|
else
|
170
183
|
# including an interface is not supported yet
|
171
184
|
end
|
@@ -174,7 +187,8 @@ module TypeProf
|
|
174
187
|
name = member.name
|
175
188
|
if name.kind == :class
|
176
189
|
mod = conv_type_name(name)
|
177
|
-
|
190
|
+
type_args = member.args.map {|type| conv_type(type) }
|
191
|
+
extended_modules << [mod, type_args]
|
178
192
|
else
|
179
193
|
# extending a module with an interface is not supported yet
|
180
194
|
end
|
@@ -205,6 +219,7 @@ module TypeProf
|
|
205
219
|
included_modules: included_modules,
|
206
220
|
extended_modules: extended_modules,
|
207
221
|
methods: methods,
|
222
|
+
attr_methods: attr_methods,
|
208
223
|
ivars: ivars,
|
209
224
|
cvars: cvars,
|
210
225
|
rbs_sources: rbs_sources,
|
@@ -231,7 +246,7 @@ module TypeProf
|
|
231
246
|
@all_env.class_decls[name].decls.each do |decl|
|
232
247
|
decl = decl.decl
|
233
248
|
next if decl.is_a?(RBS::AST::Declarations::Module)
|
234
|
-
|
249
|
+
each_reference(decl) {|name| queue << [:visit, name] }
|
235
250
|
end
|
236
251
|
queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
|
237
252
|
end
|
@@ -246,24 +261,32 @@ module TypeProf
|
|
246
261
|
end
|
247
262
|
end
|
248
263
|
|
249
|
-
def
|
264
|
+
def each_reference(decl, &blk)
|
250
265
|
yield decl.name
|
251
|
-
|
266
|
+
if decl.super_class
|
267
|
+
name = decl.super_class.name
|
268
|
+
else
|
269
|
+
name = RBS::BuiltinNames::Object.name
|
270
|
+
end
|
252
271
|
return if decl.name == RBS::BuiltinNames::BasicObject.name
|
253
|
-
return if decl.name ==
|
254
|
-
@all_env.class_decls[
|
255
|
-
|
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
|
256
278
|
end
|
257
279
|
end
|
258
280
|
|
259
|
-
def
|
281
|
+
def get_super_class(name, decls)
|
260
282
|
return nil if name == RBS::BuiltinNames::BasicObject.name
|
261
283
|
|
262
284
|
decls.each do |decl|
|
263
285
|
decl = decl.decl
|
264
286
|
case decl
|
265
287
|
when RBS::AST::Declarations::Class
|
266
|
-
|
288
|
+
super_class = decl.super_class
|
289
|
+
return super_class.name, super_class.args if super_class
|
267
290
|
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
|
268
291
|
return nil
|
269
292
|
else
|
@@ -271,7 +294,7 @@ module TypeProf
|
|
271
294
|
end
|
272
295
|
end
|
273
296
|
|
274
|
-
return RBS::BuiltinNames::Object.name
|
297
|
+
return RBS::BuiltinNames::Object.name, []
|
275
298
|
end
|
276
299
|
|
277
300
|
def conv_method_def(rbs_method_types)
|
@@ -290,7 +313,7 @@ module TypeProf
|
|
290
313
|
opt_kw_tys = func.optional_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
291
314
|
req_kw_tys = func.required_keywords.to_h {|key, type| [key, conv_type(type.type)] }
|
292
315
|
rest_kw_ty = func.rest_keywords
|
293
|
-
|
316
|
+
rest_kw_ty = conv_type(rest_kw_ty.type) if rest_kw_ty
|
294
317
|
|
295
318
|
ret_ty = conv_type(func.return_type)
|
296
319
|
|
@@ -307,32 +330,12 @@ module TypeProf
|
|
307
330
|
}
|
308
331
|
end
|
309
332
|
|
310
|
-
def
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
req_kw_tys: {},
|
317
|
-
opt_kw_tys: {},
|
318
|
-
rest_kw_ty: nil,
|
319
|
-
blk: nil,
|
320
|
-
ret_ty: ty,
|
321
|
-
}]
|
322
|
-
end
|
323
|
-
|
324
|
-
def attr_writer_def(ty)
|
325
|
-
[{
|
326
|
-
type_params: [],
|
327
|
-
lead_tys: [ty],
|
328
|
-
opt_tys: [],
|
329
|
-
rest_ty: nil,
|
330
|
-
req_kw_tys: {},
|
331
|
-
opt_kw_tys: {},
|
332
|
-
rest_kw_ty: nil,
|
333
|
-
blk: nil,
|
334
|
-
ret_ty: ty,
|
335
|
-
}]
|
333
|
+
def attr_method_def(kind, name, ty)
|
334
|
+
{
|
335
|
+
kind: kind,
|
336
|
+
ivar: name,
|
337
|
+
ty: ty,
|
338
|
+
}
|
336
339
|
end
|
337
340
|
|
338
341
|
def conv_block(rbs_block)
|
@@ -445,6 +448,8 @@ module TypeProf
|
|
445
448
|
json = scratch.rbs_reader.load_library(feature)
|
446
449
|
rescue RBS::EnvironmentLoader::UnknownLibraryError
|
447
450
|
return nil
|
451
|
+
rescue RBS::DuplicatedDeclarationError
|
452
|
+
return true
|
448
453
|
end
|
449
454
|
# need cache?
|
450
455
|
Import.new(scratch, json).import
|
@@ -467,8 +472,8 @@ module TypeProf
|
|
467
472
|
def import(explicit = false)
|
468
473
|
classes = @json[:classes].map do |classpath, cdef|
|
469
474
|
type_params = cdef[:type_params]
|
470
|
-
superclass
|
471
|
-
members
|
475
|
+
superclass, superclass_type_args = cdef[:superclass]
|
476
|
+
members = cdef[:members]
|
472
477
|
|
473
478
|
name = classpath.last
|
474
479
|
superclass = path_to_klass(superclass) if superclass
|
@@ -492,23 +497,27 @@ module TypeProf
|
|
492
497
|
end
|
493
498
|
end
|
494
499
|
|
495
|
-
[klass, members]
|
500
|
+
[klass, superclass_type_args, members]
|
496
501
|
end
|
497
502
|
|
498
|
-
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) })
|
499
505
|
included_modules = members[:included_modules]
|
500
506
|
extended_modules = members[:extended_modules]
|
501
507
|
methods = members[:methods]
|
508
|
+
attr_methods = members[:attr_methods]
|
502
509
|
ivars = members[:ivars]
|
503
510
|
cvars = members[:cvars]
|
504
511
|
rbs_sources = members[:rbs_sources]
|
505
512
|
|
506
|
-
included_modules.each do |mod|
|
507
|
-
|
513
|
+
included_modules.each do |mod, type_args|
|
514
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
515
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, false, nil)
|
508
516
|
end
|
509
517
|
|
510
|
-
extended_modules.each do |mod|
|
511
|
-
|
518
|
+
extended_modules.each do |mod, type_args|
|
519
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
520
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, true, nil)
|
512
521
|
end
|
513
522
|
|
514
523
|
methods.each do |(singleton, method_name), mdef|
|
@@ -517,6 +526,14 @@ module TypeProf
|
|
517
526
|
@scratch.add_method(klass, method_name, singleton, mdef)
|
518
527
|
end
|
519
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
|
+
|
520
537
|
ivars.each do |ivar_name, ty|
|
521
538
|
ty = conv_type(ty).remove_type_vars
|
522
539
|
@scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
|
@@ -583,7 +600,7 @@ module TypeProf
|
|
583
600
|
req, lead_tys, opt_tys, ret_ty = blk
|
584
601
|
lead_tys = lead_tys.map {|ty| conv_type(ty) }
|
585
602
|
opt_tys = opt_tys.map {|ty| conv_type(ty) }
|
586
|
-
msig = MethodSignature.new(lead_tys, opt_tys, nil,
|
603
|
+
msig = MethodSignature.new(lead_tys, opt_tys, nil, [], {}, nil, Type.nil)
|
587
604
|
ret_ty = conv_type(ret_ty)
|
588
605
|
ret = [Type::Proc.new(TypedBlock.new(msig, ret_ty), Type::Builtin[:proc])]
|
589
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]
|
@@ -170,6 +194,15 @@ module TypeProf
|
|
170
194
|
|
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)
|
197
|
+
|
198
|
+
klass, singleton = recv_orig.method_dispatch_info
|
199
|
+
cur_subst = {}
|
200
|
+
direct_method = true
|
201
|
+
scratch.adjust_substitution(klass, singleton, mid, self, recv.generate_substitution) do |subst, direct|
|
202
|
+
direct_method &&= direct
|
203
|
+
cur_subst = Type.merge_substitution(cur_subst, subst)
|
204
|
+
end
|
205
|
+
|
173
206
|
found = false
|
174
207
|
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
175
208
|
@sig_rets.each do |msig, ret_ty|
|
@@ -178,56 +211,15 @@ module TypeProf
|
|
178
211
|
# XXX: support self type in msig
|
179
212
|
subst = aargs.consistent_with_method_signature?(msig)
|
180
213
|
next unless subst
|
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)
|
217
|
+
end
|
218
|
+
|
219
|
+
subst = Type.merge_substitution(subst, cur_subst)
|
181
220
|
# need to check self tyvar?
|
182
221
|
subst[Type::Var.new(:self)] = recv
|
183
|
-
|
184
|
-
when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
|
185
|
-
tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
|
186
|
-
tyvars.each_with_index do |tyvar, idx|
|
187
|
-
ty = subst[tyvar]
|
188
|
-
if ty
|
189
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
190
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
191
|
-
elems.update(idx, ty)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
end
|
195
|
-
tyvars.zip(recv.elems.elems) do |tyvar, elem|
|
196
|
-
if subst[tyvar]
|
197
|
-
subst[tyvar] = subst[tyvar].union(elem)
|
198
|
-
else
|
199
|
-
subst[tyvar] = elem
|
200
|
-
end
|
201
|
-
end
|
202
|
-
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
203
|
-
tyvar_elem = Type::Var.new(:Elem)
|
204
|
-
if subst[tyvar_elem]
|
205
|
-
ty = subst[tyvar_elem]
|
206
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
207
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
208
|
-
elems.update(nil, ty)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
subst.merge!({ tyvar_elem => recv.elems.squash })
|
212
|
-
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
213
|
-
tyvar_k = Type::Var.new(:K)
|
214
|
-
tyvar_v = Type::Var.new(:V)
|
215
|
-
k_ty0, v_ty0 = recv.elems.squash
|
216
|
-
if subst[tyvar_k] && subst[tyvar_v]
|
217
|
-
k_ty = subst[tyvar_k]
|
218
|
-
v_ty = subst[tyvar_v]
|
219
|
-
k_ty0 = k_ty0.union(k_ty)
|
220
|
-
v_ty0 = v_ty0.union(v_ty)
|
221
|
-
alloc_site = AllocationSite.new(caller_ep)
|
222
|
-
ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
|
223
|
-
ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
|
224
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
225
|
-
elems.update(k_ty, v_ty)
|
226
|
-
end
|
227
|
-
end
|
228
|
-
# XXX: need to heuristically replace ret type Hash[K, V] with self, instead of conversative type?
|
229
|
-
subst.merge!({ tyvar_k => k_ty0, tyvar_v => v_ty0 })
|
230
|
-
end
|
222
|
+
|
231
223
|
found = true
|
232
224
|
if aargs.blk_ty.is_a?(Type::Proc)
|
233
225
|
#raise NotImplementedError unless aargs.blk_ty.block_body.is_a?(ISeqBlock) # XXX
|
@@ -235,91 +227,33 @@ module TypeProf
|
|
235
227
|
dummy_ep = ExecutionPoint.new(dummy_ctx, -1, caller_ep)
|
236
228
|
s_recv = recv
|
237
229
|
s_recv = s_recv.base_type while s_recv.respond_to?(:base_type)
|
238
|
-
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({}))
|
239
231
|
if msig.blk_ty.is_a?(Type::Proc)
|
240
232
|
scratch.add_callsite!(dummy_ctx, caller_ep, ncaller_env, &ctn)
|
241
|
-
|
233
|
+
bsig = msig.blk_ty.block_body.msig
|
242
234
|
alloc_site = AllocationSite.new(caller_ep).add_id(self)
|
243
|
-
nlead_tys = (
|
244
|
-
|
245
|
-
|
246
|
-
ty = ty.substitute(subst.merge({ tyvar_elem => recv.elems.squash_or_any }), Config.options[:type_depth_limit])
|
247
|
-
else
|
248
|
-
ty = ty.substitute(subst, Config.options[:type_depth_limit])
|
249
|
-
end
|
250
|
-
ty = ty.remove_type_vars
|
251
|
-
alloc_site2 = alloc_site.add_id(i)
|
252
|
-
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))
|
253
238
|
ty
|
254
239
|
end
|
255
|
-
0.upto(
|
256
|
-
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?
|
257
242
|
scratch.do_invoke_block(aargs.blk_ty, naargs, dummy_ep, dummy_env) do |blk_ret_ty, _ep, _env|
|
258
243
|
subst2 = Type.match?(blk_ret_ty, msig.blk_ty.block_body.ret_ty)
|
259
244
|
if subst2
|
260
245
|
subst2 = Type.merge_substitution(subst, subst2)
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
tyvars.each_with_index do |tyvar, idx|
|
265
|
-
ty = subst2[tyvar]
|
266
|
-
if ty
|
267
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
268
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
269
|
-
elems.update(idx, ty)
|
270
|
-
end
|
271
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
272
|
-
end
|
273
|
-
end
|
274
|
-
tyvars.zip(recv.elems.elems) do |tyvar, elem|
|
275
|
-
if subst2[tyvar]
|
276
|
-
subst2[tyvar] = subst2[tyvar].union(elem)
|
277
|
-
else
|
278
|
-
subst2[tyvar] = elem
|
279
|
-
end
|
280
|
-
end
|
281
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
282
|
-
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
283
|
-
tyvar_elem = Type::Var.new(:Elem)
|
284
|
-
if subst2[tyvar_elem]
|
285
|
-
ty = subst2[tyvar_elem]
|
286
|
-
ncaller_env, ty = scratch.localize_type(ty, ncaller_env, caller_ep)
|
287
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
288
|
-
elems.update(nil, ty)
|
289
|
-
end
|
290
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
291
|
-
end
|
292
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
293
|
-
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
294
|
-
tyvar_k = Type::Var.new(:K)
|
295
|
-
tyvar_v = Type::Var.new(:V)
|
296
|
-
k_ty0, v_ty0 = recv.elems.squash
|
297
|
-
if subst2[tyvar_k] && subst2[tyvar_v]
|
298
|
-
k_ty = subst2[tyvar_k]
|
299
|
-
v_ty = subst2[tyvar_v]
|
300
|
-
k_ty0 = k_ty0.union(k_ty)
|
301
|
-
v_ty0 = v_ty0.union(v_ty)
|
302
|
-
alloc_site = AllocationSite.new(caller_ep)
|
303
|
-
ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
|
304
|
-
ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
|
305
|
-
ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id, recv_orig.base_type) do |elems|
|
306
|
-
elems.update(k_ty, v_ty)
|
307
|
-
end
|
308
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
309
|
-
end
|
310
|
-
ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
|
311
|
-
else
|
312
|
-
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 }
|
313
249
|
end
|
250
|
+
ret_ty2 = ret_ty.substitute(subst2, Config.options[:type_depth_limit]).remove_type_vars
|
314
251
|
else
|
315
|
-
|
316
|
-
# XXX: need warning
|
317
|
-
ret_ty = Type.any
|
252
|
+
ret_ty2 = Type.any
|
318
253
|
end
|
319
|
-
ret_ty = ret_ty.remove_type_vars
|
320
254
|
# XXX: check the return type from the block
|
321
255
|
# sig.blk_ty.block_body.ret_ty.eql?(_ret_ty) ???
|
322
|
-
scratch.add_return_value!(dummy_ctx,
|
256
|
+
scratch.add_return_value!(dummy_ctx, ret_ty2)
|
323
257
|
end
|
324
258
|
# scratch.add_return_value!(dummy_ctx, ret_ty) ?
|
325
259
|
# This makes `def foo; 1.times { return "str" }; end` return Integer|String
|
@@ -357,7 +291,6 @@ module TypeProf
|
|
357
291
|
end
|
358
292
|
|
359
293
|
def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
360
|
-
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(caller_env) : caller_env } # for Kernel#lambda
|
361
294
|
@impl[recv, mid, aargs, caller_ep, caller_env, scratch, &ctn]
|
362
295
|
end
|
363
296
|
end
|