Skip to content

Commit 457ac52

Browse files
lauraharkercopybara-github
authored andcommitted
Fix optimizer bug inlining usages of non-constant properties
PiperOrigin-RevId: 322194564
1 parent be94031 commit 457ac52

File tree

3 files changed

+52
-37
lines changed

3 files changed

+52
-37
lines changed

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

Lines changed: 5 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,7 @@ private void collect(JSModule module, Scope scope, Node n) {
444444
type = getValueType(n.getFirstChild());
445445
break;
446446
case NAME:
447+
case GETPROP:
447448
// TODO(b/127505242): CAST parents may indicate a set.
448449
// This may be a variable get or set.
449450
switch (parent.getToken()) {
@@ -492,7 +493,9 @@ private void collect(JSModule module, Scope scope, Node n) {
492493
case ITER_REST:
493494
case OBJECT_REST:
494495
// This may be a set.
495-
if (NodeUtil.isLhsByDestructuring(n)) {
496+
// TODO(b/120303257): this should extend to qnames too, but doing
497+
// so causes invalid output. Covered in CollapsePropertiesTest
498+
if (n.isName() && NodeUtil.isLhsByDestructuring(n)) {
496499
isSet = true;
497500
type = NameType.OTHER;
498501
}
@@ -506,42 +509,12 @@ private void collect(JSModule module, Scope scope, Node n) {
506509
type = NameType.OTHER;
507510
}
508511
}
509-
name = n.getString();
510-
break;
511-
case GETPROP:
512-
// TODO(b/117673791): Merge this case with NAME case to fix.
513-
// TODO(b/120303257): Merging this case with the NAME case makes this a breaking bug.
514-
// TODO(b/127505242): CAST parents may indicate a set.
515-
// This may be a namespaced name get or set.
516-
if (parent != null) {
517-
switch (parent.getToken()) {
518-
case ASSIGN:
519-
if (parent.getFirstChild() == n) {
520-
isSet = true;
521-
type = getValueType(n.getNext());
522-
}
523-
break;
524-
case GETPROP:
525-
// This is nested in another getprop. Return and only create a Ref for the outermost
526-
// getprop in the chain.
527-
return;
528-
case INC:
529-
case DEC:
530-
case ITER_SPREAD:
531-
case OBJECT_SPREAD:
532-
break; // isSet = false, type = OTHER.
533-
default:
534-
if (NodeUtil.isAssignmentOp(parent) && parent.getFirstChild() == n) {
535-
isSet = true;
536-
type = NameType.OTHER;
537-
}
538-
}
539-
}
540512
if (!n.isQualifiedName()) {
541513
return;
542514
}
543515
name = n.getQualifiedName();
544516
break;
517+
545518
case CALL:
546519
if (isObjectHasOwnPropertyCall(n)) {
547520
String qname = n.getFirstFirstChild().getQualifiedName();

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

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,34 @@
4545
import org.junit.runner.RunWith;
4646
import org.junit.runners.JUnit4;
4747

48-
/**
49-
* Tests for {@link GlobalNamespace}.
50-
*
51-
* @author [email protected] (Nick Santos)
52-
*/
48+
/** Tests for {@link GlobalNamespace}. */
5349
@RunWith(JUnit4.class)
5450
public final class GlobalNamespaceTest {
5551

5652
@Nullable private Compiler lastCompiler = null;
5753

54+
@Test
55+
public void detectsPropertySetsInAssignmentOperators() {
56+
GlobalNamespace namespace = parse("const a = {b: 0}; a.b += 1; a.b = 2;");
57+
58+
assertThat(namespace.getSlot("a.b").getGlobalSets()).isEqualTo(3);
59+
}
60+
61+
@Test
62+
public void detectsPropertySetsInDestructuring() {
63+
GlobalNamespace namespace = parse("const a = {b: 0}; [a.b] = [1]; ({b: a.b} = {b: 2});");
64+
65+
// TODO(b/120303257): this should be 3
66+
assertThat(namespace.getSlot("a.b").getGlobalSets()).isEqualTo(1);
67+
}
68+
69+
@Test
70+
public void detectsPropertySetsInIncDecOperators() {
71+
GlobalNamespace namespace = parse("const a = {b: 0}; a.b++; a.b--;");
72+
73+
assertThat(namespace.getSlot("a.b").getGlobalSets()).isEqualTo(3);
74+
}
75+
5876
@Test
5977
public void firstGlobalAssignmentIsConsideredDeclaration() {
6078
GlobalNamespace namespace = parse("");

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,4 +652,28 @@ public void testForwardedExportNested() {
652652
" const proto = 0;",
653653
"}"));
654654
}
655+
656+
@Test
657+
public void testQualifiedNameSetViaUnaryDecrementNotInlined() {
658+
testSame(
659+
lines(
660+
"const a = {b: 0, c: 0};",
661+
"const v1 = a.b;",
662+
"a.b--;",
663+
"const v2 = a.b;",
664+
"a.b--;",
665+
"use(v1 + v2);"));
666+
}
667+
668+
@Test
669+
public void testQualifiedNameSetViaUnaryIncrementNotInlined() {
670+
testSame(
671+
lines(
672+
"const a = {b: 0};",
673+
"const v1 = a.b;",
674+
"a.b++;",
675+
"const v2 = a.b;",
676+
"a.b++;",
677+
"use(v1 + v2);"));
678+
}
655679
}

0 commit comments

Comments
 (0)