You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@royale.apache.org by jo...@apache.org on 2024/07/25 17:14:01 UTC
(royale-compiler) 01/03: compiler-jx: source map improvements
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 <jo...@apache.org>
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);
}
Re: (royale-compiler) 01/03: compiler-jx: source map improvements
Posted by Josh Tynjala <jo...@bowlerhat.dev>.
I plan to do some more work on this in August. It's not quite ready yet.
--
Josh Tynjala
Bowler Hat LLC <https://bowlerhat.dev>
On Fri, Jul 26, 2024 at 5:22 AM Harbs <ha...@gmail.com> wrote:
> Josh, it looks like you did some work on source map names. Is there
> something ready to test yet?
>
> Thanks,
> Harbs
>
> > On Jul 25, 2024, at 8:14 PM, joshtynjala@apache.org wrote:
> >
> > 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 <jo...@apache.org>
> > 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);
> > }
> >
> >
>
>
Re: (royale-compiler) 01/03: compiler-jx: source map improvements
Posted by Harbs <ha...@gmail.com>.
Josh, it looks like you did some work on source map names. Is there something ready to test yet?
Thanks,
Harbs
> On Jul 25, 2024, at 8:14 PM, joshtynjala@apache.org wrote:
>
> 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 <jo...@apache.org>
> 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);
> }
>
>