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

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: 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
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
156 // sufficiently to deduce some information about it, that can be used 156 // sufficiently to deduce some information about it, that can be used
157 // to speed up later parsing. Finding errors is not the goal of pre-parsing, 157 // to speed up later parsing. Finding errors is not the goal of pre-parsing,
158 // rather it is to speed up properly written and correct programs. 158 // rather it is to speed up properly written and correct programs.
159 // That means that contextual checks (like a label being declared where 159 // That means that contextual checks (like a label being declared where
160 // it is used) are generally omitted. 160 // it is used) are generally omitted.
161 161
162 162
163 PreParser::Statement PreParser::ParseStatementListItem(bool* ok) { 163 PreParser::Statement PreParser::ParseStatementListItem(bool top_level,
164 bool* ok) {
164 // ECMA 262 6th Edition 165 // ECMA 262 6th Edition
165 // StatementListItem[Yield, Return] : 166 // StatementListItem[Yield, Return] :
166 // Statement[?Yield, ?Return] 167 // Statement[?Yield, ?Return]
167 // Declaration[?Yield] 168 // Declaration[?Yield]
168 // 169 //
169 // Declaration[Yield] : 170 // Declaration[Yield] :
170 // HoistableDeclaration[?Yield] 171 // HoistableDeclaration[?Yield]
171 // ClassDeclaration[?Yield] 172 // ClassDeclaration[?Yield]
172 // LexicalDeclaration[In, ?Yield] 173 // LexicalDeclaration[In, ?Yield]
173 // 174 //
174 // HoistableDeclaration[Yield, Default] : 175 // HoistableDeclaration[Yield, Default] :
175 // FunctionDeclaration[?Yield, ?Default] 176 // FunctionDeclaration[?Yield, ?Default]
176 // GeneratorDeclaration[?Yield, ?Default] 177 // GeneratorDeclaration[?Yield, ?Default]
177 // 178 //
178 // LexicalDeclaration[In, Yield] : 179 // LexicalDeclaration[In, Yield] :
179 // LetOrConst BindingList[?In, ?Yield] ; 180 // LetOrConst BindingList[?In, ?Yield] ;
180 181
182 // Allow ambient variable, function, and class declarations.
183 bool ambient =
184 scope_->typed() && CheckContextualKeyword(CStrVector("declare"));
185 if (ambient && !top_level) {
186 *ok = false;
187 ReportMessage(MessageTemplate::kIllegalDeclare);
188 return Statement::Default();
189 }
181 switch (peek()) { 190 switch (peek()) {
182 case Token::FUNCTION: 191 case Token::FUNCTION:
183 return ParseFunctionDeclaration(ok); 192 return ParseFunctionDeclaration(ambient, ok);
184 case Token::CLASS: 193 case Token::CLASS:
185 return ParseClassDeclaration(ok); 194 return ParseClassDeclaration(ambient, ok);
186 case Token::CONST: 195 case Token::CONST:
187 if (allow_const()) { 196 if (allow_const()) {
188 return ParseVariableStatement(kStatementListItem, ok); 197 return ParseVariableStatement(kStatementListItem, ambient, ok);
189 } 198 }
190 break; 199 break;
200 case Token::VAR:
201 return ParseVariableStatement(kStatementListItem, ambient, ok);
191 case Token::LET: 202 case Token::LET:
192 if (IsNextLetKeyword()) { 203 if (IsNextLetKeyword()) {
193 return ParseVariableStatement(kStatementListItem, ok); 204 return ParseVariableStatement(kStatementListItem, ambient, ok);
194 } 205 }
195 break; 206 break;
196 case Token::IDENTIFIER: 207 case Token::IDENTIFIER:
197 case Token::FUTURE_STRICT_RESERVED_WORD: { 208 case Token::FUTURE_STRICT_RESERVED_WORD: {
198 if (!scope_->typed()) break; 209 if (!scope_->typed() || ambient) break;
199 int pos = peek_position(); 210 int pos = peek_position();
200 if (CheckContextualKeyword(CStrVector("type"))) { 211 if (CheckContextualKeyword(CStrVector("type"))) {
201 return ParseTypeAliasDeclaration(pos, ok); 212 return ParseTypeAliasDeclaration(pos, ok);
202 } else if (CheckContextualKeyword(CStrVector("interface"))) { 213 } else if (CheckContextualKeyword(CStrVector("interface"))) {
203 return ParseInterfaceDeclaration(pos, ok); 214 return ParseInterfaceDeclaration(pos, ok);
204 } 215 }
205 break; 216 break;
206 } 217 }
207 // TODO(nikolaos): ambient
208 default: 218 default:
209 break; 219 break;
210 } 220 }
221 if (ambient) {
222 *ok = false;
223 ReportMessageAt(scanner()->peek_location(),
224 MessageTemplate::kBadAmbientDeclaration);
225 return Statement::Default();
226 }
211 return ParseStatement(kAllowLabelledFunctionStatement, ok); 227 return ParseStatement(kAllowLabelledFunctionStatement, ok);
212 } 228 }
213 229
214 230
215 void PreParser::ParseStatementList(int end_token, bool* ok, 231 void PreParser::ParseStatementList(int end_token, bool top_level, bool* ok,
216 Scanner::BookmarkScope* bookmark) { 232 Scanner::BookmarkScope* bookmark) {
217 // SourceElements :: 233 // SourceElements ::
218 // (Statement)* <end_token> 234 // (Statement)* <end_token>
219 235
220 // Bookkeeping for trial parse if bookmark is set: 236 // Bookkeeping for trial parse if bookmark is set:
221 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet()); 237 DCHECK_IMPLIES(bookmark, bookmark->HasBeenSet());
222 bool maybe_reset = bookmark != nullptr; 238 bool maybe_reset = bookmark != nullptr;
223 int count_statements = 0; 239 int count_statements = 0;
224 240
225 bool directive_prologue = true; 241 bool directive_prologue = true;
226 while (peek() != end_token) { 242 while (peek() != end_token) {
227 if (directive_prologue && peek() != Token::STRING) { 243 if (directive_prologue && peek() != Token::STRING) {
228 directive_prologue = false; 244 directive_prologue = false;
229 } 245 }
230 bool starts_with_identifier = peek() == Token::IDENTIFIER; 246 bool starts_with_identifier = peek() == Token::IDENTIFIER;
231 Scanner::Location token_loc = scanner()->peek_location(); 247 Scanner::Location token_loc = scanner()->peek_location();
232 Statement statement = ParseStatementListItem(ok); 248 Statement statement = ParseStatementListItem(top_level, ok);
233 if (!*ok) return; 249 if (!*ok) return;
234 250
235 if (directive_prologue) { 251 if (directive_prologue) {
236 bool use_strict_found = statement.IsUseStrictLiteral(); 252 bool use_strict_found = statement.IsUseStrictLiteral();
237 bool use_types_found = 253 bool use_types_found =
238 statement.IsUseTypesLiteral() && allow_harmony_types(); 254 statement.IsUseTypesLiteral() && allow_harmony_types();
239 255
240 if (use_strict_found) { 256 if (use_strict_found) {
241 scope_->SetLanguageMode( 257 scope_->SetLanguageMode(
242 static_cast<LanguageMode>(scope_->language_mode() | STRICT)); 258 static_cast<LanguageMode>(scope_->language_mode() | STRICT));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 return Statement::Default(); 317 return Statement::Default();
302 } 318 }
303 return ParseSubStatement(allow_function, ok); 319 return ParseSubStatement(allow_function, ok);
304 } 320 }
305 321
306 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) { 322 PreParser::Statement PreParser::ParseScopedStatement(bool legacy, bool* ok) {
307 if (is_strict(language_mode()) || peek() != Token::FUNCTION || 323 if (is_strict(language_mode()) || peek() != Token::FUNCTION ||
308 (legacy && allow_harmony_restrictive_declarations())) { 324 (legacy && allow_harmony_restrictive_declarations())) {
309 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok); 325 return ParseSubStatement(kDisallowLabelledFunctionStatement, ok);
310 } else { 326 } else {
311 return ParseFunctionDeclaration(CHECK_OK); 327 return ParseFunctionDeclaration(false, CHECK_OK);
312 } 328 }
313 } 329 }
314 330
315 PreParser::Statement PreParser::ParseSubStatement( 331 PreParser::Statement PreParser::ParseSubStatement(
316 AllowLabelledFunctionStatement allow_function, bool* ok) { 332 AllowLabelledFunctionStatement allow_function, bool* ok) {
317 // Statement :: 333 // Statement ::
318 // Block 334 // Block
319 // VariableStatement 335 // VariableStatement
320 // EmptyStatement 336 // EmptyStatement
321 // ExpressionStatement 337 // ExpressionStatement
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 is_strict(language_mode()) 406 is_strict(language_mode())
391 ? MessageTemplate::kStrictFunction 407 ? MessageTemplate::kStrictFunction
392 : MessageTemplate::kSloppyFunction); 408 : MessageTemplate::kSloppyFunction);
393 *ok = false; 409 *ok = false;
394 return Statement::Default(); 410 return Statement::Default();
395 411
396 case Token::DEBUGGER: 412 case Token::DEBUGGER:
397 return ParseDebuggerStatement(ok); 413 return ParseDebuggerStatement(ok);
398 414
399 case Token::VAR: 415 case Token::VAR:
400 return ParseVariableStatement(kStatement, ok); 416 return ParseVariableStatement(kStatement, false, ok);
401 417
402 default: 418 default:
403 return ParseExpressionOrLabelledStatement(allow_function, ok); 419 return ParseExpressionOrLabelledStatement(allow_function, ok);
404 } 420 }
405 } 421 }
406 422
407 423
408 PreParser::Statement PreParser::ParseFunctionDeclaration(bool* ok) { 424 PreParser::Statement PreParser::ParseFunctionDeclaration(bool ambient,
425 bool* ok) {
409 // FunctionDeclaration :: 426 // FunctionDeclaration ::
410 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}' 427 // 'function' Identifier '(' FormalParameterListopt ')' '{' FunctionBody '}'
411 // GeneratorDeclaration :: 428 // GeneratorDeclaration ::
412 // 'function' '*' Identifier '(' FormalParameterListopt ')' 429 // 'function' '*' Identifier '(' FormalParameterListopt ')'
413 // '{' FunctionBody '}' 430 // '{' FunctionBody '}'
414 Expect(Token::FUNCTION, CHECK_OK); 431 Expect(Token::FUNCTION, CHECK_OK);
415 int pos = position(); 432 int pos = position();
416 bool is_generator = Check(Token::MUL); 433 bool is_generator = Check(Token::MUL);
417 bool is_strict_reserved = false; 434 bool is_strict_reserved = false;
418 Identifier name = ParseIdentifierOrStrictReservedWord( 435 Identifier name = ParseIdentifierOrStrictReservedWord(
419 &is_strict_reserved, CHECK_OK); 436 &is_strict_reserved, CHECK_OK);
437 typesystem::TypeFlags type_flags =
438 ambient ? typesystem::kAmbient : typesystem::kAllowSignature;
420 ParseFunctionLiteral(name, scanner()->location(), 439 ParseFunctionLiteral(name, scanner()->location(),
421 is_strict_reserved ? kFunctionNameIsStrictReserved 440 is_strict_reserved ? kFunctionNameIsStrictReserved
422 : kFunctionNameValidityUnknown, 441 : kFunctionNameValidityUnknown,
423 is_generator ? FunctionKind::kGeneratorFunction 442 is_generator ? FunctionKind::kGeneratorFunction
424 : FunctionKind::kNormalFunction, 443 : FunctionKind::kNormalFunction,
425 pos, FunctionLiteral::kDeclaration, language_mode(), 444 pos, FunctionLiteral::kDeclaration, language_mode(),
426 typesystem::kAllowSignature, CHECK_OK); 445 type_flags, CHECK_OK);
427 return Statement::FunctionDeclaration(); 446 return Statement::FunctionDeclaration();
428 } 447 }
429 448
430 449
431 PreParser::Statement PreParser::ParseClassDeclaration(bool* ok) { 450 PreParser::Statement PreParser::ParseClassDeclaration(bool ambient, bool* ok) {
432 Expect(Token::CLASS, CHECK_OK); 451 Expect(Token::CLASS, CHECK_OK);
433 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) { 452 if (!allow_harmony_sloppy() && is_sloppy(language_mode())) {
434 ReportMessage(MessageTemplate::kSloppyLexical); 453 ReportMessage(MessageTemplate::kSloppyLexical);
435 *ok = false; 454 *ok = false;
436 return Statement::Default(); 455 return Statement::Default();
437 } 456 }
438 457
439 int pos = position(); 458 int pos = position();
440 bool is_strict_reserved = false; 459 bool is_strict_reserved = false;
441 Identifier name = 460 Identifier name =
442 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); 461 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
443 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos, 462 ParseClassLiteral(name, scanner()->location(), is_strict_reserved, pos,
444 CHECK_OK); 463 ambient, CHECK_OK);
445 return Statement::Default(); 464 return Statement::Default();
446 } 465 }
447 466
448 467
449 PreParser::Statement PreParser::ParseBlock(bool* ok) { 468 PreParser::Statement PreParser::ParseBlock(bool* ok) {
450 // Block :: 469 // Block ::
451 // '{' StatementList '}' 470 // '{' StatementList '}'
452 471
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 while (peek() != Token::RBRACE) {
456 final = ParseStatementListItem(CHECK_OK); 475 final = ParseStatementListItem(false, CHECK_OK);
457 } 476 }
458 Expect(Token::RBRACE, ok); 477 Expect(Token::RBRACE, ok);
459 return final; 478 return final;
460 } 479 }
461 480
462 481
463 PreParser::Statement PreParser::ParseVariableStatement( 482 PreParser::Statement PreParser::ParseVariableStatement(
464 VariableDeclarationContext var_context, 483 VariableDeclarationContext var_context, bool ambient, bool* ok) {
465 bool* ok) {
466 // VariableStatement :: 484 // VariableStatement ::
467 // VariableDeclarations ';' 485 // VariableDeclarations ';'
468 486
469 Statement result = ParseVariableDeclarations( 487 Statement result =
470 var_context, nullptr, nullptr, nullptr, nullptr, nullptr, CHECK_OK); 488 ParseVariableDeclarations(var_context, nullptr, nullptr, nullptr, nullptr,
489 nullptr, ambient, CHECK_OK);
471 ExpectSemicolon(CHECK_OK); 490 ExpectSemicolon(CHECK_OK);
472 return result; 491 return result;
473 } 492 }
474 493
475 494
476 // If the variable declaration declares exactly one non-const 495 // If the variable declaration declares exactly one non-const
477 // variable, then *var is set to that variable. In all other cases, 496 // variable, then *var is set to that variable. In all other cases,
478 // *var is untouched; in particular, it is the caller's responsibility 497 // *var is untouched; in particular, it is the caller's responsibility
479 // to initialize it properly. This mechanism is also used for the parsing 498 // to initialize it properly. This mechanism is also used for the parsing
480 // of 'for-in' loops. 499 // of 'for-in' loops.
481 PreParser::Statement PreParser::ParseVariableDeclarations( 500 PreParser::Statement PreParser::ParseVariableDeclarations(
482 VariableDeclarationContext var_context, int* num_decl, bool* is_lexical, 501 VariableDeclarationContext var_context, int* num_decl, bool* is_lexical,
483 bool* is_binding_pattern, Scanner::Location* first_initializer_loc, 502 bool* is_binding_pattern, Scanner::Location* first_initializer_loc,
484 Scanner::Location* bindings_loc, bool* ok) { 503 Scanner::Location* bindings_loc, bool ambient, bool* ok) {
485 // VariableDeclarations :: 504 // VariableDeclarations ::
486 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[','] 505 // ('var' | 'const') (Identifier ('=' AssignmentExpression)?)+[',']
487 // 506 //
488 // The ES6 Draft Rev3 specifies the following grammar for const declarations 507 // The ES6 Draft Rev3 specifies the following grammar for const declarations
489 // 508 //
490 // ConstDeclaration :: 509 // ConstDeclaration ::
491 // const ConstBinding (',' ConstBinding)* ';' 510 // const ConstBinding (',' ConstBinding)* ';'
492 // ConstBinding :: 511 // ConstBinding ::
493 // Identifier '=' AssignmentExpression 512 // Identifier '=' AssignmentExpression
494 // 513 //
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 566 }
548 } 567 }
549 568
550 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral(); 569 is_pattern = pattern.IsObjectLiteral() || pattern.IsArrayLiteral();
551 570
552 // Parse optional type annotation. 571 // Parse optional type annotation.
553 if (scope_->typed() && Check(Token::COLON)) { // Braces required here. 572 if (scope_->typed() && Check(Token::COLON)) { // Braces required here.
554 ParseValidType(CHECK_OK); 573 ParseValidType(CHECK_OK);
555 } 574 }
556 575
576 // Skip initializers, for ambient declarations.
rossberg 2016/04/20 15:16:35 Nit: maybe don't say "skip initializers", but "no
nickie 2016/04/21 13:57:10 Done.
577 if (ambient) {
578 nvars++;
579 continue;
580 }
581
557 Scanner::Location variable_loc = scanner()->location(); 582 Scanner::Location variable_loc = scanner()->location();
558 nvars++; 583 nvars++;
559 if (Check(Token::ASSIGN)) { 584 if (Check(Token::ASSIGN)) {
560 ExpressionClassifier classifier(this); 585 ExpressionClassifier classifier(this);
561 ParseAssignmentExpression(var_context != kForStatement, &classifier, 586 ParseAssignmentExpression(var_context != kForStatement, &classifier,
562 CHECK_OK); 587 CHECK_OK);
563 ValidateExpression(&classifier, CHECK_OK); 588 ValidateExpression(&classifier, CHECK_OK);
564 589
565 variable_loc.end_pos = scanner()->location().end_pos; 590 variable_loc.end_pos = scanner()->location().end_pos;
566 if (first_initializer_loc && !first_initializer_loc->IsValid()) { 591 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) { 643 if (starts_with_identifier && expr.IsIdentifier() && peek() == Token::COLON) {
619 // Expression is a single identifier, and not, e.g., a parenthesized 644 // Expression is a single identifier, and not, e.g., a parenthesized
620 // identifier. 645 // identifier.
621 DCHECK(!expr.AsIdentifier().IsFutureReserved()); 646 DCHECK(!expr.AsIdentifier().IsFutureReserved());
622 DCHECK(is_sloppy(language_mode()) || 647 DCHECK(is_sloppy(language_mode()) ||
623 !IsFutureStrictReserved(expr.AsIdentifier())); 648 !IsFutureStrictReserved(expr.AsIdentifier()));
624 Consume(Token::COLON); 649 Consume(Token::COLON);
625 // ES#sec-labelled-function-declarations Labelled Function Declarations 650 // ES#sec-labelled-function-declarations Labelled Function Declarations
626 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) { 651 if (peek() == Token::FUNCTION && is_sloppy(language_mode())) {
627 if (allow_function == kAllowLabelledFunctionStatement) { 652 if (allow_function == kAllowLabelledFunctionStatement) {
628 return ParseFunctionDeclaration(ok); 653 return ParseFunctionDeclaration(false, ok);
629 } else { 654 } else {
630 return ParseScopedStatement(true, ok); 655 return ParseScopedStatement(true, ok);
631 } 656 }
632 } 657 }
633 Statement statement = 658 Statement statement =
634 ParseStatement(kDisallowLabelledFunctionStatement, ok); 659 ParseStatement(kDisallowLabelledFunctionStatement, ok);
635 return statement.IsJumpStatement() ? Statement::Default() : statement; 660 return statement.IsJumpStatement() ? Statement::Default() : statement;
636 // Preparsing is disabled for extensions (because the extension details 661 // Preparsing is disabled for extensions (because the extension details
637 // aren't passed to lazily compiled functions), so we don't 662 // aren't passed to lazily compiled functions), so we don't
638 // accept "native function" in the preparser. 663 // accept "native function" in the preparser.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 ParseExpression(true, CHECK_OK); 797 ParseExpression(true, CHECK_OK);
773 } else { 798 } else {
774 Expect(Token::DEFAULT, CHECK_OK); 799 Expect(Token::DEFAULT, CHECK_OK);
775 } 800 }
776 Expect(Token::COLON, CHECK_OK); 801 Expect(Token::COLON, CHECK_OK);
777 token = peek(); 802 token = peek();
778 Statement statement = Statement::Jump(); 803 Statement statement = Statement::Jump();
779 while (token != Token::CASE && 804 while (token != Token::CASE &&
780 token != Token::DEFAULT && 805 token != Token::DEFAULT &&
781 token != Token::RBRACE) { 806 token != Token::RBRACE) {
782 statement = ParseStatementListItem(CHECK_OK); 807 statement = ParseStatementListItem(false, CHECK_OK);
783 token = peek(); 808 token = peek();
784 } 809 }
785 } 810 }
786 Expect(Token::RBRACE, ok); 811 Expect(Token::RBRACE, ok);
787 return Statement::Default(); 812 return Statement::Default();
788 } 813 }
789 814
790 815
791 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) { 816 PreParser::Statement PreParser::ParseDoWhileStatement(bool* ok) {
792 // DoStatement :: 817 // DoStatement ::
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
827 ForEachStatement::VisitMode mode; 852 ForEachStatement::VisitMode mode;
828 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) || 853 if (peek() == Token::VAR || (peek() == Token::CONST && allow_const()) ||
829 (peek() == Token::LET && IsNextLetKeyword())) { 854 (peek() == Token::LET && IsNextLetKeyword())) {
830 int decl_count; 855 int decl_count;
831 bool is_lexical; 856 bool is_lexical;
832 bool is_binding_pattern; 857 bool is_binding_pattern;
833 Scanner::Location first_initializer_loc = Scanner::Location::invalid(); 858 Scanner::Location first_initializer_loc = Scanner::Location::invalid();
834 Scanner::Location bindings_loc = Scanner::Location::invalid(); 859 Scanner::Location bindings_loc = Scanner::Location::invalid();
835 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical, 860 ParseVariableDeclarations(kForStatement, &decl_count, &is_lexical,
836 &is_binding_pattern, &first_initializer_loc, 861 &is_binding_pattern, &first_initializer_loc,
837 &bindings_loc, CHECK_OK); 862 &bindings_loc, false, CHECK_OK);
838 if (CheckInOrOf(&mode, ok)) { 863 if (CheckInOrOf(&mode, ok)) {
839 if (!*ok) return Statement::Default(); 864 if (!*ok) return Statement::Default();
840 if (decl_count != 1) { 865 if (decl_count != 1) {
841 PreParserTraits::ReportMessageAt( 866 PreParserTraits::ReportMessageAt(
842 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings, 867 bindings_loc, MessageTemplate::kForInOfLoopMultiBindings,
843 ForEachStatement::VisitModeString(mode)); 868 ForEachStatement::VisitModeString(mode));
844 *ok = false; 869 *ok = false;
845 return Statement::Default(); 870 return Statement::Default();
846 } 871 }
847 if (first_initializer_loc.IsValid() && 872 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, 1073 CheckArityRestrictions(formals.arity, kind, formals.has_rest, start_position,
1049 formals_end_position, CHECK_OK); 1074 formals_end_position, CHECK_OK);
1050 1075
1051 // See Parser::ParseFunctionLiteral for more information about lazy parsing 1076 // See Parser::ParseFunctionLiteral for more information about lazy parsing
1052 // and lazy compilation. 1077 // and lazy compilation.
1053 bool is_lazily_parsed = 1078 bool is_lazily_parsed =
1054 (outer_is_script_scope && allow_lazy() && !parenthesized_function_); 1079 (outer_is_script_scope && allow_lazy() && !parenthesized_function_);
1055 parenthesized_function_ = false; 1080 parenthesized_function_ = false;
1056 1081
1057 // Parse optional type annotation. 1082 // Parse optional type annotation.
1058 if (scope_->typed() && 1083 if (scope_->typed() && !(type_flags & typesystem::kDisallowTypeAnnotation) &&
1059 !(type_flags & typesystem::kDisallowTypeAnnotation) &&
1060 Check(Token::COLON)) { // Braces required here. 1084 Check(Token::COLON)) { // Braces required here.
1061 ParseValidType(CHECK_OK); 1085 ParseValidType(CHECK_OK);
1062 } 1086 }
1063 1087
1064 // Allow for a function signature (i.e., a literal without body). 1088 // Allow or even enforce a function signature (i.e., literal without body),
1065 if (peek() != Token::LBRACE && scope_->typed() && 1089 // In that case, return a nullptr instead of a function literal.
1066 (type_flags & typesystem::kAllowSignature)) { 1090 if ((type_flags & typesystem::kDisallowBody) ||
1091 (peek() != Token::LBRACE && scope_->typed() &&
1092 (type_flags & typesystem::kAllowSignature))) {
1067 ExpectSemicolon(CHECK_OK); 1093 ExpectSemicolon(CHECK_OK);
1068 return this->EmptyExpression(); 1094 return this->EmptyExpression();
1069 } 1095 }
1070 1096
1071 Expect(Token::LBRACE, CHECK_OK); 1097 Expect(Token::LBRACE, CHECK_OK);
1072 if (is_lazily_parsed) { 1098 if (is_lazily_parsed) {
1073 ParseLazyFunctionLiteralBody(CHECK_OK); 1099 ParseLazyFunctionLiteralBody(CHECK_OK);
1074 } else { 1100 } else {
1075 ParseStatementList(Token::RBRACE, CHECK_OK); 1101 ParseStatementList(Token::RBRACE, false, CHECK_OK);
1076 } 1102 }
1077 Expect(Token::RBRACE, CHECK_OK); 1103 Expect(Token::RBRACE, CHECK_OK);
1078 1104
1079 // Parsing the body may change the language mode in our scope. 1105 // Parsing the body may change the language mode in our scope.
1080 language_mode = function_scope->language_mode(); 1106 language_mode = function_scope->language_mode();
1081 1107
1082 // Validate name and parameter names. We can do this only after parsing the 1108 // Validate name and parameter names. We can do this only after parsing the
1083 // function, since the function can declare itself strict. 1109 // function, since the function can declare itself strict.
1084 CheckFunctionName(language_mode, function_name, function_name_validity, 1110 CheckFunctionName(language_mode, function_name, function_name_validity,
1085 function_name_location, CHECK_OK); 1111 function_name_location, CHECK_OK);
1086 const bool allow_duplicate_parameters = 1112 const bool allow_duplicate_parameters =
1087 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind); 1113 is_sloppy(language_mode) && formals.is_simple && !IsConciseMethod(kind);
1088 ValidateFormalParameters(&formals_classifier, language_mode, 1114 ValidateFormalParameters(&formals_classifier, language_mode,
1089 allow_duplicate_parameters, CHECK_OK); 1115 allow_duplicate_parameters, CHECK_OK);
1090 1116
1091 if (is_strict(language_mode)) { 1117 if (is_strict(language_mode)) {
1092 int end_position = scanner()->location().end_pos; 1118 int end_position = scanner()->location().end_pos;
1093 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK); 1119 CheckStrictOctalLiteral(start_position, end_position, CHECK_OK);
1094 } 1120 }
1095 1121
1096 return Expression::Default(); 1122 return Expression::Default();
1097 } 1123 }
1098 1124
1099 1125
1100 void PreParser::ParseLazyFunctionLiteralBody(bool* ok, 1126 void PreParser::ParseLazyFunctionLiteralBody(bool* ok,
1101 Scanner::BookmarkScope* bookmark) { 1127 Scanner::BookmarkScope* bookmark) {
1102 int body_start = position(); 1128 int body_start = position();
1103 ParseStatementList(Token::RBRACE, ok, bookmark); 1129 ParseStatementList(Token::RBRACE, false, ok, bookmark);
1104 if (!*ok) return; 1130 if (!*ok) return;
1105 if (bookmark && bookmark->HasBeenReset()) return; 1131 if (bookmark && bookmark->HasBeenReset()) return;
1106 1132
1107 // Position right after terminal '}'. 1133 // Position right after terminal '}'.
1108 DCHECK_EQ(Token::RBRACE, scanner()->peek()); 1134 DCHECK_EQ(Token::RBRACE, scanner()->peek());
1109 int body_end = scanner()->peek_location().end_pos; 1135 int body_end = scanner()->peek_location().end_pos;
1110 log_->LogFunction(body_start, body_end, 1136 log_->LogFunction(body_start, body_end,
1111 function_state_->materialized_literal_count(), 1137 function_state_->materialized_literal_count(),
1112 function_state_->expected_property_count(), language_mode(), 1138 function_state_->expected_property_count(), language_mode(),
1113 scope_->uses_super_property(), scope_->calls_eval()); 1139 scope_->uses_super_property(), scope_->calls_eval());
1114 } 1140 }
1115 1141
1116 1142
1117 PreParserExpression PreParser::ParseClassLiteral( 1143 PreParserExpression PreParser::ParseClassLiteral(
1118 PreParserIdentifier name, Scanner::Location class_name_location, 1144 PreParserIdentifier name, Scanner::Location class_name_location,
1119 bool name_is_strict_reserved, int pos, bool* ok) { 1145 bool name_is_strict_reserved, int pos, bool ambient, bool* ok) {
1120 // All parts of a ClassDeclaration and ClassExpression are strict code. 1146 // All parts of a ClassDeclaration and ClassExpression are strict code.
1121 if (name_is_strict_reserved) { 1147 if (name_is_strict_reserved) {
1122 ReportMessageAt(class_name_location, 1148 ReportMessageAt(class_name_location,
1123 MessageTemplate::kUnexpectedStrictReserved); 1149 MessageTemplate::kUnexpectedStrictReserved);
1124 *ok = false; 1150 *ok = false;
1125 return EmptyExpression(); 1151 return EmptyExpression();
1126 } 1152 }
1127 if (IsEvalOrArguments(name)) { 1153 if (IsEvalOrArguments(name)) {
1128 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments); 1154 ReportMessageAt(class_name_location, MessageTemplate::kStrictEvalArguments);
1129 *ok = false; 1155 *ok = false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 while (peek() != Token::RBRACE) { 1191 while (peek() != Token::RBRACE) {
1166 if (Check(Token::SEMICOLON)) continue; 1192 if (Check(Token::SEMICOLON)) continue;
1167 const bool in_class = true; 1193 const bool in_class = true;
1168 const bool is_static = false; 1194 const bool is_static = false;
1169 bool is_computed_name = false; // Classes do not care about computed 1195 bool is_computed_name = false; // Classes do not care about computed
1170 // property names here. 1196 // property names here.
1171 Identifier name; 1197 Identifier name;
1172 ExpressionClassifier classifier(this); 1198 ExpressionClassifier classifier(this);
1173 ParsePropertyDefinition(&checker, in_class, has_extends, is_static, 1199 ParsePropertyDefinition(&checker, in_class, has_extends, is_static,
1174 &is_computed_name, &has_seen_constructor, 1200 &is_computed_name, &has_seen_constructor,
1175 &classifier, &name, CHECK_OK); 1201 &classifier, &name, ambient, CHECK_OK);
1176 ValidateExpression(&classifier, CHECK_OK); 1202 ValidateExpression(&classifier, CHECK_OK);
1177 } 1203 }
1178 1204
1179 Expect(Token::RBRACE, CHECK_OK); 1205 Expect(Token::RBRACE, CHECK_OK);
1180 1206
1181 return Expression::Default(); 1207 return Expression::Default();
1182 } 1208 }
1183 1209
1184 1210
1185 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) { 1211 PreParser::Expression PreParser::ParseV8Intrinsic(bool* ok) {
(...skipping 19 matching lines...) Expand all
1205 1231
1206 PreParserExpression PreParser::ParseDoExpression(bool* ok) { 1232 PreParserExpression PreParser::ParseDoExpression(bool* ok) {
1207 // AssignmentExpression :: 1233 // AssignmentExpression ::
1208 // do '{' StatementList '}' 1234 // do '{' StatementList '}'
1209 Expect(Token::DO, CHECK_OK); 1235 Expect(Token::DO, CHECK_OK);
1210 Expect(Token::LBRACE, CHECK_OK); 1236 Expect(Token::LBRACE, CHECK_OK);
1211 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE); 1237 Scope* block_scope = NewScope(scope_, BLOCK_SCOPE);
1212 { 1238 {
1213 BlockState block_state(&scope_, block_scope); 1239 BlockState block_state(&scope_, block_scope);
1214 while (peek() != Token::RBRACE) { 1240 while (peek() != Token::RBRACE) {
1215 ParseStatementListItem(CHECK_OK); 1241 ParseStatementListItem(false, CHECK_OK);
1216 } 1242 }
1217 Expect(Token::RBRACE, CHECK_OK); 1243 Expect(Token::RBRACE, CHECK_OK);
1218 return PreParserExpression::Default(); 1244 return PreParserExpression::Default();
1219 } 1245 }
1220 } 1246 }
1221 1247
1222 #undef CHECK_OK 1248 #undef CHECK_OK
1223 1249
1224 1250
1225 } // namespace internal 1251 } // namespace internal
1226 } // namespace v8 1252 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698