private Node aliasAndInlineArguments ( Node fnTemplateRoot , ImmutableMap < String , Node > argMap , Set < String > namesToAlias ) { if ( namesToAlias == null || namesToAlias . isEmpty ( ) ) { // There are no names to alias, just inline the arguments directly. Node result = FunctionArgumentInjector . inject ( compiler , fnTemplateRoot , null , argMap ) ; checkState ( result == fnTemplateRoot ) ; return result ; } else { // Create local alias of names that can not be safely // used directly. // An arg map that will be updated to contain the // safe aliases. Map < String , Node > newArgMap = new HashMap <> ( argMap ) ; // Declare the alias in the same order as they // are declared. List < Node > newVars = new ArrayList <> ( ) ; // NOTE: argMap is a linked map so we get the parameters in the // order that they were declared. for ( Entry < String , Node > entry : argMap . entrySet ( ) ) { String name = entry . getKey ( ) ; if ( namesToAlias . contains ( name ) ) { if ( name . equals ( THIS_MARKER ) ) { boolean referencesThis = NodeUtil . referencesThis ( fnTemplateRoot ) ; // Update "this", this is only necessary if "this" is referenced // and the value of "this" is not Token.THIS, or the value of "this" // has side effects. Node value = entry . getValue ( ) ; if ( ! value . isThis ( ) && ( referencesThis || NodeUtil . mayHaveSideEffects ( value , compiler ) ) ) { String newName = getUniqueThisName ( ) ; Node newValue = entry . getValue ( ) . cloneTree ( ) ; Node newNode = NodeUtil . newVarNode ( newName , newValue ) . useSourceInfoIfMissingFromForTree ( newValue ) ; newVars . add ( 0 , newNode ) ; // Remove the parameter from the list to replace. newArgMap . put ( THIS_MARKER , IR . name ( newName ) . srcrefTree ( newValue ) ) ; } } else { Node newValue = entry . getValue ( ) . cloneTree ( ) ; Node newNode = NodeUtil . newVarNode ( name , newValue ) . useSourceInfoIfMissingFromForTree ( newValue ) ; newVars . add ( 0 , newNode ) ; // Remove the parameter from the list to replace. newArgMap . remove ( name ) ; } } } // Inline the arguments. Node result = FunctionArgumentInjector . inject ( compiler , fnTemplateRoot , null , newArgMap ) ; checkState ( result == fnTemplateRoot ) ; // Now that the names have been replaced, add the new aliases for // the old names. for ( Node n : newVars ) { fnTemplateRoot . addChildToFront ( n ) ; } return result ; } }
Inlines the arguments within the node tree using the given argument map replaces unsafe names with local aliases .