Skip to content

Commit eaf5ec7

Browse files
lauraharkercopybara-github
authored andcommitted
Make GlobalNamespace.Name.Ref's 'type' field private and add more accessors
Aside from encapsulation being good practice in Java, this simplifies a followup CL adding more values to the GlobalNamespace.Name.Ref enum. PiperOrigin-RevId: 499278964
1 parent abf6c0e commit eaf5ec7

File tree

3 files changed

+87
-54
lines changed

3 files changed

+87
-54
lines changed

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

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2300,10 +2300,11 @@ private static boolean isQnameDeclarationWithoutAssignment(@Nullable Node node)
23002300
* A global name reference. Contains references to the relevant parse tree node and its ancestors
23012301
* that may be affected.
23022302
*/
2303-
static class Ref implements StaticRef {
2303+
static final class Ref implements StaticRef {
23042304

23052305
// Note: we are more aggressive about collapsing @enum and @constructor
23062306
// declarations than implied here, see Name#canCollapse
2307+
// Non-private for testing
23072308
enum Type {
23082309
/**
23092310
* Set in the scope in which a name is declared, either the global scope or a module scope:
@@ -2342,7 +2343,7 @@ enum Type {
23422343
// Not final because CollapseProperties needs to update the namespace in-place.
23432344
private Node node;
23442345
final Name name;
2345-
final Type type;
2346+
private final Type type;
23462347
/**
23472348
* The scope in which the reference is resolved. Note that for ALIASING_GETS like "var x = ns;"
23482349
* this scope may not be the correct hoist scope of the aliasing VAR.
@@ -2391,10 +2392,48 @@ Ref getTwin() {
23912392
return twin;
23922393
}
23932394

2395+
boolean isDeleteProp() {
2396+
return this.type == Type.DELETE_PROP;
2397+
}
2398+
2399+
boolean isSubclassingGet() {
2400+
return this.type == Type.SUBCLASSING_GET;
2401+
}
2402+
2403+
/**
2404+
* Whether this is a "twin" ref, i.e. a ref that is both a get and a set.
2405+
*
2406+
* <p>Example: `a.b` from `x = a.b = 0;`
2407+
*/
2408+
boolean isTwin() {
2409+
return this.twin != null;
2410+
}
2411+
2412+
boolean isGet() {
2413+
switch (this.type) {
2414+
case DIRECT_GET:
2415+
case ALIASING_GET:
2416+
case SUBCLASSING_GET:
2417+
case CALL_GET:
2418+
case PROTOTYPE_GET:
2419+
return true;
2420+
default:
2421+
return false;
2422+
}
2423+
}
2424+
2425+
boolean isAliasingGet() {
2426+
return this.type == Type.ALIASING_GET;
2427+
}
2428+
23942429
boolean isSet() {
23952430
return type == Type.SET_FROM_GLOBAL || type == Type.SET_FROM_LOCAL;
23962431
}
23972432

2433+
boolean isSetFromGlobal() {
2434+
return this.type == Type.SET_FROM_GLOBAL;
2435+
}
2436+
23982437
@Override
23992438
public String toString() {
24002439
return MoreObjects.toStringHelper(this)

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

Lines changed: 44 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -370,17 +370,15 @@ private void inlineAliasesForName(Name name, GlobalNamespace namespace) {
370370
List<Ref> refs = new ArrayList<>(name.getRefs());
371371
for (Ref ref : refs) {
372372
Scope hoistScope = ref.scope.getClosestHoistScope();
373-
if (ref.type == Ref.Type.ALIASING_GET && !mayBeGlobalAlias(ref) && ref.getTwin() == null) {
373+
if (ref.isAliasingGet() && !mayBeGlobalAlias(ref) && !ref.isTwin()) {
374374
// {@code name} meets condition (c). Try to inline it.
375375
// TODO(johnlenz): consider picking up new aliases at the end
376376
// of the pass instead of immediately like we do for global
377377
// inlines.
378378
inlineAliasIfPossible(name, ref, namespace);
379-
} else if (ref.type == Ref.Type.ALIASING_GET
380-
&& hoistScope.isGlobal()
381-
&& ref.getTwin() == null) { // ignore aliases in chained assignments
379+
} else if (ref.isAliasingGet() && hoistScope.isGlobal() && !ref.isTwin()) {
382380
inlineGlobalAliasIfPossible(name, ref, namespace);
383-
} else if (name.isClass() && ref.type == Ref.Type.SUBCLASSING_GET && name.props != null) {
381+
} else if (name.isClass() && ref.isSubclassingGet() && name.props != null) {
384382
for (Name prop : name.props) {
385383
rewriteAllSubclassInheritedAccesses(name, ref, prop, namespace);
386384
}
@@ -494,7 +492,7 @@ private boolean rewriteAllSubclassInheritedAccesses(
494492
Name subclassNameObj = namespace.getOwnSlot(subclassName);
495493
if (subclassNameObj != null && subclassNameObj.subclassingGetCount() > 0) {
496494
for (Ref ref : subclassNameObj.getRefs()) {
497-
if (ref.type == Ref.Type.SUBCLASSING_GET) {
495+
if (ref.isSubclassingGet()) {
498496
rewriteAllSubclassInheritedAccesses(superclassNameObj, ref, prop, namespace);
499497
}
500498
}
@@ -763,7 +761,7 @@ private void inlineGlobalAliasIfPossible(Name name, Ref alias, GlobalNamespace n
763761
// Rewrite the initialization of the alias, unless this is an unsafe alias inline
764762
// caused by an @constructor. In that case, we need to leave the initialization around.
765763
Ref aliasDeclaration = aliasingName.getDeclaration();
766-
if (aliasDeclaration.getTwin() != null) {
764+
if (aliasDeclaration.isTwin()) {
767765
// This is in a nested assign.
768766
// Replace
769767
// a.b = aliasing.name = aliased.name
@@ -797,42 +795,39 @@ private void rewriteAliasReferences(
797795
Name aliasingName, Ref aliasingRef, Set<AstChange> newNodes) {
798796
List<Ref> refs = new ArrayList<>(aliasingName.getRefs());
799797
for (Ref ref : refs) {
800-
switch (ref.type) {
801-
case SET_FROM_GLOBAL:
802-
continue;
803-
case DIRECT_GET:
804-
case ALIASING_GET:
805-
case PROTOTYPE_GET:
806-
case CALL_GET:
807-
case SUBCLASSING_GET:
808-
if (ref.getTwin() != null) {
809-
// The reference is the left-hand side of a nested assignment. This means we store two
810-
// separate 'twin' Refs with the same node of types ALIASING_GET and SET_FROM_GLOBAL.
811-
// For example, the read of `c.d` has a twin reference in
812-
// a.b = c.d = e.f;
813-
// We handle this case later.
814-
checkState(ref.type == Ref.Type.ALIASING_GET, ref);
815-
break;
816-
}
817-
if (ref.getNode().isStringKey()) {
818-
// e.g. `y` in `const {y} = x;`
819-
DestructuringGlobalNameExtractor.reassignDestructringLvalue(
820-
ref.getNode(), aliasingRef.getNode().cloneTree(), newNodes, ref, compiler);
821-
} else {
822-
// e.g. `x.y`
823-
checkState(ref.getNode().isGetProp() || ref.getNode().isName());
824-
Node newNode = aliasingRef.getNode().cloneTree();
825-
Node node = ref.getNode();
826-
newNode.srcref(node);
827-
node.replaceWith(newNode);
828-
compiler.reportChangeToEnclosingScope(newNode);
829-
newNodes.add(new AstChange(ref.scope, newNode));
830-
}
831-
aliasingName.removeRef(ref);
832-
break;
833-
default:
834-
throw new IllegalStateException();
798+
if (ref.isSetFromGlobal()) {
799+
// Handled elsewhere
800+
continue;
801+
}
802+
803+
checkState(ref.isGet(), ref); // names with local sets should not be rewritten
804+
805+
// Twin refs that are both gets and sets are handled later, with the other sets.
806+
if (ref.isTwin()) {
807+
// The reference is the left-hand side of a nested assignment. This means we store two
808+
// separate 'twin' Refs with the same node of types ALIASING_GET and SET_FROM_GLOBAL.
809+
// For example, the read of `c.d` has a twin reference in
810+
// a.b = c.d = e.f;
811+
// We handle this case later.
812+
checkState(ref.isAliasingGet(), ref);
813+
continue;
814+
}
815+
816+
if (ref.getNode().isStringKey()) {
817+
// e.g. `y` in `const {y} = x;`
818+
DestructuringGlobalNameExtractor.reassignDestructringLvalue(
819+
ref.getNode(), aliasingRef.getNode().cloneTree(), newNodes, ref, compiler);
820+
} else {
821+
// e.g. `x.y`
822+
checkState(ref.getNode().isGetProp() || ref.getNode().isName());
823+
Node newNode = aliasingRef.getNode().cloneTree();
824+
Node node = ref.getNode();
825+
newNode.srcref(node);
826+
node.replaceWith(newNode);
827+
compiler.reportChangeToEnclosingScope(newNode);
828+
newNodes.add(new AstChange(ref.scope, newNode));
835829
}
830+
aliasingName.removeRef(ref);
836831
}
837832
}
838833

@@ -1340,18 +1335,17 @@ private ImmutableSet<Name> checkNamespaces() {
13401335
if (ref == name.getDeclaration()) {
13411336
continue;
13421337
}
1343-
1344-
if (ref.type == Ref.Type.DELETE_PROP) {
1338+
if (ref.isDeleteProp()) {
13451339
if (initialized) {
13461340
warnAboutNamespaceRedefinition(name, ref);
13471341
}
1348-
} else if (ref.type == Ref.Type.SET_FROM_GLOBAL || ref.type == Ref.Type.SET_FROM_LOCAL) {
1342+
} else if (ref.isSet()) {
13491343
if (initialized && !isSafeNamespaceReinit(ref)) {
13501344
warnAboutNamespaceRedefinition(name, ref);
13511345
}
13521346

13531347
initialized = true;
1354-
} else if (ref.type == Ref.Type.ALIASING_GET) {
1348+
} else if (ref.isAliasingGet()) {
13551349
warnAboutNamespaceAliasing(name, ref);
13561350
logDecisionForName(name, "escapes");
13571351
escaped.add(name);
@@ -1475,7 +1469,7 @@ private void flattenReferencesTo(Name n, String alias) {
14751469
// 2) References inside a complex assign. (a = x.y = 0). These are
14761470
// called TWIN references, because they show up twice in the
14771471
// reference list. Only collapse the set, not the alias.
1478-
if (!NodeUtil.mayBeObjectLitKey(r.getNode()) && (r.getTwin() == null || r.isSet())) {
1472+
if (!NodeUtil.mayBeObjectLitKey(r.getNode()) && (!r.isTwin() || r.isSet())) {
14791473
flattenNameRef(alias, r.getNode(), rParent, originalName);
14801474
} else if (r.getNode().isStringKey() && r.getNode().getParent().isObjectPattern()) {
14811475
Node newNode = IR.name(alias).srcref(r.getNode());
@@ -1521,7 +1515,7 @@ private void flattenPrefixes(String alias, String originalName, Name n, int dept
15211515

15221516
// References inside a complex assign (a = x.y = 0)
15231517
// have twins. We should only flatten one of the twins.
1524-
if (r.getTwin() == null || r.isSet()) {
1518+
if (!r.isTwin() || r.isSet()) {
15251519
flattenNameRefAtDepth(alias, r.getNode(), depth, originalName);
15261520
}
15271521
}
@@ -1643,7 +1637,7 @@ private void collapseDeclarationOfNameAndDescendants(Name n, String alias, Set<N
16431637
* @param ref An object containing information about the assignment getting updated
16441638
*/
16451639
private void updateTwinnedDeclaration(String alias, Name refName, Ref ref) {
1646-
checkNotNull(ref.getTwin());
1640+
checkState(ref.isTwin(), ref);
16471641
// Don't handle declarations of an already flat name, just qualified names.
16481642
if (!ref.getNode().isGetProp()) {
16491643
return;
@@ -1760,7 +1754,7 @@ private void updateGlobalNameDeclarationAtAssignNode(
17601754
// we are only collapsing for global names.
17611755
Ref ref = n.getDeclaration();
17621756
Node rvalue = ref.getNode().getNext();
1763-
if (ref.getTwin() != null) {
1757+
if (ref.isTwin()) {
17641758
updateTwinnedDeclaration(alias, ref.name, ref);
17651759
return;
17661760
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ private void collectDefines(Node root) {
352352
private @Nullable Ref selectDefineDeclaration(Name name) {
353353
for (Ref ref : name.getRefs()) {
354354
// Make sure we don't select a local set as the declaration.
355-
if (!Ref.Type.SET_FROM_GLOBAL.equals(ref.type)) {
355+
if (!ref.isSetFromGlobal()) {
356356
continue;
357357
}
358358

@@ -582,7 +582,7 @@ private boolean hasValidValue(Define define) {
582582
private static boolean isGlobalConst(Name name) {
583583
return name.getTotalSets() == 1
584584
&& name.getDeclaration() != null
585-
&& name.getDeclaration().type.equals(Ref.Type.SET_FROM_GLOBAL);
585+
&& name.getDeclaration().isSetFromGlobal();
586586
}
587587

588588
/**

0 commit comments

Comments
 (0)