/** * Returns a new EMPTY node. * * <p>EMPTY Nodes have no type information, so this is functionally the same as calling {@code * IR.empty()}. It exists so that a pass can be consistent about always using {@code AstFactory} * to create new nodes. */ Node createEmpty() { return IR.empty(); }
/** * Remove always true loop conditions. */ private void tryFoldForCondition(Node forCondition) { if (NodeUtil.getPureBooleanValue(forCondition) == TernaryValue.TRUE) { reportChangeToEnclosingScope(forCondition); forCondition.replaceWith(IR.empty()); } } }
@Override public void performRemove(AbstractCompiler compiler) { // replace internal name with "" c.replaceChild(c.getFirstChild(), IR.empty()); compiler.reportChangeToEnclosingScope(c.getFirstChild()); } }
/** * Remove always true loop conditions. */ private void tryFoldForCondition(Node forCondition) { if (NodeUtil.getPureBooleanValue(forCondition) == TernaryValue.TRUE) { forCondition.getParent().replaceChild(forCondition, IR.empty()); reportCodeChange(); } } }
/** Set the given function/class node to an empty name */ public static void removeName(Node n) { checkState(n.isFunction() || n.isClass()); Node originalName = n.getFirstChild(); Node emptyName = n.isFunction() ? IR.name("") : IR.empty(); n.replaceChild(originalName, emptyName.useSourceInfoFrom(originalName)); }
@Override public void removeInternal(AbstractCompiler compiler) { if (!alreadyRemoved(classNode)) { Node nameNode = classNode.getFirstChild(); if (!nameNode.isEmpty()) { // Just empty the class's name. If the expression is assigned to an unused variable, // then the whole class might still be removed as part of that assignment. classNode.replaceChild(nameNode, IR.empty().useSourceInfoFrom(nameNode)); compiler.reportChangeToEnclosingScope(classNode); } } }
@Override void removeInternal(AbstractCompiler compiler) { Node declaration = checkNotNull(nameNode.getParent()); compiler.reportChangeToEnclosingScope(declaration); // NOTE: We don't need to preserve the initializer value, because we currently do not remove // for-loop vars whose initializing values have side effects. if (nameNode.getPrevious() == null && nameNode.getNext() == null) { // only child, so we can remove the whole declaration declaration.replaceWith(IR.empty().useSourceInfoFrom(declaration)); } else { declaration.removeChild(nameNode); } NodeUtil.markFunctionsDeleted(nameNode, compiler); } }
/** * Removes DOs that have empty bodies into FORs, which are * much easier for the CFA to analyze. */ Node tryFoldEmptyDo(Node n) { checkArgument(n.isDo()); Node body = NodeUtil.getLoopCodeBlock(n); if (body.isBlock() && !body.hasChildren()) { Node cond = NodeUtil.getConditionExpression(n); Node forNode = IR.forNode(IR.empty().srcref(n), cond.detach(), IR.empty().srcref(n), body.detach()); n.replaceWith(forNode); reportChangeToEnclosingScope(forNode); return forNode; } return n; }
/** * Remove the provided object and its method call. */ private void inlineEmptyMethod(Node parent, Node call) { // If the return value of the method call is read, // replace it with "void 0". Otherwise, remove the call entirely. if (NodeUtil.isExprCall(parent)) { parent.getParent().replaceChild(parent, IR.empty()); } else { Node srcLocation = call; parent.replaceChild(call, NodeUtil.newUndefinedNode(srcLocation)); } compiler.reportCodeChange(); }
@Override public void visit(NodeTraversal t, Node n, Node parent) { switch (n.getToken()) { case CLASS: if (needsInnerNameRewriting(n, parent)) { classStack.removeFirst(); n.replaceChild(n.getFirstChild(), IR.empty().useSourceInfoFrom(n.getFirstChild())); compiler.reportChangeToEnclosingScope(n); } break; case NAME: maybeUpdateClassSelfRef(t, n, parent); break; default: break; } }
/** * Removes DOs that have empty bodies into FORs, which are * much easier for the CFA to analyze. */ Node tryFoldEmptyDo(Node n) { Preconditions.checkArgument(n.isDo()); Node body = NodeUtil.getLoopCodeBlock(n); if (body.isBlock() && !body.hasChildren()) { Node cond = NodeUtil.getConditionExpression(n); Node whileNode = IR.forNode(IR.empty().srcref(n), cond.detachFromParent(), IR.empty().srcref(n), body.detachFromParent()) .srcref(n); n.getParent().replaceChild(n, whileNode); reportCodeChange(); return whileNode; } return n; }
private void visitExportFrom(NodeTraversal t, Node export, Node parent) { // export {x, y as z} from 'moduleIdentifier'; Node moduleIdentifier = export.getLastChild(); Node importNode = IR.importNode(IR.empty(), IR.empty(), moduleIdentifier.cloneNode()); importNode.useSourceInfoFrom(export); parent.addChildBefore(importNode, export); visit(t, importNode, parent); String moduleName = getVarNameOfImport(moduleIdentifier.getString()); for (Node exportSpec : export.getFirstChild().children()) { exportedNameToLocalQName.put( exportSpec.getLastChild().getString(), new LocalQName(moduleName + "." + exportSpec.getFirstChild().getString(), exportSpec)); } parent.removeChild(export); t.reportCodeChange(); }
/** * Remove the provided object and its method call. */ private void inlineEmptyMethod(NodeTraversal t, Node parent, Node call) { // If the return value of the method call is read, // replace it with "void 0". Otherwise, remove the call entirely. if (NodeUtil.isExprCall(parent)) { parent.replaceWith(IR.empty()); NodeUtil.markFunctionsDeleted(parent, compiler); } else { Node srcLocation = call; parent.replaceChild(call, NodeUtil.newUndefinedNode(srcLocation)); NodeUtil.markFunctionsDeleted(call, compiler); } t.reportCodeChange(); }
private void maybeCreateQualifiedDeclaration(NodeTraversal t, Node n, Node parent) { if (currNamespace != null) { Node name = n.getFirstChild(); String oldName = name.getString(); String qName = maybePrependCurrNamespace(oldName); Node newName = n.isFunction() ? IR.name("") : IR.empty(); newName.useSourceInfoFrom(n); n.replaceChild(name, newName); Node placeHolder = IR.empty(); parent.replaceChild(n, placeHolder); Node newDec = NodeUtil.newQNameDeclaration( compiler, qName, n, n.getJSDocInfo()).useSourceInfoFromForTree(n); n.setJSDocInfo(null); parent.replaceChild(placeHolder, newDec); t.reportCodeChange(); } }
private void maybeCreateQualifiedDeclaration(Node n, Node parent) { if (currNamespace != null) { Node name = n.getFirstChild(); String oldName = name.getString(); String qName = maybePrependCurrNamespace(oldName); Node newName = n.isFunction() ? IR.name("") : IR.empty(); newName.useSourceInfoFrom(n); n.replaceChild(name, newName); Node placeHolder = IR.empty(); parent.replaceChild(n, placeHolder); Node newDec = NodeUtil.newQNameDeclaration( compiler, qName, n, n.getJSDocInfo()).useSourceInfoFromForTree(n); n.setJSDocInfo(null); parent.replaceChild(placeHolder, newDec); compiler.reportCodeChange(); } }
private void visitExportStar(NodeTraversal t, Node export, Node parent) { // export * from 'moduleIdentifier'; Node moduleIdentifier = export.getLastChild(); // Make an "import 'spec'" from this export node and then visit it to rewrite to a require(). Node importNode = IR.importNode(IR.empty(), IR.empty(), moduleIdentifier.cloneNode()); importNode.useSourceInfoFrom(export); parent.addChildBefore(importNode, export); visit(t, importNode, parent); String moduleName = getVarNameOfImport(moduleIdentifier.getString()); export.replaceWith( IR.exprResult( IR.call( IR.getprop(IR.name("$$module"), IR.string("exportAllFrom")), IR.name(moduleName))) .useSourceInfoFromForTree(export)); t.reportCodeChange(); }
public ReferenceReplacer(Node script, Node googImportNode, boolean globalizeAllReferences) { this.googImportNode = googImportNode; this.globalizeAllReferences = globalizeAllReferences; NodeTraversal.traverse(compiler, script, this); if (googImportNode.getSecondChild().isImportStar()) { if (hasBadExport) { googImportNode.getSecondChild().setOriginalName("goog"); googImportNode.getSecondChild().setString("$goog"); } else { googImportNode.getSecondChild().replaceWith(IR.empty()); } compiler.reportChangeToEnclosingScope(googImportNode); } }
private void normalizeAssignShorthand(Node shorthand) { if (shorthand.getFirstChild().isName()) { Node name = shorthand.getFirstChild(); shorthand.setType(NodeUtil.getOpFromAssignmentOp(shorthand)); Node parent = shorthand.getParent(); Node insertPoint = IR.empty(); parent.replaceChild(shorthand, insertPoint); Node assign = IR.assign(name.cloneNode().useSourceInfoFrom(name), shorthand) .useSourceInfoFrom(shorthand); assign.setJSDocInfo(shorthand.getJSDocInfo()); shorthand.setJSDocInfo(null); parent.replaceChild(insertPoint, assign); compiler.reportCodeChange(); } }
private void normalizeAssignShorthand(Node shorthand) { if (shorthand.getFirstChild().isName()) { Node name = shorthand.getFirstChild(); shorthand.setToken(NodeUtil.getOpFromAssignmentOp(shorthand)); Node parent = shorthand.getParent(); Node insertPoint = IR.empty(); parent.replaceChild(shorthand, insertPoint); Node assign = IR.assign(name.cloneNode().useSourceInfoFrom(name), shorthand) .useSourceInfoFrom(shorthand); assign.setJSDocInfo(shorthand.getJSDocInfo()); shorthand.setJSDocInfo(null); parent.replaceChild(insertPoint, assign); compiler.reportChangeToEnclosingScope(assign); } }