| Index: src/preparser.cc
|
| diff --git a/src/preparser.cc b/src/preparser.cc
|
| index 74e11b1d454b3b33a3f6bcadb18f91476a246f37..305070c9576dbd61f444a2fd963bf466deda2eff 100644
|
| --- a/src/preparser.cc
|
| +++ b/src/preparser.cc
|
| @@ -48,6 +48,8 @@ PreParserIdentifier PreParserTraits::GetSymbol(Scanner* scanner) {
|
| return PreParserIdentifier::Static();
|
| } else if (scanner->current_token() == Token::YIELD) {
|
| return PreParserIdentifier::Yield();
|
| + } else if (scanner->current_token() == Token::ASYNC) {
|
| + return PreParserIdentifier::Async();
|
| }
|
| if (scanner->UnescapedLiteralMatches("eval", 4)) {
|
| return PreParserIdentifier::Eval();
|
| @@ -190,6 +192,11 @@ PreParser::Statement PreParser::ParseStatementListItem(bool* ok) {
|
| switch (peek()) {
|
| case Token::FUNCTION:
|
| return ParseFunctionDeclaration(ok);
|
| + case Token::ASYNC:
|
| + if (IsNextAsyncFunctionKeyword()) {
|
| + return ParseFunctionDeclaration(ok);
|
| + }
|
| + break;
|
| case Token::CLASS:
|
| return ParseClassDeclaration(ok);
|
| case Token::CONST:
|
| @@ -397,6 +404,15 @@ PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
|
| case Token::TRY:
|
| return ParseTryStatement(ok);
|
|
|
| + case Token::ASYNC:
|
| + // Make sure async keyword is followed by a function keyword,
|
| + // otherwise parse 'async' as part of an expression or
|
| + // labelled statement (default case in this switch).
|
| + if (!allow_harmony_async_await() || !IsNextAsyncFunctionKeyword()) {
|
| + return ParseExpressionOrLabelledStatement(ok);
|
| + }
|
| +
|
| + // Fall through.
|
| case Token::FUNCTION: {
|
| Scanner::Location start_location = scanner()->peek_location();
|
| Statement statement = ParseFunctionDeclaration(CHECK_OK);
|
| @@ -436,21 +452,31 @@ PreParser::Statement PreParser::ParseSubStatement(bool* ok) {
|
| PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
|
| // FunctionDeclaration ::
|
| // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
|
| + // AsyncFunctionDeclaration ::
|
| + // 'async' 'function' Identifier '(' FormalParameterListopt ')'
|
| + // '{' FunctionBody '}'
|
| // GeneratorDeclaration ::
|
| // 'function' '*' Identifier '(' FormalParameterListopt ')'
|
| // '{' FunctionBody '}'
|
| + bool is_async = allow_harmony_async_await() ? Check(Token::ASYNC) : false;
|
| Expect(Token::FUNCTION, CHECK_OK);
|
| int pos = position();
|
| - bool is_generator = Check(Token::MUL);
|
| + bool is_generator = is_async ? false : Check(Token::MUL);
|
| bool is_strict_reserved = false;
|
| Identifier name = ParseIdentifierOrStrictReservedWord(
|
| &is_strict_reserved, CHECK_OK);
|
| +
|
| + FunctionKind kind = FunctionKind::kNormalFunction;
|
| + if (is_generator) {
|
| + kind = FunctionKind::kGeneratorFunction;
|
| + } else if (is_async) {
|
| + kind = FunctionKind::kAsyncFunction;
|
| + }
|
| +
|
| ParseFunctionLiteral(name, scanner()->location(),
|
| is_strict_reserved ? kFunctionNameIsStrictReserved
|
| : kFunctionNameValidityUnknown,
|
| - is_generator ? FunctionKind::kGeneratorFunction
|
| - : FunctionKind::kNormalFunction,
|
| - pos, FunctionLiteral::DECLARATION,
|
| + kind, pos, FunctionLiteral::DECLARATION,
|
| FunctionLiteral::NORMAL_ARITY, language_mode(),
|
| CHECK_OK);
|
| return Statement::FunctionDeclaration();
|
|
|