Class: Riml::AST_Rewriter::ClassDefinitionToFunctions::SuperToSuperclassFunction
- Inherits:
-
Riml::AST_Rewriter
- Object
- Riml::AST_Rewriter
- Riml::AST_Rewriter::ClassDefinitionToFunctions::SuperToSuperclassFunction
- Defined in:
- lib/riml/ast_rewriter.rb
Overview
rewrites calls to ‘super’ in public/private non-initialize functions
Constant Summary
Constants included from Constants
Constants::BUILTIN_COMMANDS, Constants::BUILTIN_FUNCTIONS, Constants::COMPARISON_OPERATORS, Constants::COMPILED_STRING_LOCATION, Constants::DEFINE_KEYWORDS, Constants::END_KEYWORDS, Constants::IGNORECASE_CAPABLE_OPERATORS, Constants::KEYWORDS, Constants::REGISTERS, Constants::RIML_CLASS_COMMANDS, Constants::RIML_COMMANDS, Constants::RIML_END_KEYWORDS, Constants::RIML_FILE_COMMANDS, Constants::RIML_KEYWORDS, Constants::SPECIAL_VARIABLE_PREFIXES, Constants::SPLAT_LITERAL, Constants::UNKNOWN_LOCATION_INFO, Constants::VIML_COMMANDS, Constants::VIML_END_KEYWORDS, Constants::VIML_KEYWORDS
Instance Attribute Summary
Attributes inherited from Riml::AST_Rewriter
Instance Method Summary collapse
- #add_superclass_func_ref_to_constructor(superclass) ⇒ Object
- #match?(node) ⇒ Boolean
- #replace(node) ⇒ Object
- #superclass_func_name(superclass) ⇒ Object
Methods inherited from Riml::AST_Rewriter
#add_SID_function!, #add_SID_function?, #do_establish_parents, #do_rewrite_on_match, #establish_parents, #initialize, #max_recursion_lvl, #reorder_includes_based_on_class_dependencies!, #resolve_class_dependencies!, #resolve_class_dependencies?, #rewrite, #rewrite_included_and_sourced_files!, #rewrite_on_match, #watch_for_class_pickup
Constructor Details
This class inherits a constructor from Riml::AST_Rewriter
Instance Method Details
#add_superclass_func_ref_to_constructor(superclass) ⇒ Object
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 |
# File 'lib/riml/ast_rewriter.rb', line 790 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
722 723 724 725 726 727 728 |
# File 'lib/riml/ast_rewriter.rb', line 722 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
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 |
# File 'lib/riml/ast_rewriter.rb', line 730 def replace(node) 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 superclass_function = superclass.find_function(func_scope, superclass_func_name(superclass)) if superclass.nil? || !superclass_function error_msg = "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." error = Riml::InvalidSuper.new(error_msg, node) raise error end node_args = if node.arguments.empty? && !node.with_parens && superclass_function.splat [SplatNode.new(GetVariableNode.new('a:', '000'))] else if @function_node.private_function? node.arguments.unshift GetVariableNode.new(nil, @function_node.parameters.first) end node.arguments end # check if SplatNode is in node_args. If it is, check if the splat # value is equal to splat param. If it is, and we're inside a # private function, we have to add the explicit object (first # parameter to the function we're in) to the splat arg if @function_node.private_function? if (splat_node = node_args.detect { |arg| SplatNode === arg }) self_var = GetVariableNode.new('a:', @function_node.parameters.first) splat_node.expression = BinaryOperatorNode.new('+', [ListNode.wrap(self_var), splat_node.expression]) establish_parents(splat_node.expression) end # call s:ClassA_private_func(args) call_node_name = superclass_func_name(superclass) else # call self.ClassA_public_func(args) call_node_name = DictGetDotNode.new( GetVariableNode.new(nil, 'self'), [superclass_func_name(superclass)] ) end call_node = CallNode.new( nil, call_node_name, node_args ) call_node.super_call = true node.replace_with(call_node) # private functions are NOT extended in constructor function unless @function_node.private_function? add_superclass_func_ref_to_constructor(superclass) end reestablish_parents(@function_node) end |
#superclass_func_name(superclass) ⇒ Object
786 787 788 |
# File 'lib/riml/ast_rewriter.rb', line 786 def superclass_func_name(superclass) "#{superclass.name}_#{@function_node.original_name}" end |