typeprof 0.30.1 → 0.31.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +23 -4
  3. data/lib/typeprof/cli/cli.rb +27 -7
  4. data/lib/typeprof/code_range.rb +9 -7
  5. data/lib/typeprof/core/ast/base.rb +27 -10
  6. data/lib/typeprof/core/ast/call.rb +85 -24
  7. data/lib/typeprof/core/ast/const.rb +7 -12
  8. data/lib/typeprof/core/ast/control.rb +345 -71
  9. data/lib/typeprof/core/ast/meta.rb +5 -5
  10. data/lib/typeprof/core/ast/method.rb +15 -5
  11. data/lib/typeprof/core/ast/misc.rb +21 -2
  12. data/lib/typeprof/core/ast/module.rb +10 -7
  13. data/lib/typeprof/core/ast/pattern.rb +9 -1
  14. data/lib/typeprof/core/ast/sig_decl.rb +163 -42
  15. data/lib/typeprof/core/ast/sig_type.rb +394 -24
  16. data/lib/typeprof/core/ast/value.rb +10 -2
  17. data/lib/typeprof/core/ast/variable.rb +32 -2
  18. data/lib/typeprof/core/ast.rb +15 -4
  19. data/lib/typeprof/core/builtin.rb +15 -9
  20. data/lib/typeprof/core/env/method.rb +21 -16
  21. data/lib/typeprof/core/env/method_entity.rb +11 -2
  22. data/lib/typeprof/core/env/module_entity.rb +57 -0
  23. data/lib/typeprof/core/env/narrowing.rb +131 -0
  24. data/lib/typeprof/core/env/static_read.rb +9 -8
  25. data/lib/typeprof/core/env.rb +37 -12
  26. data/lib/typeprof/core/graph/box.rb +207 -97
  27. data/lib/typeprof/core/graph/change_set.rb +44 -37
  28. data/lib/typeprof/core/graph/vertex.rb +4 -21
  29. data/lib/typeprof/core/service.rb +30 -1
  30. data/lib/typeprof/core/type.rb +48 -123
  31. data/lib/typeprof/core.rb +1 -0
  32. data/lib/typeprof/diagnostic.rb +5 -6
  33. data/lib/typeprof/lsp/messages.rb +21 -15
  34. data/lib/typeprof/lsp/server.rb +132 -39
  35. data/lib/typeprof/lsp/text.rb +1 -0
  36. data/lib/typeprof/version.rb +1 -1
  37. data/typeprof.conf.jsonc +22 -0
  38. data/typeprof.gemspec +1 -0
  39. metadata +19 -6
@@ -1,5 +1,83 @@
1
1
  module TypeProf::Core
2
2
  class AST
3
+ def self.typecheck_for_module(genv, changes, f_mod, f_args, a_vtx, subst)
4
+ changes.add_edge(genv, a_vtx, changes.target)
5
+ a_vtx.each_type do |ty|
6
+ ty = ty.base_type(genv)
7
+ while ty
8
+ if ty.mod == f_mod && ty.is_a?(Type::Instance)
9
+ args_all_match = true
10
+ f_args.zip(ty.args) do |f_arg_node, a_arg_ty|
11
+ unless f_arg_node.typecheck(genv, changes, a_arg_ty, subst)
12
+ args_all_match = false
13
+ break
14
+ end
15
+ end
16
+ return true if args_all_match
17
+ end
18
+ changes.add_depended_superclass(ty.mod)
19
+
20
+ if f_mod.module?
21
+ return true if typecheck_for_prepended_modules(genv, changes, ty, f_mod, f_args, subst)
22
+ return true if typecheck_for_included_modules(genv, changes, ty, f_mod, f_args, subst)
23
+ end
24
+
25
+ ty = genv.get_superclass_type(ty, changes, {})
26
+ end
27
+ end
28
+ return false
29
+ end
30
+
31
+ def self.typecheck_for_prepended_modules(genv, changes, a_ty, f_mod, f_args, subst)
32
+ a_ty.mod.prepended_modules.each do |prep_decl, prep_mod|
33
+ if prep_decl.is_a?(AST::SigPrependNode) && prep_mod.type_params
34
+ prep_ty = genv.get_instance_type(prep_mod, prep_decl.args, changes, {}, a_ty)
35
+ else
36
+ type_params = prep_mod.type_params.map {|ty_param| Source.new() } # TODO: better support
37
+ prep_ty = Type::Instance.new(genv, prep_mod, type_params)
38
+ end
39
+ if prep_ty.mod == f_mod
40
+ args_all_match = true
41
+ f_args.zip(prep_ty.args) do |f_arg_node, a_arg_ty|
42
+ unless f_arg_node.typecheck(genv, changes, a_arg_ty, subst)
43
+ args_all_match = false
44
+ break
45
+ end
46
+ end
47
+ return true if args_all_match
48
+ end
49
+ changes.add_depended_superclass(prep_ty.mod)
50
+
51
+ return true if typecheck_for_prepended_modules(genv, changes, prep_ty, f_mod, f_args, subst)
52
+ end
53
+ return false
54
+ end
55
+
56
+ def self.typecheck_for_included_modules(genv, changes, a_ty, f_mod, f_args, subst)
57
+ a_ty.mod.included_modules.each do |inc_decl, inc_mod|
58
+ if inc_decl.is_a?(AST::SigIncludeNode) && inc_mod.type_params
59
+ inc_ty = genv.get_instance_type(inc_mod, inc_decl.args, changes, {}, a_ty)
60
+ else
61
+ type_params = inc_mod.type_params.map {|ty_param| Source.new() } # TODO: better support
62
+ inc_ty = Type::Instance.new(genv, inc_mod, type_params)
63
+ end
64
+ if inc_ty.mod == f_mod
65
+ args_all_match = true
66
+ f_args.zip(inc_ty.args) do |f_arg_node, a_arg_vtx|
67
+ unless f_arg_node.typecheck(genv, changes, a_arg_vtx, subst)
68
+ args_all_match = false
69
+ break
70
+ end
71
+ end
72
+ return true if args_all_match
73
+ end
74
+ changes.add_depended_superclass(inc_ty.mod)
75
+
76
+ return true if typecheck_for_included_modules(genv, changes, inc_ty, f_mod, f_args, subst)
77
+ end
78
+ return false
79
+ end
80
+
3
81
  class SigFuncType < Node
4
82
  def initialize(raw_decl, raw_type_params, raw_block, lenv)
5
83
  super(raw_decl, lenv)
@@ -101,6 +179,14 @@ module TypeProf::Core
101
179
  changes.add_edge(genv, Source.new(genv.true_type, genv.false_type), vtx)
102
180
  end
103
181
 
182
+ def typecheck(genv, changes, vtx, subst)
183
+ changes.add_edge(genv, vtx, changes.target)
184
+ vtx.each_type do |ty|
185
+ return false unless ty == genv.true_type || ty == genv.false_type
186
+ end
187
+ true
188
+ end
189
+
104
190
  def show
105
191
  "bool"
106
192
  end
@@ -115,6 +201,14 @@ module TypeProf::Core
115
201
  changes.add_edge(genv, Source.new(genv.nil_type), vtx)
116
202
  end
117
203
 
204
+ def typecheck(genv, changes, vtx, subst)
205
+ changes.add_edge(genv, vtx, changes.target)
206
+ vtx.each_type do |ty|
207
+ return false unless ty == genv.nil_type
208
+ end
209
+ true
210
+ end
211
+
118
212
  def show
119
213
  "nil"
120
214
  end
@@ -129,6 +223,10 @@ module TypeProf::Core
129
223
  changes.add_edge(genv, subst[:"*self"], vtx)
130
224
  end
131
225
 
226
+ def typecheck(genv, changes, vtx, subst)
227
+ true # TODO: check self type
228
+ end
229
+
132
230
  def show
133
231
  "self"
134
232
  end
@@ -143,6 +241,10 @@ module TypeProf::Core
143
241
  changes.add_edge(genv, Source.new(genv.obj_type), vtx)
144
242
  end
145
243
 
244
+ def typecheck(genv, changes, vtx, subst)
245
+ true
246
+ end
247
+
146
248
  def show
147
249
  "void"
148
250
  end
@@ -156,6 +258,10 @@ module TypeProf::Core
156
258
  #Source.new(genv.obj_type).add_edge(genv, vtx) # TODO
157
259
  end
158
260
 
261
+ def typecheck(genv, changes, vtx, subst)
262
+ true
263
+ end
264
+
159
265
  def show
160
266
  "untyped"
161
267
  end
@@ -170,6 +276,10 @@ module TypeProf::Core
170
276
  # TODO
171
277
  end
172
278
 
279
+ def typecheck(genv, changes, vtx, subst)
280
+ true
281
+ end
282
+
173
283
  def show
174
284
  "top"
175
285
  end
@@ -184,6 +294,11 @@ module TypeProf::Core
184
294
  changes.add_edge(genv, Source.new(Type::Bot.new(genv)), vtx)
185
295
  end
186
296
 
297
+ def typecheck(genv, changes, vtx, subst)
298
+ changes.add_edge(genv, vtx, changes.target)
299
+ vtx.types.empty?
300
+ end
301
+
187
302
  def show
188
303
  "bot"
189
304
  end
@@ -198,6 +313,10 @@ module TypeProf::Core
198
313
  changes.add_edge(genv, subst[:"*instance"], vtx)
199
314
  end
200
315
 
316
+ def typecheck(genv, changes, vtx, subst)
317
+ true # TODO: implement
318
+ end
319
+
201
320
  def show
202
321
  "instance"
203
322
  end
@@ -212,6 +331,10 @@ module TypeProf::Core
212
331
  changes.add_edge(genv, subst[:"*class"], vtx)
213
332
  end
214
333
 
334
+ def typecheck(genv, changes, vtx, subst)
335
+ true # TODO: implement
336
+ end
337
+
215
338
  def show
216
339
  "class"
217
340
  end
@@ -236,13 +359,13 @@ module TypeProf::Core
236
359
 
237
360
  static_reads = []
238
361
  if @cpath.empty?
239
- static_reads << BaseTypeAliasRead.new(genv, @name, @toplevel ? CRef::Toplevel : @lenv.cref)
362
+ static_reads << BaseTypeAliasRead.new(genv, @name, @toplevel ? CRef::Toplevel : @lenv.cref, false)
240
363
  else
241
- static_reads << BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
364
+ static_reads << BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
242
365
  @cpath[1..].each do |cname|
243
- static_reads << ScopedConstRead.new(cname, static_reads.last)
366
+ static_reads << ScopedConstRead.new(cname, static_reads.last, false)
244
367
  end
245
- static_reads << ScopedTypeAliasRead.new(@name, static_reads.last)
368
+ static_reads << ScopedTypeAliasRead.new(@name, static_reads.last, false)
246
369
  end
247
370
  static_reads
248
371
  end
@@ -258,9 +381,24 @@ module TypeProf::Core
258
381
  changes.add_depended_static_read(@static_ret.last)
259
382
  tae = @static_ret.last.type_alias_entity
260
383
  if tae && tae.exist?
384
+ # Check for recursive expansion
385
+ expansion_key = [@cpath, @name]
386
+ subst[:__expansion_stack__] ||= []
387
+
388
+ if subst[:__expansion_stack__].include?(expansion_key)
389
+ # Recursive expansion detected: this type alias references itself
390
+ # Stop expansion here to prevent SystemStackError. The type system
391
+ # will handle the incomplete expansion gracefully, typically by
392
+ # treating unresolved recursive references as 'untyped', which
393
+ # maintains type safety while allowing the program to continue.
394
+ return
395
+ end
396
+
261
397
  # need to check tae decls are all consistent?
262
398
  decl = tae.decls.each {|decl| break decl }
263
399
  subst0 = subst.dup
400
+ subst0[:__expansion_stack__] = subst[:__expansion_stack__].dup + [expansion_key]
401
+
264
402
  # raise if decl.params.size != @args.size # ?
265
403
  decl.params.zip(@args) do |param, arg|
266
404
  subst0[param] = arg.covariant_vertex(genv, changes, subst0) # passing subst0 is ok?
@@ -273,9 +411,24 @@ module TypeProf::Core
273
411
  changes.add_depended_static_read(@static_ret.last)
274
412
  tae = @static_ret.last.type_alias_entity
275
413
  if tae && tae.exist?
414
+ # Check for recursive expansion
415
+ expansion_key = [@cpath, @name]
416
+ subst[:__expansion_stack__] ||= []
417
+
418
+ if subst[:__expansion_stack__].include?(expansion_key)
419
+ # Recursive expansion detected: this type alias references itself
420
+ # Stop expansion here to prevent SystemStackError. The type system
421
+ # will handle the incomplete expansion gracefully, typically by
422
+ # treating unresolved recursive references as 'untyped', which
423
+ # maintains type safety while allowing the program to continue.
424
+ return
425
+ end
426
+
276
427
  # need to check tae decls are all consistent?
277
428
  decl = tae.decls.each {|decl| break decl }
278
429
  subst0 = subst.dup
430
+ subst0[:__expansion_stack__] = subst[:__expansion_stack__].dup + [expansion_key]
431
+
279
432
  # raise if decl.params.size != @args.size # ?
280
433
  decl.params.zip(@args) do |param, arg|
281
434
  subst0[param] = arg.contravariant_vertex(genv, changes, subst0)
@@ -284,6 +437,20 @@ module TypeProf::Core
284
437
  end
285
438
  end
286
439
 
440
+ def typecheck(genv, changes, vtx, subst)
441
+ changes.add_depended_static_read(@static_ret.last)
442
+ tae = @static_ret.last.type_alias_entity
443
+ if tae && tae.exist?
444
+ # TODO: check for recursive expansion
445
+ decl = tae.decls.each {|decl| break decl }
446
+ subst0 = subst.dup
447
+ decl.params.zip(@args) do |param, arg|
448
+ subst0[param] = arg.covariant_vertex(genv, changes, subst0)
449
+ end
450
+ tae.type.typecheck(genv, changes, vtx, subst0)
451
+ end
452
+ end
453
+
287
454
  def show
288
455
  "(...alias...)"
289
456
  end
@@ -311,22 +478,49 @@ module TypeProf::Core
311
478
  end
312
479
  end
313
480
 
481
+ def typecheck(genv, changes, vtx, subst)
482
+ @types.each do |type|
483
+ return true if type.typecheck(genv, changes, vtx, subst)
484
+ end
485
+ false
486
+ end
487
+
314
488
  def show
315
489
  @types.map {|ty| ty.show }.join(" | ")
316
490
  end
317
491
  end
318
492
 
319
493
  class SigTyIntersectionNode < SigTyNode
494
+ def initialize(raw_decl, lenv)
495
+ super(raw_decl, lenv)
496
+ @types = (raw_decl.types || []).map {|type| AST.create_rbs_type(type, lenv) }
497
+ end
498
+
499
+ attr_reader :types
500
+
501
+ def subnodes = { types: }
502
+
320
503
  def covariant_vertex0(genv, changes, vtx, subst)
321
- #raise NotImplementedError
504
+ @types.each do |type|
505
+ type.covariant_vertex0(genv, changes, vtx, subst)
506
+ end
322
507
  end
323
508
 
324
509
  def contravariant_vertex0(genv, changes, vtx, subst)
325
- #raise NotImplementedError
510
+ @types.each do |type|
511
+ type.contravariant_vertex0(genv, changes, vtx, subst)
512
+ end
513
+ end
514
+
515
+ def typecheck(genv, changes, vtx, subst)
516
+ @types.each do |type|
517
+ return false unless type.typecheck(genv, changes, vtx, subst)
518
+ end
519
+ true
326
520
  end
327
521
 
328
522
  def show
329
- "(...intersection...)"
523
+ @types.map {|ty| ty.show }.join(" & ")
330
524
  end
331
525
  end
332
526
 
@@ -343,11 +537,11 @@ module TypeProf::Core
343
537
 
344
538
  def define0(genv)
345
539
  const_reads = []
346
- const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
540
+ const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
347
541
  const_reads << const_read
348
542
  unless @cpath.empty?
349
543
  @cpath[1..].each do |cname|
350
- const_read = ScopedConstRead.new(cname, const_read)
544
+ const_read = ScopedConstRead.new(cname, const_read, false)
351
545
  const_reads << const_read
352
546
  end
353
547
  end
@@ -378,6 +572,30 @@ module TypeProf::Core
378
572
  changes.add_edge(genv, Source.new(Type::Singleton.new(genv, mod)), vtx)
379
573
  end
380
574
 
575
+ def typecheck(genv, changes, vtx, subst)
576
+ changes.add_depended_static_read(@static_ret.last)
577
+ cpath = @static_ret.last.cpath
578
+ return unless cpath
579
+ f_mod = genv.resolve_cpath(cpath)
580
+ changes.add_edge(genv, vtx, changes.target)
581
+ vtx.each_type do |ty|
582
+ case ty
583
+ when Type::Singleton
584
+ if f_mod.module?
585
+ # TODO: implement
586
+ else
587
+ a_mod = ty.mod
588
+ while a_mod
589
+ return true if a_mod == f_mod
590
+ changes.add_depended_superclass(a_mod)
591
+ a_mod = a_mod.superclass
592
+ end
593
+ end
594
+ end
595
+ end
596
+ false
597
+ end
598
+
381
599
  def show
382
600
  s = "::#{ @cpath.join("::") }"
383
601
  if !@args.empty?
@@ -403,11 +621,11 @@ module TypeProf::Core
403
621
  def define0(genv)
404
622
  @args.each {|arg| arg.define(genv) }
405
623
  const_reads = []
406
- const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
624
+ const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
407
625
  const_reads << const_read
408
626
  unless @cpath.empty?
409
627
  @cpath[1..].each do |cname|
410
- const_read = ScopedConstRead.new(cname, const_read)
628
+ const_read = ScopedConstRead.new(cname, const_read, false)
411
629
  const_reads << const_read
412
630
  end
413
631
  end
@@ -435,16 +653,33 @@ module TypeProf::Core
435
653
  cpath = @static_ret.last.cpath
436
654
  return unless cpath
437
655
  mod = genv.resolve_cpath(cpath)
438
- args = @args.map {|arg| arg.contravariant_vertex(genv, changes, subst) }
656
+ # TODO: report error for wrong type arguments
657
+ # TODO: support default type args
658
+ args = mod.type_params.zip(@args).map do |_, arg|
659
+ arg ? arg.contravariant_vertex(genv, changes, subst) : Source.new
660
+ end
439
661
  changes.add_edge(genv, Source.new(Type::Instance.new(genv, mod, args)), vtx)
440
662
  end
441
663
 
664
+ def typecheck(genv, changes, vtx, subst)
665
+ changes.add_depended_static_read(@static_ret.last)
666
+ cpath = @static_ret.last.cpath
667
+ return unless cpath
668
+ f_mod = genv.resolve_cpath(cpath)
669
+ AST.typecheck_for_module(genv, changes, f_mod, @args, vtx, subst)
670
+ end
671
+
442
672
  def show
443
- s = "::#{ @cpath.join("::") }"
444
- if !@args.empty?
445
- s << "[...]"
673
+ cpath = @static_ret.last.cpath
674
+ if cpath
675
+ s = "#{ cpath.join("::") }"
676
+ if !@args.empty?
677
+ s << "[...]"
678
+ end
679
+ s
680
+ else
681
+ "(unknown instance)"
446
682
  end
447
- s
448
683
  end
449
684
  end
450
685
 
@@ -477,22 +712,96 @@ module TypeProf::Core
477
712
  changes.add_edge(genv, Source.new(Type::Array.new(genv, elems, genv.gen_ary_type(unified_elem))), vtx)
478
713
  end
479
714
 
715
+ def typecheck(genv, changes, vtx, subst)
716
+ changes.add_edge(genv, vtx, changes.target)
717
+ vtx.each_type do |ty|
718
+ case ty
719
+ when Type::Array
720
+ next if ty.elems.size != @types.size
721
+ @types.zip(ty.elems) do |f_ty, a_ty|
722
+ return false unless f_ty.typecheck(genv, changes, a_ty, subst)
723
+ end
724
+ return true
725
+ when Type::Instance
726
+ @types.each do |f_ty|
727
+ return false unless f_ty.typecheck(genv, changes, vtx, subst)
728
+ end
729
+ return true
730
+ end
731
+ end
732
+ false
733
+ end
734
+
480
735
  def show
481
736
  "[#{ @types.map {|ty| ty.show }.join(", ") }]"
482
737
  end
483
738
  end
484
739
 
485
740
  class SigTyRecordNode < SigTyNode
741
+ def initialize(raw_decl, lenv)
742
+ super(raw_decl, lenv)
743
+ @fields = raw_decl.fields.transform_values { |val| AST.create_rbs_type(val, lenv) }
744
+ end
745
+
746
+ attr_reader :fields
747
+ def subnodes = { fields: }
748
+
486
749
  def covariant_vertex0(genv, changes, vtx, subst)
487
- raise NotImplementedError
750
+ field_vertices = {}
751
+ @fields.each do |key, field_node|
752
+ field_vertices[key] = field_node.covariant_vertex(genv, changes, subst)
753
+ end
754
+
755
+ # Create base Hash type for Record
756
+ key_vtx = Source.new(genv.symbol_type)
757
+ # Create union of all field values for the Hash value type
758
+ val_vtx = changes.new_covariant_vertex(genv, [self, :union])
759
+ field_vertices.each_value do |field_vtx|
760
+ changes.add_edge(genv, field_vtx, val_vtx)
761
+ end
762
+ base_hash_type = genv.gen_hash_type(key_vtx, val_vtx)
763
+
764
+ changes.add_edge(genv, Source.new(Type::Record.new(genv, field_vertices, base_hash_type)), vtx)
488
765
  end
489
766
 
490
767
  def contravariant_vertex0(genv, changes, vtx, subst)
491
- raise NotImplementedError
768
+ field_vertices = {}
769
+ @fields.each do |key, field_node|
770
+ field_vertices[key] = field_node.contravariant_vertex(genv, changes, subst)
771
+ end
772
+
773
+ # Create base Hash type for Record
774
+ key_vtx = Source.new(genv.symbol_type)
775
+ # Create union of all field values for the Hash value type
776
+ val_vtx = changes.new_contravariant_vertex(genv, [self, :union])
777
+ field_vertices.each_value do |field_vtx|
778
+ changes.add_edge(genv, field_vtx, val_vtx)
779
+ end
780
+ base_hash_type = genv.gen_hash_type(key_vtx, val_vtx)
781
+
782
+ changes.add_edge(genv, Source.new(Type::Record.new(genv, field_vertices, base_hash_type)), vtx)
783
+ end
784
+
785
+ def typecheck(genv, changes, vtx, subst)
786
+ changes.add_edge(genv, vtx, changes.target)
787
+ vtx.each_type do |ty|
788
+ case ty
789
+ when Type::Hash
790
+ @fields.each do |key, field_node|
791
+ val_vtx = ty.get_value(key)
792
+ return false unless field_node.typecheck(genv, changes, val_vtx, subst)
793
+ end
794
+ return true
795
+ end
796
+ end
797
+ false
492
798
  end
493
799
 
494
800
  def show
495
- "(...record...)"
801
+ field_strs = @fields.map do |key, field_node|
802
+ "#{ key }: #{ field_node.show }"
803
+ end
804
+ "{ #{ field_strs.join(", ") } }"
496
805
  end
497
806
  end
498
807
 
@@ -516,6 +825,11 @@ module TypeProf::Core
516
825
  changes.add_edge(genv, Source.new(Type::Var.new(genv, @var, subst[@var])), vtx)
517
826
  end
518
827
 
828
+ def typecheck(genv, changes, vtx, subst)
829
+ changes.add_edge(genv, vtx, subst[@var]) unless vtx == subst[@var]
830
+ true
831
+ end
832
+
519
833
  def show
520
834
  "#{ @var }"
521
835
  end
@@ -540,6 +854,10 @@ module TypeProf::Core
540
854
  changes.add_edge(genv, Source.new(genv.nil_type), vtx)
541
855
  end
542
856
 
857
+ def typecheck(genv, changes, vtx, subst)
858
+ @type.typecheck(genv, changes, vtx, subst)
859
+ end
860
+
543
861
  def show
544
862
  s = @type.show
545
863
  if @type.is_a?(SigTyIntersectionNode) || @type.is_a?(SigTyUnionNode)
@@ -579,22 +897,65 @@ module TypeProf::Core
579
897
  changes.add_edge(genv, Source.new(get_type(genv)), vtx)
580
898
  end
581
899
 
900
+ def typecheck(genv, changes, vtx, subst)
901
+ if @lit.is_a?(::Symbol)
902
+ changes.add_edge(genv, vtx, changes.target)
903
+ vtx.each_type do |ty|
904
+ case ty
905
+ when Type::Symbol
906
+ return true if ty.sym == @lit
907
+ end
908
+ end
909
+ return false
910
+ end
911
+ f_mod = get_type(genv).mod
912
+ AST.typecheck_for_module(genv, changes, f_mod, [], vtx, subst)
913
+ end
914
+
582
915
  def show
583
916
  @lit.inspect
584
917
  end
585
918
  end
586
919
 
587
920
  class SigTyProcNode < SigTyNode
921
+ def initialize(raw_decl, lenv)
922
+ super(raw_decl, lenv)
923
+ # raw_decl.type is an RBS::Types::Function, we need to wrap it in a MethodType
924
+ if raw_decl.type
925
+ method_type = RBS::MethodType.new(
926
+ type: raw_decl.type,
927
+ type_params: [],
928
+ block: raw_decl.block,
929
+ location: raw_decl.location
930
+ )
931
+ @type = AST.create_rbs_func_type(method_type, nil, raw_decl.block, lenv)
932
+ else
933
+ @type = nil
934
+ end
935
+ end
936
+
937
+ attr_reader :type
938
+ def subnodes = { type: }
939
+
588
940
  def covariant_vertex0(genv, changes, vtx, subst)
589
- raise NotImplementedError
941
+ # For now, just return the base Proc type without the function signature details
942
+ # TODO: Create a proper Type::Proc with the function signature
943
+ changes.add_edge(genv, Source.new(genv.proc_type), vtx)
590
944
  end
591
945
 
592
946
  def contravariant_vertex0(genv, changes, vtx, subst)
593
- Source.new()
947
+ # For now, just return the base Proc type without the function signature details
948
+ # TODO: Create a proper Type::Proc with the function signature
949
+ changes.add_edge(genv, Source.new(genv.proc_type), vtx)
950
+ end
951
+
952
+ def typecheck(genv, changes, vtx, subst)
953
+ # TODO: proper check
954
+ AST.typecheck_for_module(genv, changes, genv.proc_type.mod, [], vtx, subst)
594
955
  end
595
956
 
596
957
  def show
597
- "(...proc...)"
958
+ "^(...)"
598
959
  end
599
960
  end
600
961
 
@@ -615,11 +976,11 @@ module TypeProf::Core
615
976
  def define0(genv)
616
977
  @args.each {|arg| arg.define(genv) }
617
978
  const_reads = []
618
- const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
979
+ const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
619
980
  const_reads << const_read
620
981
  unless @cpath.empty?
621
982
  @cpath[1..].each do |cname|
622
- const_read = ScopedConstRead.new(cname, const_read)
983
+ const_read = ScopedConstRead.new(cname, const_read, false)
623
984
  const_reads << const_read
624
985
  end
625
986
  end
@@ -651,6 +1012,15 @@ module TypeProf::Core
651
1012
  changes.add_edge(genv, Source.new(Type::Instance.new(genv, mod, args)), vtx)
652
1013
  end
653
1014
 
1015
+ def typecheck(genv, changes, vtx, subst)
1016
+ changes.add_depended_static_read(@static_ret.last)
1017
+ cpath = @static_ret.last.cpath
1018
+ return unless cpath
1019
+ f_mod = genv.resolve_cpath(cpath)
1020
+ # self/f_mod: formal, vtx: actual
1021
+ AST.typecheck_for_module(genv, changes, f_mod, @args, vtx, subst)
1022
+ end
1023
+
654
1024
  def show
655
1025
  s = "::#{ @cpath.join("::") }"
656
1026
  if !@args.empty?
@@ -272,7 +272,11 @@ module TypeProf::Core
272
272
  @vals << AST.create_node(raw_elem.value, lenv)
273
273
  when :assoc_splat_node
274
274
  @keys << nil
275
- @vals << AST.create_node(raw_elem.value, lenv)
275
+ if raw_elem.value
276
+ @vals << AST.create_node(raw_elem.value, lenv)
277
+ else
278
+ @vals << DummyNilNode.new(code_range, lenv)
279
+ end
276
280
  @splat = true
277
281
  else
278
282
  raise "unknown hash elem: #{ raw_elem.type }"
@@ -297,7 +301,11 @@ module TypeProf::Core
297
301
  @changes.add_edge(genv, v, unified_val)
298
302
  literal_pairs[key.lit] = v if key.is_a?(SymbolNode)
299
303
  else
300
- h = val.install(genv)
304
+ if val.is_a?(DummyNilNode)
305
+ h = @lenv.get_var(:"**anonymous_keyword")
306
+ else
307
+ h = val.install(genv)
308
+ end
301
309
  # TODO: do we want to call to_hash on h?
302
310
  @changes.add_hash_splat_box(genv, h, unified_key, unified_val)
303
311
  end