break;
}
}
private void visitObjectPattern(NodeTraversal t, Node objectPattern, Node parent) {
Node rhs, nodeToDetach;
if (NodeUtil.isNameDeclaration(parent) && !NodeUtil.isEnhancedFor(parent.getParent())) {
rhs = objectPattern.getLastChild();
nodeToDetach = parent;
} else if (parent.isAssign() && parent.getParent().isExprResult()) {
rhs = parent.getLastChild();
nodeToDetach = parent.getParent();
} else if (parent.isStringKey() || parent.isArrayPattern()
|| parent.isDefaultValue()) {
// Nested object pattern; do nothing. We will visit it after rewriting the parent.
return;
} else if (NodeUtil.isEnhancedFor(parent) || NodeUtil.isEnhancedFor(parent.getParent())) {
visitDestructuringPatternInEnhancedFor(objectPattern);
return;
} else if (parent.isCatch()) {
visitDestructuringPatternInCatch(objectPattern);
return;
} else {
throw new IllegalStateException("Unexpected OBJECT_PATTERN parent: " + parent);
}
// Convert 'var {a: b, c: d} = rhs' to:
// var temp = rhs;
// var b = temp.a;
// var d = temp.c;
String tempVarName = DESTRUCTURING_TEMP_VAR + (destructuringVarCounter++);
Node tempDecl = IR.var(IR.name(tempVarName), rhs.detachFromParent())
.useSourceInfoIfMissingFromForTree(objectPattern);
nodeToDetach.getParent().addChildBefore(tempDecl, nodeToDetach);
for (Node child = objectPattern.getFirstChild(), next;
child != null;
child = next) {
next = child.getNext();
Node newLHS, newRHS;
if (child.isStringKey()) {
Preconditions.checkState(child.hasChildren());
Node getprop = new Node(child.isQuotedString() ? Token.GETELEM : Token.GETPROP,
IR.name(tempVarName),
IR.string(child.getString()));
Node value = child.removeFirstChild();
if (!value.isDefaultValue()) {
newLHS = value;
newRHS = getprop;
} else {
newLHS = value.removeFirstChild();
Node defaultValue = value.removeFirstChild();
newRHS = defaultValueHook(getprop, defaultValue);
}
} else if (child.isComputedProp()) {
if (child.getLastChild().isDefaultValue()) {
newLHS = child.getLastChild().removeFirstChild();
Node getelem = IR.getelem(
IR.name(tempVarName),
child.removeFirstChild());
String intermediateTempVarName = DESTRUCTURING_TEMP_VAR + (destructuringVarCounter++);
Node intermediateDecl = IR.var(IR.name(intermediateTempVarName), getelem);
intermediateDecl.useSourceInfoIfMissingFromForTree(child);
nodeToDetach.getParent().addChildBefore(intermediateDecl, nodeToDetach);
newRHS = defaultValueHook(
IR.name(intermediateTempVarName),
child.getLastChild().removeFirstChild());
} else {
newRHS = IR.getelem(IR.name(tempVarName), child.removeFirstChild());
newLHS = child.removeFirstChild();
}
} else if (child.isDefaultValue()) {
newLHS = child.removeFirstChild();
Node defaultValue = child.removeFirstChild();
Node getprop = IR.getprop(IR.name(tempVarName), IR.string(newLHS.getString()));
newRHS = defaultValueHook(getprop, defaultValue);
} else {
throw new IllegalStateException("Unexpected OBJECT_PATTERN child: " + child);
}
Node newNode;
if (NodeUtil.isNameDeclaration(parent)) {
newNode = IR.declaration(newLHS, newRHS, parent.getType());
} else if (parent.isAssign()) {
newNode = IR.exprResult(IR.assign(newLHS, newRHS));
} else {
throw new IllegalStateException("not reached");
}
newNode.useSourceInfoIfMissingFromForTree(child);
nodeToDetach.getParent().addChildBefore(newNode, nodeToDetach);
// Explicitly visit the LHS of the new node since it may be a nested
// destructuring pattern.