typeprof 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +3 -3
- 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 +50 -26
- 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/hash-merge-bang.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
- data/typeprof.gemspec +1 -1
- metadata +9 -4
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
|
|
|
@@ -90,9 +100,13 @@ module TypeProf
|
|
|
90
100
|
json = {}
|
|
91
101
|
|
|
92
102
|
each_class_decl do |name, decls|
|
|
93
|
-
super_class_name = get_super_class_name(name, decls)
|
|
94
103
|
klass = conv_type_name(name)
|
|
95
|
-
|
|
104
|
+
super_class_name, super_class_args = get_super_class(name, decls)
|
|
105
|
+
if super_class_name
|
|
106
|
+
name = conv_type_name(super_class_name)
|
|
107
|
+
type_args = super_class_args.map {|type| conv_type(type) }
|
|
108
|
+
superclass = [name, type_args]
|
|
109
|
+
end
|
|
96
110
|
|
|
97
111
|
type_params = nil
|
|
98
112
|
included_modules = []
|
|
@@ -155,7 +169,8 @@ module TypeProf
|
|
|
155
169
|
name = member.name
|
|
156
170
|
if name.kind == :class
|
|
157
171
|
mod = conv_type_name(name)
|
|
158
|
-
|
|
172
|
+
type_args = member.args.map {|type| conv_type(type) }
|
|
173
|
+
included_modules << [mod, type_args]
|
|
159
174
|
else
|
|
160
175
|
# including an interface is not supported yet
|
|
161
176
|
end
|
|
@@ -164,7 +179,8 @@ module TypeProf
|
|
|
164
179
|
name = member.name
|
|
165
180
|
if name.kind == :class
|
|
166
181
|
mod = conv_type_name(name)
|
|
167
|
-
|
|
182
|
+
type_args = member.args.map {|type| conv_type(type) }
|
|
183
|
+
extended_modules << [mod, type_args]
|
|
168
184
|
else
|
|
169
185
|
# extending a module with an interface is not supported yet
|
|
170
186
|
end
|
|
@@ -246,14 +262,15 @@ module TypeProf
|
|
|
246
262
|
end
|
|
247
263
|
end
|
|
248
264
|
|
|
249
|
-
def
|
|
265
|
+
def get_super_class(name, decls)
|
|
250
266
|
return nil if name == RBS::BuiltinNames::BasicObject.name
|
|
251
267
|
|
|
252
268
|
decls.each do |decl|
|
|
253
269
|
decl = decl.decl
|
|
254
270
|
case decl
|
|
255
271
|
when RBS::AST::Declarations::Class
|
|
256
|
-
|
|
272
|
+
super_class = decl.super_class
|
|
273
|
+
return super_class.name, super_class.args if super_class
|
|
257
274
|
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Interface
|
|
258
275
|
return nil
|
|
259
276
|
else
|
|
@@ -261,7 +278,7 @@ module TypeProf
|
|
|
261
278
|
end
|
|
262
279
|
end
|
|
263
280
|
|
|
264
|
-
return RBS::BuiltinNames::Object.name
|
|
281
|
+
return RBS::BuiltinNames::Object.name, []
|
|
265
282
|
end
|
|
266
283
|
|
|
267
284
|
def conv_method_def(rbs_method_types)
|
|
@@ -445,6 +462,10 @@ module TypeProf
|
|
|
445
462
|
Import.new(scratch, scratch.rbs_reader.load_path(rbs_path)).import(true)
|
|
446
463
|
end
|
|
447
464
|
|
|
465
|
+
def self.import_rbs_code(scratch, rbs_name, rbs_code)
|
|
466
|
+
Import.new(scratch, scratch.rbs_reader.load_rbs_string(rbs_name, rbs_code)).import(true)
|
|
467
|
+
end
|
|
468
|
+
|
|
448
469
|
def initialize(scratch, json)
|
|
449
470
|
@scratch = scratch
|
|
450
471
|
@json = json
|
|
@@ -453,8 +474,8 @@ module TypeProf
|
|
|
453
474
|
def import(explicit = false)
|
|
454
475
|
classes = @json[:classes].map do |classpath, cdef|
|
|
455
476
|
type_params = cdef[:type_params]
|
|
456
|
-
superclass
|
|
457
|
-
members
|
|
477
|
+
superclass, superclass_type_args = cdef[:superclass]
|
|
478
|
+
members = cdef[:members]
|
|
458
479
|
|
|
459
480
|
name = classpath.last
|
|
460
481
|
superclass = path_to_klass(superclass) if superclass
|
|
@@ -462,7 +483,8 @@ module TypeProf
|
|
|
462
483
|
|
|
463
484
|
klass = @scratch.get_constant(base_klass, name)
|
|
464
485
|
if klass.is_a?(Type::Any)
|
|
465
|
-
|
|
486
|
+
superclass_type_args = superclass_type_args&.map {|ty| conv_type(ty) }
|
|
487
|
+
klass = @scratch.new_class(base_klass, name, type_params, superclass, superclass_type_args, nil)
|
|
466
488
|
|
|
467
489
|
# There builtin classes are needed to interpret RBS declarations
|
|
468
490
|
case classpath
|
|
@@ -489,12 +511,14 @@ module TypeProf
|
|
|
489
511
|
cvars = members[:cvars]
|
|
490
512
|
rbs_sources = members[:rbs_sources]
|
|
491
513
|
|
|
492
|
-
included_modules.each do |mod|
|
|
493
|
-
|
|
514
|
+
included_modules.each do |mod, type_args|
|
|
515
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
|
516
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, false, nil)
|
|
494
517
|
end
|
|
495
518
|
|
|
496
|
-
extended_modules.each do |mod|
|
|
497
|
-
|
|
519
|
+
extended_modules.each do |mod, type_args|
|
|
520
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
|
521
|
+
@scratch.include_module(klass, path_to_klass(mod), type_args, true, nil)
|
|
498
522
|
end
|
|
499
523
|
|
|
500
524
|
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
|
data/lib/typeprof/type.rb
CHANGED
|
@@ -170,7 +170,7 @@ module TypeProf
|
|
|
170
170
|
"untyped"
|
|
171
171
|
end
|
|
172
172
|
|
|
173
|
-
def
|
|
173
|
+
def method_dispatch_info
|
|
174
174
|
nil
|
|
175
175
|
end
|
|
176
176
|
|
|
@@ -430,15 +430,17 @@ module TypeProf
|
|
|
430
430
|
end
|
|
431
431
|
|
|
432
432
|
class Class < Type # or Module
|
|
433
|
-
def initialize(kind, idx, type_params, superclass, name)
|
|
433
|
+
def initialize(kind, idx, type_params, superclass, superclass_type_args, name)
|
|
434
434
|
@kind = kind # :class | :module
|
|
435
435
|
@idx = idx
|
|
436
436
|
@type_params = type_params
|
|
437
437
|
@superclass = superclass
|
|
438
|
+
raise if @kind == :class && !@superclass
|
|
439
|
+
@superclass_type_args = superclass_type_args
|
|
438
440
|
@_name = name
|
|
439
441
|
end
|
|
440
442
|
|
|
441
|
-
attr_reader :kind, :idx, :type_params, :superclass
|
|
443
|
+
attr_reader :kind, :idx, :type_params, :superclass, :superclass_type_args
|
|
442
444
|
|
|
443
445
|
def inspect
|
|
444
446
|
if @_name
|
|
@@ -449,11 +451,11 @@ module TypeProf
|
|
|
449
451
|
end
|
|
450
452
|
|
|
451
453
|
def screen_name(scratch)
|
|
452
|
-
"#{ scratch.get_class_name(self) }
|
|
454
|
+
"singleton(#{ scratch.get_class_name(self) })"
|
|
453
455
|
end
|
|
454
456
|
|
|
455
|
-
def
|
|
456
|
-
|
|
457
|
+
def method_dispatch_info
|
|
458
|
+
[self, true]
|
|
457
459
|
end
|
|
458
460
|
|
|
459
461
|
def consistent?(other)
|
|
@@ -504,8 +506,8 @@ module TypeProf
|
|
|
504
506
|
end
|
|
505
507
|
end
|
|
506
508
|
|
|
507
|
-
def
|
|
508
|
-
|
|
509
|
+
def method_dispatch_info
|
|
510
|
+
[@klass, false]
|
|
509
511
|
end
|
|
510
512
|
|
|
511
513
|
def consistent?(other)
|
|
@@ -558,8 +560,8 @@ module TypeProf
|
|
|
558
560
|
end
|
|
559
561
|
end
|
|
560
562
|
|
|
561
|
-
def
|
|
562
|
-
@base_type.
|
|
563
|
+
def method_dispatch_info
|
|
564
|
+
@base_type.method_dispatch_info
|
|
563
565
|
end
|
|
564
566
|
|
|
565
567
|
def substitute(subst, depth)
|
|
@@ -600,8 +602,8 @@ module TypeProf
|
|
|
600
602
|
end
|
|
601
603
|
end
|
|
602
604
|
|
|
603
|
-
def
|
|
604
|
-
@base_type.
|
|
605
|
+
def method_dispatch_info
|
|
606
|
+
@base_type.method_dispatch_info
|
|
605
607
|
end
|
|
606
608
|
|
|
607
609
|
def substitute(_subst, _depth)
|
|
@@ -630,8 +632,8 @@ module TypeProf
|
|
|
630
632
|
@base_type
|
|
631
633
|
end
|
|
632
634
|
|
|
633
|
-
def
|
|
634
|
-
@base_type.
|
|
635
|
+
def method_dispatch_info
|
|
636
|
+
@base_type.method_dispatch_info
|
|
635
637
|
end
|
|
636
638
|
|
|
637
639
|
def consistent?(_other)
|
|
@@ -785,6 +787,10 @@ module TypeProf
|
|
|
785
787
|
end
|
|
786
788
|
str = str.empty? ? "" : "(#{ str.join(", ") })"
|
|
787
789
|
|
|
790
|
+
# Dirty Hack: Stop the iteration at most once!
|
|
791
|
+
# I'll remove this hack if RBS removes the limitation of nesting blocks
|
|
792
|
+
return str if caller_locations.any? {|frame| frame.label == "show_block_signature" }
|
|
793
|
+
|
|
788
794
|
optional = false
|
|
789
795
|
blks = []
|
|
790
796
|
@blk_ty.each_child_global do |ty|
|