/** * @return An appropriate AST node for the boolean value. */ static Node booleanNode(boolean value) { return value ? IR.trueNode() : IR.falseNode(); }
@VisibleForTesting static Map<String, Node> getAdditionalReplacements(CompilerOptions options) { Map<String, Node> additionalReplacements = new HashMap<>(); if (options.markAsCompiled || options.closurePass) { additionalReplacements.put(COMPILED_CONSTANT_NAME, IR.trueNode()); } if (options.closurePass && options.locale != null) { additionalReplacements.put(CLOSURE_LOCALE_CONSTANT_NAME, IR.string(options.locale)); } return additionalReplacements; }
/** * @return An appropriate AST node for the boolean value. */ static Node booleanNode(boolean value) { return value ? IR.trueNode() : IR.falseNode(); }
@VisibleForTesting static Map<String, Node> getAdditionalReplacements( CompilerOptions options) { Map<String, Node> additionalReplacements = new HashMap<String, Node>(); if (options.markAsCompiled || options.closurePass) { additionalReplacements.put(COMPILED_CONSTANT_NAME, IR.trueNode()); } if (options.closurePass && options.locale != null) { additionalReplacements.put(CLOSURE_LOCALE_CONSTANT_NAME, IR.string(options.locale)); } return additionalReplacements; }
Node createBoolean(boolean value) { Node result = value ? IR.trueNode() : IR.falseNode(); if (isAddingTypes()) { result.setJSType(getNativeType(JSTypeNative.BOOLEAN_TYPE)); } return result; }
private static Node createIteratorResult(Node value, boolean done) { return IR.objectlit( IR.propdef(IR.stringKey("value"), value), IR.propdef(IR.stringKey("done"), done ? IR.trueNode() : IR.falseNode())); }
/** * Create an assignment to the branch coverage data for the given index into the array. * * @return the newly constructed assignment node. */ private Node newBranchInstrumentationNode(NodeTraversal traversal, Node node, int idx) { String arrayName = createArrayName(traversal); // Create instrumentation Node Node getElemNode = IR.getelem(IR.name(arrayName), IR.number(idx)); // Make line number 0-based Node exprNode = IR.exprResult(IR.assign(getElemNode, IR.trueNode())); // Note line as instrumented String fileName = traversal.getSourceName(); if (!instrumentationData.containsKey(fileName)) { instrumentationData.put(fileName, new FileInstrumentationData(fileName, arrayName)); } return exprNode.useSourceInfoIfMissingFromForTree(node); }
/** * Creates and return a new instrumentation node. The instrumentation Node is * of the form: "arrayName[lineNumber] = true;" * Note 1: Node returns a 1-based line number. * Note 2: Line numbers in instrumentation are made 0-based. This is done to * map to their bit representation in BitField. Thus, there's a one-to-one * correspondence of the line number seen on instrumented files and their bit * encodings. * * @return an instrumentation node corresponding to the line number */ private Node newInstrumentationNode(NodeTraversal traversal, Node node) { int lineNumber = node.getLineno(); String arrayName = createArrayName(traversal); // Create instrumentation Node Node getElemNode = IR.getelem( IR.name(arrayName), IR.number(lineNumber - 1)); // Make line number 0-based Node exprNode = IR.exprResult(IR.assign(getElemNode, IR.trueNode())); // Note line as instrumented String fileName = getFileName(traversal); if (!instrumentationData.containsKey(fileName)) { instrumentationData.put(fileName, new FileInstrumentationData(fileName, arrayName)); } instrumentationData.get(fileName).setLineAsInstrumented(lineNumber); return exprNode.useSourceInfoIfMissingFromForTree(node); }
/** * Creates and return a new instrumentation node. The instrumentation Node is * of the form: "arrayName[lineNumber] = true;" * Note 1: Node returns a 1-based line number. * Note 2: Line numbers in instrumentation are made 0-based. This is done to * map to their bit representation in BitField. Thus, there's a one-to-one * correspondence of the line number seen on instrumented files and their bit * encodings. * * @return an instrumentation node corresponding to the line number */ private Node newInstrumentationNode(NodeTraversal traversal, Node node) { int lineNumber = node.getLineno(); String arrayName = createArrayName(traversal); // Create instrumentation Node Node getElemNode = IR.getelem( IR.name(arrayName), IR.number(lineNumber - 1)); // Make line number 0-based Node exprNode = IR.exprResult(IR.assign(getElemNode, IR.trueNode())); // Note line as instrumented String fileName = getFileName(traversal); if (!instrumentationData.containsKey(fileName)) { instrumentationData.put(fileName, new FileInstrumentationData(fileName, arrayName)); } instrumentationData.get(fileName).setLineAsInstrumented(lineNumber); return exprNode.useSourceInfoIfMissingFromForTree(node); }
/** * Try to fold {@code left instanceof right} into {@code true} * or {@code false}. */ private Node tryFoldInstanceof(Node n, Node left, Node right) { checkArgument(n.isInstanceOf()); // TODO(johnlenz) Use type information if available to fold // instanceof. if (NodeUtil.isLiteralValue(left, true) && !mayHaveSideEffects(right)) { Node replacementNode = null; if (NodeUtil.isImmutableValue(left)) { // Non-object types are never instances. replacementNode = IR.falseNode(); } else if (right.isName() && "Object".equals(right.getString())) { replacementNode = IR.trueNode(); } if (replacementNode != null) { n.replaceWith(replacementNode); reportChangeToEnclosingScope(replacementNode); markFunctionsDeleted(n); return replacementNode; } } return n; }
/** * Try to fold {@code left instanceof right} into {@code true} * or {@code false}. */ private Node tryFoldInstanceof(Node n, Node left, Node right) { Preconditions.checkArgument(n.isInstanceOf()); // TODO(johnlenz) Use type information if available to fold // instanceof. if (NodeUtil.isLiteralValue(left, true) && !mayHaveSideEffects(right)) { Node replacementNode = null; if (NodeUtil.isImmutableValue(left)) { // Non-object types are never instances. replacementNode = IR.falseNode(); } else if (right.isName() && "Object".equals(right.getString())) { replacementNode = IR.trueNode(); } if (replacementNode != null) { n.getParent().replaceChild(n, replacementNode); reportCodeChange(); return replacementNode; } } return n; }
/** * Assigns a {@code true} prop, with the name of the marker. to the prototype of the class. * * <pre>{@code * /** @constructor *\/ * function C() { } * * C.prototype['instance_of__C'] = true; * }</pre> */ private Node addMarkerToFunction( String markerName, @Nullable String className, Node nodeToInsertAfter) { if (className == null) { // This can happen with anonymous classes declared with the type `Function`. return nodeToInsertAfter; } Node classNode = NodeUtil.newQName(compiler, className); Node assign = IR.exprResult( IR.assign( IR.getelem(IR.getprop(classNode, IR.string("prototype")), IR.string(markerName)), IR.trueNode())); nodeToInsertAfter.getParent().addChildAfter(assign, nodeToInsertAfter); compiler.reportChangeToEnclosingScope(assign); return assign; }
/** * Converts all of the given call nodes to object literals that are safe to * do so. */ private void processObjectCreateSetCall(Node callNode) { Node curParam = callNode.getSecondChild(); if (canOptimizeObjectCreateSet(curParam)) { Node objNode = IR.objectlit().srcref(callNode); while (curParam != null) { Node keyNode = curParam; Node valueNode = IR.trueNode().srcref(keyNode); curParam = curParam.getNext(); callNode.removeChild(keyNode); addKeyValueToObjLit(objNode, keyNode, valueNode); } callNode.replaceWith(objNode); compiler.reportChangeToEnclosingScope(objNode); } }
/** Adds an ES5 getter to the given object literal to use an an export. */ private void addExport(Node definePropertiesLit, String exportedName, LocalQName localQName) { Node exportedValue = NodeUtil.newQName(compiler, localQName.qName); Node getterFunction = IR.function(IR.name(""), IR.paramList(), IR.block(IR.returnNode(exportedValue))); getterFunction.useSourceInfoFromForTree(localQName.nodeForSourceInfo); Node objLit = IR.objectlit( IR.stringKey("enumerable", IR.trueNode()), IR.stringKey("get", getterFunction)); definePropertiesLit.addChildToBack(IR.stringKey(exportedName, objLit)); compiler.reportChangeToChangeScope(getterFunction); }
private Node addMarker( FunctionType funType, Node nodeToInsertAfter, @Nullable ObjectType interfaceType) { if (funType.getSource() == null) { return nodeToInsertAfter; } String className = NodeUtil.getName(funType.getSource()); // This can happen with anonymous classes declared with the type // {@code Function}. if (className == null) { return nodeToInsertAfter; } Node classNode = NodeUtil.newQName( compiler, className); Node marker = IR.string( interfaceType == null ? "instance_of__" + className : "implements__" + interfaceType.getReferenceName()); Node assign = IR.exprResult(IR.assign( IR.getelem( IR.getprop( classNode, IR.string("prototype")), marker), IR.trueNode())); nodeToInsertAfter.getParent().addChildAfter(assign, nodeToInsertAfter); compiler.reportCodeChange(); nodeToInsertAfter = assign; return nodeToInsertAfter; }
currCase .getLastChild() .addChildToFront(IR.exprResult(IR.assign(didEnter.cloneTree(), IR.trueNode()))); if (currCase.isDefaultCase()) { if (currentStatement.hasChildren()) {
/** * Converts all of the given call nodes to object literals that are safe to * do so. */ private void processObjectCreateSetCall(Node callNode) { Node curParam = callNode.getSecondChild(); if (canOptimizeObjectCreateSet(curParam)) { Node objNode = IR.objectlit().srcref(callNode); while (curParam != null) { Node keyNode = curParam; Node valueNode = IR.trueNode().srcref(keyNode); curParam = curParam.getNext(); callNode.removeChild(keyNode); if (!keyNode.isString()) { keyNode = IR.string(NodeUtil.getStringValue(keyNode)) .srcref(keyNode); } keyNode.setType(Token.STRING_KEY); keyNode.setQuotedString(); objNode.addChildToBack(IR.propdef(keyNode, valueNode)); } callNode.getParent().replaceChild(callNode, objNode); compiler.reportCodeChange(); } }
if (!guard.isEmpty()) { Node firstEntry = IR.name(GENERATOR_DO_WHILE_INITIAL); enclosingBlock.addChildToFront(IR.var(firstEntry.cloneTree(), IR.trueNode())); guard = IR.or(firstEntry, n.getLastChild().detachFromParent()); n.addChildToBack(guard);