private void populateFunctionDefinitions ( String name , List < Node > references ) { AmbiguatedFunctionSummary summaryForName = checkNotNull ( summariesByName . get ( name ) ) ; // Make sure we get absolutely every R-value assigned to `name` or at the very least detect // there are some we're missing. Overlooking a single R-value would invalidate the analysis. List < ImmutableList < Node > > rvaluesAssignedToName = references . stream ( ) // Eliminate any references that we're sure are R-values themselves. Otherwise // there's a high probability we'll inspect an R-value for futher R-values. We wouldn't // find any, and then we'd have to consider `name` impure. . filter ( ( n ) - > ! isDefinitelyRValue ( n ) ) // For anything that might be an L-reference, get the expression being assigned to it. . map ( NodeUtil :: getRValueOfLValue ) // If the assigned R-value is an analyzable expression, collect all the possible // FUNCTIONs that could result from that expression. If the expression isn't analyzable, // represent that with `null` so we can blacklist `name`. . map ( ( n ) - > ( n == null ) ? null : collectCallableLeaves ( n ) ) . collect ( toList ( ) ) ; if ( rvaluesAssignedToName . isEmpty ( ) || rvaluesAssignedToName . contains ( null ) ) { // Any of: // - There are no L-values with this name. // - There's a an L-value and we can't find the associated R-values. // - There's a an L-value with R-values are not all known to be callable. summaryForName . setAllFlags ( ) ; } else { rvaluesAssignedToName . stream ( ) . flatMap ( List :: stream ) . forEach ( ( rvalue ) - > { if ( rvalue . isFunction ( ) ) { summariesForAllNamesOfFunctionByNode . put ( rvalue , summaryForName ) ; } else { String rvalueName = nameForReference ( rvalue ) ; AmbiguatedFunctionSummary rvalueSummary = summariesByName . getOrDefault ( rvalueName , unknownFunctionSummary ) ; reverseCallGraph . connect ( rvalueSummary . graphNode , SideEffectPropagation . forAlias ( ) , summaryForName . graphNode ) ; } } ) ; }
For a name and its set of references record the set of functions that may define that name or blacklist the name if there are unclear definitions .