static boolean isValidDefineValue(Node val) { switch (val.getToken()) { case STRING: case NUMBER: case TRUE: case FALSE: return true; case NEG: return val.getFirstChild().isNumber(); default: return false; } }
static boolean isValidDefineValue(Node val) { switch (val.getType()) { case Token.STRING: case Token.NUMBER: case Token.TRUE: case Token.FALSE: return true; case Token.NEG: return val.getFirstChild().isNumber(); default: return false; } }
private boolean isOptimizableKey(Node curParam) { if (this.canUseEs6Syntax) { return !NodeUtil.isStatement(curParam); } else { // Not ES6, all keys must be strings or numbers. return curParam.isString() || curParam.isNumber(); } }
/** * Returns whether the given call to goog.object.create can be converted to an * object literal. */ private static boolean canOptimizeObjectCreateSet(Node firstParam) { Node curParam = firstParam; while (curParam != null) { // All keys must be strings or numbers. if (!curParam.isString() && !curParam.isNumber()) { return false; } curParam = curParam.getNext(); } return true; } }
/** * Try to evaluate known Numeric methods * parseInt(), parseFloat() */ private Node tryFoldKnownNumericMethods(Node subtree, Node callTarget) { checkArgument(subtree.isCall()); if (isASTNormalized()) { // check if this is a call on a string method // then dispatch to specific folding method. String functionNameString = callTarget.getString(); Node firstArgument = callTarget.getNext(); if ((firstArgument != null) && (firstArgument.isString() || firstArgument.isNumber()) && (functionNameString.equals("parseInt") || functionNameString.equals("parseFloat"))) { subtree = tryFoldParseNumber(subtree, functionNameString, firstArgument); } } return subtree; }
/** * Returns whether the given call to goog.object.create can be converted to an * object literal. */ private static boolean canOptimizeObjectCreate(Node firstParam) { Node curParam = firstParam; while (curParam != null) { // All keys must be strings or numbers. if (!curParam.isString() && !curParam.isNumber()) { return false; } curParam = curParam.getNext(); // Check for an odd number of parameters. if (curParam == null) { return false; } curParam = curParam.getNext(); } return true; }
private void checkDuplicateEnumValues(NodeTraversal t, Node n) { Set<String> values = new HashSet<>(); for (Node child : n.children()) { Node valueNode = child.getLastChild(); String value; if (valueNode == null) { return; } else if (valueNode.isString()) { value = valueNode.getString(); } else if (valueNode.isNumber()) { value = Double.toString(valueNode.getDouble()); } else { return; } if (!values.add(value)) { t.report(valueNode, DUPLICATE_ENUM_VALUE, value); } } } }
private void checkDuplicateEnumValues(NodeTraversal t, Node n) { Set<String> values = new HashSet<String>(); for (Node child : n.children()) { Node valueNode = child.getLastChild(); String value; if (valueNode == null) { return; } else if (valueNode.isString()) { value = valueNode.getString(); } else if (valueNode.isNumber()) { value = Double.toString(valueNode.getDouble()); } else { return; } if (!values.add(value)) { t.report(valueNode, DUPLICATE_ENUM_VALUE, value); } } } }
public static String getCommonJsImportPath( Node requireCall, ModuleLoader.ResolutionMode resolutionMode) { if (resolutionMode == ModuleLoader.ResolutionMode.WEBPACK) { Node pathArgument = requireCall.getChildCount() >= 3 ? requireCall.getChildAtIndex(2) : requireCall.getSecondChild(); if (pathArgument.isNumber()) { return String.valueOf((int) pathArgument.getDouble()); } else { return pathArgument.getString(); } } return requireCall.getSecondChild().getString(); }
private Node tryReduceVoid(Node n) { Node child = n.getFirstChild(); if ((!child.isNumber() || child.getDouble() != 0.0) && !mayHaveSideEffects(n)) { n.replaceChild(child, IR.number(0)); reportChangeToEnclosingScope(n); } return n; }
private void addKeyValueToObjLit(Node objNode, Node keyNode, Node valueNode) { if (keyNode.isNumber() || keyNode.isString()) { if (keyNode.isNumber()) { keyNode = IR.string(numberToString(keyNode.getDouble())) .srcref(keyNode); } keyNode.setToken(Token.STRING_KEY); keyNode.setQuotedString(); objNode.addChildToBack(IR.propdef(keyNode, valueNode)); } else { objNode.addChildToBack(IR.computedProp(keyNode, valueNode).srcref(keyNode)); } }
private Node tryReduceVoid(Node n) { Node child = n.getFirstChild(); if ((!child.isNumber() || child.getDouble() != 0.0) && !mayHaveSideEffects(n)) { n.replaceChild(child, IR.number(0)); reportCodeChange(); } return n; }
private Node transformMembers(Node members, boolean enumIsOfNumberType) { assert members.isObjectLit(); int lastCount = -1; Node enumMembers = new Node(Token.ENUM_MEMBERS); for (Node child : members.children()) { Node name = Node.newString(Token.NAME, child.getString()); Node value = child.getFirstChild().detach(); Node newMember; // Check whether we can emit simply the name, and rely on the automatic numeric assignment // in TypeScript. For example, enum E { A, B } is equivalent to enum E { A = 0, B = 1 }. if (enumIsOfNumberType && value.isNumber() && value.getDouble() == lastCount + 1) { newMember = name; } else { // We cannot reuse the STRING_KEY node here, because it pretty prints as a: 0, and we // want a = 1. Instead we recreate an ASSIGN node with same contents as STRING_KEY newMember = new Node(Token.ASSIGN, name, value); } if (enumIsOfNumberType && value.isNumber()) { lastCount = (int) value.getDouble(); } enumMembers.addChildToBack(newMember); nodeComments.moveComment(child, newMember); } return enumMembers; } }
/** * Applies optimizations to all previously marked nodes. */ public void applyChanges() { for (Node n : toRemove) { // Don't remove any nodes twice since doing so would violate change reporting constraints. if (alreadyRemoved(n)) { continue; } compiler.reportChangeToEnclosingScope(n); n.detach(); NodeUtil.markFunctionsDeleted(n, compiler); } for (Node n : toReplaceWithZero) { Preconditions.checkState(!n.isNumber() || n.getDouble() != 0.0); // Don't remove any nodes twice since doing so would violate change reporting constraints. if (alreadyRemoved(n)) { continue; } compiler.reportChangeToEnclosingScope(n); n.replaceWith(IR.number(0).srcref(n)); NodeUtil.markFunctionsDeleted(n, compiler); } } }
Node processUnaryExpression(UnaryExpressionTree exprNode) { Token type = transformUnaryTokenType(exprNode.operator.type); Node operand = transform(exprNode.operand); if (type == Token.NEG && operand.isNumber()) { operand.setDouble(-operand.getDouble()); return operand; } else { if (type == Token.DELPROP && !(operand.isGetProp() || operand.isGetElem() || operand.isName())) { String msg = "Invalid delete operand. Only properties can be deleted."; errorReporter.error( msg, sourceName, operand.getLineno(), 0); } return newNode(type, operand); } }
private Node reduceSubstractionAssignment(Node n) { Node right = n.getLastChild(); if (right.isNumber()) { if (right.getDouble() == 1) { Node newNode = IR.dec(n.removeFirstChild(), false); n.replaceWith(newNode); reportChangeToEnclosingScope(newNode); return newNode; } else if (right.getDouble() == -1) { Node newNode = IR.inc(n.removeFirstChild(), false); n.replaceWith(newNode); reportChangeToEnclosingScope(newNode); return newNode; } } return n; }
private Node reduceSubstractionAssignment(Node n) { Node right = n.getLastChild(); if (right.isNumber()) { if (right.getDouble() == 1) { Node newNode = IR.dec(n.removeFirstChild(), false); n.getParent().replaceChild(n, newNode); reportCodeChange(); return newNode; } else if (right.getDouble() == -1) { Node newNode = IR.inc(n.removeFirstChild(), false); n.getParent().replaceChild(n, newNode); reportCodeChange(); return newNode; } } return n; }
Node processUnaryExpression(UnaryExpressionTree exprNode) { int type = transformUnaryTokenType(exprNode.operator.type); Node operand = transform(exprNode.operand); if (type == Token.NEG && operand.isNumber()) { operand.setDouble(-operand.getDouble()); return operand; } else { if (type == Token.DELPROP && !(operand.isGetProp() || operand.isGetElem() || operand.isName())) { String msg = "Invalid delete operand. Only properties can be deleted."; errorReporter.error( msg, sourceName, operand.getLineno(), 0); } else if (type == Token.INC || type == Token.DEC) { return createIncrDecrNode(type, false, operand); } return newNode(type, operand); } }