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