private Token createToken(TokenType type, int beginToken) { return new Token(type, getTokenRange(beginToken)); }
/** * Transforms the given node and then sets its type to Token.STRING if it * was Token.NAME. If its type was already Token.STRING, then quotes it. * Used for properties, as the old AST uses String tokens, while the new one * uses Name tokens for unquoted strings. For example, in * var o = {'a' : 1, b: 2}; * the string 'a' is quoted, while the name b is turned into a string, but * unquoted. */ private Node processObjectLitKeyAsString( com.google.javascript.jscomp.parsing.parser.Token token) { Node ret; if (token == null) { return createMissingExpressionNode(); } else if (token.type == TokenType.IDENTIFIER) { ret = processName(token.asIdentifier(), true); } else if (token.type == TokenType.NUMBER) { ret = transformNumberAsString(token.asLiteral()); ret.putBooleanProp(Node.QUOTED_PROP, true); } else { ret = processString(token.asLiteral()); ret.putBooleanProp(Node.QUOTED_PROP, true); } checkState(ret.isString()); return ret; }
/** * Reports an error message at a given token. * @param token The location to report the message at. * @param message The message to report in String.format style. * @param arguments The arguments to fill in the message format. */ private void reportError(Token token, String message, Object... arguments) { if (token == null) { reportError(message, arguments); } else { errorReporter.reportError(token.getStart(), message, arguments); } }
Node processTemplateLiteralPortion(TemplateLiteralPortionTree tree) { return processTemplateLiteralToken(tree.value.asLiteral()); }
private Token eatPredefinedString(String string) { Token token = eatId(); if (token == null || !token.asIdentifier().value.equals(string)) { reportExpectedError(token, string); return null; } return token; }
Node processTemplateLiteralPortion(TemplateLiteralPortionTree tree) { return processTemplateLiteralToken(tree.value.asTemplateLiteral()); }
Node processStringLiteral(LiteralExpressionTree literalTree) { LiteralToken token = literalTree.literalToken.asLiteral(); Node n = processString(token); String value = n.getString(); if (value.indexOf('\u000B') != -1) { // NOTE(nicksantos): In JavaScript, there are 3 ways to // represent a vertical tab: \v, \x0B, \u000B. // The \v notation was added later, and is not understood // on IE. So we need to preserve it as-is. This is really // obnoxious, because we do not have a good way to represent // how the original string was encoded without making the // representation of strings much more complicated. // // To handle this, we look at the original source test, and // mark the string as \v-encoded or not. If a string is // \v encoded, then all the vertical tabs in that string // will be encoded with a \v. int start = token.location.start.offset; int end = token.location.end.offset; if (start < sourceString.length() && (sourceString.substring( start, Math.min(sourceString.length(), end)).contains("\\v"))) { n.putBooleanProp(Node.SLASH_V, true); } } return n; }
private Token eatPredefinedString(String string) { Token token = eatId(); if (token == null || !token.asIdentifier().value.equals(string)) { reportExpectedError(token, string); return null; } return token; }
Node processStringLiteral(LiteralExpressionTree literalTree) { LiteralToken token = literalTree.literalToken.asLiteral(); Node n = processString(token); String value = n.getString(); if (value.indexOf('\u000B') != -1) { // NOTE(nicksantos): In JavaScript, there are 3 ways to // represent a vertical tab: \v, \x0B, \u000B. // The \v notation was added later, and is not understood // on IE. So we need to preserve it as-is. This is really // obnoxious, because we do not have a good way to represent // how the original string was encoded without making the // representation of strings much more complicated. // // To handle this, we look at the original source test, and // mark the string as \v-encoded or not. If a string is // \v encoded, then all the vertical tabs in that string // will be encoded with a \v. int start = token.location.start.offset; int end = token.location.end.offset; if (start < sourceString.length() && (sourceString.substring( start, Math.min(sourceString.length(), end)).contains("\\v"))) { n.putBooleanProp(Node.SLASH_V, true); } } return n; }
/** * Transforms the given node and then sets its type to Token.STRING if it * was Token.NAME. If its type was already Token.STRING, then quotes it. * Used for properties, as the old AST uses String tokens, while the new one * uses Name tokens for unquoted strings. For example, in * var o = {'a' : 1, b: 2}; * the string 'a' is quoted, while the name b is turned into a string, but * unquoted. */ private Node processObjectLitKeyAsString( com.google.javascript.jscomp.parsing.parser.Token token) { Node ret; if (token == null) { return createMissingExpressionNode(); } else if (token.type == TokenType.IDENTIFIER) { ret = processName(token.asIdentifier(), true); } else if (token.type == TokenType.NUMBER) { ret = transformNumberAsString(token.asLiteral()); ret.putBooleanProp(Node.QUOTED_PROP, true); } else { ret = processString(token.asLiteral()); ret.putBooleanProp(Node.QUOTED_PROP, true); } Preconditions.checkState(ret.isString()); return ret; }
/** * Processes property name assignments in an object pattern. * * <p>Covers these cases. * * <pre><code> * let {name} = someObject; * let {key: name} = someObject; * let {key: name = something} = someObject; * </code></pre> */ private Node processObjectPatternPropertyNameAssignment( PropertyNameAssignmentTree propertyNameAssignment) { Node key = processObjectLitKeyAsString(propertyNameAssignment.name); key.setToken(Token.STRING_KEY); ParseTree targetTree = propertyNameAssignment.value; final Node valueNode; if (targetTree == null) { // `let { /** inlineType */ key } = something;` // The key is also the target name. valueNode = processNameWithInlineJSDoc(propertyNameAssignment.name.asIdentifier()); key.setShorthandProperty(true); } else { valueNode = processDestructuringElementTarget(targetTree); } key.addChildToFront(valueNode); return key; }
private Token createToken(TokenType type, int beginToken) { return new Token(type, getTokenRange(beginToken)); }
/** * Reports an error message at a given token. * @param token The location to report the message at. * @param message The message to report in String.format style. * @param arguments The arguments to fill in the message format. */ @FormatMethod private void reportError(Token token, @FormatString String message, Object... arguments) { if (token == null) { reportError(message, arguments); } else { errorReporter.reportError(token.getStart(), message, arguments); } }
Node processNumberLiteral(LiteralExpressionTree literalNode) { double value = normalizeNumber(literalNode.literalToken.asLiteral()); Node number = newNumberNode(value); setSourceInfo(number, literalNode); return number; }
private ParseTree parsePropertyNameAssignment() { SourcePosition start = getTreeStartLocation(); Token name = eatObjectLiteralPropertyName(); Token colon = eatOpt(TokenType.COLON); if (colon == null) { if (name.type != TokenType.IDENTIFIER) { reportExpectedError(peekToken(), TokenType.COLON); } else if (Keywords.isKeyword(name.asIdentifier().value) && !Keywords.isTypeScriptSpecificKeyword(name.asIdentifier().value)) { reportError(name, "Cannot use keyword in short object literal"); } else if (peek(TokenType.EQUAL)) { IdentifierExpressionTree idTree = new IdentifierExpressionTree( getTreeLocation(start), (IdentifierToken) name); eat(TokenType.EQUAL); ParseTree defaultValue = parseAssignmentExpression(); return new DefaultParameterTree(getTreeLocation(start), idTree, defaultValue); } } ParseTree value = colon == null ? null : parseAssignmentExpression(); return new PropertyNameAssignmentTree(getTreeLocation(start), name, value); }
return new Token(Keywords.getTokenType(value), getTokenRange(beginToken));
Node processNumberLiteral(LiteralExpressionTree literalNode) { double value = normalizeNumber(literalNode.literalToken.asLiteral()); Node number = newNumberNode(value); setSourceInfo(number, literalNode); return number; }
private ParseTree parsePropertyNameAssignment() { SourcePosition start = getTreeStartLocation(); Token name = eatObjectLiteralPropertyName(); Token colon = eatOpt(TokenType.COLON); if (colon == null) { if (name.type != TokenType.IDENTIFIER) { reportExpectedError(peekToken(), TokenType.COLON); } else if (Keywords.isKeyword( name.asIdentifier().value, /* includeTypeScriptKeywords= */ false)) { reportError(name, "Cannot use keyword in short object literal"); } else if (peek(TokenType.EQUAL)) { IdentifierExpressionTree idTree = new IdentifierExpressionTree( getTreeLocation(start), (IdentifierToken) name); eat(TokenType.EQUAL); ParseTree defaultValue = parseAssignmentExpression(); return new DefaultParameterTree(getTreeLocation(start), idTree, defaultValue); } } ParseTree value = colon == null ? null : parseAssignmentExpression(); return new PropertyNameAssignmentTree(getTreeLocation(start), name, value); }
return new Token(k.type, getTokenRange(beginToken));
Node processRegExpLiteral(LiteralExpressionTree literalTree) { LiteralToken token = literalTree.literalToken.asLiteral(); Node literalStringNode = newStringNode(normalizeRegex(token)); // TODO(johnlenz): fix the source location. setSourceInfo(literalStringNode, token); Node node = newNode(Token.REGEXP, literalStringNode); String rawRegex = token.value; int lastSlash = rawRegex.lastIndexOf('/'); String flags = ""; if (lastSlash < rawRegex.length()) { flags = rawRegex.substring(lastSlash + 1); } validateRegExpFlags(literalTree, flags); if (!flags.isEmpty()) { Node flagsNode = newStringNode(flags); // TODO(johnlenz): fix the source location. setSourceInfo(flagsNode, token); node.addChildToBack(flagsNode); } return node; }