typeprof 0.31.1 → 0.32.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/README.md +2 -1
- data/doc/report_guide.md +88 -0
- data/lib/typeprof/cli/cli.rb +9 -3
- data/lib/typeprof/code_range.rb +7 -5
- data/lib/typeprof/core/ast/base.rb +18 -6
- data/lib/typeprof/core/ast/call.rb +96 -32
- data/lib/typeprof/core/ast/const.rb +12 -9
- data/lib/typeprof/core/ast/control.rb +60 -30
- data/lib/typeprof/core/ast/meta.rb +194 -2
- data/lib/typeprof/core/ast/method.rb +74 -20
- data/lib/typeprof/core/ast/misc.rb +27 -7
- data/lib/typeprof/core/ast/module.rb +33 -3
- data/lib/typeprof/core/ast/sig_decl.rb +85 -24
- data/lib/typeprof/core/ast/sig_type.rb +77 -31
- data/lib/typeprof/core/ast/value.rb +14 -6
- data/lib/typeprof/core/ast/variable.rb +11 -4
- data/lib/typeprof/core/ast.rb +95 -14
- data/lib/typeprof/core/builtin.rb +184 -12
- data/lib/typeprof/core/env/method.rb +171 -6
- data/lib/typeprof/core/env/method_entity.rb +18 -15
- data/lib/typeprof/core/env/module_entity.rb +56 -18
- data/lib/typeprof/core/env/static_read.rb +4 -4
- data/lib/typeprof/core/env/type_alias_entity.rb +1 -1
- data/lib/typeprof/core/env/value_entity.rb +25 -3
- data/lib/typeprof/core/env.rb +79 -17
- data/lib/typeprof/core/graph/box.rb +379 -52
- data/lib/typeprof/core/graph/change_set.rb +59 -46
- data/lib/typeprof/core/graph/filter.rb +8 -5
- data/lib/typeprof/core/graph/vertex.rb +20 -19
- data/lib/typeprof/core/service.rb +317 -23
- data/lib/typeprof/core/type.rb +41 -7
- data/lib/typeprof/core/util.rb +6 -0
- data/lib/typeprof/lsp/messages.rb +5 -0
- data/lib/typeprof/lsp/server.rb +35 -4
- data/lib/typeprof/version.rb +1 -1
- metadata +3 -2
|
@@ -12,13 +12,13 @@ module TypeProf::Core
|
|
|
12
12
|
|
|
13
13
|
if @static_cpath
|
|
14
14
|
ncref = CRef.new(@static_cpath, meta ? :metaclass : :class, nil, lenv.cref)
|
|
15
|
-
nlenv = LocalEnv.new(@lenv.
|
|
15
|
+
nlenv = LocalEnv.new(@lenv.file_context, ncref, {}, [])
|
|
16
16
|
@body = raw_scope ? AST.create_node(raw_scope, nlenv, use_result) : DummyNilNode.new(code_range, lenv)
|
|
17
17
|
else
|
|
18
18
|
@body = nil
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
@cname_code_range = meta ? nil :
|
|
21
|
+
@cname_code_range = meta ? nil : lenv.code_range_from_node(raw_node.constant_path)
|
|
22
22
|
@mod_cdef = nil
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -89,7 +89,22 @@ module TypeProf::Core
|
|
|
89
89
|
def initialize(raw_node, lenv, use_result)
|
|
90
90
|
super(raw_node, lenv, raw_node.constant_path, false, raw_node.body, use_result)
|
|
91
91
|
raw_superclass = raw_node.superclass
|
|
92
|
-
|
|
92
|
+
if raw_superclass
|
|
93
|
+
# In Ruby, the superclass expression is evaluated before the class constant
|
|
94
|
+
# is created. When the superclass is a bare constant with the same name as
|
|
95
|
+
# the class being defined (e.g., `class Foo < Foo` inside a module), use the
|
|
96
|
+
# outer scope to avoid resolving to the class itself.
|
|
97
|
+
if @static_cpath && lenv.cref.outer &&
|
|
98
|
+
raw_superclass.type == :constant_read_node &&
|
|
99
|
+
raw_superclass.name == @static_cpath.last
|
|
100
|
+
slenv = LocalEnv.new(lenv.file_context, lenv.cref.outer, {}, [])
|
|
101
|
+
@superclass_cpath = AST.create_node(raw_superclass, slenv)
|
|
102
|
+
else
|
|
103
|
+
@superclass_cpath = AST.create_node(raw_superclass, lenv)
|
|
104
|
+
end
|
|
105
|
+
else
|
|
106
|
+
@superclass_cpath = nil
|
|
107
|
+
end
|
|
93
108
|
end
|
|
94
109
|
|
|
95
110
|
attr_reader :superclass_cpath
|
|
@@ -113,6 +128,21 @@ module TypeProf::Core
|
|
|
113
128
|
|
|
114
129
|
def install0(genv)
|
|
115
130
|
@superclass_cpath.install(genv) if @superclass_cpath
|
|
131
|
+
if @static_cpath && @superclass_cpath
|
|
132
|
+
const_read = @superclass_cpath.static_ret
|
|
133
|
+
if const_read && const_read.cpath
|
|
134
|
+
super_mod = genv.resolve_cpath(const_read.cpath)
|
|
135
|
+
self_mod = genv.resolve_cpath(@static_cpath)
|
|
136
|
+
mod = super_mod
|
|
137
|
+
while mod
|
|
138
|
+
if mod == self_mod
|
|
139
|
+
@changes.add_diagnostic(:code_range, "circular inheritance", @superclass_cpath)
|
|
140
|
+
break
|
|
141
|
+
end
|
|
142
|
+
mod = mod.superclass
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
116
146
|
super(genv)
|
|
117
147
|
end
|
|
118
148
|
end
|
|
@@ -15,20 +15,27 @@ module TypeProf::Core
|
|
|
15
15
|
# TODO: decl.type_params
|
|
16
16
|
# TODO: decl.super_class.args
|
|
17
17
|
ncref = CRef.new(@cpath, :class, nil, lenv.cref)
|
|
18
|
-
nlenv = LocalEnv.new(@lenv.
|
|
18
|
+
nlenv = LocalEnv.new(@lenv.file_context, ncref, {}, [])
|
|
19
19
|
@members = raw_decl.members.map do |member|
|
|
20
20
|
AST.create_rbs_member(member, nlenv)
|
|
21
21
|
end.compact
|
|
22
22
|
# TODO?: param.variance, param.unchecked, param.upper_bound
|
|
23
23
|
@params = raw_decl.type_params.map {|param| param.name }
|
|
24
|
+
@params_default_types = raw_decl.type_params.map do |param|
|
|
25
|
+
ty = param.default_type
|
|
26
|
+
ty ? AST.create_rbs_type(ty, lenv) : nil
|
|
27
|
+
end
|
|
24
28
|
end
|
|
25
29
|
|
|
26
|
-
attr_reader :cpath, :members, :params
|
|
30
|
+
attr_reader :cpath, :members, :params, :params_default_types
|
|
27
31
|
|
|
28
|
-
def subnodes = { members: }
|
|
32
|
+
def subnodes = { members:, params_default_types: }
|
|
29
33
|
def attrs = { cpath:, params: }
|
|
30
34
|
|
|
31
35
|
def define0(genv)
|
|
36
|
+
@params_default_types.each do |ty|
|
|
37
|
+
ty&.define(genv)
|
|
38
|
+
end
|
|
32
39
|
@members.each do |member|
|
|
33
40
|
member.define(genv)
|
|
34
41
|
end
|
|
@@ -46,6 +53,9 @@ module TypeProf::Core
|
|
|
46
53
|
def undefine0(genv)
|
|
47
54
|
mod = genv.resolve_cpath(@cpath)
|
|
48
55
|
mod.remove_module_decl(genv, self)
|
|
56
|
+
@params_default_types.each do |ty|
|
|
57
|
+
ty&.undefine(genv)
|
|
58
|
+
end
|
|
49
59
|
@members.each do |member|
|
|
50
60
|
member.undefine(genv)
|
|
51
61
|
end
|
|
@@ -180,19 +190,19 @@ module TypeProf::Core
|
|
|
180
190
|
def initialize(raw_decl, lenv)
|
|
181
191
|
super(raw_decl, lenv)
|
|
182
192
|
@mid = raw_decl.name
|
|
183
|
-
@mid_code_range =
|
|
193
|
+
@mid_code_range = lenv.code_range_from_node(raw_decl.location[:name])
|
|
184
194
|
@singleton = raw_decl.singleton?
|
|
185
195
|
@instance = raw_decl.instance?
|
|
186
|
-
@method_types = raw_decl.overloads.map do |overload|
|
|
196
|
+
@method_types = OverloadSet.new(raw_decl.overloads.map do |overload|
|
|
187
197
|
method_type = overload.method_type
|
|
188
198
|
AST.create_rbs_func_type(method_type, method_type.type_params, method_type.block, lenv)
|
|
189
|
-
end
|
|
199
|
+
end)
|
|
190
200
|
@overloading = raw_decl.overloading
|
|
191
201
|
end
|
|
192
202
|
|
|
193
203
|
attr_reader :mid, :singleton, :instance, :method_types, :overloading, :mid_code_range
|
|
194
204
|
|
|
195
|
-
def subnodes = { method_types: }
|
|
205
|
+
def subnodes = { method_types: @method_types.to_a }
|
|
196
206
|
def attrs = { mid:, mid_code_range:, singleton:, instance:, overloading: }
|
|
197
207
|
|
|
198
208
|
def mname_code_range(_name) = @mid_code_range
|
|
@@ -222,10 +232,10 @@ module TypeProf::Core
|
|
|
222
232
|
def define0(genv)
|
|
223
233
|
@args.each {|arg| arg.define(genv) }
|
|
224
234
|
const_reads = []
|
|
225
|
-
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref,
|
|
235
|
+
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, true)
|
|
226
236
|
const_reads << const_read
|
|
227
237
|
@cpath[1..].each do |cname|
|
|
228
|
-
const_read = ScopedConstRead.new(cname, const_read,
|
|
238
|
+
const_read = ScopedConstRead.new(cname, const_read, true)
|
|
229
239
|
const_reads << const_read
|
|
230
240
|
end
|
|
231
241
|
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
@@ -271,10 +281,10 @@ module TypeProf::Core
|
|
|
271
281
|
def define0(genv)
|
|
272
282
|
@args.each {|arg| arg.define(genv) }
|
|
273
283
|
const_reads = []
|
|
274
|
-
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref,
|
|
284
|
+
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, true)
|
|
275
285
|
const_reads << const_read
|
|
276
286
|
@cpath[1..].each do |cname|
|
|
277
|
-
const_read = ScopedConstRead.new(cname, const_read,
|
|
287
|
+
const_read = ScopedConstRead.new(cname, const_read, true)
|
|
278
288
|
const_reads << const_read
|
|
279
289
|
end
|
|
280
290
|
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
@@ -336,6 +346,7 @@ module TypeProf::Core
|
|
|
336
346
|
location: raw_decl.type.location
|
|
337
347
|
)
|
|
338
348
|
@method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
|
|
349
|
+
@method_types = OverloadSet.new([@method_type])
|
|
339
350
|
end
|
|
340
351
|
|
|
341
352
|
attr_reader :mid, :method_type
|
|
@@ -344,7 +355,7 @@ module TypeProf::Core
|
|
|
344
355
|
def attrs = { mid: }
|
|
345
356
|
|
|
346
357
|
def install0(genv)
|
|
347
|
-
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid,
|
|
358
|
+
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid, @method_types, false)
|
|
348
359
|
Source.new
|
|
349
360
|
end
|
|
350
361
|
end
|
|
@@ -371,6 +382,7 @@ module TypeProf::Core
|
|
|
371
382
|
location: raw_decl.type.location
|
|
372
383
|
)
|
|
373
384
|
@method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
|
|
385
|
+
@method_types = OverloadSet.new([@method_type])
|
|
374
386
|
end
|
|
375
387
|
|
|
376
388
|
attr_reader :mid, :method_type
|
|
@@ -379,7 +391,7 @@ module TypeProf::Core
|
|
|
379
391
|
def attrs = { mid: }
|
|
380
392
|
|
|
381
393
|
def install0(genv)
|
|
382
|
-
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid,
|
|
394
|
+
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid, @method_types, false)
|
|
383
395
|
Source.new
|
|
384
396
|
end
|
|
385
397
|
end
|
|
@@ -402,6 +414,52 @@ module TypeProf::Core
|
|
|
402
414
|
end
|
|
403
415
|
end
|
|
404
416
|
|
|
417
|
+
class SigModuleAliasBaseNode < Node
|
|
418
|
+
def initialize(raw_decl, lenv)
|
|
419
|
+
super(raw_decl, lenv)
|
|
420
|
+
@cpath = AST.resolve_rbs_name(raw_decl.new_name, lenv)
|
|
421
|
+
@old_cpath = AST.resolve_rbs_name(raw_decl.old_name, lenv)
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
attr_reader :cpath, :old_cpath
|
|
425
|
+
def attrs = { cpath:, old_cpath: }
|
|
426
|
+
|
|
427
|
+
def define0(genv)
|
|
428
|
+
outer = genv.resolve_cpath(@cpath[0..-2])
|
|
429
|
+
cname = @cpath.last
|
|
430
|
+
alias_mod = outer.inner_modules[cname] ||= ModuleEntity.new(outer.cpath + [cname], outer)
|
|
431
|
+
target_mod = genv.resolve_cpath(@old_cpath)
|
|
432
|
+
alias_mod.add_alias_decl(genv, self, target_mod)
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def define_copy(genv)
|
|
436
|
+
outer = genv.resolve_cpath(@cpath[0..-2])
|
|
437
|
+
alias_mod = outer.inner_modules[@cpath.last]
|
|
438
|
+
target_mod = genv.resolve_cpath(@old_cpath)
|
|
439
|
+
alias_mod.add_alias_decl(genv, self, target_mod)
|
|
440
|
+
alias_mod.remove_alias_decl(genv, @prev_node)
|
|
441
|
+
super(genv)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def undefine0(genv)
|
|
445
|
+
outer = genv.resolve_cpath(@cpath[0..-2])
|
|
446
|
+
alias_mod = outer.inner_modules[@cpath.last]
|
|
447
|
+
alias_mod.remove_alias_decl(genv, self)
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
def install0(genv)
|
|
451
|
+
mod_val = Source.new(Type::Singleton.new(genv, genv.resolve_cpath(@cpath)))
|
|
452
|
+
@changes.add_edge(genv, mod_val, @static_ret.vtx)
|
|
453
|
+
Source.new
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
class SigClassAliasNode < SigModuleAliasBaseNode
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
class SigModuleAliasNode < SigModuleAliasBaseNode
|
|
461
|
+
end
|
|
462
|
+
|
|
405
463
|
class SigConstNode < Node
|
|
406
464
|
def initialize(raw_decl, lenv)
|
|
407
465
|
super(raw_decl, lenv)
|
|
@@ -415,9 +473,10 @@ module TypeProf::Core
|
|
|
415
473
|
|
|
416
474
|
def define0(genv)
|
|
417
475
|
@type.define(genv)
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
476
|
+
cdef = genv.resolve_const(@cpath)
|
|
477
|
+
cdef.on_const_added(genv, @cpath)
|
|
478
|
+
cdef.add_decl(self)
|
|
479
|
+
cdef
|
|
421
480
|
end
|
|
422
481
|
|
|
423
482
|
def define_copy(genv)
|
|
@@ -428,7 +487,9 @@ module TypeProf::Core
|
|
|
428
487
|
end
|
|
429
488
|
|
|
430
489
|
def undefine0(genv)
|
|
431
|
-
genv.resolve_const(@cpath)
|
|
490
|
+
cdef = genv.resolve_const(@cpath)
|
|
491
|
+
cdef.remove_decl(self)
|
|
492
|
+
cdef.on_const_removed(genv, @cpath)
|
|
432
493
|
@type.undefine(genv)
|
|
433
494
|
end
|
|
434
495
|
|
|
@@ -490,20 +551,20 @@ module TypeProf::Core
|
|
|
490
551
|
|
|
491
552
|
def define0(genv)
|
|
492
553
|
@type.define(genv)
|
|
493
|
-
mod = genv.
|
|
494
|
-
mod.
|
|
495
|
-
mod
|
|
554
|
+
mod = genv.resolve_cpath(cpath)
|
|
555
|
+
mod.add_ivar_decl(genv, @class_scope, @var, self)
|
|
496
556
|
end
|
|
497
557
|
|
|
498
558
|
def define_copy(genv)
|
|
499
|
-
mod = genv.
|
|
500
|
-
mod.
|
|
501
|
-
mod.
|
|
559
|
+
mod = genv.resolve_cpath(cpath)
|
|
560
|
+
mod.add_ivar_decl(genv, @class_scope, @var, self)
|
|
561
|
+
mod.remove_ivar_decl(genv, @class_scope, @var, @prev_node)
|
|
502
562
|
super(genv)
|
|
503
563
|
end
|
|
504
564
|
|
|
505
565
|
def undefine0(genv)
|
|
506
|
-
genv.
|
|
566
|
+
mod = genv.resolve_cpath(cpath)
|
|
567
|
+
mod.remove_ivar_decl(genv, @class_scope, @var, self)
|
|
507
568
|
@type.undefine(genv)
|
|
508
569
|
end
|
|
509
570
|
|
|
@@ -2,7 +2,10 @@ module TypeProf::Core
|
|
|
2
2
|
class AST
|
|
3
3
|
def self.typecheck_for_module(genv, changes, f_mod, f_args, a_vtx, subst)
|
|
4
4
|
changes.add_edge(genv, a_vtx, changes.target)
|
|
5
|
+
found_any = false
|
|
5
6
|
a_vtx.each_type do |ty|
|
|
7
|
+
next if ty.is_a?(Type::Bot)
|
|
8
|
+
found_any = true
|
|
6
9
|
ty = ty.base_type(genv)
|
|
7
10
|
while ty
|
|
8
11
|
if ty.mod == f_mod && ty.is_a?(Type::Instance)
|
|
@@ -25,7 +28,7 @@ module TypeProf::Core
|
|
|
25
28
|
ty = genv.get_superclass_type(ty, changes, {})
|
|
26
29
|
end
|
|
27
30
|
end
|
|
28
|
-
return
|
|
31
|
+
return !found_any
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
def self.typecheck_for_prepended_modules(genv, changes, a_ty, f_mod, f_args, subst)
|
|
@@ -33,7 +36,7 @@ module TypeProf::Core
|
|
|
33
36
|
if prep_decl.is_a?(AST::SigPrependNode) && prep_mod.type_params
|
|
34
37
|
prep_ty = genv.get_instance_type(prep_mod, prep_decl.args, changes, {}, a_ty)
|
|
35
38
|
else
|
|
36
|
-
type_params = prep_mod.type_params.map {|
|
|
39
|
+
type_params = prep_mod.type_params.map {|(_name, _default_ty)| Source.new() } # TODO: better support
|
|
37
40
|
prep_ty = Type::Instance.new(genv, prep_mod, type_params)
|
|
38
41
|
end
|
|
39
42
|
if prep_ty.mod == f_mod
|
|
@@ -58,7 +61,7 @@ module TypeProf::Core
|
|
|
58
61
|
if inc_decl.is_a?(AST::SigIncludeNode) && inc_mod.type_params
|
|
59
62
|
inc_ty = genv.get_instance_type(inc_mod, inc_decl.args, changes, {}, a_ty)
|
|
60
63
|
else
|
|
61
|
-
type_params = inc_mod.type_params.map {|
|
|
64
|
+
type_params = inc_mod.type_params.map {|(_name, _default_ty)| Source.new() } # TODO: better support
|
|
62
65
|
inc_ty = Type::Instance.new(genv, inc_mod, type_params)
|
|
63
66
|
end
|
|
64
67
|
if inc_ty.mod == f_mod
|
|
@@ -108,13 +111,19 @@ module TypeProf::Core
|
|
|
108
111
|
param = raw_decl.type.rest_positionals
|
|
109
112
|
@rest_positionals = param ? AST.create_rbs_type(param.type, lenv) : nil
|
|
110
113
|
|
|
111
|
-
@
|
|
114
|
+
@req_keyword_keys = []
|
|
115
|
+
@req_keyword_values = []
|
|
116
|
+
raw_decl.type.required_keywords.each do |key, ty|
|
|
112
117
|
raise "unsupported argument type: #{ ty.class }" if !ty.is_a?(RBS::Types::Function::Param)
|
|
113
|
-
|
|
118
|
+
@req_keyword_keys << key
|
|
119
|
+
@req_keyword_values << AST.create_rbs_type(ty.type, lenv)
|
|
114
120
|
end
|
|
115
|
-
@
|
|
121
|
+
@opt_keyword_keys = []
|
|
122
|
+
@opt_keyword_values = []
|
|
123
|
+
raw_decl.type.optional_keywords.each do |key, ty|
|
|
116
124
|
raise "unsupported argument type: #{ ty.class }" if !ty.is_a?(RBS::Types::Function::Param)
|
|
117
|
-
|
|
125
|
+
@opt_keyword_keys << key
|
|
126
|
+
@opt_keyword_values << AST.create_rbs_type(ty.type, lenv)
|
|
118
127
|
end
|
|
119
128
|
param = raw_decl.type.rest_keywords
|
|
120
129
|
@rest_keywords = param ? AST.create_rbs_type(param.type, lenv) : nil
|
|
@@ -124,8 +133,10 @@ module TypeProf::Core
|
|
|
124
133
|
@post_positionals = []
|
|
125
134
|
@opt_positionals = []
|
|
126
135
|
@rest_positionals = SigTyBaseAnyNode.new(raw_decl, lenv)
|
|
127
|
-
@
|
|
128
|
-
@
|
|
136
|
+
@req_keyword_keys = []
|
|
137
|
+
@req_keyword_values = []
|
|
138
|
+
@opt_keyword_keys = []
|
|
139
|
+
@opt_keyword_values = []
|
|
129
140
|
@rest_keywords = nil
|
|
130
141
|
end
|
|
131
142
|
|
|
@@ -137,8 +148,10 @@ module TypeProf::Core
|
|
|
137
148
|
attr_reader :post_positionals
|
|
138
149
|
attr_reader :opt_positionals
|
|
139
150
|
attr_reader :rest_positionals
|
|
140
|
-
attr_reader :
|
|
141
|
-
attr_reader :
|
|
151
|
+
attr_reader :req_keyword_keys
|
|
152
|
+
attr_reader :req_keyword_values
|
|
153
|
+
attr_reader :opt_keyword_keys
|
|
154
|
+
attr_reader :opt_keyword_values
|
|
142
155
|
attr_reader :rest_keywords
|
|
143
156
|
attr_reader :return_type
|
|
144
157
|
|
|
@@ -148,12 +161,17 @@ module TypeProf::Core
|
|
|
148
161
|
post_positionals:,
|
|
149
162
|
opt_positionals:,
|
|
150
163
|
rest_positionals:,
|
|
151
|
-
|
|
152
|
-
|
|
164
|
+
req_keyword_values:,
|
|
165
|
+
opt_keyword_values:,
|
|
153
166
|
rest_keywords:,
|
|
154
167
|
return_type:,
|
|
155
168
|
}
|
|
156
|
-
def attrs = {
|
|
169
|
+
def attrs = {
|
|
170
|
+
type_params:,
|
|
171
|
+
req_keyword_keys:,
|
|
172
|
+
opt_keyword_keys:,
|
|
173
|
+
block_required:,
|
|
174
|
+
}
|
|
157
175
|
end
|
|
158
176
|
|
|
159
177
|
class SigTyNode < Node
|
|
@@ -182,6 +200,7 @@ module TypeProf::Core
|
|
|
182
200
|
def typecheck(genv, changes, vtx, subst)
|
|
183
201
|
changes.add_edge(genv, vtx, changes.target)
|
|
184
202
|
vtx.each_type do |ty|
|
|
203
|
+
next if ty.is_a?(Type::Bot)
|
|
185
204
|
return false unless ty == genv.true_type || ty == genv.false_type
|
|
186
205
|
end
|
|
187
206
|
true
|
|
@@ -204,6 +223,7 @@ module TypeProf::Core
|
|
|
204
223
|
def typecheck(genv, changes, vtx, subst)
|
|
205
224
|
changes.add_edge(genv, vtx, changes.target)
|
|
206
225
|
vtx.each_type do |ty|
|
|
226
|
+
next if ty.is_a?(Type::Bot)
|
|
207
227
|
return false unless ty == genv.nil_type
|
|
208
228
|
end
|
|
209
229
|
true
|
|
@@ -287,11 +307,11 @@ module TypeProf::Core
|
|
|
287
307
|
|
|
288
308
|
class SigTyBaseBottomNode < SigTyNode
|
|
289
309
|
def covariant_vertex0(genv, changes, vtx, subst)
|
|
290
|
-
changes.add_edge(genv, Source.new(
|
|
310
|
+
changes.add_edge(genv, Source.new(genv.bot_type), vtx)
|
|
291
311
|
end
|
|
292
312
|
|
|
293
313
|
def contravariant_vertex0(genv, changes, vtx, subst)
|
|
294
|
-
changes.add_edge(genv, Source.new(
|
|
314
|
+
changes.add_edge(genv, Source.new(genv.bot_type), vtx)
|
|
295
315
|
end
|
|
296
316
|
|
|
297
317
|
def typecheck(genv, changes, vtx, subst)
|
|
@@ -530,6 +550,8 @@ module TypeProf::Core
|
|
|
530
550
|
name = raw_decl.name
|
|
531
551
|
@cpath = name.namespace.path + [name.name]
|
|
532
552
|
@toplevel = name.namespace.absolute?
|
|
553
|
+
# RBS::Types::ClassSingleton#args was added in RBS 4.0
|
|
554
|
+
@args = raw_decl.respond_to?(:args) ? raw_decl.args.map {|arg| AST.create_rbs_type(arg, lenv) } : []
|
|
533
555
|
end
|
|
534
556
|
|
|
535
557
|
attr_reader :cpath, :toplevel
|
|
@@ -578,7 +600,10 @@ module TypeProf::Core
|
|
|
578
600
|
return unless cpath
|
|
579
601
|
f_mod = genv.resolve_cpath(cpath)
|
|
580
602
|
changes.add_edge(genv, vtx, changes.target)
|
|
603
|
+
found_any = false
|
|
581
604
|
vtx.each_type do |ty|
|
|
605
|
+
next if ty.is_a?(Type::Bot)
|
|
606
|
+
found_any = true
|
|
582
607
|
case ty
|
|
583
608
|
when Type::Singleton
|
|
584
609
|
if f_mod.module?
|
|
@@ -593,7 +618,7 @@ module TypeProf::Core
|
|
|
593
618
|
end
|
|
594
619
|
end
|
|
595
620
|
end
|
|
596
|
-
|
|
621
|
+
!found_any
|
|
597
622
|
end
|
|
598
623
|
|
|
599
624
|
def show
|
|
@@ -714,7 +739,10 @@ module TypeProf::Core
|
|
|
714
739
|
|
|
715
740
|
def typecheck(genv, changes, vtx, subst)
|
|
716
741
|
changes.add_edge(genv, vtx, changes.target)
|
|
742
|
+
found_any = false
|
|
717
743
|
vtx.each_type do |ty|
|
|
744
|
+
next if ty.is_a?(Type::Bot)
|
|
745
|
+
found_any = true
|
|
718
746
|
case ty
|
|
719
747
|
when Type::Array
|
|
720
748
|
next if ty.elems.size != @types.size
|
|
@@ -729,7 +757,7 @@ module TypeProf::Core
|
|
|
729
757
|
return true
|
|
730
758
|
end
|
|
731
759
|
end
|
|
732
|
-
|
|
760
|
+
!found_any
|
|
733
761
|
end
|
|
734
762
|
|
|
735
763
|
def show
|
|
@@ -740,16 +768,18 @@ module TypeProf::Core
|
|
|
740
768
|
class SigTyRecordNode < SigTyNode
|
|
741
769
|
def initialize(raw_decl, lenv)
|
|
742
770
|
super(raw_decl, lenv)
|
|
743
|
-
@
|
|
771
|
+
@keys = raw_decl.fields.keys
|
|
772
|
+
@vals = raw_decl.fields.values.map { |val| AST.create_rbs_type(val, lenv) }
|
|
744
773
|
end
|
|
745
774
|
|
|
746
|
-
attr_reader :
|
|
747
|
-
def subnodes = {
|
|
775
|
+
attr_reader :keys, :vals
|
|
776
|
+
def subnodes = { vals: }
|
|
777
|
+
def attrs = { keys: }
|
|
748
778
|
|
|
749
779
|
def covariant_vertex0(genv, changes, vtx, subst)
|
|
750
780
|
field_vertices = {}
|
|
751
|
-
@
|
|
752
|
-
field_vertices[key] =
|
|
781
|
+
@keys.zip(@vals) do |key, val_node|
|
|
782
|
+
field_vertices[key] = val_node.covariant_vertex(genv, changes, subst)
|
|
753
783
|
end
|
|
754
784
|
|
|
755
785
|
# Create base Hash type for Record
|
|
@@ -766,8 +796,8 @@ module TypeProf::Core
|
|
|
766
796
|
|
|
767
797
|
def contravariant_vertex0(genv, changes, vtx, subst)
|
|
768
798
|
field_vertices = {}
|
|
769
|
-
@
|
|
770
|
-
field_vertices[key] =
|
|
799
|
+
@keys.zip(@vals) do |key, val_node|
|
|
800
|
+
field_vertices[key] = val_node.contravariant_vertex(genv, changes, subst)
|
|
771
801
|
end
|
|
772
802
|
|
|
773
803
|
# Create base Hash type for Record
|
|
@@ -784,22 +814,25 @@ module TypeProf::Core
|
|
|
784
814
|
|
|
785
815
|
def typecheck(genv, changes, vtx, subst)
|
|
786
816
|
changes.add_edge(genv, vtx, changes.target)
|
|
817
|
+
found_any = false
|
|
787
818
|
vtx.each_type do |ty|
|
|
819
|
+
next if ty.is_a?(Type::Bot)
|
|
820
|
+
found_any = true
|
|
788
821
|
case ty
|
|
789
822
|
when Type::Hash
|
|
790
|
-
@
|
|
823
|
+
@keys.zip(@vals) do |key, val_node|
|
|
791
824
|
val_vtx = ty.get_value(key)
|
|
792
|
-
return false unless
|
|
825
|
+
return false unless val_node.typecheck(genv, changes, val_vtx, subst)
|
|
793
826
|
end
|
|
794
827
|
return true
|
|
795
828
|
end
|
|
796
829
|
end
|
|
797
|
-
|
|
830
|
+
!found_any
|
|
798
831
|
end
|
|
799
832
|
|
|
800
833
|
def show
|
|
801
|
-
field_strs = @
|
|
802
|
-
"#{ key }: #{
|
|
834
|
+
field_strs = @keys.zip(@vals).map do |key, val_node|
|
|
835
|
+
"#{ key }: #{ val_node.show }"
|
|
803
836
|
end
|
|
804
837
|
"{ #{ field_strs.join(", ") } }"
|
|
805
838
|
end
|
|
@@ -855,6 +888,16 @@ module TypeProf::Core
|
|
|
855
888
|
end
|
|
856
889
|
|
|
857
890
|
def typecheck(genv, changes, vtx, subst)
|
|
891
|
+
# For optional type T?, check if all non-nil types match T.
|
|
892
|
+
# nil is always acceptable.
|
|
893
|
+
changes.add_edge(genv, vtx, changes.target)
|
|
894
|
+
has_non_nil = false
|
|
895
|
+
vtx.each_type do |ty|
|
|
896
|
+
next if ty.is_a?(Type::Bot)
|
|
897
|
+
next if ty == genv.nil_type
|
|
898
|
+
has_non_nil = true
|
|
899
|
+
end
|
|
900
|
+
return true unless has_non_nil
|
|
858
901
|
@type.typecheck(genv, changes, vtx, subst)
|
|
859
902
|
end
|
|
860
903
|
|
|
@@ -900,13 +943,16 @@ module TypeProf::Core
|
|
|
900
943
|
def typecheck(genv, changes, vtx, subst)
|
|
901
944
|
if @lit.is_a?(::Symbol)
|
|
902
945
|
changes.add_edge(genv, vtx, changes.target)
|
|
946
|
+
found_any = false
|
|
903
947
|
vtx.each_type do |ty|
|
|
948
|
+
next if ty.is_a?(Type::Bot)
|
|
949
|
+
found_any = true
|
|
904
950
|
case ty
|
|
905
951
|
when Type::Symbol
|
|
906
952
|
return true if ty.sym == @lit
|
|
907
953
|
end
|
|
908
954
|
end
|
|
909
|
-
return
|
|
955
|
+
return !found_any
|
|
910
956
|
end
|
|
911
957
|
f_mod = get_type(genv).mod
|
|
912
958
|
AST.typecheck_for_module(genv, changes, f_mod, [], vtx, subst)
|
|
@@ -5,7 +5,7 @@ module TypeProf::Core
|
|
|
5
5
|
when :string_node
|
|
6
6
|
AST.create_node(raw_part, lenv)
|
|
7
7
|
when :embedded_statements_node
|
|
8
|
-
raw_part.statements ? AST.create_node(raw_part.statements, lenv) : DummyNilNode.new(
|
|
8
|
+
raw_part.statements ? AST.create_node(raw_part.statements, lenv) : DummyNilNode.new(lenv.code_range_from_node(raw_part), lenv)
|
|
9
9
|
when :embedded_variable_node
|
|
10
10
|
AST.create_node(raw_part.variable, lenv)
|
|
11
11
|
else
|
|
@@ -275,7 +275,7 @@ module TypeProf::Core
|
|
|
275
275
|
if raw_elem.value
|
|
276
276
|
@vals << AST.create_node(raw_elem.value, lenv)
|
|
277
277
|
else
|
|
278
|
-
@vals <<
|
|
278
|
+
@vals << nil
|
|
279
279
|
end
|
|
280
280
|
@splat = true
|
|
281
281
|
else
|
|
@@ -293,15 +293,20 @@ module TypeProf::Core
|
|
|
293
293
|
unified_key = Vertex.new(self)
|
|
294
294
|
unified_val = Vertex.new(self)
|
|
295
295
|
literal_pairs = {}
|
|
296
|
+
all_symbol_keys = true
|
|
296
297
|
@keys.zip(@vals) do |key, val|
|
|
297
298
|
if key
|
|
298
299
|
k = key.install(genv).new_vertex(genv, self)
|
|
299
300
|
v = val.install(genv).new_vertex(genv, self)
|
|
300
301
|
@changes.add_edge(genv, k, unified_key)
|
|
301
302
|
@changes.add_edge(genv, v, unified_val)
|
|
302
|
-
|
|
303
|
+
if key.is_a?(SymbolNode)
|
|
304
|
+
literal_pairs[key.lit] = v
|
|
305
|
+
else
|
|
306
|
+
all_symbol_keys = false
|
|
307
|
+
end
|
|
303
308
|
else
|
|
304
|
-
if val.
|
|
309
|
+
if val.nil?
|
|
305
310
|
h = @lenv.get_var(:"**anonymous_keyword")
|
|
306
311
|
else
|
|
307
312
|
h = val.install(genv)
|
|
@@ -310,10 +315,13 @@ module TypeProf::Core
|
|
|
310
315
|
@changes.add_hash_splat_box(genv, h, unified_key, unified_val)
|
|
311
316
|
end
|
|
312
317
|
end
|
|
318
|
+
base_hash_type = genv.gen_hash_type(unified_key, unified_val)
|
|
313
319
|
if @splat
|
|
314
|
-
Source.new(
|
|
320
|
+
Source.new(base_hash_type)
|
|
321
|
+
elsif all_symbol_keys
|
|
322
|
+
Source.new(Type::Record.new(genv, literal_pairs, base_hash_type))
|
|
315
323
|
else
|
|
316
|
-
Source.new(Type::Hash.new(genv, literal_pairs,
|
|
324
|
+
Source.new(Type::Hash.new(genv, literal_pairs, base_hash_type))
|
|
317
325
|
end
|
|
318
326
|
end
|
|
319
327
|
end
|
|
@@ -46,7 +46,7 @@ module TypeProf::Core
|
|
|
46
46
|
def initialize(raw_node, rhs, lenv)
|
|
47
47
|
super(raw_node, lenv)
|
|
48
48
|
@var = raw_node.name
|
|
49
|
-
@var_code_range =
|
|
49
|
+
@var_code_range = lenv.code_range_from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
|
|
50
50
|
@rhs = rhs
|
|
51
51
|
end
|
|
52
52
|
|
|
@@ -68,6 +68,13 @@ module TypeProf::Core
|
|
|
68
68
|
super(pos, &blk)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
|
+
def narrowings
|
|
72
|
+
@narrowings ||= [
|
|
73
|
+
Narrowing.new({ @var => Narrowing::NilConstraint.new(false) }),
|
|
74
|
+
Narrowing.new({ @var => Narrowing::NilConstraint.new(true) }),
|
|
75
|
+
]
|
|
76
|
+
end
|
|
77
|
+
|
|
71
78
|
def modified_vars(tbl, vars)
|
|
72
79
|
vars << self.var if tbl.include?(self.var)
|
|
73
80
|
end
|
|
@@ -109,7 +116,7 @@ module TypeProf::Core
|
|
|
109
116
|
def initialize(raw_node, rhs, lenv)
|
|
110
117
|
super(raw_node, lenv)
|
|
111
118
|
@var = raw_node.name
|
|
112
|
-
@var_code_range =
|
|
119
|
+
@var_code_range = lenv.code_range_from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
|
|
113
120
|
@rhs = rhs
|
|
114
121
|
end
|
|
115
122
|
|
|
@@ -191,7 +198,7 @@ module TypeProf::Core
|
|
|
191
198
|
def initialize(raw_node, rhs, lenv)
|
|
192
199
|
super(raw_node, lenv)
|
|
193
200
|
@var = raw_node.name
|
|
194
|
-
@var_code_range =
|
|
201
|
+
@var_code_range = lenv.code_range_from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
|
|
195
202
|
@rhs = rhs
|
|
196
203
|
end
|
|
197
204
|
|
|
@@ -264,7 +271,7 @@ module TypeProf::Core
|
|
|
264
271
|
def initialize(raw_node, rhs, lenv)
|
|
265
272
|
super(raw_node, lenv)
|
|
266
273
|
@var = raw_node.name
|
|
267
|
-
@var_code_range =
|
|
274
|
+
@var_code_range = lenv.code_range_from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
|
|
268
275
|
@rhs = rhs
|
|
269
276
|
end
|
|
270
277
|
|