Skip to content

Commit

Permalink
Rollback "Clean up some CollapseProperties logic."
Browse files Browse the repository at this point in the history
broke Google projects

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=174249406
  • Loading branch information
lauraharker authored and brad4d committed Nov 2, 2017
1 parent 46104a8 commit eeb661b
Showing 1 changed file with 87 additions and 44 deletions.
131 changes: 87 additions & 44 deletions src/com/google/javascript/jscomp/CollapseProperties.java
Expand Up @@ -400,62 +400,103 @@ 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()) {
updateGlobalNameDeclaration(n, alias, canCollapseChildNames); updateObjLitOrFunctionDeclaration(n, alias, canCollapseChildNames);
} }


if (n.props == null) { if (n.props == null) {
return; return;
} }
for (Name p : n.props) { for (Name p : n.props) {
collapseDeclarationOfNameAndDescendants(p, appendPropForAlias(alias, p.getBaseName())); // Recur first so that saved node ancestries are intact when needed.
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 adding a VAR stub and collapsing the property. e.g. c = a.b = 1; => var a$b; c = a$b = 1; * by changing it to a variable declaration (e.g. a.b = 1 -> var a$b = 1).
* This specifically handles "twinned" assignments, which are those where the assignment is also * The property's value may either be a primitive or an object literal or
* used as a reference and which need special handling. * function whose properties aren't collapsible.
* *
* @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 updated * @param ref An object containing information about the assignment getting
* updated
*/ */
private void updateTwinnedDeclaration(String alias, Name refName, Ref ref) { private void updateSimpleDeclaration(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 = Node nameNode = NodeUtil.newName(compiler, alias, grandparent.getFirstChild(),
NodeUtil.newName(compiler, alias, grandparent.getFirstChild(), refName.getFullName()); refName.getFullName());
NodeUtil.copyNameAnnotations(ref.node.getLastChild(), nameNode); NodeUtil.copyNameAnnotations(ref.node.getLastChild(), nameNode);


// BEFORE: if (grandparent.isExprResult()) {
// ... (x.y = 3); // BEFORE: a.b.c = ...;
// // exprstmt
// AFTER: // assign
// var x$y; // getprop
// ... (x$y = 3); // getprop

// name a
Node current = grandparent; // string b
Node currentParent = grandparent.getParent(); // string c
for (; // NODE
!currentParent.isScript() && !currentParent.isNormalBlock(); // AFTER: var a$b$c = ...;
current = currentParent, currentParent = currentParent.getParent()) {} // var

// name a$b$c
// Create a stub variable declaration right // NODE
// before the current statement.
Node stubVar = IR.var(nameNode.cloneTree()).useSourceInfoIfMissingFrom(nameNode); // Remove the r-value (NODE).
currentParent.addChildBefore(stubVar, current); parent.removeChild(rvalue);

nameNode.addChildToFront(rvalue);
parent.replaceChild(ref.node, nameNode);
compiler.reportChangeToEnclosingScope(nameNode); Node varNode = IR.var(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 @@ -477,7 +518,7 @@ private void updateTwinnedDeclaration(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 updateGlobalNameDeclaration( private void updateObjLitOrFunctionDeclaration(
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 @@ -486,18 +527,24 @@ private void updateGlobalNameDeclaration(
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:
updateGlobalNameDeclarationAtAssignNode( updateObjLitOrFunctionDeclarationAtAssignNode(
n, alias, canCollapseChildNames); n, alias, canCollapseChildNames);
break; break;
case VAR: case VAR:
case LET: case LET:
case CONST: case CONST:
updateGlobalNameDeclarationAtVariableNode(n, canCollapseChildNames); updateObjLitOrFunctionDeclarationAtVariableNode(n, canCollapseChildNames);
break; break;
case FUNCTION: case FUNCTION:
updateGlobalNameDeclarationAtFunctionNode(n, canCollapseChildNames); updateFunctionDeclarationAtFunctionNode(n, canCollapseChildNames);
break; break;
default: default:
break; break;
Expand All @@ -507,12 +554,12 @@ private void updateGlobalNameDeclaration(
/** /**
* 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 #updateGlobalNameDeclaration}. * {@link #updateObjLitOrFunctionDeclaration}.
* *
* @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 updateGlobalNameDeclarationAtAssignNode( private void updateObjLitOrFunctionDeclarationAtAssignNode(
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 @@ -523,10 +570,6 @@ private void updateGlobalNameDeclarationAtAssignNode(
// 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 @@ -613,11 +656,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 #updateGlobalNameDeclaration}. * node. See comment for {@link #updateObjLitOrFunctionDeclaration}.
* *
* @param n An object representing a global name (e.g. "a") * @param n An object representing a global name (e.g. "a")
*/ */
private void updateGlobalNameDeclarationAtVariableNode( private void updateObjLitOrFunctionDeclarationAtVariableNode(
Name n, boolean canCollapseChildNames) { Name n, boolean canCollapseChildNames) {
if (!canCollapseChildNames) { if (!canCollapseChildNames) {
return; return;
Expand Down Expand Up @@ -654,11 +697,11 @@ private void updateGlobalNameDeclarationAtVariableNode(
/** /**
* 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 #updateGlobalNameDeclaration}. * {@link #updateObjLitOrFunctionDeclaration}.
* *
* @param n An object representing a global name (e.g. "a") * @param n An object representing a global name (e.g. "a")
*/ */
private void updateGlobalNameDeclarationAtFunctionNode( private void updateFunctionDeclarationAtFunctionNode(
Name n, boolean canCollapseChildNames) { Name n, boolean canCollapseChildNames) {
if (!canCollapseChildNames || !n.canCollapse()) { if (!canCollapseChildNames || !n.canCollapse()) {
return; return;
Expand Down

0 comments on commit eeb661b

Please sign in to comment.