OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |