Class: TypeProf::Core::AST

Inherits:
Object
  • Object
show all
Defined in:
lib/typeprof/core/ast.rb,
lib/typeprof/core/ast/base.rb,
lib/typeprof/core/ast/call.rb,
lib/typeprof/core/ast/meta.rb,
lib/typeprof/core/ast/misc.rb,
lib/typeprof/core/ast/const.rb,
lib/typeprof/core/ast/value.rb,
lib/typeprof/core/ast/method.rb,
lib/typeprof/core/ast/module.rb,
lib/typeprof/core/ast/control.rb,
lib/typeprof/core/ast/pattern.rb,
lib/typeprof/core/ast/sig_decl.rb,
lib/typeprof/core/ast/sig_type.rb,
lib/typeprof/core/ast/variable.rb

Defined Under Namespace

Classes: AliasGlobalVariableNode, AliasNode, AltPatternNode, AndNode, ArrayNode, ArrayPatternNode, AttrAccessorMetaNode, AttrReaderMetaNode, BeginNode, BranchNode, BreakNode, CallBaseNode, CallNode, CallReadNode, CallWriteNode, CapturePatternNode, CaseMatchNode, CaseNode, ClassNode, ClassVariableReadNode, ClassVariableWriteNode, ComplexNode, ConstantReadNode, ConstantWriteNode, DefNode, DefinedNode, DummyNilNode, DummyRHSNode, DummySymbolNode, FalseNode, FindPatternNode, FlipFlopNode, FloatNode, ForNode, ForwardingSuperNode, GlobalVariableReadNode, GlobalVariableWriteNode, HashNode, HashPatternNode, IfNode, IfPatternNode, IncludeMetaNode, IndexReadNode, IndexWriteNode, InstanceVariableReadNode, InstanceVariableWriteNode, IntegerNode, InterpolatedMatchLastLineNode, InterpolatedRegexpNode, InterpolatedStringNode, InterpolatedSymbolNode, LambdaNode, LiteralNode, LocalVariableReadNode, LocalVariableWriteNode, LoopNode, MatchLastLineNode, MatchPreidcateNode, MatchRequiredNode, MatchWriteNode, ModuleBaseNode, ModuleNode, MultiWriteNode, NextNode, NilNode, Node, OperatorNode, OrNode, PinnedPatternNode, PostExecutionNode, ProgramNode, RangeNode, RationalNode, RedoNode, RegexpNode, RegexpReferenceReadNode, RescueModifierNode, RetryNode, ReturnNode, SelfNode, SigAliasNode, SigAttrAccessorNode, SigAttrReaderNode, SigAttrWriterNode, SigClassNode, SigConstNode, SigDefNode, SigFuncType, SigGlobalVariableNode, SigIncludeNode, SigInterfaceNode, SigModuleBaseNode, SigModuleNode, SigTyAliasNode, SigTyBaseAnyNode, SigTyBaseBoolNode, SigTyBaseBottomNode, SigTyBaseClassNode, SigTyBaseInstanceNode, SigTyBaseNilNode, SigTyBaseSelfNode, SigTyBaseTopNode, SigTyBaseVoidNode, SigTyInstanceNode, SigTyInterfaceNode, SigTyIntersectionNode, SigTyLiteralNode, SigTyNode, SigTyOptionalNode, SigTyProcNode, SigTyRecordNode, SigTySingletonNode, SigTyTupleNode, SigTyUnionNode, SigTyVarNode, SigTypeAliasNode, SingletonClassNode, SourceEncodingNode, SplatNode, StatementsNode, StringNode, SuperNode, SymbolNode, TrueNode, UndefNode, UnlessNode, UntilNode, WhileNode, YieldNode

Class Method Summary collapse

Class Method Details

.create_node(raw_node, lenv, use_result = true) ⇒ Object

: (untyped, TypeProf::Core::LocalEnv, ?bool) -> TypeProf::Core::AST::Node



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/typeprof/core/ast.rb', line 22

def self.create_node(raw_node, lenv, use_result = true)
  while true
    case raw_node.type
    when :parentheses_node
      raw_node = raw_node.body
    when :implicit_node
      raw_node = raw_node.value
    else
      break
    end
  end

  case raw_node.type

  # definition
  when :statements_node then StatementsNode.new(raw_node, lenv, use_result)
  when :module_node then ModuleNode.new(raw_node, lenv, use_result)
  when :class_node then ClassNode.new(raw_node, lenv, use_result)
  when :singleton_class_node then SingletonClassNode.new(raw_node, lenv, use_result)
  when :def_node then DefNode.new(raw_node, lenv, use_result)
  when :alias_method_node then AliasNode.new(raw_node, lenv)
  when :undef_node then UndefNode.new(raw_node, lenv)

  # control
  when :and_node then AndNode.new(raw_node, lenv)
  when :or_node then OrNode.new(raw_node, lenv)
  when :if_node then IfNode.new(raw_node, lenv)
  when :unless_node then UnlessNode.new(raw_node, lenv)
  when :case_node then CaseNode.new(raw_node, lenv)
  when :case_match_node then CaseMatchNode.new(raw_node, lenv)
  when :while_node then WhileNode.new(raw_node, lenv)
  when :until_node then UntilNode.new(raw_node, lenv)
  when :break_node then BreakNode.new(raw_node, lenv)
  when :next_node then NextNode.new(raw_node, lenv)
  when :redo_node then RedoNode.new(raw_node, lenv)
  when :return_node then ReturnNode.new(raw_node, lenv)
  when :begin_node then BeginNode.new(raw_node, lenv)
  when :retry_node then RetryNode.new(raw_node, lenv)
  when :rescue_modifier_node then RescueModifierNode.new(raw_node, lenv)

  # constants
  when :constant_read_node, :constant_path_node
    ConstantReadNode.new(raw_node, lenv)
  when :constant_write_node, :constant_path_write_node
    ConstantWriteNode.new(raw_node, AST.create_node(raw_node.value, lenv), lenv)
  when :constant_operator_write_node
    read = ConstantReadNode.new(raw_node, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
    ConstantWriteNode.new(raw_node, rhs, lenv)
  when :constant_or_write_node
    read = ConstantReadNode.new(raw_node, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    ConstantWriteNode.new(raw_node, rhs, lenv)
  when :constant_and_write_node
    read = ConstantReadNode.new(raw_node, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    ConstantWriteNode.new(raw_node, rhs, lenv)
  when :constant_path_operator_write_node
    read = ConstantReadNode.new(raw_node.target, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
    ConstantWriteNode.new(raw_node, rhs, lenv)
  when :constant_path_or_write_node
    read = ConstantReadNode.new(raw_node.target, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    ConstantWriteNode.new(raw_node, rhs, lenv)
  when :constant_path_and_write_node
    read = ConstantReadNode.new(raw_node.target, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    ConstantWriteNode.new(raw_node, rhs, lenv)

  # variables
  when :local_variable_read_node
    LocalVariableReadNode.new(raw_node, lenv)
  when :local_variable_write_node
    LocalVariableWriteNode.new(raw_node, AST.create_node(raw_node.value, lenv), lenv)
  when :local_variable_operator_write_node
    read = LocalVariableReadNode.new(raw_node, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
    LocalVariableWriteNode.new(raw_node, rhs, lenv)
  when :local_variable_or_write_node
    read = LocalVariableReadNode.new(raw_node, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    LocalVariableWriteNode.new(raw_node, rhs, lenv)
  when :local_variable_and_write_node
    read = LocalVariableReadNode.new(raw_node, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    LocalVariableWriteNode.new(raw_node, rhs, lenv)
  when :instance_variable_read_node
    InstanceVariableReadNode.new(raw_node, lenv)
  when :instance_variable_write_node
    InstanceVariableWriteNode.new(raw_node, AST.create_node(raw_node.value, lenv), lenv)
  when :instance_variable_operator_write_node
    read = InstanceVariableReadNode.new(raw_node, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
    InstanceVariableWriteNode.new(raw_node, rhs, lenv)
  when :instance_variable_or_write_node
    read = InstanceVariableReadNode.new(raw_node, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    InstanceVariableWriteNode.new(raw_node, rhs, lenv)
  when :instance_variable_and_write_node
    read = InstanceVariableReadNode.new(raw_node, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    InstanceVariableWriteNode.new(raw_node, rhs, lenv)
  when :class_variable_read_node
    ClassVariableReadNode.new(raw_node, lenv)
  when :class_variable_write_node
    ClassVariableWriteNode.new(raw_node, AST.create_node(raw_node.value, lenv), lenv)
  when :class_variable_operator_write_node
    read = ClassVariableReadNode.new(raw_node, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
  when :class_variable_or_write_node
    read = ClassVariableReadNode.new(raw_node, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    ClassVariableWriteNode.new(raw_node, rhs, lenv)
  when :class_variable_and_write_node
    read = ClassVariableReadNode.new(raw_node, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    ClassVariableWriteNode.new(raw_node, rhs, lenv)
  when :global_variable_read_node
    GlobalVariableReadNode.new(raw_node, lenv)
  when :global_variable_write_node
    GlobalVariableWriteNode.new(raw_node, AST.create_node(raw_node.value, lenv), lenv)
  when :global_variable_operator_write_node
    read = GlobalVariableReadNode.new(raw_node, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
    GlobalVariableWriteNode.new(raw_node, rhs, lenv)
  when :global_variable_or_write_node
    read = GlobalVariableReadNode.new(raw_node, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    GlobalVariableWriteNode.new(raw_node, rhs, lenv)
  when :global_variable_and_write_node
    read = GlobalVariableReadNode.new(raw_node, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    GlobalVariableWriteNode.new(raw_node, rhs, lenv)
  when :numbered_reference_read_node
    RegexpReferenceReadNode.new(raw_node, lenv)
  when :back_reference_read_node
    RegexpReferenceReadNode.new(raw_node, lenv)

  # assignment targets
  when :index_operator_write_node
    read = IndexReadNode.new(raw_node, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
    IndexWriteNode.new(raw_node, rhs, lenv)
  when :index_or_write_node
    read = IndexReadNode.new(raw_node, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    IndexWriteNode.new(raw_node, rhs, lenv)
  when :index_and_write_node
    read = IndexReadNode.new(raw_node, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    IndexWriteNode.new(raw_node, rhs, lenv)
  when :call_operator_write_node
    read = CallReadNode.new(raw_node, lenv)
    rhs = OperatorNode.new(raw_node, read, lenv)
    CallWriteNode.new(raw_node, rhs, lenv)
  when :call_or_write_node
    read = CallReadNode.new(raw_node, lenv)
    rhs = OrNode.new(raw_node, read, raw_node.value, lenv)
    CallWriteNode.new(raw_node, rhs, lenv)
  when :call_and_write_node
    read = CallReadNode.new(raw_node, lenv)
    rhs = AndNode.new(raw_node, read, raw_node.value, lenv)
    CallWriteNode.new(raw_node, rhs, lenv)
  when :multi_write_node then MultiWriteNode.new(raw_node, lenv)
  when :match_write_node then MatchWriteNode.new(raw_node, lenv)

  # value
  when :self_node then SelfNode.new(raw_node, lenv)
  when :nil_node then NilNode.new(raw_node, lenv)
  when :true_node then TrueNode.new(raw_node, lenv)
  when :false_node then FalseNode.new(raw_node, lenv)
  when :integer_node then IntegerNode.new(raw_node, lenv)
  when :float_node then FloatNode.new(raw_node, lenv)
  when :rational_node then RationalNode.new(raw_node, lenv)
  when :imaginary_node then ComplexNode.new(raw_node, lenv)
  when :source_file_node then StringNode.new(raw_node, lenv, "")
  when :source_line_node then IntegerNode.new(raw_node, lenv, 0)
  when :source_encoding_node then SourceEncodingNode.new(raw_node, lenv)
  when :symbol_node then SymbolNode.new(raw_node, lenv)
  when :interpolated_symbol_node then InterpolatedSymbolNode.new(raw_node, lenv)
  when :string_node then StringNode.new(raw_node, lenv, raw_node.content)
  when :interpolated_string_node then InterpolatedStringNode.new(raw_node, lenv)
  when :x_string_node then StringNode.new(raw_node, lenv, "")
  when :interpolated_x_string_node then InterpolatedStringNode.new(raw_node, lenv)
  when :regular_expression_node then RegexpNode.new(raw_node, lenv)
  when :interpolated_regular_expression_node then InterpolatedRegexpNode.new(raw_node, lenv)
  when :match_last_line_node then MatchLastLineNode.new(raw_node, lenv)
  when :interpolated_match_last_line_node then InterpolatedMatchLastLineNode.new(raw_node, lenv)
  when :range_node then RangeNode.new(raw_node, lenv)
  when :array_node then ArrayNode.new(raw_node, lenv)
  when :hash_node then HashNode.new(raw_node, lenv, false)
  when :keyword_hash_node then HashNode.new(raw_node, lenv, true)
  when :lambda_node then LambdaNode.new(raw_node, lenv)

  # misc
  when :defined_node then DefinedNode.new(raw_node, lenv)
  when :splat_node then SplatNode.new(raw_node, lenv)
  when :for_node then ForNode.new(raw_node, lenv)
  when :alias_global_variable_node then AliasGlobalVariableNode.new(raw_node, lenv)
  when :post_execution_node then PostExecutionNode.new(raw_node, lenv)
  when :flip_flop_node then FlipFlopNode.new(raw_node, lenv)
  when :shareable_constant_node then create_node(raw_node.write, lenv)
  when :match_required_node then MatchRequiredNode.new(raw_node, lenv)
  when :match_predicate_node then MatchPreidcateNode.new(raw_node, lenv)

  # call
  when :super_node then SuperNode.new(raw_node, lenv)
  when :forwarding_super_node then ForwardingSuperNode.new(raw_node, lenv)
  when :yield_node then YieldNode.new(raw_node, lenv)
  when :call_node
    if !raw_node.receiver
      # TODO: handle them only when it is directly under class or module
      case raw_node.name
      when :include
        return IncludeMetaNode.new(raw_node, lenv)
      when :attr_reader
        return AttrReaderMetaNode.new(raw_node, lenv)
      when :attr_accessor
        return AttrAccessorMetaNode.new(raw_node, lenv)
      end
    end
    CallNode.new(raw_node, lenv)
  else
    pp raw_node
    raise "not supported yet: #{ raw_node.type }"
  end
end

.create_part_node(raw_part, lenv) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
# File 'lib/typeprof/core/ast/value.rb', line 3

def self.create_part_node(raw_part, lenv)
  case raw_part.type
  when :string_node
    AST.create_node(raw_part, lenv)
  when :embedded_statements_node
    raw_part.statements ? AST.create_node(raw_part.statements, lenv) : DummyNilNode.new(TypeProf::CodeRange.from_node(raw_part), lenv)
  when :embedded_variable_node
    AST.create_node(raw_part.variable, lenv)
  else
    raise "unknown symbol part: #{ raw_part.type }"
  end
end

.create_pattern_node(raw_node, lenv) ⇒ Object



276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/typeprof/core/ast.rb', line 276

def self.create_pattern_node(raw_node, lenv)
  while true
    case raw_node.type
    when :parentheses_node
      raw_node = raw_node.body
    when :implicit_node
      raw_node = raw_node.value
    else
      break
    end
  end

  case raw_node.type
  when :array_pattern_node then ArrayPatternNode.new(raw_node, lenv)
  when :hash_pattern_node then HashPatternNode.new(raw_node, lenv)
  when :find_pattern_node then FindPatternNode.new(raw_node, lenv)

  when :alternation_pattern_node then AltPatternNode.new(raw_node, lenv)

  when :capture_pattern_node then CapturePatternNode.new(raw_node, lenv)

  when :if_node then IfPatternNode.new(raw_node, lenv)

  when :pinned_variable_node then PinnedPatternNode.new(raw_node, lenv)
  when :pinned_expression_node then PinnedPatternNode.new(raw_node, lenv)

  when :local_variable_target_node
    dummy_node = DummyRHSNode.new(TypeProf::CodeRange.from_node(raw_node.location), lenv)
    LocalVariableWriteNode.new(raw_node, dummy_node, lenv)

  when :constant_read_node, :constant_path_node
    ConstantReadNode.new(raw_node, lenv)

  when :self_node then SelfNode.new(raw_node, lenv)
  when :nil_node then NilNode.new(raw_node, lenv)
  when :true_node then TrueNode.new(raw_node, lenv)
  when :false_node then FalseNode.new(raw_node, lenv)
  when :integer_node then IntegerNode.new(raw_node, lenv)
  when :float_node then FloatNode.new(raw_node, lenv)
  when :rational_node then RationalNode.new(raw_node, lenv)
  when :imaginary_node then ComplexNode.new(raw_node, lenv)
  when :source_file_node then StringNode.new(raw_node, lenv, "")
  when :source_line_node then IntegerNode.new(raw_node, lenv, 0)
  when :source_encoding_node then SourceEncodingNode.new(raw_node, lenv)
  when :symbol_node then SymbolNode.new(raw_node, lenv)
  when :interpolated_symbol_node then InterpolatedSymbolNode.new(raw_node, lenv)
  when :string_node then StringNode.new(raw_node, lenv, raw_node.content)
  when :interpolated_string_node then InterpolatedStringNode.new(raw_node, lenv)
  when :x_string_node then StringNode.new(raw_node, lenv, "")
  when :interpolated_x_string_node then InterpolatedStringNode.new(raw_node, lenv)
  when :regular_expression_node then RegexpNode.new(raw_node, lenv)
  when :interpolated_regular_expression_node then InterpolatedRegexpNode.new(raw_node, lenv)

  when :array_node then ArrayNode.new(raw_node, lenv) # for %w[foo bar]
  when :range_node then RangeNode.new(raw_node, lenv) # TODO: support range pattern correctly

  else
    raise "unknown pattern node type: #{ raw_node.type }"
  end
end

.create_rbs_decl(raw_decl, lenv) ⇒ Object



373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/typeprof/core/ast.rb', line 373

def self.create_rbs_decl(raw_decl, lenv)
  case raw_decl
  when RBS::AST::Declarations::Class
    SigClassNode.new(raw_decl, lenv)
  when RBS::AST::Declarations::Module
    SigModuleNode.new(raw_decl, lenv)
  when RBS::AST::Declarations::Interface
    SigInterfaceNode.new(raw_decl, lenv)
  when RBS::AST::Declarations::Constant
    SigConstNode.new(raw_decl, lenv)
  when RBS::AST::Declarations::AliasDecl
  when RBS::AST::Declarations::TypeAlias
    SigTypeAliasNode.new(raw_decl, lenv)
    # TODO: check
  when RBS::AST::Declarations::Global
    SigGlobalVariableNode.new(raw_decl, lenv)
  else
    raise "unsupported: #{ raw_decl.class }"
  end
end

.create_rbs_func_type(raw_decl, raw_type_params, raw_block, lenv) ⇒ Object



418
419
420
# File 'lib/typeprof/core/ast.rb', line 418

def self.create_rbs_func_type(raw_decl, raw_type_params, raw_block, lenv)
  SigFuncType.new(raw_decl, raw_type_params, raw_block, lenv)
end

.create_rbs_member(raw_decl, lenv) ⇒ Object



394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/typeprof/core/ast.rb', line 394

def self.create_rbs_member(raw_decl, lenv)
  case raw_decl
  when RBS::AST::Members::MethodDefinition
    SigDefNode.new(raw_decl, lenv)
  when RBS::AST::Members::Include
    SigIncludeNode.new(raw_decl, lenv)
  when RBS::AST::Members::Extend
  when RBS::AST::Members::Public
  when RBS::AST::Members::Private
  when RBS::AST::Members::Alias
    SigAliasNode.new(raw_decl, lenv)
  when RBS::AST::Members::AttrReader
    SigAttrReaderNode.new(raw_decl, lenv)
  when RBS::AST::Members::AttrWriter
    SigAttrWriterNode.new(raw_decl, lenv)
  when RBS::AST::Members::AttrAccessor
    SigAttrAccessorNode.new(raw_decl, lenv)
  when RBS::AST::Declarations::Base
    self.create_rbs_decl(raw_decl, lenv)
  else
    raise "unsupported: #{ raw_decl.class }"
  end
end

.create_rbs_type(raw_decl, lenv) ⇒ Object



422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/typeprof/core/ast.rb', line 422

def self.create_rbs_type(raw_decl, lenv)
  case raw_decl
  when RBS::Types::Bases::Nil
    SigTyBaseNilNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Bool
    SigTyBaseBoolNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Self
    SigTyBaseSelfNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Void
    SigTyBaseVoidNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Any
    SigTyBaseAnyNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Top
    SigTyBaseTopNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Bottom
    SigTyBaseBottomNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Instance
    SigTyBaseInstanceNode.new(raw_decl, lenv)
  when RBS::Types::Bases::Class
    SigTyBaseClassNode.new(raw_decl, lenv)

  when RBS::Types::Alias
    SigTyAliasNode.new(raw_decl, lenv)
  when RBS::Types::Union
    SigTyUnionNode.new(raw_decl, lenv)
  when RBS::Types::Intersection
    SigTyIntersectionNode.new(raw_decl, lenv)
  when RBS::Types::ClassSingleton
    SigTySingletonNode.new(raw_decl, lenv)
  when RBS::Types::ClassInstance
    SigTyInstanceNode.new(raw_decl, lenv)
  when RBS::Types::Tuple
    SigTyTupleNode.new(raw_decl, lenv)
  when RBS::Types::Record
    SigTyRecordNode.new(raw_decl, lenv)
  when RBS::Types::Interface
    SigTyInterfaceNode.new(raw_decl, lenv)
  when RBS::Types::Proc
    SigTyProcNode.new(raw_decl, lenv)
  when RBS::Types::Variable
    SigTyVarNode.new(raw_decl, lenv)
  when RBS::Types::Optional
    SigTyOptionalNode.new(raw_decl, lenv)
  when RBS::Types::Literal
    SigTyLiteralNode.new(raw_decl, lenv)
  else
    raise "unknown RBS type: #{ raw_decl.class }"
  end
end

.create_target_node(raw_node, lenv) ⇒ Object



251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/typeprof/core/ast.rb', line 251

def self.create_target_node(raw_node, lenv)
  dummy_node = DummyRHSNode.new(TypeProf::CodeRange.from_node(raw_node.location), lenv)
  case raw_node.type
  when :local_variable_target_node
    LocalVariableWriteNode.new(raw_node, dummy_node, lenv)
  when :instance_variable_target_node
    InstanceVariableWriteNode.new(raw_node, dummy_node, lenv)
  when :class_variable_target_node
    ClassVariableWriteNode.new(raw_node, dummy_node, lenv)
  when :global_variable_target_node
    GlobalVariableWriteNode.new(raw_node, dummy_node, lenv)
  when :constant_target_node
    ConstantWriteNode.new(raw_node, dummy_node, lenv)
  when :constant_path_target_node
    ConstantWriteNode.new(raw_node, dummy_node, lenv)
  when :index_target_node
    IndexWriteNode.new(raw_node, dummy_node, lenv)
  when :call_target_node
    CallWriteNode.new(raw_node, dummy_node, lenv)
  else
    pp raw_node
    raise "not supported yet: #{ raw_node.type }"
  end
end

.get_rbs_comment_before(raw_node, lenv) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/typeprof/core/ast/method.rb', line 3

def self.get_rbs_comment_before(raw_node, lenv)
  comments = Fiber[:comments]
  i = comments.bsearch_index {|comment| comment.location.start_line >= raw_node.location.start_line } || comments.size
  lineno = raw_node.location.start_line
  rbs_comments = []
  while i > 0
    i -= 1
    lineno -= 1
    comment = comments[i]
    comment_loc = comment.location
    comment_text = comment_loc.slice
    if comment_loc.start_line == lineno && comment_text.start_with?("#:")
      rbs_comments[comment_loc.start_line] = " " * (comment_loc.start_column + 2) + comment_text[2..]
    else
      break
    end
  end
  return nil if rbs_comments.empty?
  rbs_comments = rbs_comments.map {|line| line || "" }.join("\n")
  method_type = RBS::Parser.parse_method_type(rbs_comments)
  if method_type
    AST.create_rbs_func_type(method_type, method_type.type_params, method_type.block, lenv)
  else
    nil
  end
rescue RBS::ParsingError
  # TODO: report the error
  nil
end

.is_a_class(node) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
# File 'lib/typeprof/core/ast/control.rb', line 3

def self.is_a_class(node)
  if node.is_a?(CallNode)
    recv = node.recv
    if recv.is_a?(LocalVariableReadNode)
      if node.positional_args && node.positional_args.size == 1 && node.positional_args[0].static_ret
        # TODO: need static resolusion of a constant
        return [recv.var, node.positional_args[0].static_ret]
      end
    end
  end
  return nil
end

.parse_cpath(raw_node, cref) ⇒ Object



337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/typeprof/core/ast.rb', line 337

def self.parse_cpath(raw_node, cref)
  names = []
  while raw_node
    case raw_node.type
    when :constant_read_node
      names << raw_node.name
      break
    when :constant_path_node, :constant_path_target_node
      if raw_node.parent
        # temporarily support old Prism https://bugs.ruby-lang.org/issues/20467
        names << (raw_node.respond_to?(:name) ? raw_node.name : raw_node.child.name)
        raw_node = raw_node.parent
      else
        return names.reverse
      end
    when :self_node
      break if cref.scope_level == :class
      return nil
    else
      return nil
    end
  end
  return cref.cpath + names.reverse
end

.parse_params(tbl, raw_args, lenv) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/typeprof/core/ast/method.rb', line 33

def self.parse_params(tbl, raw_args, lenv)
  unless raw_args
    return {
      req_positionals: [],
      opt_positionals: [],
      opt_positional_defaults: [],
      rest_positionals: nil,
      post_positionals: [],
      req_keywords: [],
      opt_keywords: [],
      opt_keyword_defaults: [],
      rest_keywords: nil,
      block: nil,
    }
  end

  args_code_ranges = []
  req_positionals = []
  raw_args.requireds.each do |n|
    args_code_ranges << TypeProf::CodeRange.from_node(n.location)
    req_positionals << (n.is_a?(Prism::MultiTargetNode) ? nil : n.name)
  end

  # pre_init = args[1]

  opt_positionals = []
  opt_positional_defaults = []
  raw_args.optionals.each do |n|
    opt_positionals << n.name
    opt_positional_defaults << AST.create_node(n.value, lenv)
  end

  post_positionals = raw_args.posts.map {|n| (n.is_a?(Prism::MultiTargetNode) ? nil : n.name) }

  rest_positionals = raw_args.rest&.name

  req_keywords = []
  opt_keywords = []
  opt_keyword_defaults = []

  raw_args.keywords.each do |kw|
    case kw.type
    when :required_keyword_parameter_node
      req_keywords << kw.name
    when :optional_keyword_parameter_node
      opt_keywords << kw.name
      opt_keyword_defaults << AST.create_node(kw.value, lenv)
    end
  end

  case raw_args.keyword_rest
  when Prism::KeywordRestParameterNode
    rest_keywords = raw_args.keyword_rest.name if raw_args.keyword_rest
  when Prism::NoKeywordsParameterNode
    # what to do?
  when nil
    # nothing to do
  else
    raise "unexpected keyword rest: #{ raw_args.keyword_rest.class }"
  end

  block = raw_args.block.name if raw_args.block

  {
    req_positionals:,
    opt_positionals:,
    opt_positional_defaults:,
    rest_positionals:,
    post_positionals:,
    req_keywords:,
    opt_keywords:,
    opt_keyword_defaults:,
    rest_keywords:,
    block:,
    args_code_ranges:
  }
end

.parse_rb(path, src) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/typeprof/core/ast.rb', line 3

def self.parse_rb(path, src)
  result = Prism.parse(src)

  return nil unless result.errors.empty?

  # comments, errors, magic_comments
  raw_scope = result.value

  raise unless raw_scope.type == :program_node

  Fiber[:comments] = result.comments

  cref = CRef::Toplevel
  lenv = LocalEnv.new(path, cref, {}, [])

  ProgramNode.new(raw_scope, lenv)
end

.parse_rbs(path, src) ⇒ Object



362
363
364
365
366
367
368
369
370
371
# File 'lib/typeprof/core/ast.rb', line 362

def self.parse_rbs(path, src)
  _buffer, _directives, raw_decls = RBS::Parser.parse_signature(src)

  cref = CRef::Toplevel
  lenv = LocalEnv.new(path, cref, {}, [])

  raw_decls.map do |raw_decl|
    AST.create_rbs_decl(raw_decl, lenv)
  end
end

.parse_return_arguments(raw_node, lenv, code_range) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/typeprof/core/ast/control.rb', line 193

def self.parse_return_arguments(raw_node, lenv, code_range)
  if raw_node.arguments
    elems = raw_node.arguments.arguments
    if elems.one?
      AST.create_node(elems.first, lenv)
    else
      ArrayNode.new(raw_node.arguments, lenv, elems)
    end
  else
    DummyNilNode.new(code_range, lenv)
  end
end

.resolve_rbs_name(name, lenv) ⇒ Object



3
4
5
6
7
8
9
# File 'lib/typeprof/core/ast/sig_decl.rb', line 3

def self.resolve_rbs_name(name, lenv)
  if name.namespace.absolute?
    name.namespace.path + [name.name]
  else
    lenv.cref.cpath + name.namespace.path + [name.name]
  end
end