typeprof 0.5.1 → 0.6.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 +1 -1
- data/lib/typeprof/analyzer.rb +145 -113
- data/lib/typeprof/builtin.rb +23 -8
- data/lib/typeprof/config.rb +10 -6
- data/lib/typeprof/container-type.rb +26 -17
- data/lib/typeprof/export.rb +6 -6
- data/lib/typeprof/import.rb +67 -32
- data/lib/typeprof/method.rb +32 -15
- data/lib/typeprof/type.rb +20 -14
- data/lib/typeprof/version.rb +1 -1
- data/smoke/array11.rb +1 -1
- data/smoke/array6.rb +2 -2
- data/smoke/array8.rb +1 -1
- data/smoke/block-args2.rb +3 -3
- data/smoke/block-args3.rb +4 -4
- data/smoke/block-blockarg.rb +1 -1
- data/smoke/block5.rb +1 -1
- data/smoke/constant2.rb +1 -2
- data/smoke/demo5.rb +1 -1
- data/smoke/demo9.rb +1 -1
- data/smoke/hash1.rb +2 -1
- data/smoke/hash4.rb +1 -1
- data/smoke/inheritance2.rb +2 -2
- data/smoke/ivar2.rb +1 -1
- data/smoke/kernel-class.rb +1 -1
- data/smoke/kwsplat1.rb +1 -1
- data/smoke/multiple-superclass.rb +1 -1
- data/smoke/parameterizedd-self.rb +2 -2
- data/smoke/parameterizedd-self2.rb +15 -0
- data/smoke/rbs-tyvar6.rb +17 -0
- data/smoke/rbs-tyvar6.rbs +12 -0
- data/smoke/struct.rb +2 -2
- data/smoke/super4.rb +43 -0
- data/smoke/super5.rb +36 -0
- data/smoke/union-recv.rb +2 -2
- metadata +7 -2
data/lib/typeprof/config.rb
CHANGED
@@ -69,19 +69,23 @@ module TypeProf
|
|
69
69
|
prologue_ep = ExecutionPoint.new(prologue_ctx, -1, nil)
|
70
70
|
prologue_env = Env.new(StaticEnv.new(:top, Type.nil, false), [], [], Utils::HashWrapper.new({}))
|
71
71
|
|
72
|
-
Config.rb_files.each do |
|
73
|
-
if
|
74
|
-
iseq = ISeq.compile_str(
|
72
|
+
Config.rb_files.each do |rb|
|
73
|
+
if rb.is_a?(Array) # [String name, String content]
|
74
|
+
iseq = ISeq.compile_str(*rb.reverse)
|
75
75
|
else
|
76
|
-
iseq = ISeq.compile(
|
76
|
+
iseq = ISeq.compile(rb)
|
77
77
|
end
|
78
78
|
ep, env = TypeProf.starting_state(iseq)
|
79
79
|
scratch.merge_env(ep, env)
|
80
80
|
scratch.add_callsite!(ep.ctx, prologue_ep, prologue_env) {|ty, ep| }
|
81
81
|
end
|
82
82
|
|
83
|
-
Config.rbs_files.each do |
|
84
|
-
|
83
|
+
Config.rbs_files.each do |rbs|
|
84
|
+
if rbs.is_a?(Array) # [String name, String content]
|
85
|
+
Import.import_rbs_code(scratch, *rbs)
|
86
|
+
else
|
87
|
+
Import.import_rbs_file(scratch, rbs)
|
88
|
+
end
|
85
89
|
end
|
86
90
|
|
87
91
|
result = scratch.type_profile
|
@@ -85,7 +85,7 @@ module TypeProf
|
|
85
85
|
Cell.new(@elems.limit_size(limit - 1), @base_type)
|
86
86
|
end
|
87
87
|
|
88
|
-
def
|
88
|
+
def method_dispatch_info
|
89
89
|
raise
|
90
90
|
end
|
91
91
|
|
@@ -214,8 +214,8 @@ module TypeProf
|
|
214
214
|
end
|
215
215
|
end
|
216
216
|
|
217
|
-
def
|
218
|
-
@base_type.
|
217
|
+
def method_dispatch_info
|
218
|
+
@base_type.method_dispatch_info
|
219
219
|
end
|
220
220
|
end
|
221
221
|
|
@@ -255,7 +255,7 @@ module TypeProf
|
|
255
255
|
Array.new(@elems.limit_size(limit - 1), @base_type)
|
256
256
|
end
|
257
257
|
|
258
|
-
def
|
258
|
+
def method_dispatch_info
|
259
259
|
raise
|
260
260
|
end
|
261
261
|
|
@@ -306,6 +306,9 @@ module TypeProf
|
|
306
306
|
|
307
307
|
def screen_name(scratch)
|
308
308
|
if Config.options[:show_container_raw_elements] || @rest_ty == Type.bot
|
309
|
+
if @lead_tys.empty?
|
310
|
+
return "Array[bot]" # RBS does not allow an empty tuple "[]"
|
311
|
+
end
|
309
312
|
s = @lead_tys.map do |ty|
|
310
313
|
ty.screen_name(scratch)
|
311
314
|
end
|
@@ -527,8 +530,8 @@ module TypeProf
|
|
527
530
|
end
|
528
531
|
end
|
529
532
|
|
530
|
-
def
|
531
|
-
@base_type.
|
533
|
+
def method_dispatch_info
|
534
|
+
@base_type.method_dispatch_info
|
532
535
|
end
|
533
536
|
end
|
534
537
|
|
@@ -562,7 +565,7 @@ module TypeProf
|
|
562
565
|
Hash.new(@elems.limit_size(limit - 1), @base_type)
|
563
566
|
end
|
564
567
|
|
565
|
-
def
|
568
|
+
def method_dispatch_info
|
566
569
|
raise
|
567
570
|
end
|
568
571
|
|
@@ -631,16 +634,22 @@ module TypeProf
|
|
631
634
|
end
|
632
635
|
|
633
636
|
def screen_name(scratch)
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
+
if !@map_tys.empty? && @map_tys.all? {|k_ty,| k_ty.is_a?(Type::Symbol) }
|
638
|
+
s = @map_tys.map do |k_ty, v_ty|
|
639
|
+
v = v_ty.screen_name(scratch)
|
637
640
|
"#{ k_ty.sym }: #{ v }"
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
+
end.join(", ")
|
642
|
+
"{#{ s }}"
|
643
|
+
else
|
644
|
+
k_ty = v_ty = Type.bot
|
645
|
+
@map_tys.each do |k, v|
|
646
|
+
k_ty = k_ty.union(k)
|
647
|
+
v_ty = v_ty.union(v)
|
641
648
|
end
|
642
|
-
|
643
|
-
|
649
|
+
k_ty = k_ty.screen_name(scratch)
|
650
|
+
v_ty = v_ty.screen_name(scratch)
|
651
|
+
"Hash[#{ k_ty }, #{ v_ty }]"
|
652
|
+
end
|
644
653
|
end
|
645
654
|
|
646
655
|
def pretty_print(q)
|
@@ -806,8 +815,8 @@ module TypeProf
|
|
806
815
|
end
|
807
816
|
end
|
808
817
|
|
809
|
-
def
|
810
|
-
@base_type.
|
818
|
+
def method_dispatch_info
|
819
|
+
@base_type.method_dispatch_info
|
811
820
|
end
|
812
821
|
end
|
813
822
|
end
|
data/lib/typeprof/export.rb
CHANGED
@@ -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
|
@@ -174,7 +174,7 @@ module TypeProf
|
|
174
174
|
cvars = cvars.map do |var, entry|
|
175
175
|
next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
|
176
176
|
[var, entry.type.screen_name(@scratch), entry.rbs_declared]
|
177
|
-
end
|
177
|
+
end.compact
|
178
178
|
|
179
179
|
if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
|
180
180
|
return nil if consts.empty? && included_mods.empty? && extended_mods.empty? && ivars.empty? && cvars.empty? && iseq_methods.empty? && attr_methods.empty? && inner_classes.empty?
|
data/lib/typeprof/import.rb
CHANGED
@@ -10,7 +10,10 @@ module TypeProf
|
|
10
10
|
def self.get_builtin_env
|
11
11
|
unless @builtin_env
|
12
12
|
@builtin_env = RBS::Environment.new
|
13
|
-
|
13
|
+
|
14
|
+
loader = RBS::EnvironmentLoader.new
|
15
|
+
new_decls = loader.load(env: @builtin_env).map {|decl,| decl }
|
16
|
+
@builtin_env_json = load_rbs(@builtin_env, new_decls)
|
14
17
|
end
|
15
18
|
|
16
19
|
return @builtin_env.dup, @builtin_env_json
|
@@ -21,27 +24,34 @@ module TypeProf
|
|
21
24
|
end
|
22
25
|
|
23
26
|
def load_library(lib)
|
24
|
-
|
27
|
+
loader = RBS::EnvironmentLoader.new(core_root: nil)
|
28
|
+
loader.add(library: lib)
|
29
|
+
new_decls = loader.load(env: @env).map {|decl,| decl }
|
30
|
+
RBSReader.load_rbs(@env, new_decls)
|
25
31
|
end
|
26
32
|
|
27
33
|
def load_path(path)
|
28
|
-
|
34
|
+
loader = RBS::EnvironmentLoader.new(core_root: nil)
|
35
|
+
loader.add(path: path)
|
36
|
+
new_decls = loader.load(env: @env).map {|decl,| decl }
|
37
|
+
RBSReader.load_rbs(@env, new_decls)
|
29
38
|
end
|
30
39
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
40
|
+
def load_rbs_string(name, content)
|
41
|
+
buffer = RBS::Buffer.new(name: name, content: content)
|
42
|
+
new_decls = []
|
43
|
+
RBS::Parser.parse_signature(buffer).each do |decl|
|
44
|
+
@env << decl
|
45
|
+
new_decls << decl
|
37
46
|
end
|
38
|
-
|
47
|
+
RBSReader.load_rbs(@env, new_decls)
|
48
|
+
end
|
39
49
|
|
50
|
+
def self.load_rbs(env, new_decls)
|
40
51
|
all_env = env.resolve_type_names
|
41
|
-
|
42
52
|
resolver = RBS::TypeNameResolver.from_env(all_env)
|
43
53
|
cur_env = RBS::Environment.new
|
44
|
-
new_decls.each do |decl
|
54
|
+
new_decls.each do |decl|
|
45
55
|
cur_env << env.resolve_declaration(resolver, decl, outer: [], prefix: RBS::Namespace.root)
|
46
56
|
end
|
47
57
|
|
@@ -52,6 +62,7 @@ module TypeProf
|
|
52
62
|
class RBS2JSON
|
53
63
|
def initialize(all_env, cur_env)
|
54
64
|
@all_env, @cur_env = all_env, cur_env
|
65
|
+
@env_walker = RBS::EnvironmentWalker.new(env: @cur_env) # Currently, only each_type_name is used
|
55
66
|
end
|
56
67
|
|
57
68
|
def dump_json
|
@@ -90,9 +101,13 @@ module TypeProf
|
|
90
101
|
json = {}
|
91
102
|
|
92
103
|
each_class_decl do |name, decls|
|
93
|
-
super_class_name = get_super_class_name(name, decls)
|
94
104
|
klass = conv_type_name(name)
|
95
|
-
|
105
|
+
super_class_name, super_class_args = get_super_class(name, decls)
|
106
|
+
if super_class_name
|
107
|
+
name = conv_type_name(super_class_name)
|
108
|
+
type_args = super_class_args.map {|type| conv_type(type) }
|
109
|
+
superclass = [name, type_args]
|
110
|
+
end
|
96
111
|
|
97
112
|
type_params = nil
|
98
113
|
included_modules = []
|
@@ -155,7 +170,8 @@ module TypeProf
|
|
155
170
|
name = member.name
|
156
171
|
if name.kind == :class
|
157
172
|
mod = conv_type_name(name)
|
158
|
-
|
173
|
+
type_args = member.args.map {|type| conv_type(type) }
|
174
|
+
included_modules << [mod, type_args]
|
159
175
|
else
|
160
176
|
# including an interface is not supported yet
|
161
177
|
end
|
@@ -164,7 +180,8 @@ module TypeProf
|
|
164
180
|
name = member.name
|
165
181
|
if name.kind == :class
|
166
182
|
mod = conv_type_name(name)
|
167
|
-
|
183
|
+
type_args = member.args.map {|type| conv_type(type) }
|
184
|
+
extended_modules << [mod, type_args]
|
168
185
|
else
|
169
186
|
# extending a module with an interface is not supported yet
|
170
187
|
end
|
@@ -221,7 +238,7 @@ module TypeProf
|
|
221
238
|
@all_env.class_decls[name].decls.each do |decl|
|
222
239
|
decl = decl.decl
|
223
240
|
next if decl.is_a?(RBS::AST::Declarations::Module)
|
224
|
-
|
241
|
+
each_reference(decl) {|name| queue << [:visit, name] }
|
225
242
|
end
|
226
243
|
queue << [:visit, name.namespace.to_type_name] if !name.namespace.empty?
|
227
244
|
end
|
@@ -236,24 +253,35 @@ module TypeProf
|
|
236
253
|
end
|
237
254
|
end
|
238
255
|
|
239
|
-
def
|
256
|
+
def each_reference(decl, &blk)
|
240
257
|
yield decl.name
|
241
|
-
|
258
|
+
if decl.super_class
|
259
|
+
name = decl.super_class.name
|
260
|
+
args = decl.super_class.args
|
261
|
+
if args
|
262
|
+
args.each do |ty|
|
263
|
+
@env_walker.each_type_name(ty, &blk)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
else
|
267
|
+
name = RBS::BuiltinNames::Object.name
|
268
|
+
end
|
242
269
|
return if decl.name == RBS::BuiltinNames::BasicObject.name
|
243
|
-
return if decl.name ==
|
244
|
-
@all_env.class_decls[
|
245
|
-
|
270
|
+
return if decl.name == name
|
271
|
+
@all_env.class_decls[name].decls.each do |decl|
|
272
|
+
each_reference(decl.decl, &blk)
|
246
273
|
end
|
247
274
|
end
|
248
275
|
|
249
|
-
def
|
276
|
+
def get_super_class(name, decls)
|
250
277
|
return nil if name == RBS::BuiltinNames::BasicObject.name
|
251
278
|
|
252
279
|
decls.each do |decl|
|
253
280
|
decl = decl.decl
|
254
281
|
case decl
|
255
282
|
when RBS::AST::Declarations::Class
|
256
|
-
|
283
|
+
super_class = decl.super_class
|
284
|
+
return super_class.name, super_class.args if super_class
|
257
285
|
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
|
258
286
|
return nil
|
259
287
|
else
|
@@ -261,7 +289,7 @@ module TypeProf
|
|
261
289
|
end
|
262
290
|
end
|
263
291
|
|
264
|
-
return RBS::BuiltinNames::Object.name
|
292
|
+
return RBS::BuiltinNames::Object.name, []
|
265
293
|
end
|
266
294
|
|
267
295
|
def conv_method_def(rbs_method_types)
|
@@ -445,6 +473,10 @@ module TypeProf
|
|
445
473
|
Import.new(scratch, scratch.rbs_reader.load_path(rbs_path)).import(true)
|
446
474
|
end
|
447
475
|
|
476
|
+
def self.import_rbs_code(scratch, rbs_name, rbs_code)
|
477
|
+
Import.new(scratch, scratch.rbs_reader.load_rbs_string(rbs_name, rbs_code)).import(true)
|
478
|
+
end
|
479
|
+
|
448
480
|
def initialize(scratch, json)
|
449
481
|
@scratch = scratch
|
450
482
|
@json = json
|
@@ -453,8 +485,8 @@ module TypeProf
|
|
453
485
|
def import(explicit = false)
|
454
486
|
classes = @json[:classes].map do |classpath, cdef|
|
455
487
|
type_params = cdef[:type_params]
|
456
|
-
superclass
|
457
|
-
members
|
488
|
+
superclass, superclass_type_args = cdef[:superclass]
|
489
|
+
members = cdef[:members]
|
458
490
|
|
459
491
|
name = classpath.last
|
460
492
|
superclass = path_to_klass(superclass) if superclass
|
@@ -462,7 +494,8 @@ module TypeProf
|
|
462
494
|
|
463
495
|
klass = @scratch.get_constant(base_klass, name)
|
464
496
|
if klass.is_a?(Type::Any)
|
465
|
-
|
497
|
+
superclass_type_args = superclass_type_args&.map {|ty| conv_type(ty) }
|
498
|
+
klass = @scratch.new_class(base_klass, name, type_params, superclass, superclass_type_args, nil)
|
466
499
|
|
467
500
|
# There builtin classes are needed to interpret RBS declarations
|
468
501
|
case classpath
|
@@ -489,12 +522,14 @@ module TypeProf
|
|
489
522
|
cvars = members[:cvars]
|
490
523
|
rbs_sources = members[:rbs_sources]
|
491
524
|
|
492
|
-
included_modules.each do |mod|
|
493
|
-
|
525
|
+
included_modules.each do |mod, type_args|
|
526
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
527
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, false, nil)
|
494
528
|
end
|
495
529
|
|
496
|
-
extended_modules.each do |mod|
|
497
|
-
|
530
|
+
extended_modules.each do |mod, type_args|
|
531
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
532
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, true, nil)
|
498
533
|
end
|
499
534
|
|
500
535
|
methods.each do |(singleton, method_name), mdef|
|
data/lib/typeprof/method.rb
CHANGED
@@ -170,6 +170,34 @@ module TypeProf
|
|
170
170
|
|
171
171
|
def do_send(recv_orig, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
172
172
|
recv = scratch.globalize_type(recv_orig, caller_env, caller_ep)
|
173
|
+
|
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
|
+
klass, singleton = recv_orig.method_dispatch_info
|
196
|
+
cur_subst = {}
|
197
|
+
scratch.generate_substitution(klass, singleton, mid, self, tmp_subst) do |subst|
|
198
|
+
cur_subst = Type.merge_substitution(cur_subst, subst)
|
199
|
+
end
|
200
|
+
|
173
201
|
found = false
|
174
202
|
aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
|
175
203
|
@sig_rets.each do |msig, ret_ty|
|
@@ -178,11 +206,10 @@ module TypeProf
|
|
178
206
|
# XXX: support self type in msig
|
179
207
|
subst = aargs.consistent_with_method_signature?(msig)
|
180
208
|
next unless subst
|
181
|
-
# need to check self tyvar?
|
182
|
-
subst[Type::Var.new(:self)] = recv
|
183
209
|
case
|
184
210
|
when recv.is_a?(Type::Cell) && recv_orig.is_a?(Type::LocalCell)
|
185
211
|
tyvars = recv.base_type.klass.type_params.map {|name,| Type::Var.new(name) }
|
212
|
+
# XXX: This should be skipped when the called methods belongs to superclass
|
186
213
|
tyvars.each_with_index do |tyvar, idx|
|
187
214
|
ty = subst[tyvar]
|
188
215
|
if ty
|
@@ -192,13 +219,6 @@ module TypeProf
|
|
192
219
|
end
|
193
220
|
end
|
194
221
|
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
222
|
when recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
|
203
223
|
tyvar_elem = Type::Var.new(:Elem)
|
204
224
|
if subst[tyvar_elem]
|
@@ -208,16 +228,12 @@ module TypeProf
|
|
208
228
|
elems.update(nil, ty)
|
209
229
|
end
|
210
230
|
end
|
211
|
-
subst.merge!({ tyvar_elem => recv.elems.squash })
|
212
231
|
when recv.is_a?(Type::Hash) && recv_orig.is_a?(Type::LocalHash)
|
213
232
|
tyvar_k = Type::Var.new(:K)
|
214
233
|
tyvar_v = Type::Var.new(:V)
|
215
|
-
k_ty0, v_ty0 = recv.elems.squash
|
216
234
|
if subst[tyvar_k] && subst[tyvar_v]
|
217
235
|
k_ty = subst[tyvar_k]
|
218
236
|
v_ty = subst[tyvar_v]
|
219
|
-
k_ty0 = k_ty0.union(k_ty)
|
220
|
-
v_ty0 = v_ty0.union(v_ty)
|
221
237
|
alloc_site = AllocationSite.new(caller_ep)
|
222
238
|
ncaller_env, k_ty = scratch.localize_type(k_ty, ncaller_env, caller_ep, alloc_site.add_id(:k))
|
223
239
|
ncaller_env, v_ty = scratch.localize_type(v_ty, ncaller_env, caller_ep, alloc_site.add_id(:v))
|
@@ -225,9 +241,10 @@ module TypeProf
|
|
225
241
|
elems.update(k_ty, v_ty)
|
226
242
|
end
|
227
243
|
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
244
|
end
|
245
|
+
subst = Type.merge_substitution(subst, cur_subst)
|
246
|
+
# need to check self tyvar?
|
247
|
+
subst[Type::Var.new(:self)] = recv
|
231
248
|
found = true
|
232
249
|
if aargs.blk_ty.is_a?(Type::Proc)
|
233
250
|
#raise NotImplementedError unless aargs.blk_ty.block_body.is_a?(ISeqBlock) # XXX
|