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

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

Issue 1871923003: Add parsing for ambient declarations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@types-devel
Patch Set: Minor fixes to address code review comments Created 4 years, 8 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') | test/cctest/test-parsing.cc » ('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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 CheckStrictOctalLiteral(start_position, end_pos, &ok); 133 CheckStrictOctalLiteral(start_position, end_pos, &ok);
134 if (!ok) return kPreParseSuccess; 134 if (!ok) return kPreParseSuccess;
135 } 135 }
136 } 136 }
137 return kPreParseSuccess; 137 return kPreParseSuccess;
138 } 138 }
139 139
140 140
141 PreParserExpression PreParserTraits::ParseClassLiteral( 141 PreParserExpression PreParserTraits::ParseClassLiteral(
142 PreParserIdentifier name, Scanner::Location class_name_location, 142 PreParserIdentifier name, Scanner::Location class_name_location,
143 bool name_is_strict_reserved, int pos, bool* ok) { 143 bool name_is_strict_reserved, int pos, bool ambient, bool* ok) {
144 return pre_parser_->ParseClassLiteral(name, class_name_location, 144 return pre_parser_->ParseClassLiteral(
145 name_is_strict_reserved, pos, ok); 145 name, class_name_location, name_is_strict_reserved, pos, ambient, ok);
146 } 146 }
147 147
148 148
149 // Preparsing checks a JavaScript program and emits preparse-data that helps 149 // Preparsing checks a JavaScript program and emits preparse-data that helps
150 // a later parsing to be faster. 150 // a later parsing to be faster.
151 // See preparser-data.h for the data. 151 // See preparser-data.h for the data.
152 152
153 // The PreParser checks that the syntax follows the grammar for JavaScript, 153 // The PreParser checks that the syntax follows the grammar for JavaScript,
154 // and collects some information about the program along the way. 154 // and collects some information about the program along the way.
155 // The grammar check is only performed in order to understand the program 155 // The grammar check is only performed in order to understand the program
(...skipping 15 matching lines...) Expand all
171 // ClassDeclaration[?Yield] 171 // ClassDeclaration[?Yield]
172 // LexicalDeclaration[In, ?Yield] 172 // LexicalDeclaration[In, ?Yield]
173 // 173 //
174 // HoistableDeclaration[Yield, Default] : 174 // HoistableDeclaration[Yield, Default] :
175 // FunctionDeclaration[?Yield, ?Default] 175 // FunctionDeclaration[?Yield, ?Default]
176 // GeneratorDeclaration[?Yield, ?Default] 176 // GeneratorDeclaration[?Yield, ?Default]
177 // 177 //
178 // LexicalDeclaration[In, Yield] : 178 // LexicalDeclaration[In, Yield] :
179 // LetOrConst BindingList[?In, ?Yield] ; 179 // LetOrConst BindingList[?In, ?Yield] ;
180 180
181 // Allow ambient variable, function, and class declarations.
182 bool ambient =
183 scope_->typed() && CheckContextualKeyword(CStrVector("declare"));
184 if (ambient && !scope_->is_toplevel_scope()) {
185 *ok = false;
186 ReportMessage(MessageTemplate::kIllegalDeclare);
187 return Statement::Default();
188 }
181 switch (peek()) { 189 switch (peek()) {
182 case Token::FUNCTION: 190 case Token::FUNCTION:
183 return ParseFunctionDeclaration(ok); 191 return ParseFunctionDeclaration(ambient, ok);
184 case Token::CLASS: 192 case Token::CLASS:
185 return ParseClassDeclaration(ok); 193 return ParseClassDeclaration(ambient, ok);
186 case Token::CONST: 194 case Token::CONST:
187 if (allow_const()) { 195 if (allow_const()) {
188 return ParseVariableStatement(kStatementListItem, ok); 196 return ParseVariableStatement(kStatementListItem, ambient, ok);
189 } 197 }
190 break; 198 break;
199 case Token::VAR:
200 return ParseVariableStatement(kStatementListItem, ambient, ok);
191 case Token::LET: 201 case Token::LET:
192 if (IsNextLetKeyword()) { 202 if (IsNextLetKeyword()) {
193 return ParseVariableStatement(kStatementListItem, ok); 203 return ParseVariableStatement(kStatementListItem, ambient, ok);
194 } 204 }
195 break; 205 break;
196 case Token::IDENTIFIER: 206 case Token::IDENTIFIER:
197 case Token::FUTURE_STRICT_RESERVED_WORD: { 207 case Token::FUTURE_STRICT_RESERVED_WORD: {
198 if (!scope_->typed()) break; 208 if (!scope_->typed() || ambient) break;
199 int pos = peek_position(); 209 int pos = peek_position();
200 if (CheckContextualKeyword(CStrVector("type"))) { 210 if (CheckContextualKeyword(CStrVector("type"))) {
201 return ParseTypeAliasDeclaration(pos, ok); 211 return ParseTypeAliasDeclaration(pos, ok);
202 } else if (CheckContextualKeyword(CStrVector("interface"))) { 212 } else if (CheckContextualKeyword(CStrVector("interface"))) {
203 return ParseInterfaceDeclaration(pos, ok); 213 return ParseInterfaceDeclaration(pos, ok);
204 } 214 }
205 break; 215 break;
206 } 216 }
207 // TODO(nikolaos): ambient
208 default: 217 default:
209 break; 218 break;
210 } 219 }
220 if (ambient) {
221 *ok = false;
222 ReportMessageAt(scanner()->peek_location(),
223 MessageTemplate::kBadAmbientDeclaration);
224 return Statement::Default();
225 }
211 return ParseStatement(kAllowLabelledFunctionStatement, ok); 226 return ParseStatement(kAllowLabelledFunctionStatement, ok);
212 } 227 }
213 228
214 229
215 void PreParser::ParseStatementList(int end_token, bool* ok, 230 void PreParser::ParseStatementList(int end_token, bool* ok,
216 Scanner::BookmarkScope* bookmark) { 231 Scanner::BookmarkScope* bookmark) {
217 // SourceElements :: 232 // SourceElements ::
218 // (Statement)* <end_token> 233 // (Statement)* <end_token>
219 234
220 // Bookkeeping for trial parse if bookmark is set: 235 // Bookkeeping for trial parse if bookmark is set:
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 return Statement::Default(); 316 return Statement::Default();
302 } 317 }
303 return ParseSubStatement(allow_function, ok); 318 return ParseSubStatement(allow_function, ok);
304 } 319 }
305 320
306 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { 321 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
307 if (is_strict(language_mode()) || peek() != Token::FUNCTION || 322 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
308 (legacy && allow_harmony_restrictive_declarations())) { 323 (legacy && allow_harmony_restrictive_declarations())) {
309 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); 324 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
310 } else { 325 } else {
311 return ParseFunctionDeclaration(CHECK_OK); 326 return ParseFunctionDeclaration(false, CHECK_OK);
312 } 327 }
313 } 328 }
314 329
315 PreParser::Statement PreParser::ParseSubStatement( 330 PreParser::Statement PreParser::ParseSubStatement(
316 AllowLabelledFunctionStatement allow_function, bool* ok) { 331 AllowLabelledFunctionStatement allow_function, bool* ok) {
317 // Statement :: 332 // Statement ::
318 // Block 333 // Block
319 // VariableStatement 334 // VariableStatement
320 // EmptyStatement 335 // EmptyStatement
321 // ExpressionStatement 336 // ExpressionStatement
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 is_strict(language_mode()) 405 is_strict(language_mode())
391 ? MessageTemplate::kStrictFunction 406 ? MessageTemplate::kStrictFunction
392 : MessageTemplate::kSloppyFunction); 407 : MessageTemplate::kSloppyFunction);
393 *ok = false; 408 *ok = false;
394 return Statement::Default(); 409 return Statement::Default();
395 410
396 case Token::DEBUGGER: 411 case Token::DEBUGGER:
397 return ParseDebuggerStatement(ok); 412 return ParseDebuggerStatement(ok);
398 413
399 case Token::VAR: 414 case Token::VAR:
400 return ParseVariableStatement(kStatement, ok); 415 return ParseVariableStatement(kStatement, false, ok);
401 416
402 default: 417 default:
403 return ParseExpressionOrLabelledStatement(allow_function, ok); 418 return ParseExpressionOrLabelledStatement(allow_function, ok);
404 } 419 }
405 } 420 }
406 421
407 422
408 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 423 PreParser::Statement PreParser::ParseFunctionDeclaration(bool ambient,
424 bool* ok) {
409 // FunctionDeclaration :: 425 // FunctionDeclaration ::
410 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 426 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
411 // GeneratorDeclaration :: 427 // GeneratorDeclaration ::
412 // 'function' '*' Identifier '(' FormalParameterListopt ')' 428 // 'function' '*' Identifier '(' FormalParameterListopt ')'
413 // '{' FunctionBody '}' 429 // '{' FunctionBody '}'
414 Expect(Token::FUNCTION, CHECK_OK); 430 Expect(Token::FUNCTION, CHECK_OK);
415 int pos = position(); 431 int pos = position();
416 bool is_generator = Check(Token::MUL); 432 bool is_generator = Check(Token::MUL);
417 bool is_strict_reserved = false; 433 bool is_strict_reserved = false;
418 Identifier name = ParseIdentifierOrStrictReservedWord( 434 Identifier name = ParseIdentifierOrStrictReservedWord(
419 &is_strict_reserved, CHECK_OK); 435 &is_strict_reserved, CHECK_OK);
436 typesystem::TypeFlags type_flags =
437 ambient ? typesystem::kAmbient : typesystem::kAllowSignature;
420 ParseFunctionLiteral(name, scanner()->location(), 438 ParseFunctionLiteral(name, scanner()->location(),
421 is_strict_reserved ? kFunctionNameIsStrictReserved 439 is_strict_reserved ? kFunctionNameIsStrictReserved
422 : kFunctionNameValidityUnknown, 440 : kFunctionNameValidityUnknown,
423 is_generator ? FunctionKind::kGeneratorFunction 441 is_generator ? FunctionKind::kGeneratorFunction
424 : FunctionKind::kNormalFunction, 442 : FunctionKind::kNormalFunction,
425 pos, FunctionLiteral::kDeclaration, language_mode(), 443 pos, FunctionLiteral::kDeclaration, language_mode(),
426 typesystem::kAllowSignature, CHECK_OK); 444 type_flags, CHECK_OK);
427 return Statement::FunctionDeclaration(); 445 return Statement::FunctionDeclaration();
428 } 446 }
429 447
430 448
431 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { 449 PreParser::Statement PreParser::ParseClassDeclaration(bool ambient, bool* ok) {
432 Expect(Token::CLASS, CHECK_OK); 450 Expect(Token::CLASS, CHECK_OK);
433 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 451 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
434 ReportMessage(MessageTemplate::kSloppyLexical); 452 ReportMessage(MessageTemplate::kSloppyLexical);
435 *ok = false; 453 *ok = false;
436 return Statement::Default(); 454 return Statement::Default();
437 } 455 }
438 456
439 int pos = position(); 457 int pos = position();
440 bool is_strict_reserved = false; 458 bool is_strict_reserved = false;
441 Identifier name = 459 Identifier name =
442 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 460 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
443 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, 461 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
444 CHECK_OK); 462 ambient, CHECK_OK);
445 return Statement::Default(); 463 return Statement::Default();
446 } 464 }
447 465
448 466
449 PreParser::Statement PreParser::ParseBlock(bool* ok) { 467 PreParser::Statement PreParser::ParseBlock(bool* ok) {
450 // Block :: 468 // Block ::
451 // '{' StatementList '}' 469 // '{' StatementList '}'
452 470
471 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
nickie 2016/04/21 13:59:10 The changes in this method are repeated in https:/
453 Expect(Token::LBRACE, CHECK_OK); 472 Expect(Token::LBRACE, CHECK_OK);
454 Statement final = Statement::Default(); 473 Statement final = Statement::Default();
455 while (peek() != Token::RBRACE) { 474 {
456 final = ParseStatementListItem(CHECK_OK); 475 BlockState block_state(&scope_, block_scope);
476 while (peek() != Token::RBRACE) {
477 final = ParseStatementListItem(CHECK_OK);
478 }
457 } 479 }
458 Expect(Token::RBRACE, ok); 480 Expect(Token::RBRACE, ok);
459 return final; 481 return final;
460 } 482 }
461 483
462 484
463 PreParser::Statement PreParser::ParseVariableStatement( 485 PreParser::Statement PreParser::ParseVariableStatement(
464 VariableDeclarationContext var_context, 486 VariableDeclarationContext var_context, bool ambient, bool* ok) {
465 bool* ok) {
466 // VariableStatement :: 487 // VariableStatement ::
467 // VariableDeclarations ';' 488 // VariableDeclarations ';'
468 489
469 Statement result = ParseVariableDeclarations( 490 Statement result =
470 var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK); 491 ParseVariableDeclarations(var_context, nullptr, nullptr, nullptr, nullptr,
492 nullptr, ambient, CHECK_OK);
471 ExpectSemicolon(CHECK_OK); 493 ExpectSemicolon(CHECK_OK);
472 return result; 494 return result;
473 } 495 }
474 496
475 497
476 // If the variable declaration declares exactly one non-const 498 // If the variable declaration declares exactly one non-const
477 // variable, then *var is set to that variable. In all other cases, 499 // variable, then *var is set to that variable. In all other cases,
478 // *var is untouched; in particular, it is the caller's responsibility 500 // *var is untouched; in particular, it is the caller's responsibility
479 // to initialize it properly. This mechanism is also used for the parsing 501 // to initialize it properly. This mechanism is also used for the parsing
480 // of 'for-in' loops. 502 // of 'for-in' loops.
481 PreParser::Statement PreParser::ParseVariableDeclarations( 503 PreParser::Statement PreParser::ParseVariableDeclarations(
482 VariableDeclarationContext var_context, int* num_decl, bool* is_lexical, 504 VariableDeclarationContext var_context, int* num_decl, bool* is_lexical,
483 bool* is_binding_pattern, Scanner::Location* first_initializer_loc, 505 bool* is_binding_pattern, Scanner::Location* first_initializer_loc,
484 Scanner::Location* bindings_loc, bool* ok) { 506 Scanner::Location* bindings_loc, bool ambient, bool* ok) {
485 // VariableDeclarations :: 507 // VariableDeclarations ::
486 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 508 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
487 // 509 //
488 // The ES6 Draft Rev3 specifies the following grammar for const declarations 510 // The ES6 Draft Rev3 specifies the following grammar for const declarations
489 // 511 //
490 // ConstDeclaration :: 512 // ConstDeclaration ::
491 // const ConstBinding (',' ConstBinding)* ';' 513 // const ConstBinding (',' ConstBinding)* ';'
492 // ConstBinding :: 514 // ConstBinding ::
493 // Identifier '=' AssignmentExpression 515 // Identifier '=' AssignmentExpression
494 // 516 //
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 569 }
548 } 570 }
549 571
550 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); 572 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral();
551 573
552 // Parse optional type annotation. 574 // Parse optional type annotation.
553 if (scope_->typed() && Check(Token::COLON)) { // Braces required here. 575 if (scope_->typed() && Check(Token::COLON)) { // Braces required here.
554 ParseValidType(CHECK_OK); 576 ParseValidType(CHECK_OK);
555 } 577 }
556 578
579 // Initializers are not allowed in ambient declarations.
580 if (ambient) {
581 nvars++;
582 continue;
583 }
584
557 Scanner::Location variable_loc = scanner()->location(); 585 Scanner::Location variable_loc = scanner()->location();
558 nvars++; 586 nvars++;
559 if (Check(Token::ASSIGN)) { 587 if (Check(Token::ASSIGN)) {
560 ExpressionClassifier classifier(this); 588 ExpressionClassifier classifier(this);
561 ParseAssignmentExpression(var_context != kForStatement, &classifier, 589 ParseAssignmentExpression(var_context != kForStatement, &classifier,
562 CHECK_OK); 590 CHECK_OK);
563 ValidateExpression(&classifier, CHECK_OK); 591 ValidateExpression(&classifier, CHECK_OK);
564 592
565 variable_loc.end_pos = scanner()->location().end_pos; 593 variable_loc.end_pos = scanner()->location().end_pos;
566 if (first_initializer_loc && !first_initializer_loc->IsValid()) { 594 if (first_initializer_loc && !first_initializer_loc->IsValid()) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) { 646 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
619 // Expression is a single identifier, and not, e.g., a parenthesized 647 // Expression is a single identifier, and not, e.g., a parenthesized
620 // identifier. 648 // identifier.
621 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 649 DCHECK(!expr.AsIdentifier().IsFutureReserved());
622 DCHECK(is_sloppy(language_mode()) || 650 DCHECK(is_sloppy(language_mode()) ||
623 !IsFutureStrictReserved(expr.AsIdentifier())); 651 !IsFutureStrictReserved(expr.AsIdentifier()));
624 Consume(Token::COLON); 652 Consume(Token::COLON);
625 // ES#sec-labelled-function-declarations Labelled Function Declarations 653 // ES#sec-labelled-function-declarations Labelled Function Declarations
626 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { 654 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
627 if (allow_function == kAllowLabelledFunctionStatement) { 655 if (allow_function == kAllowLabelledFunctionStatement) {
628 return ParseFunctionDeclaration(ok); 656 return ParseFunctionDeclaration(false, ok);
629 } else { 657 } else {
630 return ParseScopedStatement(true, ok); 658 return ParseScopedStatement(true, ok);
631 } 659 }
632 } 660 }
633 Statement statement = 661 Statement statement =
634 ParseStatement(kDisallowLabelledFunctionStatement, ok); 662 ParseStatement(kDisallowLabelledFunctionStatement, ok);
635 return statement.IsJumpStatement() ? Statement::Default() : statement; 663 return statement.IsJumpStatement() ? Statement::Default() : statement;
636 // Preparsing is disabled for extensions (because the extension details 664 // Preparsing is disabled for extensions (because the extension details
637 // aren't passed to lazily compiled functions), so we don't 665 // aren't passed to lazily compiled functions), so we don't
638 // accept "native function" in the preparser. 666 // accept "native function" in the preparser.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 ForEachStatement::VisitMode mode; 855 ForEachStatement::VisitMode mode;
828 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || 856 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
829 (peek() == Token::LET && IsNextLetKeyword())) { 857 (peek() == Token::LET && IsNextLetKeyword())) {
830 int decl_count; 858 int decl_count;
831 bool is_lexical; 859 bool is_lexical;
832 bool is_binding_pattern; 860 bool is_binding_pattern;
833 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); 861 Scanner::Location first_initializer_loc = Scanner::Location::invalid();
834 Scanner::Location bindings_loc = Scanner::Location::invalid(); 862 Scanner::Location bindings_loc = Scanner::Location::invalid();
835 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, 863 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical,
836 &is_binding_pattern, &first_initializer_loc, 864 &is_binding_pattern, &first_initializer_loc,
837 &bindings_loc, CHECK_OK); 865 &bindings_loc, false, CHECK_OK);
838 if (CheckInOrOf(&mode, ok)) { 866 if (CheckInOrOf(&mode, ok)) {
839 if (!*ok) return Statement::Default(); 867 if (!*ok) return Statement::Default();
840 if (decl_count != 1) { 868 if (decl_count != 1) {
841 PreParserTraits::ReportMessageAt( 869 PreParserTraits::ReportMessageAt(
842 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings, 870 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings,
843 ForEachStatement::VisitModeString(mode)); 871 ForEachStatement::VisitModeString(mode));
844 *ok = false; 872 *ok = false;
845 return Statement::Default(); 873 return Statement::Default();
846 } 874 }
847 if (first_initializer_loc.IsValid() && 875 if (first_initializer_loc.IsValid() &&
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position, 1076 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
1049 formals_end_position, CHECK_OK); 1077 formals_end_position, CHECK_OK);
1050 1078
1051 // See Parser::ParseFunctionLiteral for more information about lazy parsing 1079 // See Parser::ParseFunctionLiteral for more information about lazy parsing
1052 // and lazy compilation. 1080 // and lazy compilation.
1053 bool is_lazily_parsed = 1081 bool is_lazily_parsed =
1054 (outer_is_script_scope && allow_lazy() && !parenthesized_function_); 1082 (outer_is_script_scope && allow_lazy() && !parenthesized_function_);
1055 parenthesized_function_ = false; 1083 parenthesized_function_ = false;
1056 1084
1057 // Parse optional type annotation. 1085 // Parse optional type annotation.
1058 if (scope_->typed() && 1086 if (scope_->typed() && !(type_flags & typesystem::kDisallowTypeAnnotation) &&
1059 !(type_flags & typesystem::kDisallowTypeAnnotation) &&
1060 Check(Token::COLON)) { // Braces required here. 1087 Check(Token::COLON)) { // Braces required here.
1061 ParseValidType(CHECK_OK); 1088 ParseValidType(CHECK_OK);
1062 } 1089 }
1063 1090
1064 // Allow for a function signature (i.e., a literal without body). 1091 // Allow or even enforce a function signature (i.e., literal without body),
1065 if (peek() != Token::LBRACE && scope_->typed() && 1092 // In that case, return a nullptr instead of a function literal.
1066 (type_flags & typesystem::kAllowSignature)) { 1093 if ((type_flags & typesystem::kDisallowBody) ||
1094 (peek() != Token::LBRACE && scope_->typed() &&
1095 (type_flags & typesystem::kAllowSignature))) {
1067 ExpectSemicolon(CHECK_OK); 1096 ExpectSemicolon(CHECK_OK);
1068 return this->EmptyExpression(); 1097 return this->EmptyExpression();
1069 } 1098 }
1070 1099
1071 Expect(Token::LBRACE, CHECK_OK); 1100 Expect(Token::LBRACE, CHECK_OK);
1072 if (is_lazily_parsed) { 1101 if (is_lazily_parsed) {
1073 ParseLazyFunctionLiteralBody(CHECK_OK); 1102 ParseLazyFunctionLiteralBody(CHECK_OK);
1074 } else { 1103 } else {
1075 ParseStatementList(Token::RBRACE, CHECK_OK); 1104 ParseStatementList(Token::RBRACE, CHECK_OK);
1076 } 1105 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1109 int body_end = scanner()->peek_location().end_pos; 1138 int body_end = scanner()->peek_location().end_pos;
1110 log_->LogFunction(body_start, body_end, 1139 log_->LogFunction(body_start, body_end,
1111 function_state_->materialized_literal_count(), 1140 function_state_->materialized_literal_count(),
1112 function_state_->expected_property_count(), language_mode(), 1141 function_state_->expected_property_count(), language_mode(),
1113 scope_->uses_super_property(), scope_->calls_eval()); 1142 scope_->uses_super_property(), scope_->calls_eval());
1114 } 1143 }
1115 1144
1116 1145
1117 PreParserExpression PreParser::ParseClassLiteral( 1146 PreParserExpression PreParser::ParseClassLiteral(
1118 PreParserIdentifier name, Scanner::Location class_name_location, 1147 PreParserIdentifier name, Scanner::Location class_name_location,
1119 bool name_is_strict_reserved, int pos, bool* ok) { 1148 bool name_is_strict_reserved, int pos, bool ambient, bool* ok) {
1120 // All parts of a ClassDeclaration and ClassExpression are strict code. 1149 // All parts of a ClassDeclaration and ClassExpression are strict code.
1121 if (name_is_strict_reserved) { 1150 if (name_is_strict_reserved) {
1122 ReportMessageAt(class_name_location, 1151 ReportMessageAt(class_name_location,
1123 MessageTemplate::kUnexpectedStrictReserved); 1152 MessageTemplate::kUnexpectedStrictReserved);
1124 *ok = false; 1153 *ok = false;
1125 return EmptyExpression(); 1154 return EmptyExpression();
1126 } 1155 }
1127 if (IsEvalOrArguments(name)) { 1156 if (IsEvalOrArguments(name)) {
1128 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); 1157 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
1129 *ok = false; 1158 *ok = false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 while (peek() != Token::RBRACE) { 1194 while (peek() != Token::RBRACE) {
1166 if (Check(Token::SEMICOLON)) continue; 1195 if (Check(Token::SEMICOLON)) continue;
1167 const bool in_class = true; 1196 const bool in_class = true;
1168 const bool is_static = false; 1197 const bool is_static = false;
1169 bool is_computed_name = false; // Classes do not care about computed 1198 bool is_computed_name = false; // Classes do not care about computed
1170 // property names here. 1199 // property names here.
1171 Identifier name; 1200 Identifier name;
1172 ExpressionClassifier classifier(this); 1201 ExpressionClassifier classifier(this);
1173 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, 1202 ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
1174 &is_computed_name, &has_seen_constructor, 1203 &is_computed_name, &has_seen_constructor,
1175 &classifier, &name, CHECK_OK); 1204 &classifier, &name, ambient, CHECK_OK);
1176 ValidateExpression(&classifier, CHECK_OK); 1205 ValidateExpression(&classifier, CHECK_OK);
1177 } 1206 }
1178 1207
1179 Expect(Token::RBRACE, CHECK_OK); 1208 Expect(Token::RBRACE, CHECK_OK);
1180 1209
1181 return Expression::Default(); 1210 return Expression::Default();
1182 } 1211 }
1183 1212
1184 1213
1185 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1214 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 Expect(Token::RBRACE, CHECK_OK); 1246 Expect(Token::RBRACE, CHECK_OK);
1218 return PreParserExpression::Default(); 1247 return PreParserExpression::Default();
1219 } 1248 }
1220 } 1249 }
1221 1250
1222 #undef CHECK_OK 1251 #undef CHECK_OK
1223 1252
1224 1253
1225 } // namespace internal 1254 } // namespace internal
1226 } // namespace v8 1255 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/preparser.h ('k') | test/cctest/test-parsing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698