Java Code Examples for com.google.javascript.rhino.Node#replaceChild()
The following examples show how to use
com.google.javascript.rhino.Node#replaceChild() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: InlineProperties.java From astor with GNU General Public License v2.0 | 6 votes |
@Override public void visit(NodeTraversal t, Node n, Node parent) { if (n.isGetProp() && !NodeUtil.isLValue(n)) { Node target = n.getFirstChild(); String propName = n.getLastChild().getString(); PropertyInfo info = props.get(propName); if (info != null && info != INVALIDATED && isMatchingType(target, info.type)) { Node replacement = info.value.cloneTree(); if (NodeUtil.mayHaveSideEffects(n.getFirstChild(), compiler)) { replacement = IR.comma(n.removeFirstChild(), replacement).srcref(n); } parent.replaceChild(n, replacement); compiler.reportCodeChange(); } } }
Example 2
Source File: ProcessCommonJSModules.java From astor with GNU General Public License v2.0 | 6 votes |
/** * Visit require calls. Emit corresponding goog.require and rewrite require * to be a direct reference to name of require module. */ private void visitRequireCall(NodeTraversal t, Node require, Node parent) { String moduleName = toModuleName(require.getChildAtIndex(1).getString(), normalizeSourceName(t.getSourceName())); Node moduleRef = IR.name(moduleName).srcref(require); parent.replaceChild(require, moduleRef); Node script = getCurrentScriptNode(parent); if (reportDependencies) { t.getInput().addRequire(moduleName); } // Rewrite require("name"). script.addChildToFront(IR.exprResult( IR.call(IR.getprop(IR.name("goog"), IR.string("require")), IR.string(moduleName))).copyInformationFromForTree(require)); compiler.reportCodeChange(); }
Example 3
Source File: SpecializeModule.java From astor with GNU General Public License v2.0 | 6 votes |
/** * Generates a definition of the original function that can be added as * a fixup in the modules that directly depend on the specialized module. * * <PRE> * The trick here is that even if the original function is declared as: * * function foo() { * // stuff * } * * the fixup will have to be of the form * * foo = function() { * // stuff * } * </PRE> * */ private Node generateFixupDefinition() { Node functionCopy = copiedOriginalFunction(); Node nameNode; if (isAssignFunction) { nameNode = NodeUtil.newQualifiedNameNode( compiler.getCodingConvention(), name, functionCopy, name); } else { // Grab the name node from the original function and make that // function anonymous. nameNode = functionCopy.getFirstChild(); functionCopy.replaceChild(nameNode, NodeUtil.newName(compiler.getCodingConvention(), "", nameNode)); } Node assignment = IR.assign(nameNode, functionCopy); assignment.copyInformationFrom(functionCopy); return NodeUtil.newExpr(assignment); }
Example 4
Source File: RemoveGoogScopePass.java From clutz with MIT License | 6 votes |
private void maybeReassignAlias(Node assign) { Node lhs = assign.getFirstChild(); if (!lhs.isGetProp()) { // TODO(dpurpura): Add support for GET_ELEM. (e.g. Foo['abc']) return; } // Find the name of the deepest first child. String alias = null; for (Node child = lhs; child != null; child = child.getFirstChild()) { if (child.isName()) { alias = child.getQualifiedName(); } } checkNotNull(alias, "Missing name for alias"); if (aliasToProvidedNamespace.containsKey(alias)) { String providedNamespace = aliasToProvidedNamespace.get(alias); String suffix = lhs.getQualifiedName().substring(alias.length()); Node fullName = NodeUtil.newQName(compiler, providedNamespace + suffix); assign.replaceChild(lhs, fullName); } return; }
Example 5
Source File: Closure_79_Normalize_t.java From coming with MIT License | 6 votes |
/** * Limit the number of special cases where LABELs need to be handled. Only * BLOCK and loops are allowed to be labeled. Loop labels must remain in * place as the named continues are not allowed for labeled blocks. */ private void normalizeLabels(Node n) { Preconditions.checkArgument(n.getType() == Token.LABEL); Node last = n.getLastChild(); switch (last.getType()) { case Token.LABEL: case Token.BLOCK: case Token.FOR: case Token.WHILE: case Token.DO: return; default: Node block = new Node(Token.BLOCK); block.copyInformationFrom(last); n.replaceChild(last, block); block.addChildToFront(last); reportCodeChange("LABEL normalization"); return; } }
Example 6
Source File: Closure_105_FoldConstants_s.java From coming with MIT License | 6 votes |
/** * Try to fold a ADD node */ void tryFoldAdd(NodeTraversal t, Node n, Node left, Node right, Node parent) { if (left.getType() == Token.STRING || right.getType() == Token.STRING) { // Add strings. String leftString = NodeUtil.getStringValue(left); String rightString = NodeUtil.getStringValue(right); if (leftString != null && rightString != null) { parent.replaceChild(n, Node.newString(leftString + rightString)); t.getCompiler().reportCodeChange(); } } else { // Try arithmetic add tryFoldArithmetic(t, n, left, right, parent); } }
Example 7
Source File: Closure_105_FoldConstants_t.java From coming with MIT License | 5 votes |
/** * Try to fold array-length. e.g [1, 2, 3].length ==> 3, [x, y].length ==> 2 */ void tryFoldGetProp(NodeTraversal t, Node n, Node left, Node right, Node parent) { if (right.getType() == Token.STRING && right.getString().equals("length")) { int knownLength = -1; switch (left.getType()) { case Token.ARRAYLIT: if (NodeUtil.mayHaveSideEffects(left)) { // Nope, can't fold this, without handling the side-effects. return; } knownLength = left.getChildCount(); break; case Token.STRING: knownLength = left.getString().length(); break; default: // Not a foldable case, forget it. return; } Preconditions.checkState(knownLength != -1); Node lengthNode = Node.newNumber(knownLength); parent.replaceChild(n, lengthNode); t.getCompiler().reportCodeChange(); } }
Example 8
Source File: Closure_23_PeepholeFoldConstants_t.java From coming with MIT License | 5 votes |
private Node tryFoldInForcedStringContext(Node n) { // For now, we only know how to fold ctors. Preconditions.checkArgument(n.isNew()); Node objectType = n.getFirstChild(); if (!objectType.isName()) { return n; } if (objectType.getString().equals("String")) { Node value = objectType.getNext(); String stringValue = null; if (value == null) { stringValue = ""; } else { if (!NodeUtil.isImmutableValue(value)) { return n; } stringValue = NodeUtil.getStringValue(value); } if (stringValue == null) { return n; } Node parent = n.getParent(); Node newString = IR.string(stringValue); parent.replaceChild(n, newString); newString.copyInformationFrom(parent); reportCodeChange(); return newString; } return n; }
Example 9
Source File: Closure_23_PeepholeFoldConstants_s.java From coming with MIT License | 5 votes |
private Node tryFoldInForcedStringContext(Node n) { // For now, we only know how to fold ctors. Preconditions.checkArgument(n.isNew()); Node objectType = n.getFirstChild(); if (!objectType.isName()) { return n; } if (objectType.getString().equals("String")) { Node value = objectType.getNext(); String stringValue = null; if (value == null) { stringValue = ""; } else { if (!NodeUtil.isImmutableValue(value)) { return n; } stringValue = NodeUtil.getStringValue(value); } if (stringValue == null) { return n; } Node parent = n.getParent(); Node newString = IR.string(stringValue); parent.replaceChild(n, newString); newString.copyInformationFrom(parent); reportCodeChange(); return newString; } return n; }
Example 10
Source File: Closure_23_PeepholeFoldConstants_t.java From coming with MIT License | 5 votes |
/** * Expressions such as [foo() * 10 * 20] generate parse trees * where no node has two const children ((foo() * 10) * 20), so * performArithmeticOp() won't fold it -- tryFoldLeftChildOp() will. * Specifically, it folds associative expressions where: * - The left child is also an associative expression of the same time. * - The right child is a constant NUMBER constant. * - The left child's right child is a NUMBER constant. */ private Node tryFoldLeftChildOp(Node n, Node left, Node right) { int opType = n.getType(); Preconditions.checkState( (NodeUtil.isAssociative(opType) && NodeUtil.isCommutative(opType)) || n.isAdd()); Preconditions.checkState( !n.isAdd()|| !NodeUtil.mayBeString(n)); // Use getNumberValue to handle constants like "NaN" and "Infinity" // other values are converted to numbers elsewhere. Double rightValObj = NodeUtil.getNumberValue(right); if (rightValObj != null && left.getType() == opType) { Preconditions.checkState(left.getChildCount() == 2); Node ll = left.getFirstChild(); Node lr = ll.getNext(); Node valueToCombine = ll; Node replacement = performArithmeticOp(opType, valueToCombine, right); if (replacement == null) { valueToCombine = lr; replacement = performArithmeticOp(opType, valueToCombine, right); } if (replacement != null) { // Remove the child that has been combined left.removeChild(valueToCombine); // Replace the left op with the remaining child. n.replaceChild(left, left.removeFirstChild()); // New "-Infinity" node need location info explicitly // added. replacement.copyInformationFromForTree(right); n.replaceChild(right, replacement); reportCodeChange(); } } return n; }
Example 11
Source File: Closure_50_PeepholeReplaceKnownMethods_t.java From coming with MIT License | 5 votes |
/** * Try to fold .charAt() calls on strings */ private Node tryFoldStringCharAt(Node n, Node stringNode, Node arg1) { Preconditions.checkArgument(n.getType() == Token.CALL); Preconditions.checkArgument(stringNode.getType() == Token.STRING); int index; String stringAsString = stringNode.getString(); if (arg1 != null && arg1.getType() == Token.NUMBER && arg1.getNext() == null) { index = (int) arg1.getDouble(); } else { return n; } if (index < 0 || stringAsString.length() <= index) { // http://es5.github.com/#x15.5.4.4 says "" is returned when index is // out of bounds but we bail. return n; } Node resultNode = Node.newString( stringAsString.substring(index, index + 1)); Node parent = n.getParent(); parent.replaceChild(n, resultNode); reportCodeChange(); return resultNode; }
Example 12
Source File: Closure_74_PeepholeFoldConstants_s.java From coming with MIT License | 5 votes |
/** * Try to fold a AND/OR node. */ private Node tryFoldAndOr(Node n, Node left, Node right) { Node parent = n.getParent(); Node result = null; int type = n.getType(); TernaryValue leftVal = NodeUtil.getImpureBooleanValue(left); if (leftVal != TernaryValue.UNKNOWN) { boolean lval = leftVal.toBoolean(true); // (TRUE || x) => TRUE (also, (3 || x) => 3) // (FALSE && x) => FALSE if (lval && type == Token.OR || !lval && type == Token.AND) { result = left; } else if (!mayHaveSideEffects(left)) { // (FALSE || x) => x // (TRUE && x) => x result = right; } } // Note: Right hand side folding is handled by // PeepholeSubstituteAlternateSyntax#tryMinimizeCondition if (result != null) { // Fold it! n.removeChild(result); parent.replaceChild(n, result); reportCodeChange(); return result; } else { return n; } }
Example 13
Source File: Cardumen_00201_t.java From coming with MIT License | 5 votes |
@Override public void visit(NodeTraversal t, Node n, Node parent) { if (n.isCall()) { Node target = n.getFirstChild(); // TODO(johnlenz): add this to the coding convention // so we can remove goog.reflect.sinkValue as well. if (target.isName() && target.getString().equals(PROTECTOR_FN)) { Node expr = n.getLastChild(); n.detachChildren(); parent.replaceChild(n, expr); } } }
Example 14
Source File: Closure_105_FoldConstants_s.java From coming with MIT License | 4 votes |
/** * Try to fold an array join: ['a', 'b', 'c'].join('') -> 'abc'; */ void tryFoldStringJoin(NodeTraversal t, Node n, Node left, Node right, Node parent) { if (!NodeUtil.isGetProp(left) || !NodeUtil.isImmutableValue(right)) { return; } Node arrayNode = left.getFirstChild(); Node functionName = arrayNode.getNext(); if ((arrayNode.getType() != Token.ARRAYLIT) || !functionName.getString().equals("join")) { return; } String joinString = NodeUtil.getStringValue(right); List<Node> arrayFoldedChildren = Lists.newLinkedList(); StringBuilder sb = new StringBuilder(); int foldedSize = 0; Node elem = arrayNode.getFirstChild(); // Merges adjacent String nodes. while (elem != null) { if (NodeUtil.isImmutableValue(elem)) { if (sb.length() > 0) { sb.append(joinString); } sb.append(NodeUtil.getStringValue(elem)); } else { if (sb.length() > 0) { // + 2 for the quotes. foldedSize += sb.length() + 2; arrayFoldedChildren.add(Node.newString(sb.toString())); sb = new StringBuilder(); } foldedSize += InlineCostEstimator.getCost(elem); arrayFoldedChildren.add(elem); } elem = elem.getNext(); } if (sb.length() > 0) { // + 2 for the quotes. foldedSize += sb.length() + 2; arrayFoldedChildren.add(Node.newString(sb.toString())); } // one for each comma. foldedSize += arrayFoldedChildren.size() - 1; int originalSize = InlineCostEstimator.getCost(n); switch (arrayFoldedChildren.size()) { case 0: Node emptyStringNode = Node.newString(""); parent.replaceChild(n, emptyStringNode); break; case 1: Node foldedStringNode = arrayFoldedChildren.remove(0); if (foldedSize > originalSize) { return; } arrayNode.detachChildren(); if (foldedStringNode.getType() != Token.STRING) { // If the Node is not a string literal, ensure that // it is coerced to a string. Node replacement = new Node(Token.ADD, Node.newString(""), foldedStringNode); foldedStringNode = replacement; } parent.replaceChild(n, foldedStringNode); break; default: // No folding could actually be performed. if (arrayFoldedChildren.size() == arrayNode.getChildCount()) { return; } int kJoinOverhead = "[].join()".length(); foldedSize += kJoinOverhead; foldedSize += InlineCostEstimator.getCost(right); if (foldedSize > originalSize) { return; } arrayNode.detachChildren(); for (Node node : arrayFoldedChildren) { arrayNode.addChildToBack(node); } break; } t.getCompiler().reportCodeChange(); }
Example 15
Source File: Closure_97_PeepholeFoldConstants_t.java From coming with MIT License | 4 votes |
/** * Try to fold a AND/OR node. */ private Node tryFoldAndOr(Node n, Node left, Node right) { Node parent = n.getParent(); Node result = null; int type = n.getType(); TernaryValue leftVal = NodeUtil.getBooleanValue(left); if (leftVal != TernaryValue.UNKNOWN) { boolean lval = leftVal.toBoolean(true); // (TRUE || x) => TRUE (also, (3 || x) => 3) // (FALSE && x) => FALSE if (lval && type == Token.OR || !lval && type == Token.AND) { result = left; } else { // (FALSE || x) => x // (TRUE && x) => x result = right; } } else { TernaryValue rightVal = NodeUtil.getBooleanValue(right); if (rightVal != TernaryValue.UNKNOWN) { // Note: We cannot always fold when the constant is on the // right, because the typed value of the expression will depend // on the type of the constant on the right, even if the boolean // equivalent of the value does not. Specifically, in "a = x || // 0", a will be numeric 0 if x is undefined (and hence is // e.g. a valid array index). However, it is safe to fold // e.g. "if (x || true)" because 'if' doesn't care if the // expression is 'true' or '3'. int pt = parent.getType(); if (pt == Token.IF || pt == Token.WHILE || pt == Token.DO || (pt == Token.FOR && NodeUtil.getConditionExpression(parent) == n) || (pt == Token.HOOK && parent.getFirstChild() == n)) { boolean rval = rightVal.toBoolean(true); // (x || FALSE) => x // (x && TRUE) => x if (type == Token.OR && !rval || type == Token.AND && rval) { result = left; } else { // If x has no side-effects: // (x || TRUE) => TRUE // (x && FALSE) => FALSE if (!NodeUtil.mayHaveSideEffects(left)) { result = right; } } } } } // Note: The parser parses 'x && FALSE && y' as 'x && (FALSE && y)', so // there is not much need to worry about const values on left's // right child. if (result != null) { // Fold it! n.removeChild(result); parent.replaceChild(n, result); reportCodeChange(); return result; } else { return n; } }
Example 16
Source File: Closure_1_RemoveUnusedVars_t.java From coming with MIT License | 4 votes |
/** * Removes any vars in the scope that were not referenced. Removes any * assignments to those variables as well. */ private void removeUnreferencedVars() { CodingConvention convention = codingConvention; for (Iterator<Var> it = maybeUnreferenced.iterator(); it.hasNext(); ) { Var var = it.next(); // Remove calls to inheritance-defining functions where the unreferenced // class is the subclass. for (Node exprCallNode : classDefiningCalls.get(var)) { NodeUtil.removeChild(exprCallNode.getParent(), exprCallNode); compiler.reportCodeChange(); } // Regardless of what happens to the original declaration, // we need to remove all assigns, because they may contain references // to other unreferenced variables. removeAllAssigns(var); compiler.addToDebugLog("Unreferenced var: " + var.name); Node nameNode = var.nameNode; Node toRemove = nameNode.getParent(); Node parent = toRemove.getParent(); Preconditions.checkState( toRemove.isVar() || toRemove.isFunction() || toRemove.isParamList() && parent.isFunction(), "We should only declare vars and functions and function args"); if (toRemove.isParamList() && parent.isFunction()) { // Don't remove function arguments here. That's a special case // that's taken care of in removeUnreferencedFunctionArgs. } else if (NodeUtil.isFunctionExpression(toRemove)) { if (!preserveFunctionExpressionNames) { toRemove.getFirstChild().setString(""); compiler.reportCodeChange(); } // Don't remove bleeding functions. } else if (parent != null && parent.isFor() && parent.getChildCount() < 4) { // foreach iterations have 3 children. Leave them alone. } else if (toRemove.isVar() && nameNode.hasChildren() && NodeUtil.mayHaveSideEffects(nameNode.getFirstChild(), compiler)) { // If this is a single var declaration, we can at least remove the // declaration itself and just leave the value, e.g., // var a = foo(); => foo(); if (toRemove.getChildCount() == 1) { parent.replaceChild(toRemove, IR.exprResult(nameNode.removeFirstChild())); compiler.reportCodeChange(); } } else if (toRemove.isVar() && toRemove.getChildCount() > 1) { // For var declarations with multiple names (i.e. var a, b, c), // only remove the unreferenced name toRemove.removeChild(nameNode); compiler.reportCodeChange(); } else if (parent != null) { NodeUtil.removeChild(parent, toRemove); compiler.reportCodeChange(); } } }
Example 17
Source File: Cardumen_00152_s.java From coming with MIT License | 4 votes |
/** * Removes any vars in the scope that were not referenced. Removes any * assignments to those variables as well. */ private void removeUnreferencedVars() { CodingConvention convention = codingConvention; for (Iterator<Var> it = maybeUnreferenced.iterator(); it.hasNext(); ) { Var var = it.next(); // Remove calls to inheritance-defining functions where the unreferenced // class is the subclass. for (Node exprCallNode : inheritsCalls.get(var)) { NodeUtil.removeChild(exprCallNode.getParent(), exprCallNode); compiler.reportCodeChange(); } // Regardless of what happens to the original declaration, // we need to remove all assigns, because they may contain references // to other unreferenced variables. removeAllAssigns(var); compiler.addToDebugLog("Unreferenced var: " + var.name); Node nameNode = var.nameNode; Node toRemove = nameNode.getParent(); Node parent = toRemove.getParent(); Preconditions.checkState( toRemove.isVar() || toRemove.isFunction() || toRemove.isParamList() && parent.isFunction(), "We should only declare vars and functions and function args"); if (toRemove.isParamList() && parent.isFunction()) { // Don't remove function arguments here. That's a special case // that's taken care of in removeUnreferencedFunctionArgs. } else if (NodeUtil.isFunctionExpression(toRemove)) { if (!preserveFunctionExpressionNames) { toRemove.getFirstChild().setString(""); compiler.reportCodeChange(); } // Don't remove bleeding functions. } else if (parent != null && parent.isFor() && parent.getChildCount() < 4) { // foreach iterations have 3 children. Leave them alone. } else if (toRemove.isVar() && nameNode.hasChildren() && NodeUtil.mayHaveSideEffects(nameNode.getFirstChild())) { // If this is a single var declaration, we can at least remove the // declaration itself and just leave the value, e.g., // var a = foo(); => foo(); if (toRemove.getChildCount() == 1) { parent.replaceChild(toRemove, IR.exprResult(nameNode.removeFirstChild())); compiler.reportCodeChange(); } } else if (toRemove.isVar() && toRemove.getChildCount() > 1) { // For var declarations with multiple names (i.e. var a, b, c), // only remove the unreferenced name toRemove.removeChild(nameNode); compiler.reportCodeChange(); } else if (parent != null) { NodeUtil.removeChild(parent, toRemove); compiler.reportCodeChange(); } } }
Example 18
Source File: Closure_126_MinimizeExitPoints_s.java From coming with MIT License | 4 votes |
/** * Look for exits (returns, breaks, or continues, depending on the context) at * the end of a block and removes them by moving the if node's siblings, * if any, into the opposite condition block. * * @param srcBlock The block to inspect. * @param destBlock The block to move sibling nodes into. * @param ifNode The if node to work with. * @param exitType The type of exit to look for. * @param labelName The name associated with the exit, if any. * @nullable labelName null for anything excepted for named-break associated * with a label. */ private void tryMinimizeIfBlockExits(Node srcBlock, Node destBlock, Node ifNode, int exitType, String labelName) { Node exitNodeParent = null; Node exitNode = null; // Pick an exit node candidate. if (srcBlock.isBlock()) { if (!srcBlock.hasChildren()) { return; } exitNodeParent = srcBlock; exitNode = exitNodeParent.getLastChild(); } else { // Just a single statement, if it isn't an exit bail. exitNodeParent = ifNode; exitNode = srcBlock; } // Verify the candidate. if (!matchingExitNode(exitNode, exitType, labelName)) { return; } // Take case of the if nodes siblings, if any. if (ifNode.getNext() != null) { // Move siblings of the if block into the opposite // logic block of the exit. Node newDestBlock = IR.block().srcref(ifNode); if (destBlock == null) { // Only possible if this is the false block. ifNode.addChildToBack(newDestBlock); } else if (destBlock.isEmpty()) { // Use the new block. ifNode.replaceChild(destBlock, newDestBlock); } else if (destBlock.isBlock()) { // Reuse the existing block. newDestBlock = destBlock; } else { // Add the existing statement to the new block. ifNode.replaceChild(destBlock, newDestBlock); newDestBlock.addChildToBack(destBlock); } // Move all the if node's following siblings. moveAllFollowing(ifNode, ifNode.getParent(), newDestBlock); compiler.reportCodeChange(); } }
Example 19
Source File: PeepholeReplaceKnownMethods.java From astor with GNU General Public License v2.0 | 4 votes |
/** * Try to fold .split() calls on strings */ private Node tryFoldStringSplit(Node n, Node stringNode, Node arg1) { if (late) { return n; } Preconditions.checkArgument(n.isCall()); Preconditions.checkArgument(stringNode.isString()); String separator = null; String stringValue = stringNode.getString(); // Maximum number of possible splits int limit = stringValue.length() + 1; if (arg1 != null) { if (arg1.isString()) { separator = arg1.getString(); } else if (!arg1.isNull()) { return n; } Node arg2 = arg1.getNext(); if (arg2 != null) { if (arg2.isNumber()) { limit = Math.min((int) arg2.getDouble(), limit); if (limit < 0) { return n; } } else { return n; } } } // Split the string and convert the returned array into JS nodes String[] stringArray = jsSplit(stringValue, separator, limit); Node arrayOfStrings = IR.arraylit(); for (int i = 0; i < stringArray.length; i++) { arrayOfStrings.addChildToBack( IR.string(stringArray[i]).srcref(stringNode)); } Node parent = n.getParent(); parent.replaceChild(n, arrayOfStrings); reportCodeChange(); return arrayOfStrings; }
Example 20
Source File: StripCode.java From astor with GNU General Public License v2.0 | 2 votes |
/** * Replaces a node with a NULL node. This is useful where a value is * expected. * * @param n A node * @param parent {@code n}'s parent */ void replaceWithNull(Node n, Node parent) { parent.replaceChild(n, IR.nullNode()); }