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
@@ -19,6 +19,7 @@ module TypeProf::Core
19
19
  end
20
20
 
21
21
  @cname_code_range = meta ? nil : TypeProf::CodeRange.from_node(raw_node.constant_path)
22
+ @mod_cdef = nil
22
23
  end
23
24
 
24
25
  attr_reader :tbl, :cpath, :static_cpath, :cname_code_range, :body
@@ -29,9 +30,9 @@ module TypeProf::Core
29
30
  def define0(genv)
30
31
  @cpath.define(genv)
31
32
  if @static_cpath
33
+ mod = genv.resolve_cpath(@static_cpath)
34
+ @mod_cdef = mod.add_module_def(genv, self)
32
35
  @body.define(genv)
33
- @mod = genv.resolve_cpath(@static_cpath)
34
- @mod_cdef = @mod.add_module_def(genv, self)
35
36
  else
36
37
  kind = self.is_a?(ModuleNode) ? "module" : "class"
37
38
  @changes.add_diagnostic(:code_range, "TypeProf cannot analyze a non-static #{ kind }") # warning
@@ -41,15 +42,17 @@ module TypeProf::Core
41
42
 
42
43
  def define_copy(genv)
43
44
  if @static_cpath
44
- @mod_cdef.add_def(self)
45
- @mod_cdef.remove_def(@prev_node)
45
+ mod = genv.resolve_cpath(@static_cpath)
46
+ @mod_cdef = mod.add_module_def(genv, self)
47
+ mod.remove_module_def(genv, @prev_node)
46
48
  end
47
49
  super(genv)
48
50
  end
49
51
 
50
52
  def undefine0(genv)
51
53
  if @static_cpath
52
- @mod.remove_module_def(genv, self)
54
+ mod = genv.resolve_cpath(@static_cpath)
55
+ mod.remove_module_def(genv, self)
53
56
  @body.undefine(genv)
54
57
  end
55
58
  @cpath.undefine(genv)
@@ -61,8 +64,8 @@ module TypeProf::Core
61
64
  @tbl.each {|var| @body.lenv.locals[var] = Source.new(genv.nil_type) }
62
65
  @body.lenv.locals[:"*self"] = @body.lenv.cref.get_self(genv)
63
66
 
64
- @mod_val = Source.new(Type::Singleton.new(genv, genv.resolve_cpath(@static_cpath)))
65
- @changes.add_edge(genv, @mod_val, @mod_cdef.vtx)
67
+ mod_val = Source.new(Type::Singleton.new(genv, genv.resolve_cpath(@static_cpath)))
68
+ @changes.add_edge(genv, mod_val, @mod_cdef.vtx)
66
69
  ret = Vertex.new(self)
67
70
  @changes.add_edge(genv, @body.install(genv), ret)
68
71
  ret
@@ -5,7 +5,15 @@ module TypeProf::Core
5
5
  super(raw_node, lenv)
6
6
  @requireds = raw_node.requireds.map {|raw_pat| AST.create_pattern_node(raw_pat, lenv) }
7
7
  @rest = !!raw_node.rest
8
- @rest_pattern = raw_node.rest && raw_node.rest.expression ? AST.create_pattern_node(raw_node.rest.expression, lenv) : nil
8
+ @rest_pattern = case raw_node.rest
9
+ when Prism::SplatNode
10
+ AST.create_pattern_node(raw_node.rest.expression, lenv) if raw_node.rest.expression
11
+ when Prism::ImplicitRestNode, nil
12
+ nil
13
+ else
14
+ raise
15
+ end
16
+
9
17
  @posts = raw_node.posts.map {|raw_pat| AST.create_pattern_node(raw_pat, lenv) }
10
18
  end
11
19
 
@@ -52,8 +52,8 @@ module TypeProf::Core
52
52
  end
53
53
 
54
54
  def install0(genv)
55
- @mod_val = Source.new(Type::Singleton.new(genv, genv.resolve_cpath(@cpath)))
56
- @changes.add_edge(genv, @mod_val, @static_ret[:module].vtx)
55
+ mod_val = Source.new(Type::Singleton.new(genv, genv.resolve_cpath(@cpath)))
56
+ @changes.add_edge(genv, mod_val, @static_ret[:module].vtx)
57
57
  @members.each do |member|
58
58
  member.install(genv)
59
59
  end
@@ -89,10 +89,10 @@ module TypeProf::Core
89
89
  static_ret[:self_types] = self_types = []
90
90
  @self_types.zip(@self_type_args) do |(cpath, toplevel), args|
91
91
  args.each {|arg| arg.define(genv) }
92
- const_read = BaseConstRead.new(genv, cpath.first, toplevel ? CRef::Toplevel : @lenv.cref)
92
+ const_read = BaseConstRead.new(genv, cpath.first, toplevel ? CRef::Toplevel : @lenv.cref, false)
93
93
  const_reads = [const_read]
94
94
  cpath[1..].each do |cname|
95
- const_read = ScopedConstRead.new(cname, const_read)
95
+ const_read = ScopedConstRead.new(cname, const_read, false)
96
96
  const_reads << const_read
97
97
  end
98
98
  mod = genv.resolve_cpath(@cpath)
@@ -150,10 +150,10 @@ module TypeProf::Core
150
150
  const_reads = []
151
151
  if @superclass_cpath
152
152
  @superclass_args.each {|arg| arg.define(genv) }
153
- const_read = BaseConstRead.new(genv, @superclass_cpath.first, @superclass_toplevel ? CRef::Toplevel : @lenv.cref)
153
+ const_read = BaseConstRead.new(genv, @superclass_cpath.first, @superclass_toplevel ? CRef::Toplevel : @lenv.cref, false)
154
154
  const_reads << const_read
155
155
  @superclass_cpath[1..].each do |cname|
156
- const_read = ScopedConstRead.new(cname, const_read)
156
+ const_read = ScopedConstRead.new(cname, const_read, false)
157
157
  const_reads << const_read
158
158
  end
159
159
  mod = genv.resolve_cpath(@cpath)
@@ -180,6 +180,7 @@ module TypeProf::Core
180
180
  def initialize(raw_decl, lenv)
181
181
  super(raw_decl, lenv)
182
182
  @mid = raw_decl.name
183
+ @mid_code_range = TypeProf::CodeRange.from_node(raw_decl.location[:name])
183
184
  @singleton = raw_decl.singleton?
184
185
  @instance = raw_decl.instance?
185
186
  @method_types = raw_decl.overloads.map do |overload|
@@ -189,10 +190,12 @@ module TypeProf::Core
189
190
  @overloading = raw_decl.overloading
190
191
  end
191
192
 
192
- attr_reader :mid, :singleton, :instance, :method_types, :overloading
193
+ attr_reader :mid, :singleton, :instance, :method_types, :overloading, :mid_code_range
193
194
 
194
195
  def subnodes = { method_types: }
195
- def attrs = { mid:, singleton:, instance:, overloading: }
196
+ def attrs = { mid:, mid_code_range:, singleton:, instance:, overloading: }
197
+
198
+ def mname_code_range(_name) = @mid_code_range
196
199
 
197
200
  def install0(genv)
198
201
  [[@singleton, true], [@instance, false]].each do |enabled, singleton|
@@ -219,10 +222,10 @@ module TypeProf::Core
219
222
  def define0(genv)
220
223
  @args.each {|arg| arg.define(genv) }
221
224
  const_reads = []
222
- const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref)
225
+ const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
223
226
  const_reads << const_read
224
227
  @cpath[1..].each do |cname|
225
- const_read = ScopedConstRead.new(cname, const_read)
228
+ const_read = ScopedConstRead.new(cname, const_read, false)
226
229
  const_reads << const_read
227
230
  end
228
231
  mod = genv.resolve_cpath(@lenv.cref.cpath)
@@ -252,6 +255,55 @@ module TypeProf::Core
252
255
  end
253
256
  end
254
257
 
258
+ class SigPrependNode < Node
259
+ def initialize(raw_decl, lenv)
260
+ super(raw_decl, lenv)
261
+ name = raw_decl.name
262
+ @cpath = name.namespace.path + [name.name]
263
+ @toplevel = name.namespace.absolute?
264
+ @args = raw_decl.args.map {|arg| AST.create_rbs_type(arg, lenv) }
265
+ end
266
+
267
+ attr_reader :cpath, :toplevel, :args
268
+ def subnodes = { args: }
269
+ def attrs = { cpath:, toplevel: }
270
+
271
+ def define0(genv)
272
+ @args.each {|arg| arg.define(genv) }
273
+ const_reads = []
274
+ const_read = BaseConstRead.new(genv, @cpath.first, @toplevel ? CRef::Toplevel : @lenv.cref, false)
275
+ const_reads << const_read
276
+ @cpath[1..].each do |cname|
277
+ const_read = ScopedConstRead.new(cname, const_read, false)
278
+ const_reads << const_read
279
+ end
280
+ mod = genv.resolve_cpath(@lenv.cref.cpath)
281
+ const_read.followers << mod
282
+ mod.add_prepend_decl(genv, self)
283
+ const_reads
284
+ end
285
+
286
+ def define_copy(genv)
287
+ mod = genv.resolve_cpath(@lenv.cref.cpath)
288
+ mod.add_prepend_decl(genv, self)
289
+ mod.remove_prepend_decl(genv, @prev_node)
290
+ super(genv)
291
+ end
292
+
293
+ def undefine0(genv)
294
+ mod = genv.resolve_cpath(@lenv.cref.cpath)
295
+ mod.remove_prepend_decl(genv, self)
296
+ @static_ret.each do |const_read|
297
+ const_read.destroy(genv)
298
+ end
299
+ @args.each {|arg| arg.undefine(genv) }
300
+ end
301
+
302
+ def install0(genv)
303
+ Source.new
304
+ end
305
+ end
306
+
255
307
  class SigAliasNode < Node
256
308
  def initialize(raw_decl, lenv)
257
309
  super(raw_decl, lenv)
@@ -277,17 +329,13 @@ module TypeProf::Core
277
329
  def initialize(raw_decl, lenv)
278
330
  super(raw_decl, lenv)
279
331
  @mid = raw_decl.name
280
- # `eval` is used to prevent TypeProf from failing to parse keyword arguments during dogfooding.
281
- # TODO: Remove `eval` once TypeProf supports keyword arguments.
282
- eval <<~RUBY
283
- rbs_method_type = RBS::MethodType.new(
284
- type: RBS::Types::Function.empty(raw_decl.type),
285
- type_params: [],
286
- block: nil,
287
- location: raw_decl.type.location,
288
- )
289
- @method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
290
- RUBY
332
+ rbs_method_type = RBS::MethodType.new(
333
+ type: RBS::Types::Function.empty(raw_decl.type),
334
+ type_params: [],
335
+ block: nil,
336
+ location: raw_decl.type.location
337
+ )
338
+ @method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
291
339
  end
292
340
 
293
341
  attr_reader :mid, :method_type
@@ -306,27 +354,23 @@ module TypeProf::Core
306
354
  super(raw_decl, lenv)
307
355
  @mid = :"#{raw_decl.name}="
308
356
 
309
- # `eval` is used to prevent TypeProf from failing to parse keyword arguments during dogfooding.
310
- # TODO: Remove `eval` once TypeProf supports keyword arguments.
311
- eval <<~RUBY
312
- # (raw_decl.type) -> raw_decl.type
313
- rbs_method_type = RBS::MethodType.new(
314
- type: RBS::Types::Function.new(
315
- required_positionals: [RBS::Types::Function::Param.new(name: nil, type: raw_decl.type, location: raw_decl.type.location)],
316
- optional_positionals: [],
317
- rest_positionals: nil,
318
- trailing_positionals: [],
319
- required_keywords: {},
320
- optional_keywords: {},
321
- rest_keywords: nil,
322
- return_type: raw_decl.type,
323
- ),
324
- type_params: [],
325
- block: nil,
326
- location: raw_decl.type.location,
327
- )
328
- @method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
329
- RUBY
357
+ # (raw_decl.type) -> raw_decl.type
358
+ rbs_method_type = RBS::MethodType.new(
359
+ type: RBS::Types::Function.new(
360
+ required_positionals: [RBS::Types::Function::Param.new(name: nil, type: raw_decl.type, location: raw_decl.type.location)],
361
+ optional_positionals: [],
362
+ rest_positionals: nil,
363
+ trailing_positionals: [],
364
+ required_keywords: {},
365
+ optional_keywords: {},
366
+ rest_keywords: nil,
367
+ return_type: raw_decl.type
368
+ ),
369
+ type_params: [],
370
+ block: nil,
371
+ location: raw_decl.type.location
372
+ )
373
+ @method_type = AST.create_rbs_func_type(rbs_method_type, [], nil, lenv)
330
374
  end
331
375
 
332
376
  attr_reader :mid, :method_type
@@ -431,6 +475,83 @@ module TypeProf::Core
431
475
  end
432
476
  end
433
477
 
478
+ class SigInstanceVariableNode < Node
479
+ def initialize(raw_decl, lenv, class_scope)
480
+ super(raw_decl, lenv)
481
+ @var = raw_decl.name
482
+ @cpath = lenv.cref.cpath
483
+ @class_scope = class_scope
484
+ @type = AST.create_rbs_type(raw_decl.type, lenv)
485
+ end
486
+
487
+ attr_reader :cpath, :class_scope, :type
488
+ def subnodes = { type: }
489
+ def attrs = { cpath:, class_scope: }
490
+
491
+ def define0(genv)
492
+ @type.define(genv)
493
+ mod = genv.resolve_ivar(cpath, @class_scope, @var)
494
+ mod.add_decl(self)
495
+ mod
496
+ end
497
+
498
+ def define_copy(genv)
499
+ mod = genv.resolve_ivar(cpath, @class_scope, @var)
500
+ mod.add_decl(self)
501
+ mod.remove_decl(@prev_node)
502
+ super(genv)
503
+ end
504
+
505
+ def undefine0(genv)
506
+ genv.resolve_ivar(cpath, @class_scope, @var).remove_decl(self)
507
+ @type.undefine(genv)
508
+ end
509
+
510
+ def install0(genv)
511
+ box = @changes.add_type_read_box(genv, @type)
512
+ @changes.add_edge(genv, box.ret, @static_ret.vtx)
513
+ box.ret
514
+ end
515
+ end
516
+
517
+ class SigClassVariableNode < Node
518
+ def initialize(raw_decl, lenv)
519
+ super(raw_decl, lenv)
520
+ @var = raw_decl.name
521
+ @cpath = lenv.cref.cpath
522
+ @type = AST.create_rbs_type(raw_decl.type, lenv)
523
+ end
524
+
525
+ attr_reader :cpath, :type
526
+ def subnodes = { type: }
527
+ def attrs = { cpath: }
528
+
529
+ def define0(genv)
530
+ @type.define(genv)
531
+ cvar = genv.resolve_cvar(cpath, @var)
532
+ cvar.add_decl(self)
533
+ cvar
534
+ end
535
+
536
+ def define_copy(genv)
537
+ cvar = genv.resolve_cvar(cpath, @var)
538
+ cvar.add_decl(self)
539
+ cvar.remove_decl(@prev_node)
540
+ super(genv)
541
+ end
542
+
543
+ def undefine0(genv)
544
+ genv.resolve_cvar(cpath, @var).remove_decl(self)
545
+ @type.undefine(genv)
546
+ end
547
+
548
+ def install0(genv)
549
+ box = @changes.add_type_read_box(genv, @type)
550
+ @changes.add_edge(genv, box.ret, @static_ret.vtx)
551
+ box.ret
552
+ end
553
+ end
554
+
434
555
  class SigGlobalVariableNode < Node
435
556
  def initialize(raw_decl, lenv)
436
557
  super(raw_decl, lenv)