[JS IR] Improve debug info precision for blocks

Namely:
- Generate debug info for closing braces, which allows the breakpoints
  set on closing braces to be hit
- Generate debug info for 'if' and 'try/catch' statements.

KT-46276
This commit is contained in:
Sergej Jaskiewicz
2022-10-13 19:15:49 +02:00
committed by Space Team
parent a1c61bb9a0
commit a939f9ccd0
129 changed files with 423 additions and 160 deletions
@@ -4,7 +4,6 @@
package org.jetbrains.kotlin.js.backend;
import com.intellij.openapi.util.text.StringUtil;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.js.backend.ast.*;
@@ -377,8 +376,8 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override
public void visitCatch(@NotNull JsCatch x) {
pushSourceInfo(x.getSource());
printCommentsBeforeNode(x);
pushSourceInfo(x.getSource());
spaceOpt();
p.print(CHARS_CATCH);
@@ -399,8 +398,8 @@ public class JsToStringGenerationVisitor extends JsVisitor {
rightParen();
spaceOpt();
printCommentsAfterNode(x);
popSourceInfo();
printCommentsAfterNode(x);
sourceLocationConsumer.pushSourceInfo(null);
accept(x.getBody());
@@ -742,8 +741,8 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override
public void visitIf(@NotNull JsIf x) {
pushSourceInfo(x.getSource());
printCommentsBeforeNode(x);
pushSourceInfo(x.getSource());
_if();
spaceOpt();
@@ -751,8 +750,8 @@ public class JsToStringGenerationVisitor extends JsVisitor {
accept(x.getIfExpression());
rightParen();
printCommentsAfterNode(x);
popSourceInfo();
printCommentsAfterNode(x);
JsStatement thenStmt = x.getThenStatement();
JsStatement elseStatement = x.getElseStatement();
@@ -1140,9 +1139,11 @@ public class JsToStringGenerationVisitor extends JsVisitor {
@Override
public void visitTry(@NotNull JsTry x) {
printCommentsBeforeNode(x);
pushSourceInfo(x.getSource());
p.print(CHARS_TRY);
spaceOpt();
lineBreakAfterBlock = false;
popSourceInfo();
accept(x.getTryBlock());
acceptList(x.getCatches());
@@ -1418,21 +1419,24 @@ public class JsToStringGenerationVisitor extends JsVisitor {
}
}
private void printJsBlock(JsBlock x, boolean finalNewline, Object closingBracketLocation) {
private void printJsBlock(JsBlock x, boolean finalNewline, @Nullable Object defaultClosingBraceLocation) {
if (!lineBreakAfterBlock) {
finalNewline = false;
lineBreakAfterBlock = true;
}
sourceLocationConsumer.pushSourceInfo(null);
printCommentsBeforeNode(x);
boolean needBraces = !x.isTransparent();
if (needBraces) {
sourceLocationConsumer.pushSourceInfo(x.getSource());
blockOpen();
sourceLocationConsumer.popSourceInfo();
}
sourceLocationConsumer.pushSourceInfo(null);
Iterator<JsStatement> iterator = x.getStatements().iterator();
while (iterator.hasNext()) {
boolean isGlobal = x.isTransparent() || globalBlocks.contains(x);
@@ -1454,7 +1458,6 @@ public class JsToStringGenerationVisitor extends JsVisitor {
accept(statement);
if (stmtIsGlobalBlock) {
//noinspection SuspiciousMethodCalls
globalBlocks.remove(statement);
}
if (needSemi) {
@@ -1494,23 +1497,28 @@ public class JsToStringGenerationVisitor extends JsVisitor {
// _blockClose() modified
p.indentOut();
if (closingBracketLocation != null) {
pushSourceInfo(closingBracketLocation);
sourceLocationConsumer.popSourceInfo();
Object closingBraceLocation = x.getClosingBraceSource();
if (closingBraceLocation == null)
closingBraceLocation = defaultClosingBraceLocation;
if (closingBraceLocation != null) {
pushSourceInfo(closingBraceLocation);
}
p.print('}');
if (closingBracketLocation != null) {
if (closingBraceLocation != null) {
popSourceInfo();
}
if (finalNewline) {
newlineOpt();
}
} else {
sourceLocationConsumer.popSourceInfo();
}
needSemi = false;
printCommentsAfterNode(x);
sourceLocationConsumer.popSourceInfo();
}
private void assignment() {
@@ -4,6 +4,7 @@
package org.jetbrains.kotlin.js.backend.ast;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.js.util.AstUtil;
import org.jetbrains.annotations.NotNull;
import com.intellij.util.SmartList;
@@ -17,6 +18,9 @@ public class JsBlock extends SourceInfoAwareJsNode implements JsStatement {
@NotNull
private final List<JsStatement> statements;
@Nullable
private Object closingBraceSource;
public JsBlock() {
this(new SmartList<JsStatement>());
}
@@ -38,6 +42,15 @@ public class JsBlock extends SourceInfoAwareJsNode implements JsStatement {
return statements;
}
@Nullable
public Object getClosingBraceSource() {
return closingBraceSource;
}
public void setClosingBraceSource(@Nullable Object closingBraceLocation) {
this.closingBraceSource = closingBraceLocation;
}
public boolean isEmpty() {
return statements.isEmpty();
}
@@ -67,6 +80,8 @@ public class JsBlock extends SourceInfoAwareJsNode implements JsStatement {
@NotNull
@Override
public JsBlock deepCopy() {
return new JsBlock(AstUtil.deepCopy(statements)).withMetadataFrom(this);
JsBlock block = new JsBlock(AstUtil.deepCopy(statements)).withMetadataFrom(this);
block.setClosingBraceSource(getClosingBraceSource());
return block;
}
}
@@ -21,6 +21,9 @@ public final class JsIf extends SourceInfoAwareJsNode implements JsStatement {
@Nullable
private JsStatement elseStatement;
@Nullable
private Object elseSource;
public JsIf(@NotNull JsExpression ifExpression, @NotNull JsStatement thenStatement, @Nullable JsStatement elseStatement) {
this.ifExpression = ifExpression;
this.thenStatement = thenStatement;