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);
}
}
}