34
34
import com .google .javascript .jscomp .GlobalNamespace .Ref ;
35
35
import com .google .javascript .jscomp .NodeTraversal .AbstractPostOrderCallback ;
36
36
import com .google .javascript .jscomp .NodeTraversal .ExternsSkippingCallback ;
37
- import com .google .javascript .jscomp .Normalize .PropagateConstantPropertyOverVars ;
38
37
import com .google .javascript .jscomp .base .format .SimpleFormat ;
39
38
import com .google .javascript .jscomp .deps .ModuleLoader .ResolutionMode ;
40
39
import com .google .javascript .jscomp .diagnostic .LogFile ;
@@ -236,25 +235,13 @@ private void performMinimalInliningAndModuleExportCollapsing(Node externs, Node
236
235
// and reuse that one instead.
237
236
namespace = new GlobalNamespace (decisionsLog , compiler , root );
238
237
new CollapseProperties ().process (externs , root );
239
-
240
- namespace = null ; // free up memory before PropagateConstantPropertyOverVars
241
- // This shouldn't be necessary, this pass should already be setting new constants as
242
- // constant.
243
- // TODO(b/64256754): Investigate.
244
- new PropagateConstantPropertyOverVars (compiler , false ).process (externs , root );
245
238
}
246
239
247
240
private void performAggressiveInliningAndCollapsing (Node externs , Node root ) {
248
241
new ConcretizeStaticInheritanceForInlining (compiler ).process (externs , root );
249
242
new AggressiveInlineAliases ().process (externs , root );
250
243
251
244
new CollapseProperties ().process (externs , root );
252
-
253
- namespace = null ; // free up memory before PropagateConstantPropertyOverVars
254
- // This shouldn't be necessary, this pass should already be setting new constants as
255
- // constant.
256
- // TODO(b/64256754): Investigate.
257
- new PropagateConstantPropertyOverVars (compiler , false ).process (externs , root );
258
245
}
259
246
260
247
private void performAggressiveInliningForTest (Node externs , Node root ) {
@@ -1082,6 +1069,7 @@ private Node expandObjectPattern(
1082
1069
checkState (keyChild .isObjectPattern ());
1083
1070
String uniqueId = t .getCompiler ().getUniqueIdSupplier ().getUniqueId (t .getInput ());
1084
1071
nameNode = IR .name ("destructuring$" + uniqueId ).srcref (keyChild );
1072
+ nameNode .putBooleanProp (Node .IS_CONSTANT_NAME , true );
1085
1073
}
1086
1074
Node newRhs = IR .getprop (rhs .cloneTree (), key .getString ()).srcref (keyChild );
1087
1075
Node newConstNode = IR .constNode (nameNode , newRhs ).srcref (objectPattern );
@@ -1543,6 +1531,22 @@ private void flattenSimpleStubDeclaration(Name name, String alias) {
1543
1531
compiler .reportChangeToEnclosingScope (varNode );
1544
1532
}
1545
1533
1534
+ /**
1535
+ * Returns whether a NAME node with the given {@code collapsedName}, for a name originally
1536
+ * declared at {@code declarationNode}, should be annotated with {@link Node#IS_CONSTANT_NAME}
1537
+ *
1538
+ * <p>Validity checks in unit tests will otherwise throw an exception.
1539
+ */
1540
+ private boolean shouldAddConstantName (Node declarationNode , String collapsedName ) {
1541
+ if (declarationNode == null ) {
1542
+ return false ;
1543
+ }
1544
+ JSDocInfo info = NodeUtil .getBestJSDocInfo (declarationNode .getParent ());
1545
+ return (info != null && info .isConstant ())
1546
+ || declarationNode .getBooleanProp (Node .IS_CONSTANT_NAME )
1547
+ || compiler .getCodingConvention ().isConstant (collapsedName );
1548
+ }
1549
+
1546
1550
/**
1547
1551
* Flattens all references to a collapsible property of a global name except its initial
1548
1552
* definition.
@@ -1552,6 +1556,9 @@ private void flattenSimpleStubDeclaration(Name name, String alias) {
1552
1556
*/
1553
1557
private void flattenReferencesTo (Name n , String alias ) {
1554
1558
String originalName = n .getFullName ();
1559
+ boolean isConstantName =
1560
+ shouldAddConstantName (
1561
+ n .getDeclaration () != null ? n .getDeclaration ().getNode () : null , alias );
1555
1562
for (Ref r : n .getRefs ()) {
1556
1563
if (r == n .getDeclaration ()) {
1557
1564
// Declarations are handled separately.
@@ -1561,7 +1568,7 @@ private void flattenReferencesTo(Name n, String alias) {
1561
1568
// We shouldn't flatten a reference that's an object literal key, because duplicate keys
1562
1569
// show up as refs.
1563
1570
if (!NodeUtil .mayBeObjectLitKey (r .getNode ())) {
1564
- flattenNameRef (alias , r .getNode (), rParent , originalName );
1571
+ flattenNameRef (alias , r .getNode (), rParent , originalName , isConstantName );
1565
1572
} else if (r .getNode ().isStringKey () && r .getNode ().getParent ().isObjectPattern ()) {
1566
1573
Node newNode = IR .name (alias ).srcref (r .getNode ());
1567
1574
NodeUtil .copyNameAnnotations (r .getNode (), newNode );
@@ -1575,7 +1582,7 @@ private void flattenReferencesTo(Name n, String alias) {
1575
1582
// replaced with "a$b" in all occurrences of "a.b.c", "a.b.c.d", etc.
1576
1583
if (n .props != null ) {
1577
1584
for (Name p : n .props ) {
1578
- flattenPrefixes (alias , originalName + p .getBaseName (), p , 1 );
1585
+ flattenPrefixes (alias , originalName + p .getBaseName (), p , 1 , isConstantName );
1579
1586
}
1580
1587
}
1581
1588
}
@@ -1590,12 +1597,13 @@ private void flattenReferencesTo(Name n, String alias) {
1590
1597
* to n.getFullName(), but pre-computed to save on intermediate string allocation
1591
1598
* @param depth The difference in depth between the property name and the prefix name (e.g. 2)
1592
1599
*/
1593
- private void flattenPrefixes (String alias , String originalName , Name n , int depth ) {
1600
+ private void flattenPrefixes (
1601
+ String alias , String originalName , Name n , int depth , boolean isConstantName ) {
1594
1602
// Only flatten the prefix of a name declaration if the name being
1595
1603
// initialized is fully qualified (i.e. not an object literal key).
1596
1604
Ref decl = n .getDeclaration ();
1597
1605
if (decl != null && decl .getNode () != null && decl .getNode ().isGetProp ()) {
1598
- flattenNameRefAtDepth (alias , decl .getNode (), depth , originalName );
1606
+ flattenNameRefAtDepth (alias , decl .getNode (), depth , originalName , isConstantName );
1599
1607
}
1600
1608
1601
1609
for (Ref r : n .getRefs ()) {
@@ -1604,12 +1612,12 @@ private void flattenPrefixes(String alias, String originalName, Name n, int dept
1604
1612
continue ;
1605
1613
}
1606
1614
1607
- flattenNameRefAtDepth (alias , r .getNode (), depth , originalName );
1615
+ flattenNameRefAtDepth (alias , r .getNode (), depth , originalName , isConstantName );
1608
1616
}
1609
1617
1610
1618
if (n .props != null ) {
1611
1619
for (Name p : n .props ) {
1612
- flattenPrefixes (alias , originalName + p .getBaseName (), p , depth + 1 );
1620
+ flattenPrefixes (alias , originalName + p .getBaseName (), p , depth + 1 , isConstantName );
1613
1621
}
1614
1622
}
1615
1623
}
@@ -1622,7 +1630,8 @@ private void flattenPrefixes(String alias, String originalName, Name n, int dept
1622
1630
* @param depth The difference in depth between the property name and the prefix name (e.g. 2)
1623
1631
* @param originalName String version of the property name.
1624
1632
*/
1625
- private void flattenNameRefAtDepth (String alias , Node n , int depth , String originalName ) {
1633
+ private void flattenNameRefAtDepth (
1634
+ String alias , Node n , int depth , String originalName , boolean isConstantName ) {
1626
1635
// This method has to work for both GETPROP chains and, in rare cases,
1627
1636
// OBJLIT keys, possibly nested. That's why we check for children before
1628
1637
// proceeding. In the OBJLIT case, we don't need to do anything.
@@ -1635,7 +1644,7 @@ private void flattenNameRefAtDepth(String alias, Node n, int depth, String origi
1635
1644
n = n .getFirstChild ();
1636
1645
}
1637
1646
if (n .isGetProp () && n .getFirstChild ().isGetProp ()) {
1638
- flattenNameRef (alias , n .getFirstChild (), n , originalName );
1647
+ flattenNameRef (alias , n .getFirstChild (), n , originalName , isConstantName );
1639
1648
}
1640
1649
}
1641
1650
}
@@ -1647,8 +1656,10 @@ private void flattenNameRefAtDepth(String alias, Node n, int depth, String origi
1647
1656
* @param n The GETPROP node corresponding to the original name (e.g. "a.b")
1648
1657
* @param parent {@code n}'s parent
1649
1658
* @param originalName String version of the property name.
1659
+ * @param isConstantName whether to annotate with {@link Node#IS_CONSTANT_NAME}
1650
1660
*/
1651
- private void flattenNameRef (String alias , Node n , Node parent , String originalName ) {
1661
+ private void flattenNameRef (
1662
+ String alias , Node n , Node parent , String originalName , boolean isConstantName ) {
1652
1663
Preconditions .checkArgument (
1653
1664
n .isGetProp (), "Expected GETPROP, found %s. Node: %s" , n .getToken (), n );
1654
1665
@@ -1662,6 +1673,9 @@ private void flattenNameRef(String alias, Node n, Node parent, String originalNa
1662
1673
// name a$b$c
1663
1674
Node ref = NodeUtil .newName (compiler , alias , n , originalName ).copyTypeFrom (n );
1664
1675
NodeUtil .copyNameAnnotations (n , ref );
1676
+ if (isConstantName ) {
1677
+ ref .putBooleanProp (Node .IS_CONSTANT_NAME , isConstantName );
1678
+ }
1665
1679
if (NodeUtil .isNormalOrOptChainCall (parent ) && n .isFirstChildOf (parent )) {
1666
1680
// The node was a call target. We are deliberately flattening these as
1667
1681
// the "this" isn't provided by the namespace. Mark it as such:
@@ -1869,13 +1883,9 @@ private void updateGlobalNameDeclarationAtAssignNode(
1869
1883
Node nameNode =
1870
1884
NodeUtil .newName (compiler , alias , ref .getNode ().getAncestor (2 ), n .getFullName ());
1871
1885
1872
- Node constPropNode = ref .getNode ();
1873
- JSDocInfo info = NodeUtil .getBestJSDocInfo (ref .getNode ().getParent ());
1874
- nameNode .putBooleanProp (
1875
- Node .IS_CONSTANT_NAME ,
1876
- (info != null && info .hasConstAnnotation ())
1877
- || constPropNode .getBooleanProp (Node .IS_CONSTANT_NAME ));
1886
+ nameNode .putBooleanProp (Node .IS_CONSTANT_NAME , shouldAddConstantName (ref .getNode (), alias ));
1878
1887
1888
+ JSDocInfo info = NodeUtil .getBestJSDocInfo (ref .getNode ().getParent ());
1879
1889
if (info != null ) {
1880
1890
varNode .setJSDocInfo (info );
1881
1891
}
@@ -2097,14 +2107,15 @@ private void declareVariablesForObjLitValues(
2097
2107
2098
2108
String propAlias = appendPropForAlias (alias , propName );
2099
2109
Node refNode = null ;
2110
+ boolean isConstantName = shouldAddConstantName (key , propAlias );
2100
2111
if (discardKeys ) {
2101
2112
key .detach ();
2102
2113
value .detach ();
2103
2114
// Don't report a change here because the objlit has already been removed from the tree.
2104
2115
} else {
2105
2116
// Substitute a reference for the value.
2106
2117
refNode = IR .name (propAlias );
2107
- if (key . getBooleanProp ( Node . IS_CONSTANT_NAME ) ) {
2118
+ if (isConstantName ) {
2108
2119
refNode .putBooleanProp (Node .IS_CONSTANT_NAME , true );
2109
2120
}
2110
2121
@@ -2115,7 +2126,7 @@ private void declareVariablesForObjLitValues(
2115
2126
// Declare the collapsed name as a variable with the original value.
2116
2127
Node nameNode = IR .name (propAlias );
2117
2128
nameNode .addChildToFront (value );
2118
- if (key . getBooleanProp ( Node . IS_CONSTANT_NAME ) ) {
2129
+ if (isConstantName ) {
2119
2130
nameNode .putBooleanProp (Node .IS_CONSTANT_NAME , true );
2120
2131
}
2121
2132
Node newVar = IR .var (nameNode ).srcrefTreeIfMissing (key );
@@ -2174,8 +2185,14 @@ private void addStubsForUndeclaredProperties(Name n, String alias, Node parent,
2174
2185
// Determine if this is a constant var by checking the first
2175
2186
// reference to it. Don't check the declaration, as it might be null.
2176
2187
Node constPropNode = p .getFirstRef ().getNode ();
2177
- nameNode .putBooleanProp (
2178
- Node .IS_CONSTANT_NAME , constPropNode .getBooleanProp (Node .IS_CONSTANT_NAME ));
2188
+ boolean isConstantName =
2189
+ // Don't call shouldAddConstantName because it expects to see a declaration node for
2190
+ // a name, and this name is, by definition, undeclared.
2191
+ constPropNode .getBooleanProp (Node .IS_CONSTANT_NAME )
2192
+ || compiler .getCodingConvention ().isConstant (propAlias );
2193
+ if (isConstantName ) {
2194
+ nameNode .putBooleanProp (Node .IS_CONSTANT_NAME , true );
2195
+ }
2179
2196
2180
2197
compiler .reportChangeToEnclosingScope (newVar );
2181
2198
addAfter = newVar ;
0 commit comments