Chromium Code Reviews| Index: src/parsing/parser-base.h |
| diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h |
| index 368a0d75835dca61c80f89056429e22cd3d58ee8..7f7f6e3a2d8850ece8a710e6a67cbce9bbdede4c 100644 |
| --- a/src/parsing/parser-base.h |
| +++ b/src/parsing/parser-base.h |
| @@ -36,6 +36,14 @@ enum class ParseFunctionFlags { |
| kIsDefault = 4 |
| }; |
| +enum class FunctionBody { |
| + Normal, |
| + ArrowBlock = Normal, |
|
neis
2016/05/11 09:45:16
I find that confusing.
|
| + ArrowConcise, |
| +}; |
| + |
| +enum class FunctionParsePhase { Unknown, FormalParameters, FunctionBody }; |
| + |
| static inline ParseFunctionFlags operator|(ParseFunctionFlags lhs, |
| ParseFunctionFlags rhs) { |
| typedef unsigned char T; |
| @@ -305,10 +313,21 @@ class ParserBase : public Traits { |
| FunctionKind kind() const { return kind_; } |
| FunctionState* outer() const { return outer_function_state_; } |
| + bool is_async_function_body() const { |
| + return is_async_function() && |
| + parse_phase() == FunctionParsePhase::FunctionBody; |
| + } |
| + |
| + FunctionParsePhase parse_phase() const { return parse_phase_; } |
| + |
| + void set_parse_phase(FunctionParsePhase parse_phase) { |
| + parse_phase_ = parse_phase; |
| + } |
| + |
| void set_generator_object_variable( |
| typename Traits::Type::GeneratorVariable* variable) { |
| DCHECK(variable != NULL); |
| - DCHECK(is_generator()); |
| + DCHECK(is_generator() || is_async_function()); |
|
neis
2016/05/11 09:45:16
Didn't you introduce a function for this?
|
| generator_object_variable_ = variable; |
| } |
| typename Traits::Type::GeneratorVariable* generator_object_variable() |
| @@ -411,6 +430,8 @@ class ParserBase : public Traits { |
| // to this function. Filled in by constructor. |
| bool this_function_is_parenthesized_; |
| + FunctionParsePhase parse_phase_ = FunctionParsePhase::Unknown; |
| + |
| friend class ParserTraits; |
| friend class PreParserTraits; |
| friend class Checkpoint; |
| @@ -2156,8 +2177,9 @@ ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, |
| ValidateFormalParameterInitializer(&arrow_formals_classifier, ok); |
| Scanner::Location loc(lhs_beg_pos, scanner()->location().end_pos); |
| - Scope* scope = |
| - this->NewScope(scope_, FUNCTION_SCOPE, FunctionKind::kArrowFunction); |
| + Scope* scope = this->NewScope(scope_, FUNCTION_SCOPE, |
| + is_async ? FunctionKind::kAsyncArrowFunction |
| + : FunctionKind::kArrowFunction); |
| // Because the arrow's parameters were parsed in the outer scope, any |
| // usage flags that might have been triggered there need to be copied |
| // to the arrow scope. |
| @@ -2581,10 +2603,14 @@ ParserBase<Traits>::ParseUnaryExpression(ExpressionClassifier* classifier, |
| Consume(Token::AWAIT); |
| ExpressionT value = ParseUnaryExpression(classifier, CHECK_OK); |
| - classifier->RecordFormalParameterInitializerError( |
| - Scanner::Location(beg_pos, scanner()->location().end_pos), |
| - MessageTemplate::kAwaitExpressionFormalParameter); |
| - |
| + if (!function_state_->is_async_function_body()) { |
| + // Not currently parsing function body --- must have occurred within |
| + // formal parameter parsing. |
| + ReportMessageAt(Scanner::Location(beg_pos, scanner()->location().end_pos), |
| + MessageTemplate::kAwaitExpressionFormalParameter); |
| + *ok = false; |
| + return this->EmptyExpression(); |
| + } |
| return Traits::RewriteAwaitExpression(value, beg_pos); |
| } else { |
| return this->ParsePostfixExpression(classifier, ok); |
| @@ -3182,11 +3208,12 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
| int expected_property_count = -1; |
| Scanner::Location super_loc; |
| + FunctionKind arrow_kind = is_async ? kAsyncArrowFunction : kArrowFunction; |
| { |
| typename Traits::Type::Factory function_factory(ast_value_factory()); |
| - FunctionState function_state( |
| - &function_state_, &scope_, formal_parameters.scope, |
| - is_async ? kAsyncArrowFunction : kArrowFunction, &function_factory); |
| + FunctionState function_state(&function_state_, &scope_, |
| + formal_parameters.scope, arrow_kind, |
| + &function_factory); |
| function_state.SkipMaterializedLiterals( |
| formal_parameters.materialized_literals_count); |
| @@ -3194,6 +3221,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
| this->ReindexLiterals(formal_parameters); |
| Expect(Token::ARROW, CHECK_OK); |
| + function_state.set_parse_phase(FunctionParsePhase::FunctionBody); |
| if (peek() == Token::LBRACE) { |
| // Multiple statement body |
| @@ -3211,7 +3239,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
| } else { |
| body = this->ParseEagerFunctionBody( |
| this->EmptyIdentifier(), RelocInfo::kNoPosition, formal_parameters, |
| - kArrowFunction, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
| + arrow_kind, FunctionLiteral::kAnonymousExpression, CHECK_OK); |
| materialized_literal_count = |
| function_state.materialized_literal_count(); |
| expected_property_count = function_state.expected_property_count(); |
| @@ -3224,18 +3252,25 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
| function_state_->return_expr_context()); |
| ReturnExprScope allow_tail_calls( |
| function_state_, ReturnExprContext::kInsideValidReturnStatement); |
| - ExpressionT expression = |
| - ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| - Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| body = this->NewStatementList(1, zone()); |
| - this->AddParameterInitializationBlock(formal_parameters, body, CHECK_OK); |
| - body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| + this->AddParameterInitializationBlock(formal_parameters, body, is_async, |
| + CHECK_OK); |
| + if (is_async) { |
| + this->ParseAsyncArrowSingleExpressionBody(body, accept_IN, &classifier, |
| + pos, CHECK_OK); |
| + Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| + } else { |
| + ExpressionT expression = |
| + ParseAssignmentExpression(accept_IN, &classifier, CHECK_OK); |
| + Traits::RewriteNonPattern(&classifier, CHECK_OK); |
| + body->Add(factory()->NewReturnStatement(expression, pos), zone()); |
| + if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| + // ES6 14.6.1 Static Semantics: IsInTailPosition |
| + this->MarkTailPosition(expression); |
| + } |
| + } |
| materialized_literal_count = function_state.materialized_literal_count(); |
| expected_property_count = function_state.expected_property_count(); |
| - if (allow_tailcalls() && !is_sloppy(language_mode())) { |
| - // ES6 14.6.1 Static Semantics: IsInTailPosition |
| - this->MarkTailPosition(expression); |
| - } |
| this->MarkCollectedTailCallExpressions(); |
| } |
| super_loc = function_state.super_location(); |
| @@ -3265,7 +3300,7 @@ ParserBase<Traits>::ParseArrowFunctionLiteral( |
| materialized_literal_count, expected_property_count, num_parameters, |
| FunctionLiteral::kNoDuplicateParameters, |
| FunctionLiteral::kAnonymousExpression, |
| - FunctionLiteral::kShouldLazyCompile, FunctionKind::kArrowFunction, |
| + FunctionLiteral::kShouldLazyCompile, arrow_kind, |
| formal_parameters.scope->start_position()); |
| function_literal->set_function_token_position( |