| Index: src/parsing/parser-base.h
|
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h
|
| index 46689d54c02bcb645cc658ef7481349764a85c5a..f4cfc4974ccfec9470fdfec7bdd8ea1df5cec62c 100644
|
| --- a/src/parsing/parser-base.h
|
| +++ b/src/parsing/parser-base.h
|
| @@ -29,6 +29,32 @@ enum AllowLabelledFunctionStatement {
|
| kDisallowLabelledFunctionStatement,
|
| };
|
|
|
| +enum class ParseFunctionFlags {
|
| + kIsNormal = 0,
|
| + kIsGenerator = 1,
|
| + kIsAsync = 2,
|
| + kIsDefault = 4
|
| +};
|
| +
|
| +static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs,
|
| + ParseFunctionFlags rhs) {
|
| + typedef unsigned char T;
|
| + return static_cast<ParseFunctionFlags>(static_cast<T>(lhs) |
|
| + static_cast<T>(rhs));
|
| +}
|
| +
|
| +static inline ParseFunctionFlags& operator|=(ParseFunctionFlags& lhs,
|
| + const ParseFunctionFlags& rhs) {
|
| + lhs = lhs | rhs;
|
| + return lhs;
|
| +}
|
| +
|
| +static inline bool operator&(ParseFunctionFlags bitfield,
|
| + ParseFunctionFlags mask) {
|
| + typedef unsigned char T;
|
| + return static_cast<T>(bitfield) & static_cast<T>(mask);
|
| +}
|
| +
|
| struct FormalParametersBase {
|
| explicit FormalParametersBase(Scope* scope) : scope(scope) {}
|
| Scope* scope;
|
| @@ -116,7 +142,8 @@ class ParserBase : public Traits {
|
| allow_harmony_restrictive_declarations_(false),
|
| allow_harmony_do_expressions_(false),
|
| allow_harmony_function_name_(false),
|
| - allow_harmony_function_sent_(false) {}
|
| + allow_harmony_function_sent_(false),
|
| + allow_harmony_async_await_(false) {}
|
|
|
| #define ALLOW_ACCESSORS(name) \
|
| bool allow_##name() const { return allow_##name##_; } \
|
| @@ -135,6 +162,7 @@ class ParserBase : public Traits {
|
| ALLOW_ACCESSORS(harmony_do_expressions);
|
| ALLOW_ACCESSORS(harmony_function_name);
|
| ALLOW_ACCESSORS(harmony_function_sent);
|
| + ALLOW_ACCESSORS(harmony_async_await);
|
| SCANNER_ACCESSORS(harmony_exponentiation_operator);
|
|
|
| #undef SCANNER_ACCESSORS
|
| @@ -224,6 +252,7 @@ class ParserBase : public Traits {
|
| }
|
|
|
| bool is_generator() const { return IsGeneratorFunction(kind_); }
|
| + bool is_async_function() const { return IsAsyncFunction(kind_); }
|
|
|
| FunctionKind kind() const { return kind_; }
|
| FunctionState* outer() const { return outer_function_state_; }
|
| @@ -467,6 +496,11 @@ class ParserBase : public Traits {
|
| scanner()->is_next_contextual_keyword(keyword);
|
| }
|
|
|
| + bool PeekAheadContextualKeyword(Vector<const char> keyword) {
|
| + return PeekAhead() == Token::IDENTIFIER &&
|
| + scanner()->is_next_next_contextual_keyword(keyword);
|
| + }
|
| +
|
| void ExpectMetaProperty(Vector<const char> property_name,
|
| const char* full_name, int pos, bool* ok);
|
|
|
| @@ -557,6 +591,9 @@ class ParserBase : public Traits {
|
|
|
| LanguageMode language_mode() { return scope_->language_mode(); }
|
| bool is_generator() const { return function_state_->is_generator(); }
|
| + bool is_async_function() const {
|
| + return function_state_->is_async_function();
|
| + }
|
|
|
| // Report syntax errors.
|
| void ReportMessage(MessageTemplate::Template message, const char* arg = NULL,
|
| @@ -643,7 +680,8 @@ class ParserBase : public Traits {
|
|
|
| void ValidateArrowFormalParameters(const ExpressionClassifier* classifier,
|
| ExpressionT expr,
|
| - bool parenthesized_formals, bool* ok) {
|
| + bool parenthesized_formals, bool is_async,
|
| + bool* ok) {
|
| if (classifier->is_valid_binding_pattern()) {
|
| // A simple arrow formal parameter: IDENTIFIER => BODY.
|
| if (!this->IsIdentifier(expr)) {
|
| @@ -663,6 +701,12 @@ class ParserBase : public Traits {
|
| ReportClassifierError(error);
|
| *ok = false;
|
| }
|
| + if (is_async && !classifier->is_valid_async_arrow_formal_parameters()) {
|
| + const typename ExpressionClassifier::Error& error =
|
| + classifier->async_arrow_formal_parameters_error();
|
| + ReportClassifierError(error);
|
| + *ok = false;
|
| + }
|
| }
|
|
|
| void ValidateLetPattern(const ExpressionClassifier* classifier, bool* ok) {
|
| @@ -736,13 +780,18 @@ class ParserBase : public Traits {
|
| ExpressionClassifier* classifier, bool* ok);
|
|
|
| ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
|
| - bool* ok);
|
| + bool* is_async, bool* ok);
|
| + ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
|
| + bool* ok) {
|
| + bool is_async;
|
| + return ParsePrimaryExpression(classifier, &is_async, ok);
|
| + }
|
| ExpressionT ParseExpression(bool accept_IN, bool* ok);
|
| ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
|
| bool* ok);
|
| ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
|
| ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
|
| - bool* is_computed_name,
|
| + bool* is_await, bool* is_computed_name,
|
| ExpressionClassifier* classifier, bool* ok);
|
| ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
|
| ObjectLiteralPropertyT ParsePropertyDefinition(
|
| @@ -750,8 +799,13 @@ class ParserBase : public Traits {
|
| bool is_static, bool* is_computed_name, bool* has_seen_constructor,
|
| ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
|
| typename Traits::Type::ExpressionList ParseArguments(
|
| + Scanner::Location* first_spread_pos, bool maybe_arrow,
|
| + ExpressionClassifier* classifier, bool* ok);
|
| + typename Traits::Type::ExpressionList ParseArguments(
|
| Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
|
| - bool* ok);
|
| + bool* ok) {
|
| + return ParseArguments(first_spread_pos, false, classifier, ok);
|
| + }
|
|
|
| ExpressionT ParseAssignmentExpression(bool accept_IN,
|
| ExpressionClassifier* classifier,
|
| @@ -768,12 +822,15 @@ class ParserBase : public Traits {
|
| ExpressionT ParseLeftHandSideExpression(ExpressionClassifier* classifier,
|
| bool* ok);
|
| ExpressionT ParseMemberWithNewPrefixesExpression(
|
| - ExpressionClassifier* classifier, bool* ok);
|
| - ExpressionT ParseMemberExpression(ExpressionClassifier* classifier, bool* ok);
|
| + ExpressionClassifier* classifier, bool* is_async, bool* ok);
|
| + ExpressionT ParseMemberExpression(ExpressionClassifier* classifier,
|
| + bool* is_async, bool* ok);
|
| ExpressionT ParseMemberExpressionContinuation(
|
| - ExpressionT expression, ExpressionClassifier* classifier, bool* ok);
|
| + ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
|
| + bool* ok);
|
| ExpressionT ParseArrowFunctionLiteral(bool accept_IN,
|
| const FormalParametersT& parameters,
|
| + bool is_async,
|
| const ExpressionClassifier& classifier,
|
| bool* ok);
|
| ExpressionT ParseTemplateLiteral(ExpressionT tag, int start,
|
| @@ -916,6 +973,7 @@ class ParserBase : public Traits {
|
| bool allow_harmony_do_expressions_;
|
| bool allow_harmony_function_name_;
|
| bool allow_harmony_function_sent_;
|
| + bool allow_harmony_async_await_;
|
| };
|
|
|
| template <class Traits>
|
| @@ -1067,6 +1125,14 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
|
| scanner()->location(), MessageTemplate::kStrictEvalArguments);
|
| }
|
| }
|
| + if (this->IsAwait(name)) {
|
| + if (is_async_function()) {
|
| + classifier->RecordPatternError(
|
| + scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
|
| + }
|
| + classifier->RecordAsyncArrowFormalParametersError(
|
| + scanner()->location(), MessageTemplate::kAwaitBindingIdentifier);
|
| + }
|
|
|
| if (classifier->duplicate_finder() != nullptr &&
|
| scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
|
| @@ -1119,6 +1185,7 @@ ParserBase<Traits>::ParseIdentifierOrStrictReservedWord(
|
|
|
| IdentifierT name = this->GetSymbol(scanner());
|
| if (this->IsArguments(name)) scope_->RecordArgumentsUsage();
|
| +
|
| return name;
|
| }
|
|
|
| @@ -1183,11 +1250,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseRegExpLiteral(
|
| #define DUMMY ) // to make indentation work
|
| #undef DUMMY
|
|
|
| -
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
| - bool* ok) {
|
| + bool* is_async, bool* ok) {
|
| // PrimaryExpression ::
|
| // 'this'
|
| // 'null'
|
| @@ -1203,6 +1269,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
| // '(' Expression ')'
|
| // TemplateLiteral
|
| // do Block
|
| + // AsyncFunctionExpression
|
|
|
| int beg_pos = peek_position();
|
| switch (peek()) {
|
| @@ -1223,6 +1290,17 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
|
| return this->ExpressionFromLiteral(Next(), beg_pos, scanner(), factory());
|
|
|
| case Token::IDENTIFIER:
|
| + if (allow_harmony_async_await() &&
|
| + PeekContextualKeyword(CStrVector("async")) &&
|
| + !scanner()->HasAnyLineTerminatorAfterNext()) {
|
| + if (PeekAhead() == Token::FUNCTION) {
|
| + Consume(Token::IDENTIFIER);
|
| + return this->ParseAsyncFunctionExpression(CHECK_OK);
|
| + }
|
| + // CoverCallExpressionAndAsyncArrowHead
|
| + *is_async = true;
|
| + }
|
| + /* Falls through */
|
| case Token::LET:
|
| case Token::STATIC:
|
| case Token::YIELD:
|
| @@ -1489,11 +1567,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseArrayLiteral(
|
| return result;
|
| }
|
|
|
| -
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
|
| - IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name,
|
| - ExpressionClassifier* classifier, bool* ok) {
|
| + IdentifierT* name, bool* is_get, bool* is_set, bool* is_await,
|
| + bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
|
| Token::Value token = peek();
|
| int pos = peek_position();
|
|
|
| @@ -1538,6 +1615,9 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParsePropertyName(
|
| default:
|
| *name = ParseIdentifierName(CHECK_OK);
|
| scanner()->IsGetOrSet(is_get, is_set);
|
| + if (this->IsAwait(*name)) {
|
| + *is_await = true;
|
| + }
|
| break;
|
| }
|
|
|
| @@ -1558,14 +1638,22 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| ExpressionT value = this->EmptyExpression();
|
| bool is_get = false;
|
| bool is_set = false;
|
| + bool is_await = false;
|
| bool is_generator = Check(Token::MUL);
|
|
|
| Token::Value name_token = peek();
|
| +
|
| + bool is_async = allow_harmony_async_await() && !is_generator &&
|
| + name_token == Token::IDENTIFIER &&
|
| + PeekContextualKeyword(CStrVector("async")) &&
|
| + !scanner()->HasAnyLineTerminatorAfterNext() &&
|
| + PeekAhead() != Token::LPAREN;
|
| +
|
| int next_beg_pos = scanner()->peek_location().beg_pos;
|
| int next_end_pos = scanner()->peek_location().end_pos;
|
| - ExpressionT name_expression =
|
| - ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier,
|
| - CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + ExpressionT name_expression = ParsePropertyName(
|
| + name, &is_get, &is_set, &is_await, is_computed_name, classifier,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
|
|
| if (fni_ != nullptr && !*is_computed_name) {
|
| this->PushLiteralName(fni_, *name);
|
| @@ -1610,7 +1698,11 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| classifier->RecordLetPatternError(
|
| scanner()->location(), MessageTemplate::kLetInLexicalBinding);
|
| }
|
| -
|
| + if (is_await && is_async_function()) {
|
| + classifier->RecordPatternError(
|
| + Scanner::Location(next_beg_pos, next_end_pos),
|
| + MessageTemplate::kAwaitBindingIdentifier);
|
| + }
|
| ExpressionT lhs = this->ExpressionFromIdentifier(
|
| *name, next_beg_pos, next_end_pos, scope_, factory());
|
| CheckDestructuringElement(lhs, classifier, next_beg_pos, next_end_pos);
|
| @@ -1648,6 +1740,16 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| Scanner::Location(next_beg_pos, scanner()->location().end_pos),
|
| MessageTemplate::kInvalidDestructuringTarget);
|
|
|
| + if (is_async) {
|
| + DCHECK(!is_generator);
|
| + DCHECK(!is_get);
|
| + DCHECK(!is_set);
|
| + bool dont_care;
|
| + name_expression = ParsePropertyName(
|
| + name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
|
| + CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| + }
|
| +
|
| if (is_generator || peek() == Token::LPAREN) {
|
| // MethodDefinition
|
| // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
|
| @@ -1658,8 +1760,10 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
| }
|
|
|
| - FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod
|
| - : FunctionKind::kConciseMethod;
|
| + FunctionKind kind = is_generator
|
| + ? FunctionKind::kConciseGeneratorMethod
|
| + : is_async ? FunctionKind::kAsyncConciseMethod
|
| + : FunctionKind::kConciseMethod;
|
|
|
| if (in_class && !is_static && this->IsConstructor(*name)) {
|
| *has_seen_constructor = true;
|
| @@ -1697,7 +1801,7 @@ ParserBase<Traits>::ParsePropertyDefinition(
|
| name_token = peek();
|
|
|
| name_expression = ParsePropertyName(
|
| - name, &dont_care, &dont_care, is_computed_name, classifier,
|
| + name, &dont_care, &dont_care, &dont_care, is_computed_name, classifier,
|
| CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
|
|
|
| if (!*is_computed_name) {
|
| @@ -1792,11 +1896,10 @@ typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseObjectLiteral(
|
| pos);
|
| }
|
|
|
| -
|
| template <class Traits>
|
| typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
|
| - Scanner::Location* first_spread_arg_loc, ExpressionClassifier* classifier,
|
| - bool* ok) {
|
| + Scanner::Location* first_spread_arg_loc, bool maybe_arrow,
|
| + ExpressionClassifier* classifier, bool* ok) {
|
| // Arguments ::
|
| // '(' (AssignmentExpression)*[','] ')'
|
|
|
| @@ -1851,7 +1954,7 @@ typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
|
| }
|
| *first_spread_arg_loc = spread_arg;
|
|
|
| - if (spread_arg.IsValid()) {
|
| + if ((!maybe_arrow || peek() != Token::ARROW) && spread_arg.IsValid()) {
|
| // Unspread parameter sequences are translated into array literals in the
|
| // parser. Ensure that the number of materialized literals matches between
|
| // the parser and preparser
|
| @@ -1883,18 +1986,32 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| ParserBase<Traits>::Checkpoint checkpoint(this);
|
| ExpressionClassifier arrow_formals_classifier(this,
|
| classifier->duplicate_finder());
|
| +
|
| + bool is_async = allow_harmony_async_await() && peek() == Token::IDENTIFIER &&
|
| + PeekContextualKeyword(CStrVector("async")) &&
|
| + !scanner()->HasAnyLineTerminatorAfterNext();
|
| +
|
| bool parenthesized_formals = peek() == Token::LPAREN;
|
| - if (!parenthesized_formals) {
|
| + if (!is_async && !parenthesized_formals) {
|
| ArrowFormalParametersUnexpectedToken(&arrow_formals_classifier);
|
| }
|
| ExpressionT expression = this->ParseConditionalExpression(
|
| accept_IN, &arrow_formals_classifier, CHECK_OK);
|
| +
|
| + if (is_async && peek_any_identifier() && PeekAhead() == Token::ARROW) {
|
| + // async Identifier => AsyncConciseBody
|
| + IdentifierT name =
|
| + ParseAndClassifyIdentifier(&arrow_formals_classifier, CHECK_OK);
|
| + expression = this->ExpressionFromIdentifier(
|
| + name, position(), scanner()->location().end_pos, scope_, factory());
|
| + }
|
| +
|
| if (peek() == Token::ARROW) {
|
| classifier->RecordPatternError(scanner()->peek_location(),
|
| MessageTemplate::kUnexpectedToken,
|
| Token::String(Token::ARROW));
|
| ValidateArrowFormalParameters(&arrow_formals_classifier, expression,
|
| - parenthesized_formals, CHECK_OK);
|
| + parenthesized_formals, is_async, CHECK_OK);
|
| Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos);
|
| Scope* scope =
|
| this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction);
|
| @@ -1919,7 +2036,7 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| duplicate_loc);
|
| }
|
| expression = this->ParseArrowFunctionLiteral(
|
| - accept_IN, parameters, arrow_formals_classifier, CHECK_OK);
|
| + accept_IN, parameters, is_async, arrow_formals_classifier, CHECK_OK);
|
|
|
| if (fni_ != nullptr) fni_->Infer();
|
|
|
| @@ -1936,8 +2053,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN,
|
| classifier->Accumulate(
|
| &arrow_formals_classifier,
|
| ExpressionClassifier::StandardProductions |
|
| - ExpressionClassifier::FormalParametersProductions |
|
| - ExpressionClassifier::CoverInitializedNameProduction,
|
| + ExpressionClassifier::FormalParametersProductions |
|
| + ExpressionClassifier::CoverInitializedNameProduction |
|
| + ExpressionClassifier::AsyncArrowFormalParametersProduction,
|
| false);
|
|
|
| if (!Token::IsAssignmentOp(peek())) {
|
| @@ -2180,6 +2298,7 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
|
| // '-' UnaryExpression
|
| // '~' UnaryExpression
|
| // '!' UnaryExpression
|
| + // [+Await] AwaitExpression[?Yield]
|
|
|
| Token::Value op = peek();
|
| if (Token::IsUnaryOp(op)) {
|
| @@ -2225,6 +2344,17 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier,
|
| expression,
|
| position());
|
|
|
| + } else if (is_async_function() &&
|
| + PeekContextualKeyword(CStrVector("await"))) {
|
| + int beg_pos = peek_position();
|
| + Consume(Token::IDENTIFIER);
|
| + ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK);
|
| +
|
| + classifier->RecordFormalParameterInitializerError(
|
| + Scanner::Location(beg_pos, scanner()->location().end_pos),
|
| + MessageTemplate::kAwaitExpressionFormalParameter);
|
| +
|
| + return Traits::RewriteAwaitExpression(value, beg_pos);
|
| } else {
|
| return this->ParsePostfixExpression(classifier, ok);
|
| }
|
| @@ -2269,9 +2399,9 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
|
| ExpressionClassifier* classifier, bool* ok) {
|
| // LeftHandSideExpression ::
|
| // (NewExpression | MemberExpression) ...
|
| -
|
| - ExpressionT result =
|
| - this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
|
| + bool is_async = false;
|
| + ExpressionT result = this->ParseMemberWithNewPrefixesExpression(
|
| + classifier, &is_async, CHECK_OK);
|
|
|
| while (true) {
|
| switch (peek()) {
|
| @@ -2289,11 +2419,9 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
|
| }
|
|
|
| case Token::LPAREN: {
|
| + int pos;
|
| Traits::RewriteNonPattern(classifier, CHECK_OK);
|
| BindingPatternUnexpectedToken(classifier);
|
| - ArrowFormalParametersUnexpectedToken(classifier);
|
| -
|
| - int pos;
|
| if (scanner()->current_token() == Token::IDENTIFIER ||
|
| scanner()->current_token() == Token::SUPER) {
|
| // For call of an identifier we want to report position of
|
| @@ -2315,7 +2443,18 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
|
| }
|
| Scanner::Location spread_pos;
|
| typename Traits::Type::ExpressionList args =
|
| - ParseArguments(&spread_pos, classifier, CHECK_OK);
|
| + ParseArguments(&spread_pos, is_async, classifier, CHECK_OK);
|
| +
|
| + if (V8_UNLIKELY(is_async && peek() == Token::ARROW)) {
|
| + if (args->length()) {
|
| + // async ( Arguments ) => ...
|
| + return Traits::ExpressionListToExpression(args);
|
| + }
|
| + // async () => ...
|
| + return factory()->NewEmptyParentheses(pos);
|
| + }
|
| +
|
| + ArrowFormalParametersUnexpectedToken(classifier);
|
|
|
| // Keep track of eval() calls since they disable all local variable
|
| // optimizations.
|
| @@ -2374,11 +2513,10 @@ ParserBase<Traits>::ParseLeftHandSideExpression(
|
| }
|
| }
|
|
|
| -
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
|
| - ExpressionClassifier* classifier, bool* ok) {
|
| + ExpressionClassifier* classifier, bool* is_async, bool* ok) {
|
| // NewExpression ::
|
| // ('new')+ MemberExpression
|
| //
|
| @@ -2411,7 +2549,8 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
|
| } else if (peek() == Token::PERIOD) {
|
| return ParseNewTargetExpression(CHECK_OK);
|
| } else {
|
| - result = this->ParseMemberWithNewPrefixesExpression(classifier, CHECK_OK);
|
| + result = this->ParseMemberWithNewPrefixesExpression(classifier, is_async,
|
| + CHECK_OK);
|
| }
|
| Traits::RewriteNonPattern(classifier, CHECK_OK);
|
| if (peek() == Token::LPAREN) {
|
| @@ -2427,8 +2566,8 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
|
| result = factory()->NewCallNew(result, args, new_pos);
|
| }
|
| // The expression can still continue with . or [ after the arguments.
|
| - result =
|
| - this->ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
|
| + result = this->ParseMemberExpressionContinuation(result, is_async,
|
| + classifier, CHECK_OK);
|
| return result;
|
| }
|
| // NewExpression without arguments.
|
| @@ -2436,14 +2575,13 @@ ParserBase<Traits>::ParseMemberWithNewPrefixesExpression(
|
| new_pos);
|
| }
|
| // No 'new' or 'super' keyword.
|
| - return this->ParseMemberExpression(classifier, ok);
|
| + return this->ParseMemberExpression(classifier, is_async, ok);
|
| }
|
|
|
| -
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
|
| - bool* ok) {
|
| + bool* is_async, bool* ok) {
|
| // MemberExpression ::
|
| // (PrimaryExpression | FunctionLiteral | ClassLiteral)
|
| // ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
|
| @@ -2500,10 +2638,11 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
|
| const bool is_new = false;
|
| result = ParseSuperExpression(is_new, classifier, CHECK_OK);
|
| } else {
|
| - result = ParsePrimaryExpression(classifier, CHECK_OK);
|
| + result = ParsePrimaryExpression(classifier, is_async, CHECK_OK);
|
| }
|
|
|
| - result = ParseMemberExpressionContinuation(result, classifier, CHECK_OK);
|
| + result =
|
| + ParseMemberExpressionContinuation(result, is_async, classifier, CHECK_OK);
|
| return result;
|
| }
|
|
|
| @@ -2570,16 +2709,17 @@ ParserBase<Traits>::ParseNewTargetExpression(bool* ok) {
|
| return this->NewTargetExpression(scope_, factory(), pos);
|
| }
|
|
|
| -
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseMemberExpressionContinuation(
|
| - ExpressionT expression, ExpressionClassifier* classifier, bool* ok) {
|
| + ExpressionT expression, bool* is_async, ExpressionClassifier* classifier,
|
| + bool* ok) {
|
| // Parses this part of MemberExpression:
|
| // ('[' Expression ']' | '.' Identifier | TemplateLiteral)*
|
| while (true) {
|
| switch (peek()) {
|
| case Token::LBRACK: {
|
| + *is_async = false;
|
| Traits::RewriteNonPattern(classifier, CHECK_OK);
|
| BindingPatternUnexpectedToken(classifier);
|
| ArrowFormalParametersUnexpectedToken(classifier);
|
| @@ -2596,6 +2736,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
|
| break;
|
| }
|
| case Token::PERIOD: {
|
| + *is_async = false;
|
| Traits::RewriteNonPattern(classifier, CHECK_OK);
|
| BindingPatternUnexpectedToken(classifier);
|
| ArrowFormalParametersUnexpectedToken(classifier);
|
| @@ -2612,6 +2753,7 @@ ParserBase<Traits>::ParseMemberExpressionContinuation(
|
| }
|
| case Token::TEMPLATE_SPAN:
|
| case Token::TEMPLATE_TAIL: {
|
| + *is_async = false;
|
| Traits::RewriteNonPattern(classifier, CHECK_OK);
|
| BindingPatternUnexpectedToken(classifier);
|
| ArrowFormalParametersUnexpectedToken(classifier);
|
| @@ -2779,11 +2921,10 @@ bool ParserBase<Traits>::IsNextLetKeyword() {
|
| }
|
| }
|
|
|
| -
|
| template <class Traits>
|
| typename ParserBase<Traits>::ExpressionT
|
| ParserBase<Traits>::ParseArrowFunctionLiteral(
|
| - bool accept_IN, const FormalParametersT& formal_parameters,
|
| + bool accept_IN, const FormalParametersT& formal_parameters, bool is_async,
|
| const ExpressionClassifier& formals_classifier, bool* ok) {
|
| if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) {
|
| // ASI inserts `;` after arrow parameters if a line terminator is found.
|
| @@ -2802,9 +2943,9 @@ ParserBase<Traits>::ParseArrowFunctionLiteral(
|
|
|
| {
|
| typename Traits::Type::Factory function_factory(ast_value_factory());
|
| - FunctionState function_state(&function_state_, &scope_,
|
| - formal_parameters.scope, kArrowFunction,
|
| - &function_factory);
|
| + FunctionState function_state(
|
| + &function_state_, &scope_, formal_parameters.scope,
|
| + is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory);
|
|
|
| function_state.SkipMaterializedLiterals(
|
| formal_parameters.materialized_literals_count);
|
|
|