Class: Riml::AST_Rewriter::ClassDefinitionToFunctions::SuperToSuperclassFunction

Inherits:
Riml::AST_Rewriter
  • Object
show all
Defined in:
lib/ast_rewriter.rb

Overview

rewrites calls to ‘super’ in non-initialize function

Constant Summary

Constants included from Constants

Constants::BUILTIN_COMMANDS, Constants::BUILTIN_FUNCTIONS, Constants::COMPARISON_OPERATORS, Constants::DEFINE_KEYWORDS, Constants::END_KEYWORDS, Constants::IGNORECASE_CAPABLE_OPERATORS, Constants::KEYWORDS, Constants::REGISTERS, Constants::RIML_COMMANDS, Constants::RIML_END_KEYWORDS, Constants::RIML_KEYWORDS, Constants::SPECIAL_VARIABLE_PREFIXES, Constants::SPLAT_LITERAL, Constants::VIML_COMMANDS, Constants::VIML_END_KEYWORDS, Constants::VIML_KEYWORDS

Instance Attribute Summary

Attributes inherited from Riml::AST_Rewriter

#ast, #classes, #rewritten_included_and_sourced_files

Instance Method Summary collapse

Methods inherited from Riml::AST_Rewriter

#add_SID_function!, #add_SID_function?, #do_establish_parents, #do_rewrite_on_match, #establish_parents, #initialize, #recursive?, #rewrite, #rewrite_included_and_sourced_files!, #rewrite_on_match

Constructor Details

This class inherits a constructor from Riml::AST_Rewriter

Instance Method Details

#add_superclass_func_ref_to_constructor(superclass) ⇒ Object



502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
# File 'lib/ast_rewriter.rb', line 502

def add_superclass_func_ref_to_constructor(superclass)
  super_func_name = superclass_func_name(superclass)
  assign_node = AssignNode.new('=',
    DictGetDotNode.new(
      GetVariableNode.new(nil, ast.constructor_obj_name),
      [super_func_name]
    ),
    CallNode.new(
      nil, 'function', [
        BinaryOperatorNode.new(
          '.',
          [
            BinaryOperatorNode.new(
              '.',
              [
                StringNode.new('<SNR>', :s),
                CallNode.new('s:', 'SID', []),
              ]
            ),
            StringNode.new("_s:#{super_func_name}", :s)
          ],
        )
      ],
    )
  )
  ast.constructor.expressions << assign_node
  reestablish_parents(ast.constructor)
end

#match?(node) ⇒ Boolean

Returns:

  • (Boolean)


463
464
465
466
467
468
469
# File 'lib/ast_rewriter.rb', line 463

def match?(node)
  return false unless SuperNode === node
  n = node
  n = n.parent until DefNode === n || n.nil?
  return false if n.nil? || ast.constructor == n
  @function_node = n
end

#replace(node) ⇒ Object



471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
# File 'lib/ast_rewriter.rb', line 471

def replace(node)
  # TODO: check if class even has superclass before all this
  func_scope = 's:'
  superclass = classes[ast.superclass_full_name]
  while superclass && !superclass.has_function?(func_scope, superclass_func_name(superclass)) && superclass.superclass?
    superclass = classes[superclass.superclass_full_name]
  end
  if superclass.nil? || !superclass.has_function?(func_scope, superclass_func_name(superclass))
    raise Riml::UserFunctionNotFoundError,
      "super was called in class #{ast.full_name} in " \
      "function #{@function_node.original_name}, but there are no " \
      "functions with this name in that class's superclass hierarchy."
  end
  call_node = CallNode.new(
    nil,
    DictGetDotNode.new(
      GetVariableNode.new(nil, 'self'),
      [superclass_func_name(superclass)]
    ),
    node.arguments
  )

  node.replace_with(call_node)
  add_superclass_func_ref_to_constructor(superclass)
  reestablish_parents(@function_node)
end

#superclass_func_name(superclass) ⇒ Object



498
499
500
# File 'lib/ast_rewriter.rb', line 498

def superclass_func_name(superclass)
  "#{superclass.name}_#{@function_node.original_name}"
end