Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(251)

Unified Diff: src/preparser.h

Issue 1423663006: [es7] Implement async functions parsing Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/preparser.h
diff --git a/src/preparser.h b/src/preparser.h
index cdfceea2608f19a6d6f93bc7804d7288e318fc61..ac3683124e7c101bc50976f3d73424207240384d 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -119,7 +119,8 @@ class ParserBase : public Traits {
allow_harmony_new_target_(false),
allow_strong_mode_(false),
allow_legacy_const_(true),
- allow_harmony_do_expressions_(false) {}
+ allow_harmony_do_expressions_(false),
+ allow_harmony_async_await_(false) {}
#define ALLOW_ACCESSORS(name) \
bool allow_##name() const { return allow_##name##_; } \
@@ -139,6 +140,7 @@ class ParserBase : public Traits {
ALLOW_ACCESSORS(strong_mode);
ALLOW_ACCESSORS(legacy_const);
ALLOW_ACCESSORS(harmony_do_expressions);
+ ALLOW_ACCESSORS(harmony_async_await);
#undef ALLOW_ACCESSORS
uintptr_t stack_limit() const { return stack_limit_; }
@@ -216,6 +218,7 @@ class ParserBase : public Traits {
}
bool is_generator() const { return IsGeneratorFunction(kind_); }
+ bool is_async() const { return IsAsyncFunction(kind_); }
FunctionKind kind() const { return kind_; }
FunctionState* outer() const { return outer_function_state_; }
@@ -402,7 +405,8 @@ class ParserBase : public Traits {
Token::Value next = peek();
return next == Token::IDENTIFIER || next == Token::FUTURE_RESERVED_WORD ||
next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
- next == Token::STATIC || next == Token::YIELD;
+ next == Token::STATIC || next == Token::YIELD ||
+ next == Token::ASYNC;
}
bool CheckContextualKeyword(Vector<const char> keyword) {
@@ -509,6 +513,7 @@ class ParserBase : public Traits {
LanguageMode language_mode() { return scope_->language_mode(); }
bool is_generator() const { return function_state_->is_generator(); }
+ bool is_async() const { return function_state_->is_async(); }
bool allow_const() {
return is_strict(language_mode()) || allow_harmony_sloppy() ||
@@ -743,6 +748,7 @@ class ParserBase : public Traits {
bool has_rest, int formals_start_pos, int formals_end_pos, bool* ok);
bool IsNextLetKeyword();
+ bool IsNextAsyncFunctionKeyword();
// Checks if the expression is a valid reference expression (e.g., on the
// left-hand side of assignments). Although ruled out by ECMA as early errors,
@@ -848,6 +854,7 @@ class ParserBase : public Traits {
bool allow_strong_mode_;
bool allow_legacy_const_;
bool allow_harmony_do_expressions_;
+ bool allow_harmony_async_await_;
};
@@ -881,6 +888,9 @@ class PreParserIdentifier {
static PreParserIdentifier Yield() {
return PreParserIdentifier(kYieldIdentifier);
}
+ static PreParserIdentifier Async() {
+ return PreParserIdentifier(kAsyncIdentifier);
+ }
static PreParserIdentifier Prototype() {
return PreParserIdentifier(kPrototypeIdentifier);
}
@@ -894,6 +904,7 @@ class PreParserIdentifier {
bool IsLet() const { return type_ == kLetIdentifier; }
bool IsStatic() const { return type_ == kStaticIdentifier; }
bool IsYield() const { return type_ == kYieldIdentifier; }
+ bool IsAsync() const { return type_ == kAsyncIdentifier; }
bool IsPrototype() const { return type_ == kPrototypeIdentifier; }
bool IsConstructor() const { return type_ == kConstructorIdentifier; }
bool IsFutureReserved() const { return type_ == kFutureReservedIdentifier; }
@@ -919,6 +930,7 @@ class PreParserIdentifier {
kLetIdentifier,
kStaticIdentifier,
kYieldIdentifier,
+ kAsyncIdentifier,
kEvalIdentifier,
kArgumentsIdentifier,
kUndefinedIdentifier,
@@ -1997,6 +2009,7 @@ void ParserBase<Traits>::GetUnexpectedTokenMessage(
case Token::LET:
case Token::STATIC:
case Token::YIELD:
+ case Token::ASYNC:
case Token::FUTURE_STRICT_RESERVED_WORD:
*message = is_strict(language_mode())
? MessageTemplate::kUnexpectedStrictReserved
@@ -2108,6 +2121,7 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
} else if (is_sloppy(language_mode()) &&
(next == Token::FUTURE_STRICT_RESERVED_WORD ||
next == Token::LET || next == Token::STATIC ||
+ next == Token::ASYNC ||
(next == Token::YIELD && !is_generator()))) {
classifier->RecordStrictModeFormalParameterError(
scanner()->location(), MessageTemplate::kUnexpectedStrictReserved);
@@ -2116,6 +2130,10 @@ ParserBase<Traits>::ParseAndClassifyIdentifier(ExpressionClassifier* classifier,
MessageTemplate::kLetInLexicalBinding);
}
return this->GetSymbol(scanner());
+ } else if (next == Token::ASYNC) {
+ // Async token is special because it's allowed in any mode
+ // as identifier name
+ return this->GetSymbol(scanner());
} else {
this->ReportUnexpectedToken(next);
*ok = false;
@@ -2129,7 +2147,8 @@ typename ParserBase<Traits>::IdentifierT ParserBase<
Traits>::ParseIdentifierOrStrictReservedWord(bool* is_strict_reserved,
bool* ok) {
Token::Value next = Next();
- if (next == Token::IDENTIFIER) {
+ // Async is allowed as an identifier
+ if (next == Token::IDENTIFIER || next == Token::ASYNC) {
*is_strict_reserved = false;
} else if (next == Token::FUTURE_STRICT_RESERVED_WORD || next == Token::LET ||
next == Token::STATIC ||
@@ -2153,7 +2172,8 @@ ParserBase<Traits>::ParseIdentifierName(bool* ok) {
Token::Value next = Next();
if (next != Token::IDENTIFIER && next != Token::FUTURE_RESERVED_WORD &&
next != Token::LET && next != Token::STATIC && next != Token::YIELD &&
- next != Token::FUTURE_STRICT_RESERVED_WORD && !Token::IsKeyword(next)) {
+ next != Token::ASYNC && next != Token::FUTURE_STRICT_RESERVED_WORD &&
+ !Token::IsKeyword(next)) {
this->ReportUnexpectedToken(next);
*ok = false;
return Traits::EmptyIdentifier();
@@ -2280,6 +2300,7 @@ ParserBase<Traits>::ParsePrimaryExpression(ExpressionClassifier* classifier,
case Token::LET:
case Token::STATIC:
case Token::YIELD:
+ case Token::ASYNC:
case Token::FUTURE_STRICT_RESERVED_WORD: {
// Using eval or arguments in this context is OK even in strict mode.
IdentifierT name = ParseAndClassifyIdentifier(classifier, CHECK_OK);
@@ -3448,7 +3469,7 @@ typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
bool* ok) {
// MemberExpression ::
- // (PrimaryExpression | FunctionLiteral | ClassLiteral)
+ // (PrimaryExpression | FunctionLiteral | AsyncLiteral | ClassLiteral)
// ('[' Expression ']' | '.' Identifier | Arguments | TemplateLiteral)*
// The '[' Expression ']' and '.' Identifier parts are parsed by
@@ -3457,13 +3478,17 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
// Parse the initial primary or function expression.
ExpressionT result = this->EmptyExpression();
- if (peek() == Token::FUNCTION) {
+ Token::Value token = peek();
+ if (token == Token::FUNCTION ||
+ (allow_harmony_async_await() && token == Token::ASYNC &&
+ IsNextAsyncFunctionKeyword())) {
+ bool is_async = Check(Token::ASYNC);
BindingPatternUnexpectedToken(classifier);
ArrowFormalParametersUnexpectedToken(classifier);
Consume(Token::FUNCTION);
int function_token_position = position();
- bool is_generator = Check(Token::MUL);
+ bool is_generator = is_async ? false : Check(Token::MUL);
IdentifierT name = this->EmptyIdentifier();
bool is_strict_reserved_name = false;
Scanner::Location function_name_location = Scanner::Location::invalid();
@@ -3475,14 +3500,20 @@ ParserBase<Traits>::ParseMemberExpression(ExpressionClassifier* classifier,
function_name_location = scanner()->location();
function_type = FunctionLiteral::NAMED_EXPRESSION;
}
+
+ FunctionKind kind = FunctionKind::kNormalFunction;
+ if (is_generator) {
+ kind = FunctionKind::kGeneratorFunction;
+ } else if (is_async) {
+ kind = FunctionKind::kAsyncFunction;
+ }
+
result = this->ParseFunctionLiteral(
name, function_name_location,
is_strict_reserved_name ? kFunctionNameIsStrictReserved
: kFunctionNameValidityUnknown,
- is_generator ? FunctionKind::kGeneratorFunction
- : FunctionKind::kNormalFunction,
- function_token_position, function_type, FunctionLiteral::NORMAL_ARITY,
- language_mode(), CHECK_OK);
+ kind, function_token_position, function_type,
+ FunctionLiteral::NORMAL_ARITY, language_mode(), CHECK_OK);
} else if (peek() == Token::SUPER) {
const bool is_new = false;
result = ParseSuperExpression(is_new, classifier, CHECK_OK);
@@ -3900,6 +3931,7 @@ bool ParserBase<Traits>::IsNextLetKeyword() {
case Token::STATIC:
case Token::LET: // Yes, you can do let let = ... in sloppy mode
case Token::YIELD:
+ case Token::ASYNC:
return true;
default:
return false;
@@ -3908,6 +3940,15 @@ bool ParserBase<Traits>::IsNextLetKeyword() {
template <class Traits>
+bool ParserBase<Traits>::IsNextAsyncFunctionKeyword() {
+ DCHECK(peek() == Token::ASYNC);
+ Token::Value next_next = PeekAhead();
+ return next_next == Token::FUNCTION &&
+ !scanner()->HasAnyLineTerminatorBeforeNext();
+}
+
+
+template <class Traits>
typename ParserBase<Traits>::ExpressionT
ParserBase<Traits>::ParseArrowFunctionLiteral(
bool accept_IN, const FormalParametersT& formal_parameters,
« no previous file with comments | « src/parser.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698