Skip to content

Commit

Permalink
Clean up some CollapseProperties logic.
Browse files Browse the repository at this point in the history
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=174229266
  • Loading branch information
lauraharker authored and brad4d committed Nov 2, 2017
1 parent ab1eb56 commit 87b202b
Showing 1 changed file with 44 additions and 87 deletions.
131 changes: 44 additions & 87 deletions src/com/google/javascript/jscomp/CollapseProperties.java
Expand Up @@ -400,103 +400,62 @@ private void collapseDeclarationOfNameAndDescendants(Name n, String alias) {


// Handle this name first so that nested object literals get unrolled. // Handle this name first so that nested object literals get unrolled.
if (n.canCollapse()) { if (n.canCollapse()) {
updateObjLitOrFunctionDeclaration(n, alias, canCollapseChildNames); updateGlobalNameDeclaration(n, alias, canCollapseChildNames);
} }


if (n.props == null) { if (n.props == null) {
return; return;
} }
for (Name p : n.props) { for (Name p : n.props) {
// Recur first so that saved node ancestries are intact when needed. collapseDeclarationOfNameAndDescendants(p, appendPropForAlias(alias, p.getBaseName()));
collapseDeclarationOfNameAndDescendants(
p, appendPropForAlias(alias, p.getBaseName()));
if (!p.inExterns
&& canCollapseChildNames
&& p.getDeclaration() != null
&& p.canCollapse()
&& p.getDeclaration().node != null
&& p.getDeclaration().node.getParent() != null
&& p.getDeclaration().node.getParent().isAssign()) {
updateSimpleDeclaration(
appendPropForAlias(alias, p.getBaseName()), p, p.getDeclaration());
}
} }
} }


/** /**
* Updates the initial assignment to a collapsible property at global scope * Updates the initial assignment to a collapsible property at global scope
* by changing it to a variable declaration (e.g. a.b = 1 -> var a$b = 1). * by adding a VAR stub and collapsing the property. e.g. c = a.b = 1; => var a$b; c = a$b = 1;
* The property's value may either be a primitive or an object literal or * This specifically handles "twinned" assignments, which are those where the assignment is also
* function whose properties aren't collapsible. * used as a reference and which need special handling.
* *
* @param alias The flattened property name (e.g. "a$b") * @param alias The flattened property name (e.g. "a$b")
* @param refName The name for the reference being updated. * @param refName The name for the reference being updated.
* @param ref An object containing information about the assignment getting * @param ref An object containing information about the assignment getting updated
* updated
*/ */
private void updateSimpleDeclaration(String alias, Name refName, Ref ref) { private void updateTwinnedDeclaration(String alias, Name refName, Ref ref) {
checkNotNull(ref.getTwin());
Node rvalue = ref.node.getNext(); Node rvalue = ref.node.getNext();
Node parent = ref.node.getParent(); Node parent = ref.node.getParent();
Node grandparent = parent.getParent(); Node grandparent = parent.getParent();
Node greatGrandparent = grandparent.getParent();


if (rvalue != null && rvalue.isFunction()) { if (rvalue != null && rvalue.isFunction()) {
checkForHosedThisReferences(rvalue, refName.docInfo, refName); checkForHosedThisReferences(rvalue, refName.docInfo, refName);
} }


// Create the new alias node. // Create the new alias node.
Node nameNode = NodeUtil.newName(compiler, alias, grandparent.getFirstChild(), Node nameNode =
refName.getFullName()); NodeUtil.newName(compiler, alias, grandparent.getFirstChild(), refName.getFullName());
NodeUtil.copyNameAnnotations(ref.node.getLastChild(), nameNode); NodeUtil.copyNameAnnotations(ref.node.getLastChild(), nameNode);


if (grandparent.isExprResult()) { // BEFORE:
// BEFORE: a.b.c = ...; // ... (x.y = 3);
// exprstmt //
// assign // AFTER:
// getprop // var x$y;
// getprop // ... (x$y = 3);
// name a
// string b Node current = grandparent;
// string c Node currentParent = grandparent.getParent();
// NODE for (;
// AFTER: var a$b$c = ...; !currentParent.isScript() && !currentParent.isNormalBlock();
// var current = currentParent, currentParent = currentParent.getParent()) {}
// name a$b$c
// NODE // Create a stub variable declaration right

// before the current statement.
// Remove the r-value (NODE). Node stubVar = IR.var(nameNode.cloneTree()).useSourceInfoIfMissingFrom(nameNode);
parent.removeChild(rvalue); currentParent.addChildBefore(stubVar, current);
nameNode.addChildToFront(rvalue);

parent.replaceChild(ref.node, nameNode);
Node varNode = IR.var(nameNode); compiler.reportChangeToEnclosingScope(nameNode);
greatGrandparent.replaceChild(grandparent, varNode);
compiler.reportChangeToEnclosingScope(varNode);
} else {
// This must be a complex assignment.
checkNotNull(ref.getTwin());

// BEFORE:
// ... (x.y = 3);
//
// AFTER:
// var x$y;
// ... (x$y = 3);

Node current = grandparent;
Node currentParent = grandparent.getParent();
for (;
!currentParent.isScript() && !currentParent.isNormalBlock();
current = currentParent, currentParent = currentParent.getParent()) {}

// Create a stub variable declaration right
// before the current statement.
Node stubVar = IR.var(nameNode.cloneTree())
.useSourceInfoIfMissingFrom(nameNode);
currentParent.addChildBefore(stubVar, current);

parent.replaceChild(ref.node, nameNode);
compiler.reportChangeToEnclosingScope(nameNode);
}
} }


/** /**
Expand All @@ -518,7 +477,7 @@ private void updateSimpleDeclaration(String alias, Name refName, Ref ref) {
* this name. (This is mostly passed for convenience; it's equivalent to * this name. (This is mostly passed for convenience; it's equivalent to
* n.canCollapseChildNames()). * n.canCollapseChildNames()).
*/ */
private void updateObjLitOrFunctionDeclaration( private void updateGlobalNameDeclaration(
Name n, String alias, boolean canCollapseChildNames) { Name n, String alias, boolean canCollapseChildNames) {
Ref decl = n.getDeclaration(); Ref decl = n.getDeclaration();
if (decl == null) { if (decl == null) {
Expand All @@ -527,24 +486,18 @@ private void updateObjLitOrFunctionDeclaration(
return; return;
} }


if (decl.getTwin() != null) {
// Twin declarations will get handled when normal references
// are handled.
return;
}

switch (decl.node.getParent().getToken()) { switch (decl.node.getParent().getToken()) {
case ASSIGN: case ASSIGN:
updateObjLitOrFunctionDeclarationAtAssignNode( updateGlobalNameDeclarationAtAssignNode(
n, alias, canCollapseChildNames); n, alias, canCollapseChildNames);
break; break;
case VAR: case VAR:
case LET: case LET:
case CONST: case CONST:
updateObjLitOrFunctionDeclarationAtVariableNode(n, canCollapseChildNames); updateGlobalNameDeclarationAtVariableNode(n, canCollapseChildNames);
break; break;
case FUNCTION: case FUNCTION:
updateFunctionDeclarationAtFunctionNode(n, canCollapseChildNames); updateGlobalNameDeclarationAtFunctionNode(n, canCollapseChildNames);
break; break;
default: default:
break; break;
Expand All @@ -554,12 +507,12 @@ private void updateObjLitOrFunctionDeclaration(
/** /**
* Updates the first initialization (a.k.a "declaration") of a global name * Updates the first initialization (a.k.a "declaration") of a global name
* that occurs at an ASSIGN node. See comment for * that occurs at an ASSIGN node. See comment for
* {@link #updateObjLitOrFunctionDeclaration}. * {@link #updateGlobalNameDeclaration}.
* *
* @param n An object representing a global name (e.g. "a", "a.b.c") * @param n An object representing a global name (e.g. "a", "a.b.c")
* @param alias The flattened name for {@code n} (e.g. "a", "a$b$c") * @param alias The flattened name for {@code n} (e.g. "a", "a$b$c")
*/ */
private void updateObjLitOrFunctionDeclarationAtAssignNode( private void updateGlobalNameDeclarationAtAssignNode(
Name n, String alias, boolean canCollapseChildNames) { Name n, String alias, boolean canCollapseChildNames) {
// NOTE: It's important that we don't add additional nodes // NOTE: It's important that we don't add additional nodes
// (e.g. a var node before the exprstmt) because the exprstmt might be // (e.g. a var node before the exprstmt) because the exprstmt might be
Expand All @@ -570,6 +523,10 @@ private void updateObjLitOrFunctionDeclarationAtAssignNode(
// we are only collapsing for global names. // we are only collapsing for global names.
Ref ref = n.getDeclaration(); Ref ref = n.getDeclaration();
Node rvalue = ref.node.getNext(); Node rvalue = ref.node.getNext();
if (ref.getTwin() != null) {
updateTwinnedDeclaration(alias, ref.name, ref);
return;
}
Node varNode = new Node(Token.VAR); Node varNode = new Node(Token.VAR);
Node varParent = ref.node.getAncestor(3); Node varParent = ref.node.getAncestor(3);
Node grandparent = ref.node.getAncestor(2); Node grandparent = ref.node.getAncestor(2);
Expand Down Expand Up @@ -656,11 +613,11 @@ public void visit(NodeTraversal t, Node n, Node parent) {


/** /**
* Updates the first initialization (a.k.a "declaration") of a global name that occurs at a VAR * Updates the first initialization (a.k.a "declaration") of a global name that occurs at a VAR
* node. See comment for {@link #updateObjLitOrFunctionDeclaration}. * node. See comment for {@link #updateGlobalNameDeclaration}.
* *
* @param n An object representing a global name (e.g. "a") * @param n An object representing a global name (e.g. "a")
*/ */
private void updateObjLitOrFunctionDeclarationAtVariableNode( private void updateGlobalNameDeclarationAtVariableNode(
Name n, boolean canCollapseChildNames) { Name n, boolean canCollapseChildNames) {
if (!canCollapseChildNames) { if (!canCollapseChildNames) {
return; return;
Expand Down Expand Up @@ -697,11 +654,11 @@ private void updateObjLitOrFunctionDeclarationAtVariableNode(
/** /**
* Updates the first initialization (a.k.a "declaration") of a global name * Updates the first initialization (a.k.a "declaration") of a global name
* that occurs at a FUNCTION node. See comment for * that occurs at a FUNCTION node. See comment for
* {@link #updateObjLitOrFunctionDeclaration}. * {@link #updateGlobalNameDeclaration}.
* *
* @param n An object representing a global name (e.g. "a") * @param n An object representing a global name (e.g. "a")
*/ */
private void updateFunctionDeclarationAtFunctionNode( private void updateGlobalNameDeclarationAtFunctionNode(
Name n, boolean canCollapseChildNames) { Name n, boolean canCollapseChildNames) {
if (!canCollapseChildNames || !n.canCollapse()) { if (!canCollapseChildNames || !n.canCollapse()) {
return; return;
Expand Down

0 comments on commit 87b202b

Please sign in to comment.