| Index: src/preparser.h
|
| diff --git a/src/preparser.h b/src/preparser.h
|
| index 3a68bed6c9f8e23769fe258735d7831a98fc40f3..d0c7e3e198f8eb4e2f417f0b1f5b74ace00ad45a 100644
|
| --- a/src/preparser.h
|
| +++ b/src/preparser.h
|
| @@ -347,6 +347,8 @@ class PreParser : public ParserBase {
|
| // if bit 1 is set, it's a string literal.
|
| // If neither is set, it's no particular type, and both set isn't
|
| // use yet.
|
| + // Bit 2 is used to mark the expression as being parenthesized,
|
| + // so "(foo)" isn't recognized as a pure identifier (and possible label).
|
| class Expression {
|
| public:
|
| static Expression Default() {
|
| @@ -387,8 +389,21 @@ class PreParser : public ParserBase {
|
| static_cast<PreParser::Identifier::Type>(code_ >> kIdentifierShift));
|
| }
|
|
|
| + bool IsParenthesized() {
|
| + // If bit 0 or 1 is set, we interpret bit 2 as meaning parenthesized.
|
| + return (code_ & 7) > 4;
|
| + }
|
| +
|
| + bool IsRawIdentifier() {
|
| + return !IsParenthesized() && IsIdentifier();
|
| + }
|
| +
|
| bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; }
|
|
|
| + bool IsRawStringLiteral() {
|
| + return !IsParenthesized() && IsStringLiteral();
|
| + }
|
| +
|
| bool IsUseStrictLiteral() {
|
| return (code_ & kStringLiteralMask) == kUseStrictString;
|
| }
|
| @@ -405,10 +420,27 @@ class PreParser : public ParserBase {
|
| return code_ == kStrictFunctionExpression;
|
| }
|
|
|
| + Expression Parenthesize() {
|
| + int type = code_ & 3;
|
| + if (type != 0) {
|
| + // Identifiers and string literals can be parenthesized.
|
| + // They no longer work as labels or directive prologues,
|
| + // but are still recognized in other contexts.
|
| + return Expression(code_ | kParenthesizedExpressionFlag);
|
| + }
|
| + // For other types of expressions, it's not important to remember
|
| + // the parentheses.
|
| + return *this;
|
| + }
|
| +
|
| private:
|
| // First two/three bits are used as flags.
|
| // Bit 0 and 1 represent identifiers or strings literals, and are
|
| // mutually exclusive, but can both be absent.
|
| + // If bit 0 or 1 are set, bit 2 marks that the expression has
|
| + // been wrapped in parentheses (a string literal can no longer
|
| + // be a directive prologue, and an identifier can no longer be
|
| + // a label.
|
| enum {
|
| kUnknownExpression = 0,
|
| // Identifiers
|
| @@ -420,6 +452,9 @@ class PreParser : public ParserBase {
|
| kUseStrictString = kStringLiteralFlag | 8,
|
| kStringLiteralMask = kUseStrictString,
|
|
|
| + // Only if identifier or string literal.
|
| + kParenthesizedExpressionFlag = 4,
|
| +
|
| // Below here applies if neither identifier nor string literal.
|
| kThisExpression = 4,
|
| kThisPropertyExpression = 8,
|
| @@ -445,11 +480,13 @@ class PreParser : public ParserBase {
|
| // Preserves being an unparenthesized string literal, possibly
|
| // "use strict".
|
| static Statement ExpressionStatement(Expression expression) {
|
| - if (expression.IsUseStrictLiteral()) {
|
| - return Statement(kUseStrictExpressionStatement);
|
| - }
|
| - if (expression.IsStringLiteral()) {
|
| - return Statement(kStringLiteralExpressionStatement);
|
| + if (!expression.IsParenthesized()) {
|
| + if (expression.IsUseStrictLiteral()) {
|
| + return Statement(kUseStrictExpressionStatement);
|
| + }
|
| + if (expression.IsStringLiteral()) {
|
| + return Statement(kStringLiteralExpressionStatement);
|
| + }
|
| }
|
| return Default();
|
| }
|
|
|