typeprof 0.21.11 → 0.30.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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -31
  3. data/bin/typeprof +5 -0
  4. data/doc/doc.ja.md +134 -0
  5. data/doc/doc.md +136 -0
  6. data/lib/typeprof/cli/cli.rb +180 -0
  7. data/lib/typeprof/cli.rb +2 -133
  8. data/lib/typeprof/code_range.rb +112 -0
  9. data/lib/typeprof/core/ast/base.rb +263 -0
  10. data/lib/typeprof/core/ast/call.rb +251 -0
  11. data/lib/typeprof/core/ast/const.rb +126 -0
  12. data/lib/typeprof/core/ast/control.rb +432 -0
  13. data/lib/typeprof/core/ast/meta.rb +150 -0
  14. data/lib/typeprof/core/ast/method.rb +335 -0
  15. data/lib/typeprof/core/ast/misc.rb +263 -0
  16. data/lib/typeprof/core/ast/module.rb +123 -0
  17. data/lib/typeprof/core/ast/pattern.rb +140 -0
  18. data/lib/typeprof/core/ast/sig_decl.rb +471 -0
  19. data/lib/typeprof/core/ast/sig_type.rb +663 -0
  20. data/lib/typeprof/core/ast/value.rb +319 -0
  21. data/lib/typeprof/core/ast/variable.rb +315 -0
  22. data/lib/typeprof/core/ast.rb +472 -0
  23. data/lib/typeprof/core/builtin.rb +146 -0
  24. data/lib/typeprof/core/env/method.rb +137 -0
  25. data/lib/typeprof/core/env/method_entity.rb +55 -0
  26. data/lib/typeprof/core/env/module_entity.rb +408 -0
  27. data/lib/typeprof/core/env/static_read.rb +155 -0
  28. data/lib/typeprof/core/env/type_alias_entity.rb +27 -0
  29. data/lib/typeprof/core/env/value_entity.rb +32 -0
  30. data/lib/typeprof/core/env.rb +360 -0
  31. data/lib/typeprof/core/graph/box.rb +991 -0
  32. data/lib/typeprof/core/graph/change_set.rb +224 -0
  33. data/lib/typeprof/core/graph/filter.rb +155 -0
  34. data/lib/typeprof/core/graph/vertex.rb +222 -0
  35. data/lib/typeprof/core/graph.rb +3 -0
  36. data/lib/typeprof/core/service.rb +522 -0
  37. data/lib/typeprof/core/type.rb +348 -0
  38. data/lib/typeprof/core/util.rb +81 -0
  39. data/lib/typeprof/core.rb +32 -0
  40. data/lib/typeprof/diagnostic.rb +35 -0
  41. data/lib/typeprof/lsp/messages.rb +430 -0
  42. data/lib/typeprof/lsp/server.rb +177 -0
  43. data/lib/typeprof/lsp/text.rb +69 -0
  44. data/lib/typeprof/lsp/util.rb +61 -0
  45. data/lib/typeprof/lsp.rb +4 -907
  46. data/lib/typeprof/version.rb +1 -1
  47. data/lib/typeprof.rb +4 -18
  48. data/typeprof.gemspec +5 -7
  49. metadata +48 -35
  50. data/.github/dependabot.yml +0 -6
  51. data/.github/workflows/main.yml +0 -39
  52. data/.gitignore +0 -9
  53. data/Gemfile +0 -17
  54. data/Gemfile.lock +0 -41
  55. data/Rakefile +0 -10
  56. data/exe/typeprof +0 -10
  57. data/lib/typeprof/analyzer.rb +0 -2598
  58. data/lib/typeprof/arguments.rb +0 -414
  59. data/lib/typeprof/block.rb +0 -176
  60. data/lib/typeprof/builtin.rb +0 -893
  61. data/lib/typeprof/code-range.rb +0 -177
  62. data/lib/typeprof/config.rb +0 -158
  63. data/lib/typeprof/container-type.rb +0 -912
  64. data/lib/typeprof/export.rb +0 -589
  65. data/lib/typeprof/import.rb +0 -852
  66. data/lib/typeprof/insns-def.rb +0 -65
  67. data/lib/typeprof/iseq.rb +0 -864
  68. data/lib/typeprof/method.rb +0 -355
  69. data/lib/typeprof/type.rb +0 -1140
  70. data/lib/typeprof/utils.rb +0 -212
  71. data/tools/coverage.rb +0 -14
  72. data/tools/setup-insns-def.rb +0 -30
  73. data/typeprof-lsp +0 -3
@@ -0,0 +1,319 @@
1
+ module TypeProf::Core
2
+ class AST
3
+ def self.create_part_node(raw_part, lenv)
4
+ case raw_part.type
5
+ when :string_node
6
+ AST.create_node(raw_part, lenv)
7
+ when :embedded_statements_node
8
+ AST.create_node(raw_part.statements, lenv)
9
+ when :embedded_variable_node
10
+ AST.create_node(raw_part.variable, lenv)
11
+ else
12
+ raise "unknown symbol part: #{ raw_part.type }"
13
+ end
14
+ end
15
+
16
+ class SelfNode < Node
17
+ def install0(genv)
18
+ @lenv.get_var(:"*self")
19
+ end
20
+ end
21
+
22
+ class LiteralNode < Node
23
+ def initialize(raw_node, lenv, lit)
24
+ super(raw_node, lenv)
25
+ @lit = lit
26
+ end
27
+
28
+ attr_reader :lit
29
+
30
+ def attrs = { lit: }
31
+
32
+ def install0(genv)
33
+ raise "not supported yet: #{ @lit.inspect }"
34
+ end
35
+ end
36
+
37
+ class NilNode < LiteralNode
38
+ def initialize(raw_node, lenv)
39
+ super(raw_node, lenv, nil)
40
+ end
41
+
42
+ def install0(genv) = Source.new(genv.nil_type)
43
+ end
44
+
45
+ class TrueNode < LiteralNode
46
+ def initialize(raw_node, lenv)
47
+ super(raw_node, lenv, true)
48
+ end
49
+
50
+ def install0(genv) = Source.new(genv.true_type)
51
+ end
52
+
53
+ class FalseNode < LiteralNode
54
+ def initialize(raw_node, lenv)
55
+ super(raw_node, lenv, false)
56
+ end
57
+
58
+ def install0(genv) = Source.new(genv.false_type)
59
+ end
60
+
61
+ class IntegerNode < LiteralNode
62
+ def initialize(raw_node, lenv, lit = raw_node.slice)
63
+ super(raw_node, lenv, Integer(lit))
64
+ end
65
+
66
+ def install0(genv) = Source.new(genv.int_type)
67
+ end
68
+
69
+ class FloatNode < LiteralNode
70
+ def initialize(raw_node, lenv)
71
+ super(raw_node, lenv, Float(raw_node.slice))
72
+ end
73
+
74
+ def install0(genv) = Source.new(genv.float_type)
75
+ end
76
+
77
+ class RationalNode < LiteralNode
78
+ def initialize(raw_node, lenv)
79
+ super(raw_node, lenv, raw_node.slice.to_r)
80
+ end
81
+
82
+ def install0(genv) = Source.new(genv.rational_type)
83
+ end
84
+
85
+ class ComplexNode < LiteralNode
86
+ def initialize(raw_node, lenv)
87
+ super(raw_node, lenv, raw_node.slice.to_c)
88
+ end
89
+
90
+ def install0(genv) = Source.new(genv.complex_type)
91
+ end
92
+
93
+ class SymbolNode < LiteralNode
94
+ def initialize(raw_node, lenv)
95
+ super(raw_node, lenv, raw_node.value.to_sym)
96
+ end
97
+
98
+ def install0(genv) = Source.new(Type::Symbol.new(genv, @lit))
99
+ end
100
+
101
+ class InterpolatedSymbolNode < Node
102
+ def initialize(raw_node, lenv)
103
+ super(raw_node, lenv)
104
+ @parts = raw_node.parts.map do |raw_part|
105
+ AST.create_part_node(raw_part, lenv)
106
+ end
107
+ end
108
+
109
+ attr_reader :parts
110
+
111
+ def subnodes = { parts: }
112
+
113
+ def install0(genv)
114
+ @parts.each do |subnode|
115
+ subnode.install(genv)
116
+ end
117
+ Source.new(genv.symbol_type)
118
+ end
119
+ end
120
+
121
+ class StringNode < LiteralNode
122
+ def initialize(raw_node, lenv, content)
123
+ super(raw_node, lenv, content)
124
+ end
125
+
126
+ def install0(genv) = Source.new(genv.str_type)
127
+ end
128
+
129
+ class InterpolatedStringNode < Node
130
+ def initialize(raw_node, lenv)
131
+ super(raw_node, lenv)
132
+ @parts = []
133
+
134
+ queue = raw_node.parts.dup
135
+
136
+ until queue.empty?
137
+ raw_part = queue.shift
138
+
139
+ if raw_part.type == :interpolated_string_node
140
+ queue.unshift(*raw_part.parts)
141
+ else
142
+ @parts << AST.create_part_node(raw_part, lenv)
143
+ end
144
+ end
145
+ end
146
+
147
+ attr_reader :parts
148
+
149
+ def subnodes = { parts: }
150
+
151
+ def install0(genv)
152
+ @parts.each do |subnode|
153
+ subnode.install(genv)
154
+ end
155
+ Source.new(genv.str_type)
156
+ end
157
+ end
158
+
159
+ class RegexpNode < Node
160
+ def initialize(raw_node, lenv)
161
+ super(raw_node, lenv)
162
+ end
163
+
164
+ def install0(genv) = Source.new(genv.regexp_type)
165
+ end
166
+
167
+ class InterpolatedRegexpNode < Node
168
+ def initialize(raw_node, lenv)
169
+ super(raw_node, lenv)
170
+ @parts = raw_node.parts.map do |raw_part|
171
+ AST.create_part_node(raw_part, lenv)
172
+ end
173
+ end
174
+
175
+ attr_reader :parts
176
+
177
+ def subnodes = { parts: }
178
+
179
+ def install0(genv)
180
+ @parts.each do |subnode|
181
+ subnode.install(genv)
182
+ end
183
+ Source.new(genv.regexp_type)
184
+ end
185
+ end
186
+
187
+ class MatchLastLineNode < Node
188
+ def initialize(raw_node, lenv)
189
+ super(raw_node, lenv)
190
+ end
191
+
192
+ def install0(genv) = Source.new(genv.true_type, genv.false_type)
193
+ end
194
+
195
+ class InterpolatedMatchLastLineNode < Node
196
+ def initialize(raw_node, lenv)
197
+ super(raw_node, lenv)
198
+ @parts = raw_node.parts.map do |raw_part|
199
+ AST.create_part_node(raw_part, lenv)
200
+ end
201
+ end
202
+
203
+ attr_reader :parts
204
+
205
+ def subnodes = { parts: }
206
+
207
+ def install0(genv)
208
+ @parts.each do |subnode|
209
+ subnode.install(genv)
210
+ end
211
+ Source.new(genv.true_type, genv.false_type)
212
+ end
213
+ end
214
+
215
+ class RangeNode < Node
216
+ def initialize(raw_node, lenv)
217
+ super(raw_node, lenv)
218
+ @begin = raw_node.left ? AST.create_node(raw_node.left, lenv) : DummyNilNode.new(raw_node, lenv)
219
+ @end = raw_node.right ? AST.create_node(raw_node.right, lenv) : DummyNilNode.new(raw_node, lenv)
220
+ end
221
+
222
+ attr_reader :begin, :end
223
+
224
+ def subnodes = { begin:, end: }
225
+
226
+ def install0(genv)
227
+ elem = Vertex.new(self)
228
+ @changes.add_edge(genv, @begin.install(genv), elem)
229
+ @changes.add_edge(genv, @end.install(genv), elem)
230
+ Source.new(genv.gen_range_type(elem))
231
+ end
232
+ end
233
+
234
+ class ArrayNode < Node
235
+ def initialize(raw_node, lenv, elems = raw_node.elements)
236
+ super(raw_node, lenv)
237
+ @elems = elems.map {|n| AST.create_node(n, lenv) }
238
+ @splat = @elems.any? {|e| e.is_a?(SplatNode) }
239
+ end
240
+
241
+ attr_reader :elems, :splat
242
+
243
+ def subnodes = { elems: }
244
+ def attrs = { splat: }
245
+
246
+ def install0(genv)
247
+ elems = @elems.map {|e| e.install(genv).new_vertex(genv, self) }
248
+ unified_elem = Vertex.new(self)
249
+ elems.each {|vtx| @changes.add_edge(genv, vtx, unified_elem) }
250
+ base_ty = genv.gen_ary_type(unified_elem)
251
+ if @splat
252
+ Source.new(base_ty)
253
+ else
254
+ Source.new(Type::Array.new(genv, elems, base_ty))
255
+ end
256
+ end
257
+ end
258
+
259
+ class HashNode < Node
260
+ def initialize(raw_node, lenv, keywords)
261
+ super(raw_node, lenv)
262
+ @keys = []
263
+ @vals = []
264
+ @keywords = keywords
265
+ @splat = false
266
+
267
+ raw_node.elements.each do |raw_elem|
268
+ # TODO: Support :assoc_splat_node
269
+ case raw_elem.type
270
+ when :assoc_node
271
+ @keys << AST.create_node(raw_elem.key, lenv)
272
+ @vals << AST.create_node(raw_elem.value, lenv)
273
+ when :assoc_splat_node
274
+ @keys << nil
275
+ @vals << AST.create_node(raw_elem.value, lenv)
276
+ @splat = true
277
+ else
278
+ raise "unknown hash elem: #{ raw_elem.type }"
279
+ end
280
+ end
281
+ end
282
+
283
+ attr_reader :keys, :vals, :splat, :keywords
284
+
285
+ def subnodes = { keys:, vals: }
286
+ def attrs = { splat:, keywords: }
287
+
288
+ def install0(genv)
289
+ unified_key = Vertex.new(self)
290
+ unified_val = Vertex.new(self)
291
+ literal_pairs = {}
292
+ @keys.zip(@vals) do |key, val|
293
+ if key
294
+ k = key.install(genv).new_vertex(genv, self)
295
+ v = val.install(genv).new_vertex(genv, self)
296
+ @changes.add_edge(genv, k, unified_key)
297
+ @changes.add_edge(genv, v, unified_val)
298
+ literal_pairs[key.lit] = v if key.is_a?(SymbolNode)
299
+ else
300
+ h = val.install(genv)
301
+ # TODO: do we want to call to_hash on h?
302
+ @changes.add_hash_splat_box(genv, h, unified_key, unified_val)
303
+ end
304
+ end
305
+ if @splat
306
+ Source.new(genv.gen_hash_type(unified_key, unified_val))
307
+ else
308
+ Source.new(Type::Hash.new(genv, literal_pairs, genv.gen_hash_type(unified_key, unified_val)))
309
+ end
310
+ end
311
+ end
312
+
313
+ class LambdaNode < Node
314
+ def install0(genv)
315
+ Source.new(genv.proc_type)
316
+ end
317
+ end
318
+ end
319
+ end
@@ -0,0 +1,315 @@
1
+ module TypeProf::Core
2
+ class AST
3
+ class LocalVariableReadNode < Node
4
+ def initialize(raw_node, lenv)
5
+ super(raw_node, lenv)
6
+ @var = raw_node.name
7
+ end
8
+
9
+ attr_reader :var
10
+
11
+ def attrs = { var: }
12
+
13
+ def install0(genv)
14
+ @lenv.get_var(@var)
15
+ end
16
+
17
+ def retrieve_at(pos)
18
+ yield self if code_range.include?(pos)
19
+ end
20
+ end
21
+
22
+ class LocalVariableWriteNode < Node
23
+ def initialize(raw_node, rhs, lenv)
24
+ super(raw_node, lenv)
25
+ @var = raw_node.name
26
+ @var_code_range = TypeProf::CodeRange.from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
27
+ @rhs = rhs
28
+ end
29
+
30
+ attr_reader :var, :var_code_range, :rhs
31
+
32
+ def subnodes = { rhs: }
33
+ def attrs = { var: }
34
+
35
+ def install0(genv)
36
+ val = @rhs.install(genv)
37
+
38
+ vtx = @lenv.new_var(@var, self)
39
+ @changes.add_edge(genv, val, vtx)
40
+ val
41
+ end
42
+
43
+ def retrieve_at(pos, &blk)
44
+ yield self if @var_code_range && @var_code_range.include?(pos)
45
+ super(pos, &blk)
46
+ end
47
+
48
+ def modified_vars(tbl, vars)
49
+ vars << self.var if tbl.include?(self.var)
50
+ end
51
+ end
52
+
53
+ class InstanceVariableReadNode < Node
54
+ def initialize(raw_node, lenv)
55
+ super(raw_node, lenv)
56
+ @var = raw_node.name
57
+ end
58
+
59
+ attr_reader :var
60
+
61
+ def attrs = { var: }
62
+
63
+ def install0(genv)
64
+ case @lenv.cref.scope_level
65
+ when :class, :instance
66
+ box = @changes.add_ivar_read_box(genv, lenv.cref.cpath, lenv.cref.scope_level == :class, @var)
67
+ @lenv.apply_read_filter(genv, self, @var, box.ret)
68
+ else
69
+ Source.new()
70
+ end
71
+ end
72
+
73
+ def retrieve_at(pos)
74
+ yield self if code_range.include?(pos)
75
+ end
76
+ end
77
+
78
+ class InstanceVariableWriteNode < Node
79
+ def initialize(raw_node, rhs, lenv)
80
+ super(raw_node, lenv)
81
+ @var = raw_node.name
82
+ @var_code_range = TypeProf::CodeRange.from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
83
+ @rhs = rhs
84
+ end
85
+
86
+ attr_reader :var, :var_code_range, :rhs
87
+
88
+ def subnodes = { rhs: }
89
+ def attrs = { var: }
90
+
91
+ def define0(genv)
92
+ @rhs.define(genv) if @rhs
93
+ case @lenv.cref.scope_level
94
+ when :class, :instance
95
+ val = genv.resolve_ivar(@lenv.cref.cpath, @lenv.cref.scope_level == :class, @var)
96
+ val.add_def(self)
97
+ val
98
+ else
99
+ # TODO: warn
100
+ nil
101
+ end
102
+ end
103
+
104
+ def define_copy(genv)
105
+ case @lenv.cref.scope_level
106
+ when :class, :instance
107
+ val = genv.resolve_ivar(@lenv.cref.cpath, @lenv.cref.scope_level == :class, @var)
108
+ val.add_def(self)
109
+ val.remove_def(@prev_node)
110
+ end
111
+ super(genv)
112
+ end
113
+
114
+ def undefine0(genv)
115
+ case @lenv.cref.scope_level
116
+ when :class, :instance
117
+ val = genv.resolve_ivar(@lenv.cref.cpath, @lenv.cref.scope_level == :class, @var)
118
+ val.remove_def(self)
119
+ end
120
+ @rhs.undefine(genv) if @rhs
121
+ end
122
+
123
+ def install0(genv)
124
+ val = @rhs.install(genv)
125
+ case @lenv.cref.scope_level
126
+ when :class, :instance
127
+ @changes.add_ivar_read_box(genv, @lenv.cref.cpath, @lenv.cref.scope_level == :class, @var)
128
+ val = val.new_vertex(genv, self) # avoid multi-edge from val to static_ret.vtx
129
+ @changes.add_edge(genv, val, @static_ret.vtx)
130
+ end
131
+ val
132
+ end
133
+
134
+ def retrieve_at(pos, &blk)
135
+ yield self if @var_code_range && @var_code_range.include?(pos)
136
+ super(pos, &blk)
137
+ end
138
+ end
139
+
140
+ class GlobalVariableReadNode < Node
141
+ def initialize(raw_node, lenv)
142
+ super(raw_node, lenv)
143
+ @var = raw_node.name
144
+ end
145
+
146
+ attr_reader :var
147
+
148
+ def attrs = { var: }
149
+
150
+ def install0(genv)
151
+ box = @changes.add_gvar_read_box(genv, @var)
152
+ box.ret
153
+ end
154
+
155
+ def retrieve_at(pos)
156
+ yield self if code_range.include?(pos)
157
+ end
158
+ end
159
+
160
+ class GlobalVariableWriteNode < Node
161
+ def initialize(raw_node, rhs, lenv)
162
+ super(raw_node, lenv)
163
+ @var = raw_node.name
164
+ @var_code_range = TypeProf::CodeRange.from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
165
+ @rhs = rhs
166
+ end
167
+
168
+ attr_reader :var, :var_code_range, :rhs
169
+
170
+ def subnodes = { rhs: }
171
+ def attrs = { var: }
172
+
173
+ def define0(genv)
174
+ @rhs.define(genv) if @rhs
175
+ val = genv.resolve_gvar(@var)
176
+ val.add_def(self)
177
+ val
178
+ end
179
+
180
+ def define_copy(genv)
181
+ val = genv.resolve_gvar(@var)
182
+ val.add_def(self)
183
+ val.remove_def(@prev_node)
184
+ super(genv)
185
+ end
186
+
187
+ def undefine0(genv)
188
+ val = genv.resolve_gvar(@var)
189
+ val.remove_def(self)
190
+ @rhs.undefine(genv) if @rhs
191
+ end
192
+
193
+ def install0(genv)
194
+ val = @rhs.install(genv)
195
+ val = val.new_vertex(genv, self) # avoid multi-edge from val to static_ret.vtx
196
+ @changes.add_edge(genv, val, @static_ret.vtx)
197
+ val
198
+ end
199
+
200
+ def retrieve_at(pos, &blk)
201
+ yield self if @var_code_range && @var_code_range.include?(pos)
202
+ super(pos, &blk)
203
+ end
204
+ end
205
+
206
+ class AliasGlobalVariableNode < Node
207
+ def initialize(raw_node, lenv)
208
+ super(raw_node, lenv)
209
+ # XXX: Who use this? I want to hard-code English.rb
210
+ end
211
+
212
+ def install0(genv)
213
+ Source.new(genv.nil_type)
214
+ end
215
+ end
216
+
217
+ class PostExecutionNode < Node
218
+ def initialize(raw_node, lenv)
219
+ super(raw_node, lenv)
220
+ @body = raw_node.statements ? AST.create_node(raw_node.statements, lenv) : DummyNilNode.new(TypeProf::CodeRange.new(code_range.last, code_range.last), lenv)
221
+ end
222
+
223
+ attr_reader :body
224
+
225
+ def subnodes = { body: }
226
+
227
+ def install0(genv)
228
+ @body.install(genv)
229
+ Source.new(genv.nil_type)
230
+ end
231
+ end
232
+
233
+ class ClassVariableWriteNode < Node
234
+ def initialize(raw_node, rhs, lenv)
235
+ super(raw_node, lenv)
236
+ @var = raw_node.name
237
+ @var_code_range = TypeProf::CodeRange.from_node(raw_node.respond_to?(:name_loc) ? raw_node.name_loc : raw_node)
238
+ @rhs = rhs
239
+ end
240
+
241
+ attr_reader :var, :var_code_range, :rhs
242
+
243
+ def subnodes = { rhs: }
244
+ def attrs = { var: }
245
+
246
+ def define0(genv)
247
+ @rhs.define(genv) if @rhs
248
+ mod = genv.resolve_cvar(@lenv.cref.cpath, @var)
249
+ mod.add_def(self)
250
+ mod
251
+ end
252
+
253
+ def define_copy(genv)
254
+ mod = genv.resolve_cvar(@lenv.cref.cpath, @var)
255
+ mod.add_def(self)
256
+ mod.remove_def(@prev_node)
257
+ super(genv)
258
+ end
259
+
260
+ def undefine0(genv)
261
+ mod = genv.resolve_cvar(@lenv.cref.cpath, @var)
262
+ mod.remove_def(self)
263
+ @rhs.undefine(genv) if @rhs
264
+ end
265
+
266
+ def install0(genv)
267
+ @changes.add_cvar_read_box(genv, @lenv.cref.cpath, @var)
268
+ val = @rhs.install(genv)
269
+ val = val.new_vertex(genv, self) # avoid multi-edge from val to static_ret.vtx
270
+ @changes.add_edge(genv, val, @static_ret.vtx)
271
+ val
272
+ end
273
+
274
+ def retrieve_at(pos, &blk)
275
+ yield self if @var_code_range && @var_code_range.include?(pos)
276
+ super(pos, &blk)
277
+ end
278
+ end
279
+
280
+ class ClassVariableReadNode < Node
281
+ def initialize(raw_node, lenv)
282
+ super(raw_node, lenv)
283
+ @var = raw_node.name
284
+ end
285
+
286
+ attr_reader :var
287
+
288
+ def attrs = { var: }
289
+
290
+ def install0(genv)
291
+ box = @changes.add_cvar_read_box(genv, lenv.cref.cpath, @var)
292
+ @lenv.apply_read_filter(genv, self, @var, box.ret)
293
+ end
294
+
295
+ def retrieve_at(pos)
296
+ yield self if code_range.include?(pos)
297
+ end
298
+ end
299
+
300
+ class RegexpReferenceReadNode < Node
301
+ def initialize(raw_node, lenv)
302
+ super(raw_node, lenv)
303
+ @var = raw_node.type == :back_reference_read_node ? :"$&" : :"$#{raw_node.number}"
304
+ end
305
+
306
+ attr_reader :var
307
+
308
+ def attrs = { var: }
309
+
310
+ def install0(genv)
311
+ Source.new(genv.str_type)
312
+ end
313
+ end
314
+ end
315
+ end