This is an automated email from the ASF dual-hosted git repository. joshtynjala pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/royale-compiler.git
commit 16db787e6048324cd40911fbe097d989a6f86d1d Author: Josh Tynjala <[email protected]> AuthorDate: Thu Jul 25 09:23:42 2024 -0700 compiler-jx: source map improvements added original symbol name to field and method definition, if applicable added mappings for default parameter value initialization improved mappings for field and method definitions added original symbol name to identifiers, if applicable --- .../compiler/codegen/js/IMappingEmitter.java | 16 +++++ .../compiler/internal/codegen/js/JSEmitter.java | 65 +++++++++++++-------- .../compiler/internal/codegen/js/JSSubEmitter.java | 15 +++++ .../internal/codegen/js/jx/FieldEmitter.java | 57 ++++++++++++++---- .../internal/codegen/js/jx/IdentifierEmitter.java | 64 +++++++++++++------- .../internal/codegen/js/jx/MethodEmitter.java | 7 ++- .../codegen/js/royale/JSRoyaleEmitter.java | 68 +++++++++++++--------- .../codegen/mxml/royale/MXMLRoyaleEmitter.java | 39 +++++++++---- .../royale/compiler/utils/SourceMapUtils.java | 2 +- .../js/sourcemaps/TestSourceMapFieldMembers.java | 51 ++++++++++------ .../js/sourcemaps/TestSourceMapMethodMembers.java | 48 +++++++++++++++ .../compiler/internal/test/SourceMapTestBase.java | 35 ++++++++++- 12 files changed, 348 insertions(+), 119 deletions(-) diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IMappingEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IMappingEmitter.java index bcc575747..6e5dee410 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IMappingEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/codegen/js/IMappingEmitter.java @@ -37,6 +37,11 @@ public interface IMappingEmitter */ void startMapping(ISourceLocation node); + /** + * Adds a node to the source map using a custom symbol name. + */ + void startMapping(ISourceLocation node, String symbolName); + /** * Adds a node to the source map using custom line and column values, * instead of the node's own line and column. Useful for starting a mapping @@ -50,6 +55,17 @@ public interface IMappingEmitter */ void startMapping(ISourceLocation node, ISourceLocation afterNode); + /** + * Adds a node the the source map using a custom symbol name, and custom + * line and column values. + */ + void startMapping(ISourceLocation node, String symbolName, int line, int column); + + /** + * Adds to the source map, without a node. + */ + void startMapping(String sourcePath, String symbolName, int line, int column); + /** * Commits a mapping to the source map. */ diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java index 85f069c5e..b534c2783 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSEmitter.java @@ -384,18 +384,57 @@ public class JSEmitter extends ASEmitter implements IJSEmitter { startMapping(node, node.getLine(), node.getColumn()); } + + public void startMapping(ISourceLocation node, String symbolName) + { + startMapping(node, symbolName, node.getLine(), node.getColumn()); + } public void startMapping(ISourceLocation node, int line, int column) + { + startMapping(node, null, line, column); + } + + public void startMapping(ISourceLocation node, ISourceLocation afterNode) + { + startMapping(node, afterNode.getEndLine(), afterNode.getEndColumn()); + } + + public void startMapping(ISourceLocation node, String symbolName, int line, int column) + { + String sourcePath = node.getSourcePath(); + if (sourcePath == null) + { + //if the source path is null, this node may have been generated by + //the compiler automatically. for example, an untyped variable will + //have a node for the * type. + if (node instanceof IASNode) + { + IASNode parentNode = ((IASNode) node).getParent(); + if (parentNode != null) + { + //try the parent node + startMapping(parentNode, symbolName, line, column); + return; + } + } + } + + startMapping(sourcePath, symbolName, line, column); + } + + public void startMapping(String sourcePath, String symbolName, int line, int column) { if (isBufferWrite()) { return; } + IEmitter parentEmitter = getParentEmitter(); if (parentEmitter != null && parentEmitter instanceof IMappingEmitter) { IMappingEmitter mappingParent = (IMappingEmitter) parentEmitter; - mappingParent.startMapping(node, line, column); + mappingParent.startMapping(sourcePath, symbolName, line, column); return; } if (lastMapping != null) @@ -407,39 +446,17 @@ public class JSEmitter extends ASEmitter implements IJSEmitter + " in file " + lastMapping.sourcePath); } - String sourcePath = node.getSourcePath(); - if (sourcePath == null) - { - //if the source path is null, this node may have been generated by - //the compiler automatically. for example, an untyped variable will - //have a node for the * type. - if (node instanceof IASNode) - { - IASNode parentNode = ((IASNode) node).getParent(); - if (parentNode != null) - { - //try the parent node - startMapping(parentNode, line, column); - return; - } - } - } - //prefer forward slash sourcePath = sourcePath.replace('\\', '/'); SourceMapMapping mapping = new SourceMapMapping(); mapping.sourcePath = sourcePath; + mapping.name = symbolName; mapping.sourceStartPosition = new FilePosition(line, column); mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn()); lastMapping = mapping; } - public void startMapping(ISourceLocation node, ISourceLocation afterNode) - { - startMapping(node, afterNode.getEndLine(), afterNode.getEndColumn()); - } - public void endMapping(ISourceLocation node) { if (isBufferWrite()) diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSubEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSubEmitter.java index 6e347bdae..013381934 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSubEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/JSSubEmitter.java @@ -114,11 +114,26 @@ public class JSSubEmitter emitter.startMapping(node); } + protected void startMapping(ISourceLocation node, String sourcePath) + { + emitter.startMapping(node, sourcePath); + } + protected void startMapping(ISourceLocation node, int line, int column) { emitter.startMapping(node, line, column); } + protected void startMapping(ISourceLocation node, String symbolName, int line, int column) + { + emitter.startMapping(node, symbolName, line, column); + } + + protected void startMapping(String sourcePath, String symbolName, int line, int column) + { + emitter.startMapping(sourcePath, symbolName, line, column); + } + protected void startMapping(ISourceLocation node, ISourceLocation afterNode) { emitter.startMapping(node, afterNode); diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java index 6db4a849c..da0f83db8 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/FieldEmitter.java @@ -125,6 +125,7 @@ public class FieldEmitter extends JSSubEmitter implements { def = enode.resolveType(getProject()); } + IExpressionNode nameNode = node.getNameExpressionNode(); // TODO (mschmalle) if (getEmitter().getDocEmitter() instanceof IJSRoyaleDocEmitter && !isComplexInitializedStatic) @@ -159,7 +160,6 @@ public class FieldEmitter extends JSSubEmitter implements if (definition == null) definition = ndef.getContainingScope().getDefinition(); - startMapping(node.getNameExpressionNode()); className = getEmitter().formatQualifiedName(definition.getQualifiedName()); if (isComplexInitializedStatic) { @@ -167,22 +167,40 @@ public class FieldEmitter extends JSSubEmitter implements } else { - write(className - + ASEmitterTokens.MEMBER_ACCESS.getToken() + root); - String qname = node.getName(); + startMapping(nameNode); + write(className); + write(ASEmitterTokens.MEMBER_ACCESS.getToken()); + write(root); + endMapping(nameNode); + String nodeName = node.getName(); + String qname = nodeName; IDefinition nodeDef = node.getDefinition(); if (nodeDef != null && !nodeDef.isStatic() && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts()) - qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname); + { + qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname); + } - if (EmitterUtils.isCustomNamespace(node.getNamespace())) { + if (EmitterUtils.isCustomNamespace(node.getNamespace())) + { INamespaceDecorationNode ns = ((VariableNode) node).getNamespaceNode(); INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(getProject()); fjs.formatQualifiedName(nsDef.getQualifiedName()); // register with used names String s = nsDef.getURI(); + startMapping(nameNode, node.getName()); write(JSRoyaleEmitter.formatNamespacedProperty(s, qname, false)); + endMapping(nameNode); } - else write(qname); - endMapping(node.getNameExpressionNode()); + else + { + String symbolName = null; + if (!qname.equals(nodeName)) + { + symbolName = nodeName; + } + startMapping(nameNode, symbolName); + write(qname); + endMapping(nameNode); + } } } @@ -236,10 +254,10 @@ public class FieldEmitter extends JSSubEmitter implements (!ndef.isStatic() && EmitterUtils.isScalar(vnode)) || isPackageOrFileMember) { - IExpressionNode beforeNode = node.getVariableTypeNode(); + IExpressionNode beforeNode = enode; if (beforeNode.getAbsoluteStart() == -1) { - beforeNode = node.getNameExpressionNode(); + beforeNode = nameNode; } startMapping(node, beforeNode); write(ASEmitterTokens.SPACE); @@ -371,10 +389,10 @@ public class FieldEmitter extends JSSubEmitter implements private void emitComplexInitializedStatic(IVariableNode node, String className, IDefinition variableTypeExprDef) { JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter(); IExpressionNode vnode = node.getAssignedValueNode(); + IExpressionNode nameNode = node.getNameExpressionNode(); write(className); write(ASEmitterTokens.MEMBER_ACCESS.getToken()); write(fjs.formatGetter(getFieldName(node, fjs))); - endMapping(node.getNameExpressionNode()); write(ASEmitterTokens.SPACE); writeToken(ASEmitterTokens.EQUAL); write(ASEmitterTokens.FUNCTION); @@ -385,7 +403,9 @@ public class FieldEmitter extends JSSubEmitter implements writeToken(ASEmitterTokens.VAR); writeToken("value"); writeToken(ASEmitterTokens.EQUAL); + startMapping(vnode); write(vnodeString); + endMapping(vnode); writeNewline(ASEmitterTokens.SEMICOLON); write(IASLanguageConstants.Object); write(ASEmitterTokens.MEMBER_ACCESS); @@ -444,10 +464,23 @@ public class FieldEmitter extends JSSubEmitter implements { ((IJSRoyaleDocEmitter) getEmitter().getDocEmitter()).emitFieldDoc(node, variableTypeExprDef, getProject()); } + startMapping(node); write(className); write(ASEmitterTokens.MEMBER_ACCESS); - write(getFieldName(node, fjs)); + endMapping(node); + String symbolName = null; + String nodeName = node.getName(); + String fieldName = getFieldName(node, fjs); + if (!fieldName.equals(nodeName)) + { + symbolName = nodeName; + } + startMapping(nameNode, symbolName); + write(fieldName); + endMapping(nameNode); + startMapping(node); write(ASEmitterTokens.SEMICOLON); + endMapping(node); writeNewline(); writeNewline(); write(IASLanguageConstants.Object); diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java index bf41d0648..cab686677 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/IdentifierEmitter.java @@ -102,27 +102,14 @@ public class IdentifierEmitter extends JSSubEmitter implements { return; } - IASNode prevSibling = parentNode.getChild(0); - if(prevSibling == node) - { - startMapping(parentNode); - } - else - { - startMapping(prevSibling); - } + startMapping(node); write(getEmitter().formatQualifiedName(sname)); - if(prevSibling != node) + if (!isCustomNamespace) { - endMapping(prevSibling); - startMapping(parentNode, prevSibling); - } - if (!isCustomNamespace) { write(ASEmitterTokens.MEMBER_ACCESS); wroteMemberAccess = true; } - - endMapping(parentNode); + endMapping(node); } } else if (!NativeUtils.isNative(node.getName())) @@ -162,7 +149,9 @@ public class IdentifierEmitter extends JSSubEmitter implements wroteSelf = true; } else + { write(ASEmitterTokens.THIS); + } if (!isCustomNamespace) { write(ASEmitterTokens.MEMBER_ACCESS); @@ -172,7 +161,9 @@ public class IdentifierEmitter extends JSSubEmitter implements } else if (EmitterUtils.writeE4xFilterNode(getProject(), getModel(), node)) { + startMapping(node); write("node."); + endMapping(node); } if (generateClosure) @@ -189,7 +180,9 @@ public class IdentifierEmitter extends JSSubEmitter implements { String qname = node.getName(); if (nodeDef != null && !isStatic && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts()) + { qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname); + } write(qname); } @@ -256,55 +249,82 @@ public class IdentifierEmitter extends JSSubEmitter implements //member access expression, it shouldn't be fully qualified needsFormattedName = parentMemberAccessNode.getLeftOperandNode() == node; } - startMapping(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(); + startMapping(node, node.getName()); write(JSRoyaleEmitter.formatNamespacedProperty(ns, qname, accessWithNS)); + endMapping(node); } else { - if (!(nodeDef.getParent() instanceof IPackageDefinition)) { + if (!(nodeDef.getParent() instanceof IPackageDefinition)) + { qname = node.getName(); if (nodeDef != null && !isStatic && (nodeDef.getParent() instanceof ClassDefinition) && (!(nodeDef instanceof IParameterDefinition)) && nodeDef.isPrivate() && getProject().getAllowPrivateNameConflicts()) + { qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname); + } } + startMapping(node); 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 (NativeUtils.isSyntheticJSType(qname) && !(parentNode instanceof IFunctionCallNode)) + { getEmitter().getModel().needLanguage = true; 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 write(getEmitter().formatQualifiedName(qname)); + else + { + startMapping(node); + write(getEmitter().formatQualifiedName(qname)); + endMapping(node); + } } else if (isCustomNamespace) { String ns = ((INamespaceResolvedReference)nodeDef.getNamespaceReference()).resolveAETNamespace(getProject()).getName(); + startMapping(node, node.getName()); write(JSRoyaleEmitter.formatNamespacedProperty(ns, qname, accessWithNS)); + 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); + { + qname = getEmitter().formatPrivateName(nodeDef.getParent().getQualifiedName(), qname); + originalSymbolName = node.getName(); + } + startMapping(node, originalSymbolName, node.getLine(), node.getColumn()); write(qname); + endMapping(node); } - 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 diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java index 3e470cf96..719a96b65 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/jx/MethodEmitter.java @@ -39,6 +39,7 @@ import org.apache.royale.compiler.internal.tree.as.FunctionNode; import org.apache.royale.compiler.problems.ICompilerProblem; import org.apache.royale.compiler.projects.ICompilerProject; import org.apache.royale.compiler.tree.as.IClassNode; +import org.apache.royale.compiler.tree.as.IExpressionNode; import org.apache.royale.compiler.tree.as.IFunctionNode; import org.apache.royale.utils.ASTUtil; @@ -75,6 +76,8 @@ public class MethodEmitter extends JSSubEmitter implements && isConstructor && getModel().getImplicitBindableImplementation() == ImplicitBindableImplementation.EXTENDS; + IExpressionNode nameNode = fn.getNameExpressionNode(); + String qname = null; IFunctionDefinition.FunctionClassification classification = fn.getFunctionClassification(); if(classification == IFunctionDefinition.FunctionClassification.FILE_MEMBER || @@ -89,7 +92,7 @@ public class MethodEmitter extends JSSubEmitter implements } else { - startMapping(node.getNameExpressionNode()); + startMapping(nameNode); ITypeDefinition typeDef = EmitterUtils.getTypeDefinition(node); if (typeDef != null) { @@ -113,11 +116,11 @@ public class MethodEmitter extends JSSubEmitter implements write(ASEmitterTokens.MEMBER_ACCESS); } } + endMapping(nameNode); if (!isConstructor) { fjs.emitMemberName(node); } - endMapping(node.getNameExpressionNode()); } if (node.getMetaTags() != null) { //offset mapping by any metadata tags that will be in the first child node diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java index 72ea28a8f..a7bd7ce69 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/js/royale/JSRoyaleEmitter.java @@ -583,8 +583,6 @@ public class JSRoyaleEmitter extends JSEmitter implements IJSRoyaleEmitter if (defaults != null) { - final StringBuilder code = new StringBuilder(); - if (!EmitterUtils.hasBody(node)) { indentPush(); @@ -600,35 +598,41 @@ public class JSRoyaleEmitter extends JSEmitter implements IJSRoyaleEmitter if (pnode != null) { - code.setLength(0); - /* x = typeof y !== 'undefined' ? y : z;\n */ - code.append(pnode.getName()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(ASEmitterTokens.EQUAL.getToken()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(ASEmitterTokens.TYPEOF.getToken()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(pnode.getName()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(ASEmitterTokens.STRICT_NOT_EQUAL.getToken()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(ASEmitterTokens.SINGLE_QUOTE.getToken()); - code.append(ASEmitterTokens.UNDEFINED.getToken()); - code.append(ASEmitterTokens.SINGLE_QUOTE.getToken()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(ASEmitterTokens.TERNARY.getToken()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(pnode.getName()); - code.append(ASEmitterTokens.SPACE.getToken()); - code.append(ASEmitterTokens.COLON.getToken()); - code.append(ASEmitterTokens.SPACE.getToken()); + startMapping(pnode); + write(pnode.getName()); + write(ASEmitterTokens.SPACE.getToken()); + write(ASEmitterTokens.EQUAL.getToken()); + write(ASEmitterTokens.SPACE.getToken()); + write(ASEmitterTokens.TYPEOF.getToken()); + write(ASEmitterTokens.SPACE.getToken()); + write(pnode.getName()); + write(ASEmitterTokens.SPACE.getToken()); + write(ASEmitterTokens.STRICT_NOT_EQUAL.getToken()); + write(ASEmitterTokens.SPACE.getToken()); + write(ASEmitterTokens.SINGLE_QUOTE.getToken()); + write(ASEmitterTokens.UNDEFINED.getToken()); + write(ASEmitterTokens.SINGLE_QUOTE.getToken()); + write(ASEmitterTokens.SPACE.getToken()); + write(ASEmitterTokens.TERNARY.getToken()); + write(ASEmitterTokens.SPACE.getToken()); + write(pnode.getName()); + write(ASEmitterTokens.SPACE.getToken()); + write(ASEmitterTokens.COLON.getToken()); + write(ASEmitterTokens.SPACE.getToken()); + endMapping(pnode); IExpressionNode assignedValueNode = pnode.getAssignedValueNode(); - code.append(stringifyNode(assignedValueNode)); - code.append(ASEmitterTokens.SEMICOLON.getToken()); + if (assignedValueNode != null) + { + startMapping(assignedValueNode); + write(stringifyNode(assignedValueNode)); + endMapping(assignedValueNode); + } - write(code.toString()); + startMapping(pnode); + write(ASEmitterTokens.SEMICOLON.getToken()); + endMapping(pnode); if (i == n - 1 && !EmitterUtils.hasBody(node)) indentPop(); @@ -859,6 +863,7 @@ public class JSRoyaleEmitter extends JSEmitter implements IJSRoyaleEmitter public void emitMemberName(IDefinitionNode node) { ICompilerProject project = getWalker().getProject(); + IExpressionNode nameNode = node.getNameExpressionNode(); if (node.getNodeID() == ASTNodeID.FunctionID) { FunctionNode fn = (FunctionNode)node; @@ -868,15 +873,24 @@ public class JSRoyaleEmitter extends JSEmitter implements IJSRoyaleEmitter INamespaceDefinition nsDef = (INamespaceDefinition)ns.resolve(project); formatQualifiedName(nsDef.getQualifiedName()); // register with used names String s = nsDef.getURI(); + startMapping(nameNode, node.getName()); write(formatNamespacedProperty(s, node.getName(), true)); + endMapping(nameNode); return; } } + String symbolName = null; String qname = node.getName(); IDefinition nodeDef = node.getDefinition(); if (nodeDef != null && !nodeDef.isStatic() && nodeDef.isPrivate() && project.getAllowPrivateNameConflicts()) + { qname = formatPrivateName(nodeDef.getParent().getQualifiedName(), qname); + symbolName = node.getName(); + } + + startMapping(nameNode, symbolName); write(qname); + endMapping(nameNode); } public static String formatNamespacedProperty(String s, String propName, boolean access) { diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java index 55c3e0200..e357fb74a 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/internal/codegen/mxml/royale/MXMLRoyaleEmitter.java @@ -685,21 +685,18 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements startMapping(node, node.getLine(), node.getColumn()); } + public void startMapping(ISourceLocation node, String symbolName) + { + startMapping(node, symbolName, node.getLine(), node.getColumn()); + } + public void startMapping(ISourceLocation node, int line, int column) { - if (isBufferWrite()) - { - return; - } - if (lastMapping != null) - { - FilePosition sourceStartPosition = lastMapping.sourceStartPosition; - throw new IllegalStateException("Cannot start new mapping when another mapping is already started. " - + "Previous mapping at Line " + sourceStartPosition.getLine() - + " and Column " + sourceStartPosition.getColumn() - + " in file " + lastMapping.sourcePath); - } + startMapping(node, null, line, column); + } + public void startMapping(ISourceLocation node, String symbolName, int line, int column) + { String sourcePath = node.getSourcePath(); if (sourcePath == null) { @@ -717,9 +714,27 @@ public class MXMLRoyaleEmitter extends MXMLEmitter implements } } } + startMapping(sourcePath, symbolName, line, column); + } + + public void startMapping(String sourcePath, String symbolName, int line, int column) + { + if (isBufferWrite()) + { + return; + } + if (lastMapping != null) + { + FilePosition sourceStartPosition = lastMapping.sourceStartPosition; + throw new IllegalStateException("Cannot start new mapping when another mapping is already started. " + + "Previous mapping at Line " + sourceStartPosition.getLine() + + " and Column " + sourceStartPosition.getColumn() + + " in file " + lastMapping.sourcePath); + } SourceMapMapping mapping = new SourceMapMapping(); mapping.sourcePath = sourcePath; + mapping.name = symbolName; mapping.sourceStartPosition = new FilePosition(line, column); mapping.destStartPosition = new FilePosition(getCurrentLine(), getCurrentColumn()); lastMapping = mapping; diff --git a/compiler-jx/src/main/java/org/apache/royale/compiler/utils/SourceMapUtils.java b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/SourceMapUtils.java index ba2d9bb71..7af93ec80 100644 --- a/compiler-jx/src/main/java/org/apache/royale/compiler/utils/SourceMapUtils.java +++ b/compiler-jx/src/main/java/org/apache/royale/compiler/utils/SourceMapUtils.java @@ -205,7 +205,7 @@ public class SourceMapUtils //SourceMapGeneratorV3's appendTo() that omits the last //entry, for some reason FilePosition newEndPosition = new FilePosition(endPosition.getLine(), endPosition.getColumn() + 1); - generator.addMapping(sourceName, null, sourceStartPosition, endPosition, newEndPosition); + generator.addMapping(sourceName, symbolName, sourceStartPosition, endPosition, newEndPosition); } private static class SourceMapEntryCounter implements SourceMapConsumerV3.EntryVisitor diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapFieldMembers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapFieldMembers.java index 219f6f6c5..7c5455fb1 100644 --- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapFieldMembers.java +++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapFieldMembers.java @@ -33,7 +33,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("var foo;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @type {*}\n */\nRoyaleTest_A.prototype.foo - assertMapping(node, 0, 4, 4, 0, 4, 26); // foo + assertMapping(node, 0, 4, 4, 0, 4, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 4, 4, 23, 4, 26); // foo } @Test @@ -42,7 +43,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("var foo:String = null;"); asBlockWalker.visitVariable(node); //**\n * @package\n * @type {string}\n */\nRoyaleTest_A.prototype.foo = null - assertMapping(node, 0, 4, 4, 0, 4, 26); // foo + assertMapping(node, 0, 4, 4, 0, 4, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 4, 4, 23, 4, 26); // foo assertMapping(node, 0, 14, 4, 26, 4, 29); // = assertMapping(node, 0, 17, 4, 29, 4, 33); // null } @@ -53,7 +55,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("var foo:int;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 0 - assertMapping(node, 0, 4, 4, 0, 4, 26); // foo + assertMapping(node, 0, 4, 4, 0, 4, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 4, 4, 23, 4, 26); // foo } @Test @@ -62,7 +65,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("var foo = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @type {*}\n */\nRoyaleTest_A.prototype.foo = 420 - assertMapping(node, 0, 4, 4, 0, 4, 26); // foo + assertMapping(node, 0, 4, 4, 0, 4, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 4, 4, 23, 4, 26); // foo assertMapping(node, 0, 7, 4, 26, 4, 29); // = assertMapping(node, 0, 10, 4, 29, 4, 32); // 420 } @@ -73,7 +77,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("var foo:int = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 420 - assertMapping(node, 0, 4, 4, 0, 4, 26); // foo + assertMapping(node, 0, 4, 4, 0, 4, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 4, 4, 23, 4, 26); // foo assertMapping(node, 0, 11, 4, 26, 4, 29); // = assertMapping(node, 0, 14, 4, 29, 4, 32); // 420 } @@ -84,7 +89,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static var foo;"); asBlockWalker.visitVariable(node); ////**\n * @package\n * @type {*}\n */\nRoyaleTest_A.foo - assertMapping(node, 0, 11, 4, 0, 4, 16); // foo + assertMapping(node, 0, 11, 4, 0, 4, 13); // RoyaleTest_A. + assertMapping(node, 0, 11, 4, 13, 4, 16); // foo } @Test @@ -93,7 +99,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static var foo:int;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @type {number}\n */\nRoyaleTest_A.foo = 0 - assertMapping(node, 0, 11, 4, 0, 4, 16); // foo + assertMapping(node, 0, 11, 4, 0, 4, 13); // RoyaleTest_A. + assertMapping(node, 0, 11, 4, 13, 4, 16); // foo } @Test @@ -102,7 +109,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static var foo = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @type {*}\n */\nRoyaleTest_A.foo = 420 - assertMapping(node, 0, 11, 4, 0, 4, 16); // foo + assertMapping(node, 0, 11, 4, 0, 4, 13); // RoyaleTest_A. + assertMapping(node, 0, 11, 4, 13, 4, 16); // foo assertMapping(node, 0, 14, 4, 16, 4, 19); // = assertMapping(node, 0, 17, 4, 19, 4, 22); // 420 } @@ -113,7 +121,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static var foo:int = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @type {number}\n */\nRoyaleTest_A.foo = 420 - assertMapping(node, 0, 11, 4, 0, 4, 16); // foo + assertMapping(node, 0, 11, 4, 0, 4, 13); // RoyaleTest_A. + assertMapping(node, 0, 11, 4, 13, 4, 16); // foo assertMapping(node, 0, 18, 4, 16, 4, 19); // = assertMapping(node, 0, 21, 4, 19, 4, 22); // 420 } @@ -124,7 +133,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("const foo;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {*}\n */\nRoyaleTest_A.prototype.foo - assertMapping(node, 0, 6, 5, 0, 5, 26); // foo + assertMapping(node, 0, 6, 5, 0, 5, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 6, 5, 23, 5, 26); // foo } @Test @@ -133,7 +143,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("const foo:int;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 0 - assertMapping(node, 0, 6, 5, 0, 5, 26); // foo + assertMapping(node, 0, 6, 5, 0, 5, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 6, 5, 23, 5, 26); // foo } @Test @@ -142,7 +153,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("const foo = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {*}\n */\nRoyaleTest_A.prototype.foo = 420 - assertMapping(node, 0, 6, 5, 0, 5, 26); // foo + assertMapping(node, 0, 6, 5, 0, 5, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 6, 5, 23, 5, 26); // foo assertMapping(node, 0, 9, 5, 26, 5, 29); // = assertMapping(node, 0, 12, 5, 29, 5, 32); // 420 } @@ -153,7 +165,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("const foo:int = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {number}\n */\nRoyaleTest_A.prototype.foo = 420 - assertMapping(node, 0, 6, 5, 0, 5, 26); // foo + assertMapping(node, 0, 6, 5, 0, 5, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 6, 5, 23, 5, 26); // foo assertMapping(node, 0, 13, 5, 26, 5, 29); // = assertMapping(node, 0, 16, 5, 29, 5, 32); // 420 } @@ -164,7 +177,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static const foo;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {*}\n */\nRoyaleTest_A.foo - assertMapping(node, 0, 13, 5, 0, 5, 16); // foo + assertMapping(node, 0, 13, 5, 0, 5, 13); // RoyaleTest_A. + assertMapping(node, 0, 13, 5, 13, 5, 16); // foo } @Test @@ -173,7 +187,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static const foo:int;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {number}\n */\nRoyaleTest_A.foo = 0 - assertMapping(node, 0, 13, 5, 0, 5, 16); // foo + assertMapping(node, 0, 13, 5, 0, 5, 13); // RoyaleTest_A. + assertMapping(node, 0, 13, 5, 13, 5, 16); // foo } @Test @@ -182,7 +197,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static const foo = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {*}\n */\nRoyaleTest_A.foo = 420 - assertMapping(node, 0, 13, 5, 0, 5, 16); // foo + assertMapping(node, 0, 13, 5, 0, 5, 13); // RoyaleTest_A. + assertMapping(node, 0, 13, 5, 13, 5, 16); // foo assertMapping(node, 0, 16, 5, 16, 5, 19); // = assertMapping(node, 0, 19, 5, 19, 5, 22); // 420 } @@ -193,7 +209,8 @@ public class TestSourceMapFieldMembers extends SourceMapTestBase IVariableNode node = getField("static const foo:int = 420;"); asBlockWalker.visitVariable(node); ///**\n * @package\n * @const\n * @type {number}\n */\nRoyaleTest_A.foo = 420 - assertMapping(node, 0, 13, 5, 0, 5, 16); // foo + assertMapping(node, 0, 13, 5, 0, 5, 13); // RoyaleTest_A. + assertMapping(node, 0, 13, 5, 13, 5, 16); // foo assertMapping(node, 0, 20, 5, 16, 5, 19); // = assertMapping(node, 0, 23, 5, 19, 5, 22); // 420 } diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapMethodMembers.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapMethodMembers.java new file mode 100644 index 000000000..a0933567f --- /dev/null +++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/codegen/js/sourcemaps/TestSourceMapMethodMembers.java @@ -0,0 +1,48 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.royale.compiler.internal.codegen.js.sourcemaps; + +import org.apache.royale.compiler.driver.IBackend; +import org.apache.royale.compiler.internal.driver.js.royale.RoyaleBackend; +import org.apache.royale.compiler.internal.test.SourceMapTestBase; +import org.apache.royale.compiler.tree.as.IFunctionNode; +import org.junit.Test; + +public class TestSourceMapMethodMembers extends SourceMapTestBase +{ + @Test + public void testMethod() + { + IFunctionNode node = getMethod("function foo(){}"); + asBlockWalker.visitFunction(node); + //RoyaleTest_A.prototype.foo = function() {\n} + assertMapping(node, 0, 9, 0, 0, 0, 23); // RoyaleTest_A.prototype. + assertMapping(node, 0, 9, 0, 23, 0, 26); // foo + assertMapping(node, 0, 0, 0, 26, 0, 37); // = function + assertMapping(node, 0, 12, 0, 37, 0, 38); // ( + assertMapping(node, 0, 13, 0, 38, 0, 39); // ) + assertMapping(node, 0, 14, 0, 40, 0, 41); // { + assertMapping(node, 0, 15, 1, 0, 1, 1); // } + } + + protected IBackend createBackend() + { + return new RoyaleBackend(); + } +} diff --git a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/SourceMapTestBase.java b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/SourceMapTestBase.java index df0f30abf..9ab45387e 100644 --- a/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/SourceMapTestBase.java +++ b/compiler-jx/src/test/java/org/apache/royale/compiler/internal/test/SourceMapTestBase.java @@ -41,6 +41,12 @@ public class SourceMapTestBase extends ASTestBase protected void assertMapping(IASNode node, int nodeStartLine, int nodeStartColumn, int outStartLine, int outStartColumn, int outEndLine, int outEndColumn) + { + assertMapping(node, nodeStartLine, nodeStartColumn, outStartLine, outStartColumn, outEndLine, outEndColumn, null); + } + + protected void assertMapping(IASNode node, int nodeStartLine, int nodeStartColumn, + int outStartLine, int outStartColumn, int outEndLine, int outEndColumn, String symbolName) { int sourceStartLine = nodeStartLine + node.getLine(); int sourceStartColumn = nodeStartColumn; @@ -60,14 +66,39 @@ public class SourceMapTestBase extends ASTestBase && startPosition.getLine() == outStartLine && startPosition.getColumn() == outStartColumn && endPosition.getLine() == outEndLine - && endPosition.getColumn() == outEndColumn) + && endPosition.getColumn() == outEndColumn + && ((symbolName == null && mapping.name == null) || (symbolName != null && symbolName.equals(mapping.name)))) { foundMapping = true; break; } } + // uncomment for debugging + // if (!foundMapping) + // { + // System.err.println("generated code:"); + // System.err.println(writer.toString()); + // System.err.println("expected mapping:"); + // System.err.println(" name: " + symbolName); + // System.err.println(" node: " + nodeStartLine + ", " + nodeStartColumn); + // System.err.println(" source: " + sourceStartLine + ", " + sourceStartColumn); + // System.err.println(" start: " + outStartLine + ", " + outStartColumn); + // System.err.println(" end: " + outEndLine + ", " + outEndColumn); + // for (int i = 0; i < mappings.size(); i++) + // { + // IMappingEmitter.SourceMapMapping mapping = mappings.get(i); + // System.err.println("actual mapping (" + i + "):"); + // FilePosition sourcePosition = mapping.sourceStartPosition; + // FilePosition startPosition = mapping.destStartPosition; + // FilePosition endPosition = mapping.destEndPosition; + // System.err.println(" name: " + mapping.name); + // System.err.println(" source: " + sourcePosition.getLine() + ", " + sourcePosition.getColumn()); + // System.err.println(" start: " + startPosition.getLine() + ", " + startPosition.getColumn()); + // System.err.println(" end: " + endPosition.getLine() + ", " + endPosition.getColumn()); + // } + // } assertTrue("Mapping not found for node " + node.getNodeID() + ". Expected " - + "source: (" + nodeStartLine + ", " + nodeStartColumn + "), dest: (" + outStartLine + ", " + outStartColumn + ") to (" + outEndLine + ", " + outEndColumn + ")", + + "source: (" + nodeStartLine + ", " + nodeStartColumn + "), dest: (" + outStartLine + ", " + outStartColumn + ") to (" + outEndLine + ", " + outEndColumn + "), name: " + symbolName, foundMapping); }
