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( |