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

Side by Side Diff: src/parsing/preparser.cc

Issue 1841543003: [esnext] implement frontend changes for async/await proposal (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Uncomment that test Created 4 years, 7 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 unified diff | Download patch
« no previous file with comments | « src/parsing/preparser.h ('k') | src/parsing/scanner.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <cmath> 5 #include <cmath>
6 6
7 #include "src/allocation.h" 7 #include "src/allocation.h"
8 #include "src/base/logging.h" 8 #include "src/base/logging.h"
9 #include "src/conversions-inl.h" 9 #include "src/conversions-inl.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 return PreParserIdentifier::Await(); 44 return PreParserIdentifier::Await();
45 } else if (scanner->current_token() == 45 } else if (scanner->current_token() ==
46 Token::FUTURE_STRICT_RESERVED_WORD) { 46 Token::FUTURE_STRICT_RESERVED_WORD) {
47 return PreParserIdentifier::FutureStrictReserved(); 47 return PreParserIdentifier::FutureStrictReserved();
48 } else if (scanner->current_token() == Token::LET) { 48 } else if (scanner->current_token() == Token::LET) {
49 return PreParserIdentifier::Let(); 49 return PreParserIdentifier::Let();
50 } else if (scanner->current_token() == Token::STATIC) { 50 } else if (scanner->current_token() == Token::STATIC) {
51 return PreParserIdentifier::Static(); 51 return PreParserIdentifier::Static();
52 } else if (scanner->current_token() == Token::YIELD) { 52 } else if (scanner->current_token() == Token::YIELD) {
53 return PreParserIdentifier::Yield(); 53 return PreParserIdentifier::Yield();
54 } else if (scanner->current_token() == Token::ASYNC) {
55 return PreParserIdentifier::Async();
54 } 56 }
55 if (scanner->UnescapedLiteralMatches("eval", 4)) { 57 if (scanner->UnescapedLiteralMatches("eval", 4)) {
56 return PreParserIdentifier::Eval(); 58 return PreParserIdentifier::Eval();
57 } 59 }
58 if (scanner->UnescapedLiteralMatches("arguments", 9)) { 60 if (scanner->UnescapedLiteralMatches("arguments", 9)) {
59 return PreParserIdentifier::Arguments(); 61 return PreParserIdentifier::Arguments();
60 } 62 }
61 if (scanner->UnescapedLiteralMatches("undefined", 9)) { 63 if (scanner->UnescapedLiteralMatches("undefined", 9)) {
62 return PreParserIdentifier::Undefined(); 64 return PreParserIdentifier::Undefined();
63 } 65 }
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 return ParseHoistableDeclaration(ok); 188 return ParseHoistableDeclaration(ok);
187 case Token::CLASS: 189 case Token::CLASS:
188 return ParseClassDeclaration(ok); 190 return ParseClassDeclaration(ok);
189 case Token::CONST: 191 case Token::CONST:
190 return ParseVariableStatement(kStatementListItem, ok); 192 return ParseVariableStatement(kStatementListItem, ok);
191 case Token::LET: 193 case Token::LET:
192 if (IsNextLetKeyword()) { 194 if (IsNextLetKeyword()) {
193 return ParseVariableStatement(kStatementListItem, ok); 195 return ParseVariableStatement(kStatementListItem, ok);
194 } 196 }
195 break; 197 break;
198 case Token::ASYNC:
199 if (allow_harmony_async_await() && PeekAhead() == Token::FUNCTION &&
200 !scanner()->HasAnyLineTerminatorAfterNext()) {
201 Consume(Token::ASYNC);
202 return ParseAsyncFunctionDeclaration(ok);
203 }
204 /* falls through */
196 default: 205 default:
197 break; 206 break;
198 } 207 }
199 return ParseStatement(kAllowLabelledFunctionStatement, ok); 208 return ParseStatement(kAllowLabelledFunctionStatement, ok);
200 } 209 }
201 210
202 211
203 void PreParser::ParseStatementList(int end_token, bool* ok, 212 void PreParser::ParseStatementList(int end_token, bool* ok,
204 Scanner::BookmarkScope* bookmark) { 213 Scanner::BookmarkScope* bookmark) {
205 // SourceElements :: 214 // SourceElements ::
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 return ParseDebuggerStatement(ok); 383 return ParseDebuggerStatement(ok);
375 384
376 case Token::VAR: 385 case Token::VAR:
377 return ParseVariableStatement(kStatement, ok); 386 return ParseVariableStatement(kStatement, ok);
378 387
379 default: 388 default:
380 return ParseExpressionOrLabelledStatement(allow_function, ok); 389 return ParseExpressionOrLabelledStatement(allow_function, ok);
381 } 390 }
382 } 391 }
383 392
393 PreParser::Statement PreParser::ParseHoistableDeclaration(
394 int pos, ParseFunctionFlags flags, bool* ok) {
395 const bool is_generator = flags & ParseFunctionFlags::kIsGenerator;
396 const bool is_async = flags & ParseFunctionFlags::kIsAsync;
397 DCHECK(!is_generator || !is_async);
384 398
385 PreParser::Statement PreParser::ParseHoistableDeclaration(
386 int pos, bool is_generator, bool* ok) {
387 bool is_strict_reserved = false; 399 bool is_strict_reserved = false;
388 Identifier name = ParseIdentifierOrStrictReservedWord( 400 Identifier name = ParseIdentifierOrStrictReservedWord(
389 &is_strict_reserved, CHECK_OK); 401 &is_strict_reserved, CHECK_OK);
402
403 if (V8_UNLIKELY(is_async_function() && this->IsAwait(name))) {
404 ReportMessageAt(scanner()->location(),
405 MessageTemplate::kAwaitBindingIdentifier);
406 *ok = false;
407 return Statement::Default();
408 }
409
390 ParseFunctionLiteral(name, scanner()->location(), 410 ParseFunctionLiteral(name, scanner()->location(),
391 is_strict_reserved ? kFunctionNameIsStrictReserved 411 is_strict_reserved ? kFunctionNameIsStrictReserved
392 : kFunctionNameValidityUnknown, 412 : kFunctionNameValidityUnknown,
393 is_generator ? FunctionKind::kGeneratorFunction 413 is_generator ? FunctionKind::kGeneratorFunction
394 : FunctionKind::kNormalFunction, 414 : is_async ? FunctionKind::kAsyncFunction
415 : FunctionKind::kNormalFunction,
395 pos, FunctionLiteral::kDeclaration, language_mode(), 416 pos, FunctionLiteral::kDeclaration, language_mode(),
396 CHECK_OK); 417 CHECK_OK);
397 return Statement::FunctionDeclaration(); 418 return Statement::FunctionDeclaration();
398 } 419 }
399 420
421 PreParser::Statement PreParser::ParseAsyncFunctionDeclaration(bool* ok) {
422 // AsyncFunctionDeclaration ::
423 // async [no LineTerminator here] function BindingIdentifier[Await]
424 // ( FormalParameters[Await] ) { AsyncFunctionBody }
425 DCHECK_EQ(scanner()->current_token(), Token::ASYNC);
426 int pos = position();
427 Expect(Token::FUNCTION, CHECK_OK);
428 ParseFunctionFlags flags = ParseFunctionFlags::kIsAsync;
429 return ParseHoistableDeclaration(pos, flags, ok);
430 }
400 431
401 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) { 432 PreParser::Statement PreParser::ParseHoistableDeclaration(bool* ok) {
402 // FunctionDeclaration :: 433 // FunctionDeclaration ::
403 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 434 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
404 // GeneratorDeclaration :: 435 // GeneratorDeclaration ::
405 // 'function' '*' Identifier '(' FormalParameterListopt ')' 436 // 'function' '*' Identifier '(' FormalParameterListopt ')'
406 // '{' FunctionBody '}' 437 // '{' FunctionBody '}'
438
407 Expect(Token::FUNCTION, CHECK_OK); 439 Expect(Token::FUNCTION, CHECK_OK);
408 int pos = position(); 440 int pos = position();
409 bool is_generator = Check(Token::MUL); 441 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
410 return ParseHoistableDeclaration(pos, is_generator, CHECK_OK); 442 if (Check(Token::MUL)) {
443 flags |= ParseFunctionFlags::kIsGenerator;
444 }
445 return ParseHoistableDeclaration(pos, flags, ok);
411 } 446 }
412 447
413 448
414 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { 449 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) {
415 Expect(Token::CLASS, CHECK_OK); 450 Expect(Token::CLASS, CHECK_OK);
416 451
417 int pos = position(); 452 int pos = position();
418 bool is_strict_reserved = false; 453 bool is_strict_reserved = false;
419 Identifier name = 454 Identifier name =
420 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 455 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 594
560 if (num_decl != nullptr) *num_decl = nvars; 595 if (num_decl != nullptr) *num_decl = nvars;
561 if (is_lexical != nullptr) *is_lexical = lexical; 596 if (is_lexical != nullptr) *is_lexical = lexical;
562 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern; 597 if (is_binding_pattern != nullptr) *is_binding_pattern = is_pattern;
563 return Statement::Default(); 598 return Statement::Default();
564 } 599 }
565 600
566 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 601 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) {
567 Consume(Token::FUNCTION); 602 Consume(Token::FUNCTION);
568 int pos = position(); 603 int pos = position();
569 bool is_generator = Check(Token::MUL); 604 ParseFunctionFlags flags = ParseFunctionFlags::kIsNormal;
570 if (allow_harmony_restrictive_declarations() && is_generator) { 605 if (Check(Token::MUL)) {
571 PreParserTraits::ReportMessageAt( 606 flags |= ParseFunctionFlags::kIsGenerator;
572 scanner()->location(), 607 if (allow_harmony_restrictive_declarations()) {
573 MessageTemplate::kGeneratorInLegacyContext); 608 PreParserTraits::ReportMessageAt(
574 *ok = false; 609 scanner()->location(), MessageTemplate::kGeneratorInLegacyContext);
575 return Statement::Default(); 610 *ok = false;
611 return Statement::Default();
612 }
576 } 613 }
577 return ParseHoistableDeclaration(pos, is_generator, ok); 614 return ParseHoistableDeclaration(pos, flags, ok);
578 } 615 }
579 616
580 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement( 617 PreParser::Statement PreParser::ParseExpressionOrLabelledStatement(
581 AllowLabelledFunctionStatement allow_function, bool* ok) { 618 AllowLabelledFunctionStatement allow_function, bool* ok) {
582 // ExpressionStatement | LabelledStatement :: 619 // ExpressionStatement | LabelledStatement ::
583 // Expression ';' 620 // Expression ';'
584 // Identifier ':' Statement 621 // Identifier ':' Statement
585 622
586 switch (peek()) { 623 switch (peek()) {
587 case Token::FUNCTION: 624 case Token::FUNCTION:
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 allow_duplicate_parameters, CHECK_OK); 1141 allow_duplicate_parameters, CHECK_OK);
1105 1142
1106 if (is_strict(language_mode)) { 1143 if (is_strict(language_mode)) {
1107 int end_position = scanner()->location().end_pos; 1144 int end_position = scanner()->location().end_pos;
1108 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); 1145 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
1109 } 1146 }
1110 1147
1111 return Expression::Default(); 1148 return Expression::Default();
1112 } 1149 }
1113 1150
1151 PreParser::Expression PreParser::ParseAsyncFunctionExpression(bool* ok) {
1152 // AsyncFunctionDeclaration ::
1153 // async [no LineTerminator here] function ( FormalParameters[Await] )
1154 // { AsyncFunctionBody }
1155 //
1156 // async [no LineTerminator here] function BindingIdentifier[Await]
1157 // ( FormalParameters[Await] ) { AsyncFunctionBody }
1158 int pos = position();
1159 Expect(Token::FUNCTION, CHECK_OK);
1160 bool is_strict_reserved = false;
1161 Identifier name;
1162 FunctionLiteral::FunctionType type = FunctionLiteral::kAnonymousExpression;
1163
1164 if (peek_any_identifier()) {
1165 type = FunctionLiteral::kNamedExpression;
1166 name = ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
1167 if (this->IsAwait(name)) {
1168 ReportMessageAt(scanner()->location(),
1169 MessageTemplate::kAwaitBindingIdentifier);
1170 *ok = false;
1171 return Expression::Default();
1172 }
1173 }
1174
1175 ParseFunctionLiteral(name, scanner()->location(),
1176 is_strict_reserved ? kFunctionNameIsStrictReserved
1177 : kFunctionNameValidityUnknown,
1178 FunctionKind::kAsyncFunction, pos, type, language_mode(),
1179 CHECK_OK);
1180 return Expression::Default();
1181 }
1114 1182
1115 void PreParser::ParseLazyFunctionLiteralBody(bool* ok, 1183 void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
1116 Scanner::BookmarkScope* bookmark) { 1184 Scanner::BookmarkScope* bookmark) {
1117 int body_start = position(); 1185 int body_start = position();
1118 ParseStatementList(Token::RBRACE, ok, bookmark); 1186 ParseStatementList(Token::RBRACE, ok, bookmark);
1119 if (!*ok) return; 1187 if (!*ok) return;
1120 if (bookmark && bookmark->HasBeenReset()) return; 1188 if (bookmark && bookmark->HasBeenReset()) return;
1121 1189
1122 // Position right after terminal '}'. 1190 // Position right after terminal '}'.
1123 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 1191 DCHECK_EQ(Token::RBRACE, scanner()->peek());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 } 1233 }
1166 } 1234 }
1167 1235
1168 ClassLiteralChecker checker(this); 1236 ClassLiteralChecker checker(this);
1169 bool has_seen_constructor = false; 1237 bool has_seen_constructor = false;
1170 1238
1171 Expect(Token::LBRACE, CHECK_OK); 1239 Expect(Token::LBRACE, CHECK_OK);
1172 while (peek() != Token::RBRACE) { 1240 while (peek() != Token::RBRACE) {
1173 if (Check(Token::SEMICOLON)) continue; 1241 if (Check(Token::SEMICOLON)) continue;
1174 const bool in_class = true; 1242 const bool in_class = true;
1175 const bool is_static = false;
1176 bool is_computed_name = false; // Classes do not care about computed 1243 bool is_computed_name = false; // Classes do not care about computed
1177 // property names here. 1244 // property names here.
1178 Identifier name; 1245 Identifier name;
1179 ExpressionClassifier property_classifier(this); 1246 ExpressionClassifier property_classifier(this);
1180 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, 1247 ParsePropertyDefinition(&checker, in_class, has_extends, MethodKind::Normal,
1181 &is_computed_name, &has_seen_constructor, 1248 &is_computed_name, &has_seen_constructor,
1182 &property_classifier, &name, CHECK_OK); 1249 &property_classifier, &name, CHECK_OK);
1183 ValidateExpression(&property_classifier, CHECK_OK); 1250 ValidateExpression(&property_classifier, CHECK_OK);
1184 if (classifier != nullptr) { 1251 if (classifier != nullptr) {
1185 classifier->Accumulate(&property_classifier, 1252 classifier->Accumulate(&property_classifier,
1186 ExpressionClassifier::ExpressionProductions); 1253 ExpressionClassifier::ExpressionProductions);
1187 } 1254 }
1188 } 1255 }
1189 1256
1190 Expect(Token::RBRACE, CHECK_OK); 1257 Expect(Token::RBRACE, CHECK_OK);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 } 1291 }
1225 Expect(Token::RBRACE, CHECK_OK); 1292 Expect(Token::RBRACE, CHECK_OK);
1226 return PreParserExpression::Default(); 1293 return PreParserExpression::Default();
1227 } 1294 }
1228 1295
1229 #undef CHECK_OK 1296 #undef CHECK_OK
1230 1297
1231 1298
1232 } // namespace internal 1299 } // namespace internal
1233 } // namespace v8 1300 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | src/parsing/scanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698