private void appendBehaviorMembersToBlock ( final PolymerClassDefinition cls , Node block ) { String qualifiedPath = cls . target . getQualifiedName ( ) + ".prototype." ; Map < String , Node > nameToExprResult = new HashMap <> ( ) ; for ( BehaviorDefinition behavior : cls . behaviors ) { for ( MemberDefinition behaviorFunction : behavior . functionsToCopy ) { String fnName = behaviorFunction . name . getString ( ) ; // Don't copy functions already defined by the element itself. if ( NodeUtil . getFirstPropMatchingKey ( cls . descriptor , fnName ) != null ) { continue ; } // Avoid copying over the same function twice. The last definition always wins. if ( nameToExprResult . containsKey ( fnName ) ) { block . removeChild ( nameToExprResult . get ( fnName ) ) ; } Node fnValue = behaviorFunction . value . cloneTree ( ) ; NodeUtil . markNewScopesChanged ( fnValue , compiler ) ; Node exprResult = IR . exprResult ( IR . assign ( NodeUtil . newQName ( compiler , qualifiedPath + fnName ) , fnValue ) ) ; exprResult . useSourceInfoIfMissingFromForTree ( behaviorFunction . name ) ; JSDocInfoBuilder info = JSDocInfoBuilder . maybeCopyFrom ( behaviorFunction . info ) ; // Uses of private members that come from behaviors are not recognized correctly, // so just suppress that warning. info . addSuppression ( "unusedPrivateMembers" ) ; // If the function in the behavior is @protected, switch it to @public so that // we don't get a visibility warning. This is a bit of a hack but easier than // making the type system understand that methods are "inherited" from behaviors. if ( behaviorFunction . info != null && behaviorFunction . info . getVisibility ( ) == Visibility . PROTECTED ) { info . overwriteVisibility ( Visibility . PUBLIC ) ; } // Behaviors whose declarations are not in the global scope may contain references to // symbols which do not exist in the element's scope. Only copy a function stub. if ( ! behavior . isGlobalDeclaration ) { NodeUtil . getFunctionBody ( fnValue ) . removeChildren ( ) ; } exprResult . getFirstChild ( ) . setJSDocInfo ( info . build ( ) ) ; block . addChildToBack ( exprResult ) ; nameToExprResult . put ( fnName , exprResult ) ; } // Copy other members. for ( MemberDefinition behaviorProp : behavior . nonPropertyMembersToCopy ) { String propName = behaviorProp . name . getString ( ) ; if ( nameToExprResult . containsKey ( propName ) ) { block . removeChild ( nameToExprResult . get ( propName ) ) ; } Node exprResult = IR . exprResult ( NodeUtil . newQName ( compiler , qualifiedPath + propName ) ) ; exprResult . useSourceInfoFromForTree ( behaviorProp . name ) ; JSDocInfoBuilder info = JSDocInfoBuilder . maybeCopyFrom ( behaviorProp . info ) ; if ( behaviorProp . name . isGetterDef ( ) ) { info = new JSDocInfoBuilder ( true ) ; if ( behaviorProp . info != null && behaviorProp . info . getReturnType ( ) != null ) { info . recordType ( behaviorProp . info . getReturnType ( ) ) ; } } exprResult . getFirstChild ( ) . setJSDocInfo ( info . build ( ) ) ; block . addChildToBack ( exprResult ) ; nameToExprResult . put ( propName , exprResult ) ; } } }
Appends all required behavior functions and non - property members to the given block .