[JS] Make sourcemaps more precise wrt JS syntax

- Generate mappings for function parameters
- Don't generate debug info for dots in qualified references
- A location of a JsNameRef is considered the start of the rightmost
  name
This commit is contained in:
Sergej Jaskiewicz
2022-11-01 19:19:11 +01:00
committed by Space Team
parent 4515130bfc
commit 8efa72ca36
5 changed files with 34 additions and 15 deletions
@@ -673,10 +673,12 @@ public class JsToStringGenerationVisitor extends JsVisitor {
pushSourceInfo(x.getSource()); pushSourceInfo(x.getSource());
leftParen(); leftParen();
boolean notFirst = false; boolean notFirst = false;
sourceLocationConsumer.pushSourceInfo(null);
for (JsParameter param : x.getParameters()) { for (JsParameter param : x.getParameters()) {
notFirst = sepCommaOptSpace(notFirst); notFirst = sepCommaOptSpace(notFirst);
accept(param); accept(param);
} }
sourceLocationConsumer.popSourceInfo();
rightParen(); rightParen();
space(); space();
@@ -845,8 +847,9 @@ public class JsToStringGenerationVisitor extends JsVisitor {
} }
public void visitNameRef(@NotNull JsNameRef nameRef, boolean withQualifier) { public void visitNameRef(@NotNull JsNameRef nameRef, boolean withQualifier) {
pushSourceInfo(nameRef.getSource());
printCommentsBeforeNode(nameRef); printCommentsBeforeNode(nameRef);
p.maybeIndent();
JsExpression qualifier = nameRef.getQualifier(); JsExpression qualifier = nameRef.getQualifier();
if (qualifier != null && withQualifier) { if (qualifier != null && withQualifier) {
@@ -869,11 +872,11 @@ public class JsToStringGenerationVisitor extends JsVisitor {
p.print('.'); p.print('.');
} }
p.maybeIndent(); pushSourceInfo(nameRef.getSource());
p.print(nameRef.getIdent()); p.print(nameRef.getIdent());
popSourceInfo();
printCommentsAfterNode(nameRef); printCommentsAfterNode(nameRef);
popSourceInfo();
} }
@Override @Override
@@ -1004,7 +1007,9 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override @Override
public void visitParameter(@NotNull JsParameter x) { public void visitParameter(@NotNull JsParameter x) {
pushSourceInfo(x.getSource());
nameOf(x); nameOf(x);
popSourceInfo();
} }
@Override @Override
@@ -589,7 +589,7 @@ public class JsAstMapper {
while (fromParamNode != null) { while (fromParamNode != null) {
String fromParamName = fromParamNode.getString(); String fromParamName = fromParamNode.getString();
JsName name = scopeContext.localNameFor(fromParamName); JsName name = scopeContext.localNameFor(fromParamName);
toFn.getParameters().add(new JsParameter(name)); toFn.getParameters().add(withLocation(new JsParameter(name), fromParamNode));
fromParamNode = fromParamNode.getNext(); fromParamNode = fromParamNode.getNext();
} }
@@ -1132,17 +1132,28 @@ public class JsAstMapper {
if (astNode == null) return null; if (astNode == null) return null;
CodePosition location = node.getPosition(); CodePosition location = node.getPosition();
// For functions, consider their location to be at the opening parenthesis. switch (node.getType()) {
if (node.getType() == TokenStream.FUNCTION) { case TokenStream.FUNCTION:
Node c = node.getFirstChild(); // For functions, consider their location to be at the opening parenthesis.
while (c != null && c.getType() != TokenStream.LP) Node c = node.getFirstChild();
c = c.getNext(); while (c != null && c.getType() != TokenStream.LP)
if (c != null && c.getPosition() != null) c = c.getNext();
location = c.getPosition(); if (c != null && c.getPosition() != null)
location = c.getPosition();
break;
case TokenStream.GETPROP:
// For dot-qualified references, consider their position to be at the rightmost name reference.
location = node.getLastChild().getPosition();
break;
} }
if (location != null) { if (location != null) {
JsLocation jsLocation = new JsLocation(fileName, location.getLine(), location.getOffset()); String originalName = null;
if (astNode instanceof JsFunction || astNode instanceof JsVars.JsVar || astNode instanceof JsParameter) {
JsName name = ((HasName) astNode).getName();
originalName = name != null ? name.toString() : null;
}
JsLocation jsLocation = new JsLocation(fileName, location.getLine(), location.getOffset(), originalName);
if (astNode instanceof SourceInfoAwareJsNode) { if (astNode instanceof SourceInfoAwareJsNode) {
astNode.setSource(jsLocation); astNode.setSource(jsLocation);
} }
@@ -203,6 +203,10 @@ public class Node implements Cloneable {
return first; return first;
} }
public Node getLastChild() {
return last;
}
public Node getNext() { public Node getNext() {
return next; return next;
} }
@@ -228,10 +228,9 @@ public class Parser {
if (!ts.matchToken(TokenStream.GWT)) { if (!ts.matchToken(TokenStream.GWT)) {
do { do {
CodePosition namePosition = ts.tokenPosition;
mustMatchToken(ts, TokenStream.NAME, "msg.no.parm"); mustMatchToken(ts, TokenStream.NAME, "msg.no.parm");
String s = ts.getString(); String s = ts.getString();
args.addChildToBack(nf.createName(s, namePosition)); args.addChildToBack(nf.createName(s, ts.tokenPosition));
} }
while (ts.matchToken(TokenStream.COMMA)); while (ts.matchToken(TokenStream.COMMA));
@@ -106,9 +106,9 @@ class SourceMapLocationRemapper(private val sourceMap: SourceMap, private val so
handleNode(invocation, invocation.qualifier, *invocation.arguments.toTypedArray()) handleNode(invocation, invocation.qualifier, *invocation.arguments.toTypedArray())
override fun visitFunction(x: JsFunction) { override fun visitFunction(x: JsFunction) {
nodeList += x
x.parameters.forEach { accept(it) } x.parameters.forEach { accept(it) }
x.body.statements.forEach { accept(it) } x.body.statements.forEach { accept(it) }
nodeList += x
} }
override fun visitElement(node: JsNode) { override fun visitElement(node: JsNode) {