typeprof 0.31.1 → 0.33.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 +31 -6
- data/lib/typeprof/core/ast/call.rb +120 -39
- data/lib/typeprof/core/ast/const.rb +22 -11
- data/lib/typeprof/core/ast/control.rb +62 -32
- data/lib/typeprof/core/ast/meta.rb +279 -14
- data/lib/typeprof/core/ast/method.rb +82 -24
- data/lib/typeprof/core/ast/misc.rb +41 -12
- data/lib/typeprof/core/ast/module.rb +38 -4
- data/lib/typeprof/core/ast/pattern.rb +51 -23
- data/lib/typeprof/core/ast/sig_decl.rb +141 -27
- data/lib/typeprof/core/ast/sig_type.rb +113 -32
- data/lib/typeprof/core/ast/value.rb +14 -6
- data/lib/typeprof/core/ast/variable.rb +17 -4
- data/lib/typeprof/core/ast.rb +98 -14
- data/lib/typeprof/core/builtin.rb +184 -12
- data/lib/typeprof/core/env/method.rb +343 -6
- data/lib/typeprof/core/env/method_entity.rb +18 -15
- data/lib/typeprof/core/env/module_entity.rb +116 -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 +113 -23
- data/lib/typeprof/core/graph/box.rb +508 -63
- data/lib/typeprof/core/graph/change_set.rb +64 -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 +340 -24
- 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
|
@@ -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,22 +190,26 @@ module TypeProf::Core
|
|
|
180
190
|
def initialize(raw_decl, lenv)
|
|
181
191
|
super(raw_decl, lenv)
|
|
182
192
|
@mid = raw_decl.name
|
|
183
|
-
@
|
|
193
|
+
@mid_code_range_loc = 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
|
-
attr_reader :mid, :singleton, :instance, :method_types, :overloading
|
|
203
|
+
attr_reader :mid, :singleton, :instance, :method_types, :overloading
|
|
204
|
+
|
|
205
|
+
def mid_code_range
|
|
206
|
+
@mid_code_range ||= @lenv.code_range_from_node(@mid_code_range_loc) if @mid_code_range_loc
|
|
207
|
+
end
|
|
194
208
|
|
|
195
|
-
def subnodes = { method_types: }
|
|
196
|
-
def attrs = { mid:,
|
|
209
|
+
def subnodes = { method_types: @method_types.to_a }
|
|
210
|
+
def attrs = { mid:, singleton:, instance:, overloading: }
|
|
197
211
|
|
|
198
|
-
def mname_code_range(_name) =
|
|
212
|
+
def mname_code_range(_name) = mid_code_range
|
|
199
213
|
|
|
200
214
|
def install0(genv)
|
|
201
215
|
[[@singleton, true], [@instance, false]].each do |enabled, singleton|
|
|
@@ -222,10 +236,10 @@ module TypeProf::Core
|
|
|
222
236
|
def define0(genv)
|
|
223
237
|
@args.each {|arg| arg.define(genv) }
|
|
224
238
|
const_reads = []
|
|
225
|
-
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref,
|
|
239
|
+
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, true)
|
|
226
240
|
const_reads << const_read
|
|
227
241
|
@cpath[1..].each do |cname|
|
|
228
|
-
const_read = ScopedConstRead.new(cname, const_read,
|
|
242
|
+
const_read = ScopedConstRead.new(cname, const_read, true)
|
|
229
243
|
const_reads << const_read
|
|
230
244
|
end
|
|
231
245
|
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
@@ -271,10 +285,10 @@ module TypeProf::Core
|
|
|
271
285
|
def define0(genv)
|
|
272
286
|
@args.each {|arg| arg.define(genv) }
|
|
273
287
|
const_reads = []
|
|
274
|
-
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref,
|
|
288
|
+
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, true)
|
|
275
289
|
const_reads << const_read
|
|
276
290
|
@cpath[1..].each do |cname|
|
|
277
|
-
const_read = ScopedConstRead.new(cname, const_read,
|
|
291
|
+
const_read = ScopedConstRead.new(cname, const_read, true)
|
|
278
292
|
const_reads << const_read
|
|
279
293
|
end
|
|
280
294
|
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
@@ -304,6 +318,55 @@ module TypeProf::Core
|
|
|
304
318
|
end
|
|
305
319
|
end
|
|
306
320
|
|
|
321
|
+
class SigExtendNode < Node
|
|
322
|
+
def initialize(raw_decl, lenv)
|
|
323
|
+
super(raw_decl, lenv)
|
|
324
|
+
name = raw_decl.name
|
|
325
|
+
@cpath = name.namespace.path + [name.name]
|
|
326
|
+
@toplevel = name.namespace.absolute?
|
|
327
|
+
@args = raw_decl.args.map {|arg| AST.create_rbs_type(arg, lenv) }
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
attr_reader :cpath, :toplevel, :args
|
|
331
|
+
def subnodes = { args: }
|
|
332
|
+
def attrs = { cpath:, toplevel: }
|
|
333
|
+
|
|
334
|
+
def define0(genv)
|
|
335
|
+
@args.each {|arg| arg.define(genv) }
|
|
336
|
+
const_reads = []
|
|
337
|
+
const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, true)
|
|
338
|
+
const_reads << const_read
|
|
339
|
+
@cpath[1..].each do |cname|
|
|
340
|
+
const_read = ScopedConstRead.new(cname, const_read, true)
|
|
341
|
+
const_reads << const_read
|
|
342
|
+
end
|
|
343
|
+
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
344
|
+
const_read.followers << mod
|
|
345
|
+
mod.add_extend_decl(genv, self)
|
|
346
|
+
const_reads
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
def define_copy(genv)
|
|
350
|
+
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
351
|
+
mod.add_extend_decl(genv, self)
|
|
352
|
+
mod.remove_extend_decl(genv, @prev_node)
|
|
353
|
+
super(genv)
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def undefine0(genv)
|
|
357
|
+
mod = genv.resolve_cpath(@lenv.cref.cpath)
|
|
358
|
+
mod.remove_extend_decl(genv, self)
|
|
359
|
+
@static_ret.each do |const_read|
|
|
360
|
+
const_read.destroy(genv)
|
|
361
|
+
end
|
|
362
|
+
@args.each {|arg| arg.undefine(genv) }
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def install0(genv)
|
|
366
|
+
Source.new
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
307
370
|
class SigAliasNode < Node
|
|
308
371
|
def initialize(raw_decl, lenv)
|
|
309
372
|
super(raw_decl, lenv)
|
|
@@ -336,6 +399,7 @@ module TypeProf::Core
|
|
|
336
399
|
location: raw_decl.type.location
|
|
337
400
|
)
|
|
338
401
|
@method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
|
|
402
|
+
@method_types = OverloadSet.new([@method_type])
|
|
339
403
|
end
|
|
340
404
|
|
|
341
405
|
attr_reader :mid, :method_type
|
|
@@ -344,7 +408,7 @@ module TypeProf::Core
|
|
|
344
408
|
def attrs = { mid: }
|
|
345
409
|
|
|
346
410
|
def install0(genv)
|
|
347
|
-
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid,
|
|
411
|
+
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid, @method_types, false)
|
|
348
412
|
Source.new
|
|
349
413
|
end
|
|
350
414
|
end
|
|
@@ -371,6 +435,7 @@ module TypeProf::Core
|
|
|
371
435
|
location: raw_decl.type.location
|
|
372
436
|
)
|
|
373
437
|
@method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
|
|
438
|
+
@method_types = OverloadSet.new([@method_type])
|
|
374
439
|
end
|
|
375
440
|
|
|
376
441
|
attr_reader :mid, :method_type
|
|
@@ -379,7 +444,7 @@ module TypeProf::Core
|
|
|
379
444
|
def attrs = { mid: }
|
|
380
445
|
|
|
381
446
|
def install0(genv)
|
|
382
|
-
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid,
|
|
447
|
+
@changes.add_method_decl_box(genv, @lenv.cref.cpath, false, @mid, @method_types, false)
|
|
383
448
|
Source.new
|
|
384
449
|
end
|
|
385
450
|
end
|
|
@@ -402,6 +467,52 @@ module TypeProf::Core
|
|
|
402
467
|
end
|
|
403
468
|
end
|
|
404
469
|
|
|
470
|
+
class SigModuleAliasBaseNode < Node
|
|
471
|
+
def initialize(raw_decl, lenv)
|
|
472
|
+
super(raw_decl, lenv)
|
|
473
|
+
@cpath = AST.resolve_rbs_name(raw_decl.new_name, lenv)
|
|
474
|
+
@old_cpath = AST.resolve_rbs_name(raw_decl.old_name, lenv)
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
attr_reader :cpath, :old_cpath
|
|
478
|
+
def attrs = { cpath:, old_cpath: }
|
|
479
|
+
|
|
480
|
+
def define0(genv)
|
|
481
|
+
outer = genv.resolve_cpath(@cpath[0..-2])
|
|
482
|
+
cname = @cpath.last
|
|
483
|
+
alias_mod = outer.inner_modules[cname] ||= ModuleEntity.new(outer.cpath + [cname], outer)
|
|
484
|
+
target_mod = genv.resolve_cpath(@old_cpath)
|
|
485
|
+
alias_mod.add_alias_decl(genv, self, target_mod)
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def define_copy(genv)
|
|
489
|
+
outer = genv.resolve_cpath(@cpath[0..-2])
|
|
490
|
+
alias_mod = outer.inner_modules[@cpath.last]
|
|
491
|
+
target_mod = genv.resolve_cpath(@old_cpath)
|
|
492
|
+
alias_mod.add_alias_decl(genv, self, target_mod)
|
|
493
|
+
alias_mod.remove_alias_decl(genv, @prev_node)
|
|
494
|
+
super(genv)
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def undefine0(genv)
|
|
498
|
+
outer = genv.resolve_cpath(@cpath[0..-2])
|
|
499
|
+
alias_mod = outer.inner_modules[@cpath.last]
|
|
500
|
+
alias_mod.remove_alias_decl(genv, self)
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def install0(genv)
|
|
504
|
+
mod_val = Source.new(Type::Singleton.new(genv, genv.resolve_cpath(@cpath)))
|
|
505
|
+
@changes.add_edge(genv, mod_val, @static_ret.vtx)
|
|
506
|
+
Source.new
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
class SigClassAliasNode < SigModuleAliasBaseNode
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
class SigModuleAliasNode < SigModuleAliasBaseNode
|
|
514
|
+
end
|
|
515
|
+
|
|
405
516
|
class SigConstNode < Node
|
|
406
517
|
def initialize(raw_decl, lenv)
|
|
407
518
|
super(raw_decl, lenv)
|
|
@@ -415,9 +526,10 @@ module TypeProf::Core
|
|
|
415
526
|
|
|
416
527
|
def define0(genv)
|
|
417
528
|
@type.define(genv)
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
529
|
+
cdef = genv.resolve_const(@cpath)
|
|
530
|
+
cdef.on_const_added(genv, @cpath)
|
|
531
|
+
cdef.add_decl(self)
|
|
532
|
+
cdef
|
|
421
533
|
end
|
|
422
534
|
|
|
423
535
|
def define_copy(genv)
|
|
@@ -428,7 +540,9 @@ module TypeProf::Core
|
|
|
428
540
|
end
|
|
429
541
|
|
|
430
542
|
def undefine0(genv)
|
|
431
|
-
genv.resolve_const(@cpath)
|
|
543
|
+
cdef = genv.resolve_const(@cpath)
|
|
544
|
+
cdef.remove_decl(self)
|
|
545
|
+
cdef.on_const_removed(genv, @cpath)
|
|
432
546
|
@type.undefine(genv)
|
|
433
547
|
end
|
|
434
548
|
|
|
@@ -490,20 +604,20 @@ module TypeProf::Core
|
|
|
490
604
|
|
|
491
605
|
def define0(genv)
|
|
492
606
|
@type.define(genv)
|
|
493
|
-
mod = genv.
|
|
494
|
-
mod.
|
|
495
|
-
mod
|
|
607
|
+
mod = genv.resolve_cpath(cpath)
|
|
608
|
+
mod.add_ivar_decl(genv, @class_scope, @var, self)
|
|
496
609
|
end
|
|
497
610
|
|
|
498
611
|
def define_copy(genv)
|
|
499
|
-
mod = genv.
|
|
500
|
-
mod.
|
|
501
|
-
mod.
|
|
612
|
+
mod = genv.resolve_cpath(cpath)
|
|
613
|
+
mod.add_ivar_decl(genv, @class_scope, @var, self)
|
|
614
|
+
mod.remove_ivar_decl(genv, @class_scope, @var, @prev_node)
|
|
502
615
|
super(genv)
|
|
503
616
|
end
|
|
504
617
|
|
|
505
618
|
def undefine0(genv)
|
|
506
|
-
genv.
|
|
619
|
+
mod = genv.resolve_cpath(cpath)
|
|
620
|
+
mod.remove_ivar_decl(genv, @class_scope, @var, self)
|
|
507
621
|
@type.undefine(genv)
|
|
508
622
|
end
|
|
509
623
|
|
|
@@ -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)
|
|
@@ -20,12 +23,15 @@ module TypeProf::Core
|
|
|
20
23
|
if f_mod.module?
|
|
21
24
|
return true if typecheck_for_prepended_modules(genv, changes, ty, f_mod, f_args, subst)
|
|
22
25
|
return true if typecheck_for_included_modules(genv, changes, ty, f_mod, f_args, subst)
|
|
26
|
+
if ty.is_a?(Type::Singleton)
|
|
27
|
+
return true if typecheck_for_extended_modules(genv, changes, ty, f_mod, f_args, subst)
|
|
28
|
+
end
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
ty = genv.get_superclass_type(ty, changes, {})
|
|
26
32
|
end
|
|
27
33
|
end
|
|
28
|
-
return
|
|
34
|
+
return !found_any
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
def self.typecheck_for_prepended_modules(genv, changes, a_ty, f_mod, f_args, subst)
|
|
@@ -33,7 +39,7 @@ module TypeProf::Core
|
|
|
33
39
|
if prep_decl.is_a?(AST::SigPrependNode) && prep_mod.type_params
|
|
34
40
|
prep_ty = genv.get_instance_type(prep_mod, prep_decl.args, changes, {}, a_ty)
|
|
35
41
|
else
|
|
36
|
-
type_params = prep_mod.type_params.map {|
|
|
42
|
+
type_params = prep_mod.type_params.map {|(_name, _default_ty)| Source.new() } # TODO: better support
|
|
37
43
|
prep_ty = Type::Instance.new(genv, prep_mod, type_params)
|
|
38
44
|
end
|
|
39
45
|
if prep_ty.mod == f_mod
|
|
@@ -58,7 +64,7 @@ module TypeProf::Core
|
|
|
58
64
|
if inc_decl.is_a?(AST::SigIncludeNode) && inc_mod.type_params
|
|
59
65
|
inc_ty = genv.get_instance_type(inc_mod, inc_decl.args, changes, {}, a_ty)
|
|
60
66
|
else
|
|
61
|
-
type_params = inc_mod.type_params.map {|
|
|
67
|
+
type_params = inc_mod.type_params.map {|(_name, _default_ty)| Source.new() } # TODO: better support
|
|
62
68
|
inc_ty = Type::Instance.new(genv, inc_mod, type_params)
|
|
63
69
|
end
|
|
64
70
|
if inc_ty.mod == f_mod
|
|
@@ -78,6 +84,32 @@ module TypeProf::Core
|
|
|
78
84
|
return false
|
|
79
85
|
end
|
|
80
86
|
|
|
87
|
+
def self.typecheck_for_extended_modules(genv, changes, a_ty, f_mod, f_args, subst)
|
|
88
|
+
a_ty.mod.extended_modules.each do |ext_decl, ext_mod|
|
|
89
|
+
if ext_decl.is_a?(AST::SigExtendNode) && ext_mod.type_params
|
|
90
|
+
ext_ty = genv.get_instance_type(ext_mod, ext_decl.args, changes, {}, a_ty)
|
|
91
|
+
else
|
|
92
|
+
type_params = ext_mod.type_params.map {|(_name, _default_ty)| Source.new() } # TODO: better support
|
|
93
|
+
ext_ty = Type::Instance.new(genv, ext_mod, type_params)
|
|
94
|
+
end
|
|
95
|
+
if ext_ty.mod == f_mod
|
|
96
|
+
args_all_match = true
|
|
97
|
+
f_args.zip(ext_ty.args) do |f_arg_node, a_arg_vtx|
|
|
98
|
+
unless f_arg_node.typecheck(genv, changes, a_arg_vtx, subst)
|
|
99
|
+
args_all_match = false
|
|
100
|
+
break
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
return true if args_all_match
|
|
104
|
+
end
|
|
105
|
+
changes.add_depended_superclass(ext_ty.mod)
|
|
106
|
+
|
|
107
|
+
# The extended module may itself include other modules
|
|
108
|
+
return true if typecheck_for_included_modules(genv, changes, ext_ty, f_mod, f_args, subst)
|
|
109
|
+
end
|
|
110
|
+
return false
|
|
111
|
+
end
|
|
112
|
+
|
|
81
113
|
class SigFuncType < Node
|
|
82
114
|
def initialize(raw_decl, raw_type_params, raw_block, lenv)
|
|
83
115
|
super(raw_decl, lenv)
|
|
@@ -108,13 +140,19 @@ module TypeProf::Core
|
|
|
108
140
|
param = raw_decl.type.rest_positionals
|
|
109
141
|
@rest_positionals = param ? AST.create_rbs_type(param.type, lenv) : nil
|
|
110
142
|
|
|
111
|
-
@
|
|
143
|
+
@req_keyword_keys = []
|
|
144
|
+
@req_keyword_values = []
|
|
145
|
+
raw_decl.type.required_keywords.each do |key, ty|
|
|
112
146
|
raise "unsupported argument type: #{ ty.class }" if !ty.is_a?(RBS::Types::Function::Param)
|
|
113
|
-
|
|
147
|
+
@req_keyword_keys << key
|
|
148
|
+
@req_keyword_values << AST.create_rbs_type(ty.type, lenv)
|
|
114
149
|
end
|
|
115
|
-
@
|
|
150
|
+
@opt_keyword_keys = []
|
|
151
|
+
@opt_keyword_values = []
|
|
152
|
+
raw_decl.type.optional_keywords.each do |key, ty|
|
|
116
153
|
raise "unsupported argument type: #{ ty.class }" if !ty.is_a?(RBS::Types::Function::Param)
|
|
117
|
-
|
|
154
|
+
@opt_keyword_keys << key
|
|
155
|
+
@opt_keyword_values << AST.create_rbs_type(ty.type, lenv)
|
|
118
156
|
end
|
|
119
157
|
param = raw_decl.type.rest_keywords
|
|
120
158
|
@rest_keywords = param ? AST.create_rbs_type(param.type, lenv) : nil
|
|
@@ -124,8 +162,10 @@ module TypeProf::Core
|
|
|
124
162
|
@post_positionals = []
|
|
125
163
|
@opt_positionals = []
|
|
126
164
|
@rest_positionals = SigTyBaseAnyNode.new(raw_decl, lenv)
|
|
127
|
-
@
|
|
128
|
-
@
|
|
165
|
+
@req_keyword_keys = []
|
|
166
|
+
@req_keyword_values = []
|
|
167
|
+
@opt_keyword_keys = []
|
|
168
|
+
@opt_keyword_values = []
|
|
129
169
|
@rest_keywords = nil
|
|
130
170
|
end
|
|
131
171
|
|
|
@@ -137,8 +177,10 @@ module TypeProf::Core
|
|
|
137
177
|
attr_reader :post_positionals
|
|
138
178
|
attr_reader :opt_positionals
|
|
139
179
|
attr_reader :rest_positionals
|
|
140
|
-
attr_reader :
|
|
141
|
-
attr_reader :
|
|
180
|
+
attr_reader :req_keyword_keys
|
|
181
|
+
attr_reader :req_keyword_values
|
|
182
|
+
attr_reader :opt_keyword_keys
|
|
183
|
+
attr_reader :opt_keyword_values
|
|
142
184
|
attr_reader :rest_keywords
|
|
143
185
|
attr_reader :return_type
|
|
144
186
|
|
|
@@ -148,12 +190,17 @@ module TypeProf::Core
|
|
|
148
190
|
post_positionals:,
|
|
149
191
|
opt_positionals:,
|
|
150
192
|
rest_positionals:,
|
|
151
|
-
|
|
152
|
-
|
|
193
|
+
req_keyword_values:,
|
|
194
|
+
opt_keyword_values:,
|
|
153
195
|
rest_keywords:,
|
|
154
196
|
return_type:,
|
|
155
197
|
}
|
|
156
|
-
def attrs = {
|
|
198
|
+
def attrs = {
|
|
199
|
+
type_params:,
|
|
200
|
+
req_keyword_keys:,
|
|
201
|
+
opt_keyword_keys:,
|
|
202
|
+
block_required:,
|
|
203
|
+
}
|
|
157
204
|
end
|
|
158
205
|
|
|
159
206
|
class SigTyNode < Node
|
|
@@ -182,6 +229,7 @@ module TypeProf::Core
|
|
|
182
229
|
def typecheck(genv, changes, vtx, subst)
|
|
183
230
|
changes.add_edge(genv, vtx, changes.target)
|
|
184
231
|
vtx.each_type do |ty|
|
|
232
|
+
next if ty.is_a?(Type::Bot)
|
|
185
233
|
return false unless ty == genv.true_type || ty == genv.false_type
|
|
186
234
|
end
|
|
187
235
|
true
|
|
@@ -204,6 +252,7 @@ module TypeProf::Core
|
|
|
204
252
|
def typecheck(genv, changes, vtx, subst)
|
|
205
253
|
changes.add_edge(genv, vtx, changes.target)
|
|
206
254
|
vtx.each_type do |ty|
|
|
255
|
+
next if ty.is_a?(Type::Bot)
|
|
207
256
|
return false unless ty == genv.nil_type
|
|
208
257
|
end
|
|
209
258
|
true
|
|
@@ -287,11 +336,11 @@ module TypeProf::Core
|
|
|
287
336
|
|
|
288
337
|
class SigTyBaseBottomNode < SigTyNode
|
|
289
338
|
def covariant_vertex0(genv, changes, vtx, subst)
|
|
290
|
-
changes.add_edge(genv, Source.new(
|
|
339
|
+
changes.add_edge(genv, Source.new(genv.bot_type), vtx)
|
|
291
340
|
end
|
|
292
341
|
|
|
293
342
|
def contravariant_vertex0(genv, changes, vtx, subst)
|
|
294
|
-
changes.add_edge(genv, Source.new(
|
|
343
|
+
changes.add_edge(genv, Source.new(genv.bot_type), vtx)
|
|
295
344
|
end
|
|
296
345
|
|
|
297
346
|
def typecheck(genv, changes, vtx, subst)
|
|
@@ -445,7 +494,13 @@ module TypeProf::Core
|
|
|
445
494
|
decl = tae.decls.each {|decl| break decl }
|
|
446
495
|
subst0 = subst.dup
|
|
447
496
|
decl.params.zip(@args) do |param, arg|
|
|
448
|
-
|
|
497
|
+
if arg.is_a?(SigTyVarNode) && subst[arg.var]
|
|
498
|
+
# Share the vertex so that the types inferred in the alias body flow
|
|
499
|
+
# back into the variable, which makes `U` of `(array[U])` inferrable
|
|
500
|
+
subst0[param] = subst[arg.var]
|
|
501
|
+
else
|
|
502
|
+
subst0[param] = arg.covariant_vertex(genv, changes, subst0)
|
|
503
|
+
end
|
|
449
504
|
end
|
|
450
505
|
tae.type.typecheck(genv, changes, vtx, subst0)
|
|
451
506
|
end
|
|
@@ -530,6 +585,8 @@ module TypeProf::Core
|
|
|
530
585
|
name = raw_decl.name
|
|
531
586
|
@cpath = name.namespace.path + [name.name]
|
|
532
587
|
@toplevel = name.namespace.absolute?
|
|
588
|
+
# RBS::Types::ClassSingleton#args was added in RBS 4.0
|
|
589
|
+
@args = raw_decl.respond_to?(:args) ? raw_decl.args.map {|arg| AST.create_rbs_type(arg, lenv) } : []
|
|
533
590
|
end
|
|
534
591
|
|
|
535
592
|
attr_reader :cpath, :toplevel
|
|
@@ -578,7 +635,10 @@ module TypeProf::Core
|
|
|
578
635
|
return unless cpath
|
|
579
636
|
f_mod = genv.resolve_cpath(cpath)
|
|
580
637
|
changes.add_edge(genv, vtx, changes.target)
|
|
638
|
+
found_any = false
|
|
581
639
|
vtx.each_type do |ty|
|
|
640
|
+
next if ty.is_a?(Type::Bot)
|
|
641
|
+
found_any = true
|
|
582
642
|
case ty
|
|
583
643
|
when Type::Singleton
|
|
584
644
|
if f_mod.module?
|
|
@@ -593,7 +653,7 @@ module TypeProf::Core
|
|
|
593
653
|
end
|
|
594
654
|
end
|
|
595
655
|
end
|
|
596
|
-
|
|
656
|
+
!found_any
|
|
597
657
|
end
|
|
598
658
|
|
|
599
659
|
def show
|
|
@@ -714,7 +774,10 @@ module TypeProf::Core
|
|
|
714
774
|
|
|
715
775
|
def typecheck(genv, changes, vtx, subst)
|
|
716
776
|
changes.add_edge(genv, vtx, changes.target)
|
|
777
|
+
found_any = false
|
|
717
778
|
vtx.each_type do |ty|
|
|
779
|
+
next if ty.is_a?(Type::Bot)
|
|
780
|
+
found_any = true
|
|
718
781
|
case ty
|
|
719
782
|
when Type::Array
|
|
720
783
|
next if ty.elems.size != @types.size
|
|
@@ -729,7 +792,7 @@ module TypeProf::Core
|
|
|
729
792
|
return true
|
|
730
793
|
end
|
|
731
794
|
end
|
|
732
|
-
|
|
795
|
+
!found_any
|
|
733
796
|
end
|
|
734
797
|
|
|
735
798
|
def show
|
|
@@ -740,16 +803,18 @@ module TypeProf::Core
|
|
|
740
803
|
class SigTyRecordNode < SigTyNode
|
|
741
804
|
def initialize(raw_decl, lenv)
|
|
742
805
|
super(raw_decl, lenv)
|
|
743
|
-
@
|
|
806
|
+
@keys = raw_decl.fields.keys
|
|
807
|
+
@vals = raw_decl.fields.values.map { |val| AST.create_rbs_type(val, lenv) }
|
|
744
808
|
end
|
|
745
809
|
|
|
746
|
-
attr_reader :
|
|
747
|
-
def subnodes = {
|
|
810
|
+
attr_reader :keys, :vals
|
|
811
|
+
def subnodes = { vals: }
|
|
812
|
+
def attrs = { keys: }
|
|
748
813
|
|
|
749
814
|
def covariant_vertex0(genv, changes, vtx, subst)
|
|
750
815
|
field_vertices = {}
|
|
751
|
-
@
|
|
752
|
-
field_vertices[key] =
|
|
816
|
+
@keys.zip(@vals) do |key, val_node|
|
|
817
|
+
field_vertices[key] = val_node.covariant_vertex(genv, changes, subst)
|
|
753
818
|
end
|
|
754
819
|
|
|
755
820
|
# Create base Hash type for Record
|
|
@@ -766,8 +831,8 @@ module TypeProf::Core
|
|
|
766
831
|
|
|
767
832
|
def contravariant_vertex0(genv, changes, vtx, subst)
|
|
768
833
|
field_vertices = {}
|
|
769
|
-
@
|
|
770
|
-
field_vertices[key] =
|
|
834
|
+
@keys.zip(@vals) do |key, val_node|
|
|
835
|
+
field_vertices[key] = val_node.contravariant_vertex(genv, changes, subst)
|
|
771
836
|
end
|
|
772
837
|
|
|
773
838
|
# Create base Hash type for Record
|
|
@@ -784,22 +849,25 @@ module TypeProf::Core
|
|
|
784
849
|
|
|
785
850
|
def typecheck(genv, changes, vtx, subst)
|
|
786
851
|
changes.add_edge(genv, vtx, changes.target)
|
|
852
|
+
found_any = false
|
|
787
853
|
vtx.each_type do |ty|
|
|
854
|
+
next if ty.is_a?(Type::Bot)
|
|
855
|
+
found_any = true
|
|
788
856
|
case ty
|
|
789
857
|
when Type::Hash
|
|
790
|
-
@
|
|
858
|
+
@keys.zip(@vals) do |key, val_node|
|
|
791
859
|
val_vtx = ty.get_value(key)
|
|
792
|
-
return false unless
|
|
860
|
+
return false unless val_node.typecheck(genv, changes, val_vtx, subst)
|
|
793
861
|
end
|
|
794
862
|
return true
|
|
795
863
|
end
|
|
796
864
|
end
|
|
797
|
-
|
|
865
|
+
!found_any
|
|
798
866
|
end
|
|
799
867
|
|
|
800
868
|
def show
|
|
801
|
-
field_strs = @
|
|
802
|
-
"#{ key }: #{
|
|
869
|
+
field_strs = @keys.zip(@vals).map do |key, val_node|
|
|
870
|
+
"#{ key }: #{ val_node.show }"
|
|
803
871
|
end
|
|
804
872
|
"{ #{ field_strs.join(", ") } }"
|
|
805
873
|
end
|
|
@@ -855,6 +923,16 @@ module TypeProf::Core
|
|
|
855
923
|
end
|
|
856
924
|
|
|
857
925
|
def typecheck(genv, changes, vtx, subst)
|
|
926
|
+
# For optional type T?, check if all non-nil types match T.
|
|
927
|
+
# nil is always acceptable.
|
|
928
|
+
changes.add_edge(genv, vtx, changes.target)
|
|
929
|
+
has_non_nil = false
|
|
930
|
+
vtx.each_type do |ty|
|
|
931
|
+
next if ty.is_a?(Type::Bot)
|
|
932
|
+
next if ty == genv.nil_type
|
|
933
|
+
has_non_nil = true
|
|
934
|
+
end
|
|
935
|
+
return true unless has_non_nil
|
|
858
936
|
@type.typecheck(genv, changes, vtx, subst)
|
|
859
937
|
end
|
|
860
938
|
|
|
@@ -900,13 +978,16 @@ module TypeProf::Core
|
|
|
900
978
|
def typecheck(genv, changes, vtx, subst)
|
|
901
979
|
if @lit.is_a?(::Symbol)
|
|
902
980
|
changes.add_edge(genv, vtx, changes.target)
|
|
981
|
+
found_any = false
|
|
903
982
|
vtx.each_type do |ty|
|
|
983
|
+
next if ty.is_a?(Type::Bot)
|
|
984
|
+
found_any = true
|
|
904
985
|
case ty
|
|
905
986
|
when Type::Symbol
|
|
906
987
|
return true if ty.sym == @lit
|
|
907
988
|
end
|
|
908
989
|
end
|
|
909
|
-
return
|
|
990
|
+
return !found_any
|
|
910
991
|
end
|
|
911
992
|
f_mod = get_type(genv).mod
|
|
912
993
|
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
|