public void emit()

in compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/BinaryOperatorEmitter.java [60:665]


    public void emit(IBinaryOperatorNode node)
    {
        // TODO (mschmalle) will remove this cast as more things get abstracted
        JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();

        String op = node.getOperator().getOperatorText();
        boolean isAssignment = op.contains("=")
                && !op.contains("==")
                && !(op.startsWith("<") || op.startsWith(">") || op
                        .startsWith("!"));
        ASTNodeID id = node.getNodeID();
        /*
        if (id == ASTNodeID.Op_InID
                || id == ASTNodeID.Op_LogicalAndAssignID
                || id == ASTNodeID.Op_LogicalOrAssignID)
        {
            super.emitBinaryOperator(node);
        }
        else */if (id == ASTNodeID.Op_IsID || id == ASTNodeID.Op_AsID)
        {
            fjs.emitIsAs(node, node.getLeftOperandNode(), node.getRightOperandNode(),
                    id, false);
        }
        else if (id == ASTNodeID.Op_InstanceOfID)
        {
			if (ASNodeUtils.hasParenOpen(node)) {
				write(ASEmitterTokens.PAREN_OPEN);
			}
            getWalker().walk(node.getLeftOperandNode());

            startMapping(node, node.getLeftOperandNode());
            write(ASEmitterTokens.SPACE);
            writeToken(ASEmitterTokens.INSTANCEOF);
            endMapping(node);

            IDefinition dnode = (node.getRightOperandNode())
                    .resolve(getProject());
			if (dnode != null)
			{
				String dnodeQname = dnode.getQualifiedName();
                boolean isPackageOrFileMember = false;
                if (dnode instanceof IVariableDefinition)
                {
                    IVariableDefinition variable = (IVariableDefinition) dnode;
                    VariableClassification classification = variable.getVariableClassification();
                    if (classification == VariableClassification.PACKAGE_MEMBER ||
                            classification == VariableClassification.FILE_MEMBER)
                    {
                        isPackageOrFileMember = true;
                    }
                }
                else if (dnode instanceof IFunctionDefinition)
                {
                    IFunctionDefinition func = (IFunctionDefinition) dnode;
                    FunctionClassification classification = func.getFunctionClassification();
                    if (classification == FunctionClassification.PACKAGE_MEMBER ||
                            classification == FunctionClassification.FILE_MEMBER)
                    {
                        isPackageOrFileMember = true;
                    }
                }
				else if(dnode instanceof ITypeDefinition)
				{
					isPackageOrFileMember = true;
				}
				if(isPackageOrFileMember)
				{
					dnodeQname = getEmitter().formatQualifiedName(dnodeQname);
				}
                write(dnodeQname);
			}
			else
			{
				getWalker().walk(node.getRightOperandNode());
			}
			if (ASNodeUtils.hasParenClose(node)) {
				write(ASEmitterTokens.PAREN_CLOSE);
			}
        }
        else
        {
            IExpressionNode leftSide = node.getLeftOperandNode();
            IDefinition leftDef = leftSide.resolveType(getWalker().getProject());
            if (leftSide.getNodeID() == ASTNodeID.MemberAccessExpressionID)
            {
                IASNode lnode = leftSide.getChild(0);
                IASNode rnode = leftSide.getChild(1);
                IDefinition rnodeDef = (rnode instanceof IIdentifierNode) ?
                		((IIdentifierNode) rnode).resolve(getWalker().getProject()) :
                		null;
                boolean isDynamicAccess = rnode instanceof DynamicAccessNode;
                if (lnode.getNodeID() == ASTNodeID.SuperID
                        && rnodeDef instanceof AccessorDefinition)
                {
                    if (isAssignment)
                    {
						boolean propagateAssignedValue = !(node.getParent() instanceof IBlockNode);
						if (propagateAssignedValue)
						{
							write(ASEmitterTokens.PAREN_OPEN);
							write(ASEmitterTokens.FUNCTION);
							write(ASEmitterTokens.PAREN_OPEN);
							write("$value");
							write(ASEmitterTokens.PAREN_CLOSE);
							write(ASEmitterTokens.BLOCK_OPEN);
						}

						IClassNode cnode = (IClassNode) node
                                .getAncestorOfType(IClassNode.class);
                        if (cnode != null)
                        	write(getEmitter().formatQualifiedName(
                                cnode.getQualifiedName()));
                        else
                        	write(getEmitter().formatQualifiedName(
                        		getModel().getCurrentClass().getQualifiedName()));
                        		
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSGoogEmitterTokens.SUPERCLASS);
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(fjs.formatSetter(rnodeDef.getBaseName()));
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSEmitterTokens.APPLY);
                        write(ASEmitterTokens.PAREN_OPEN);
                        write(ASEmitterTokens.THIS);
                        writeToken(ASEmitterTokens.COMMA);
                        write(ASEmitterTokens.SQUARE_OPEN);
                        if (op.length() > 1) // += and things like that
                        {
                            write(getEmitter().formatQualifiedName(
                                    cnode.getQualifiedName()));
                            write(ASEmitterTokens.MEMBER_ACCESS);
                            write(JSGoogEmitterTokens.SUPERCLASS);
                            write(ASEmitterTokens.MEMBER_ACCESS);
							write(fjs.formatGetter(rnodeDef.getBaseName()));
                            write(ASEmitterTokens.MEMBER_ACCESS);
                            write(JSEmitterTokens.APPLY);
                            write(ASEmitterTokens.PAREN_OPEN);
                            write(ASEmitterTokens.THIS);
                            write(ASEmitterTokens.PAREN_CLOSE);
                            write(op.substring(0, 1));
                        }

						if (propagateAssignedValue)
						{
							write("$value");
							write(ASEmitterTokens.SQUARE_CLOSE);
							write(ASEmitterTokens.PAREN_CLOSE);
							write(ASEmitterTokens.SEMICOLON);
							// returning the original $value ensures that
							// chained assignments work properly
							// the getter should NOT be called!
							// x = super.y = z;
							writeToken(ASEmitterTokens.RETURN);
							write("$value");
							write(ASEmitterTokens.SEMICOLON);
							write(ASEmitterTokens.BLOCK_CLOSE);
							write(ASEmitterTokens.PAREN_CLOSE);
							write(ASEmitterTokens.MEMBER_ACCESS);
							write(JSEmitterTokens.APPLY);
							write(ASEmitterTokens.PAREN_OPEN);
							write(ASEmitterTokens.THIS);
							writeToken(ASEmitterTokens.COMMA);
							write(ASEmitterTokens.SQUARE_OPEN);
						}
                        getWalker().walk(node.getRightOperandNode());
                        write(ASEmitterTokens.SQUARE_CLOSE);
                        write(ASEmitterTokens.PAREN_CLOSE);
                        return;
                    }
                }
                else if (((JSRoyaleEmitter)getEmitter()).isXMLList((IMemberAccessExpressionNode)leftSide))
                {
                	MemberAccessExpressionNode xmlNode = (MemberAccessExpressionNode)leftSide;
                	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                	{
                		boolean wrapQuotes = true;
	                    getWalker().walk(xmlNode.getLeftOperandNode());
	                    IExpressionNode rightSide = xmlNode.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute('");
		                    getWalker().walk(rightSide.getChild(0));
	                    }
	                    else if (rightSide instanceof IDynamicAccessNode && ((IDynamicAccessNode) rightSide).getLeftOperandNode().getNodeID() == ASTNodeID.Op_AtID) {
							write(".setAttribute(");
							wrapQuotes = false;
							getWalker().walk(((IDynamicAccessNode)rightSide).getRightOperandNode());
						}
	                    else if (rightSide instanceof INamespaceAccessExpressionNode) {
							write(".setChild(");
							write("new QName(");
							getWalker().walk(((INamespaceAccessExpressionNode) rightSide).getLeftOperandNode());
							write(",'");
							getWalker().walk(((INamespaceAccessExpressionNode) rightSide).getRightOperandNode());
							write("')");
							wrapQuotes = false;
						}
	                    else
	                    {
		                    write(".setChild('");
		                    getWalker().walk(rightSide);
	                    }
	                    if (wrapQuotes) write("'");
	                    write(", ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    getWalker().walk(xmlNode.getLeftOperandNode());
	                    IExpressionNode rightSide = xmlNode.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute('");
		                    getWalker().walk(((UnaryOperatorAtNode)rightSide).getChild(0));
	                    }
	                    else
	                    {
		                    write(".setChild('");
		                    getWalker().walk(rightSide);
	                    }
	                    write("', ");
                        getWalker().walk(node.getLeftOperandNode());
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddID)
                	{
	                    getWalker().walk(xmlNode);
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                }
                else if (isDynamicAccess && ((JSRoyaleEmitter)getEmitter()).isXMLish((IExpressionNode)lnode))
                {
                	DynamicAccessNode dyn = (DynamicAccessNode)rnode;
                	ITypeDefinition type = dyn.getRightOperandNode().resolveType(getProject());
                	if (type.isInstanceOf("String", getProject()) || type.isInstanceOf("Object", getProject())
                			|| type == getProject().getBuiltinType(BuiltinType.ANY_TYPE))
        			{
                		String field;
                    	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                    	{
    	                    getWalker().walk(lnode);
    	                    IExpressionNode dynLeft = dyn.getLeftOperandNode();
    	                    IExpressionNode dynRight = dyn.getRightOperandNode();
    	                    if (dynLeft instanceof UnaryOperatorAtNode)
    	                    {
    		                    write(".setAttribute(");
    							field = fjs.stringifyNode(dyn.getRightOperandNode());
    	                    }
    	                    else if (dynRight instanceof UnaryOperatorAtNode)
    	                    {
    		                    write(".setAttribute(");
    							field = fjs.stringifyNode(dynRight.getChild(0));
    	                    }
    	                    else
    	                    {
    		                    write(".setChild(");
    							field = fjs.stringifyNode(dynLeft);
    	                    }
    	                    write(field + ", ");
    	                    getWalker().walk(node.getRightOperandNode());
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    return;
                    	}
                    	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                    	{
    	                    getWalker().walk(lnode);
    	                    IExpressionNode rightSide = dyn.getRightOperandNode();
    	                    if (rightSide instanceof UnaryOperatorAtNode)
    	                    {
    		                    write(".setAttribute('");
    							field = fjs.stringifyNode(((UnaryOperatorAtNode)rightSide).getChild(0));
    							field = field.replace("\"", ""); // remove wrapping double-quotes
    	                    }
    	                    else
    	                    {
    		                    write(".setChild('");
    							field = fjs.stringifyNode(rightSide);
    							field = field.replace("\"", ""); // remove wrapping double-quotes
    	                    }
    	                    write(field + "', ");
                            getWalker().walk(node.getLeftOperandNode());
    	                    write(".plus(");
    	                    getWalker().walk(node.getRightOperandNode());
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    return;
                    	}
                    	else if (node.getNodeID() == ASTNodeID.Op_AddID)
                    	{
    	                    getWalker().walk(dyn);
    	                    write(".plus(");
    	                    getWalker().walk(node.getRightOperandNode());
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    return;
                    	}
        			}
                }
                else if (((JSRoyaleEmitter)getEmitter()).isProxy(((MemberAccessExpressionNode)leftSide).getLeftOperandNode()) && leftDef == null)
                {
                	MemberAccessExpressionNode proxyNode = (MemberAccessExpressionNode)leftSide;
                	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                	{
	                    getWalker().walk(proxyNode.getLeftOperandNode());
	                    IExpressionNode rightSide = proxyNode.getRightOperandNode();
	                    write(".setProperty('");
	                    getWalker().walk(rightSide);
	                    write("', ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    IExpressionNode rightSide = proxyNode.getRightOperandNode();
	                    getWalker().walk(proxyNode.getLeftOperandNode());
	                    write(".setProperty('");
	                    getWalker().walk(rightSide);
	                    write("', ");
	                    getWalker().walk(proxyNode.getLeftOperandNode());
	                    write(".getProperty(");
	                    write(ASEmitterTokens.SINGLE_QUOTE);
	                    getWalker().walk(rightSide);
	                    write(ASEmitterTokens.SINGLE_QUOTE);
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    write(" + ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                }
                else if (((JSRoyaleEmitter)getEmitter()).isDateProperty((MemberAccessExpressionNode)leftSide, true))
                {
                	specialCaseDate(node, (MemberAccessExpressionNode)leftSide);
                    return;
                }
            }
            else if (leftSide.getNodeID() == ASTNodeID.IdentifierID)
            {
    			if ((leftDef != null)
    				&& SemanticUtils.isXMLish(leftDef, getWalker().getProject()))
    			{
                	if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    getWalker().walk(leftSide);
	                    write(" = ");
	                    getWalker().walk(leftSide);
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                }
            }
            else if (leftSide.getNodeID() == ASTNodeID.ArrayIndexExpressionID) // dynamic access
            {
            	DynamicAccessNode dyn = (DynamicAccessNode)leftSide;
            	IExpressionNode dynLeft = dyn.getLeftOperandNode();
            	ITypeDefinition type = dyn.getRightOperandNode().resolveType(getProject());
            	if (((JSRoyaleEmitter)getEmitter()).isXMLish(dynLeft)/* && !SemanticUtils.isNumericType(type, getProject())*/) //type.isInstanceOf("String", getProject())
    			{
            		String field;
                	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                	{
	                    getWalker().walk(dynLeft);
	                    IExpressionNode rightSide = dyn.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute(");
							field = fjs.stringifyNode((rightSide).getChild(0));
	                    }
	                    else
	                    {
							write(".setChild(");
							field = fjs.stringifyNode(rightSide);
	                    }
						if (field.startsWith("\"") && field.endsWith("\"")) {
							// remove wrapping double-quotes and swap to single quotes
							field = "'" + field.substring(1, field.length() - 1) + "'";
						}
	                    write(field + ", ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    getWalker().walk(dynLeft);
	                    IExpressionNode rightSide = dyn.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute('");
							field = fjs.stringifyNode(((UnaryOperatorAtNode)rightSide).getChild(0));
							field = field.replace("\"", ""); // remove wrapping double-quotes
	                    }
	                    else
	                    {
		                    write(".setChild('");
							field = fjs.stringifyNode(rightSide);
							field = field.replace("\"", ""); // remove wrapping double-quotes
	                    }
	                    write(field + "', ");
                        getWalker().walk(node.getLeftOperandNode());
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddID)
                	{
	                    getWalker().walk(dyn);
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}

    			}
            	else if (((JSRoyaleEmitter)getEmitter()).isProxy(dynLeft))
            	{
            		if (isAssignment)
            		{
	                    getWalker().walk(dynLeft);
	                    IExpressionNode rightSide = dyn.getRightOperandNode();
	                    write(".setProperty(");
	                    getWalker().walk(rightSide);
	                    write(", ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
            		}
            		else
            		{
	                    getWalker().walk(dynLeft);
	                    IExpressionNode rightSide = dyn.getRightOperandNode();
	                    write(".getProperty(");
	                    getWalker().walk(rightSide);
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    write(ASEmitterTokens.SPACE);
	                    writeToken(op);
	                    getWalker().walk(node.getRightOperandNode());
            		}
                    return;            		
            	}
            }
            
			if (id == ASTNodeID.Op_EqualID || id ==ASTNodeID.Op_NotEqualID) {
				//QName == QName
				if (leftDef != null && leftDef.getQualifiedName().equals("QName")) {
					IDefinition rightDef = node.getRightOperandNode().resolveType(getProject());
					if (rightDef != null && rightDef.getQualifiedName().equals("QName")) {
						//handle non-strict equality/inequality a little differently via QName.equality method
						if (id == ASTNodeID.Op_NotEqualID) write("!");
						write("QName.equality(");
						getWalker().walk(node.getLeftOperandNode());
						write(",");
						getWalker().walk(node.getRightOperandNode());
						write(")");
						return;
					}
				} else {
					IASNode codeContext = node.getAncestorOfType(IClassNode.class);
					boolean isFrameworkXML = false;
					if (codeContext instanceof IClassNode) {
						if (((IClassNode) codeContext).getQualifiedName().equals("XML") || ((IClassNode) codeContext).getQualifiedName().equals("XMLList")) {
							//we will ignore the internal code of the emulation support classes for these cases
							isFrameworkXML = true;
						}
					}
					if (!isFrameworkXML) {
						boolean leftIsAny = (leftDef == null || getProject().getBuiltinType(BuiltinType.ANY_TYPE).equals(leftDef));
						IDefinition rightDef = node.getRightOperandNode().resolveType(getProject());
						boolean rightIsAny = (rightDef == null || getProject().getBuiltinType(BuiltinType.ANY_TYPE).equals(rightDef));
						boolean leftIsXMLish = (leftIsAny && SemanticUtils.isXMLish(node.getLeftOperandNode(), getProject())) || SemanticUtils.isXMLish(leftDef, getProject());
						boolean rightIsXMLish = (rightIsAny && SemanticUtils.isXMLish(node.getRightOperandNode(), getProject())) || SemanticUtils.isXMLish(rightDef, getProject());


						if (leftIsXMLish && rightIsXMLish) {


							startMapping(node, node.getLeftOperandNode());
							//handle non-strict equality/inequality for XMLish comparisons a little differently
							if (id == ASTNodeID.Op_NotEqualID) write("!");
							write("XML.equality(");
							endMapping(node);
							getWalker().walk(node.getLeftOperandNode());
							startMapping(node, node.getLeftOperandNode());
							write(",");
							endMapping(node);
							getWalker().walk(node.getRightOperandNode());
							startMapping(node, node.getLeftOperandNode());
							write(")");
							endMapping(node);
							return;
						} else {
							if (leftIsXMLish || rightIsXMLish) {

								IDefinition otherDef = leftIsXMLish ? rightDef : leftDef;
								boolean otherIsBoolean = getProject().getBuiltinType(BuiltinType.BOOLEAN).equals(otherDef);


								if (otherIsBoolean || (leftIsAny && rightIsXMLish) || (rightIsAny && leftIsXMLish)) {

									if (otherIsBoolean) {
										//cover xmlish ==/!= boolean and boolean ==/!= xmlish variations by converting the boolean value to string (xmlishBooleanEqualityOperand):
										if (leftIsXMLish) getWalker().walk(node.getLeftOperandNode());
										else xmlishBooleanEqualityOperand(node.getLeftOperandNode());
										write(" " + node.getOperator().getOperatorText() + " ");
										if (leftIsXMLish) xmlishBooleanEqualityOperand(node.getRightOperandNode());
										else getWalker().walk(node.getRightOperandNode());
										return;
									} else {
										//cover xmlish ==/!= * (typed) and * (typed) ==/!= xmlish variations:
										IExpressionNode lhs = leftIsXMLish ? node.getLeftOperandNode() : node.getRightOperandNode();
										IExpressionNode rhs = leftIsXMLish ? node.getRightOperandNode() : node.getLeftOperandNode();
										//@todo check the source-mapping to the equality/inequality operator, this could probably be improved:
										startMapping(node, node.getLeftOperandNode());
										//handle non-strict equality/inequality for XMLish comparisons a little differently via XML.mixedEquality method
										if (id == ASTNodeID.Op_NotEqualID) write("!");

										write("XML.mixedEquality(");
										endMapping(node);
										getWalker().walk(lhs);
										startMapping(node, node.getLeftOperandNode());
										write(",");
										endMapping(node);
										getWalker().walk(rhs);
										startMapping(node, node.getLeftOperandNode());
										write(")");
										endMapping(node);
										return;
									}
								}
							}
						}
					}
				}
			} else if (id == ASTNodeID.Op_AddID) {
				IDefinition rightDef = node.getRightOperandNode().resolveType(getProject());
				boolean leftIsXMLish = (SemanticUtils.isXMLish(node.getLeftOperandNode(), getProject())) || SemanticUtils.isXMLish(leftDef, getProject());
				boolean rightIsXMLish = (SemanticUtils.isXMLish(node.getRightOperandNode(), getProject())) || SemanticUtils.isXMLish(rightDef, getProject());
				boolean process;
				if (leftIsXMLish) {
					process = !rightIsXMLish;
				} else {
					process = rightIsXMLish;
				}
				if (process) {
					IASNode codeContext = node.getAncestorOfType(IClassNode.class);
					boolean isFrameworkXML = false;
					if (codeContext instanceof IClassNode) {
						if (((IClassNode) codeContext).getQualifiedName().equals("XML") || ((IClassNode) codeContext).getQualifiedName().equals("XMLList")) {
							//we will ignore the internal code of the emulation support classes for these cases
							isFrameworkXML = true;
						}
					}
					if (!isFrameworkXML) {
						IExpressionNode leftOperand = node.getLeftOperandNode();
						IExpressionNode rightOperand = node.getRightOperandNode();
						FunctionCallNode functionCallNode;
						if (leftIsXMLish) {
							//wrap in string coercion
							if (EmitterUtils.xmlRequiresNullCheck((NodeBase) leftOperand, getProject())) {
								//if it is a simple identifier, then it could be a null reference so use the XMLList.coerce_string method, which retains null
								functionCallNode = EmitterUtils.wrapXMLListStringCoercion((NodeBase) leftOperand);
							} else {
								//if it is a member access expression or something else then assume we don't have to check for null
								functionCallNode = EmitterUtils.wrapSimpleStringCoercion((NodeBase) leftOperand);
							}
							functionCallNode.setParent((NodeBase) node);
							leftOperand = functionCallNode;
						} else {
							//wrap in string coercion
							if (EmitterUtils.xmlRequiresNullCheck((NodeBase) rightOperand, getProject())) {
								//if it is a simple identifier, then it could be a null reference so use the XMLList.coerce_string method, which retains null
								functionCallNode = EmitterUtils.wrapXMLListStringCoercion((NodeBase) rightOperand);
							} else {
								//if it is a member access expression or something else then assume we don't have to check for null
								functionCallNode = EmitterUtils.wrapSimpleStringCoercion((NodeBase) rightOperand);
							}
							functionCallNode.setParent((NodeBase) node);
							rightOperand = functionCallNode;
						}
						getWalker().walk(leftOperand);
						write(ASEmitterTokens.SPACE);
						writeToken(ASEmitterTokens.PLUS);
						write(ASEmitterTokens.SPACE);
						getWalker().walk(rightOperand);
						return;
					}
				}

			}
			
		
			super_emitBinaryOperator(node, isAssignment);
        }
    }