public void emit()

in compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java [54:363]


    public void emit(IIdentifierNode node)
    {
    	if (node instanceof NonResolvingIdentifierNode)
    	{
            startMapping(node);
    		write(node.getName());
            endMapping(node);
    		return;
    	}
        IDefinition nodeDef = ((IIdentifierNode) node).resolve(getProject());

        IASNode parentNode = node.getParent();
        ASTNodeID parentNodeId = parentNode.getNodeID();
        IASNode grandparentNode = parentNode.getParent();
  //      ASTNodeID grandparentNodeId = (parentNode != null) ? grandparentNode.getNodeID() : null;

        boolean identifierIsAccessorFunction = nodeDef instanceof AccessorDefinition;
        boolean identifierIsPlainFunction = nodeDef instanceof FunctionDefinition
                && !identifierIsAccessorFunction;
        boolean emitName = true;
        boolean wroteMemberAccess = false;
    	JSRoyaleEmitter fjs = (JSRoyaleEmitter)getEmitter();
        RoyaleJSProject project = (RoyaleJSProject)getWalker().getProject();
    	boolean isCustomNamespace = false;
    	boolean isStatic = nodeDef != null && nodeDef.isStatic();
        if (nodeDef instanceof FunctionDefinition &&
          	  fjs.isCustomNamespace((FunctionDefinition)nodeDef))
              isCustomNamespace = true;

        if (isStatic
                && nodeDef instanceof IConstantDefinition
                && project != null && project.config != null
                && project.config.getInlineConstants())
        {
            IConstantDefinition constDef = (IConstantDefinition) nodeDef;
            Object initialValue = constDef.resolveInitialValue(project);
            if (initialValue != null)
            {
                emitInitialValue(parentNode, initialValue);
                return;
            }
        }
        if (isStatic)
        {
            String sname = nodeDef.getParent().getQualifiedName();
            if (sname.length() > 0)
            {
                if (emitStaticConstants(parentNode, nodeDef))
                {
                    return;
                }
                startMapping(node);
                write(getEmitter().formatQualifiedName(sname));
                if (!isCustomNamespace)
                {
                    write(ASEmitterTokens.MEMBER_ACCESS);
                    wroteMemberAccess = true;
                }
                endMapping(node);
            }
        }
        else if (!NativeUtils.isNative(node.getName()))
        {
            // an instance method not in a function call or member access
            boolean generateClosure = identifierIsPlainFunction && ((FunctionDefinition) nodeDef)
                    .getFunctionClassification() == FunctionClassification.CLASS_MEMBER &&
                    (!(parentNodeId == ASTNodeID.FunctionCallID || parentNodeId == ASTNodeID.MemberAccessExpressionID));
            if (generateClosure)
            {
                getEmitter().emitClosureStart();
            }

            boolean wroteSelf = false;
            if (EmitterUtils.writeThis(getProject(), getModel(), node))
            {
                IFunctionObjectNode functionObjectNode = (IFunctionObjectNode) node
                        .getParent().getAncestorOfType(
                                IFunctionObjectNode.class);

                IFunctionNode functionNode = (IFunctionNode) node
                .getParent().getAncestorOfType(
                        IFunctionNode.class);
                IFunctionDefinition functionDef = null;
                if (functionNode != null)
                	functionDef = functionNode.getDefinition();

                startMapping(node);
                if (functionObjectNode != null)
                {
                    write(JSGoogEmitterTokens.SELF);
                    wroteSelf = true;
                }
                else if (functionNode != null && functionDef.getFunctionClassification() == FunctionClassification.LOCAL)
                {
                    write(JSGoogEmitterTokens.SELF);
                    wroteSelf = true;
                }
                else
                {
                    write(ASEmitterTokens.THIS);
                }

                if (!isCustomNamespace) {
                    write(ASEmitterTokens.MEMBER_ACCESS);
                    wroteMemberAccess = true;
                }
                endMapping(node);
            }
            else if (EmitterUtils.writeE4xFilterNode(getProject(), getModel(), node))
            {
                startMapping(node);
            	write("node.");
                endMapping(node);
            }

            if (generateClosure)
            {
                if (isCustomNamespace)
                {
                	Namespace ns = (Namespace)((INamespaceResolvedReference)((FunctionDefinition)nodeDef).getNamespaceReference()).resolveAETNamespace(getProject());
                	INamespaceDefinition nsDef = ((FunctionDefinition)nodeDef).getNamespaceReference().resolveNamespaceReference(getProject());
        			fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names
                	String nsName = ns.getName();
                	write(JSRoyaleEmitter.formatNamespacedProperty(nsName, node.getName(), true));
                }
                else
                {
            		String qname = node.getName();
                	if (nodeDef != null && !isStatic && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
                    {
                		qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
                    }
            		write(qname);
                }

                writeToken(ASEmitterTokens.COMMA);
                if (wroteSelf)
                    write(JSGoogEmitterTokens.SELF);
                else
                	write(ASEmitterTokens.THIS);
                getEmitter().emitClosureEnd(node, nodeDef);
                emitName = false;
            }
        }
        
        if (emitName)
        {
            boolean accessWithNS = !wroteMemberAccess;
            if (nodeDef != null)
            {
                // this can be optimized but this way lets
                // us breakpoint on the node.getName() to make
                // sure it is ok to always use the short name in an MAE
                String qname = nodeDef.getQualifiedName();
                boolean isPackageOrFileMember = false;
                if (nodeDef instanceof IVariableDefinition)
                {
                    IVariableDefinition variable = (IVariableDefinition) nodeDef;
                    VariableClassification classification = variable.getVariableClassification();
                    if (classification == VariableClassification.PACKAGE_MEMBER ||
                            classification == VariableClassification.FILE_MEMBER)
                    {
                        isPackageOrFileMember = true;
                    }
                    String ns = nodeDef.getNamespaceReference().getBaseName();
                    isCustomNamespace = EmitterUtils.isCustomNamespace(ns);
                    if (isCustomNamespace && parentNode instanceof IMemberAccessExpressionNode
                            && ((IMemberAccessExpressionNode) parentNode).getRightOperandNode() == node) {
                        accessWithNS = true;
                        boolean wasCustomNamespace = false;
                        //duplicate some checks in MemberAccessEmitter to avoid double output of MEMBER_ACCESS
                        if (nodeDef instanceof IAccessorDefinition && ((IMemberAccessExpressionNode) parentNode).getOperator() == IOperatorNode.OperatorType.MEMBER_ACCESS)
                            wasCustomNamespace = fjs.isCustomNamespace((FunctionDefinition)nodeDef);
                        
                        if (!wasCustomNamespace) {
                            //we already wrote member access before walking to this node.
                            accessWithNS = false;
                        }
                    }
                }
                else if (nodeDef instanceof IFunctionDefinition)
                {
                    IFunctionDefinition func = (IFunctionDefinition) nodeDef;
                    FunctionClassification classification = func.getFunctionClassification();
                    if (classification == FunctionClassification.PACKAGE_MEMBER ||
                            classification == FunctionClassification.FILE_MEMBER)
                    {
                        isPackageOrFileMember = true;
                    }
                }
                boolean needsFormattedName = false;
                if (isPackageOrFileMember && parentNodeId == ASTNodeID.MemberAccessExpressionID)
                {
                    IMemberAccessExpressionNode parentMemberAccessNode = (IMemberAccessExpressionNode) parentNode;
                    //if the package or file member isn't on the left side of a
                    //member access expression, it shouldn't be fully qualified
                    needsFormattedName = parentMemberAccessNode.getLeftOperandNode() == node;
                }
                if (parentNodeId == ASTNodeID.MemberAccessExpressionID)
                {
                	if (needsFormattedName)
                	{
                        startMapping(node);
                	    write(getEmitter().formatQualifiedName(qname));
                        endMapping(node);
                	}
                    else if (isCustomNamespace)
                    {
                    	String ns = ((INamespaceResolvedReference)(nodeDef.getNamespaceReference())).resolveAETNamespace(getProject()).getName();
                        if (accessWithNS)
                        {
                            write(ASEmitterTokens.MEMBER_ACCESS);
                        }
                        startMapping(node, node.getName());
                    	write(JSRoyaleEmitter.formatNamespacedProperty(ns, qname, false));
                        endMapping(node);
                    }
                	else
                	{
                        String originalQname = null;
                	    if (!(nodeDef.getParent() instanceof IPackageDefinition))
                        {
                            qname = node.getName();
                            if (nodeDef != null && !isStatic && (nodeDef.getParent() instanceof ClassDefinition) && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
                            {
                                originalQname = qname;
                                qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
                            }
                        }
                        startMapping(node, originalQname);
                    	write(qname);
                        endMapping(node);
                	}
                }
                else if (isPackageOrFileMember)
                {
                    startMapping(node);
                    write(getEmitter().formatQualifiedName(qname));
                    endMapping(node);
                }
                else if (nodeDef instanceof TypeDefinitionBase)
                {
                    if (NativeUtils.isSyntheticJSType(qname) && !(parentNode instanceof IFunctionCallNode))
                    {
                        if (project instanceof RoyaleJSProject)
                        {
                            ((RoyaleJSProject)project).needLanguage = true;
                        }
                        getEmitter().getModel().needLanguage = true;
                        write(fjs.formatQualifiedName(JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken()));
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSRoyaleEmitterTokens.SYNTH_TYPE);
                        write(ASEmitterTokens.PAREN_OPEN);
                        write(ASEmitterTokens.SINGLE_QUOTE);
                        startMapping(node);
                        write(getEmitter().formatQualifiedName(qname));
                        endMapping(node);
                        write(ASEmitterTokens.SINGLE_QUOTE);
                        write(ASEmitterTokens.PAREN_CLOSE);
                    }
                    else
                    {
                        startMapping(node);
                        write(getEmitter().formatQualifiedName(qname));
                        endMapping(node);
                    }
                }
                else if (isCustomNamespace)
                {
                	String ns = ((INamespaceResolvedReference)nodeDef.getNamespaceReference()).resolveAETNamespace(getProject()).getName();
                    if (accessWithNS)
                    {
                        write(ASEmitterTokens.MEMBER_ACCESS);
                    }
                    startMapping(node, node.getName());
                	write(JSRoyaleEmitter.formatNamespacedProperty(ns, qname, false));
                    endMapping(node);
                }
                else
                {
                    String originalSymbolName = null;
                	if (nodeDef != null && !isStatic && (nodeDef.getParent() instanceof ClassDefinition) && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
                    {
                        qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname);
                        originalSymbolName = node.getName();
                    }
                    startMapping(node, originalSymbolName, node.getLine(), node.getColumn());
                    write(qname);
                    endMapping(node);
                }
            }
            else if (getModel().inE4xFilter && EmitterUtils.writeE4xFilterNode(getProject(), getModel(), node) /* swapped this out to allow for deeper nesting inside the filter expression ... instead of original:grandparentNodeId == ASTNodeID.E4XFilterID*/
            		&& (!(parentNodeId == ASTNodeID.MemberAccessExpressionID
                    || parentNodeId == ASTNodeID.Op_DescendantsID
                    || parentNodeId == ASTNodeID.FunctionCallID)))
            {
                startMapping(node);
                write("child('");
                write(node.getName());
                write("')");
                endMapping(node);
            }
            else
            {
                startMapping(node);
                write(node.getName());
                endMapping(node);
            }
        }
    }