typeprof 0.4.1 → 0.5.3
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/.github/workflows/main.yml +1 -2
- data/Gemfile.lock +3 -3
- data/README.md +6 -0
- data/lib/typeprof/analyzer.rb +73 -57
- data/lib/typeprof/arguments.rb +27 -19
- data/lib/typeprof/block.rb +5 -2
- data/lib/typeprof/builtin.rb +14 -4
- data/lib/typeprof/config.rb +10 -6
- data/lib/typeprof/container-type.rb +104 -97
- data/lib/typeprof/export.rb +1 -1
- data/lib/typeprof/import.rb +44 -22
- data/lib/typeprof/method.rb +70 -12
- data/lib/typeprof/type.rb +103 -88
- data/lib/typeprof/version.rb +1 -1
- data/smoke/arguments2.rb +1 -1
- data/smoke/block-kwarg.rb +1 -1
- data/smoke/block10.rb +1 -1
- data/smoke/hash-fetch.rb +3 -3
- data/smoke/hash-merge-bang.rb +11 -0
- data/smoke/hash1.rb +1 -1
- data/smoke/hash3.rb +1 -1
- data/smoke/hash4.rb +1 -1
- data/smoke/ivar2.rb +1 -1
- data/smoke/keyword4.rb +1 -1
- data/smoke/kwsplat1.rb +1 -1
- data/smoke/kwsplat2.rb +1 -1
- data/smoke/pattern-match1.rb +23 -0
- data/smoke/pattern-match2.rb +15 -0
- data/smoke/rbs-tyvar3.rb +11 -19
- data/smoke/rbs-tyvar3.rbs +4 -3
- data/smoke/rbs-tyvar4.rb +36 -0
- data/smoke/rbs-tyvar5.rb +12 -0
- data/smoke/rbs-tyvar5.rbs +8 -0
- data/smoke/uninitialize-var.rb +12 -0
- data/typeprof.gemspec +1 -1
- metadata +12 -5
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
|
@@ -19,13 +19,44 @@ module TypeProf
|
|
19
19
|
# Cell, Array, and Hash are types for global interface, e.g., TypedISeq.
|
20
20
|
# Do not push such types to local environment, stack, etc.
|
21
21
|
|
22
|
+
class ContainerType < Type
|
23
|
+
def match?(other)
|
24
|
+
return nil if self.class != other.class
|
25
|
+
return nil unless @base_type.consistent?(other.base_type)
|
26
|
+
@elems.match?(other.elems)
|
27
|
+
end
|
28
|
+
|
29
|
+
def each_free_type_variable(&blk)
|
30
|
+
@elems.each_free_type_variable(&blk)
|
31
|
+
end
|
32
|
+
|
33
|
+
def consistent?(other)
|
34
|
+
raise "must not be used"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.create_empty_instance(klass)
|
38
|
+
base_type = Type::Instance.new(klass)
|
39
|
+
case klass
|
40
|
+
when Type::Builtin[:ary] # XXX: check inheritance...
|
41
|
+
Type::Array.new(Type::Array::Elements.new([], Type.bot), base_type)
|
42
|
+
when Type::Builtin[:hash]
|
43
|
+
Type.gen_hash(base_type) {|h| }
|
44
|
+
else
|
45
|
+
Type::Cell.new(Type::Cell::Elements.new([Type.bot] * klass.type_params.size), base_type)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
22
50
|
# The most basic container type for default type parameter class
|
23
|
-
class Cell <
|
51
|
+
class Cell < ContainerType
|
24
52
|
def initialize(elems, base_type)
|
25
53
|
raise if !elems.is_a?(Cell::Elements)
|
26
54
|
@elems = elems # Cell::Elements
|
27
55
|
raise unless base_type
|
28
56
|
@base_type = base_type
|
57
|
+
if base_type.klass.type_params.size != elems.elems.size
|
58
|
+
raise
|
59
|
+
end
|
29
60
|
end
|
30
61
|
|
31
62
|
attr_reader :elems, :base_type
|
@@ -44,7 +75,7 @@ module TypeProf
|
|
44
75
|
|
45
76
|
def localize(env, alloc_site, depth)
|
46
77
|
return env, Type.any if depth <= 0
|
47
|
-
alloc_site = alloc_site.add_id(:cell)
|
78
|
+
alloc_site = alloc_site.add_id(:cell).add_id(@base_type)
|
48
79
|
env, elems = @elems.localize(env, alloc_site, depth)
|
49
80
|
env.deploy_type(LocalCell, alloc_site, elems, @base_type)
|
50
81
|
end
|
@@ -58,31 +89,13 @@ module TypeProf
|
|
58
89
|
raise
|
59
90
|
end
|
60
91
|
|
61
|
-
def consistent?(other, subst)
|
62
|
-
case other
|
63
|
-
when Type::Any then true
|
64
|
-
when Type::Var then other.add_subst!(self, subst)
|
65
|
-
when Type::Union
|
66
|
-
other.types.each do |ty2|
|
67
|
-
return true if consistent?(ty2, subst)
|
68
|
-
end
|
69
|
-
return false
|
70
|
-
when Type::Cell
|
71
|
-
@elems.size == other.elems.size &&
|
72
|
-
@base_type.consistent?(other.base_type, subst) &&
|
73
|
-
@elems.zip(other.elems).all? {|elem1, elem2| elem1..consistent?(elem2, subst) }
|
74
|
-
else
|
75
|
-
self == other
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
92
|
def substitute(subst, depth)
|
80
93
|
return Type.any if depth <= 0
|
81
94
|
elems = @elems.substitute(subst, depth)
|
82
95
|
Cell.new(elems, @base_type)
|
83
96
|
end
|
84
97
|
|
85
|
-
class Elements
|
98
|
+
class Elements # Cell
|
86
99
|
include Utils::StructuralEquality
|
87
100
|
|
88
101
|
def initialize(elems)
|
@@ -124,12 +137,21 @@ module TypeProf
|
|
124
137
|
end
|
125
138
|
end
|
126
139
|
|
127
|
-
def
|
128
|
-
|
140
|
+
def match?(other)
|
141
|
+
return nil if @elems.size != other.elems.size
|
142
|
+
subst = nil
|
129
143
|
@elems.zip(other.elems) do |ty0, ty1|
|
130
|
-
|
144
|
+
subst2 = Type.match?(ty0, ty1)
|
145
|
+
return nil unless subst2
|
146
|
+
subst = Type.merge_substitution(subst, subst2)
|
147
|
+
end
|
148
|
+
subst
|
149
|
+
end
|
150
|
+
|
151
|
+
def each_free_type_variable(&blk)
|
152
|
+
@elems.each do |ty|
|
153
|
+
ty.each_free_type_variable(&blk)
|
131
154
|
end
|
132
|
-
return true
|
133
155
|
end
|
134
156
|
|
135
157
|
def substitute(subst, depth)
|
@@ -146,6 +168,9 @@ module TypeProf
|
|
146
168
|
|
147
169
|
def union(other)
|
148
170
|
return self if self == other
|
171
|
+
if @elems.size != other.elems.size
|
172
|
+
raise "#{ @elems.size } != #{ other.elems.size }"
|
173
|
+
end
|
149
174
|
elems = []
|
150
175
|
@elems.zip(other.elems) do |ty0, ty1|
|
151
176
|
elems << ty0.union(ty1)
|
@@ -155,7 +180,7 @@ module TypeProf
|
|
155
180
|
end
|
156
181
|
end
|
157
182
|
|
158
|
-
class LocalCell <
|
183
|
+
class LocalCell < ContainerType
|
159
184
|
def initialize(id, base_type)
|
160
185
|
@id = id
|
161
186
|
raise unless base_type
|
@@ -184,6 +209,7 @@ module TypeProf
|
|
184
209
|
else
|
185
210
|
elems = Cell::Elements.new([]) # XXX
|
186
211
|
end
|
212
|
+
visited.delete(self)
|
187
213
|
Cell.new(elems, @base_type)
|
188
214
|
end
|
189
215
|
end
|
@@ -191,14 +217,10 @@ module TypeProf
|
|
191
217
|
def get_method(mid, scratch)
|
192
218
|
@base_type.get_method(mid, scratch)
|
193
219
|
end
|
194
|
-
|
195
|
-
def consistent?(other, subst)
|
196
|
-
raise "must not be used"
|
197
|
-
end
|
198
220
|
end
|
199
221
|
|
200
222
|
# Do not insert Array type to local environment, stack, etc.
|
201
|
-
class Array <
|
223
|
+
class Array < ContainerType
|
202
224
|
def initialize(elems, base_type)
|
203
225
|
raise unless elems.is_a?(Array::Elements)
|
204
226
|
@elems = elems # Array::Elements
|
@@ -223,7 +245,7 @@ module TypeProf
|
|
223
245
|
|
224
246
|
def localize(env, alloc_site, depth)
|
225
247
|
return env, Type.any if depth <= 0
|
226
|
-
alloc_site = alloc_site.add_id(:ary)
|
248
|
+
alloc_site = alloc_site.add_id(:ary).add_id(@base_type)
|
227
249
|
env, elems = @elems.localize(env, alloc_site, depth - 1)
|
228
250
|
env.deploy_type(LocalArray, alloc_site, elems, @base_type)
|
229
251
|
end
|
@@ -237,29 +259,13 @@ module TypeProf
|
|
237
259
|
raise
|
238
260
|
end
|
239
261
|
|
240
|
-
def consistent?(other, subst)
|
241
|
-
case other
|
242
|
-
when Type::Any then true
|
243
|
-
when Type::Var then other.add_subst!(self, subst)
|
244
|
-
when Type::Union
|
245
|
-
other.types.each do |ty2|
|
246
|
-
return true if consistent?(ty2, subst)
|
247
|
-
end
|
248
|
-
return false
|
249
|
-
when Type::Array
|
250
|
-
@base_type.consistent?(other.base_type, subst) && @elems.consistent?(other.elems, subst)
|
251
|
-
else
|
252
|
-
self == other
|
253
|
-
end
|
254
|
-
end
|
255
|
-
|
256
262
|
def substitute(subst, depth)
|
257
263
|
return Type.any if depth <= 0
|
258
264
|
elems = @elems.substitute(subst, depth - 1)
|
259
265
|
Array.new(elems, @base_type)
|
260
266
|
end
|
261
267
|
|
262
|
-
class Elements
|
268
|
+
class Elements # Array
|
263
269
|
include Utils::StructuralEquality
|
264
270
|
|
265
271
|
def initialize(lead_tys, rest_ty = Type.bot)
|
@@ -318,14 +324,24 @@ module TypeProf
|
|
318
324
|
end
|
319
325
|
end
|
320
326
|
|
321
|
-
def
|
327
|
+
def match?(other)
|
322
328
|
n = [@lead_tys.size, other.lead_tys.size].min
|
323
|
-
n.times do |i|
|
324
|
-
return false unless @lead_tys[i].consistent?(other.lead_tys[i], subst)
|
325
|
-
end
|
326
329
|
rest_ty1 = @lead_tys[n..].inject(@rest_ty) {|ty1, ty2| ty1.union(ty2) }
|
327
330
|
rest_ty2 = other.lead_tys[n..].inject(other.rest_ty) {|ty1, ty2| ty1.union(ty2) }
|
328
|
-
|
331
|
+
subst = nil
|
332
|
+
(@lead_tys[0, n] + [rest_ty1]).zip(other.lead_tys[0, n] + [rest_ty2]) do |ty0, ty1|
|
333
|
+
subst2 = Type.match?(ty0, ty1)
|
334
|
+
return nil unless subst2
|
335
|
+
subst = Type.merge_substitution(subst, subst2)
|
336
|
+
end
|
337
|
+
subst
|
338
|
+
end
|
339
|
+
|
340
|
+
def each_free_type_variable(&blk)
|
341
|
+
@lead_tys.each do |ty|
|
342
|
+
ty.each_free_type_variable(&blk)
|
343
|
+
end
|
344
|
+
@rest_ty&.each_free_type_variable(&blk)
|
329
345
|
end
|
330
346
|
|
331
347
|
def substitute(subst, depth)
|
@@ -476,7 +492,7 @@ module TypeProf
|
|
476
492
|
end
|
477
493
|
|
478
494
|
# Do not insert Array type to local environment, stack, etc.
|
479
|
-
class LocalArray <
|
495
|
+
class LocalArray < ContainerType
|
480
496
|
def initialize(id, base_type)
|
481
497
|
@id = id
|
482
498
|
raise unless base_type
|
@@ -506,6 +522,7 @@ module TypeProf
|
|
506
522
|
# TODO: currently out-of-scope array cannot be accessed
|
507
523
|
elems = Array::Elements.new([], Type.any)
|
508
524
|
end
|
525
|
+
visited.delete(self)
|
509
526
|
Array.new(elems, @base_type)
|
510
527
|
end
|
511
528
|
end
|
@@ -513,14 +530,10 @@ module TypeProf
|
|
513
530
|
def get_method(mid, scratch)
|
514
531
|
@base_type.get_method(mid, scratch)
|
515
532
|
end
|
516
|
-
|
517
|
-
def consistent?(other, subst)
|
518
|
-
raise "must not be used"
|
519
|
-
end
|
520
533
|
end
|
521
534
|
|
522
535
|
|
523
|
-
class Hash <
|
536
|
+
class Hash < ContainerType
|
524
537
|
def initialize(elems, base_type)
|
525
538
|
@elems = elems
|
526
539
|
raise unless elems
|
@@ -539,7 +552,7 @@ module TypeProf
|
|
539
552
|
|
540
553
|
def localize(env, alloc_site, depth)
|
541
554
|
return env, Type.any if depth <= 0
|
542
|
-
alloc_site = alloc_site.add_id(:hash)
|
555
|
+
alloc_site = alloc_site.add_id(:hash).add_id(@base_type)
|
543
556
|
env, elems = @elems.localize(env, alloc_site, depth - 1)
|
544
557
|
env.deploy_type(LocalHash, alloc_site, elems, @base_type)
|
545
558
|
end
|
@@ -553,29 +566,13 @@ module TypeProf
|
|
553
566
|
raise
|
554
567
|
end
|
555
568
|
|
556
|
-
def consistent?(other, subst)
|
557
|
-
case other
|
558
|
-
when Type::Any then true
|
559
|
-
when Type::Var then other.add_subst!(self, subst)
|
560
|
-
when Type::Union
|
561
|
-
other.types.each do |ty2|
|
562
|
-
return true if consistent?(ty2, subst)
|
563
|
-
end
|
564
|
-
return false
|
565
|
-
when Type::Hash
|
566
|
-
@base_type.consistent?(other.base_type, subst) && @elems.consistent?(other.elems, subst)
|
567
|
-
else
|
568
|
-
self == other
|
569
|
-
end
|
570
|
-
end
|
571
|
-
|
572
569
|
def substitute(subst, depth)
|
573
570
|
return Type.any if depth <= 0
|
574
571
|
elems = @elems.substitute(subst, depth - 1)
|
575
572
|
Hash.new(elems, @base_type)
|
576
573
|
end
|
577
574
|
|
578
|
-
class Elements
|
575
|
+
class Elements # Hash
|
579
576
|
include Utils::StructuralEquality
|
580
577
|
|
581
578
|
def initialize(map_tys)
|
@@ -635,9 +632,13 @@ module TypeProf
|
|
635
632
|
|
636
633
|
def screen_name(scratch)
|
637
634
|
s = @map_tys.map do |k_ty, v_ty|
|
638
|
-
k = k_ty.screen_name(scratch)
|
639
635
|
v = v_ty.screen_name(scratch)
|
640
|
-
|
636
|
+
if k_ty.is_a?(Type::Symbol)
|
637
|
+
"#{ k_ty.sym }: #{ v }"
|
638
|
+
else
|
639
|
+
k = k_ty.screen_name(scratch)
|
640
|
+
"#{ k }=>#{ v }"
|
641
|
+
end
|
641
642
|
end.join(", ")
|
642
643
|
"{#{ s }}"
|
643
644
|
end
|
@@ -657,22 +658,31 @@ module TypeProf
|
|
657
658
|
end
|
658
659
|
end
|
659
660
|
|
660
|
-
def
|
661
|
-
|
661
|
+
def match?(other)
|
662
|
+
subst = nil
|
662
663
|
other.map_tys.each do |k1, v1|
|
663
|
-
|
664
|
+
subst2 = nil
|
664
665
|
@map_tys.each do |k0, v0|
|
665
|
-
subst3 =
|
666
|
-
if
|
667
|
-
|
668
|
-
|
669
|
-
|
666
|
+
subst3 = Type.match?(k0, k1)
|
667
|
+
if subst3
|
668
|
+
subst4 = Type.match?(v0, v1)
|
669
|
+
if subst4
|
670
|
+
subst2 = Type.merge_substitution(subst2, subst3)
|
671
|
+
subst2 = Type.merge_substitution(subst2, subst4)
|
672
|
+
end
|
670
673
|
end
|
671
674
|
end
|
672
|
-
return
|
675
|
+
return nil unless subst2
|
676
|
+
subst = Type.merge_substitution(subst, subst2)
|
677
|
+
end
|
678
|
+
subst
|
679
|
+
end
|
680
|
+
|
681
|
+
def each_free_type_variable(&blk)
|
682
|
+
@map_tys.each do |k, v|
|
683
|
+
k.each_free_type_variable(&blk)
|
684
|
+
v.each_free_type_variable(&blk)
|
673
685
|
end
|
674
|
-
subst.replace(subst2)
|
675
|
-
true
|
676
686
|
end
|
677
687
|
|
678
688
|
def substitute(subst, depth)
|
@@ -706,7 +716,7 @@ module TypeProf
|
|
706
716
|
def [](key_ty)
|
707
717
|
val_ty = Type.bot
|
708
718
|
@map_tys.each do |k_ty, v_ty|
|
709
|
-
if
|
719
|
+
if Type.match?(k_ty, key_ty)
|
710
720
|
val_ty = val_ty.union(v_ty)
|
711
721
|
end
|
712
722
|
end
|
@@ -763,7 +773,7 @@ module TypeProf
|
|
763
773
|
end
|
764
774
|
end
|
765
775
|
|
766
|
-
class LocalHash <
|
776
|
+
class LocalHash < ContainerType
|
767
777
|
def initialize(id, base_type)
|
768
778
|
@id = id
|
769
779
|
@base_type = base_type
|
@@ -791,6 +801,7 @@ module TypeProf
|
|
791
801
|
else
|
792
802
|
elems = Hash::Elements.new({Type.any => Type.any})
|
793
803
|
end
|
804
|
+
visited.delete(self)
|
794
805
|
Hash.new(elems, @base_type)
|
795
806
|
end
|
796
807
|
end
|
@@ -798,10 +809,6 @@ module TypeProf
|
|
798
809
|
def get_method(mid, scratch)
|
799
810
|
@base_type.get_method(mid, scratch)
|
800
811
|
end
|
801
|
-
|
802
|
-
def consistent?(other, subst)
|
803
|
-
raise "must not be used"
|
804
|
-
end
|
805
812
|
end
|
806
813
|
end
|
807
814
|
end
|
data/lib/typeprof/export.rb
CHANGED
@@ -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
|
|
@@ -210,7 +220,7 @@ module TypeProf
|
|
210
220
|
# * superclasses and modules appear earlier than their subclasses (Object is earlier than String)
|
211
221
|
# * namespace module appers earlier than its children (Process is earlier than Process::Status)
|
212
222
|
visited = {}
|
213
|
-
queue = @cur_env.class_decls.keys.map {|name| [:visit, name] }
|
223
|
+
queue = @cur_env.class_decls.keys.map {|name| [:visit, name] }.reverse
|
214
224
|
until queue.empty?
|
215
225
|
event, name = queue.pop
|
216
226
|
case event
|
@@ -365,10 +375,15 @@ module TypeProf
|
|
365
375
|
raise if ty.args.size != 2
|
366
376
|
[:array, [:Enumerator], [], conv_type(ty.args.first)]
|
367
377
|
else
|
368
|
-
|
378
|
+
if ty.args.empty?
|
379
|
+
[:instance, klass]
|
380
|
+
else
|
381
|
+
[:cell, [:instance, klass], ty.args.map {|ty| conv_type(ty) }]
|
382
|
+
end
|
369
383
|
end
|
370
384
|
when RBS::Types::Bases::Bool then [:bool]
|
371
385
|
when RBS::Types::Bases::Any then [:any]
|
386
|
+
when RBS::Types::Bases::Top then [:any]
|
372
387
|
when RBS::Types::Bases::Void then [:void]
|
373
388
|
when RBS::Types::Bases::Self then [:self]
|
374
389
|
when RBS::Types::Bases::Nil then [:nil]
|
@@ -440,6 +455,10 @@ module TypeProf
|
|
440
455
|
Import.new(scratch, scratch.rbs_reader.load_path(rbs_path)).import(true)
|
441
456
|
end
|
442
457
|
|
458
|
+
def self.import_rbs_code(scratch, rbs_name, rbs_code)
|
459
|
+
Import.new(scratch, scratch.rbs_reader.load_rbs_string(rbs_name, rbs_code)).import(true)
|
460
|
+
end
|
461
|
+
|
443
462
|
def initialize(scratch, json)
|
444
463
|
@scratch = scratch
|
445
464
|
@json = json
|
@@ -485,11 +504,11 @@ module TypeProf
|
|
485
504
|
rbs_sources = members[:rbs_sources]
|
486
505
|
|
487
506
|
included_modules.each do |mod|
|
488
|
-
@scratch.include_module(klass, path_to_klass(mod), nil)
|
507
|
+
@scratch.include_module(klass, path_to_klass(mod), false, nil)
|
489
508
|
end
|
490
509
|
|
491
510
|
extended_modules.each do |mod|
|
492
|
-
@scratch.
|
511
|
+
@scratch.include_module(klass, path_to_klass(mod), true, nil)
|
493
512
|
end
|
494
513
|
|
495
514
|
methods.each do |(singleton, method_name), mdef|
|
@@ -499,24 +518,25 @@ module TypeProf
|
|
499
518
|
end
|
500
519
|
|
501
520
|
ivars.each do |ivar_name, ty|
|
502
|
-
ty = conv_type(ty)
|
521
|
+
ty = conv_type(ty).remove_type_vars
|
503
522
|
@scratch.add_ivar_write!(Type::Instance.new(klass), ivar_name, ty, nil)
|
504
523
|
end
|
505
524
|
|
506
525
|
cvars.each do |ivar_name, ty|
|
507
|
-
ty = conv_type(ty)
|
526
|
+
ty = conv_type(ty).remove_type_vars
|
508
527
|
@scratch.add_cvar_write!(klass, ivar_name, ty, nil)
|
509
528
|
end
|
510
529
|
end
|
511
530
|
|
512
531
|
@json[:constants].each do |classpath, value|
|
513
532
|
base_klass = path_to_klass(classpath[0..-2])
|
514
|
-
value = conv_type(value)
|
533
|
+
value = conv_type(value).remove_type_vars
|
515
534
|
@scratch.add_constant(base_klass, classpath[-1], value, nil)
|
516
535
|
end
|
517
536
|
|
518
|
-
@json[:globals].each do |name,
|
519
|
-
|
537
|
+
@json[:globals].each do |name, ty|
|
538
|
+
ty = conv_type(ty).remove_type_vars
|
539
|
+
@scratch.add_gvar_write!(name, ty, nil)
|
520
540
|
end
|
521
541
|
|
522
542
|
true
|
@@ -574,6 +594,8 @@ module TypeProf
|
|
574
594
|
case ty.first
|
575
595
|
when :class then path_to_klass(ty[1])
|
576
596
|
when :instance then Type::Instance.new(path_to_klass(ty[1]))
|
597
|
+
when :cell
|
598
|
+
Type::Cell.new(Type::Cell::Elements.new(ty[2].map {|ty| conv_type(ty) }), conv_type(ty[1]))
|
577
599
|
when :any then Type.any
|
578
600
|
when :void then Type::Void.new
|
579
601
|
when :nil then Type.nil
|
@@ -609,7 +631,7 @@ module TypeProf
|
|
609
631
|
end
|
610
632
|
when :union
|
611
633
|
tys = ty[1]
|
612
|
-
Type::Union.new(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil) # XXX: Array and Hash support
|
634
|
+
Type::Union.new(Utils::Set[*tys.map {|ty2| conv_type(ty2) }], nil).normalize # XXX: Array and Hash support
|
613
635
|
when :var
|
614
636
|
Type::Var.new(ty[1])
|
615
637
|
when :proc
|