Skip to content

Commit 0715ade

Browse files
rishipalcopybara-github
authored andcommitted
Stop creating block scope for synthetic block nodes
A BLOCK marked as synthetic is not a real JS block with {} around it in the JS code. It just represents a span of statements that need to be kept together. Synthetic blocks do not exist in the source AST and hence do not create their own scope. This CL impacts the NodeTraversal class and several JSCompiler passes. PiperOrigin-RevId: 618383865
1 parent ec51a58 commit 0715ade

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

src/com/google/javascript/jscomp/CodeGenerator.java

+2
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,8 @@ protected void add(Node node, Context context, boolean printComments) {
769769
add("static");
770770
}
771771
}
772+
// A BLOCK marked as synthetic is not a real JS block with {} around it in the JS code.
773+
// It just represents a span of statements that need to be kept together.
772774
boolean preserveBlock = node.isBlock() && !node.isSyntheticBlock();
773775
if (preserveBlock) {
774776
cc.beginBlock();

src/com/google/javascript/jscomp/NodeUtil.java

+4
Original file line numberDiff line numberDiff line change
@@ -2451,6 +2451,10 @@ public static boolean isStatementBlock(Node n) {
24512451
static boolean createsBlockScope(Node n) {
24522452
switch (n.getToken()) {
24532453
case BLOCK:
2454+
if (n.isSyntheticBlock()) {
2455+
// Don't create block scope for synthetic blocks.
2456+
return false;
2457+
}
24542458
Node parent = n.getParent();
24552459
// Don't create block scope for switch cases or catch blocks.
24562460
return parent != null && !isSwitchCase(parent) && !parent.isCatch();

test/com/google/javascript/jscomp/CreateSyntheticBlocksTest.java

+15
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
*/
1616
package com.google.javascript.jscomp;
1717

18+
import static com.google.common.truth.Truth.assertThat;
19+
import static com.google.javascript.rhino.testing.NodeSubject.assertNode;
20+
1821
import com.google.javascript.jscomp.parsing.parser.FeatureSet;
1922
import com.google.javascript.rhino.Node;
2023
import org.junit.Before;
@@ -161,4 +164,16 @@ public void testVariableDeclaration1() {
161164
testSame("startMarker();let x=1;endMarker()");
162165
testSame("startMarker();const x=1;endMarker()");
163166
}
167+
168+
@Test
169+
public void testSyntheticBlock_doesNotCreateNewScope() {
170+
testSame("startMarker();var x=1;endMarker()");
171+
Node script = this.getLastCompiler().getJsRoot().getOnlyChild();
172+
assertNode(script).isScript();
173+
Node synctheticBlock = script.getFirstChild();
174+
assertNode(synctheticBlock).isBlock();
175+
assertThat(synctheticBlock.isSyntheticBlock()).isTrue();
176+
// confirm that synthetic block does not create a new block scope
177+
assertThat(NodeUtil.createsBlockScope(synctheticBlock)).isFalse();
178+
}
164179
}

0 commit comments

Comments
 (0)