private boolean partiallyInlineAlias ( Ref alias , GlobalNamespace namespace , ReferenceCollection aliasRefs , Node aliasLhsNode ) { BasicBlock aliasBlock = null ; // This initial iteration through all the alias references does two things: // a) Find the control flow block in which the alias is assigned. // b) See if the alias var is assigned to in multiple places, and return if that's the case. // NOTE: we still may inline if the alias is assigned in a loop or inner function and that // assignment statement is potentially executed multiple times. // This is more aggressive than what "inlineAliasIfPossible" does. for ( Reference aliasRef : aliasRefs ) { Node aliasRefNode = aliasRef . getNode ( ) ; if ( aliasRefNode == aliasLhsNode ) { aliasBlock = aliasRef . getBasicBlock ( ) ; continue ; } else if ( aliasRef . isLvalue ( ) ) { // Don't replace any references if the alias is reassigned return false ; } } Set < AstChange > newNodes = new LinkedHashSet <> ( ) ; boolean alreadySeenInitialAlias = false ; boolean foundNonReplaceableAlias = false ; // Do a second iteration through all the alias references, and replace any inlinable references. for ( Reference aliasRef : aliasRefs ) { Node aliasRefNode = aliasRef . getNode ( ) ; if ( aliasRefNode == aliasLhsNode ) { alreadySeenInitialAlias = true ; continue ; } else if ( aliasRef . isDeclaration ( ) ) { // Ignore any alias declarations, e.g. "var alias;", since there's nothing to inline. continue ; } BasicBlock refBlock = aliasRef . getBasicBlock ( ) ; if ( ( refBlock != aliasBlock && aliasBlock . provablyExecutesBefore ( refBlock ) ) || ( refBlock == aliasBlock && alreadySeenInitialAlias ) ) { // We replace the alias only if the alias and reference are in the same BasicBlock, // the aliasing assignment takes place before the reference, and the alias is // never reassigned. codeChanged = true ; newNodes . add ( replaceAliasReference ( alias , aliasRef ) ) ; } else { foundNonReplaceableAlias = true ; } } // We removed all references to the alias, so remove the original aliasing assignment. if ( ! foundNonReplaceableAlias ) { tryReplacingAliasingAssignment ( alias , aliasLhsNode ) ; } if ( codeChanged ) { // Inlining the variable may have introduced new references // to descendants of {@code name}. So those need to be collected now. namespace . scanNewNodes ( newNodes ) ; } return ! foundNonReplaceableAlias ; }
Inlines some references to an alias with its value . This handles cases where the alias is not declared at initialization . It does nothing if the alias is reassigned after being initialized unless the reassignment occurs because of an enclosing function or a loop .