From 8efa72ca366bb6cc9d3cf3836b36a2f2059b4917 Mon Sep 17 00:00:00 2001 From: Sergej Jaskiewicz Date: Tue, 1 Nov 2022 19:19:11 +0100 Subject: [PATCH] [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 --- .../backend/JsToStringGenerationVisitor.java | 11 +++++-- .../com/google/gwt/dev/js/JsAstMapper.java | 29 +++++++++++++------ .../src/com/google/gwt/dev/js/rhino/Node.java | 4 +++ .../com/google/gwt/dev/js/rhino/Parser.java | 3 +- .../sourcemaps/SourceMapLocationRemapper.kt | 2 +- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java b/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java index 4bad325d50b..d12c6c992a0 100644 --- a/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java +++ b/js/js.ast/src/org/jetbrains/kotlin/js/backend/JsToStringGenerationVisitor.java @@ -673,10 +673,12 @@ public class JsToStringGenerationVisitor extends JsVisitor { pushSourceInfo(x.getSource()); leftParen(); boolean notFirst = false; + sourceLocationConsumer.pushSourceInfo(null); for (JsParameter param : x.getParameters()) { notFirst = sepCommaOptSpace(notFirst); accept(param); } + sourceLocationConsumer.popSourceInfo(); rightParen(); space(); @@ -845,8 +847,9 @@ public class JsToStringGenerationVisitor extends JsVisitor { } public void visitNameRef(@NotNull JsNameRef nameRef, boolean withQualifier) { - pushSourceInfo(nameRef.getSource()); + printCommentsBeforeNode(nameRef); + p.maybeIndent(); JsExpression qualifier = nameRef.getQualifier(); if (qualifier != null && withQualifier) { @@ -869,11 +872,11 @@ public class JsToStringGenerationVisitor extends JsVisitor { p.print('.'); } - p.maybeIndent(); + pushSourceInfo(nameRef.getSource()); p.print(nameRef.getIdent()); + popSourceInfo(); printCommentsAfterNode(nameRef); - popSourceInfo(); } @Override @@ -1004,7 +1007,9 @@ public class JsToStringGenerationVisitor extends JsVisitor { @Override public void visitParameter(@NotNull JsParameter x) { + pushSourceInfo(x.getSource()); nameOf(x); + popSourceInfo(); } @Override diff --git a/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java b/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java index 7050badb350..45a31ae83a1 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java +++ b/js/js.parser/src/com/google/gwt/dev/js/JsAstMapper.java @@ -589,7 +589,7 @@ public class JsAstMapper { while (fromParamNode != null) { String fromParamName = fromParamNode.getString(); JsName name = scopeContext.localNameFor(fromParamName); - toFn.getParameters().add(new JsParameter(name)); + toFn.getParameters().add(withLocation(new JsParameter(name), fromParamNode)); fromParamNode = fromParamNode.getNext(); } @@ -1132,17 +1132,28 @@ public class JsAstMapper { if (astNode == null) return null; CodePosition location = node.getPosition(); - // For functions, consider their location to be at the opening parenthesis. - if (node.getType() == TokenStream.FUNCTION) { - Node c = node.getFirstChild(); - while (c != null && c.getType() != TokenStream.LP) - c = c.getNext(); - if (c != null && c.getPosition() != null) - location = c.getPosition(); + switch (node.getType()) { + case TokenStream.FUNCTION: + // For functions, consider their location to be at the opening parenthesis. + Node c = node.getFirstChild(); + while (c != null && c.getType() != TokenStream.LP) + c = c.getNext(); + 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) { - 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) { astNode.setSource(jsLocation); } diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java b/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java index 1f9cd3f5a5b..e2f10d95aa9 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/Node.java @@ -203,6 +203,10 @@ public class Node implements Cloneable { return first; } + public Node getLastChild() { + return last; + } + public Node getNext() { return next; } diff --git a/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java b/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java index 35f8421753b..0c1d707ccc6 100644 --- a/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java +++ b/js/js.parser/src/com/google/gwt/dev/js/rhino/Parser.java @@ -228,10 +228,9 @@ public class Parser { if (!ts.matchToken(TokenStream.GWT)) { do { - CodePosition namePosition = ts.tokenPosition; mustMatchToken(ts, TokenStream.NAME, "msg.no.parm"); String s = ts.getString(); - args.addChildToBack(nf.createName(s, namePosition)); + args.addChildToBack(nf.createName(s, ts.tokenPosition)); } while (ts.matchToken(TokenStream.COMMA)); diff --git a/js/js.parser/src/org/jetbrains/kotlin/js/parser/sourcemaps/SourceMapLocationRemapper.kt b/js/js.parser/src/org/jetbrains/kotlin/js/parser/sourcemaps/SourceMapLocationRemapper.kt index 4b2374034f0..02b9e60a233 100644 --- a/js/js.parser/src/org/jetbrains/kotlin/js/parser/sourcemaps/SourceMapLocationRemapper.kt +++ b/js/js.parser/src/org/jetbrains/kotlin/js/parser/sourcemaps/SourceMapLocationRemapper.kt @@ -106,9 +106,9 @@ class SourceMapLocationRemapper(private val sourceMap: SourceMap, private val so handleNode(invocation, invocation.qualifier, *invocation.arguments.toTypedArray()) override fun visitFunction(x: JsFunction) { + nodeList += x x.parameters.forEach { accept(it) } x.body.statements.forEach { accept(it) } - nodeList += x } override fun visitElement(node: JsNode) {