private void rewriteDefinition ( Node definitionSite , String newMethodName ) { final Node function ; final Node subtreeToRemove ; final Node nameSource ; switch ( definitionSite . getToken ( ) ) { case GETPROP : function = definitionSite . getParent ( ) . getLastChild ( ) ; nameSource = definitionSite . getLastChild ( ) ; subtreeToRemove = NodeUtil . getEnclosingStatement ( definitionSite ) ; break ; case STRING_KEY : case MEMBER_FUNCTION_DEF : function = definitionSite . getLastChild ( ) ; nameSource = definitionSite ; subtreeToRemove = definitionSite ; break ; default : throw new IllegalArgumentException ( definitionSite . toString ( ) ) ; } // Define a new variable after the original declaration. Node statement = NodeUtil . getEnclosingStatement ( definitionSite ) ; Node newNameNode = IR . name ( newMethodName ) . useSourceInfoIfMissingFrom ( nameSource ) ; Node newVarNode = IR . var ( newNameNode ) . useSourceInfoIfMissingFrom ( nameSource ) ; statement . getParent ( ) . addChildBefore ( newVarNode , statement ) ; // Attatch the function to the new variable. function . detach ( ) ; newNameNode . addChildToFront ( function ) ; // Create the `this` param. String selfName = newMethodName + "$self" ; Node paramList = function . getSecondChild ( ) ; paramList . addChildToFront ( IR . name ( selfName ) . useSourceInfoIfMissingFrom ( function ) ) ; compiler . reportChangeToEnclosingScope ( paramList ) ; // Eliminate `this`. replaceReferencesToThis ( function . getSecondChild ( ) , selfName ) ; // In default param values. replaceReferencesToThis ( function . getLastChild ( ) , selfName ) ; // In function body. fixFunctionType ( function ) ; // Clean up dangling AST. NodeUtil . deleteNode ( subtreeToRemove , compiler ) ; compiler . reportChangeToEnclosingScope ( newVarNode ) ; }
Rewrites method definitions as global functions that take this as their first argument .