public StatementListNode generateDefinitionBody()

in modules/compiler/src/java/flex2/compiler/mxml/rep/init/ValueInitializer.java [725:1117]


    public StatementListNode generateDefinitionBody(Context context, HashSet<String> configNamespaces,
                                                    boolean generateDocComments, StatementListNode statementList)
    {
        assert hasDefinition() : "no definition in getDefinitionBody()";
        assert value instanceof Model : "non-Model value has definition in getDefinitionBody()";

        NodeFactory nodeFactory = context.getNodeFactory();
        StatementListNode result = statementList;

        final String varName = TEMP;
        
        Model self = (Model) value;
        Type selfType = self.getType();
        String selfTypeName;

        if (value instanceof Vector)
        {
            Vector vector = (Vector) value;
            String elementTypeName = vector.getElementTypeName();
            selfTypeName = StandardDefs.CLASS_VECTOR + ".<" + elementTypeName + ">";
        }
        else
        {
            selfTypeName = NameFormatter.toDot(selfType.getName());
        }

        boolean isDeclared = self.isDeclared();
        String id = isDeclared ? self.getId() : varName;

        TypeExpressionNode returnType =
            AbstractSyntaxTreeUtil.generateTypeExpression(nodeFactory, selfTypeName, true);
        FunctionSignatureNode functionSignature = nodeFactory.functionSignature(null, returnType);        
        int position = AbstractSyntaxTreeUtil.lineNumberToPosition(nodeFactory, getLineRef());
        VariableDefinitionNode variableDefinition;

        //  value creation
        if (modelHasInlineRValue())
        {
            Node inlineRValue = generateInlineRValue(nodeFactory, configNamespaces, generateDocComments);
            variableDefinition = AbstractSyntaxTreeUtil.generateVariable(nodeFactory, varName,
                                                                         selfTypeName, true,
                                                                         inlineRValue, position);
        }
        else if (value instanceof Vector)
        {
            Vector vector = (Vector) value;
            LiteralNumberNode literalNumber = nodeFactory.literalNumber(vector.size());
            ArgumentListNode argumentList = nodeFactory.argumentList(null, literalNumber);

            if (vector.isFixed())
            {
                LiteralBooleanNode literalBoolean = nodeFactory.literalBoolean(vector.isFixed());
                argumentList = nodeFactory.argumentList(argumentList, literalBoolean);
            }
            
            variableDefinition = AbstractSyntaxTreeUtil.generateVariableNew(nodeFactory, varName,
                                                                            selfTypeName, argumentList,
                                                                            position);
        }
        else
        {
            //  TODO confirm the availability of a 0-arg ctor!! but do
            //  it upstream from here, like when Model is built
            variableDefinition = AbstractSyntaxTreeUtil.generateVariableNew(nodeFactory, varName,
                                                                            selfTypeName, position);
        }

        StatementListNode functionStatementList = nodeFactory.statementList(null, variableDefinition);

        if (!modelHasInlineRValue())
        {
            if (value instanceof Vector)
            {
                Vector vector = (Vector) value;
                addAssignExprs(nodeFactory, configNamespaces, generateDocComments, functionStatementList,
                               vector.getElementInitializerIterator(), varName);
            }
            else
            {
                // set properties
                addAssignExprs(nodeFactory, configNamespaces, generateDocComments, functionStatementList,
                               self.getPropertyInitializerIterator(self.getType().hasDynamic()),
                               varName);
            }
        }
        
        //  set styles
        addAssignExprs(nodeFactory, configNamespaces, generateDocComments, functionStatementList,
                       self.getStyleInitializerIterator(), varName);

        //  set effects
        addAssignExprs(nodeFactory, configNamespaces, generateDocComments, functionStatementList,
                       self.getEffectInitializerIterator(), varName);

        //  add event handlers
        addAssignExprs(nodeFactory, configNamespaces, generateDocComments, functionStatementList,
                       self.getEventInitializerIterator(), varName);

        //  register effect names
        Iterator<Initializer> iterator = self.getEffectInitializerIterator();

        if (iterator.hasNext())
        {
            //list.add("\t", varName, ".registerEffects([ ", effectEventNames, " ]);", line);
            MemberExpressionNode base = AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, false);

            IdentifierNode identifier = nodeFactory.identifier(REGISTER_EFFECTS, false);
            ArgumentListNode effectEventNamesArgumentList = null;

            while (iterator.hasNext())
            {
                EffectInitializer effectInitializer = (EffectInitializer) iterator.next();
                String effectName = effectInitializer.getName();
                LiteralStringNode literalString = nodeFactory.literalString(effectName);
                effectEventNamesArgumentList = nodeFactory.argumentList(effectEventNamesArgumentList,
                                                                        literalString);
            }

            LiteralArrayNode literalArray = nodeFactory.literalArray(effectEventNamesArgumentList);
            ArgumentListNode argumentList = nodeFactory.argumentList(null, literalArray);
            CallExpressionNode selector = (CallExpressionNode) nodeFactory.callExpression(identifier,
                                                                                          argumentList);
            selector.setRValue(false);
            MemberExpressionNode memberExpression = nodeFactory.memberExpression(base, selector);
            ListNode list = nodeFactory.list(null, memberExpression);
            ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
            functionStatementList = nodeFactory.statementList(functionStatementList, expressionStatement);
        }

        //  post-init actions for values that are being assigned to properties (via id attribution)
        if (isDeclared && standardDefs.isIUIComponentWithIdProperty(selfType))
        {
            //  set id on IUIComponents that carry an id prop
            MemberExpressionNode base = AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, false);
            IdentifierNode identifier = nodeFactory.identifier(ID, false);
            LiteralStringNode literalString = nodeFactory.literalString(id);
            ArgumentListNode argumentList = nodeFactory.argumentList(null, literalString);
            SetExpressionNode selector = nodeFactory.setExpression(identifier, argumentList, false);
            MemberExpressionNode memberExpression = nodeFactory.memberExpression(base, selector);
            ListNode list = nodeFactory.list(null, memberExpression);
            ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
            functionStatementList = nodeFactory.statementList(functionStatementList, expressionStatement);
        }

        // Design layer related items
        if (self.layerParent != null)
        {
            if (self instanceof DesignLayer)
            {
                //list.add("\t", self.layerParent.getId(), ".addLayer(", varName, ");", line);
            	
                IdentifierNode method = nodeFactory.identifier(ADD_LAYER, false);
                
                IdentifierNode layerIdentifier = nodeFactory.identifier(self.layerParent.getId());
            	GetExpressionNode getExpression = nodeFactory.getExpression(layerIdentifier);
            	MemberExpressionNode layerMemberExpression = nodeFactory.memberExpression(null, getExpression);
            	
            	IdentifierNode varIdentifier = nodeFactory.identifier(varName);
            	GetExpressionNode varGetExpression = nodeFactory.getExpression(varIdentifier);
            	MemberExpressionNode varMemberExpression = nodeFactory.memberExpression(null, varGetExpression);
            	
                ArgumentListNode argumentList = nodeFactory.argumentList(null, varMemberExpression);
                
                CallExpressionNode selector = (CallExpressionNode) nodeFactory.callExpression(method, argumentList);
                selector.setRValue(false);
                
                MemberExpressionNode memberExpression = nodeFactory.memberExpression(layerMemberExpression, selector);
                ListNode list = nodeFactory.list(null, memberExpression);
                ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
                functionStatementList = nodeFactory.statementList(functionStatementList, expressionStatement); 
                
            }
            else if (self.getType().isAssignableTo(standardDefs.INTERFACE_IVISUALELEMENT))
            {   
            	// list.add("\t", varName, ".layer = ", self.layerParent.getId(), ";", line);
            	IdentifierNode varIdentifier = nodeFactory.identifier(varName);
            	GetExpressionNode varGetExpression = nodeFactory.getExpression(varIdentifier);
            	MemberExpressionNode base = nodeFactory.memberExpression(null, varGetExpression);
            	

            	IdentifierNode identifier = nodeFactory.identifier(DESIGN_LAYER, false);
            	
            	IdentifierNode layerIdentifier = nodeFactory.identifier(self.layerParent.getId());
            	GetExpressionNode getExpression = nodeFactory.getExpression(layerIdentifier);
            	
            	MemberExpressionNode rvalueMemberExpression = nodeFactory.memberExpression(null, getExpression);
                ArgumentListNode argumentList = nodeFactory.argumentList(null, rvalueMemberExpression);
                
            	SetExpressionNode selector = nodeFactory.setExpression(identifier, argumentList, false);
            	
                MemberExpressionNode memberExpression = nodeFactory.memberExpression(base, selector);
                ListNode list = nodeFactory.list(null, memberExpression);
                ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
                functionStatementList = nodeFactory.statementList(functionStatementList, expressionStatement); 
            }    
        }
        
        //  UIComponent-specific init steps
        if (standardDefs.isIUIComponent(selfType))
        {
            assert self instanceof MovieClip : "isIUIComponent(selfType) but !(self instanceof MovieClip)";
            MovieClip movieClip = (MovieClip) self;

            //  MXML implementations of IUIComponent initialize set their document property to themselves at
            //  construction time. Others need it set to the enclosing document (us).

            ListNode test;
            {
                MemberExpressionNode base =
                    AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, false);
                IdentifierNode identifier = nodeFactory.identifier(DOCUMENT, false);
                GetExpressionNode selector = nodeFactory.getExpression(identifier);
                MemberExpressionNode memberExpression = nodeFactory.memberExpression(base, selector);
                Node unaryExpression = nodeFactory.unaryExpression(Tokens.NOT_TOKEN, memberExpression);
                test = nodeFactory.list(null, unaryExpression);
            }

            StatementListNode then;
            {
                MemberExpressionNode base =
                    AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, false);
                IdentifierNode identifier = nodeFactory.identifier(DOCUMENT, false);
                ThisExpressionNode thisExpression = nodeFactory.thisExpression(-1);
                ArgumentListNode argumentList = nodeFactory.argumentList(null, thisExpression);
                SetExpressionNode selector = nodeFactory.setExpression(identifier, argumentList, false);
                MemberExpressionNode memberExpression = nodeFactory.memberExpression(base, selector);
                ListNode list = nodeFactory.list(null, memberExpression);
                ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
                then = nodeFactory.statementList(null, expressionStatement);
            }

            Node ifStatement = nodeFactory.ifStatement(test, then, null);
            functionStatementList = nodeFactory.statementList(functionStatementList, ifStatement);

            //  add visual children
            if (!standardDefs.isRepeater(selfType))
            {
                if (standardDefs.isContainer(selfType))
                {
                    if (movieClip.hasChildren())
                    {
                        functionStatementList = generateDocumentDescriptorAssignment(nodeFactory, configNamespaces, generateDocComments,
                                                                                     movieClip, varName, functionStatementList);
                        functionStatementList = generateDocumentDescriptorDocumentAssignment(nodeFactory, varName, 
                                                                                             functionStatementList);
                    }
                }
                else
                {
                    //  non-repeater - replicate DI child-creation sequence procedurally:       
                    Iterator childIter = movieClip.getChildInitializerIterator();
                    while (childIter.hasNext())
                    {
                        VisualChildInitializer init = (VisualChildInitializer)childIter.next();
                    
                        // Filter out state specific children.
                        if ( !((Model)init.getValue()).isStateSpecific())
                        {
                            MemberExpressionNode memberExpression =
                                AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, true);
                            functionStatementList =
                                init.generateAssignExpr(nodeFactory, configNamespaces, generateDocComments,
                                                        functionStatementList, memberExpression);
                        }
                    }
                }
            }
            else
            {
                //  repeater-specific init sequence: don't add children directly, instead use existing DI setup
                //  initializing repeater's childDescriptors property, for now
                VariableDefinitionNode childDescriptorVariableDefinition =
                    generateChildDescriptorVariable(nodeFactory, configNamespaces, generateDocComments,
                                                    varName, movieClip);
                functionStatementList = nodeFactory.statementList(functionStatementList,
                                                                  childDescriptorVariableDefinition);
                Node forStatement = generateRepeaterChildDescriptorLoop(nodeFactory);
                functionStatementList = nodeFactory.statementList(functionStatementList, forStatement);
            }
        }

        //  call IMXMLObject.initialized() on implementors
        if (self.getType().isAssignableTo(standardDefs.INTERFACE_IMXMLOBJECT)
                || self.getType().hasMetadata(StandardDefs.MD_IMXMLOBJECT, true))
        {
            MemberExpressionNode varNameMemberExpression =
                AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, false);
            IdentifierNode identifier = nodeFactory.identifier(INITIALIZED, false);
            ThisExpressionNode thisExpression = nodeFactory.thisExpression(-1);
            ArgumentListNode argumentList = nodeFactory.argumentList(null, thisExpression);

            if (isDeclared)
            {
                LiteralStringNode literalString = nodeFactory.literalString(id);
                argumentList = nodeFactory.argumentList(argumentList, literalString);
            }
            else
            {
                LiteralNullNode literalNull = nodeFactory.literalNull(-1);
                argumentList = nodeFactory.argumentList(argumentList, literalNull);
            }

            CallExpressionNode callExpression =
                (CallExpressionNode) nodeFactory.callExpression(identifier, argumentList);
            callExpression.setRValue(false);
            MemberExpressionNode memberExpression = nodeFactory.memberExpression(varNameMemberExpression,
                                                                                 callExpression);
            ListNode list = nodeFactory.list(null, memberExpression);
            ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
            functionStatementList = nodeFactory.statementList(functionStatementList, expressionStatement);
        }

        // generate idAssigned dispatching logic for user declared instances.
        if (isDeclared)
        {
            if (self.getRepeaterLevel() == 0)
            {
                functionStatementList = generateValueCreation(nodeFactory, functionStatementList, id, varName);
            }
            else
            {
                ThreadLocalToolkit.log(new DeclaredAndProceduralWithinRepeater(),
                                       self.getDocument().getSourcePath(), getLineRef());
            }
        
            //  evaluate all property bindings for this object - i.e. initialize properties of the object whose values
            //  are binding expressions. E.g. if we've just created <mx:Foo id="bar" x="100" y="{baz.z}"/>, then
            //  we need to evaluate (baz.z) and assign it to bar.y. This explicit evaluation pass is necessary because
            //  baz may already have been initialized, although the fact that we do it even when that's not the case is
            //  suboptimal.
            MemberExpressionNode base =
                AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, standardDefs.getBindingPackage(), BINDING_MANAGER, false);
            IdentifierNode identifier = nodeFactory.identifier(EXECUTE_BINDINGS, false);
            ThisExpressionNode thisExpression = nodeFactory.thisExpression(-1);
            ArgumentListNode argumentList = nodeFactory.argumentList(null, thisExpression);
            LiteralStringNode literalString = nodeFactory.literalString(id);
            argumentList = nodeFactory.argumentList(argumentList, literalString);
            MemberExpressionNode idMemberExpression =
                AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, id, true);
            argumentList = nodeFactory.argumentList(argumentList, idMemberExpression);
            CallExpressionNode selector = (CallExpressionNode) nodeFactory.callExpression(identifier, argumentList);
            selector.setRValue(false);
            MemberExpressionNode memberExpression = nodeFactory.memberExpression(base, selector);
            ListNode list = nodeFactory.list(null, memberExpression);
            ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
            functionStatementList = nodeFactory.statementList(functionStatementList, expressionStatement);
        }

        // If this is a stateful Halo Container, with itemCreationPolicy "immediate" we need to ensure
        // that the instance and all descendants are instantiated.
        if (standardDefs.isContainer(selfType) && self.isEarlyInit())
        {
            MemberExpressionNode varNameMemberExpression =
                AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, false);
            IdentifierNode identifier = nodeFactory.identifier(INITIALIZE, false);
            
            CallExpressionNode callExpression =
                (CallExpressionNode) nodeFactory.callExpression(identifier, null);
            callExpression.setRValue(false);
            MemberExpressionNode memberExpression = nodeFactory.memberExpression(varNameMemberExpression,
                                                                                 callExpression);
            ListNode list = nodeFactory.list(null, memberExpression);
            ExpressionStatementNode expressionStatement = nodeFactory.expressionStatement(list);
            functionStatementList = nodeFactory.statementList(functionStatementList, expressionStatement);
        }
        
        //  return created value
        MemberExpressionNode memberExpression =
            AbstractSyntaxTreeUtil.generateGetterSelector(nodeFactory, varName, false);
        ListNode list = nodeFactory.list(null, memberExpression);
        ReturnStatementNode returnStatement = nodeFactory.returnStatement(list);
        functionStatementList = nodeFactory.statementList(functionStatementList, returnStatement);

        IdentifierNode functionIdentifier = nodeFactory.identifier(getDefinitionName());
        FunctionCommonNode functionCommon = nodeFactory.functionCommon(context,
                                                                       functionIdentifier,
                                                                       functionSignature,
                                                                       functionStatementList);
        functionCommon.setUserDefinedBody(true);
        AttributeListNode attributeList = AbstractSyntaxTreeUtil.generatePrivateAttribute(nodeFactory);
        FunctionNameNode functionName = nodeFactory.functionName(Tokens.EMPTY_TOKEN, functionIdentifier);

        FunctionDefinitionNode functionDefinition = nodeFactory.functionDefinition(context, attributeList,
                                                                                   functionName, functionCommon);

        result = nodeFactory.statementList(result, functionDefinition);

        Type lvalueType = getLValueType();
        if (standardDefs.isITransientDeferredInstance(lvalueType) || self.getIsTransient())
        	result = generateDestructorBody(context, result);
        
        return result;
    }