| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 #include "vm/flags.h" | 6 #include "vm/flags.h" |
| 7 | 7 |
| 8 #ifndef DART_PRECOMPILED_RUNTIME | 8 #ifndef DART_PRECOMPILED_RUNTIME |
| 9 | 9 |
| 10 #include "lib/invocation_mirror.h" | 10 #include "lib/invocation_mirror.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 DECLARE_FLAG(bool, profile_vm); | 60 DECLARE_FLAG(bool, profile_vm); |
| 61 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); | 61 DECLARE_FLAG(bool, throw_on_javascript_int_overflow); |
| 62 DECLARE_FLAG(bool, warn_on_javascript_compatibility); | 62 DECLARE_FLAG(bool, warn_on_javascript_compatibility); |
| 63 | 63 |
| 64 // Quick access to the current thread, isolate and zone. | 64 // Quick access to the current thread, isolate and zone. |
| 65 #define T (thread()) | 65 #define T (thread()) |
| 66 #define I (isolate()) | 66 #define I (isolate()) |
| 67 #define Z (zone()) | 67 #define Z (zone()) |
| 68 | 68 |
| 69 // Quick synthetic token position. | 69 // Quick synthetic token position. |
| 70 #define ST(token_pos) Token::ToSynthetic(token_pos) | 70 #define ST(token_pos) TokenDescriptor::ToSynthetic(token_pos) |
| 71 | 71 |
| 72 #if defined(DEBUG) | 72 #if defined(DEBUG) |
| 73 class TraceParser : public ValueObject { | 73 class TraceParser : public ValueObject { |
| 74 public: | 74 public: |
| 75 TraceParser(intptr_t token_pos, | 75 TraceParser(TokenDescriptor token_pos, |
| 76 const Script& script, | 76 const Script& script, |
| 77 intptr_t* trace_indent, | 77 intptr_t* trace_indent, |
| 78 const char* msg) { | 78 const char* msg) { |
| 79 indent_ = trace_indent; | 79 indent_ = trace_indent; |
| 80 if (FLAG_trace_parser) { | 80 if (FLAG_trace_parser) { |
| 81 // Skips tracing of bootstrap libraries. | 81 // Skips tracing of bootstrap libraries. |
| 82 if (script.HasSource()) { | 82 if (script.HasSource()) { |
| 83 intptr_t line, column; | 83 intptr_t line, column; |
| 84 script.GetTokenLocation(token_pos, &line, &column); | 84 script.GetTokenLocation(token_pos, &line, &column); |
| 85 PrintIndent(); | 85 PrintIndent(); |
| 86 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", | 86 OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n", |
| 87 msg, line, column, token_pos); | 87 msg, line, column, token_pos.value()); |
| 88 } | 88 } |
| 89 (*indent_)++; | 89 (*indent_)++; |
| 90 } | 90 } |
| 91 } | 91 } |
| 92 ~TraceParser() { | 92 ~TraceParser() { |
| 93 if (FLAG_trace_parser) { | 93 if (FLAG_trace_parser) { |
| 94 (*indent_)--; | 94 (*indent_)--; |
| 95 ASSERT(*indent_ >= 0); | 95 ASSERT(*indent_ >= 0); |
| 96 } | 96 } |
| 97 } | 97 } |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 &found_captured_variables); | 255 &found_captured_variables); |
| 256 | 256 |
| 257 // Frame indices are relative to the frame pointer and are decreasing. | 257 // Frame indices are relative to the frame pointer and are decreasing. |
| 258 ASSERT(next_free_frame_index <= first_stack_local_index_); | 258 ASSERT(next_free_frame_index <= first_stack_local_index_); |
| 259 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; | 259 num_stack_locals_ = first_stack_local_index_ - next_free_frame_index; |
| 260 } | 260 } |
| 261 | 261 |
| 262 | 262 |
| 263 struct CatchParamDesc { | 263 struct CatchParamDesc { |
| 264 CatchParamDesc() | 264 CatchParamDesc() |
| 265 : token_pos(Token::kNoSourcePos), type(NULL), name(NULL), var(NULL) { } | 265 : token_pos(TokenDescriptor::kNoSource), |
| 266 intptr_t token_pos; | 266 type(NULL), |
| 267 name(NULL), |
| 268 var(NULL) { } |
| 269 TokenDescriptor token_pos; |
| 267 const AbstractType* type; | 270 const AbstractType* type; |
| 268 const String* name; | 271 const String* name; |
| 269 LocalVariable* var; | 272 LocalVariable* var; |
| 270 }; | 273 }; |
| 271 | 274 |
| 272 | 275 |
| 273 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { | 276 void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { |
| 274 ASSERT(function().IsIrregexpFunction()); | 277 ASSERT(function().IsIrregexpFunction()); |
| 275 ASSERT(function().NumOptionalParameters() == 0); | 278 ASSERT(function().NumOptionalParameters() == 0); |
| 276 const intptr_t num_params = function().num_fixed_parameters(); | 279 const intptr_t num_params = function().num_fixed_parameters(); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 DISALLOW_COPY_AND_ASSIGN(TryStack); | 345 DISALLOW_COPY_AND_ASSIGN(TryStack); |
| 343 }; | 346 }; |
| 344 | 347 |
| 345 | 348 |
| 346 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { | 349 void Parser::TryStack::AddNodeForFinallyInlining(AstNode* node) { |
| 347 inlined_finally_nodes_.Add(node); | 350 inlined_finally_nodes_.Add(node); |
| 348 } | 351 } |
| 349 | 352 |
| 350 | 353 |
| 351 // For parsing a compilation unit. | 354 // For parsing a compilation unit. |
| 352 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) | 355 Parser::Parser(const Script& script, |
| 356 const Library& library, |
| 357 TokenDescriptor token_pos) |
| 353 : isolate_(Thread::Current()->isolate()), | 358 : isolate_(Thread::Current()->isolate()), |
| 354 thread_(Thread::Current()), | 359 thread_(Thread::Current()), |
| 355 script_(Script::Handle(zone(), script.raw())), | 360 script_(Script::Handle(zone(), script.raw())), |
| 356 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), | 361 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
| 357 token_pos), | 362 token_pos), |
| 358 token_kind_(Token::kILLEGAL), | 363 token_kind_(Token::kILLEGAL), |
| 359 current_block_(NULL), | 364 current_block_(NULL), |
| 360 is_top_level_(false), | 365 is_top_level_(false), |
| 361 await_is_keyword_(false), | 366 await_is_keyword_(false), |
| 362 current_member_(NULL), | 367 current_member_(NULL), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 373 trace_indent_(0), | 378 trace_indent_(0), |
| 374 recursion_counter_(0) { | 379 recursion_counter_(0) { |
| 375 ASSERT(tokens_iterator_.IsValid()); | 380 ASSERT(tokens_iterator_.IsValid()); |
| 376 ASSERT(!library.IsNull()); | 381 ASSERT(!library.IsNull()); |
| 377 } | 382 } |
| 378 | 383 |
| 379 | 384 |
| 380 // For parsing a function. | 385 // For parsing a function. |
| 381 Parser::Parser(const Script& script, | 386 Parser::Parser(const Script& script, |
| 382 ParsedFunction* parsed_function, | 387 ParsedFunction* parsed_function, |
| 383 intptr_t token_position) | 388 TokenDescriptor token_pos) |
| 384 : isolate_(Thread::Current()->isolate()), | 389 : isolate_(Thread::Current()->isolate()), |
| 385 thread_(Thread::Current()), | 390 thread_(Thread::Current()), |
| 386 script_(Script::Handle(zone(), script.raw())), | 391 script_(Script::Handle(zone(), script.raw())), |
| 387 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), | 392 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
| 388 token_position), | 393 token_pos), |
| 389 token_kind_(Token::kILLEGAL), | 394 token_kind_(Token::kILLEGAL), |
| 390 current_block_(NULL), | 395 current_block_(NULL), |
| 391 is_top_level_(false), | 396 is_top_level_(false), |
| 392 await_is_keyword_(false), | 397 await_is_keyword_(false), |
| 393 current_member_(NULL), | 398 current_member_(NULL), |
| 394 allow_function_literals_(true), | 399 allow_function_literals_(true), |
| 395 parsed_function_(parsed_function), | 400 parsed_function_(parsed_function), |
| 396 innermost_function_(Function::Handle(zone(), | 401 innermost_function_(Function::Handle(zone(), |
| 397 parsed_function->function().raw())), | 402 parsed_function->function().raw())), |
| 398 literal_token_(LiteralToken::Handle(zone())), | 403 literal_token_(LiteralToken::Handle(zone())), |
| (...skipping 29 matching lines...) Expand all Loading... |
| 428 // Each try in this function gets its own try index. | 433 // Each try in this function gets its own try index. |
| 429 // See definition of RawPcDescriptors::PcDescriptor. | 434 // See definition of RawPcDescriptors::PcDescriptor. |
| 430 int16_t Parser::AllocateTryIndex() { | 435 int16_t Parser::AllocateTryIndex() { |
| 431 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { | 436 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { |
| 432 ReportError("too many nested try statements"); | 437 ReportError("too many nested try statements"); |
| 433 } | 438 } |
| 434 return last_used_try_index_++; | 439 return last_used_try_index_++; |
| 435 } | 440 } |
| 436 | 441 |
| 437 | 442 |
| 438 void Parser::SetScript(const Script& script, intptr_t token_pos) { | 443 void Parser::SetScript(const Script& script, TokenDescriptor token_pos) { |
| 439 script_ = script.raw(); | 444 script_ = script.raw(); |
| 440 tokens_iterator_.SetStream( | 445 tokens_iterator_.SetStream( |
| 441 TokenStream::Handle(Z, script.tokens()), token_pos); | 446 TokenStream::Handle(Z, script.tokens()), token_pos); |
| 442 token_kind_ = Token::kILLEGAL; | 447 token_kind_ = Token::kILLEGAL; |
| 443 } | 448 } |
| 444 | 449 |
| 445 | 450 |
| 446 bool Parser::SetAllowFunctionLiterals(bool value) { | 451 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 447 bool current_value = allow_function_literals_; | 452 bool current_value = allow_function_literals_; |
| 448 allow_function_literals_ = value; | 453 allow_function_literals_ = value; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 467 | 472 |
| 468 | 473 |
| 469 void Parser::set_current_class(const Class& value) { | 474 void Parser::set_current_class(const Class& value) { |
| 470 current_class_ = value.raw(); | 475 current_class_ = value.raw(); |
| 471 } | 476 } |
| 472 | 477 |
| 473 | 478 |
| 474 void Parser::SetPosition(intptr_t position) { | 479 void Parser::SetPosition(intptr_t position) { |
| 475 tokens_iterator_.SetCurrentPosition(position); | 480 tokens_iterator_.SetCurrentPosition(position); |
| 476 token_kind_ = Token::kILLEGAL; | 481 token_kind_ = Token::kILLEGAL; |
| 482 prev_token_pos_ = TokenDescriptor(position); |
| 483 } |
| 484 |
| 485 |
| 486 void Parser::SetPosition(TokenDescriptor position) { |
| 487 tokens_iterator_.SetCurrentPosition(position.value()); |
| 488 token_kind_ = Token::kILLEGAL; |
| 477 prev_token_pos_ = position; | 489 prev_token_pos_ = position; |
| 478 } | 490 } |
| 479 | 491 |
| 480 | 492 |
| 481 void Parser::ParseCompilationUnit(const Library& library, | 493 void Parser::ParseCompilationUnit(const Library& library, |
| 482 const Script& script) { | 494 const Script& script) { |
| 483 Thread* thread = Thread::Current(); | 495 Thread* thread = Thread::Current(); |
| 484 ASSERT(thread->long_jump_base()->IsSafeToJump()); | 496 ASSERT(thread->long_jump_base()->IsSafeToJump()); |
| 485 CSTAT_TIMER_SCOPE(thread, parser_timer); | 497 CSTAT_TIMER_SCOPE(thread, parser_timer); |
| 486 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); | 498 VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId); |
| 487 TimelineDurationScope tds(thread, | 499 TimelineDurationScope tds(thread, |
| 488 thread->isolate()->GetCompilerStream(), | 500 thread->isolate()->GetCompilerStream(), |
| 489 "CompileTopLevel"); | 501 "CompileTopLevel"); |
| 490 if (tds.enabled()) { | 502 if (tds.enabled()) { |
| 491 tds.SetNumArguments(1); | 503 tds.SetNumArguments(1); |
| 492 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); | 504 tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString()); |
| 493 } | 505 } |
| 494 | 506 |
| 495 Parser parser(script, library, 0); | 507 Parser parser(script, library, TokenDescriptor::kMinSource); |
| 496 parser.ParseTopLevel(); | 508 parser.ParseTopLevel(); |
| 497 } | 509 } |
| 498 | 510 |
| 499 | 511 |
| 500 void Parser::ComputeCurrentToken() { | 512 void Parser::ComputeCurrentToken() { |
| 501 ASSERT(token_kind_ == Token::kILLEGAL); | 513 ASSERT(token_kind_ == Token::kILLEGAL); |
| 502 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 514 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| 503 if (token_kind_ == Token::kERROR) { | 515 if (token_kind_ == Token::kERROR) { |
| 504 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 516 ReportError(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
| 505 } | 517 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 537 i.ToCString()); | 549 i.ToCString()); |
| 538 } | 550 } |
| 539 } | 551 } |
| 540 return ri; | 552 return ri; |
| 541 } | 553 } |
| 542 | 554 |
| 543 | 555 |
| 544 struct ParamDesc { | 556 struct ParamDesc { |
| 545 ParamDesc() | 557 ParamDesc() |
| 546 : type(NULL), | 558 : type(NULL), |
| 547 name_pos(Token::kNoSourcePos), | 559 name_pos(TokenDescriptor::kNoSource), |
| 548 name(NULL), | 560 name(NULL), |
| 549 default_value(NULL), | 561 default_value(NULL), |
| 550 metadata(NULL), | 562 metadata(NULL), |
| 551 var(NULL), | 563 var(NULL), |
| 552 is_final(false), | 564 is_final(false), |
| 553 is_field_initializer(false), | 565 is_field_initializer(false), |
| 554 has_explicit_type(false) { } | 566 has_explicit_type(false) { } |
| 555 const AbstractType* type; | 567 const AbstractType* type; |
| 556 intptr_t name_pos; | 568 TokenDescriptor name_pos; |
| 557 const String* name; | 569 const String* name; |
| 558 const Instance* default_value; // NULL if not an optional parameter. | 570 const Instance* default_value; // NULL if not an optional parameter. |
| 559 const Object* metadata; // NULL if no metadata or metadata not evaluated. | 571 const Object* metadata; // NULL if no metadata or metadata not evaluated. |
| 560 LocalVariable* var; // Scope variable allocated for this parameter. | 572 LocalVariable* var; // Scope variable allocated for this parameter. |
| 561 bool is_final; | 573 bool is_final; |
| 562 bool is_field_initializer; | 574 bool is_field_initializer; |
| 563 bool has_explicit_type; | 575 bool has_explicit_type; |
| 564 }; | 576 }; |
| 565 | 577 |
| 566 | 578 |
| 567 struct ParamList { | 579 struct ParamList { |
| 568 ParamList() { | 580 ParamList() { |
| 569 Clear(); | 581 Clear(); |
| 570 } | 582 } |
| 571 | 583 |
| 572 void Clear() { | 584 void Clear() { |
| 573 num_fixed_parameters = 0; | 585 num_fixed_parameters = 0; |
| 574 num_optional_parameters = 0; | 586 num_optional_parameters = 0; |
| 575 has_optional_positional_parameters = false; | 587 has_optional_positional_parameters = false; |
| 576 has_optional_named_parameters = false; | 588 has_optional_named_parameters = false; |
| 577 has_explicit_default_values = false; | 589 has_explicit_default_values = false; |
| 578 has_field_initializer = false; | 590 has_field_initializer = false; |
| 579 implicitly_final = false; | 591 implicitly_final = false; |
| 580 skipped = false; | 592 skipped = false; |
| 581 this->parameters = new ZoneGrowableArray<ParamDesc>(); | 593 this->parameters = new ZoneGrowableArray<ParamDesc>(); |
| 582 } | 594 } |
| 583 | 595 |
| 584 void AddFinalParameter(intptr_t name_pos, | 596 void AddFinalParameter(TokenDescriptor name_pos, |
| 585 const String* name, | 597 const String* name, |
| 586 const AbstractType* type) { | 598 const AbstractType* type) { |
| 587 this->num_fixed_parameters++; | 599 this->num_fixed_parameters++; |
| 588 ParamDesc param; | 600 ParamDesc param; |
| 589 param.name_pos = name_pos; | 601 param.name_pos = name_pos; |
| 590 param.name = name; | 602 param.name = name; |
| 591 param.is_final = true; | 603 param.is_final = true; |
| 592 param.type = type; | 604 param.type = type; |
| 593 this->parameters->Add(param); | 605 this->parameters->Add(param); |
| 594 } | 606 } |
| 595 | 607 |
| 596 void AddReceiver(const AbstractType* receiver_type, intptr_t token_pos) { | 608 void AddReceiver(const AbstractType* receiver_type, |
| 609 TokenDescriptor token_pos) { |
| 597 ASSERT(this->parameters->is_empty()); | 610 ASSERT(this->parameters->is_empty()); |
| 598 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); | 611 AddFinalParameter(token_pos, &Symbols::This(), receiver_type); |
| 599 } | 612 } |
| 600 | 613 |
| 601 void EraseParameterTypes() { | 614 void EraseParameterTypes() { |
| 602 const int num_parameters = parameters->length(); | 615 const int num_parameters = parameters->length(); |
| 603 for (int i = 0; i < num_parameters; i++) { | 616 for (int i = 0; i < num_parameters; i++) { |
| 604 (*parameters)[i].type = &Object::dynamic_type(); | 617 (*parameters)[i].type = &Object::dynamic_type(); |
| 605 } | 618 } |
| 606 } | 619 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 void Clear() { | 655 void Clear() { |
| 643 has_abstract = false; | 656 has_abstract = false; |
| 644 has_external = false; | 657 has_external = false; |
| 645 has_final = false; | 658 has_final = false; |
| 646 has_const = false; | 659 has_const = false; |
| 647 has_static = false; | 660 has_static = false; |
| 648 has_var = false; | 661 has_var = false; |
| 649 has_factory = false; | 662 has_factory = false; |
| 650 has_operator = false; | 663 has_operator = false; |
| 651 has_native = false; | 664 has_native = false; |
| 652 metadata_pos = Token::kNoSourcePos; | 665 metadata_pos = TokenDescriptor::kNoSource; |
| 653 operator_token = Token::kILLEGAL; | 666 operator_token = Token::kILLEGAL; |
| 654 type = NULL; | 667 type = NULL; |
| 655 name_pos = Token::kNoSourcePos; | 668 name_pos = TokenDescriptor::kNoSource; |
| 656 name = NULL; | 669 name = NULL; |
| 657 redirect_name = NULL; | 670 redirect_name = NULL; |
| 658 dict_name = NULL; | 671 dict_name = NULL; |
| 659 params.Clear(); | 672 params.Clear(); |
| 660 kind = RawFunction::kRegularFunction; | 673 kind = RawFunction::kRegularFunction; |
| 661 field_ = NULL; | 674 field_ = NULL; |
| 662 } | 675 } |
| 663 | 676 |
| 664 bool IsConstructor() const { | 677 bool IsConstructor() const { |
| 665 return (kind == RawFunction::kConstructor) && !has_static; | 678 return (kind == RawFunction::kConstructor) && !has_static; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 695 } | 708 } |
| 696 bool has_abstract; | 709 bool has_abstract; |
| 697 bool has_external; | 710 bool has_external; |
| 698 bool has_final; | 711 bool has_final; |
| 699 bool has_const; | 712 bool has_const; |
| 700 bool has_static; | 713 bool has_static; |
| 701 bool has_var; | 714 bool has_var; |
| 702 bool has_factory; | 715 bool has_factory; |
| 703 bool has_operator; | 716 bool has_operator; |
| 704 bool has_native; | 717 bool has_native; |
| 705 intptr_t metadata_pos; | 718 TokenDescriptor metadata_pos; |
| 706 Token::Kind operator_token; | 719 Token::Kind operator_token; |
| 707 const AbstractType* type; | 720 const AbstractType* type; |
| 708 intptr_t name_pos; | 721 TokenDescriptor name_pos; |
| 709 intptr_t decl_begin_pos; | 722 TokenDescriptor decl_begin_pos; |
| 710 String* name; | 723 String* name; |
| 711 // For constructors: NULL or name of redirected to constructor. | 724 // For constructors: NULL or name of redirected to constructor. |
| 712 String* redirect_name; | 725 String* redirect_name; |
| 713 // dict_name is the name used for the class namespace, if it | 726 // dict_name is the name used for the class namespace, if it |
| 714 // differs from 'name'. | 727 // differs from 'name'. |
| 715 // For constructors: NULL for unnamed constructor, | 728 // For constructors: NULL for unnamed constructor, |
| 716 // identifier after classname for named constructors. | 729 // identifier after classname for named constructors. |
| 717 // For getters and setters: unmangled name. | 730 // For getters and setters: unmangled name. |
| 718 String* dict_name; | 731 String* dict_name; |
| 719 ParamList params; | 732 ParamList params; |
| 720 RawFunction::Kind kind; | 733 RawFunction::Kind kind; |
| 721 // NULL for functions, field object for static or instance fields. | 734 // NULL for functions, field object for static or instance fields. |
| 722 Field* field_; | 735 Field* field_; |
| 723 }; | 736 }; |
| 724 | 737 |
| 725 | 738 |
| 726 class ClassDesc : public ValueObject { | 739 class ClassDesc : public ValueObject { |
| 727 public: | 740 public: |
| 728 ClassDesc(Zone* zone, | 741 ClassDesc(Zone* zone, |
| 729 const Class& cls, | 742 const Class& cls, |
| 730 const String& cls_name, | 743 const String& cls_name, |
| 731 bool is_interface, | 744 bool is_interface, |
| 732 intptr_t token_pos) | 745 TokenDescriptor token_pos) |
| 733 : zone_(zone), | 746 : zone_(zone), |
| 734 clazz_(cls), | 747 clazz_(cls), |
| 735 class_name_(cls_name), | 748 class_name_(cls_name), |
| 736 token_pos_(token_pos), | 749 token_pos_(token_pos), |
| 737 functions_(zone, 4), | 750 functions_(zone, 4), |
| 738 fields_(zone, 4) { | 751 fields_(zone, 4) { |
| 739 } | 752 } |
| 740 | 753 |
| 741 void AddFunction(const Function& function) { | 754 void AddFunction(const Function& function) { |
| 742 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); | 755 functions_.Add(&Function::ZoneHandle(zone_, function.raw())); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 765 bool has_constructor() const { | 778 bool has_constructor() const { |
| 766 for (int i = 0; i < functions_.length(); i++) { | 779 for (int i = 0; i < functions_.length(); i++) { |
| 767 const Function* func = functions_.At(i); | 780 const Function* func = functions_.At(i); |
| 768 if (func->kind() == RawFunction::kConstructor) { | 781 if (func->kind() == RawFunction::kConstructor) { |
| 769 return true; | 782 return true; |
| 770 } | 783 } |
| 771 } | 784 } |
| 772 return false; | 785 return false; |
| 773 } | 786 } |
| 774 | 787 |
| 775 intptr_t token_pos() const { | 788 TokenDescriptor token_pos() const { |
| 776 return token_pos_; | 789 return token_pos_; |
| 777 } | 790 } |
| 778 | 791 |
| 779 void AddMember(const MemberDesc& member) { | 792 void AddMember(const MemberDesc& member) { |
| 780 members_.Add(member); | 793 members_.Add(member); |
| 781 } | 794 } |
| 782 | 795 |
| 783 const GrowableArray<MemberDesc>& members() const { | 796 const GrowableArray<MemberDesc>& members() const { |
| 784 return members_; | 797 return members_; |
| 785 } | 798 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 799 for (intptr_t i = 0; i < len; i++) { | 812 for (intptr_t i = 0; i < len; i++) { |
| 800 res.SetAt(i, *functions_[i]); | 813 res.SetAt(i, *functions_[i]); |
| 801 } | 814 } |
| 802 return res.raw(); | 815 return res.raw(); |
| 803 } | 816 } |
| 804 | 817 |
| 805 private: | 818 private: |
| 806 Zone* zone_; | 819 Zone* zone_; |
| 807 const Class& clazz_; | 820 const Class& clazz_; |
| 808 const String& class_name_; | 821 const String& class_name_; |
| 809 intptr_t token_pos_; // Token index of "class" keyword. | 822 TokenDescriptor token_pos_; // Token index of "class" keyword. |
| 810 GrowableArray<const Function*> functions_; | 823 GrowableArray<const Function*> functions_; |
| 811 GrowableArray<const Field*> fields_; | 824 GrowableArray<const Field*> fields_; |
| 812 GrowableArray<MemberDesc> members_; | 825 GrowableArray<MemberDesc> members_; |
| 813 }; | 826 }; |
| 814 | 827 |
| 815 | 828 |
| 816 class TopLevel : public ValueObject { | 829 class TopLevel : public ValueObject { |
| 817 public: | 830 public: |
| 818 explicit TopLevel(Zone* zone) : | 831 explicit TopLevel(Zone* zone) : |
| 819 zone_(zone), | 832 zone_(zone), |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 | 1074 |
| 1062 | 1075 |
| 1063 RawObject* Parser::ParseMetadata(const Field& meta_data) { | 1076 RawObject* Parser::ParseMetadata(const Field& meta_data) { |
| 1064 LongJumpScope jump; | 1077 LongJumpScope jump; |
| 1065 if (setjmp(*jump.Set()) == 0) { | 1078 if (setjmp(*jump.Set()) == 0) { |
| 1066 Thread* thread = Thread::Current(); | 1079 Thread* thread = Thread::Current(); |
| 1067 StackZone stack_zone(thread); | 1080 StackZone stack_zone(thread); |
| 1068 Zone* zone = stack_zone.GetZone(); | 1081 Zone* zone = stack_zone.GetZone(); |
| 1069 const Class& owner_class = Class::Handle(zone, meta_data.owner()); | 1082 const Class& owner_class = Class::Handle(zone, meta_data.owner()); |
| 1070 const Script& script = Script::Handle(zone, meta_data.script()); | 1083 const Script& script = Script::Handle(zone, meta_data.script()); |
| 1071 const intptr_t token_pos = meta_data.token_pos(); | 1084 const TokenDescriptor token_pos = meta_data.token_pos(); |
| 1072 // Parsing metadata can involve following paths in the parser that are | 1085 // Parsing metadata can involve following paths in the parser that are |
| 1073 // normally used for expressions and assume current_function is non-null, | 1086 // normally used for expressions and assume current_function is non-null, |
| 1074 // so we create a fake function to use as the current_function rather than | 1087 // so we create a fake function to use as the current_function rather than |
| 1075 // scattering special cases throughout the parser. | 1088 // scattering special cases throughout the parser. |
| 1076 const Function& fake_function = Function::ZoneHandle(zone, Function::New( | 1089 const Function& fake_function = Function::ZoneHandle(zone, Function::New( |
| 1077 Symbols::At(), | 1090 Symbols::At(), |
| 1078 RawFunction::kRegularFunction, | 1091 RawFunction::kRegularFunction, |
| 1079 true, // is_static | 1092 true, // is_static |
| 1080 false, // is_const | 1093 false, // is_const |
| 1081 false, // is_abstract | 1094 false, // is_abstract |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1106 return Object::null(); | 1119 return Object::null(); |
| 1107 } | 1120 } |
| 1108 | 1121 |
| 1109 | 1122 |
| 1110 RawArray* Parser::EvaluateMetadata() { | 1123 RawArray* Parser::EvaluateMetadata() { |
| 1111 CheckToken(Token::kAT, "Metadata character '@' expected"); | 1124 CheckToken(Token::kAT, "Metadata character '@' expected"); |
| 1112 GrowableObjectArray& meta_values = | 1125 GrowableObjectArray& meta_values = |
| 1113 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 1126 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 1114 while (CurrentToken() == Token::kAT) { | 1127 while (CurrentToken() == Token::kAT) { |
| 1115 ConsumeToken(); | 1128 ConsumeToken(); |
| 1116 intptr_t expr_pos = TokenPos(); | 1129 TokenDescriptor expr_pos = TokenPos(); |
| 1117 if (!IsIdentifier()) { | 1130 if (!IsIdentifier()) { |
| 1118 ExpectIdentifier("identifier expected"); | 1131 ExpectIdentifier("identifier expected"); |
| 1119 } | 1132 } |
| 1120 // Reject expressions with deferred library prefix eagerly. | 1133 // Reject expressions with deferred library prefix eagerly. |
| 1121 Object& obj = | 1134 Object& obj = |
| 1122 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); | 1135 Object::Handle(Z, library_.LookupLocalObject(*CurrentLiteral())); |
| 1123 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 1136 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
| 1124 if (LibraryPrefix::Cast(obj).is_deferred_load()) { | 1137 if (LibraryPrefix::Cast(obj).is_deferred_load()) { |
| 1125 ReportError("Metadata must be compile-time constant"); | 1138 ReportError("Metadata must be compile-time constant"); |
| 1126 } | 1139 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1150 } | 1163 } |
| 1151 } | 1164 } |
| 1152 if (CurrentToken() == Token::kPERIOD) { | 1165 if (CurrentToken() == Token::kPERIOD) { |
| 1153 // C.x or L.C.X. | 1166 // C.x or L.C.X. |
| 1154 if (cls.IsNull()) { | 1167 if (cls.IsNull()) { |
| 1155 ReportError(expr_pos, | 1168 ReportError(expr_pos, |
| 1156 "Metadata expressions must refer to a const field " | 1169 "Metadata expressions must refer to a const field " |
| 1157 "or constructor"); | 1170 "or constructor"); |
| 1158 } | 1171 } |
| 1159 ConsumeToken(); | 1172 ConsumeToken(); |
| 1160 const intptr_t ident_pos = TokenPos(); | 1173 const TokenDescriptor ident_pos = TokenPos(); |
| 1161 String* ident = ExpectIdentifier("identifier expected"); | 1174 String* ident = ExpectIdentifier("identifier expected"); |
| 1162 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); | 1175 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); |
| 1163 if (field.IsNull()) { | 1176 if (field.IsNull()) { |
| 1164 ReportError(ident_pos, | 1177 ReportError(ident_pos, |
| 1165 "Class '%s' has no field '%s'", | 1178 "Class '%s' has no field '%s'", |
| 1166 cls.ToCString(), | 1179 cls.ToCString(), |
| 1167 ident->ToCString()); | 1180 ident->ToCString()); |
| 1168 } | 1181 } |
| 1169 if (!field.is_const()) { | 1182 if (!field.is_const()) { |
| 1170 ReportError(ident_pos, | 1183 ReportError(ident_pos, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1183 } | 1196 } |
| 1184 return Array::MakeArray(meta_values); | 1197 return Array::MakeArray(meta_values); |
| 1185 } | 1198 } |
| 1186 | 1199 |
| 1187 | 1200 |
| 1188 SequenceNode* Parser::ParseStaticInitializer() { | 1201 SequenceNode* Parser::ParseStaticInitializer() { |
| 1189 ExpectIdentifier("field name expected"); | 1202 ExpectIdentifier("field name expected"); |
| 1190 CheckToken(Token::kASSIGN, "field initialier expected"); | 1203 CheckToken(Token::kASSIGN, "field initialier expected"); |
| 1191 ConsumeToken(); | 1204 ConsumeToken(); |
| 1192 OpenFunctionBlock(parsed_function()->function()); | 1205 OpenFunctionBlock(parsed_function()->function()); |
| 1193 intptr_t expr_pos = TokenPos(); | 1206 TokenDescriptor expr_pos = TokenPos(); |
| 1194 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1207 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1195 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); | 1208 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); |
| 1196 current_block_->statements->Add(ret); | 1209 current_block_->statements->Add(ret); |
| 1197 return CloseBlock(); | 1210 return CloseBlock(); |
| 1198 } | 1211 } |
| 1199 | 1212 |
| 1200 | 1213 |
| 1201 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1214 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
| 1202 ASSERT(field.is_static()); | 1215 ASSERT(field.is_static()); |
| 1203 Thread* thread = Thread::Current(); | 1216 Thread* thread = Thread::Current(); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 TRACE_PARSER("ParseStaticFinalGetter"); | 1270 TRACE_PARSER("ParseStaticFinalGetter"); |
| 1258 ParamList params; | 1271 ParamList params; |
| 1259 ASSERT(func.num_fixed_parameters() == 0); // static. | 1272 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1260 ASSERT(!func.HasOptionalParameters()); | 1273 ASSERT(!func.HasOptionalParameters()); |
| 1261 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1274 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 1262 | 1275 |
| 1263 // Build local scope for function and populate with the formal parameters. | 1276 // Build local scope for function and populate with the formal parameters. |
| 1264 OpenFunctionBlock(func); | 1277 OpenFunctionBlock(func); |
| 1265 AddFormalParamsToScope(¶ms, current_block_->scope); | 1278 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1266 | 1279 |
| 1267 intptr_t ident_pos = TokenPos(); | 1280 TokenDescriptor ident_pos = TokenPos(); |
| 1268 const String& field_name = *ExpectIdentifier("field name expected"); | 1281 const String& field_name = *ExpectIdentifier("field name expected"); |
| 1269 const Class& field_class = Class::Handle(Z, func.Owner()); | 1282 const Class& field_class = Class::Handle(Z, func.Owner()); |
| 1270 const Field& field = | 1283 const Field& field = |
| 1271 Field::ZoneHandle(Z, field_class.LookupStaticField(field_name)); | 1284 Field::ZoneHandle(Z, field_class.LookupStaticField(field_name)); |
| 1272 ASSERT(!field.IsNull()); | 1285 ASSERT(!field.IsNull()); |
| 1273 | 1286 |
| 1274 // Static final fields must have an initializer. | 1287 // Static final fields must have an initializer. |
| 1275 ExpectToken(Token::kASSIGN); | 1288 ExpectToken(Token::kASSIGN); |
| 1276 | 1289 |
| 1277 const intptr_t expr_pos = TokenPos(); | 1290 const TokenDescriptor expr_pos = TokenPos(); |
| 1278 if (field.is_const()) { | 1291 if (field.is_const()) { |
| 1279 // We don't want to use ParseConstExpr() here because we don't want | 1292 // We don't want to use ParseConstExpr() here because we don't want |
| 1280 // the constant folding code to create, compile and execute a code | 1293 // the constant folding code to create, compile and execute a code |
| 1281 // fragment to evaluate the expression. Instead, we just make sure | 1294 // fragment to evaluate the expression. Instead, we just make sure |
| 1282 // the static const field initializer is a constant expression and | 1295 // the static const field initializer is a constant expression and |
| 1283 // leave the evaluation to the getter function. | 1296 // leave the evaluation to the getter function. |
| 1284 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1297 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1285 // This getter will only be called once at compile time. | 1298 // This getter will only be called once at compile time. |
| 1286 if (expr->EvalConstExpr() == NULL) { | 1299 if (expr->EvalConstExpr() == NULL) { |
| 1287 ReportError(expr_pos, "initializer is not a valid compile-time constant"); | 1300 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1305 | 1318 |
| 1306 | 1319 |
| 1307 // Create AstNodes for an implicit instance getter method: | 1320 // Create AstNodes for an implicit instance getter method: |
| 1308 // LoadLocalNode 0 ('this'); | 1321 // LoadLocalNode 0 ('this'); |
| 1309 // LoadInstanceFieldNode (field_name); | 1322 // LoadInstanceFieldNode (field_name); |
| 1310 // ReturnNode (field's value); | 1323 // ReturnNode (field's value); |
| 1311 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1324 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 1312 TRACE_PARSER("ParseInstanceGetter"); | 1325 TRACE_PARSER("ParseInstanceGetter"); |
| 1313 ParamList params; | 1326 ParamList params; |
| 1314 // func.token_pos() points to the name of the field. | 1327 // func.token_pos() points to the name of the field. |
| 1315 const intptr_t ident_pos = func.token_pos(); | 1328 const TokenDescriptor ident_pos = func.token_pos(); |
| 1316 ASSERT(current_class().raw() == func.Owner()); | 1329 ASSERT(current_class().raw() == func.Owner()); |
| 1317 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1330 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1318 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 1331 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
| 1319 ASSERT(!func.HasOptionalParameters()); | 1332 ASSERT(!func.HasOptionalParameters()); |
| 1320 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); | 1333 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 1321 | 1334 |
| 1322 // Build local scope for function and populate with the formal parameters. | 1335 // Build local scope for function and populate with the formal parameters. |
| 1323 OpenFunctionBlock(func); | 1336 OpenFunctionBlock(func); |
| 1324 AddFormalParamsToScope(¶ms, current_block_->scope); | 1337 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1325 | 1338 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1344 | 1357 |
| 1345 | 1358 |
| 1346 // Create AstNodes for an implicit instance setter method: | 1359 // Create AstNodes for an implicit instance setter method: |
| 1347 // LoadLocalNode 0 ('this') | 1360 // LoadLocalNode 0 ('this') |
| 1348 // LoadLocalNode 1 ('value') | 1361 // LoadLocalNode 1 ('value') |
| 1349 // SetInstanceField (field_name); | 1362 // SetInstanceField (field_name); |
| 1350 // ReturnNode (void); | 1363 // ReturnNode (void); |
| 1351 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 1364 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
| 1352 TRACE_PARSER("ParseInstanceSetter"); | 1365 TRACE_PARSER("ParseInstanceSetter"); |
| 1353 // func.token_pos() points to the name of the field. | 1366 // func.token_pos() points to the name of the field. |
| 1354 const intptr_t ident_pos = func.token_pos(); | 1367 const TokenDescriptor ident_pos = func.token_pos(); |
| 1355 const String& field_name = *CurrentLiteral(); | 1368 const String& field_name = *CurrentLiteral(); |
| 1356 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); | 1369 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); |
| 1357 const Field& field = | 1370 const Field& field = |
| 1358 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1371 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
| 1359 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | 1372 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
| 1360 | 1373 |
| 1361 ParamList params; | 1374 ParamList params; |
| 1362 ASSERT(current_class().raw() == func.Owner()); | 1375 ASSERT(current_class().raw() == func.Owner()); |
| 1363 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1376 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1364 params.AddFinalParameter(ident_pos, | 1377 params.AddFinalParameter(ident_pos, |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1381 StoreInstanceFieldNode* store_field = | 1394 StoreInstanceFieldNode* store_field = |
| 1382 new StoreInstanceFieldNode(ident_pos, receiver, field, value); | 1395 new StoreInstanceFieldNode(ident_pos, receiver, field, value); |
| 1383 current_block_->statements->Add(store_field); | 1396 current_block_->statements->Add(store_field); |
| 1384 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); | 1397 current_block_->statements->Add(new ReturnNode(ST(ident_pos))); |
| 1385 return CloseBlock(); | 1398 return CloseBlock(); |
| 1386 } | 1399 } |
| 1387 | 1400 |
| 1388 | 1401 |
| 1389 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { | 1402 SequenceNode* Parser::ParseConstructorClosure(const Function& func) { |
| 1390 TRACE_PARSER("ParseConstructorClosure"); | 1403 TRACE_PARSER("ParseConstructorClosure"); |
| 1391 const intptr_t token_pos = func.token_pos(); | 1404 const TokenDescriptor token_pos = func.token_pos(); |
| 1392 | 1405 |
| 1393 Function& constructor = Function::ZoneHandle(Z); | 1406 Function& constructor = Function::ZoneHandle(Z); |
| 1394 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); | 1407 TypeArguments& type_args = TypeArguments::ZoneHandle(Z); |
| 1395 ParseConstructorClosurization(&constructor, &type_args); | 1408 ParseConstructorClosurization(&constructor, &type_args); |
| 1396 ASSERT(!constructor.IsNull()); | 1409 ASSERT(!constructor.IsNull()); |
| 1397 | 1410 |
| 1398 ParamList params; | 1411 ParamList params; |
| 1399 // The first parameter of the closure function is the | 1412 // The first parameter of the closure function is the |
| 1400 // implicit closure argument. | 1413 // implicit closure argument. |
| 1401 params.AddFinalParameter(token_pos, | 1414 params.AddFinalParameter(token_pos, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1435 AstNode* new_object = | 1448 AstNode* new_object = |
| 1436 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); | 1449 CreateConstructorCallNode(token_pos, type_args, constructor, ctor_args); |
| 1437 ReturnNode* return_node = new ReturnNode(token_pos, new_object); | 1450 ReturnNode* return_node = new ReturnNode(token_pos, new_object); |
| 1438 current_block_->statements->Add(return_node); | 1451 current_block_->statements->Add(return_node); |
| 1439 return CloseBlock(); | 1452 return CloseBlock(); |
| 1440 } | 1453 } |
| 1441 | 1454 |
| 1442 | 1455 |
| 1443 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { | 1456 SequenceNode* Parser::ParseImplicitClosure(const Function& func) { |
| 1444 TRACE_PARSER("ParseImplicitClosure"); | 1457 TRACE_PARSER("ParseImplicitClosure"); |
| 1445 intptr_t token_pos = func.token_pos(); | 1458 TokenDescriptor token_pos = func.token_pos(); |
| 1446 | 1459 |
| 1447 OpenFunctionBlock(func); | 1460 OpenFunctionBlock(func); |
| 1448 | 1461 |
| 1449 ParamList params; | 1462 ParamList params; |
| 1450 params.AddFinalParameter( | 1463 params.AddFinalParameter( |
| 1451 token_pos, | 1464 token_pos, |
| 1452 &Symbols::ClosureParameter(), | 1465 &Symbols::ClosureParameter(), |
| 1453 &Object::dynamic_type()); | 1466 &Object::dynamic_type()); |
| 1454 | 1467 |
| 1455 const Function& parent = Function::ZoneHandle(func.parent_function()); | 1468 const Function& parent = Function::ZoneHandle(func.parent_function()); |
| 1456 if (parent.IsImplicitSetterFunction()) { | 1469 if (parent.IsImplicitSetterFunction()) { |
| 1457 const intptr_t ident_pos = func.token_pos(); | 1470 const TokenDescriptor ident_pos = func.token_pos(); |
| 1458 ASSERT(IsIdentifier()); | 1471 ASSERT(IsIdentifier()); |
| 1459 const String& field_name = *CurrentLiteral(); | 1472 const String& field_name = *CurrentLiteral(); |
| 1460 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); | 1473 const Class& field_class = Class::ZoneHandle(Z, parent.Owner()); |
| 1461 const Field& field = | 1474 const Field& field = |
| 1462 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); | 1475 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
| 1463 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); | 1476 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
| 1464 params.AddFinalParameter(ident_pos, | 1477 params.AddFinalParameter(ident_pos, |
| 1465 &Symbols::Value(), | 1478 &Symbols::Value(), |
| 1466 &field_type); | 1479 &field_type); |
| 1467 ASSERT(func.num_fixed_parameters() == 2); // closure, value. | 1480 ASSERT(func.num_fixed_parameters() == 2); // closure, value. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1501 current_block_->statements->Add(return_node); | 1514 current_block_->statements->Add(return_node); |
| 1502 return CloseBlock(); | 1515 return CloseBlock(); |
| 1503 } | 1516 } |
| 1504 | 1517 |
| 1505 | 1518 |
| 1506 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { | 1519 SequenceNode* Parser::ParseMethodExtractor(const Function& func) { |
| 1507 TRACE_PARSER("ParseMethodExtractor"); | 1520 TRACE_PARSER("ParseMethodExtractor"); |
| 1508 | 1521 |
| 1509 ParamList params; | 1522 ParamList params; |
| 1510 | 1523 |
| 1511 const intptr_t ident_pos = func.token_pos(); | 1524 const TokenDescriptor ident_pos = func.token_pos(); |
| 1512 ASSERT(func.token_pos() == ClassifyingTokenPositions::kMethodExtractor); | 1525 ASSERT(func.token_pos() == TokenDescriptor::kMethodExtractor); |
| 1513 ASSERT(current_class().raw() == func.Owner()); | 1526 ASSERT(current_class().raw() == func.Owner()); |
| 1514 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1527 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1515 ASSERT(func.num_fixed_parameters() == 1); // Receiver. | 1528 ASSERT(func.num_fixed_parameters() == 1); // Receiver. |
| 1516 ASSERT(!func.HasOptionalParameters()); | 1529 ASSERT(!func.HasOptionalParameters()); |
| 1517 | 1530 |
| 1518 // Build local scope for function and populate with the formal parameters. | 1531 // Build local scope for function and populate with the formal parameters. |
| 1519 OpenFunctionBlock(func); | 1532 OpenFunctionBlock(func); |
| 1520 AddFormalParamsToScope(¶ms, current_block_->scope); | 1533 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1521 | 1534 |
| 1522 // Receiver is local 0. | 1535 // Receiver is local 0. |
| 1523 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1536 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1524 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1537 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1525 | 1538 |
| 1526 ClosureNode* closure = new ClosureNode( | 1539 ClosureNode* closure = new ClosureNode( |
| 1527 ident_pos, | 1540 ident_pos, |
| 1528 Function::ZoneHandle(Z, func.extracted_method_closure()), | 1541 Function::ZoneHandle(Z, func.extracted_method_closure()), |
| 1529 load_receiver, | 1542 load_receiver, |
| 1530 NULL); | 1543 NULL); |
| 1531 | 1544 |
| 1532 ReturnNode* return_node = new ReturnNode(ident_pos, closure); | 1545 ReturnNode* return_node = new ReturnNode(ident_pos, closure); |
| 1533 current_block_->statements->Add(return_node); | 1546 current_block_->statements->Add(return_node); |
| 1534 return CloseBlock(); | 1547 return CloseBlock(); |
| 1535 } | 1548 } |
| 1536 | 1549 |
| 1537 | 1550 |
| 1538 void Parser::BuildDispatcherScope(const Function& func, | 1551 void Parser::BuildDispatcherScope(const Function& func, |
| 1539 const ArgumentsDescriptor& desc) { | 1552 const ArgumentsDescriptor& desc) { |
| 1540 ParamList params; | 1553 ParamList params; |
| 1541 // Receiver first. | 1554 // Receiver first. |
| 1542 intptr_t token_pos = func.token_pos(); | 1555 TokenDescriptor token_pos = func.token_pos(); |
| 1543 params.AddReceiver(ReceiverType(current_class()), token_pos); | 1556 params.AddReceiver(ReceiverType(current_class()), token_pos); |
| 1544 // Remaining positional parameters. | 1557 // Remaining positional parameters. |
| 1545 intptr_t i = 1; | 1558 intptr_t i = 1; |
| 1546 for (; i < desc.PositionalCount(); ++i) { | 1559 for (; i < desc.PositionalCount(); ++i) { |
| 1547 ParamDesc p; | 1560 ParamDesc p; |
| 1548 char name[64]; | 1561 char name[64]; |
| 1549 OS::SNPrint(name, 64, ":p%" Pd, i); | 1562 OS::SNPrint(name, 64, ":p%" Pd, i); |
| 1550 p.name = &String::ZoneHandle(Z, Symbols::New(name)); | 1563 p.name = &String::ZoneHandle(Z, Symbols::New(name)); |
| 1551 p.type = &Object::dynamic_type(); | 1564 p.type = &Object::dynamic_type(); |
| 1552 params.parameters->Add(p); | 1565 params.parameters->Add(p); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1572 // Build local scope for function and populate with the formal parameters. | 1585 // Build local scope for function and populate with the formal parameters. |
| 1573 OpenFunctionBlock(func); | 1586 OpenFunctionBlock(func); |
| 1574 AddFormalParamsToScope(¶ms, current_block_->scope); | 1587 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1575 } | 1588 } |
| 1576 | 1589 |
| 1577 | 1590 |
| 1578 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { | 1591 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func) { |
| 1579 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1592 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
| 1580 ASSERT(FLAG_lazy_dispatchers); | 1593 ASSERT(FLAG_lazy_dispatchers); |
| 1581 ASSERT(func.IsNoSuchMethodDispatcher()); | 1594 ASSERT(func.IsNoSuchMethodDispatcher()); |
| 1582 intptr_t token_pos = func.token_pos(); | 1595 TokenDescriptor token_pos = func.token_pos(); |
| 1583 ASSERT(func.token_pos() == 0); | 1596 ASSERT(func.token_pos() == TokenDescriptor::kMinSource); |
| 1584 ASSERT(current_class().raw() == func.Owner()); | 1597 ASSERT(current_class().raw() == func.Owner()); |
| 1585 | 1598 |
| 1586 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); | 1599 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); |
| 1587 ASSERT(desc.Count() > 0); | 1600 ASSERT(desc.Count() > 0); |
| 1588 | 1601 |
| 1589 // Set up scope for this function. | 1602 // Set up scope for this function. |
| 1590 BuildDispatcherScope(func, desc); | 1603 BuildDispatcherScope(func, desc); |
| 1591 | 1604 |
| 1592 // Receiver is local 0. | 1605 // Receiver is local 0. |
| 1593 LocalScope* scope = current_block_->scope; | 1606 LocalScope* scope = current_block_->scope; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1627 | 1640 |
| 1628 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1641 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1629 current_block_->statements->Add(return_node); | 1642 current_block_->statements->Add(return_node); |
| 1630 return CloseBlock(); | 1643 return CloseBlock(); |
| 1631 } | 1644 } |
| 1632 | 1645 |
| 1633 | 1646 |
| 1634 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { | 1647 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) { |
| 1635 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1648 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
| 1636 ASSERT(func.IsInvokeFieldDispatcher()); | 1649 ASSERT(func.IsInvokeFieldDispatcher()); |
| 1637 intptr_t token_pos = func.token_pos(); | 1650 TokenDescriptor token_pos = func.token_pos(); |
| 1638 ASSERT(func.token_pos() == 0); | 1651 ASSERT(func.token_pos() == TokenDescriptor::kMinSource); |
| 1639 ASSERT(current_class().raw() == func.Owner()); | 1652 ASSERT(current_class().raw() == func.Owner()); |
| 1640 | 1653 |
| 1641 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); | 1654 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
| 1642 ArgumentsDescriptor desc(args_desc); | 1655 ArgumentsDescriptor desc(args_desc); |
| 1643 ASSERT(desc.Count() > 0); | 1656 ASSERT(desc.Count() > 0); |
| 1644 | 1657 |
| 1645 // Set up scope for this function. | 1658 // Set up scope for this function. |
| 1646 BuildDispatcherScope(func, desc); | 1659 BuildDispatcherScope(func, desc); |
| 1647 | 1660 |
| 1648 // Receiver is local 0. | 1661 // Receiver is local 0. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1689 } else { | 1702 } else { |
| 1690 result = BuildClosureCall(token_pos, function_object, args); | 1703 result = BuildClosureCall(token_pos, function_object, args); |
| 1691 } | 1704 } |
| 1692 | 1705 |
| 1693 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1706 ReturnNode* return_node = new ReturnNode(token_pos, result); |
| 1694 current_block_->statements->Add(return_node); | 1707 current_block_->statements->Add(return_node); |
| 1695 return CloseBlock(); | 1708 return CloseBlock(); |
| 1696 } | 1709 } |
| 1697 | 1710 |
| 1698 | 1711 |
| 1699 AstNode* Parser::BuildClosureCall(intptr_t token_pos, | 1712 AstNode* Parser::BuildClosureCall(TokenDescriptor token_pos, |
| 1700 AstNode* closure, | 1713 AstNode* closure, |
| 1701 ArgumentListNode* arguments) { | 1714 ArgumentListNode* arguments) { |
| 1702 return new InstanceCallNode(token_pos, | 1715 return new InstanceCallNode(token_pos, |
| 1703 closure, | 1716 closure, |
| 1704 Symbols::Call(), | 1717 Symbols::Call(), |
| 1705 arguments); | 1718 arguments); |
| 1706 } | 1719 } |
| 1707 | 1720 |
| 1708 | 1721 |
| 1709 void Parser::SkipToMatching() { | 1722 void Parser::SkipToMatching() { |
| 1710 Token::Kind opening_token = CurrentToken(); | 1723 Token::Kind opening_token = CurrentToken(); |
| 1711 ASSERT((opening_token == Token::kLBRACE) || | 1724 ASSERT((opening_token == Token::kLBRACE) || |
| 1712 (opening_token == Token::kLPAREN)); | 1725 (opening_token == Token::kLPAREN)); |
| 1713 GrowableArray<Token::Kind> token_stack(8); | 1726 GrowableArray<Token::Kind> token_stack(8); |
| 1714 GrowableArray<intptr_t> token_pos_stack(8); | 1727 GrowableArray<TokenDescriptor> token_pos_stack(8); |
| 1715 // Adding the first opening brace here, because it will be consumed | 1728 // Adding the first opening brace here, because it will be consumed |
| 1716 // in the loop right away. | 1729 // in the loop right away. |
| 1717 token_stack.Add(opening_token); | 1730 token_stack.Add(opening_token); |
| 1718 const intptr_t start_pos = TokenPos(); | 1731 const TokenDescriptor start_pos = TokenPos(); |
| 1719 intptr_t opening_pos = start_pos; | 1732 TokenDescriptor opening_pos = start_pos; |
| 1720 token_pos_stack.Add(start_pos); | 1733 token_pos_stack.Add(start_pos); |
| 1721 bool is_match = true; | 1734 bool is_match = true; |
| 1722 bool unexpected_token_found = false; | 1735 bool unexpected_token_found = false; |
| 1723 Token::Kind token = opening_token; | 1736 Token::Kind token = opening_token; |
| 1724 intptr_t token_pos; | 1737 TokenDescriptor token_pos; |
| 1725 do { | 1738 do { |
| 1726 ConsumeToken(); | 1739 ConsumeToken(); |
| 1727 token = CurrentToken(); | 1740 token = CurrentToken(); |
| 1728 token_pos = TokenPos(); | 1741 token_pos = TokenPos(); |
| 1729 switch (token) { | 1742 switch (token) { |
| 1730 case Token::kLBRACE: | 1743 case Token::kLBRACE: |
| 1731 case Token::kLPAREN: | 1744 case Token::kLPAREN: |
| 1732 case Token::kLBRACK: | 1745 case Token::kLBRACK: |
| 1733 token_stack.Add(token); | 1746 token_stack.Add(token); |
| 1734 token_pos_stack.Add(token_pos); | 1747 token_pos_stack.Add(token_pos); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1905 const bool no_explicit_default_values = false; | 1918 const bool no_explicit_default_values = false; |
| 1906 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 1919 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
| 1907 | 1920 |
| 1908 // In top-level and mixin functions, the source may be in a different | 1921 // In top-level and mixin functions, the source may be in a different |
| 1909 // script than the script of the current class. However, we never reparse | 1922 // script than the script of the current class. However, we never reparse |
| 1910 // signature functions (except typedef signature functions), therefore | 1923 // signature functions (except typedef signature functions), therefore |
| 1911 // we do not need to keep the correct script via a patch class. Use the | 1924 // we do not need to keep the correct script via a patch class. Use the |
| 1912 // actual current class as owner of the signature function. | 1925 // actual current class as owner of the signature function. |
| 1913 const Function& signature_function = Function::Handle(Z, | 1926 const Function& signature_function = Function::Handle(Z, |
| 1914 Function::NewSignatureFunction(current_class(), | 1927 Function::NewSignatureFunction(current_class(), |
| 1915 Token::kNoSourcePos)); | 1928 TokenDescriptor::kNoSource)); |
| 1916 signature_function.set_result_type(result_type); | 1929 signature_function.set_result_type(result_type); |
| 1917 AddFormalParamsToFunction(&func_params, signature_function); | 1930 AddFormalParamsToFunction(&func_params, signature_function); |
| 1918 FunctionType& signature_type = | 1931 FunctionType& signature_type = |
| 1919 FunctionType::ZoneHandle(Z, signature_function.SignatureType()); | 1932 FunctionType::ZoneHandle(Z, signature_function.SignatureType()); |
| 1920 if (!is_top_level_) { | 1933 if (!is_top_level_) { |
| 1921 signature_type ^= ClassFinalizer::FinalizeType( | 1934 signature_type ^= ClassFinalizer::FinalizeType( |
| 1922 current_class(), signature_type, ClassFinalizer::kCanonicalize); | 1935 current_class(), signature_type, ClassFinalizer::kCanonicalize); |
| 1923 signature_function.SetSignatureType(signature_type); | 1936 signature_function.SetSignatureType(signature_type); |
| 1924 } | 1937 } |
| 1925 ASSERT(is_top_level_ || signature_type.IsFinalized()); | 1938 ASSERT(is_top_level_ || signature_type.IsFinalized()); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2046 String& native_name = *CurrentLiteral(); | 2059 String& native_name = *CurrentLiteral(); |
| 2047 ConsumeToken(); | 2060 ConsumeToken(); |
| 2048 return native_name; | 2061 return native_name; |
| 2049 } | 2062 } |
| 2050 | 2063 |
| 2051 | 2064 |
| 2052 // Resolve and return the dynamic function of the given name in the superclass. | 2065 // Resolve and return the dynamic function of the given name in the superclass. |
| 2053 // If it is not found, and resolve_getter is true, try to resolve a getter of | 2066 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 2054 // the same name. If it is still not found, return noSuchMethod and | 2067 // the same name. If it is still not found, return noSuchMethod and |
| 2055 // set is_no_such_method to true.. | 2068 // set is_no_such_method to true.. |
| 2056 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 2069 RawFunction* Parser::GetSuperFunction(TokenDescriptor token_pos, |
| 2057 const String& name, | 2070 const String& name, |
| 2058 ArgumentListNode* arguments, | 2071 ArgumentListNode* arguments, |
| 2059 bool resolve_getter, | 2072 bool resolve_getter, |
| 2060 bool* is_no_such_method) { | 2073 bool* is_no_such_method) { |
| 2061 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); | 2074 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
| 2062 if (super_class.IsNull()) { | 2075 if (super_class.IsNull()) { |
| 2063 ReportError(token_pos, "class '%s' does not have a superclass", | 2076 ReportError(token_pos, "class '%s' does not have a superclass", |
| 2064 String::Handle(Z, current_class().Name()).ToCString()); | 2077 String::Handle(Z, current_class().Name()).ToCString()); |
| 2065 } | 2078 } |
| 2066 Function& super_func = Function::Handle(Z, | 2079 Function& super_func = Function::Handle(Z, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2082 ASSERT(!super_func.IsNull()); | 2095 ASSERT(!super_func.IsNull()); |
| 2083 *is_no_such_method = true; | 2096 *is_no_such_method = true; |
| 2084 } else { | 2097 } else { |
| 2085 *is_no_such_method = false; | 2098 *is_no_such_method = false; |
| 2086 } | 2099 } |
| 2087 return super_func.raw(); | 2100 return super_func.raw(); |
| 2088 } | 2101 } |
| 2089 | 2102 |
| 2090 | 2103 |
| 2091 StaticCallNode* Parser::BuildInvocationMirrorAllocation( | 2104 StaticCallNode* Parser::BuildInvocationMirrorAllocation( |
| 2092 intptr_t call_pos, | 2105 TokenDescriptor call_pos, |
| 2093 const String& function_name, | 2106 const String& function_name, |
| 2094 const ArgumentListNode& function_args, | 2107 const ArgumentListNode& function_args, |
| 2095 const LocalVariable* temp_for_last_arg, | 2108 const LocalVariable* temp_for_last_arg, |
| 2096 bool is_super_invocation) { | 2109 bool is_super_invocation) { |
| 2097 const intptr_t args_pos = function_args.token_pos(); | 2110 const TokenDescriptor args_pos = function_args.token_pos(); |
| 2098 // Build arguments to the call to the static | 2111 // Build arguments to the call to the static |
| 2099 // InvocationMirror._allocateInvocationMirror method. | 2112 // InvocationMirror._allocateInvocationMirror method. |
| 2100 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2113 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 2101 // The first argument is the original function name. | 2114 // The first argument is the original function name. |
| 2102 arguments->Add(new LiteralNode(args_pos, function_name)); | 2115 arguments->Add(new LiteralNode(args_pos, function_name)); |
| 2103 // The second argument is the arguments descriptor of the original function. | 2116 // The second argument is the arguments descriptor of the original function. |
| 2104 const Array& args_descriptor = | 2117 const Array& args_descriptor = |
| 2105 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), | 2118 Array::ZoneHandle(ArgumentsDescriptor::New(function_args.length(), |
| 2106 function_args.names())); | 2119 function_args.names())); |
| 2107 arguments->Add(new LiteralNode(args_pos, args_descriptor)); | 2120 arguments->Add(new LiteralNode(args_pos, args_descriptor)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2131 ASSERT(!mirror_class.IsNull()); | 2144 ASSERT(!mirror_class.IsNull()); |
| 2132 const Function& allocation_function = Function::ZoneHandle( | 2145 const Function& allocation_function = Function::ZoneHandle( |
| 2133 mirror_class.LookupStaticFunction( | 2146 mirror_class.LookupStaticFunction( |
| 2134 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); | 2147 Library::PrivateCoreLibName(Symbols::AllocateInvocationMirror()))); |
| 2135 ASSERT(!allocation_function.IsNull()); | 2148 ASSERT(!allocation_function.IsNull()); |
| 2136 return new StaticCallNode(call_pos, allocation_function, arguments); | 2149 return new StaticCallNode(call_pos, allocation_function, arguments); |
| 2137 } | 2150 } |
| 2138 | 2151 |
| 2139 | 2152 |
| 2140 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 2153 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
| 2141 intptr_t call_pos, | 2154 TokenDescriptor call_pos, |
| 2142 const String& function_name, | 2155 const String& function_name, |
| 2143 const ArgumentListNode& function_args, | 2156 const ArgumentListNode& function_args, |
| 2144 const LocalVariable* temp_for_last_arg, | 2157 const LocalVariable* temp_for_last_arg, |
| 2145 bool is_super_invocation) { | 2158 bool is_super_invocation) { |
| 2146 ASSERT(function_args.length() >= 1); // The receiver is the first argument. | 2159 ASSERT(function_args.length() >= 1); // The receiver is the first argument. |
| 2147 const intptr_t args_pos = function_args.token_pos(); | 2160 const TokenDescriptor args_pos = function_args.token_pos(); |
| 2148 ArgumentListNode* arguments = new ArgumentListNode(args_pos); | 2161 ArgumentListNode* arguments = new ArgumentListNode(args_pos); |
| 2149 arguments->Add(function_args.NodeAt(0)); | 2162 arguments->Add(function_args.NodeAt(0)); |
| 2150 // The second argument is the invocation mirror. | 2163 // The second argument is the invocation mirror. |
| 2151 arguments->Add(BuildInvocationMirrorAllocation(call_pos, | 2164 arguments->Add(BuildInvocationMirrorAllocation(call_pos, |
| 2152 function_name, | 2165 function_name, |
| 2153 function_args, | 2166 function_args, |
| 2154 temp_for_last_arg, | 2167 temp_for_last_arg, |
| 2155 is_super_invocation)); | 2168 is_super_invocation)); |
| 2156 return arguments; | 2169 return arguments; |
| 2157 } | 2170 } |
| 2158 | 2171 |
| 2159 | 2172 |
| 2160 AstNode* Parser::ParseSuperCall(const String& function_name) { | 2173 AstNode* Parser::ParseSuperCall(const String& function_name) { |
| 2161 TRACE_PARSER("ParseSuperCall"); | 2174 TRACE_PARSER("ParseSuperCall"); |
| 2162 ASSERT(CurrentToken() == Token::kLPAREN); | 2175 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2163 const intptr_t supercall_pos = TokenPos(); | 2176 const TokenDescriptor supercall_pos = TokenPos(); |
| 2164 | 2177 |
| 2165 // 'this' parameter is the first argument to super call. | 2178 // 'this' parameter is the first argument to super call. |
| 2166 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2179 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 2167 AstNode* receiver = LoadReceiver(supercall_pos); | 2180 AstNode* receiver = LoadReceiver(supercall_pos); |
| 2168 arguments->Add(receiver); | 2181 arguments->Add(receiver); |
| 2169 ParseActualParameters(arguments, kAllowConst); | 2182 ParseActualParameters(arguments, kAllowConst); |
| 2170 | 2183 |
| 2171 const bool kResolveGetter = true; | 2184 const bool kResolveGetter = true; |
| 2172 bool is_no_such_method = false; | 2185 bool is_no_such_method = false; |
| 2173 const Function& super_function = Function::ZoneHandle(Z, | 2186 const Function& super_function = Function::ZoneHandle(Z, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2201 | 2214 |
| 2202 // Simple test if a node is side effect free. | 2215 // Simple test if a node is side effect free. |
| 2203 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { | 2216 static bool IsSimpleLocalOrLiteralNode(AstNode* node) { |
| 2204 return node->IsLiteralNode() || node->IsLoadLocalNode(); | 2217 return node->IsLiteralNode() || node->IsLoadLocalNode(); |
| 2205 } | 2218 } |
| 2206 | 2219 |
| 2207 | 2220 |
| 2208 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 2221 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
| 2209 ASSERT(super->IsSuper()); | 2222 ASSERT(super->IsSuper()); |
| 2210 AstNode* super_op = NULL; | 2223 AstNode* super_op = NULL; |
| 2211 const intptr_t super_pos = super->token_pos(); | 2224 const TokenDescriptor super_pos = super->token_pos(); |
| 2212 if ((op == Token::kNEGATE) || | 2225 if ((op == Token::kNEGATE) || |
| 2213 (op == Token::kBIT_NOT)) { | 2226 (op == Token::kBIT_NOT)) { |
| 2214 // Resolve the operator function in the superclass. | 2227 // Resolve the operator function in the superclass. |
| 2215 const String& operator_function_name = | 2228 const String& operator_function_name = |
| 2216 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); | 2229 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); |
| 2217 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 2230 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
| 2218 AstNode* receiver = LoadReceiver(super_pos); | 2231 AstNode* receiver = LoadReceiver(super_pos); |
| 2219 op_arguments->Add(receiver); | 2232 op_arguments->Add(receiver); |
| 2220 const bool kResolveGetter = false; | 2233 const bool kResolveGetter = false; |
| 2221 bool is_no_such_method = false; | 2234 bool is_no_such_method = false; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2233 } else { | 2246 } else { |
| 2234 ReportError(super_pos, "illegal super operator call"); | 2247 ReportError(super_pos, "illegal super operator call"); |
| 2235 } | 2248 } |
| 2236 return super_op; | 2249 return super_op; |
| 2237 } | 2250 } |
| 2238 | 2251 |
| 2239 | 2252 |
| 2240 AstNode* Parser::ParseSuperOperator() { | 2253 AstNode* Parser::ParseSuperOperator() { |
| 2241 TRACE_PARSER("ParseSuperOperator"); | 2254 TRACE_PARSER("ParseSuperOperator"); |
| 2242 AstNode* super_op = NULL; | 2255 AstNode* super_op = NULL; |
| 2243 const intptr_t operator_pos = TokenPos(); | 2256 const TokenDescriptor operator_pos = TokenPos(); |
| 2244 | 2257 |
| 2245 if (CurrentToken() == Token::kLBRACK) { | 2258 if (CurrentToken() == Token::kLBRACK) { |
| 2246 ConsumeToken(); | 2259 ConsumeToken(); |
| 2247 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2260 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2248 ExpectToken(Token::kRBRACK); | 2261 ExpectToken(Token::kRBRACK); |
| 2249 AstNode* receiver = LoadReceiver(operator_pos); | 2262 AstNode* receiver = LoadReceiver(operator_pos); |
| 2250 const Class& super_class = | 2263 const Class& super_class = |
| 2251 Class::ZoneHandle(Z, current_class().SuperClass()); | 2264 Class::ZoneHandle(Z, current_class().SuperClass()); |
| 2252 ASSERT(!super_class.IsNull()); | 2265 ASSERT(!super_class.IsNull()); |
| 2253 super_op = | 2266 super_op = |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2290 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2303 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
| 2291 if (negate_result) { | 2304 if (negate_result) { |
| 2292 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2305 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
| 2293 } | 2306 } |
| 2294 } | 2307 } |
| 2295 return super_op; | 2308 return super_op; |
| 2296 } | 2309 } |
| 2297 | 2310 |
| 2298 | 2311 |
| 2299 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, | 2312 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
| 2300 intptr_t token_pos, | 2313 TokenDescriptor token_pos, |
| 2301 AstNode* receiver) { | 2314 AstNode* receiver) { |
| 2302 Function& implicit_closure_function = | 2315 Function& implicit_closure_function = |
| 2303 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); | 2316 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); |
| 2304 if (receiver != NULL) { | 2317 if (receiver != NULL) { |
| 2305 // If we create an implicit instance closure from inside a closure of a | 2318 // If we create an implicit instance closure from inside a closure of a |
| 2306 // parameterized class, make sure that the receiver is captured as | 2319 // parameterized class, make sure that the receiver is captured as |
| 2307 // instantiator. | 2320 // instantiator. |
| 2308 if (current_block_->scope->function_level() > 0) { | 2321 if (current_block_->scope->function_level() > 0) { |
| 2309 const FunctionType& signature_type = FunctionType::Handle(Z, | 2322 const FunctionType& signature_type = FunctionType::Handle(Z, |
| 2310 implicit_closure_function.SignatureType()); | 2323 implicit_closure_function.SignatureType()); |
| 2311 const Class& scope_class = Class::Handle(Z, signature_type.type_class()); | 2324 const Class& scope_class = Class::Handle(Z, signature_type.type_class()); |
| 2312 if (scope_class.IsGeneric()) { | 2325 if (scope_class.IsGeneric()) { |
| 2313 CaptureInstantiator(); | 2326 CaptureInstantiator(); |
| 2314 } | 2327 } |
| 2315 } | 2328 } |
| 2316 } | 2329 } |
| 2317 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2330 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 2318 } | 2331 } |
| 2319 | 2332 |
| 2320 | 2333 |
| 2321 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2334 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
| 2322 intptr_t field_pos) { | 2335 TokenDescriptor field_pos) { |
| 2323 TRACE_PARSER("ParseSuperFieldAccess"); | 2336 TRACE_PARSER("ParseSuperFieldAccess"); |
| 2324 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); | 2337 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); |
| 2325 if (super_class.IsNull()) { | 2338 if (super_class.IsNull()) { |
| 2326 ReportError("class '%s' does not have a superclass", | 2339 ReportError("class '%s' does not have a superclass", |
| 2327 String::Handle(Z, current_class().Name()).ToCString()); | 2340 String::Handle(Z, current_class().Name()).ToCString()); |
| 2328 } | 2341 } |
| 2329 AstNode* implicit_argument = LoadReceiver(field_pos); | 2342 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 2330 | 2343 |
| 2331 const String& getter_name = | 2344 const String& getter_name = |
| 2332 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); | 2345 String::ZoneHandle(Z, Field::LookupGetterSymbol(field_name)); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2359 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2372 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
| 2360 } | 2373 } |
| 2361 } | 2374 } |
| 2362 return new(Z) StaticGetterNode( | 2375 return new(Z) StaticGetterNode( |
| 2363 field_pos, implicit_argument, super_class, field_name); | 2376 field_pos, implicit_argument, super_class, field_name); |
| 2364 } | 2377 } |
| 2365 | 2378 |
| 2366 | 2379 |
| 2367 StaticCallNode* Parser::GenerateSuperConstructorCall( | 2380 StaticCallNode* Parser::GenerateSuperConstructorCall( |
| 2368 const Class& cls, | 2381 const Class& cls, |
| 2369 intptr_t supercall_pos, | 2382 TokenDescriptor supercall_pos, |
| 2370 LocalVariable* receiver, | 2383 LocalVariable* receiver, |
| 2371 ArgumentListNode* forwarding_args) { | 2384 ArgumentListNode* forwarding_args) { |
| 2372 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2385 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
| 2373 // Omit the implicit super() if there is no super class (i.e. | 2386 // Omit the implicit super() if there is no super class (i.e. |
| 2374 // we're not compiling class Object), or if the super class is an | 2387 // we're not compiling class Object), or if the super class is an |
| 2375 // artificially generated "wrapper class" that has no constructor. | 2388 // artificially generated "wrapper class" that has no constructor. |
| 2376 if (super_class.IsNull() || | 2389 if (super_class.IsNull() || |
| 2377 (super_class.num_native_fields() > 0 && | 2390 (super_class.num_native_fields() > 0 && |
| 2378 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { | 2391 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { |
| 2379 return NULL; | 2392 return NULL; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2426 error_message.ToCString()); | 2439 error_message.ToCString()); |
| 2427 } | 2440 } |
| 2428 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2441 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 2429 } | 2442 } |
| 2430 | 2443 |
| 2431 | 2444 |
| 2432 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, | 2445 StaticCallNode* Parser::ParseSuperInitializer(const Class& cls, |
| 2433 LocalVariable* receiver) { | 2446 LocalVariable* receiver) { |
| 2434 TRACE_PARSER("ParseSuperInitializer"); | 2447 TRACE_PARSER("ParseSuperInitializer"); |
| 2435 ASSERT(CurrentToken() == Token::kSUPER); | 2448 ASSERT(CurrentToken() == Token::kSUPER); |
| 2436 const intptr_t supercall_pos = TokenPos(); | 2449 const TokenDescriptor supercall_pos = TokenPos(); |
| 2437 ConsumeToken(); | 2450 ConsumeToken(); |
| 2438 const Class& super_class = Class::Handle(Z, cls.SuperClass()); | 2451 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
| 2439 ASSERT(!super_class.IsNull()); | 2452 ASSERT(!super_class.IsNull()); |
| 2440 String& ctor_name = String::Handle(Z, super_class.Name()); | 2453 String& ctor_name = String::Handle(Z, super_class.Name()); |
| 2441 ctor_name = Symbols::FromConcat(ctor_name, Symbols::Dot()); | 2454 ctor_name = Symbols::FromConcat(ctor_name, Symbols::Dot()); |
| 2442 if (CurrentToken() == Token::kPERIOD) { | 2455 if (CurrentToken() == Token::kPERIOD) { |
| 2443 ConsumeToken(); | 2456 ConsumeToken(); |
| 2444 ctor_name = Symbols::FromConcat( | 2457 ctor_name = Symbols::FromConcat( |
| 2445 ctor_name, *ExpectIdentifier("constructor name expected")); | 2458 ctor_name, *ExpectIdentifier("constructor name expected")); |
| 2446 } | 2459 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2477 error_message.ToCString()); | 2490 error_message.ToCString()); |
| 2478 } | 2491 } |
| 2479 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2492 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 2480 } | 2493 } |
| 2481 | 2494 |
| 2482 | 2495 |
| 2483 AstNode* Parser::ParseInitializer(const Class& cls, | 2496 AstNode* Parser::ParseInitializer(const Class& cls, |
| 2484 LocalVariable* receiver, | 2497 LocalVariable* receiver, |
| 2485 GrowableArray<Field*>* initialized_fields) { | 2498 GrowableArray<Field*>* initialized_fields) { |
| 2486 TRACE_PARSER("ParseInitializer"); | 2499 TRACE_PARSER("ParseInitializer"); |
| 2487 const intptr_t field_pos = TokenPos(); | 2500 const TokenDescriptor field_pos = TokenPos(); |
| 2488 if (CurrentToken() == Token::kTHIS) { | 2501 if (CurrentToken() == Token::kTHIS) { |
| 2489 ConsumeToken(); | 2502 ConsumeToken(); |
| 2490 ExpectToken(Token::kPERIOD); | 2503 ExpectToken(Token::kPERIOD); |
| 2491 } | 2504 } |
| 2492 const String& field_name = *ExpectIdentifier("field name expected"); | 2505 const String& field_name = *ExpectIdentifier("field name expected"); |
| 2493 ExpectToken(Token::kASSIGN); | 2506 ExpectToken(Token::kASSIGN); |
| 2494 | 2507 |
| 2495 const bool saved_mode = SetAllowFunctionLiterals(false); | 2508 const bool saved_mode = SetAllowFunctionLiterals(false); |
| 2496 // "this" must not be accessible in initializer expressions. | 2509 // "this" must not be accessible in initializer expressions. |
| 2497 receiver->set_invisible(true); | 2510 receiver->set_invisible(true); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2553 | 2566 |
| 2554 | 2567 |
| 2555 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2568 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
| 2556 // Only use this function if the initialized field originates | 2569 // Only use this function if the initialized field originates |
| 2557 // from a different class. We need to save and restore current | 2570 // from a different class. We need to save and restore current |
| 2558 // class, library, and token stream (script). | 2571 // class, library, and token stream (script). |
| 2559 ASSERT(current_class().raw() != field.origin()); | 2572 ASSERT(current_class().raw() != field.origin()); |
| 2560 const Class& saved_class = Class::Handle(Z, current_class().raw()); | 2573 const Class& saved_class = Class::Handle(Z, current_class().raw()); |
| 2561 const Library& saved_library = Library::Handle(Z, library().raw()); | 2574 const Library& saved_library = Library::Handle(Z, library().raw()); |
| 2562 const Script& saved_script = Script::Handle(Z, script().raw()); | 2575 const Script& saved_script = Script::Handle(Z, script().raw()); |
| 2563 const intptr_t saved_token_pos = TokenPos(); | 2576 const TokenDescriptor saved_token_pos = TokenPos(); |
| 2564 | 2577 |
| 2565 set_current_class(Class::Handle(Z, field.origin())); | 2578 set_current_class(Class::Handle(Z, field.origin())); |
| 2566 set_library(Library::Handle(Z, current_class().library())); | 2579 set_library(Library::Handle(Z, current_class().library())); |
| 2567 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); | 2580 SetScript(Script::Handle(Z, current_class().script()), field.token_pos()); |
| 2568 | 2581 |
| 2569 ASSERT(IsIdentifier()); | 2582 ASSERT(IsIdentifier()); |
| 2570 ConsumeToken(); | 2583 ConsumeToken(); |
| 2571 ExpectToken(Token::kASSIGN); | 2584 ExpectToken(Token::kASSIGN); |
| 2572 AstNode* init_expr = NULL; | 2585 AstNode* init_expr = NULL; |
| 2573 intptr_t expr_pos = TokenPos(); | 2586 TokenDescriptor expr_pos = TokenPos(); |
| 2574 if (field.is_const()) { | 2587 if (field.is_const()) { |
| 2575 init_expr = ParseConstExpr(); | 2588 init_expr = ParseConstExpr(); |
| 2576 } else { | 2589 } else { |
| 2577 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2590 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2578 if (init_expr->EvalConstExpr() != NULL) { | 2591 if (init_expr->EvalConstExpr() != NULL) { |
| 2579 Instance& expr_value = Instance::ZoneHandle(Z); | 2592 Instance& expr_value = Instance::ZoneHandle(Z); |
| 2580 if (!GetCachedConstant(expr_pos, &expr_value)) { | 2593 if (!GetCachedConstant(expr_pos, &expr_value)) { |
| 2581 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); | 2594 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); |
| 2582 CacheConstantValue(expr_pos, expr_value); | 2595 CacheConstantValue(expr_pos, expr_value); |
| 2583 } | 2596 } |
| 2584 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); | 2597 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); |
| 2585 } | 2598 } |
| 2586 } | 2599 } |
| 2587 set_current_class(saved_class); | 2600 set_current_class(saved_class); |
| 2588 set_library(saved_library); | 2601 set_library(saved_library); |
| 2589 SetScript(saved_script, saved_token_pos); | 2602 SetScript(saved_script, saved_token_pos); |
| 2590 return init_expr; | 2603 return init_expr; |
| 2591 } | 2604 } |
| 2592 | 2605 |
| 2593 | 2606 |
| 2594 void Parser::ParseInitializedInstanceFields(const Class& cls, | 2607 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 2595 LocalVariable* receiver, | 2608 LocalVariable* receiver, |
| 2596 GrowableArray<Field*>* initialized_fields) { | 2609 GrowableArray<Field*>* initialized_fields) { |
| 2597 TRACE_PARSER("ParseInitializedInstanceFields"); | 2610 TRACE_PARSER("ParseInitializedInstanceFields"); |
| 2598 const Array& fields = Array::Handle(Z, cls.fields()); | 2611 const Array& fields = Array::Handle(Z, cls.fields()); |
| 2599 Field& f = Field::Handle(Z); | 2612 Field& f = Field::Handle(Z); |
| 2600 const intptr_t saved_pos = TokenPos(); | 2613 const TokenDescriptor saved_pos = TokenPos(); |
| 2601 for (int i = 0; i < fields.Length(); i++) { | 2614 for (int i = 0; i < fields.Length(); i++) { |
| 2602 f ^= fields.At(i); | 2615 f ^= fields.At(i); |
| 2603 if (!f.is_static() && f.has_initializer()) { | 2616 if (!f.is_static() && f.has_initializer()) { |
| 2604 Field& field = Field::ZoneHandle(Z); | 2617 Field& field = Field::ZoneHandle(Z); |
| 2605 field ^= fields.At(i); | 2618 field ^= fields.At(i); |
| 2606 if (field.is_final()) { | 2619 if (field.is_final()) { |
| 2607 // Final fields with initializer expression may not be initialized | 2620 // Final fields with initializer expression may not be initialized |
| 2608 // again by constructors. Remember that this field is already | 2621 // again by constructors. Remember that this field is already |
| 2609 // initialized. | 2622 // initialized. |
| 2610 initialized_fields->Add(&field); | 2623 initialized_fields->Add(&field); |
| 2611 } | 2624 } |
| 2612 AstNode* init_expr = NULL; | 2625 AstNode* init_expr = NULL; |
| 2613 if (current_class().raw() != field.origin()) { | 2626 if (current_class().raw() != field.origin()) { |
| 2614 init_expr = ParseExternalInitializedField(field); | 2627 init_expr = ParseExternalInitializedField(field); |
| 2615 } else { | 2628 } else { |
| 2616 SetPosition(field.token_pos()); | 2629 SetPosition(field.token_pos().value()); |
| 2617 ASSERT(IsIdentifier()); | 2630 ASSERT(IsIdentifier()); |
| 2618 ConsumeToken(); | 2631 ConsumeToken(); |
| 2619 ExpectToken(Token::kASSIGN); | 2632 ExpectToken(Token::kASSIGN); |
| 2620 if (current_class().is_const()) { | 2633 if (current_class().is_const()) { |
| 2621 // If the class has a const contructor, the initializer | 2634 // If the class has a const contructor, the initializer |
| 2622 // expression must be a compile-time constant. | 2635 // expression must be a compile-time constant. |
| 2623 init_expr = ParseConstExpr(); | 2636 init_expr = ParseConstExpr(); |
| 2624 } else { | 2637 } else { |
| 2625 intptr_t expr_pos = TokenPos(); | 2638 TokenDescriptor expr_pos = TokenPos(); |
| 2626 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2639 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2627 if (init_expr->EvalConstExpr() != NULL) { | 2640 if (init_expr->EvalConstExpr() != NULL) { |
| 2628 Instance& expr_value = Instance::ZoneHandle(Z); | 2641 Instance& expr_value = Instance::ZoneHandle(Z); |
| 2629 if (!GetCachedConstant(expr_pos, &expr_value)) { | 2642 if (!GetCachedConstant(expr_pos, &expr_value)) { |
| 2630 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); | 2643 expr_value = EvaluateConstExpr(expr_pos, init_expr).raw(); |
| 2631 CacheConstantValue(expr_pos, expr_value); | 2644 CacheConstantValue(expr_pos, expr_value); |
| 2632 } | 2645 } |
| 2633 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); | 2646 init_expr = new(Z) LiteralNode(field.token_pos(), expr_value); |
| 2634 } | 2647 } |
| 2635 } | 2648 } |
| 2636 } | 2649 } |
| 2637 ASSERT(init_expr != NULL); | 2650 ASSERT(init_expr != NULL); |
| 2638 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); | 2651 AstNode* instance = new LoadLocalNode(field.token_pos(), receiver); |
| 2639 EnsureExpressionTemp(); | 2652 EnsureExpressionTemp(); |
| 2640 AstNode* field_init = | 2653 AstNode* field_init = |
| 2641 new StoreInstanceFieldNode(field.token_pos(), | 2654 new StoreInstanceFieldNode(field.token_pos(), |
| 2642 instance, | 2655 instance, |
| 2643 field, | 2656 field, |
| 2644 init_expr); | 2657 init_expr); |
| 2645 current_block_->statements->Add(field_init); | 2658 current_block_->statements->Add(field_init); |
| 2646 } | 2659 } |
| 2647 } | 2660 } |
| 2648 initialized_fields->Add(NULL); // End of inline initializers. | 2661 initialized_fields->Add(NULL); // End of inline initializers. |
| 2649 SetPosition(saved_pos); | 2662 SetPosition(saved_pos); |
| 2650 } | 2663 } |
| 2651 | 2664 |
| 2652 | 2665 |
| 2653 AstNode* Parser::CheckDuplicateFieldInit( | 2666 AstNode* Parser::CheckDuplicateFieldInit( |
| 2654 intptr_t init_pos, | 2667 TokenDescriptor init_pos, |
| 2655 GrowableArray<Field*>* initialized_fields, | 2668 GrowableArray<Field*>* initialized_fields, |
| 2656 AstNode* instance, | 2669 AstNode* instance, |
| 2657 Field* field, | 2670 Field* field, |
| 2658 AstNode* init_value) { | 2671 AstNode* init_value) { |
| 2659 ASSERT(!field->is_static()); | 2672 ASSERT(!field->is_static()); |
| 2660 AstNode* result = NULL; | 2673 AstNode* result = NULL; |
| 2661 | 2674 |
| 2662 // The initializer_list is divided into two sections. The sections | 2675 // The initializer_list is divided into two sections. The sections |
| 2663 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...] | 2676 // are separated by a NULL entry: [f0, ... fn, NULL, fn+1, ...] |
| 2664 // The first fields f0 .. fn are final fields of the class that | 2677 // The first fields f0 .. fn are final fields of the class that |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2817 } | 2830 } |
| 2818 CheckFieldsInitialized(cls); | 2831 CheckFieldsInitialized(cls); |
| 2819 } | 2832 } |
| 2820 | 2833 |
| 2821 | 2834 |
| 2822 void Parser::ParseConstructorRedirection(const Class& cls, | 2835 void Parser::ParseConstructorRedirection(const Class& cls, |
| 2823 LocalVariable* receiver) { | 2836 LocalVariable* receiver) { |
| 2824 TRACE_PARSER("ParseConstructorRedirection"); | 2837 TRACE_PARSER("ParseConstructorRedirection"); |
| 2825 ExpectToken(Token::kCOLON); | 2838 ExpectToken(Token::kCOLON); |
| 2826 ASSERT(CurrentToken() == Token::kTHIS); | 2839 ASSERT(CurrentToken() == Token::kTHIS); |
| 2827 const intptr_t call_pos = TokenPos(); | 2840 const TokenDescriptor call_pos = TokenPos(); |
| 2828 ConsumeToken(); | 2841 ConsumeToken(); |
| 2829 String& ctor_name = String::Handle(Z, cls.Name()); | 2842 String& ctor_name = String::Handle(Z, cls.Name()); |
| 2830 GrowableHandlePtrArray<const String> pieces(Z, 3); | 2843 GrowableHandlePtrArray<const String> pieces(Z, 3); |
| 2831 pieces.Add(ctor_name); | 2844 pieces.Add(ctor_name); |
| 2832 pieces.Add(Symbols::Dot()); | 2845 pieces.Add(Symbols::Dot()); |
| 2833 if (CurrentToken() == Token::kPERIOD) { | 2846 if (CurrentToken() == Token::kPERIOD) { |
| 2834 ConsumeToken(); | 2847 ConsumeToken(); |
| 2835 pieces.Add(*ExpectIdentifier("constructor name expected")); | 2848 pieces.Add(*ExpectIdentifier("constructor name expected")); |
| 2836 } | 2849 } |
| 2837 ctor_name = Symbols::FromConcatAll(pieces); | 2850 ctor_name = Symbols::FromConcatAll(pieces); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2861 error_message.ToCString()); | 2874 error_message.ToCString()); |
| 2862 } | 2875 } |
| 2863 current_block_->statements->Add( | 2876 current_block_->statements->Add( |
| 2864 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 2877 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 2865 } | 2878 } |
| 2866 | 2879 |
| 2867 | 2880 |
| 2868 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2881 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 2869 ASSERT(func.IsGenerativeConstructor()); | 2882 ASSERT(func.IsGenerativeConstructor()); |
| 2870 ASSERT(func.Owner() == current_class().raw()); | 2883 ASSERT(func.Owner() == current_class().raw()); |
| 2871 const intptr_t ctor_pos = TokenPos(); | 2884 const TokenDescriptor ctor_pos = TokenPos(); |
| 2872 OpenFunctionBlock(func); | 2885 OpenFunctionBlock(func); |
| 2873 | 2886 |
| 2874 LocalVariable* receiver = new LocalVariable( | 2887 LocalVariable* receiver = new LocalVariable( |
| 2875 Token::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); | 2888 TokenDescriptor::kNoSource, |
| 2889 Symbols::This(), |
| 2890 *ReceiverType(current_class())); |
| 2876 current_block_->scope->InsertParameterAt(0, receiver); | 2891 current_block_->scope->InsertParameterAt(0, receiver); |
| 2877 | 2892 |
| 2878 // Parse expressions of instance fields that have an explicit | 2893 // Parse expressions of instance fields that have an explicit |
| 2879 // initializer expression. | 2894 // initializer expression. |
| 2880 // The receiver must not be visible to field initializer expressions. | 2895 // The receiver must not be visible to field initializer expressions. |
| 2881 receiver->set_invisible(true); | 2896 receiver->set_invisible(true); |
| 2882 GrowableArray<Field*> initialized_fields; | 2897 GrowableArray<Field*> initialized_fields; |
| 2883 ParseInitializedInstanceFields( | 2898 ParseInitializedInstanceFields( |
| 2884 current_class(), receiver, &initialized_fields); | 2899 current_class(), receiver, &initialized_fields); |
| 2885 receiver->set_invisible(false); | 2900 receiver->set_invisible(false); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2911 "optional parameters and invoke it via super from a " | 2926 "optional parameters and invoke it via super from a " |
| 2912 "constructor of the class extending the mixin application", | 2927 "constructor of the class extending the mixin application", |
| 2913 String::Handle(Z, super_class.Name()).ToCString()); | 2928 String::Handle(Z, super_class.Name()).ToCString()); |
| 2914 } | 2929 } |
| 2915 | 2930 |
| 2916 // Prepare user-defined arguments to be forwarded to super call. | 2931 // Prepare user-defined arguments to be forwarded to super call. |
| 2917 // The first user-defined argument is at position 1. | 2932 // The first user-defined argument is at position 1. |
| 2918 forwarding_args = new ArgumentListNode(ST(ctor_pos)); | 2933 forwarding_args = new ArgumentListNode(ST(ctor_pos)); |
| 2919 for (int i = 1; i < func.NumParameters(); i++) { | 2934 for (int i = 1; i < func.NumParameters(); i++) { |
| 2920 LocalVariable* param = new LocalVariable( | 2935 LocalVariable* param = new LocalVariable( |
| 2921 Token::kNoSourcePos, | 2936 TokenDescriptor::kNoSource, |
| 2922 String::ZoneHandle(Z, func.ParameterNameAt(i)), | 2937 String::ZoneHandle(Z, func.ParameterNameAt(i)), |
| 2923 Object::dynamic_type()); | 2938 Object::dynamic_type()); |
| 2924 current_block_->scope->InsertParameterAt(i, param); | 2939 current_block_->scope->InsertParameterAt(i, param); |
| 2925 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); | 2940 forwarding_args->Add(new LoadLocalNode(ST(ctor_pos), param)); |
| 2926 } | 2941 } |
| 2927 } | 2942 } |
| 2928 | 2943 |
| 2929 AstNode* super_call = GenerateSuperConstructorCall( | 2944 AstNode* super_call = GenerateSuperConstructorCall( |
| 2930 current_class(), | 2945 current_class(), |
| 2931 ctor_pos, | 2946 ctor_pos, |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3268 if (IsInstantiatorRequired()) { | 3283 if (IsInstantiatorRequired()) { |
| 3269 // Make sure that the receiver of the enclosing instance function | 3284 // Make sure that the receiver of the enclosing instance function |
| 3270 // (or implicit first parameter of an enclosing factory) is marked as | 3285 // (or implicit first parameter of an enclosing factory) is marked as |
| 3271 // captured if type checks are enabled, because they may access it to | 3286 // captured if type checks are enabled, because they may access it to |
| 3272 // instantiate types. | 3287 // instantiate types. |
| 3273 CaptureInstantiator(); | 3288 CaptureInstantiator(); |
| 3274 } | 3289 } |
| 3275 } | 3290 } |
| 3276 } | 3291 } |
| 3277 | 3292 |
| 3278 const intptr_t modifier_pos = TokenPos(); | 3293 const TokenDescriptor modifier_pos = TokenPos(); |
| 3279 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 3294 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
| 3280 if (!func.is_generated_body()) { | 3295 if (!func.is_generated_body()) { |
| 3281 // Don't add a modifier to the closure representing the body of | 3296 // Don't add a modifier to the closure representing the body of |
| 3282 // the asynchronous function or generator. | 3297 // the asynchronous function or generator. |
| 3283 func.set_modifier(func_modifier); | 3298 func.set_modifier(func_modifier); |
| 3284 } | 3299 } |
| 3285 | 3300 |
| 3286 OpenBlock(); // Open a nested scope for the outermost function block. | 3301 OpenBlock(); // Open a nested scope for the outermost function block. |
| 3287 | 3302 |
| 3288 Function& generated_body_closure = Function::ZoneHandle(Z); | 3303 Function& generated_body_closure = Function::ZoneHandle(Z); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3307 func.set_is_debuggable(false); | 3322 func.set_is_debuggable(false); |
| 3308 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); | 3323 generated_body_closure = OpenAsyncGeneratorFunction(func.token_pos()); |
| 3309 } else if (func.IsAsyncGenClosure()) { | 3324 } else if (func.IsAsyncGenClosure()) { |
| 3310 // The closure containing the body of an async* function is debuggable. | 3325 // The closure containing the body of an async* function is debuggable. |
| 3311 ASSERT(func.is_debuggable()); | 3326 ASSERT(func.is_debuggable()); |
| 3312 OpenAsyncGeneratorClosure(); | 3327 OpenAsyncGeneratorClosure(); |
| 3313 } | 3328 } |
| 3314 | 3329 |
| 3315 BoolScope allow_await(&this->await_is_keyword_, | 3330 BoolScope allow_await(&this->await_is_keyword_, |
| 3316 func.IsAsyncOrGenerator() || func.is_generated_body()); | 3331 func.IsAsyncOrGenerator() || func.is_generated_body()); |
| 3317 intptr_t end_token_pos = Token::kNoSourcePos; | 3332 TokenDescriptor end_token_pos = TokenDescriptor::kNoSource; |
| 3318 if (CurrentToken() == Token::kLBRACE) { | 3333 if (CurrentToken() == Token::kLBRACE) { |
| 3319 ConsumeToken(); | 3334 ConsumeToken(); |
| 3320 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { | 3335 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
| 3321 const Class& owner = Class::Handle(Z, func.Owner()); | 3336 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3322 if (!owner.IsObjectClass()) { | 3337 if (!owner.IsObjectClass()) { |
| 3323 AddEqualityNullCheck(); | 3338 AddEqualityNullCheck(); |
| 3324 } | 3339 } |
| 3325 } | 3340 } |
| 3326 ParseStatementSequence(); | 3341 ParseStatementSequence(); |
| 3327 end_token_pos = TokenPos(); | 3342 end_token_pos = TokenPos(); |
| 3328 ExpectToken(Token::kRBRACE); | 3343 ExpectToken(Token::kRBRACE); |
| 3329 } else if (CurrentToken() == Token::kARROW) { | 3344 } else if (CurrentToken() == Token::kARROW) { |
| 3330 if (func.IsGenerator()) { | 3345 if (func.IsGenerator()) { |
| 3331 ReportError(modifier_pos, | 3346 ReportError(modifier_pos, |
| 3332 "=> style function may not be sync* or async* generator"); | 3347 "=> style function may not be sync* or async* generator"); |
| 3333 } | 3348 } |
| 3334 ConsumeToken(); | 3349 ConsumeToken(); |
| 3335 if (String::Handle(Z, func.name()).Equals( | 3350 if (String::Handle(Z, func.name()).Equals( |
| 3336 Symbols::EqualOperator())) { | 3351 Symbols::EqualOperator())) { |
| 3337 const Class& owner = Class::Handle(Z, func.Owner()); | 3352 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3338 if (!owner.IsObjectClass()) { | 3353 if (!owner.IsObjectClass()) { |
| 3339 AddEqualityNullCheck(); | 3354 AddEqualityNullCheck(); |
| 3340 } | 3355 } |
| 3341 } | 3356 } |
| 3342 const intptr_t expr_pos = TokenPos(); | 3357 const TokenDescriptor expr_pos = TokenPos(); |
| 3343 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 3358 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 3344 ASSERT(expr != NULL); | 3359 ASSERT(expr != NULL); |
| 3345 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3360 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 3346 end_token_pos = TokenPos(); | 3361 end_token_pos = TokenPos(); |
| 3347 if (check_semicolon) { | 3362 if (check_semicolon) { |
| 3348 ExpectSemicolon(); | 3363 ExpectSemicolon(); |
| 3349 } | 3364 } |
| 3350 } else if (IsSymbol(Symbols::Native())) { | 3365 } else if (IsSymbol(Symbols::Native())) { |
| 3351 if (String::Handle(Z, func.name()).Equals( | 3366 if (String::Handle(Z, func.name()).Equals( |
| 3352 Symbols::EqualOperator())) { | 3367 Symbols::EqualOperator())) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3400 current_block_->statements->Add(body); | 3415 current_block_->statements->Add(body); |
| 3401 innermost_function_ = saved_innermost_function.raw(); | 3416 innermost_function_ = saved_innermost_function.raw(); |
| 3402 last_used_try_index_ = saved_try_index; | 3417 last_used_try_index_ = saved_try_index; |
| 3403 async_temp_scope_ = saved_async_temp_scope; | 3418 async_temp_scope_ = saved_async_temp_scope; |
| 3404 return CloseBlock(); | 3419 return CloseBlock(); |
| 3405 } | 3420 } |
| 3406 | 3421 |
| 3407 | 3422 |
| 3408 void Parser::AddEqualityNullCheck() { | 3423 void Parser::AddEqualityNullCheck() { |
| 3409 AstNode* argument = | 3424 AstNode* argument = |
| 3410 new LoadLocalNode(Token::kNoSourcePos, | 3425 new LoadLocalNode(TokenDescriptor::kNoSource, |
| 3411 current_block_->scope->parent()->VariableAt(1)); | 3426 current_block_->scope->parent()->VariableAt(1)); |
| 3412 LiteralNode* null_operand = | 3427 LiteralNode* null_operand = |
| 3413 new LiteralNode(Token::kNoSourcePos, Instance::ZoneHandle(Z)); | 3428 new LiteralNode(TokenDescriptor::kNoSource, Instance::ZoneHandle(Z)); |
| 3414 ComparisonNode* check_arg = | 3429 ComparisonNode* check_arg = |
| 3415 new ComparisonNode(Token::kNoSourcePos, | 3430 new ComparisonNode(TokenDescriptor::kNoSource, |
| 3416 Token::kEQ_STRICT, | 3431 Token::kEQ_STRICT, |
| 3417 argument, | 3432 argument, |
| 3418 null_operand); | 3433 null_operand); |
| 3419 ComparisonNode* result = | 3434 ComparisonNode* result = |
| 3420 new ComparisonNode(Token::kNoSourcePos, | 3435 new ComparisonNode(TokenDescriptor::kNoSource, |
| 3421 Token::kEQ_STRICT, | 3436 Token::kEQ_STRICT, |
| 3422 LoadReceiver(Token::kNoSourcePos), | 3437 LoadReceiver(TokenDescriptor::kNoSource), |
| 3423 null_operand); | 3438 null_operand); |
| 3424 SequenceNode* arg_is_null = new SequenceNode(Token::kNoSourcePos, | 3439 SequenceNode* arg_is_null = new SequenceNode(TokenDescriptor::kNoSource, |
| 3425 current_block_->scope); | 3440 current_block_->scope); |
| 3426 arg_is_null->Add(new ReturnNode(Token::kNoSourcePos, result)); | 3441 arg_is_null->Add(new ReturnNode(TokenDescriptor::kNoSource, result)); |
| 3427 IfNode* if_arg_null = new IfNode(Token::kNoSourcePos, | 3442 IfNode* if_arg_null = new IfNode(TokenDescriptor::kNoSource, |
| 3428 check_arg, | 3443 check_arg, |
| 3429 arg_is_null, | 3444 arg_is_null, |
| 3430 NULL); | 3445 NULL); |
| 3431 current_block_->statements->Add(if_arg_null); | 3446 current_block_->statements->Add(if_arg_null); |
| 3432 } | 3447 } |
| 3433 | 3448 |
| 3434 | 3449 |
| 3435 void Parser::SkipIf(Token::Kind token) { | 3450 void Parser::SkipIf(Token::Kind token) { |
| 3436 if (CurrentToken() == token) { | 3451 if (CurrentToken() == token) { |
| 3437 ConsumeToken(); | 3452 ConsumeToken(); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3529 if (method->has_abstract && method->IsFactoryOrConstructor()) { | 3544 if (method->has_abstract && method->IsFactoryOrConstructor()) { |
| 3530 ReportError(method->name_pos, "constructor cannot be abstract"); | 3545 ReportError(method->name_pos, "constructor cannot be abstract"); |
| 3531 } | 3546 } |
| 3532 if (method->has_const && method->IsConstructor()) { | 3547 if (method->has_const && method->IsConstructor()) { |
| 3533 current_class().set_is_const(); | 3548 current_class().set_is_const(); |
| 3534 } | 3549 } |
| 3535 | 3550 |
| 3536 // Parse the formal parameters. | 3551 // Parse the formal parameters. |
| 3537 const bool are_implicitly_final = method->has_const; | 3552 const bool are_implicitly_final = method->has_const; |
| 3538 const bool allow_explicit_default_values = true; | 3553 const bool allow_explicit_default_values = true; |
| 3539 const intptr_t formal_param_pos = TokenPos(); | 3554 const TokenDescriptor formal_param_pos = TokenPos(); |
| 3540 method->params.Clear(); | 3555 method->params.Clear(); |
| 3541 // Static functions do not have a receiver. | 3556 // Static functions do not have a receiver. |
| 3542 // The first parameter of a factory is the TypeArguments vector of | 3557 // The first parameter of a factory is the TypeArguments vector of |
| 3543 // the type of the instance to be allocated. | 3558 // the type of the instance to be allocated. |
| 3544 if (!method->has_static || method->IsConstructor()) { | 3559 if (!method->has_static || method->IsConstructor()) { |
| 3545 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); | 3560 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); |
| 3546 } else if (method->IsFactory()) { | 3561 } else if (method->IsFactory()) { |
| 3547 method->params.AddFinalParameter( | 3562 method->params.AddFinalParameter( |
| 3548 formal_param_pos, | 3563 formal_param_pos, |
| 3549 &Symbols::TypeArgumentsParameter(), | 3564 &Symbols::TypeArgumentsParameter(), |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3603 ReportError("redirecting factory '%s' may not specify default values " | 3618 ReportError("redirecting factory '%s' may not specify default values " |
| 3604 "for optional parameters", | 3619 "for optional parameters", |
| 3605 method->name->ToCString()); | 3620 method->name->ToCString()); |
| 3606 } | 3621 } |
| 3607 if (method->has_external) { | 3622 if (method->has_external) { |
| 3608 ReportError(TokenPos(), | 3623 ReportError(TokenPos(), |
| 3609 "external factory constructor '%s' may not have redirection", | 3624 "external factory constructor '%s' may not have redirection", |
| 3610 method->name->ToCString()); | 3625 method->name->ToCString()); |
| 3611 } | 3626 } |
| 3612 ConsumeToken(); | 3627 ConsumeToken(); |
| 3613 const intptr_t type_pos = TokenPos(); | 3628 const TokenDescriptor type_pos = TokenPos(); |
| 3614 is_redirecting = true; | 3629 is_redirecting = true; |
| 3615 const bool consume_unresolved_prefix = | 3630 const bool consume_unresolved_prefix = |
| 3616 (LookaheadToken(3) == Token::kLT) || | 3631 (LookaheadToken(3) == Token::kLT) || |
| 3617 (LookaheadToken(3) == Token::kPERIOD); | 3632 (LookaheadToken(3) == Token::kPERIOD); |
| 3618 const AbstractType& type = AbstractType::Handle(Z, | 3633 const AbstractType& type = AbstractType::Handle(Z, |
| 3619 ParseType(ClassFinalizer::kResolveTypeParameters, | 3634 ParseType(ClassFinalizer::kResolveTypeParameters, |
| 3620 true, | 3635 true, |
| 3621 consume_unresolved_prefix)); | 3636 consume_unresolved_prefix)); |
| 3622 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3637 if (!type.IsMalformed() && type.IsTypeParameter()) { |
| 3623 // Replace the type with a malformed type and compile a throw when called. | 3638 // Replace the type with a malformed type and compile a throw when called. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3682 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); | 3697 ASSERT((method->redirect_name == NULL) || method->IsConstructor()); |
| 3683 | 3698 |
| 3684 if (method->IsConstructor() && | 3699 if (method->IsConstructor() && |
| 3685 method->has_external && | 3700 method->has_external && |
| 3686 method->params.has_field_initializer) { | 3701 method->params.has_field_initializer) { |
| 3687 ReportError(method->name_pos, | 3702 ReportError(method->name_pos, |
| 3688 "external constructor '%s' may not have field initializers", | 3703 "external constructor '%s' may not have field initializers", |
| 3689 method->name->ToCString()); | 3704 method->name->ToCString()); |
| 3690 } | 3705 } |
| 3691 | 3706 |
| 3692 const intptr_t modifier_pos = TokenPos(); | 3707 const TokenDescriptor modifier_pos = TokenPos(); |
| 3693 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); | 3708 RawFunction::AsyncModifier async_modifier = ParseFunctionModifier(); |
| 3694 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && | 3709 if ((method->IsFactoryOrConstructor() || method->IsSetter()) && |
| 3695 (async_modifier != RawFunction::kNoModifier)) { | 3710 (async_modifier != RawFunction::kNoModifier)) { |
| 3696 ReportError(modifier_pos, | 3711 ReportError(modifier_pos, |
| 3697 "%s '%s' may not be async, async* or sync*", | 3712 "%s '%s' may not be async, async* or sync*", |
| 3698 (method->IsSetter()) ? "setter" : "constructor", | 3713 (method->IsSetter()) ? "setter" : "constructor", |
| 3699 method->name->ToCString()); | 3714 method->name->ToCString()); |
| 3700 } | 3715 } |
| 3701 | 3716 |
| 3702 intptr_t method_end_pos = TokenPos(); | 3717 TokenDescriptor method_end_pos = TokenPos(); |
| 3703 String* native_name = NULL; | 3718 String* native_name = NULL; |
| 3704 if ((CurrentToken() == Token::kLBRACE) || | 3719 if ((CurrentToken() == Token::kLBRACE) || |
| 3705 (CurrentToken() == Token::kARROW)) { | 3720 (CurrentToken() == Token::kARROW)) { |
| 3706 if (method->has_abstract) { | 3721 if (method->has_abstract) { |
| 3707 ReportError(TokenPos(), | 3722 ReportError(TokenPos(), |
| 3708 "abstract method '%s' may not have a function body", | 3723 "abstract method '%s' may not have a function body", |
| 3709 method->name->ToCString()); | 3724 method->name->ToCString()); |
| 3710 } else if (method->has_external) { | 3725 } else if (method->has_external) { |
| 3711 ReportError(TokenPos(), | 3726 ReportError(TokenPos(), |
| 3712 "external %s '%s' may not have a function body", | 3727 "external %s '%s' may not have a function body", |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3824 method->has_native, | 3839 method->has_native, |
| 3825 current_class(), | 3840 current_class(), |
| 3826 method->decl_begin_pos)); | 3841 method->decl_begin_pos)); |
| 3827 func.set_result_type(*method->type); | 3842 func.set_result_type(*method->type); |
| 3828 func.set_end_token_pos(method_end_pos); | 3843 func.set_end_token_pos(method_end_pos); |
| 3829 func.set_is_redirecting(is_redirecting); | 3844 func.set_is_redirecting(is_redirecting); |
| 3830 func.set_modifier(async_modifier); | 3845 func.set_modifier(async_modifier); |
| 3831 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { | 3846 if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) { |
| 3832 func.set_is_reflectable(false); | 3847 func.set_is_reflectable(false); |
| 3833 } | 3848 } |
| 3834 if (FLAG_enable_mirrors && (method->metadata_pos >= 0)) { | 3849 if (FLAG_enable_mirrors && (method->metadata_pos.IsReal())) { |
| 3835 library_.AddFunctionMetadata(func, method->metadata_pos); | 3850 library_.AddFunctionMetadata(func, method->metadata_pos); |
| 3836 } | 3851 } |
| 3837 if (method->has_native) { | 3852 if (method->has_native) { |
| 3838 func.set_native_name(*native_name); | 3853 func.set_native_name(*native_name); |
| 3839 } | 3854 } |
| 3840 | 3855 |
| 3841 // If this method is a redirecting factory, set the redirection information. | 3856 // If this method is a redirecting factory, set the redirection information. |
| 3842 if (!redirection_type.IsNull()) { | 3857 if (!redirection_type.IsNull()) { |
| 3843 ASSERT(func.IsFactory()); | 3858 ASSERT(func.IsFactory()); |
| 3844 func.SetRedirectionType(redirection_type); | 3859 func.SetRedirectionType(redirection_type); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3855 | 3870 |
| 3856 | 3871 |
| 3857 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { | 3872 void Parser::ParseFieldDefinition(ClassDesc* members, MemberDesc* field) { |
| 3858 TRACE_PARSER("ParseFieldDefinition"); | 3873 TRACE_PARSER("ParseFieldDefinition"); |
| 3859 // The parser has read the first field name and is now at the token | 3874 // The parser has read the first field name and is now at the token |
| 3860 // after the field name. | 3875 // after the field name. |
| 3861 ASSERT(CurrentToken() == Token::kSEMICOLON || | 3876 ASSERT(CurrentToken() == Token::kSEMICOLON || |
| 3862 CurrentToken() == Token::kCOMMA || | 3877 CurrentToken() == Token::kCOMMA || |
| 3863 CurrentToken() == Token::kASSIGN); | 3878 CurrentToken() == Token::kASSIGN); |
| 3864 ASSERT(field->type != NULL); | 3879 ASSERT(field->type != NULL); |
| 3865 ASSERT(field->name_pos >= 0); | 3880 ASSERT(field->name_pos.IsReal()); |
| 3866 ASSERT(current_member_ == field); | 3881 ASSERT(current_member_ == field); |
| 3867 // All const fields are also final. | 3882 // All const fields are also final. |
| 3868 ASSERT(!field->has_const || field->has_final); | 3883 ASSERT(!field->has_const || field->has_final); |
| 3869 | 3884 |
| 3870 if (field->has_abstract) { | 3885 if (field->has_abstract) { |
| 3871 ReportError("keyword 'abstract' not allowed in field declaration"); | 3886 ReportError("keyword 'abstract' not allowed in field declaration"); |
| 3872 } | 3887 } |
| 3873 if (field->has_external) { | 3888 if (field->has_external) { |
| 3874 ReportError("keyword 'external' not allowed in field declaration"); | 3889 ReportError("keyword 'external' not allowed in field declaration"); |
| 3875 } | 3890 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3924 field->has_static, | 3939 field->has_static, |
| 3925 field->has_final, | 3940 field->has_final, |
| 3926 field->has_const, | 3941 field->has_const, |
| 3927 is_reflectable, | 3942 is_reflectable, |
| 3928 current_class(), | 3943 current_class(), |
| 3929 *field->type, | 3944 *field->type, |
| 3930 field->name_pos); | 3945 field->name_pos); |
| 3931 class_field.set_has_initializer(has_initializer); | 3946 class_field.set_has_initializer(has_initializer); |
| 3932 members->AddField(class_field); | 3947 members->AddField(class_field); |
| 3933 field->field_ = &class_field; | 3948 field->field_ = &class_field; |
| 3934 if (FLAG_enable_mirrors && (field->metadata_pos >= 0)) { | 3949 if (FLAG_enable_mirrors && (field->metadata_pos.IsReal())) { |
| 3935 library_.AddFieldMetadata(class_field, field->metadata_pos); | 3950 library_.AddFieldMetadata(class_field, field->metadata_pos); |
| 3936 } | 3951 } |
| 3937 | 3952 |
| 3938 // Start tracking types for fields with simple initializers in their | 3953 // Start tracking types for fields with simple initializers in their |
| 3939 // definition. This avoids some of the overhead to track this at runtime | 3954 // definition. This avoids some of the overhead to track this at runtime |
| 3940 // and rules out many fields from being unnecessary unboxing candidates. | 3955 // and rules out many fields from being unnecessary unboxing candidates. |
| 3941 if (!field->has_static && has_initializer && has_simple_literal) { | 3956 if (!field->has_static && has_initializer && has_simple_literal) { |
| 3942 class_field.RecordStore(init_value); | 3957 class_field.RecordStore(init_value); |
| 3943 if (!init_value.IsNull() && init_value.IsDouble()) { | 3958 if (!init_value.IsNull() && init_value.IsDouble()) { |
| 3944 class_field.set_is_double_initialized(true); | 3959 class_field.set_is_double_initialized(true); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4071 "%s '%s' conflicts with previously declared %s", | 4086 "%s '%s' conflicts with previously declared %s", |
| 4072 member->ToCString(), | 4087 member->ToCString(), |
| 4073 name.ToCString(), | 4088 name.ToCString(), |
| 4074 existing_member->ToCString()); | 4089 existing_member->ToCString()); |
| 4075 } | 4090 } |
| 4076 } | 4091 } |
| 4077 } | 4092 } |
| 4078 | 4093 |
| 4079 | 4094 |
| 4080 void Parser::ParseClassMemberDefinition(ClassDesc* members, | 4095 void Parser::ParseClassMemberDefinition(ClassDesc* members, |
| 4081 intptr_t metadata_pos) { | 4096 TokenDescriptor metadata_pos) { |
| 4082 TRACE_PARSER("ParseClassMemberDefinition"); | 4097 TRACE_PARSER("ParseClassMemberDefinition"); |
| 4083 MemberDesc member; | 4098 MemberDesc member; |
| 4084 current_member_ = &member; | 4099 current_member_ = &member; |
| 4085 member.metadata_pos = metadata_pos; | 4100 member.metadata_pos = metadata_pos; |
| 4086 member.decl_begin_pos = TokenPos(); | 4101 member.decl_begin_pos = TokenPos(); |
| 4087 if ((CurrentToken() == Token::kEXTERNAL) && | 4102 if ((CurrentToken() == Token::kEXTERNAL) && |
| 4088 (LookaheadToken(1) != Token::kLPAREN)) { | 4103 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4089 ConsumeToken(); | 4104 ConsumeToken(); |
| 4090 member.has_external = true; | 4105 member.has_external = true; |
| 4091 } | 4106 } |
| (...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4282 UnexpectedToken(); | 4297 UnexpectedToken(); |
| 4283 } | 4298 } |
| 4284 current_member_ = NULL; | 4299 current_member_ = NULL; |
| 4285 CheckMemberNameConflict(members, &member); | 4300 CheckMemberNameConflict(members, &member); |
| 4286 members->AddMember(member); | 4301 members->AddMember(member); |
| 4287 } | 4302 } |
| 4288 | 4303 |
| 4289 | 4304 |
| 4290 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, | 4305 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes, |
| 4291 const Object& tl_owner, | 4306 const Object& tl_owner, |
| 4292 intptr_t metadata_pos) { | 4307 TokenDescriptor metadata_pos) { |
| 4293 TRACE_PARSER("ParseEnumDeclaration"); | 4308 TRACE_PARSER("ParseEnumDeclaration"); |
| 4294 const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos | 4309 const TokenDescriptor declaration_pos = |
| 4295 : TokenPos(); | 4310 (metadata_pos.IsReal()) ? metadata_pos : TokenPos(); |
| 4296 ConsumeToken(); | 4311 ConsumeToken(); |
| 4297 const intptr_t name_pos = TokenPos(); | 4312 const TokenDescriptor name_pos = TokenPos(); |
| 4298 String* enum_name = | 4313 String* enum_name = |
| 4299 ExpectUserDefinedTypeIdentifier("enum type name expected"); | 4314 ExpectUserDefinedTypeIdentifier("enum type name expected"); |
| 4300 if (FLAG_trace_parser) { | 4315 if (FLAG_trace_parser) { |
| 4301 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); | 4316 OS::Print("TopLevel parsing enum '%s'\n", enum_name->ToCString()); |
| 4302 } | 4317 } |
| 4303 ExpectToken(Token::kLBRACE); | 4318 ExpectToken(Token::kLBRACE); |
| 4304 if (!IsIdentifier()) { | 4319 if (!IsIdentifier()) { |
| 4305 ReportError("Enumeration must have at least one name"); | 4320 ReportError("Enumeration must have at least one name"); |
| 4306 } | 4321 } |
| 4307 while (IsIdentifier()) { | 4322 while (IsIdentifier()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4322 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); | 4337 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); |
| 4323 if (!obj.IsNull()) { | 4338 if (!obj.IsNull()) { |
| 4324 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); | 4339 ReportError(name_pos, "'%s' is already defined", enum_name->ToCString()); |
| 4325 } | 4340 } |
| 4326 Class& cls = Class::Handle(Z); | 4341 Class& cls = Class::Handle(Z); |
| 4327 cls = Class::New(*enum_name, script_, declaration_pos); | 4342 cls = Class::New(*enum_name, script_, declaration_pos); |
| 4328 cls.set_library(library_); | 4343 cls.set_library(library_); |
| 4329 library_.AddClass(cls); | 4344 library_.AddClass(cls); |
| 4330 cls.set_is_synthesized_class(); | 4345 cls.set_is_synthesized_class(); |
| 4331 cls.set_is_enum_class(); | 4346 cls.set_is_enum_class(); |
| 4332 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4347 if (FLAG_enable_mirrors && (metadata_pos.IsReal())) { |
| 4333 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4348 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
| 4334 } | 4349 } |
| 4335 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); | 4350 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); |
| 4336 pending_classes.Add(cls, Heap::kOld); | 4351 pending_classes.Add(cls, Heap::kOld); |
| 4337 } | 4352 } |
| 4338 | 4353 |
| 4339 | 4354 |
| 4340 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4355 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| 4341 const Object& tl_owner, | 4356 const Object& tl_owner, |
| 4342 intptr_t metadata_pos) { | 4357 TokenDescriptor metadata_pos) { |
| 4343 TRACE_PARSER("ParseClassDeclaration"); | 4358 TRACE_PARSER("ParseClassDeclaration"); |
| 4344 bool is_patch = false; | 4359 bool is_patch = false; |
| 4345 bool is_abstract = false; | 4360 bool is_abstract = false; |
| 4346 intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos(); | 4361 TokenDescriptor declaration_pos = |
| 4362 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
| 4347 if (is_patch_source() && | 4363 if (is_patch_source() && |
| 4348 (CurrentToken() == Token::kIDENT) && | 4364 (CurrentToken() == Token::kIDENT) && |
| 4349 CurrentLiteral()->Equals("patch")) { | 4365 CurrentLiteral()->Equals("patch")) { |
| 4350 ConsumeToken(); | 4366 ConsumeToken(); |
| 4351 is_patch = true; | 4367 is_patch = true; |
| 4352 } else if (CurrentToken() == Token::kABSTRACT) { | 4368 } else if (CurrentToken() == Token::kABSTRACT) { |
| 4353 is_abstract = true; | 4369 is_abstract = true; |
| 4354 ConsumeToken(); | 4370 ConsumeToken(); |
| 4355 } | 4371 } |
| 4356 ExpectToken(Token::kCLASS); | 4372 ExpectToken(Token::kCLASS); |
| 4357 const intptr_t classname_pos = TokenPos(); | 4373 const TokenDescriptor classname_pos = TokenPos(); |
| 4358 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4374 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4359 if (FLAG_trace_parser) { | 4375 if (FLAG_trace_parser) { |
| 4360 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 4376 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 4361 } | 4377 } |
| 4362 Class& cls = Class::Handle(Z); | 4378 Class& cls = Class::Handle(Z); |
| 4363 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); | 4379 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); |
| 4364 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4380 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
| 4365 if (obj.IsNull()) { | 4381 if (obj.IsNull()) { |
| 4366 if (is_patch) { | 4382 if (is_patch) { |
| 4367 ReportError(classname_pos, "missing class '%s' cannot be patched", | 4383 ReportError(classname_pos, "missing class '%s' cannot be patched", |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4441 class_name.ToCString(), | 4457 class_name.ToCString(), |
| 4442 String::Handle(orig_bound.UserVisibleName()).ToCString()); | 4458 String::Handle(orig_bound.UserVisibleName()).ToCString()); |
| 4443 } | 4459 } |
| 4444 } | 4460 } |
| 4445 cls.set_type_parameters(orig_type_parameters); | 4461 cls.set_type_parameters(orig_type_parameters); |
| 4446 } | 4462 } |
| 4447 | 4463 |
| 4448 if (is_abstract) { | 4464 if (is_abstract) { |
| 4449 cls.set_is_abstract(); | 4465 cls.set_is_abstract(); |
| 4450 } | 4466 } |
| 4451 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4467 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 4452 library_.AddClassMetadata(cls, tl_owner, metadata_pos); | 4468 library_.AddClassMetadata(cls, tl_owner, metadata_pos); |
| 4453 } | 4469 } |
| 4454 | 4470 |
| 4455 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | 4471 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
| 4456 if (is_mixin_declaration && is_patch) { | 4472 if (is_mixin_declaration && is_patch) { |
| 4457 ReportError(classname_pos, | 4473 ReportError(classname_pos, |
| 4458 "mixin application '%s' may not be a patch class", | 4474 "mixin application '%s' may not be a patch class", |
| 4459 class_name.ToCString()); | 4475 class_name.ToCString()); |
| 4460 } | 4476 } |
| 4461 | 4477 |
| 4462 AbstractType& super_type = Type::Handle(Z); | 4478 AbstractType& super_type = Type::Handle(Z); |
| 4463 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 4479 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
| 4464 ConsumeToken(); // extends or = | 4480 ConsumeToken(); // extends or = |
| 4465 const intptr_t type_pos = TokenPos(); | 4481 const TokenDescriptor type_pos = TokenPos(); |
| 4466 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4482 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4467 if (super_type.IsMalformedOrMalbounded()) { | 4483 if (super_type.IsMalformedOrMalbounded()) { |
| 4468 ReportError(Error::Handle(Z, super_type.error())); | 4484 ReportError(Error::Handle(Z, super_type.error())); |
| 4469 } | 4485 } |
| 4470 if (super_type.IsDynamicType()) { | 4486 if (super_type.IsDynamicType()) { |
| 4471 // Unlikely here, since super type is not resolved yet. | 4487 // Unlikely here, since super type is not resolved yet. |
| 4472 ReportError(type_pos, | 4488 ReportError(type_pos, |
| 4473 "class '%s' may not extend 'dynamic'", | 4489 "class '%s' may not extend 'dynamic'", |
| 4474 class_name.ToCString()); | 4490 class_name.ToCString()); |
| 4475 } | 4491 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4532 String& class_name = String::Handle(Z, cls.Name()); | 4548 String& class_name = String::Handle(Z, cls.Name()); |
| 4533 SkipMetadata(); | 4549 SkipMetadata(); |
| 4534 if (is_patch_source() && | 4550 if (is_patch_source() && |
| 4535 (CurrentToken() == Token::kIDENT) && | 4551 (CurrentToken() == Token::kIDENT) && |
| 4536 CurrentLiteral()->Equals("patch")) { | 4552 CurrentLiteral()->Equals("patch")) { |
| 4537 ConsumeToken(); | 4553 ConsumeToken(); |
| 4538 } else if (CurrentToken() == Token::kABSTRACT) { | 4554 } else if (CurrentToken() == Token::kABSTRACT) { |
| 4539 ConsumeToken(); | 4555 ConsumeToken(); |
| 4540 } | 4556 } |
| 4541 ExpectToken(Token::kCLASS); | 4557 ExpectToken(Token::kCLASS); |
| 4542 const intptr_t class_pos = TokenPos(); | 4558 const TokenDescriptor class_pos = TokenPos(); |
| 4543 ClassDesc members(Z, cls, class_name, false, class_pos); | 4559 ClassDesc members(Z, cls, class_name, false, class_pos); |
| 4544 while (CurrentToken() != Token::kLBRACE) { | 4560 while (CurrentToken() != Token::kLBRACE) { |
| 4545 ConsumeToken(); | 4561 ConsumeToken(); |
| 4546 } | 4562 } |
| 4547 ExpectToken(Token::kLBRACE); | 4563 ExpectToken(Token::kLBRACE); |
| 4548 while (CurrentToken() != Token::kRBRACE) { | 4564 while (CurrentToken() != Token::kRBRACE) { |
| 4549 intptr_t metadata_pos = SkipMetadata(); | 4565 TokenDescriptor metadata_pos = SkipMetadata(); |
| 4550 ParseClassMemberDefinition(&members, metadata_pos); | 4566 ParseClassMemberDefinition(&members, metadata_pos); |
| 4551 } | 4567 } |
| 4552 ExpectToken(Token::kRBRACE); | 4568 ExpectToken(Token::kRBRACE); |
| 4553 | 4569 |
| 4554 CheckConstructors(&members); | 4570 CheckConstructors(&members); |
| 4555 | 4571 |
| 4556 // Need to compute this here since MakeArray() will clear the | 4572 // Need to compute this here since MakeArray() will clear the |
| 4557 // functions array in members. | 4573 // functions array in members. |
| 4558 const bool need_implicit_constructor = | 4574 const bool need_implicit_constructor = |
| 4559 !members.has_constructor() && !cls.is_patch(); | 4575 !members.has_constructor() && !cls.is_patch(); |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4818 ctors.Add(member); | 4834 ctors.Add(member); |
| 4819 member = class_desc->LookupMember(*member->redirect_name); | 4835 member = class_desc->LookupMember(*member->redirect_name); |
| 4820 } | 4836 } |
| 4821 } | 4837 } |
| 4822 } | 4838 } |
| 4823 | 4839 |
| 4824 | 4840 |
| 4825 void Parser::ParseMixinAppAlias( | 4841 void Parser::ParseMixinAppAlias( |
| 4826 const GrowableObjectArray& pending_classes, | 4842 const GrowableObjectArray& pending_classes, |
| 4827 const Object& tl_owner, | 4843 const Object& tl_owner, |
| 4828 intptr_t metadata_pos) { | 4844 TokenDescriptor metadata_pos) { |
| 4829 TRACE_PARSER("ParseMixinAppAlias"); | 4845 TRACE_PARSER("ParseMixinAppAlias"); |
| 4830 const intptr_t classname_pos = TokenPos(); | 4846 const TokenDescriptor classname_pos = TokenPos(); |
| 4831 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4847 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4832 if (FLAG_trace_parser) { | 4848 if (FLAG_trace_parser) { |
| 4833 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4849 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
| 4834 class_name.ToCString()); | 4850 class_name.ToCString()); |
| 4835 } | 4851 } |
| 4836 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); | 4852 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
| 4837 if (!obj.IsNull()) { | 4853 if (!obj.IsNull()) { |
| 4838 ReportError(classname_pos, "'%s' is already defined", | 4854 ReportError(classname_pos, "'%s' is already defined", |
| 4839 class_name.ToCString()); | 4855 class_name.ToCString()); |
| 4840 } | 4856 } |
| 4841 const Class& mixin_application = | 4857 const Class& mixin_application = |
| 4842 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); | 4858 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); |
| 4843 mixin_application.set_is_mixin_app_alias(); | 4859 mixin_application.set_is_mixin_app_alias(); |
| 4844 library_.AddClass(mixin_application); | 4860 library_.AddClass(mixin_application); |
| 4845 set_current_class(mixin_application); | 4861 set_current_class(mixin_application); |
| 4846 ParseTypeParameters(mixin_application); | 4862 ParseTypeParameters(mixin_application); |
| 4847 | 4863 |
| 4848 ExpectToken(Token::kASSIGN); | 4864 ExpectToken(Token::kASSIGN); |
| 4849 | 4865 |
| 4850 if (CurrentToken() == Token::kABSTRACT) { | 4866 if (CurrentToken() == Token::kABSTRACT) { |
| 4851 mixin_application.set_is_abstract(); | 4867 mixin_application.set_is_abstract(); |
| 4852 ConsumeToken(); | 4868 ConsumeToken(); |
| 4853 } | 4869 } |
| 4854 | 4870 |
| 4855 const intptr_t type_pos = TokenPos(); | 4871 const TokenDescriptor type_pos = TokenPos(); |
| 4856 AbstractType& type = | 4872 AbstractType& type = |
| 4857 AbstractType::Handle(Z, | 4873 AbstractType::Handle(Z, |
| 4858 ParseType(ClassFinalizer::kResolveTypeParameters)); | 4874 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 4859 if (type.IsTypeParameter()) { | 4875 if (type.IsTypeParameter()) { |
| 4860 ReportError(type_pos, | 4876 ReportError(type_pos, |
| 4861 "class '%s' may not extend type parameter '%s'", | 4877 "class '%s' may not extend type parameter '%s'", |
| 4862 class_name.ToCString(), | 4878 class_name.ToCString(), |
| 4863 String::Handle(Z, type.UserVisibleName()).ToCString()); | 4879 String::Handle(Z, type.UserVisibleName()).ToCString()); |
| 4864 } | 4880 } |
| 4865 | 4881 |
| 4866 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 4882 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
| 4867 type = ParseMixins(type); | 4883 type = ParseMixins(type); |
| 4868 | 4884 |
| 4869 mixin_application.set_super_type(type); | 4885 mixin_application.set_super_type(type); |
| 4870 mixin_application.set_is_synthesized_class(); | 4886 mixin_application.set_is_synthesized_class(); |
| 4871 | 4887 |
| 4872 // This mixin application alias needs an implicit constructor, but it is | 4888 // This mixin application alias needs an implicit constructor, but it is |
| 4873 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4889 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| 4874 // because this class should be lazily compiled. | 4890 // because this class should be lazily compiled. |
| 4875 if (CurrentToken() == Token::kIMPLEMENTS) { | 4891 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 4876 ParseInterfaceList(mixin_application); | 4892 ParseInterfaceList(mixin_application); |
| 4877 } | 4893 } |
| 4878 ExpectSemicolon(); | 4894 ExpectSemicolon(); |
| 4879 pending_classes.Add(mixin_application, Heap::kOld); | 4895 pending_classes.Add(mixin_application, Heap::kOld); |
| 4880 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 4896 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 4881 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); | 4897 library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos); |
| 4882 } | 4898 } |
| 4883 } | 4899 } |
| 4884 | 4900 |
| 4885 | 4901 |
| 4886 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 4902 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 4887 // We need this lookahead to distinguish between the optional return type | 4903 // We need this lookahead to distinguish between the optional return type |
| 4888 // and the alias name of a function type alias. | 4904 // and the alias name of a function type alias. |
| 4889 // Token position remains unchanged. | 4905 // Token position remains unchanged. |
| 4890 bool Parser::IsFunctionTypeAliasName() { | 4906 bool Parser::IsFunctionTypeAliasName() { |
| 4891 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4907 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 4892 return true; | 4908 return true; |
| 4893 } | 4909 } |
| 4894 const intptr_t saved_pos = TokenPos(); | 4910 const TokenDescriptor saved_pos = TokenPos(); |
| 4895 bool is_alias_name = false; | 4911 bool is_alias_name = false; |
| 4896 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 4912 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 4897 ConsumeToken(); | 4913 ConsumeToken(); |
| 4898 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) { | 4914 if (TryParseTypeParameters() && (CurrentToken() == Token::kLPAREN)) { |
| 4899 is_alias_name = true; | 4915 is_alias_name = true; |
| 4900 } | 4916 } |
| 4901 } | 4917 } |
| 4902 SetPosition(saved_pos); | 4918 SetPosition(saved_pos); |
| 4903 return is_alias_name; | 4919 return is_alias_name; |
| 4904 } | 4920 } |
| 4905 | 4921 |
| 4906 | 4922 |
| 4907 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". | 4923 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=". |
| 4908 // Token position remains unchanged. | 4924 // Token position remains unchanged. |
| 4909 bool Parser::IsMixinAppAlias() { | 4925 bool Parser::IsMixinAppAlias() { |
| 4910 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { | 4926 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) { |
| 4911 return true; | 4927 return true; |
| 4912 } | 4928 } |
| 4913 const intptr_t saved_pos = TokenPos(); | 4929 const TokenDescriptor saved_pos = TokenPos(); |
| 4914 bool is_mixin_def = false; | 4930 bool is_mixin_def = false; |
| 4915 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 4931 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 4916 ConsumeToken(); | 4932 ConsumeToken(); |
| 4917 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { | 4933 if (TryParseTypeParameters() && (CurrentToken() == Token::kASSIGN)) { |
| 4918 is_mixin_def = true; | 4934 is_mixin_def = true; |
| 4919 } | 4935 } |
| 4920 } | 4936 } |
| 4921 SetPosition(saved_pos); | 4937 SetPosition(saved_pos); |
| 4922 return is_mixin_def; | 4938 return is_mixin_def; |
| 4923 } | 4939 } |
| 4924 | 4940 |
| 4925 | 4941 |
| 4926 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, | 4942 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes, |
| 4927 const Object& tl_owner, | 4943 const Object& tl_owner, |
| 4928 intptr_t metadata_pos) { | 4944 TokenDescriptor metadata_pos) { |
| 4929 TRACE_PARSER("ParseTypedef"); | 4945 TRACE_PARSER("ParseTypedef"); |
| 4930 intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos(); | 4946 TokenDescriptor declaration_pos = |
| 4947 metadata_pos.IsReal() ? metadata_pos : TokenPos(); |
| 4931 ExpectToken(Token::kTYPEDEF); | 4948 ExpectToken(Token::kTYPEDEF); |
| 4932 | 4949 |
| 4933 if (IsMixinAppAlias()) { | 4950 if (IsMixinAppAlias()) { |
| 4934 if (FLAG_warn_mixin_typedef) { | 4951 if (FLAG_warn_mixin_typedef) { |
| 4935 ReportWarning(TokenPos(), "deprecated mixin application typedef"); | 4952 ReportWarning(TokenPos(), "deprecated mixin application typedef"); |
| 4936 } | 4953 } |
| 4937 ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos); | 4954 ParseMixinAppAlias(pending_classes, tl_owner, metadata_pos); |
| 4938 return; | 4955 return; |
| 4939 } | 4956 } |
| 4940 | 4957 |
| 4941 // Parse the result type of the function type. | 4958 // Parse the result type of the function type. |
| 4942 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 4959 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
| 4943 if (CurrentToken() == Token::kVOID) { | 4960 if (CurrentToken() == Token::kVOID) { |
| 4944 ConsumeToken(); | 4961 ConsumeToken(); |
| 4945 result_type = Type::VoidType(); | 4962 result_type = Type::VoidType(); |
| 4946 } else if (!IsFunctionTypeAliasName()) { | 4963 } else if (!IsFunctionTypeAliasName()) { |
| 4947 // Type annotations in typedef are never ignored, even in production mode. | 4964 // Type annotations in typedef are never ignored, even in production mode. |
| 4948 // Wait until we have an owner class before resolving the result type. | 4965 // Wait until we have an owner class before resolving the result type. |
| 4949 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 4966 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 4950 } | 4967 } |
| 4951 | 4968 |
| 4952 const intptr_t alias_name_pos = TokenPos(); | 4969 const TokenDescriptor alias_name_pos = TokenPos(); |
| 4953 const String* alias_name = | 4970 const String* alias_name = |
| 4954 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 4971 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
| 4955 | 4972 |
| 4956 // Lookup alias name and report an error if it is already defined in | 4973 // Lookup alias name and report an error if it is already defined in |
| 4957 // the library scope. | 4974 // the library scope. |
| 4958 const Object& obj = | 4975 const Object& obj = |
| 4959 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); | 4976 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); |
| 4960 if (!obj.IsNull()) { | 4977 if (!obj.IsNull()) { |
| 4961 ReportError(alias_name_pos, | 4978 ReportError(alias_name_pos, |
| 4962 "'%s' is already defined", alias_name->ToCString()); | 4979 "'%s' is already defined", alias_name->ToCString()); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5005 function_type_alias.set_signature_function(signature_function); | 5022 function_type_alias.set_signature_function(signature_function); |
| 5006 | 5023 |
| 5007 if (FLAG_trace_parser) { | 5024 if (FLAG_trace_parser) { |
| 5008 OS::Print("TopLevel parsing function type alias '%s'\n", | 5025 OS::Print("TopLevel parsing function type alias '%s'\n", |
| 5009 String::Handle(Z, signature_function.Signature()).ToCString()); | 5026 String::Handle(Z, signature_function.Signature()).ToCString()); |
| 5010 } | 5027 } |
| 5011 // The alias should not be marked as finalized yet, since it needs to be | 5028 // The alias should not be marked as finalized yet, since it needs to be |
| 5012 // checked in the class finalizer for illegal self references. | 5029 // checked in the class finalizer for illegal self references. |
| 5013 ASSERT(!function_type_alias.is_finalized()); | 5030 ASSERT(!function_type_alias.is_finalized()); |
| 5014 pending_classes.Add(function_type_alias, Heap::kOld); | 5031 pending_classes.Add(function_type_alias, Heap::kOld); |
| 5015 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5032 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5016 library_.AddClassMetadata(function_type_alias, | 5033 library_.AddClassMetadata(function_type_alias, |
| 5017 tl_owner, | 5034 tl_owner, |
| 5018 metadata_pos); | 5035 metadata_pos); |
| 5019 } | 5036 } |
| 5020 } | 5037 } |
| 5021 | 5038 |
| 5022 | 5039 |
| 5023 // Consumes exactly one right angle bracket. If the current token is a single | 5040 // Consumes exactly one right angle bracket. If the current token is a single |
| 5024 // bracket token, it is consumed normally. However, if it is a double or triple | 5041 // bracket token, it is consumed normally. However, if it is a double or triple |
| 5025 // bracket, it is replaced by a single or double bracket token without | 5042 // bracket, it is replaced by a single or double bracket token without |
| 5026 // incrementing the token index. | 5043 // incrementing the token index. |
| 5027 void Parser::ConsumeRightAngleBracket() { | 5044 void Parser::ConsumeRightAngleBracket() { |
| 5028 if (token_kind_ == Token::kGT) { | 5045 if (token_kind_ == Token::kGT) { |
| 5029 ConsumeToken(); | 5046 ConsumeToken(); |
| 5030 } else if (token_kind_ == Token::kSHR) { | 5047 } else if (token_kind_ == Token::kSHR) { |
| 5031 token_kind_ = Token::kGT; | 5048 token_kind_ = Token::kGT; |
| 5032 } else { | 5049 } else { |
| 5033 UNREACHABLE(); | 5050 UNREACHABLE(); |
| 5034 } | 5051 } |
| 5035 } | 5052 } |
| 5036 | 5053 |
| 5037 | 5054 |
| 5038 intptr_t Parser::SkipMetadata() { | 5055 TokenDescriptor Parser::SkipMetadata() { |
| 5039 if (CurrentToken() != Token::kAT) { | 5056 if (CurrentToken() != Token::kAT) { |
| 5040 return Token::kNoSourcePos; | 5057 return TokenDescriptor::kNoSource; |
| 5041 } | 5058 } |
| 5042 intptr_t metadata_pos = TokenPos(); | 5059 TokenDescriptor metadata_pos = TokenPos(); |
| 5043 while (CurrentToken() == Token::kAT) { | 5060 while (CurrentToken() == Token::kAT) { |
| 5044 ConsumeToken(); | 5061 ConsumeToken(); |
| 5045 ExpectIdentifier("identifier expected"); | 5062 ExpectIdentifier("identifier expected"); |
| 5046 if (CurrentToken() == Token::kPERIOD) { | 5063 if (CurrentToken() == Token::kPERIOD) { |
| 5047 ConsumeToken(); | 5064 ConsumeToken(); |
| 5048 ExpectIdentifier("identifier expected"); | 5065 ExpectIdentifier("identifier expected"); |
| 5049 if (CurrentToken() == Token::kPERIOD) { | 5066 if (CurrentToken() == Token::kPERIOD) { |
| 5050 ConsumeToken(); | 5067 ConsumeToken(); |
| 5051 ExpectIdentifier("identifier expected"); | 5068 ExpectIdentifier("identifier expected"); |
| 5052 } | 5069 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5096 TRACE_PARSER("ParseTypeParameters"); | 5113 TRACE_PARSER("ParseTypeParameters"); |
| 5097 if (CurrentToken() == Token::kLT) { | 5114 if (CurrentToken() == Token::kLT) { |
| 5098 GrowableArray<AbstractType*> type_parameters_array(Z, 2); | 5115 GrowableArray<AbstractType*> type_parameters_array(Z, 2); |
| 5099 intptr_t index = 0; | 5116 intptr_t index = 0; |
| 5100 TypeParameter& type_parameter = TypeParameter::Handle(Z); | 5117 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
| 5101 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); | 5118 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
| 5102 String& existing_type_parameter_name = String::Handle(Z); | 5119 String& existing_type_parameter_name = String::Handle(Z); |
| 5103 AbstractType& type_parameter_bound = Type::Handle(Z); | 5120 AbstractType& type_parameter_bound = Type::Handle(Z); |
| 5104 do { | 5121 do { |
| 5105 ConsumeToken(); | 5122 ConsumeToken(); |
| 5106 const intptr_t metadata_pos = SkipMetadata(); | 5123 const TokenDescriptor metadata_pos = SkipMetadata(); |
| 5107 const intptr_t type_parameter_pos = TokenPos(); | 5124 const TokenDescriptor type_parameter_pos = TokenPos(); |
| 5108 const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos | 5125 const TokenDescriptor declaration_pos = |
| 5109 : type_parameter_pos; | 5126 metadata_pos.IsReal() ? metadata_pos : type_parameter_pos; |
| 5110 String& type_parameter_name = | 5127 String& type_parameter_name = |
| 5111 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 5128 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
| 5112 // Check for duplicate type parameters. | 5129 // Check for duplicate type parameters. |
| 5113 for (intptr_t i = 0; i < index; i++) { | 5130 for (intptr_t i = 0; i < index; i++) { |
| 5114 existing_type_parameter ^= type_parameters_array.At(i)->raw(); | 5131 existing_type_parameter ^= type_parameters_array.At(i)->raw(); |
| 5115 existing_type_parameter_name = existing_type_parameter.name(); | 5132 existing_type_parameter_name = existing_type_parameter.name(); |
| 5116 if (existing_type_parameter_name.Equals(type_parameter_name)) { | 5133 if (existing_type_parameter_name.Equals(type_parameter_name)) { |
| 5117 ReportError(type_parameter_pos, "duplicate type parameter '%s'", | 5134 ReportError(type_parameter_pos, "duplicate type parameter '%s'", |
| 5118 type_parameter_name.ToCString()); | 5135 type_parameter_name.ToCString()); |
| 5119 } | 5136 } |
| 5120 } | 5137 } |
| 5121 if (CurrentToken() == Token::kEXTENDS) { | 5138 if (CurrentToken() == Token::kEXTENDS) { |
| 5122 ConsumeToken(); | 5139 ConsumeToken(); |
| 5123 // A bound may refer to the owner of the type parameter it applies to, | 5140 // A bound may refer to the owner of the type parameter it applies to, |
| 5124 // i.e. to the class or interface currently being parsed. | 5141 // i.e. to the class or interface currently being parsed. |
| 5125 // Postpone resolution in order to avoid resolving the class and its | 5142 // Postpone resolution in order to avoid resolving the class and its |
| 5126 // type parameters, as they are not fully parsed yet. | 5143 // type parameters, as they are not fully parsed yet. |
| 5127 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); | 5144 type_parameter_bound = ParseType(ClassFinalizer::kDoNotResolve); |
| 5128 } else { | 5145 } else { |
| 5129 type_parameter_bound = I->object_store()->object_type(); | 5146 type_parameter_bound = I->object_store()->object_type(); |
| 5130 } | 5147 } |
| 5131 type_parameter = TypeParameter::New(cls, | 5148 type_parameter = TypeParameter::New(cls, |
| 5132 index, | 5149 index, |
| 5133 type_parameter_name, | 5150 type_parameter_name, |
| 5134 type_parameter_bound, | 5151 type_parameter_bound, |
| 5135 declaration_pos); | 5152 declaration_pos); |
| 5136 type_parameters_array.Add( | 5153 type_parameters_array.Add( |
| 5137 &AbstractType::ZoneHandle(Z, type_parameter.raw())); | 5154 &AbstractType::ZoneHandle(Z, type_parameter.raw())); |
| 5138 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5155 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5139 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); | 5156 library_.AddTypeParameterMetadata(type_parameter, metadata_pos); |
| 5140 } | 5157 } |
| 5141 index++; | 5158 index++; |
| 5142 } while (CurrentToken() == Token::kCOMMA); | 5159 } while (CurrentToken() == Token::kCOMMA); |
| 5143 Token::Kind token = CurrentToken(); | 5160 Token::Kind token = CurrentToken(); |
| 5144 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5161 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 5145 ConsumeRightAngleBracket(); | 5162 ConsumeRightAngleBracket(); |
| 5146 } else { | 5163 } else { |
| 5147 ReportError("right angle bracket expected"); | 5164 ReportError("right angle bracket expected"); |
| 5148 } | 5165 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5203 AbstractType& interface = AbstractType::Handle(Z); | 5220 AbstractType& interface = AbstractType::Handle(Z); |
| 5204 // First get all the interfaces already implemented by class. | 5221 // First get all the interfaces already implemented by class. |
| 5205 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); | 5222 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); |
| 5206 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 5223 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 5207 interface ^= cls_interfaces.At(i); | 5224 interface ^= cls_interfaces.At(i); |
| 5208 all_interfaces.Add(interface); | 5225 all_interfaces.Add(interface); |
| 5209 } | 5226 } |
| 5210 // Now parse and add the new interfaces. | 5227 // Now parse and add the new interfaces. |
| 5211 do { | 5228 do { |
| 5212 ConsumeToken(); | 5229 ConsumeToken(); |
| 5213 intptr_t interface_pos = TokenPos(); | 5230 TokenDescriptor interface_pos = TokenPos(); |
| 5214 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 5231 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 5215 if (interface.IsTypeParameter()) { | 5232 if (interface.IsTypeParameter()) { |
| 5216 ReportError(interface_pos, | 5233 ReportError(interface_pos, |
| 5217 "type parameter '%s' may not be used in interface list", | 5234 "type parameter '%s' may not be used in interface list", |
| 5218 String::Handle(Z, interface.UserVisibleName()).ToCString()); | 5235 String::Handle(Z, interface.UserVisibleName()).ToCString()); |
| 5219 } | 5236 } |
| 5220 all_interfaces.Add(interface); | 5237 all_interfaces.Add(interface); |
| 5221 } while (CurrentToken() == Token::kCOMMA); | 5238 } while (CurrentToken() == Token::kCOMMA); |
| 5222 cls_interfaces = Array::MakeArray(all_interfaces); | 5239 cls_interfaces = Array::MakeArray(all_interfaces); |
| 5223 cls.set_interfaces(cls_interfaces); | 5240 cls.set_interfaces(cls_interfaces); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5245 } | 5262 } |
| 5246 mixin_types.Add(mixin_type); | 5263 mixin_types.Add(mixin_type); |
| 5247 } while (CurrentToken() == Token::kCOMMA); | 5264 } while (CurrentToken() == Token::kCOMMA); |
| 5248 return MixinAppType::New(super_type, | 5265 return MixinAppType::New(super_type, |
| 5249 Array::Handle(Z, Array::MakeArray(mixin_types))); | 5266 Array::Handle(Z, Array::MakeArray(mixin_types))); |
| 5250 } | 5267 } |
| 5251 | 5268 |
| 5252 | 5269 |
| 5253 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 5270 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
| 5254 const Object& owner, | 5271 const Object& owner, |
| 5255 intptr_t metadata_pos) { | 5272 TokenDescriptor metadata_pos) { |
| 5256 TRACE_PARSER("ParseTopLevelVariable"); | 5273 TRACE_PARSER("ParseTopLevelVariable"); |
| 5257 const bool is_const = (CurrentToken() == Token::kCONST); | 5274 const bool is_const = (CurrentToken() == Token::kCONST); |
| 5258 // Const fields are implicitly final. | 5275 // Const fields are implicitly final. |
| 5259 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 5276 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 5260 const bool is_static = true; | 5277 const bool is_static = true; |
| 5261 const AbstractType& type = AbstractType::ZoneHandle(Z, | 5278 const AbstractType& type = AbstractType::ZoneHandle(Z, |
| 5262 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 5279 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
| 5263 Field& field = Field::Handle(Z); | 5280 Field& field = Field::Handle(Z); |
| 5264 Function& getter = Function::Handle(Z); | 5281 Function& getter = Function::Handle(Z); |
| 5265 while (true) { | 5282 while (true) { |
| 5266 const intptr_t name_pos = TokenPos(); | 5283 const TokenDescriptor name_pos = TokenPos(); |
| 5267 String& var_name = *ExpectIdentifier("variable name expected"); | 5284 String& var_name = *ExpectIdentifier("variable name expected"); |
| 5268 | 5285 |
| 5269 if (library_.LookupLocalObject(var_name) != Object::null()) { | 5286 if (library_.LookupLocalObject(var_name) != Object::null()) { |
| 5270 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); | 5287 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 5271 } | 5288 } |
| 5272 | 5289 |
| 5273 // Check whether a getter or setter for this name exists. A const | 5290 // Check whether a getter or setter for this name exists. A const |
| 5274 // or final field implies a setter which throws a NoSuchMethodError, | 5291 // or final field implies a setter which throws a NoSuchMethodError, |
| 5275 // thus we need to check for conflicts with existing setters and | 5292 // thus we need to check for conflicts with existing setters and |
| 5276 // getters. | 5293 // getters. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5287 | 5304 |
| 5288 const bool is_reflectable = | 5305 const bool is_reflectable = |
| 5289 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); | 5306 !(library_.is_dart_scheme() && library_.IsPrivate(var_name)); |
| 5290 | 5307 |
| 5291 field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos); | 5308 field = Field::NewTopLevel(var_name, is_final, is_const, owner, name_pos); |
| 5292 field.SetFieldType(type); | 5309 field.SetFieldType(type); |
| 5293 field.set_is_reflectable(is_reflectable); | 5310 field.set_is_reflectable(is_reflectable); |
| 5294 field.SetStaticValue(Object::null_instance(), true); | 5311 field.SetStaticValue(Object::null_instance(), true); |
| 5295 top_level->AddField(field); | 5312 top_level->AddField(field); |
| 5296 library_.AddObject(field, var_name); | 5313 library_.AddObject(field, var_name); |
| 5297 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5314 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5298 library_.AddFieldMetadata(field, metadata_pos); | 5315 library_.AddFieldMetadata(field, metadata_pos); |
| 5299 } | 5316 } |
| 5300 if (CurrentToken() == Token::kASSIGN) { | 5317 if (CurrentToken() == Token::kASSIGN) { |
| 5301 ConsumeToken(); | 5318 ConsumeToken(); |
| 5302 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); | 5319 Instance& field_value = Instance::Handle(Z, Object::sentinel().raw()); |
| 5303 bool has_simple_literal = false; | 5320 bool has_simple_literal = false; |
| 5304 if (LookaheadToken(1) == Token::kSEMICOLON) { | 5321 if (LookaheadToken(1) == Token::kSEMICOLON) { |
| 5305 has_simple_literal = IsSimpleLiteral(type, &field_value); | 5322 has_simple_literal = IsSimpleLiteral(type, &field_value); |
| 5306 } | 5323 } |
| 5307 SkipExpr(); | 5324 SkipExpr(); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5363 ConsumeToken(); | 5380 ConsumeToken(); |
| 5364 ConsumeToken(); | 5381 ConsumeToken(); |
| 5365 return RawFunction::kSyncGen; | 5382 return RawFunction::kSyncGen; |
| 5366 } | 5383 } |
| 5367 return RawFunction::kNoModifier; | 5384 return RawFunction::kNoModifier; |
| 5368 } | 5385 } |
| 5369 | 5386 |
| 5370 | 5387 |
| 5371 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5388 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
| 5372 const Object& owner, | 5389 const Object& owner, |
| 5373 intptr_t metadata_pos) { | 5390 TokenDescriptor metadata_pos) { |
| 5374 TRACE_PARSER("ParseTopLevelFunction"); | 5391 TRACE_PARSER("ParseTopLevelFunction"); |
| 5375 const intptr_t decl_begin_pos = TokenPos(); | 5392 const TokenDescriptor decl_begin_pos = TokenPos(); |
| 5376 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); | 5393 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
| 5377 const bool is_static = true; | 5394 const bool is_static = true; |
| 5378 bool is_external = false; | 5395 bool is_external = false; |
| 5379 bool is_patch = false; | 5396 bool is_patch = false; |
| 5380 if (is_patch_source() && | 5397 if (is_patch_source() && |
| 5381 (CurrentToken() == Token::kIDENT) && | 5398 (CurrentToken() == Token::kIDENT) && |
| 5382 CurrentLiteral()->Equals("patch") && | 5399 CurrentLiteral()->Equals("patch") && |
| 5383 (LookaheadToken(1) != Token::kLPAREN)) { | 5400 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5384 ConsumeToken(); | 5401 ConsumeToken(); |
| 5385 is_patch = true; | 5402 is_patch = true; |
| 5386 } else if (CurrentToken() == Token::kEXTERNAL) { | 5403 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 5387 ConsumeToken(); | 5404 ConsumeToken(); |
| 5388 is_external = true; | 5405 is_external = true; |
| 5389 } | 5406 } |
| 5390 if (CurrentToken() == Token::kVOID) { | 5407 if (CurrentToken() == Token::kVOID) { |
| 5391 ConsumeToken(); | 5408 ConsumeToken(); |
| 5392 result_type = Type::VoidType(); | 5409 result_type = Type::VoidType(); |
| 5393 } else { | 5410 } else { |
| 5394 // Parse optional type. | 5411 // Parse optional type. |
| 5395 if ((CurrentToken() == Token::kIDENT) && | 5412 if ((CurrentToken() == Token::kIDENT) && |
| 5396 (LookaheadToken(1) != Token::kLPAREN)) { | 5413 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5397 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5414 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 5398 } | 5415 } |
| 5399 } | 5416 } |
| 5400 const intptr_t name_pos = TokenPos(); | 5417 const TokenDescriptor name_pos = TokenPos(); |
| 5401 const String& func_name = *ExpectIdentifier("function name expected"); | 5418 const String& func_name = *ExpectIdentifier("function name expected"); |
| 5402 | 5419 |
| 5403 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 5420 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
| 5404 if (found && !is_patch) { | 5421 if (found && !is_patch) { |
| 5405 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); | 5422 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 5406 } else if (!found && is_patch) { | 5423 } else if (!found && is_patch) { |
| 5407 ReportError(name_pos, "missing '%s' cannot be patched", | 5424 ReportError(name_pos, "missing '%s' cannot be patched", |
| 5408 func_name.ToCString()); | 5425 func_name.ToCString()); |
| 5409 } | 5426 } |
| 5410 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); | 5427 String& accessor_name = String::Handle(Z, Field::GetterName(func_name)); |
| 5411 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5428 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 5412 ReportError(name_pos, "'%s' is already defined as getter", | 5429 ReportError(name_pos, "'%s' is already defined as getter", |
| 5413 func_name.ToCString()); | 5430 func_name.ToCString()); |
| 5414 } | 5431 } |
| 5415 // A setter named x= may co-exist with a function named x, thus we do | 5432 // A setter named x= may co-exist with a function named x, thus we do |
| 5416 // not need to check setters. | 5433 // not need to check setters. |
| 5417 | 5434 |
| 5418 CheckToken(Token::kLPAREN); | 5435 CheckToken(Token::kLPAREN); |
| 5419 const intptr_t function_pos = TokenPos(); | 5436 const TokenDescriptor function_pos = TokenPos(); |
| 5420 ParamList params; | 5437 ParamList params; |
| 5421 const bool allow_explicit_default_values = true; | 5438 const bool allow_explicit_default_values = true; |
| 5422 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5439 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 5423 | 5440 |
| 5424 const intptr_t modifier_pos = TokenPos(); | 5441 const TokenDescriptor modifier_pos = TokenPos(); |
| 5425 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5442 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
| 5426 | 5443 |
| 5427 intptr_t function_end_pos = function_pos; | 5444 TokenDescriptor function_end_pos = function_pos; |
| 5428 bool is_native = false; | 5445 bool is_native = false; |
| 5429 String* native_name = NULL; | 5446 String* native_name = NULL; |
| 5430 if (is_external) { | 5447 if (is_external) { |
| 5431 function_end_pos = TokenPos(); | 5448 function_end_pos = TokenPos(); |
| 5432 ExpectSemicolon(); | 5449 ExpectSemicolon(); |
| 5433 } else if (CurrentToken() == Token::kLBRACE) { | 5450 } else if (CurrentToken() == Token::kLBRACE) { |
| 5434 SkipBlock(); | 5451 SkipBlock(); |
| 5435 function_end_pos = TokenPos(); | 5452 function_end_pos = TokenPos(); |
| 5436 ExpectToken(Token::kRBRACE); | 5453 ExpectToken(Token::kRBRACE); |
| 5437 } else if (CurrentToken() == Token::kARROW) { | 5454 } else if (CurrentToken() == Token::kARROW) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5478 library_.AddObject(func, func_name); | 5495 library_.AddObject(func, func_name); |
| 5479 } else { | 5496 } else { |
| 5480 // Need to remove the previously added function that is being patched. | 5497 // Need to remove the previously added function that is being patched. |
| 5481 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); | 5498 const Class& toplevel_cls = Class::Handle(Z, library_.toplevel_class()); |
| 5482 const Function& replaced_func = | 5499 const Function& replaced_func = |
| 5483 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); | 5500 Function::Handle(Z, toplevel_cls.LookupStaticFunction(func_name)); |
| 5484 ASSERT(!replaced_func.IsNull()); | 5501 ASSERT(!replaced_func.IsNull()); |
| 5485 toplevel_cls.RemoveFunction(replaced_func); | 5502 toplevel_cls.RemoveFunction(replaced_func); |
| 5486 library_.ReplaceObject(func, func_name); | 5503 library_.ReplaceObject(func, func_name); |
| 5487 } | 5504 } |
| 5488 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5505 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5489 library_.AddFunctionMetadata(func, metadata_pos); | 5506 library_.AddFunctionMetadata(func, metadata_pos); |
| 5490 } | 5507 } |
| 5491 } | 5508 } |
| 5492 | 5509 |
| 5493 | 5510 |
| 5494 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 5511 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
| 5495 const Object& owner, | 5512 const Object& owner, |
| 5496 intptr_t metadata_pos) { | 5513 TokenDescriptor metadata_pos) { |
| 5497 TRACE_PARSER("ParseTopLevelAccessor"); | 5514 TRACE_PARSER("ParseTopLevelAccessor"); |
| 5498 const intptr_t decl_begin_pos = TokenPos(); | 5515 const TokenDescriptor decl_begin_pos = TokenPos(); |
| 5499 const bool is_static = true; | 5516 const bool is_static = true; |
| 5500 bool is_external = false; | 5517 bool is_external = false; |
| 5501 bool is_patch = false; | 5518 bool is_patch = false; |
| 5502 AbstractType& result_type = AbstractType::Handle(Z); | 5519 AbstractType& result_type = AbstractType::Handle(Z); |
| 5503 if (is_patch_source() && | 5520 if (is_patch_source() && |
| 5504 (CurrentToken() == Token::kIDENT) && | 5521 (CurrentToken() == Token::kIDENT) && |
| 5505 CurrentLiteral()->Equals("patch")) { | 5522 CurrentLiteral()->Equals("patch")) { |
| 5506 ConsumeToken(); | 5523 ConsumeToken(); |
| 5507 is_patch = true; | 5524 is_patch = true; |
| 5508 } else if (CurrentToken() == Token::kEXTERNAL) { | 5525 } else if (CurrentToken() == Token::kEXTERNAL) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 5521 } else { | 5538 } else { |
| 5522 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5539 result_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 5523 } | 5540 } |
| 5524 is_getter = (CurrentToken() == Token::kGET); | 5541 is_getter = (CurrentToken() == Token::kGET); |
| 5525 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { | 5542 if (CurrentToken() == Token::kGET || CurrentToken() == Token::kSET) { |
| 5526 ConsumeToken(); | 5543 ConsumeToken(); |
| 5527 } else { | 5544 } else { |
| 5528 UnexpectedToken(); | 5545 UnexpectedToken(); |
| 5529 } | 5546 } |
| 5530 } | 5547 } |
| 5531 const intptr_t name_pos = TokenPos(); | 5548 const TokenDescriptor name_pos = TokenPos(); |
| 5532 const String* field_name = ExpectIdentifier("accessor name expected"); | 5549 const String* field_name = ExpectIdentifier("accessor name expected"); |
| 5533 | 5550 |
| 5534 const intptr_t accessor_pos = TokenPos(); | 5551 const TokenDescriptor accessor_pos = TokenPos(); |
| 5535 ParamList params; | 5552 ParamList params; |
| 5536 | 5553 |
| 5537 if (!is_getter) { | 5554 if (!is_getter) { |
| 5538 const bool allow_explicit_default_values = true; | 5555 const bool allow_explicit_default_values = true; |
| 5539 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5556 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 5540 } | 5557 } |
| 5541 String& accessor_name = String::ZoneHandle(Z); | 5558 String& accessor_name = String::ZoneHandle(Z); |
| 5542 int expected_num_parameters = -1; | 5559 int expected_num_parameters = -1; |
| 5543 if (is_getter) { | 5560 if (is_getter) { |
| 5544 expected_num_parameters = 0; | 5561 expected_num_parameters = 0; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 5571 if (found && !is_patch) { | 5588 if (found && !is_patch) { |
| 5572 ReportError(name_pos, "%s for '%s' is already defined", | 5589 ReportError(name_pos, "%s for '%s' is already defined", |
| 5573 is_getter ? "getter" : "setter", | 5590 is_getter ? "getter" : "setter", |
| 5574 field_name->ToCString()); | 5591 field_name->ToCString()); |
| 5575 } else if (!found && is_patch) { | 5592 } else if (!found && is_patch) { |
| 5576 ReportError(name_pos, "missing %s for '%s' cannot be patched", | 5593 ReportError(name_pos, "missing %s for '%s' cannot be patched", |
| 5577 is_getter ? "getter" : "setter", | 5594 is_getter ? "getter" : "setter", |
| 5578 field_name->ToCString()); | 5595 field_name->ToCString()); |
| 5579 } | 5596 } |
| 5580 | 5597 |
| 5581 const intptr_t modifier_pos = TokenPos(); | 5598 const TokenDescriptor modifier_pos = TokenPos(); |
| 5582 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 5599 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
| 5583 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { | 5600 if (!is_getter && (func_modifier != RawFunction::kNoModifier)) { |
| 5584 ReportError(modifier_pos, | 5601 ReportError(modifier_pos, |
| 5585 "setter function cannot be async, async* or sync*"); | 5602 "setter function cannot be async, async* or sync*"); |
| 5586 } | 5603 } |
| 5587 | 5604 |
| 5588 intptr_t accessor_end_pos = accessor_pos; | 5605 TokenDescriptor accessor_end_pos = accessor_pos; |
| 5589 bool is_native = false; | 5606 bool is_native = false; |
| 5590 String* native_name = NULL; | 5607 String* native_name = NULL; |
| 5591 if (is_external) { | 5608 if (is_external) { |
| 5592 accessor_end_pos = TokenPos(); | 5609 accessor_end_pos = TokenPos(); |
| 5593 ExpectSemicolon(); | 5610 ExpectSemicolon(); |
| 5594 } else if (CurrentToken() == Token::kLBRACE) { | 5611 } else if (CurrentToken() == Token::kLBRACE) { |
| 5595 SkipBlock(); | 5612 SkipBlock(); |
| 5596 accessor_end_pos = TokenPos(); | 5613 accessor_end_pos = TokenPos(); |
| 5597 ExpectToken(Token::kRBRACE); | 5614 ExpectToken(Token::kRBRACE); |
| 5598 } else if (CurrentToken() == Token::kARROW) { | 5615 } else if (CurrentToken() == Token::kARROW) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5643 // Need to remove the previously added accessor that is being patched. | 5660 // Need to remove the previously added accessor that is being patched. |
| 5644 const Class& toplevel_cls = Class::Handle(Z, | 5661 const Class& toplevel_cls = Class::Handle(Z, |
| 5645 owner.IsClass() ? Class::Cast(owner).raw() | 5662 owner.IsClass() ? Class::Cast(owner).raw() |
| 5646 : PatchClass::Cast(owner).patched_class()); | 5663 : PatchClass::Cast(owner).patched_class()); |
| 5647 const Function& replaced_func = | 5664 const Function& replaced_func = |
| 5648 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); | 5665 Function::Handle(Z, toplevel_cls.LookupFunction(accessor_name)); |
| 5649 ASSERT(!replaced_func.IsNull()); | 5666 ASSERT(!replaced_func.IsNull()); |
| 5650 toplevel_cls.RemoveFunction(replaced_func); | 5667 toplevel_cls.RemoveFunction(replaced_func); |
| 5651 library_.ReplaceObject(func, accessor_name); | 5668 library_.ReplaceObject(func, accessor_name); |
| 5652 } | 5669 } |
| 5653 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5670 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5654 library_.AddFunctionMetadata(func, metadata_pos); | 5671 library_.AddFunctionMetadata(func, metadata_pos); |
| 5655 } | 5672 } |
| 5656 } | 5673 } |
| 5657 | 5674 |
| 5658 | 5675 |
| 5659 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, | 5676 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag, |
| 5660 intptr_t token_pos, | 5677 TokenDescriptor token_pos, |
| 5661 const String& url) { | 5678 const String& url) { |
| 5662 Dart_LibraryTagHandler handler = I->library_tag_handler(); | 5679 Dart_LibraryTagHandler handler = I->library_tag_handler(); |
| 5663 if (handler == NULL) { | 5680 if (handler == NULL) { |
| 5664 if (url.StartsWith(Symbols::DartScheme())) { | 5681 if (url.StartsWith(Symbols::DartScheme())) { |
| 5665 if (tag == Dart_kCanonicalizeUrl) { | 5682 if (tag == Dart_kCanonicalizeUrl) { |
| 5666 return url.raw(); | 5683 return url.raw(); |
| 5667 } | 5684 } |
| 5668 return Object::null(); | 5685 return Object::null(); |
| 5669 } | 5686 } |
| 5670 ReportError(token_pos, "no library handler registered"); | 5687 ReportError(token_pos, "no library handler registered"); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5721 ConsumeToken(); // Identifier. | 5738 ConsumeToken(); // Identifier. |
| 5722 if (CurrentToken() != Token::kCOMMA) { | 5739 if (CurrentToken() != Token::kCOMMA) { |
| 5723 return; | 5740 return; |
| 5724 } | 5741 } |
| 5725 ConsumeToken(); // Comma. | 5742 ConsumeToken(); // Comma. |
| 5726 } | 5743 } |
| 5727 } | 5744 } |
| 5728 | 5745 |
| 5729 | 5746 |
| 5730 void Parser::ParseLibraryImportExport(const Object& tl_owner, | 5747 void Parser::ParseLibraryImportExport(const Object& tl_owner, |
| 5731 intptr_t metadata_pos) { | 5748 TokenDescriptor metadata_pos) { |
| 5732 bool is_import = (CurrentToken() == Token::kIMPORT); | 5749 bool is_import = (CurrentToken() == Token::kIMPORT); |
| 5733 bool is_export = (CurrentToken() == Token::kEXPORT); | 5750 bool is_export = (CurrentToken() == Token::kEXPORT); |
| 5734 ASSERT(is_import || is_export); | 5751 ASSERT(is_import || is_export); |
| 5735 const intptr_t import_pos = TokenPos(); | 5752 const TokenDescriptor import_pos = TokenPos(); |
| 5736 ConsumeToken(); | 5753 ConsumeToken(); |
| 5737 CheckToken(Token::kSTRING, "library url expected"); | 5754 CheckToken(Token::kSTRING, "library url expected"); |
| 5738 AstNode* url_literal = ParseStringLiteral(false); | 5755 AstNode* url_literal = ParseStringLiteral(false); |
| 5739 if (FLAG_conditional_directives) { | 5756 if (FLAG_conditional_directives) { |
| 5740 bool condition_triggered = false; | 5757 bool condition_triggered = false; |
| 5741 while (CurrentToken() == Token::kIF) { | 5758 while (CurrentToken() == Token::kIF) { |
| 5742 // Conditional import: if (env == val) uri. | 5759 // Conditional import: if (env == val) uri. |
| 5743 ConsumeToken(); | 5760 ConsumeToken(); |
| 5744 ExpectToken(Token::kLPAREN); | 5761 ExpectToken(Token::kLPAREN); |
| 5745 // Parse dotted name. | 5762 // Parse dotted name. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5789 if (url.Length() == 0) { | 5806 if (url.Length() == 0) { |
| 5790 ReportError("library url expected"); | 5807 ReportError("library url expected"); |
| 5791 } | 5808 } |
| 5792 bool is_deferred_import = false; | 5809 bool is_deferred_import = false; |
| 5793 if (is_import && (IsSymbol(Symbols::Deferred()))) { | 5810 if (is_import && (IsSymbol(Symbols::Deferred()))) { |
| 5794 is_deferred_import = true; | 5811 is_deferred_import = true; |
| 5795 ConsumeToken(); | 5812 ConsumeToken(); |
| 5796 CheckToken(Token::kAS, "'as' expected"); | 5813 CheckToken(Token::kAS, "'as' expected"); |
| 5797 } | 5814 } |
| 5798 String& prefix = String::Handle(Z); | 5815 String& prefix = String::Handle(Z); |
| 5799 intptr_t prefix_pos = Token::kNoSourcePos; | 5816 TokenDescriptor prefix_pos = TokenDescriptor::kNoSource; |
| 5800 if (is_import && (CurrentToken() == Token::kAS)) { | 5817 if (is_import && (CurrentToken() == Token::kAS)) { |
| 5801 ConsumeToken(); | 5818 ConsumeToken(); |
| 5802 prefix_pos = TokenPos(); | 5819 prefix_pos = TokenPos(); |
| 5803 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 5820 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
| 5804 } | 5821 } |
| 5805 | 5822 |
| 5806 Array& show_names = Array::Handle(Z); | 5823 Array& show_names = Array::Handle(Z); |
| 5807 Array& hide_names = Array::Handle(Z); | 5824 Array& hide_names = Array::Handle(Z); |
| 5808 if (is_deferred_import || | 5825 if (is_deferred_import || |
| 5809 IsSymbol(Symbols::Show()) || | 5826 IsSymbol(Symbols::Show()) || |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5852 // library import, call the library tag handler to request loading | 5869 // library import, call the library tag handler to request loading |
| 5853 // the library. | 5870 // the library. |
| 5854 if (library.LoadNotStarted() && | 5871 if (library.LoadNotStarted() && |
| 5855 (!is_deferred_import || FLAG_load_deferred_eagerly)) { | 5872 (!is_deferred_import || FLAG_load_deferred_eagerly)) { |
| 5856 library.SetLoadRequested(); | 5873 library.SetLoadRequested(); |
| 5857 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); | 5874 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); |
| 5858 } | 5875 } |
| 5859 | 5876 |
| 5860 Namespace& ns = Namespace::Handle(Z, | 5877 Namespace& ns = Namespace::Handle(Z, |
| 5861 Namespace::New(library, show_names, hide_names)); | 5878 Namespace::New(library, show_names, hide_names)); |
| 5862 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5879 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5863 ns.AddMetadata(tl_owner, metadata_pos); | 5880 ns.AddMetadata(tl_owner, metadata_pos); |
| 5864 } | 5881 } |
| 5865 | 5882 |
| 5866 // Ensure that private dart:_ libraries are only imported into dart: | 5883 // Ensure that private dart:_ libraries are only imported into dart: |
| 5867 // libraries, including indirectly through exports. | 5884 // libraries, including indirectly through exports. |
| 5868 const String& lib_url = String::Handle(Z, library_.url()); | 5885 const String& lib_url = String::Handle(Z, library_.url()); |
| 5869 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 5886 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
| 5870 !lib_url.StartsWith(Symbols::DartScheme())) { | 5887 !lib_url.StartsWith(Symbols::DartScheme())) { |
| 5871 ReportError(import_pos, "private library is not accessible"); | 5888 ReportError(import_pos, "private library is not accessible"); |
| 5872 } | 5889 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 5902 } | 5919 } |
| 5903 } | 5920 } |
| 5904 } else { | 5921 } else { |
| 5905 ASSERT(is_export); | 5922 ASSERT(is_export); |
| 5906 library_.AddExport(ns); | 5923 library_.AddExport(ns); |
| 5907 } | 5924 } |
| 5908 } | 5925 } |
| 5909 | 5926 |
| 5910 | 5927 |
| 5911 void Parser::ParseLibraryPart() { | 5928 void Parser::ParseLibraryPart() { |
| 5912 const intptr_t source_pos = TokenPos(); | 5929 const TokenDescriptor source_pos = TokenPos(); |
| 5913 ConsumeToken(); // Consume "part". | 5930 ConsumeToken(); // Consume "part". |
| 5914 CheckToken(Token::kSTRING, "url expected"); | 5931 CheckToken(Token::kSTRING, "url expected"); |
| 5915 AstNode* url_literal = ParseStringLiteral(false); | 5932 AstNode* url_literal = ParseStringLiteral(false); |
| 5916 ASSERT(url_literal->IsLiteralNode()); | 5933 ASSERT(url_literal->IsLiteralNode()); |
| 5917 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); | 5934 ASSERT(url_literal->AsLiteralNode()->literal().IsString()); |
| 5918 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 5935 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
| 5919 ExpectSemicolon(); | 5936 ExpectSemicolon(); |
| 5920 const String& canon_url = String::CheckedHandle( | 5937 const String& canon_url = String::CheckedHandle( |
| 5921 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); | 5938 CallLibraryTagHandler(Dart_kCanonicalizeUrl, source_pos, url)); |
| 5922 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); | 5939 CallLibraryTagHandler(Dart_kSourceTag, source_pos, canon_url); |
| 5923 } | 5940 } |
| 5924 | 5941 |
| 5925 | 5942 |
| 5926 void Parser::ParseLibraryDefinition(const Object& tl_owner) { | 5943 void Parser::ParseLibraryDefinition(const Object& tl_owner) { |
| 5927 TRACE_PARSER("ParseLibraryDefinition"); | 5944 TRACE_PARSER("ParseLibraryDefinition"); |
| 5928 | 5945 |
| 5929 // Handle the script tag. | 5946 // Handle the script tag. |
| 5930 if (CurrentToken() == Token::kSCRIPTTAG) { | 5947 if (CurrentToken() == Token::kSCRIPTTAG) { |
| 5931 // Nothing to do for script tags except to skip them. | 5948 // Nothing to do for script tags except to skip them. |
| 5932 ConsumeToken(); | 5949 ConsumeToken(); |
| 5933 } | 5950 } |
| 5934 | 5951 |
| 5935 ASSERT(script_.kind() != RawScript::kSourceTag); | 5952 ASSERT(script_.kind() != RawScript::kSourceTag); |
| 5936 | 5953 |
| 5937 // We may read metadata tokens that are part of the toplevel | 5954 // We may read metadata tokens that are part of the toplevel |
| 5938 // declaration that follows the library definitions. Therefore, we | 5955 // declaration that follows the library definitions. Therefore, we |
| 5939 // need to remember the position of the last token that was | 5956 // need to remember the position of the last token that was |
| 5940 // successfully consumed. | 5957 // successfully consumed. |
| 5941 intptr_t rewind_pos = TokenPos(); | 5958 TokenDescriptor rewind_pos = TokenPos(); |
| 5942 intptr_t metadata_pos = SkipMetadata(); | 5959 TokenDescriptor metadata_pos = SkipMetadata(); |
| 5943 if (CurrentToken() == Token::kLIBRARY) { | 5960 if (CurrentToken() == Token::kLIBRARY) { |
| 5944 if (is_patch_source()) { | 5961 if (is_patch_source()) { |
| 5945 ReportError("patch cannot override library name"); | 5962 ReportError("patch cannot override library name"); |
| 5946 } | 5963 } |
| 5947 ParseLibraryName(); | 5964 ParseLibraryName(); |
| 5948 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 5965 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 5949 library_.AddLibraryMetadata(tl_owner, metadata_pos); | 5966 library_.AddLibraryMetadata(tl_owner, metadata_pos); |
| 5950 } | 5967 } |
| 5951 rewind_pos = TokenPos(); | 5968 rewind_pos = TokenPos(); |
| 5952 metadata_pos = SkipMetadata(); | 5969 metadata_pos = SkipMetadata(); |
| 5953 } | 5970 } |
| 5954 while ((CurrentToken() == Token::kIMPORT) || | 5971 while ((CurrentToken() == Token::kIMPORT) || |
| 5955 (CurrentToken() == Token::kEXPORT)) { | 5972 (CurrentToken() == Token::kEXPORT)) { |
| 5956 ParseLibraryImportExport(tl_owner, metadata_pos); | 5973 ParseLibraryImportExport(tl_owner, metadata_pos); |
| 5957 rewind_pos = TokenPos(); | 5974 rewind_pos = TokenPos(); |
| 5958 metadata_pos = SkipMetadata(); | 5975 metadata_pos = SkipMetadata(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6020 if (is_library_source() || is_patch_source()) { | 6037 if (is_library_source() || is_patch_source()) { |
| 6021 set_current_class(toplevel_class); | 6038 set_current_class(toplevel_class); |
| 6022 ParseLibraryDefinition(tl_owner); | 6039 ParseLibraryDefinition(tl_owner); |
| 6023 } else if (is_part_source()) { | 6040 } else if (is_part_source()) { |
| 6024 ParsePartHeader(); | 6041 ParsePartHeader(); |
| 6025 } | 6042 } |
| 6026 | 6043 |
| 6027 const Class& cls = Class::Handle(Z); | 6044 const Class& cls = Class::Handle(Z); |
| 6028 while (true) { | 6045 while (true) { |
| 6029 set_current_class(cls); // No current class. | 6046 set_current_class(cls); // No current class. |
| 6030 intptr_t metadata_pos = SkipMetadata(); | 6047 TokenDescriptor metadata_pos = SkipMetadata(); |
| 6031 if (CurrentToken() == Token::kCLASS) { | 6048 if (CurrentToken() == Token::kCLASS) { |
| 6032 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); | 6049 ParseClassDeclaration(pending_classes, tl_owner, metadata_pos); |
| 6033 } else if (CurrentToken() == Token::kENUM) { | 6050 } else if (CurrentToken() == Token::kENUM) { |
| 6034 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); | 6051 ParseEnumDeclaration(pending_classes, tl_owner, metadata_pos); |
| 6035 } else if ((CurrentToken() == Token::kTYPEDEF) && | 6052 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 6036 (LookaheadToken(1) != Token::kLPAREN)) { | 6053 (LookaheadToken(1) != Token::kLPAREN)) { |
| 6037 set_current_class(toplevel_class); | 6054 set_current_class(toplevel_class); |
| 6038 ParseTypedef(pending_classes, tl_owner, metadata_pos); | 6055 ParseTypedef(pending_classes, tl_owner, metadata_pos); |
| 6039 } else if ((CurrentToken() == Token::kABSTRACT) && | 6056 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 6040 (LookaheadToken(1) == Token::kCLASS)) { | 6057 (LookaheadToken(1) == Token::kCLASS)) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6145 | 6162 |
| 6146 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { | 6163 SequenceNode* Parser::CloseAsyncGeneratorTryBlock(SequenceNode *body) { |
| 6147 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); | 6164 TRACE_PARSER("CloseAsyncGeneratorTryBlock"); |
| 6148 // The generated try-catch-finally that wraps the async generator function | 6165 // The generated try-catch-finally that wraps the async generator function |
| 6149 // body is the outermost try statement. | 6166 // body is the outermost try statement. |
| 6150 ASSERT(try_stack_ != NULL); | 6167 ASSERT(try_stack_ != NULL); |
| 6151 ASSERT(try_stack_->outer_try() == NULL); | 6168 ASSERT(try_stack_->outer_try() == NULL); |
| 6152 // We only get here when parsing an async generator body. | 6169 // We only get here when parsing an async generator body. |
| 6153 ASSERT(innermost_function().IsAsyncGenClosure()); | 6170 ASSERT(innermost_function().IsAsyncGenClosure()); |
| 6154 | 6171 |
| 6155 const intptr_t try_end_pos = innermost_function().end_token_pos(); | 6172 const TokenDescriptor try_end_pos = innermost_function().end_token_pos(); |
| 6156 | 6173 |
| 6157 // The try-block (closure body code) has been parsed. We are now | 6174 // The try-block (closure body code) has been parsed. We are now |
| 6158 // generating the code for the catch block. | 6175 // generating the code for the catch block. |
| 6159 LocalScope* try_scope = current_block_->scope; | 6176 LocalScope* try_scope = current_block_->scope; |
| 6160 try_stack_->enter_catch(); | 6177 try_stack_->enter_catch(); |
| 6161 OpenBlock(); // Catch handler list. | 6178 OpenBlock(); // Catch handler list. |
| 6162 OpenBlock(); // Catch block. | 6179 OpenBlock(); // Catch block. |
| 6163 | 6180 |
| 6164 // Add the exception and stack trace parameters to the scope. | 6181 // Add the exception and stack trace parameters to the scope. |
| 6165 CatchParamDesc exception_param; | 6182 CatchParamDesc exception_param; |
| 6166 CatchParamDesc stack_trace_param; | 6183 CatchParamDesc stack_trace_param; |
| 6167 exception_param.token_pos = Token::kNoSourcePos; | 6184 exception_param.token_pos = TokenDescriptor::kNoSource; |
| 6168 exception_param.type = &Object::dynamic_type(); | 6185 exception_param.type = &Object::dynamic_type(); |
| 6169 exception_param.name = &Symbols::ExceptionParameter(); | 6186 exception_param.name = &Symbols::ExceptionParameter(); |
| 6170 stack_trace_param.token_pos = Token::kNoSourcePos; | 6187 stack_trace_param.token_pos = TokenDescriptor::kNoSource; |
| 6171 stack_trace_param.type = &Object::dynamic_type(); | 6188 stack_trace_param.type = &Object::dynamic_type(); |
| 6172 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6189 stack_trace_param.name = &Symbols::StackTraceParameter(); |
| 6173 | 6190 |
| 6174 AddCatchParamsToScope( | 6191 AddCatchParamsToScope( |
| 6175 &exception_param, &stack_trace_param, current_block_->scope); | 6192 &exception_param, &stack_trace_param, current_block_->scope); |
| 6176 | 6193 |
| 6177 // Generate code to save the exception object and stack trace | 6194 // Generate code to save the exception object and stack trace |
| 6178 // in local variables. | 6195 // in local variables. |
| 6179 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6196 LocalVariable* context_var = try_scope->LocalLookupVariable( |
| 6180 Symbols::SavedTryContextVar()); | 6197 Symbols::SavedTryContextVar()); |
| 6181 ASSERT(context_var != NULL); | 6198 ASSERT(context_var != NULL); |
| 6182 | 6199 |
| 6183 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6200 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
| 6184 Symbols::ExceptionVar()); | 6201 Symbols::ExceptionVar()); |
| 6185 ASSERT(exception_var != NULL); | 6202 ASSERT(exception_var != NULL); |
| 6186 if (exception_param.var != NULL) { | 6203 if (exception_param.var != NULL) { |
| 6187 // Generate code to load the exception object (:exception_var) into | 6204 // Generate code to load the exception object (:exception_var) into |
| 6188 // the exception variable specified in this block. | 6205 // the exception variable specified in this block. |
| 6189 current_block_->statements->Add(new(Z) StoreLocalNode( | 6206 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6190 Token::kNoSourcePos, | 6207 TokenDescriptor::kNoSource, |
| 6191 exception_param.var, | 6208 exception_param.var, |
| 6192 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 6209 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_var))); |
| 6193 } | 6210 } |
| 6194 | 6211 |
| 6195 LocalVariable* stack_trace_var = | 6212 LocalVariable* stack_trace_var = |
| 6196 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6213 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 6197 ASSERT(stack_trace_var != NULL); | 6214 ASSERT(stack_trace_var != NULL); |
| 6198 if (stack_trace_param.var != NULL) { | 6215 if (stack_trace_param.var != NULL) { |
| 6199 // A stack trace variable is specified in this block, so generate code | 6216 // A stack trace variable is specified in this block, so generate code |
| 6200 // to load the stack trace object (:stack_trace_var) into the stack | 6217 // to load the stack trace object (:stack_trace_var) into the stack |
| 6201 // trace variable specified in this block. | 6218 // trace variable specified in this block. |
| 6202 current_block_->statements->Add(new(Z) StoreLocalNode( | 6219 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6203 Token::kNoSourcePos, | 6220 TokenDescriptor::kNoSource, |
| 6204 stack_trace_param.var, | 6221 stack_trace_param.var, |
| 6205 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 6222 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, stack_trace_var))); |
| 6206 } | 6223 } |
| 6207 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6224 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
| 6208 Symbols::SavedExceptionVar()); | 6225 Symbols::SavedExceptionVar()); |
| 6209 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6226 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
| 6210 Symbols::SavedStackTraceVar()); | 6227 Symbols::SavedStackTraceVar()); |
| 6211 SaveExceptionAndStacktrace(current_block_->statements, | 6228 SaveExceptionAndStacktrace(current_block_->statements, |
| 6212 exception_var, | 6229 exception_var, |
| 6213 stack_trace_var, | 6230 stack_trace_var, |
| 6214 saved_exception_var, | 6231 saved_exception_var, |
| 6215 saved_stack_trace_var); | 6232 saved_stack_trace_var); |
| 6216 | 6233 |
| 6217 // Catch block: add the error to the stream. | 6234 // Catch block: add the error to the stream. |
| 6218 // :controller.AddError(:exception, :stack_trace); | 6235 // :controller.AddError(:exception, :stack_trace); |
| 6219 // return; // The finally block will close the stream. | 6236 // return; // The finally block will close the stream. |
| 6220 LocalVariable* controller = | 6237 LocalVariable* controller = |
| 6221 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6238 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
| 6222 ASSERT(controller != NULL); | 6239 ASSERT(controller != NULL); |
| 6223 ArgumentListNode* args = | 6240 ArgumentListNode* args = |
| 6224 new(Z) ArgumentListNode(Token::kNoSourcePos); | 6241 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 6225 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); | 6242 args->Add(new(Z) LoadLocalNode( |
| 6226 args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); | 6243 TokenDescriptor::kNoSource, exception_param.var)); |
| 6244 args->Add(new(Z) LoadLocalNode( |
| 6245 TokenDescriptor::kNoSource, stack_trace_param.var)); |
| 6227 current_block_->statements->Add( | 6246 current_block_->statements->Add( |
| 6228 new(Z) InstanceCallNode(try_end_pos, | 6247 new(Z) InstanceCallNode(try_end_pos, |
| 6229 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), | 6248 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, controller), |
| 6230 Symbols::AddError(), | 6249 Symbols::AddError(), |
| 6231 args)); | 6250 args)); |
| 6232 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos); | 6251 ReturnNode* return_node = new(Z) ReturnNode(TokenDescriptor::kNoSource); |
| 6233 AddNodeForFinallyInlining(return_node); | 6252 AddNodeForFinallyInlining(return_node); |
| 6234 current_block_->statements->Add(return_node); | 6253 current_block_->statements->Add(return_node); |
| 6235 AstNode* catch_block = CloseBlock(); | 6254 AstNode* catch_block = CloseBlock(); |
| 6236 current_block_->statements->Add(catch_block); | 6255 current_block_->statements->Add(catch_block); |
| 6237 SequenceNode* catch_handler_list = CloseBlock(); | 6256 SequenceNode* catch_handler_list = CloseBlock(); |
| 6238 | 6257 |
| 6239 TryStack* try_statement = PopTry(); | 6258 TryStack* try_statement = PopTry(); |
| 6240 ASSERT(try_stack_ == NULL); // We popped the outermost try block. | 6259 ASSERT(try_stack_ == NULL); // We popped the outermost try block. |
| 6241 | 6260 |
| 6242 // Finally block: closing the stream and returning. Instead of simply | 6261 // Finally block: closing the stream and returning. Instead of simply |
| 6243 // returning, create an await state and suspend. There may be outstanding | 6262 // returning, create an await state and suspend. There may be outstanding |
| 6244 // calls to schedule the generator body. This suspension ensures that we | 6263 // calls to schedule the generator body. This suspension ensures that we |
| 6245 // do not repeat any code of the generator body. | 6264 // do not repeat any code of the generator body. |
| 6246 // :controller.close(); | 6265 // :controller.close(); |
| 6247 // suspend; | 6266 // suspend; |
| 6248 // We need to inline this code in all recorded exit points. | 6267 // We need to inline this code in all recorded exit points. |
| 6249 intptr_t node_index = 0; | 6268 intptr_t node_index = 0; |
| 6250 SequenceNode* finally_clause = NULL; | 6269 SequenceNode* finally_clause = NULL; |
| 6251 if (try_stack_ != NULL) { | 6270 if (try_stack_ != NULL) { |
| 6252 try_stack_->enter_finally(); | 6271 try_stack_->enter_finally(); |
| 6253 } | 6272 } |
| 6254 do { | 6273 do { |
| 6255 OpenBlock(); | 6274 OpenBlock(); |
| 6256 ArgumentListNode* no_args = | 6275 ArgumentListNode* no_args = |
| 6257 new(Z) ArgumentListNode(Token::kNoSourcePos); | 6276 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 6258 current_block_->statements->Add( | 6277 current_block_->statements->Add( |
| 6259 new(Z) InstanceCallNode(try_end_pos, | 6278 new(Z) InstanceCallNode(try_end_pos, |
| 6260 new(Z) LoadLocalNode(Token::kNoSourcePos, controller), | 6279 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, controller), |
| 6261 Symbols::Close(), | 6280 Symbols::Close(), |
| 6262 no_args)); | 6281 no_args)); |
| 6263 | 6282 |
| 6264 // Suspend after the close. | 6283 // Suspend after the close. |
| 6265 AwaitMarkerNode* await_marker = | 6284 AwaitMarkerNode* await_marker = |
| 6266 new(Z) AwaitMarkerNode(async_temp_scope_, | 6285 new(Z) AwaitMarkerNode(async_temp_scope_, |
| 6267 current_block_->scope, | 6286 current_block_->scope, |
| 6268 Token::kNoSourcePos); | 6287 TokenDescriptor::kNoSource); |
| 6269 current_block_->statements->Add(await_marker); | 6288 current_block_->statements->Add(await_marker); |
| 6270 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); | 6289 ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos); |
| 6271 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); | 6290 continuation_ret->set_return_type(ReturnNode::kContinuationTarget); |
| 6272 current_block_->statements->Add(continuation_ret); | 6291 current_block_->statements->Add(continuation_ret); |
| 6273 | 6292 |
| 6274 finally_clause = CloseBlock(); | 6293 finally_clause = CloseBlock(); |
| 6275 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 6294 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
| 6276 if (node_to_inline != NULL) { | 6295 if (node_to_inline != NULL) { |
| 6277 InlinedFinallyNode* node = | 6296 InlinedFinallyNode* node = |
| 6278 new(Z) InlinedFinallyNode(try_end_pos, | 6297 new(Z) InlinedFinallyNode(try_end_pos, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 6289 if (try_stack_ != NULL) { | 6308 if (try_stack_ != NULL) { |
| 6290 try_stack_->exit_finally(); | 6309 try_stack_->exit_finally(); |
| 6291 } | 6310 } |
| 6292 | 6311 |
| 6293 const GrowableObjectArray& handler_types = | 6312 const GrowableObjectArray& handler_types = |
| 6294 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6313 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 6295 // Catch block handles all exceptions. | 6314 // Catch block handles all exceptions. |
| 6296 handler_types.Add(Object::dynamic_type()); | 6315 handler_types.Add(Object::dynamic_type()); |
| 6297 | 6316 |
| 6298 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( | 6317 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( |
| 6299 Token::kNoSourcePos, | 6318 TokenDescriptor::kNoSource, |
| 6300 catch_handler_list, | 6319 catch_handler_list, |
| 6301 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6320 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 6302 context_var, | 6321 context_var, |
| 6303 exception_var, | 6322 exception_var, |
| 6304 stack_trace_var, | 6323 stack_trace_var, |
| 6305 saved_exception_var, | 6324 saved_exception_var, |
| 6306 saved_stack_trace_var, | 6325 saved_stack_trace_var, |
| 6307 AllocateTryIndex(), | 6326 AllocateTryIndex(), |
| 6308 true); | 6327 true); |
| 6309 | 6328 |
| 6310 const intptr_t try_index = try_statement->try_index(); | 6329 const intptr_t try_index = try_statement->try_index(); |
| 6311 | 6330 |
| 6312 AstNode* try_catch_node = | 6331 AstNode* try_catch_node = |
| 6313 new(Z) TryCatchNode(Token::kNoSourcePos, | 6332 new(Z) TryCatchNode(TokenDescriptor::kNoSource, |
| 6314 body, | 6333 body, |
| 6315 context_var, | 6334 context_var, |
| 6316 catch_clause, | 6335 catch_clause, |
| 6317 finally_clause, | 6336 finally_clause, |
| 6318 try_index, | 6337 try_index, |
| 6319 finally_clause); | 6338 finally_clause); |
| 6320 current_block_->statements->Add(try_catch_node); | 6339 current_block_->statements->Add(try_catch_node); |
| 6321 return CloseBlock(); | 6340 return CloseBlock(); |
| 6322 } | 6341 } |
| 6323 | 6342 |
| 6324 | 6343 |
| 6325 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | 6344 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { |
| 6326 // This is the outermost try-catch of the function. | 6345 // This is the outermost try-catch of the function. |
| 6327 ASSERT(try_stack_ != NULL); | 6346 ASSERT(try_stack_ != NULL); |
| 6328 ASSERT(try_stack_->outer_try() == NULL); | 6347 ASSERT(try_stack_->outer_try() == NULL); |
| 6329 ASSERT(innermost_function().IsAsyncClosure()); | 6348 ASSERT(innermost_function().IsAsyncClosure()); |
| 6330 LocalScope* try_scope = current_block_->scope; | 6349 LocalScope* try_scope = current_block_->scope; |
| 6331 | 6350 |
| 6332 try_stack_->enter_catch(); | 6351 try_stack_->enter_catch(); |
| 6333 | 6352 |
| 6334 OpenBlock(); // Catch handler list. | 6353 OpenBlock(); // Catch handler list. |
| 6335 OpenBlock(); // Catch block. | 6354 OpenBlock(); // Catch block. |
| 6336 CatchParamDesc exception_param; | 6355 CatchParamDesc exception_param; |
| 6337 CatchParamDesc stack_trace_param; | 6356 CatchParamDesc stack_trace_param; |
| 6338 exception_param.token_pos = Token::kNoSourcePos; | 6357 exception_param.token_pos = TokenDescriptor::kNoSource; |
| 6339 exception_param.type = &Object::dynamic_type(); | 6358 exception_param.type = &Object::dynamic_type(); |
| 6340 exception_param.name = &Symbols::ExceptionParameter(); | 6359 exception_param.name = &Symbols::ExceptionParameter(); |
| 6341 stack_trace_param.token_pos = Token::kNoSourcePos; | 6360 stack_trace_param.token_pos = TokenDescriptor::kNoSource; |
| 6342 stack_trace_param.type = &Object::dynamic_type(); | 6361 stack_trace_param.type = &Object::dynamic_type(); |
| 6343 stack_trace_param.name = &Symbols::StackTraceParameter(); | 6362 stack_trace_param.name = &Symbols::StackTraceParameter(); |
| 6344 | 6363 |
| 6345 AddCatchParamsToScope( | 6364 AddCatchParamsToScope( |
| 6346 &exception_param, &stack_trace_param, current_block_->scope); | 6365 &exception_param, &stack_trace_param, current_block_->scope); |
| 6347 | 6366 |
| 6348 LocalVariable* context_var = try_scope->LocalLookupVariable( | 6367 LocalVariable* context_var = try_scope->LocalLookupVariable( |
| 6349 Symbols::SavedTryContextVar()); | 6368 Symbols::SavedTryContextVar()); |
| 6350 ASSERT(context_var != NULL); | 6369 ASSERT(context_var != NULL); |
| 6351 | 6370 |
| 6352 LocalVariable* exception_var = try_scope->LocalLookupVariable( | 6371 LocalVariable* exception_var = try_scope->LocalLookupVariable( |
| 6353 Symbols::ExceptionVar()); | 6372 Symbols::ExceptionVar()); |
| 6354 if (exception_param.var != NULL) { | 6373 if (exception_param.var != NULL) { |
| 6355 // Generate code to load the exception object (:exception_var) into | 6374 // Generate code to load the exception object (:exception_var) into |
| 6356 // the exception variable specified in this block. | 6375 // the exception variable specified in this block. |
| 6357 ASSERT(exception_var != NULL); | 6376 ASSERT(exception_var != NULL); |
| 6358 current_block_->statements->Add(new(Z) StoreLocalNode( | 6377 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6359 Token::kNoSourcePos, | 6378 TokenDescriptor::kNoSource, |
| 6360 exception_param.var, | 6379 exception_param.var, |
| 6361 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 6380 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_var))); |
| 6362 } | 6381 } |
| 6363 | 6382 |
| 6364 LocalVariable* stack_trace_var = | 6383 LocalVariable* stack_trace_var = |
| 6365 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6384 try_scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 6366 if (stack_trace_param.var != NULL) { | 6385 if (stack_trace_param.var != NULL) { |
| 6367 // A stack trace variable is specified in this block, so generate code | 6386 // A stack trace variable is specified in this block, so generate code |
| 6368 // to load the stack trace object (:stack_trace_var) into the stack | 6387 // to load the stack trace object (:stack_trace_var) into the stack |
| 6369 // trace variable specified in this block. | 6388 // trace variable specified in this block. |
| 6370 ASSERT(stack_trace_var != NULL); | 6389 ASSERT(stack_trace_var != NULL); |
| 6371 current_block_->statements->Add(new(Z) StoreLocalNode( | 6390 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 6372 Token::kNoSourcePos, | 6391 TokenDescriptor::kNoSource, |
| 6373 stack_trace_param.var, | 6392 stack_trace_param.var, |
| 6374 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 6393 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, stack_trace_var))); |
| 6375 } | 6394 } |
| 6376 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( | 6395 LocalVariable* saved_exception_var = try_scope->LocalLookupVariable( |
| 6377 Symbols::SavedExceptionVar()); | 6396 Symbols::SavedExceptionVar()); |
| 6378 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( | 6397 LocalVariable* saved_stack_trace_var = try_scope->LocalLookupVariable( |
| 6379 Symbols::SavedStackTraceVar()); | 6398 Symbols::SavedStackTraceVar()); |
| 6380 SaveExceptionAndStacktrace(current_block_->statements, | 6399 SaveExceptionAndStacktrace(current_block_->statements, |
| 6381 exception_var, | 6400 exception_var, |
| 6382 stack_trace_var, | 6401 stack_trace_var, |
| 6383 saved_exception_var, | 6402 saved_exception_var, |
| 6384 saved_stack_trace_var); | 6403 saved_stack_trace_var); |
| 6385 | 6404 |
| 6386 // Complete the async future with an error. This catch block executes | 6405 // Complete the async future with an error. This catch block executes |
| 6387 // unconditionally, there is no need to generate a type check for. | 6406 // unconditionally, there is no need to generate a type check for. |
| 6388 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 6407 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
| 6389 Symbols::AsyncCompleter(), false); | 6408 Symbols::AsyncCompleter(), false); |
| 6390 ASSERT(async_completer != NULL); | 6409 ASSERT(async_completer != NULL); |
| 6391 ArgumentListNode* completer_args = | 6410 ArgumentListNode* completer_args = |
| 6392 new (Z) ArgumentListNode(Token::kNoSourcePos); | 6411 new (Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 6393 completer_args->Add( | 6412 completer_args->Add( |
| 6394 new (Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var)); | 6413 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_param.var)); |
| 6395 completer_args->Add( | 6414 completer_args->Add( |
| 6396 new (Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var)); | 6415 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 6416 stack_trace_param.var)); |
| 6397 current_block_->statements->Add(new (Z) InstanceCallNode( | 6417 current_block_->statements->Add(new (Z) InstanceCallNode( |
| 6398 TokenPos(), | 6418 TokenPos(), |
| 6399 new (Z) LoadLocalNode(Token::kNoSourcePos, async_completer), | 6419 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_completer), |
| 6400 Symbols::CompleterCompleteError(), | 6420 Symbols::CompleterCompleteError(), |
| 6401 completer_args)); | 6421 completer_args)); |
| 6402 ReturnNode* return_node = new (Z) ReturnNode(Token::kNoSourcePos); | 6422 ReturnNode* return_node = new (Z) ReturnNode(TokenDescriptor::kNoSource); |
| 6403 // Behavior like a continuation return, i.e,. don't call a completer. | 6423 // Behavior like a continuation return, i.e,. don't call a completer. |
| 6404 return_node->set_return_type(ReturnNode::kContinuation); | 6424 return_node->set_return_type(ReturnNode::kContinuation); |
| 6405 current_block_->statements->Add(return_node); | 6425 current_block_->statements->Add(return_node); |
| 6406 AstNode* catch_block = CloseBlock(); | 6426 AstNode* catch_block = CloseBlock(); |
| 6407 current_block_->statements->Add(catch_block); | 6427 current_block_->statements->Add(catch_block); |
| 6408 SequenceNode* catch_handler_list = CloseBlock(); | 6428 SequenceNode* catch_handler_list = CloseBlock(); |
| 6409 | 6429 |
| 6410 const GrowableObjectArray& handler_types = | 6430 const GrowableObjectArray& handler_types = |
| 6411 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 6431 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 6412 handler_types.SetLength(0); | 6432 handler_types.SetLength(0); |
| 6413 handler_types.Add(*exception_param.type); | 6433 handler_types.Add(*exception_param.type); |
| 6414 | 6434 |
| 6415 TryStack* try_statement = PopTry(); | 6435 TryStack* try_statement = PopTry(); |
| 6416 const intptr_t try_index = try_statement->try_index(); | 6436 const intptr_t try_index = try_statement->try_index(); |
| 6417 | 6437 |
| 6418 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( | 6438 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
| 6419 Token::kNoSourcePos, | 6439 TokenDescriptor::kNoSource, |
| 6420 catch_handler_list, | 6440 catch_handler_list, |
| 6421 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), | 6441 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 6422 context_var, | 6442 context_var, |
| 6423 exception_var, | 6443 exception_var, |
| 6424 stack_trace_var, | 6444 stack_trace_var, |
| 6425 saved_exception_var, | 6445 saved_exception_var, |
| 6426 saved_stack_trace_var, | 6446 saved_stack_trace_var, |
| 6427 CatchClauseNode::kInvalidTryIndex, | 6447 CatchClauseNode::kInvalidTryIndex, |
| 6428 true); | 6448 true); |
| 6429 AstNode* try_catch_node = new (Z) TryCatchNode( | 6449 AstNode* try_catch_node = new (Z) TryCatchNode( |
| 6430 Token::kNoSourcePos, | 6450 TokenDescriptor::kNoSource, |
| 6431 try_block, | 6451 try_block, |
| 6432 context_var, | 6452 context_var, |
| 6433 catch_clause, | 6453 catch_clause, |
| 6434 NULL, // No finally clause. | 6454 NULL, // No finally clause. |
| 6435 try_index, | 6455 try_index, |
| 6436 NULL); // No rethrow-finally clause. | 6456 NULL); // No rethrow-finally clause. |
| 6437 current_block_->statements->Add(try_catch_node); | 6457 current_block_->statements->Add(try_catch_node); |
| 6438 return CloseBlock(); | 6458 return CloseBlock(); |
| 6439 } | 6459 } |
| 6440 | 6460 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6466 } | 6486 } |
| 6467 | 6487 |
| 6468 | 6488 |
| 6469 void Parser::AddSyncGenClosureParameters(ParamList* params) { | 6489 void Parser::AddSyncGenClosureParameters(ParamList* params) { |
| 6470 // Create the parameter list for the body closure of a sync generator: | 6490 // Create the parameter list for the body closure of a sync generator: |
| 6471 // 1) Implicit closure parameter; | 6491 // 1) Implicit closure parameter; |
| 6472 // 2) Iterator | 6492 // 2) Iterator |
| 6473 // Add implicit closure parameter if not already present. | 6493 // Add implicit closure parameter if not already present. |
| 6474 if (params->parameters->length() == 0) { | 6494 if (params->parameters->length() == 0) { |
| 6475 params->AddFinalParameter( | 6495 params->AddFinalParameter( |
| 6476 0, &Symbols::ClosureParameter(), &Object::dynamic_type()); | 6496 TokenDescriptor::kMinSource, |
| 6497 &Symbols::ClosureParameter(), |
| 6498 &Object::dynamic_type()); |
| 6477 } | 6499 } |
| 6478 ParamDesc iterator_param; | 6500 ParamDesc iterator_param; |
| 6479 iterator_param.name = &Symbols::IteratorParameter(); | 6501 iterator_param.name = &Symbols::IteratorParameter(); |
| 6480 iterator_param.type = &Object::dynamic_type(); | 6502 iterator_param.type = &Object::dynamic_type(); |
| 6481 params->parameters->Add(iterator_param); | 6503 params->parameters->Add(iterator_param); |
| 6482 params->num_fixed_parameters++; | 6504 params->num_fixed_parameters++; |
| 6483 } | 6505 } |
| 6484 | 6506 |
| 6485 | 6507 |
| 6486 void Parser::AddAsyncGenClosureParameters(ParamList* params) { | 6508 void Parser::AddAsyncGenClosureParameters(ParamList* params) { |
| 6487 // Create the parameter list for the body closure of an async generator. | 6509 // Create the parameter list for the body closure of an async generator. |
| 6488 // The closure has the same parameters as an asynchronous non-generator. | 6510 // The closure has the same parameters as an asynchronous non-generator. |
| 6489 AddAsyncClosureParameters(params); | 6511 AddAsyncClosureParameters(params); |
| 6490 } | 6512 } |
| 6491 | 6513 |
| 6492 | 6514 |
| 6493 RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) { | 6515 RawFunction* Parser::OpenSyncGeneratorFunction(TokenDescriptor func_pos) { |
| 6494 Function& body = Function::Handle(Z); | 6516 Function& body = Function::Handle(Z); |
| 6495 String& body_closure_name = String::Handle(Z); | 6517 String& body_closure_name = String::Handle(Z); |
| 6496 bool is_new_closure = false; | 6518 bool is_new_closure = false; |
| 6497 | 6519 |
| 6498 AddContinuationVariables(); | 6520 AddContinuationVariables(); |
| 6499 | 6521 |
| 6500 // Check whether a function for the body of this generator | 6522 // Check whether a function for the body of this generator |
| 6501 // function has already been created by a previous | 6523 // function has already been created by a previous |
| 6502 // compilation. | 6524 // compilation. |
| 6503 const Function& found_func = Function::Handle( | 6525 const Function& found_func = Function::Handle( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6550 LocalVariable* existing_var = | 6572 LocalVariable* existing_var = |
| 6551 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 6573 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6552 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6574 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| 6553 existing_var = | 6575 existing_var = |
| 6554 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 6576 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
| 6555 ASSERT((existing_var != NULL) && existing_var->is_captured()); | 6577 ASSERT((existing_var != NULL) && existing_var->is_captured()); |
| 6556 | 6578 |
| 6557 // :await_jump_var = -1; | 6579 // :await_jump_var = -1; |
| 6558 LocalVariable* jump_var = | 6580 LocalVariable* jump_var = |
| 6559 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6581 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6560 LiteralNode* init_value = | 6582 LiteralNode* init_value = new(Z) LiteralNode(TokenDescriptor::kNoSource, |
| 6561 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6583 Smi::ZoneHandle(Smi::New(-1))); |
| 6562 current_block_->statements->Add( | 6584 current_block_->statements->Add( |
| 6563 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); | 6585 new(Z) StoreLocalNode(TokenDescriptor::kNoSource, jump_var, init_value)); |
| 6564 | 6586 |
| 6565 // return new SyncIterable(body_closure); | 6587 // return new SyncIterable(body_closure); |
| 6566 const Class& iterable_class = | 6588 const Class& iterable_class = |
| 6567 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); | 6589 Class::Handle(Z, Library::LookupCoreClass(Symbols::_SyncIterable())); |
| 6568 ASSERT(!iterable_class.IsNull()); | 6590 ASSERT(!iterable_class.IsNull()); |
| 6569 const Function& iterable_constructor = Function::ZoneHandle(Z, | 6591 const Function& iterable_constructor = Function::ZoneHandle(Z, |
| 6570 iterable_class.LookupConstructorAllowPrivate( | 6592 iterable_class.LookupConstructorAllowPrivate( |
| 6571 Symbols::_SyncIterableConstructor())); | 6593 Symbols::_SyncIterableConstructor())); |
| 6572 ASSERT(!iterable_constructor.IsNull()); | 6594 ASSERT(!iterable_constructor.IsNull()); |
| 6573 | 6595 |
| 6574 const String& closure_name = String::Handle(Z, closure.name()); | 6596 const String& closure_name = String::Handle(Z, closure.name()); |
| 6575 ASSERT(closure_name.IsSymbol()); | 6597 ASSERT(closure_name.IsSymbol()); |
| 6576 | 6598 |
| 6577 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); | 6599 ArgumentListNode* arguments = |
| 6600 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 6578 ClosureNode* closure_obj = new(Z) ClosureNode( | 6601 ClosureNode* closure_obj = new(Z) ClosureNode( |
| 6579 Token::kNoSourcePos, closure, NULL, closure_body->scope()); | 6602 TokenDescriptor::kNoSource, closure, NULL, closure_body->scope()); |
| 6580 arguments->Add(closure_obj); | 6603 arguments->Add(closure_obj); |
| 6581 ConstructorCallNode* new_iterable = | 6604 ConstructorCallNode* new_iterable = |
| 6582 new(Z) ConstructorCallNode(Token::kNoSourcePos, | 6605 new(Z) ConstructorCallNode(TokenDescriptor::kNoSource, |
| 6583 TypeArguments::ZoneHandle(Z), | 6606 TypeArguments::ZoneHandle(Z), |
| 6584 iterable_constructor, | 6607 iterable_constructor, |
| 6585 arguments); | 6608 arguments); |
| 6586 ReturnNode* return_node = | 6609 ReturnNode* return_node = |
| 6587 new (Z) ReturnNode(Token::kNoSourcePos, new_iterable); | 6610 new (Z) ReturnNode(TokenDescriptor::kNoSource, new_iterable); |
| 6588 current_block_->statements->Add(return_node); | 6611 current_block_->statements->Add(return_node); |
| 6589 return CloseBlock(); | 6612 return CloseBlock(); |
| 6590 } | 6613 } |
| 6591 | 6614 |
| 6592 | 6615 |
| 6593 void Parser::AddAsyncClosureParameters(ParamList* params) { | 6616 void Parser::AddAsyncClosureParameters(ParamList* params) { |
| 6594 // Async closures have three optional parameters: | 6617 // Async closures have three optional parameters: |
| 6595 // * A continuation result. | 6618 // * A continuation result. |
| 6596 // * A continuation error. | 6619 // * A continuation error. |
| 6597 // * A continuation stack trace. | 6620 // * A continuation stack trace. |
| 6598 ASSERT(params->parameters->length() <= 1); | 6621 ASSERT(params->parameters->length() <= 1); |
| 6599 // Add implicit closure parameter if not yet present. | 6622 // Add implicit closure parameter if not yet present. |
| 6600 if (params->parameters->length() == 0) { | 6623 if (params->parameters->length() == 0) { |
| 6601 params->AddFinalParameter( | 6624 params->AddFinalParameter( |
| 6602 0, &Symbols::ClosureParameter(), &Object::dynamic_type()); | 6625 TokenDescriptor::kMinSource, |
| 6626 &Symbols::ClosureParameter(), |
| 6627 &Object::dynamic_type()); |
| 6603 } | 6628 } |
| 6604 ParamDesc result_param; | 6629 ParamDesc result_param; |
| 6605 result_param.name = &Symbols::AsyncOperationParam(); | 6630 result_param.name = &Symbols::AsyncOperationParam(); |
| 6606 result_param.default_value = &Object::null_instance(); | 6631 result_param.default_value = &Object::null_instance(); |
| 6607 result_param.type = &Object::dynamic_type(); | 6632 result_param.type = &Object::dynamic_type(); |
| 6608 params->parameters->Add(result_param); | 6633 params->parameters->Add(result_param); |
| 6609 ParamDesc error_param; | 6634 ParamDesc error_param; |
| 6610 error_param.name = &Symbols::AsyncOperationErrorParam(); | 6635 error_param.name = &Symbols::AsyncOperationErrorParam(); |
| 6611 error_param.default_value = &Object::null_instance(); | 6636 error_param.default_value = &Object::null_instance(); |
| 6612 error_param.type = &Object::dynamic_type(); | 6637 error_param.type = &Object::dynamic_type(); |
| 6613 params->parameters->Add(error_param); | 6638 params->parameters->Add(error_param); |
| 6614 ParamDesc stack_trace_param; | 6639 ParamDesc stack_trace_param; |
| 6615 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); | 6640 stack_trace_param.name = &Symbols::AsyncOperationStackTraceParam(); |
| 6616 stack_trace_param.default_value = &Object::null_instance(); | 6641 stack_trace_param.default_value = &Object::null_instance(); |
| 6617 stack_trace_param.type = &Object::dynamic_type(); | 6642 stack_trace_param.type = &Object::dynamic_type(); |
| 6618 params->parameters->Add(stack_trace_param); | 6643 params->parameters->Add(stack_trace_param); |
| 6619 params->has_optional_positional_parameters = true; | 6644 params->has_optional_positional_parameters = true; |
| 6620 params->num_optional_parameters += 3; | 6645 params->num_optional_parameters += 3; |
| 6621 } | 6646 } |
| 6622 | 6647 |
| 6623 | 6648 |
| 6624 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { | 6649 RawFunction* Parser::OpenAsyncFunction(TokenDescriptor async_func_pos) { |
| 6625 TRACE_PARSER("OpenAsyncFunction"); | 6650 TRACE_PARSER("OpenAsyncFunction"); |
| 6626 AddContinuationVariables(); | 6651 AddContinuationVariables(); |
| 6627 AddAsyncClosureVariables(); | 6652 AddAsyncClosureVariables(); |
| 6628 Function& closure = Function::Handle(Z); | 6653 Function& closure = Function::Handle(Z); |
| 6629 bool is_new_closure = false; | 6654 bool is_new_closure = false; |
| 6630 | 6655 |
| 6631 // Check whether a function for the asynchronous function body of | 6656 // Check whether a function for the asynchronous function body of |
| 6632 // this async function has already been created by a previous | 6657 // this async function has already been created by a previous |
| 6633 // compilation of this function. | 6658 // compilation of this function. |
| 6634 const Function& found_func = Function::Handle( | 6659 const Function& found_func = Function::Handle( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6671 async_temp_scope_ = current_block_->scope; | 6696 async_temp_scope_ = current_block_->scope; |
| 6672 return closure.raw(); | 6697 return closure.raw(); |
| 6673 } | 6698 } |
| 6674 | 6699 |
| 6675 | 6700 |
| 6676 void Parser::AddContinuationVariables() { | 6701 void Parser::AddContinuationVariables() { |
| 6677 // Add to current block's scope: | 6702 // Add to current block's scope: |
| 6678 // var :await_jump_var; | 6703 // var :await_jump_var; |
| 6679 // var :await_ctx_var; | 6704 // var :await_ctx_var; |
| 6680 LocalVariable* await_jump_var = new (Z) LocalVariable( | 6705 LocalVariable* await_jump_var = new (Z) LocalVariable( |
| 6681 Token::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type()); | 6706 TokenDescriptor::kNoSource, |
| 6707 Symbols::AwaitJumpVar(), |
| 6708 Object::dynamic_type()); |
| 6682 current_block_->scope->AddVariable(await_jump_var); | 6709 current_block_->scope->AddVariable(await_jump_var); |
| 6683 LocalVariable* await_ctx_var = new (Z) LocalVariable( | 6710 LocalVariable* await_ctx_var = new (Z) LocalVariable( |
| 6684 Token::kNoSourcePos, | 6711 TokenDescriptor::kNoSource, |
| 6685 Symbols::AwaitContextVar(), | 6712 Symbols::AwaitContextVar(), |
| 6686 Object::dynamic_type()); | 6713 Object::dynamic_type()); |
| 6687 current_block_->scope->AddVariable(await_ctx_var); | 6714 current_block_->scope->AddVariable(await_ctx_var); |
| 6688 } | 6715 } |
| 6689 | 6716 |
| 6690 | 6717 |
| 6691 void Parser::AddAsyncClosureVariables() { | 6718 void Parser::AddAsyncClosureVariables() { |
| 6692 // Add to current block's scope: | 6719 // Add to current block's scope: |
| 6693 // var :async_op; | 6720 // var :async_op; |
| 6694 // var :async_then_callback; | 6721 // var :async_then_callback; |
| 6695 // var :async_catch_error_callback; | 6722 // var :async_catch_error_callback; |
| 6696 // var :async_completer; | 6723 // var :async_completer; |
| 6697 LocalVariable* async_op_var = new(Z) LocalVariable( | 6724 LocalVariable* async_op_var = new(Z) LocalVariable( |
| 6698 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6725 TokenDescriptor::kNoSource, |
| 6726 Symbols::AsyncOperation(), |
| 6727 Object::dynamic_type()); |
| 6699 current_block_->scope->AddVariable(async_op_var); | 6728 current_block_->scope->AddVariable(async_op_var); |
| 6700 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6729 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
| 6701 Token::kNoSourcePos, | 6730 TokenDescriptor::kNoSource, |
| 6702 Symbols::AsyncThenCallback(), | 6731 Symbols::AsyncThenCallback(), |
| 6703 Object::dynamic_type()); | 6732 Object::dynamic_type()); |
| 6704 current_block_->scope->AddVariable(async_then_callback_var); | 6733 current_block_->scope->AddVariable(async_then_callback_var); |
| 6705 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6734 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
| 6706 Token::kNoSourcePos, | 6735 TokenDescriptor::kNoSource, |
| 6707 Symbols::AsyncCatchErrorCallback(), | 6736 Symbols::AsyncCatchErrorCallback(), |
| 6708 Object::dynamic_type()); | 6737 Object::dynamic_type()); |
| 6709 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6738 current_block_->scope->AddVariable(async_catch_error_callback_var); |
| 6710 LocalVariable* async_completer = new(Z) LocalVariable( | 6739 LocalVariable* async_completer = new(Z) LocalVariable( |
| 6711 Token::kNoSourcePos, | 6740 TokenDescriptor::kNoSource, |
| 6712 Symbols::AsyncCompleter(), | 6741 Symbols::AsyncCompleter(), |
| 6713 Object::dynamic_type()); | 6742 Object::dynamic_type()); |
| 6714 current_block_->scope->AddVariable(async_completer); | 6743 current_block_->scope->AddVariable(async_completer); |
| 6715 } | 6744 } |
| 6716 | 6745 |
| 6717 | 6746 |
| 6718 void Parser::AddAsyncGeneratorVariables() { | 6747 void Parser::AddAsyncGeneratorVariables() { |
| 6719 // Add to current block's scope: | 6748 // Add to current block's scope: |
| 6720 // var :controller; | 6749 // var :controller; |
| 6721 // The :controller variable is used by the async generator closure to | 6750 // The :controller variable is used by the async generator closure to |
| 6722 // store the StreamController object to which the yielded expressions | 6751 // store the StreamController object to which the yielded expressions |
| 6723 // are added. | 6752 // are added. |
| 6724 // var :async_op; | 6753 // var :async_op; |
| 6725 // var :async_then_callback; | 6754 // var :async_then_callback; |
| 6726 // var :async_catch_error_callback; | 6755 // var :async_catch_error_callback; |
| 6727 // These variables are used to store the async generator closure containing | 6756 // These variables are used to store the async generator closure containing |
| 6728 // the body of the async* function. They are used by the await operator. | 6757 // the body of the async* function. They are used by the await operator. |
| 6729 LocalVariable* controller_var = new(Z) LocalVariable( | 6758 LocalVariable* controller_var = new(Z) LocalVariable( |
| 6730 Token::kNoSourcePos, Symbols::Controller(), Object::dynamic_type()); | 6759 TokenDescriptor::kNoSource, |
| 6760 Symbols::Controller(), |
| 6761 Object::dynamic_type()); |
| 6731 current_block_->scope->AddVariable(controller_var); | 6762 current_block_->scope->AddVariable(controller_var); |
| 6732 LocalVariable* async_op_var = new(Z) LocalVariable( | 6763 LocalVariable* async_op_var = new(Z) LocalVariable( |
| 6733 Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type()); | 6764 TokenDescriptor::kNoSource, |
| 6765 Symbols::AsyncOperation(), |
| 6766 Object::dynamic_type()); |
| 6734 current_block_->scope->AddVariable(async_op_var); | 6767 current_block_->scope->AddVariable(async_op_var); |
| 6735 LocalVariable* async_then_callback_var = new(Z) LocalVariable( | 6768 LocalVariable* async_then_callback_var = new(Z) LocalVariable( |
| 6736 Token::kNoSourcePos, | 6769 TokenDescriptor::kNoSource, |
| 6737 Symbols::AsyncThenCallback(), | 6770 Symbols::AsyncThenCallback(), |
| 6738 Object::dynamic_type()); | 6771 Object::dynamic_type()); |
| 6739 current_block_->scope->AddVariable(async_then_callback_var); | 6772 current_block_->scope->AddVariable(async_then_callback_var); |
| 6740 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( | 6773 LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable( |
| 6741 Token::kNoSourcePos, | 6774 TokenDescriptor::kNoSource, |
| 6742 Symbols::AsyncCatchErrorCallback(), | 6775 Symbols::AsyncCatchErrorCallback(), |
| 6743 Object::dynamic_type()); | 6776 Object::dynamic_type()); |
| 6744 current_block_->scope->AddVariable(async_catch_error_callback_var); | 6777 current_block_->scope->AddVariable(async_catch_error_callback_var); |
| 6745 } | 6778 } |
| 6746 | 6779 |
| 6747 | 6780 |
| 6748 RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) { | 6781 RawFunction* Parser::OpenAsyncGeneratorFunction( |
| 6782 TokenDescriptor async_func_pos) { |
| 6749 TRACE_PARSER("OpenAsyncGeneratorFunction"); | 6783 TRACE_PARSER("OpenAsyncGeneratorFunction"); |
| 6750 AddContinuationVariables(); | 6784 AddContinuationVariables(); |
| 6751 AddAsyncGeneratorVariables(); | 6785 AddAsyncGeneratorVariables(); |
| 6752 | 6786 |
| 6753 Function& closure = Function::Handle(Z); | 6787 Function& closure = Function::Handle(Z); |
| 6754 bool is_new_closure = false; | 6788 bool is_new_closure = false; |
| 6755 | 6789 |
| 6756 // Check whether a function for the asynchronous function body of | 6790 // Check whether a function for the asynchronous function body of |
| 6757 // this async generator has already been created by a previous | 6791 // this async generator has already been created by a previous |
| 6758 // compilation of this function. | 6792 // compilation of this function. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6849 async_lib.LookupClassAllowPrivate( | 6883 async_lib.LookupClassAllowPrivate( |
| 6850 Symbols::_AsyncStarStreamController())); | 6884 Symbols::_AsyncStarStreamController())); |
| 6851 ASSERT(!controller_class.IsNull()); | 6885 ASSERT(!controller_class.IsNull()); |
| 6852 const Function& controller_constructor = Function::ZoneHandle(Z, | 6886 const Function& controller_constructor = Function::ZoneHandle(Z, |
| 6853 controller_class.LookupConstructorAllowPrivate( | 6887 controller_class.LookupConstructorAllowPrivate( |
| 6854 Symbols::_AsyncStarStreamControllerConstructor())); | 6888 Symbols::_AsyncStarStreamControllerConstructor())); |
| 6855 | 6889 |
| 6856 // :await_jump_var = -1; | 6890 // :await_jump_var = -1; |
| 6857 LocalVariable* jump_var = | 6891 LocalVariable* jump_var = |
| 6858 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); | 6892 current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6859 LiteralNode* init_value = | 6893 LiteralNode* init_value = new(Z) LiteralNode(TokenDescriptor::kNoSource, |
| 6860 new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6894 Smi::ZoneHandle(Smi::New(-1))); |
| 6861 current_block_->statements->Add( | 6895 current_block_->statements->Add( |
| 6862 new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value)); | 6896 new(Z) StoreLocalNode(TokenDescriptor::kNoSource, jump_var, init_value)); |
| 6863 | 6897 |
| 6864 // Add to AST: | 6898 // Add to AST: |
| 6865 // :async_op = <closure>; (containing the original body) | 6899 // :async_op = <closure>; (containing the original body) |
| 6866 LocalVariable* async_op_var = | 6900 LocalVariable* async_op_var = |
| 6867 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); | 6901 current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false); |
| 6868 ClosureNode* closure_obj = new(Z) ClosureNode( | 6902 ClosureNode* closure_obj = new(Z) ClosureNode( |
| 6869 Token::kNoSourcePos, closure_func, NULL, closure_body->scope()); | 6903 TokenDescriptor::kNoSource, closure_func, NULL, closure_body->scope()); |
| 6870 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( | 6904 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( |
| 6871 Token::kNoSourcePos, | 6905 TokenDescriptor::kNoSource, |
| 6872 async_op_var, | 6906 async_op_var, |
| 6873 closure_obj); | 6907 closure_obj); |
| 6874 | 6908 |
| 6875 current_block_->statements->Add(store_async_op); | 6909 current_block_->statements->Add(store_async_op); |
| 6876 | 6910 |
| 6877 // :async_then_callback = _asyncThenWrapperHelper(:async_op) | 6911 // :async_then_callback = _asyncThenWrapperHelper(:async_op) |
| 6878 const Function& async_then_wrapper_helper = Function::ZoneHandle( | 6912 const Function& async_then_wrapper_helper = Function::ZoneHandle( |
| 6879 Z, async_lib.LookupFunctionAllowPrivate( | 6913 Z, async_lib.LookupFunctionAllowPrivate( |
| 6880 Symbols::AsyncThenWrapperHelper())); | 6914 Symbols::AsyncThenWrapperHelper())); |
| 6881 ASSERT(!async_then_wrapper_helper.IsNull()); | 6915 ASSERT(!async_then_wrapper_helper.IsNull()); |
| 6882 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( | 6916 ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode( |
| 6883 Token::kNoSourcePos); | 6917 TokenDescriptor::kNoSource); |
| 6884 async_then_wrapper_helper_args->Add( | 6918 async_then_wrapper_helper_args->Add( |
| 6885 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6919 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_op_var)); |
| 6886 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( | 6920 StaticCallNode* then_wrapper_call = new (Z) StaticCallNode( |
| 6887 Token::kNoSourcePos, | 6921 TokenDescriptor::kNoSource, |
| 6888 async_then_wrapper_helper, | 6922 async_then_wrapper_helper, |
| 6889 async_then_wrapper_helper_args); | 6923 async_then_wrapper_helper_args); |
| 6890 LocalVariable* async_then_callback_var = | 6924 LocalVariable* async_then_callback_var = |
| 6891 current_block_->scope->LookupVariable( | 6925 current_block_->scope->LookupVariable( |
| 6892 Symbols::AsyncThenCallback(), false); | 6926 Symbols::AsyncThenCallback(), false); |
| 6893 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( | 6927 StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode( |
| 6894 Token::kNoSourcePos, | 6928 TokenDescriptor::kNoSource, |
| 6895 async_then_callback_var, | 6929 async_then_callback_var, |
| 6896 then_wrapper_call); | 6930 then_wrapper_call); |
| 6897 | 6931 |
| 6898 current_block_->statements->Add(store_async_then_callback); | 6932 current_block_->statements->Add(store_async_then_callback); |
| 6899 | 6933 |
| 6900 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) | 6934 // :async_catch_error_callback = _asyncErrorWrapperHelper(:async_op) |
| 6901 | 6935 |
| 6902 const Function& async_error_wrapper_helper = Function::ZoneHandle( | 6936 const Function& async_error_wrapper_helper = Function::ZoneHandle( |
| 6903 Z, async_lib.LookupFunctionAllowPrivate( | 6937 Z, async_lib.LookupFunctionAllowPrivate( |
| 6904 Symbols::AsyncErrorWrapperHelper())); | 6938 Symbols::AsyncErrorWrapperHelper())); |
| 6905 ASSERT(!async_error_wrapper_helper.IsNull()); | 6939 ASSERT(!async_error_wrapper_helper.IsNull()); |
| 6906 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( | 6940 ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode( |
| 6907 Token::kNoSourcePos); | 6941 TokenDescriptor::kNoSource); |
| 6908 async_error_wrapper_helper_args->Add( | 6942 async_error_wrapper_helper_args->Add( |
| 6909 new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6943 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_op_var)); |
| 6910 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( | 6944 StaticCallNode* error_wrapper_call = new (Z) StaticCallNode( |
| 6911 Token::kNoSourcePos, | 6945 TokenDescriptor::kNoSource, |
| 6912 async_error_wrapper_helper, | 6946 async_error_wrapper_helper, |
| 6913 async_error_wrapper_helper_args); | 6947 async_error_wrapper_helper_args); |
| 6914 LocalVariable* async_catch_error_callback_var = | 6948 LocalVariable* async_catch_error_callback_var = |
| 6915 current_block_->scope->LookupVariable( | 6949 current_block_->scope->LookupVariable( |
| 6916 Symbols::AsyncCatchErrorCallback(), false); | 6950 Symbols::AsyncCatchErrorCallback(), false); |
| 6917 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( | 6951 StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode( |
| 6918 Token::kNoSourcePos, | 6952 TokenDescriptor::kNoSource, |
| 6919 async_catch_error_callback_var, | 6953 async_catch_error_callback_var, |
| 6920 error_wrapper_call); | 6954 error_wrapper_call); |
| 6921 | 6955 |
| 6922 current_block_->statements->Add(store_async_catch_error_callback); | 6956 current_block_->statements->Add(store_async_catch_error_callback); |
| 6923 | 6957 |
| 6924 // :controller = new _AsyncStarStreamController(body_closure); | 6958 // :controller = new _AsyncStarStreamController(body_closure); |
| 6925 ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos); | 6959 ArgumentListNode* arguments = |
| 6926 arguments->Add(new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var)); | 6960 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 6961 arguments->Add( |
| 6962 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, async_op_var)); |
| 6927 ConstructorCallNode* controller_constructor_call = | 6963 ConstructorCallNode* controller_constructor_call = |
| 6928 new(Z) ConstructorCallNode(Token::kNoSourcePos, | 6964 new(Z) ConstructorCallNode(TokenDescriptor::kNoSource, |
| 6929 TypeArguments::ZoneHandle(Z), | 6965 TypeArguments::ZoneHandle(Z), |
| 6930 controller_constructor, | 6966 controller_constructor, |
| 6931 arguments); | 6967 arguments); |
| 6932 LocalVariable* controller_var = | 6968 LocalVariable* controller_var = |
| 6933 current_block_->scope->LookupVariable(Symbols::Controller(), false); | 6969 current_block_->scope->LookupVariable(Symbols::Controller(), false); |
| 6934 StoreLocalNode* store_controller = | 6970 StoreLocalNode* store_controller = |
| 6935 new(Z) StoreLocalNode(Token::kNoSourcePos, | 6971 new(Z) StoreLocalNode(TokenDescriptor::kNoSource, |
| 6936 controller_var, | 6972 controller_var, |
| 6937 controller_constructor_call); | 6973 controller_constructor_call); |
| 6938 current_block_->statements->Add(store_controller); | 6974 current_block_->statements->Add(store_controller); |
| 6939 | 6975 |
| 6940 // return :controller.stream; | 6976 // return :controller.stream; |
| 6941 ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos, | 6977 ReturnNode* return_node = new(Z) ReturnNode(TokenDescriptor::kNoSource, |
| 6942 new(Z) InstanceGetterNode(Token::kNoSourcePos, | 6978 new(Z) InstanceGetterNode(TokenDescriptor::kNoSource, |
| 6943 new(Z) LoadLocalNode(Token::kNoSourcePos, | 6979 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 6944 controller_var), | 6980 controller_var), |
| 6945 Symbols::Stream())); | 6981 Symbols::Stream())); |
| 6946 current_block_->statements->Add(return_node); | 6982 current_block_->statements->Add(return_node); |
| 6947 return CloseBlock(); | 6983 return CloseBlock(); |
| 6948 } | 6984 } |
| 6949 | 6985 |
| 6950 | 6986 |
| 6951 void Parser::OpenAsyncGeneratorClosure() { | 6987 void Parser::OpenAsyncGeneratorClosure() { |
| 6952 async_temp_scope_ = current_block_->scope; | 6988 async_temp_scope_ = current_block_->scope; |
| 6953 OpenAsyncTryBlock(); | 6989 OpenAsyncTryBlock(); |
| 6954 } | 6990 } |
| 6955 | 6991 |
| 6956 | 6992 |
| 6957 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { | 6993 SequenceNode* Parser::CloseAsyncGeneratorClosure(SequenceNode* body) { |
| 6958 // We need a temporary expression to store intermediate return values. | 6994 // We need a temporary expression to store intermediate return values. |
| 6959 parsed_function()->EnsureExpressionTemp(); | 6995 parsed_function()->EnsureExpressionTemp(); |
| 6960 | 6996 |
| 6961 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); | 6997 SequenceNode* new_body = CloseAsyncGeneratorTryBlock(body); |
| 6962 ASSERT(new_body != NULL); | 6998 ASSERT(new_body != NULL); |
| 6963 ASSERT(new_body->scope() != NULL); | 6999 ASSERT(new_body->scope() != NULL); |
| 6964 return new_body; | 7000 return new_body; |
| 6965 } | 7001 } |
| 6966 | 7002 |
| 6967 | 7003 |
| 6968 // Add a return node to the sequence if necessary. | 7004 // Add a return node to the sequence if necessary. |
| 6969 void Parser::EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos) { | 7005 void Parser::EnsureHasReturnStatement(SequenceNode* seq, |
| 7006 TokenDescriptor return_pos) { |
| 6970 if ((seq->length() == 0) || | 7007 if ((seq->length() == 0) || |
| 6971 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { | 7008 !seq->NodeAt(seq->length() - 1)->IsReturnNode()) { |
| 6972 const Function& func = innermost_function(); | 7009 const Function& func = innermost_function(); |
| 6973 // The implicit return value of synchronous generator closures is false, | 7010 // The implicit return value of synchronous generator closures is false, |
| 6974 // to indicate that there are no more elements in the iterable. | 7011 // to indicate that there are no more elements in the iterable. |
| 6975 // In other cases the implicit return value is null. | 7012 // In other cases the implicit return value is null. |
| 6976 AstNode* return_value = func.IsSyncGenClosure() | 7013 AstNode* return_value = func.IsSyncGenClosure() |
| 6977 ? new LiteralNode(return_pos, Bool::False()) | 7014 ? new LiteralNode(return_pos, Bool::False()) |
| 6978 : new LiteralNode(return_pos, Instance::ZoneHandle()); | 7015 : new LiteralNode(return_pos, Instance::ZoneHandle()); |
| 6979 seq->Add(new ReturnNode(return_pos, return_value)); | 7016 seq->Add(new ReturnNode(return_pos, return_value)); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7027 const Class& completer = | 7064 const Class& completer = |
| 7028 Class::ZoneHandle(Z, I->object_store()->completer_class()); | 7065 Class::ZoneHandle(Z, I->object_store()->completer_class()); |
| 7029 ASSERT(!completer.IsNull()); | 7066 ASSERT(!completer.IsNull()); |
| 7030 const Function& completer_constructor = Function::ZoneHandle(Z, | 7067 const Function& completer_constructor = Function::ZoneHandle(Z, |
| 7031 completer.LookupFunction(Symbols::CompleterSyncConstructor())); | 7068 completer.LookupFunction(Symbols::CompleterSyncConstructor())); |
| 7032 ASSERT(!completer_constructor.IsNull()); | 7069 ASSERT(!completer_constructor.IsNull()); |
| 7033 | 7070 |
| 7034 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 7071 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
| 7035 Symbols::AsyncCompleter(), false); | 7072 Symbols::AsyncCompleter(), false); |
| 7036 | 7073 |
| 7037 const intptr_t token_pos = ST(closure_body->token_pos()); | 7074 const TokenDescriptor token_pos = ST(closure_body->token_pos()); |
| 7038 // Add to AST: | 7075 // Add to AST: |
| 7039 // :async_completer = new Completer.sync(); | 7076 // :async_completer = new Completer.sync(); |
| 7040 ArgumentListNode* empty_args = | 7077 ArgumentListNode* empty_args = |
| 7041 new (Z) ArgumentListNode(token_pos); | 7078 new (Z) ArgumentListNode(token_pos); |
| 7042 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( | 7079 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( |
| 7043 token_pos, | 7080 token_pos, |
| 7044 TypeArguments::ZoneHandle(Z), | 7081 TypeArguments::ZoneHandle(Z), |
| 7045 completer_constructor, | 7082 completer_constructor, |
| 7046 empty_args); | 7083 empty_args); |
| 7047 StoreLocalNode* store_completer = new (Z) StoreLocalNode( | 7084 StoreLocalNode* store_completer = new (Z) StoreLocalNode( |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7273 | 7310 |
| 7274 void Parser::CaptureInstantiator() { | 7311 void Parser::CaptureInstantiator() { |
| 7275 ASSERT(current_block_->scope->function_level() > 0); | 7312 ASSERT(current_block_->scope->function_level() > 0); |
| 7276 const String* variable_name = current_function().IsInFactoryScope() ? | 7313 const String* variable_name = current_function().IsInFactoryScope() ? |
| 7277 &Symbols::TypeArgumentsParameter() : &Symbols::This(); | 7314 &Symbols::TypeArgumentsParameter() : &Symbols::This(); |
| 7278 current_block_->scope->CaptureVariable( | 7315 current_block_->scope->CaptureVariable( |
| 7279 current_block_->scope->LookupVariable(*variable_name, true)); | 7316 current_block_->scope->LookupVariable(*variable_name, true)); |
| 7280 } | 7317 } |
| 7281 | 7318 |
| 7282 | 7319 |
| 7283 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 7320 AstNode* Parser::LoadReceiver(TokenDescriptor token_pos) { |
| 7284 // A nested function may access 'this', referring to the receiver of the | 7321 // A nested function may access 'this', referring to the receiver of the |
| 7285 // outermost enclosing function. | 7322 // outermost enclosing function. |
| 7286 const bool kTestOnly = false; | 7323 const bool kTestOnly = false; |
| 7287 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 7324 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 7288 if (receiver == NULL) { | 7325 if (receiver == NULL) { |
| 7289 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 7326 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
| 7290 } | 7327 } |
| 7291 return new(Z) LoadLocalNode(TokenPos(), receiver); | 7328 return new(Z) LoadLocalNode(TokenPos(), receiver); |
| 7292 } | 7329 } |
| 7293 | 7330 |
| 7294 | 7331 |
| 7295 InstanceGetterNode* Parser::CallGetter(intptr_t token_pos, | 7332 InstanceGetterNode* Parser::CallGetter(TokenDescriptor token_pos, |
| 7296 AstNode* object, | 7333 AstNode* object, |
| 7297 const String& name) { | 7334 const String& name) { |
| 7298 return new(Z) InstanceGetterNode(token_pos, object, name); | 7335 return new(Z) InstanceGetterNode(token_pos, object, name); |
| 7299 } | 7336 } |
| 7300 | 7337 |
| 7301 | 7338 |
| 7302 // Returns ast nodes of the variable initialization. | 7339 // Returns ast nodes of the variable initialization. |
| 7303 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 7340 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 7304 bool is_final, | 7341 bool is_final, |
| 7305 bool is_const, | 7342 bool is_const, |
| 7306 SequenceNode** await_preamble) { | 7343 SequenceNode** await_preamble) { |
| 7307 TRACE_PARSER("ParseVariableDeclaration"); | 7344 TRACE_PARSER("ParseVariableDeclaration"); |
| 7308 ASSERT(IsIdentifier()); | 7345 ASSERT(IsIdentifier()); |
| 7309 const intptr_t ident_pos = TokenPos(); | 7346 const TokenDescriptor ident_pos = TokenPos(); |
| 7310 const String& ident = *CurrentLiteral(); | 7347 const String& ident = *CurrentLiteral(); |
| 7311 ConsumeToken(); // Variable identifier. | 7348 ConsumeToken(); // Variable identifier. |
| 7312 const intptr_t assign_pos = TokenPos(); | 7349 const TokenDescriptor assign_pos = TokenPos(); |
| 7313 AstNode* initialization = NULL; | 7350 AstNode* initialization = NULL; |
| 7314 LocalVariable* variable = NULL; | 7351 LocalVariable* variable = NULL; |
| 7315 if (CurrentToken() == Token::kASSIGN) { | 7352 if (CurrentToken() == Token::kASSIGN) { |
| 7316 // Variable initialization. | 7353 // Variable initialization. |
| 7317 ConsumeToken(); | 7354 ConsumeToken(); |
| 7318 AstNode* expr = ParseAwaitableExpr( | 7355 AstNode* expr = ParseAwaitableExpr( |
| 7319 is_const, kConsumeCascades, await_preamble); | 7356 is_const, kConsumeCascades, await_preamble); |
| 7320 const intptr_t expr_end_pos = TokenPos(); | 7357 const TokenDescriptor expr_end_pos = TokenPos(); |
| 7321 variable = new(Z) LocalVariable( | 7358 variable = new(Z) LocalVariable( |
| 7322 expr_end_pos, ident, type); | 7359 expr_end_pos, ident, type); |
| 7323 initialization = new(Z) StoreLocalNode( | 7360 initialization = new(Z) StoreLocalNode( |
| 7324 assign_pos, variable, expr); | 7361 assign_pos, variable, expr); |
| 7325 if (is_const) { | 7362 if (is_const) { |
| 7326 ASSERT(expr->IsLiteralNode()); | 7363 ASSERT(expr->IsLiteralNode()); |
| 7327 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 7364 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 7328 } | 7365 } |
| 7329 } else if (is_final || is_const) { | 7366 } else if (is_final || is_const) { |
| 7330 ReportError(ident_pos, | 7367 ReportError(ident_pos, |
| 7331 "missing initialization of 'final' or 'const' variable"); | 7368 "missing initialization of 'final' or 'const' variable"); |
| 7332 } else { | 7369 } else { |
| 7333 // Initialize variable with null. | 7370 // Initialize variable with null. |
| 7334 variable = new(Z) LocalVariable( | 7371 variable = new(Z) LocalVariable( |
| 7335 assign_pos, ident, type); | 7372 assign_pos, ident, type); |
| 7336 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance()); | 7373 AstNode* null_expr = new(Z) LiteralNode(ident_pos, Object::null_instance()); |
| 7337 initialization = new(Z) StoreLocalNode( | 7374 initialization = new(Z) StoreLocalNode( |
| 7338 ident_pos, variable, null_expr); | 7375 ident_pos, variable, null_expr); |
| 7339 } | 7376 } |
| 7340 | 7377 |
| 7341 ASSERT(current_block_ != NULL); | 7378 ASSERT(current_block_ != NULL); |
| 7342 const intptr_t previous_pos = | 7379 const TokenDescriptor previous_pos = |
| 7343 current_block_->scope->PreviousReferencePos(ident); | 7380 current_block_->scope->PreviousReferencePos(ident); |
| 7344 if (previous_pos >= 0) { | 7381 if (previous_pos.IsReal()) { |
| 7345 ASSERT(!script_.IsNull()); | 7382 ASSERT(!script_.IsNull()); |
| 7346 if (previous_pos > ident_pos) { | 7383 if (previous_pos > ident_pos) { |
| 7347 ReportError(ident_pos, | 7384 ReportError(ident_pos, |
| 7348 "initializer of '%s' may not refer to itself", | 7385 "initializer of '%s' may not refer to itself", |
| 7349 ident.ToCString()); | 7386 ident.ToCString()); |
| 7350 | 7387 |
| 7351 } else { | 7388 } else { |
| 7352 intptr_t line_number; | 7389 intptr_t line_number; |
| 7353 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7390 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| 7354 ReportError(ident_pos, | 7391 ReportError(ident_pos, |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7461 | 7498 |
| 7462 | 7499 |
| 7463 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 7500 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 7464 TRACE_PARSER("ParseFunctionStatement"); | 7501 TRACE_PARSER("ParseFunctionStatement"); |
| 7465 AbstractType& result_type = AbstractType::Handle(Z); | 7502 AbstractType& result_type = AbstractType::Handle(Z); |
| 7466 const String* variable_name = NULL; | 7503 const String* variable_name = NULL; |
| 7467 const String* function_name = NULL; | 7504 const String* function_name = NULL; |
| 7468 | 7505 |
| 7469 result_type = Type::DynamicType(); | 7506 result_type = Type::DynamicType(); |
| 7470 | 7507 |
| 7471 const intptr_t function_pos = TokenPos(); | 7508 const TokenDescriptor function_pos = TokenPos(); |
| 7472 intptr_t metadata_pos = Token::kNoSourcePos; | 7509 TokenDescriptor metadata_pos = TokenDescriptor::kNoSource; |
| 7473 if (is_literal) { | 7510 if (is_literal) { |
| 7474 ASSERT(CurrentToken() == Token::kLPAREN); | 7511 ASSERT(CurrentToken() == Token::kLPAREN); |
| 7475 function_name = &Symbols::AnonymousClosure(); | 7512 function_name = &Symbols::AnonymousClosure(); |
| 7476 } else { | 7513 } else { |
| 7477 metadata_pos = SkipMetadata(); | 7514 metadata_pos = SkipMetadata(); |
| 7478 if (CurrentToken() == Token::kVOID) { | 7515 if (CurrentToken() == Token::kVOID) { |
| 7479 ConsumeToken(); | 7516 ConsumeToken(); |
| 7480 result_type = Type::VoidType(); | 7517 result_type = Type::VoidType(); |
| 7481 } else if ((CurrentToken() == Token::kIDENT) && | 7518 } else if ((CurrentToken() == Token::kIDENT) && |
| 7482 (LookaheadToken(1) != Token::kLPAREN)) { | 7519 (LookaheadToken(1) != Token::kLPAREN)) { |
| 7483 result_type = ParseType(ClassFinalizer::kCanonicalize); | 7520 result_type = ParseType(ClassFinalizer::kCanonicalize); |
| 7484 } | 7521 } |
| 7485 const intptr_t name_pos = TokenPos(); | 7522 const TokenDescriptor name_pos = TokenPos(); |
| 7486 variable_name = ExpectIdentifier("function name expected"); | 7523 variable_name = ExpectIdentifier("function name expected"); |
| 7487 function_name = variable_name; | 7524 function_name = variable_name; |
| 7488 | 7525 |
| 7489 // Check that the function name has not been referenced | 7526 // Check that the function name has not been referenced |
| 7490 // before this declaration. | 7527 // before this declaration. |
| 7491 ASSERT(current_block_ != NULL); | 7528 ASSERT(current_block_ != NULL); |
| 7492 const intptr_t previous_pos = | 7529 const TokenDescriptor previous_pos = |
| 7493 current_block_->scope->PreviousReferencePos(*function_name); | 7530 current_block_->scope->PreviousReferencePos(*function_name); |
| 7494 if (previous_pos >= 0) { | 7531 if (previous_pos.IsReal()) { |
| 7495 ASSERT(!script_.IsNull()); | 7532 ASSERT(!script_.IsNull()); |
| 7496 intptr_t line_number; | 7533 intptr_t line_number; |
| 7497 script_.GetTokenLocation(previous_pos, &line_number, NULL); | 7534 script_.GetTokenLocation(previous_pos, &line_number, NULL); |
| 7498 ReportError(name_pos, | 7535 ReportError(name_pos, |
| 7499 "identifier '%s' previously used in line %" Pd "", | 7536 "identifier '%s' previously used in line %" Pd "", |
| 7500 function_name->ToCString(), | 7537 function_name->ToCString(), |
| 7501 line_number); | 7538 line_number); |
| 7502 } | 7539 } |
| 7503 } | 7540 } |
| 7504 CheckToken(Token::kLPAREN); | 7541 CheckToken(Token::kLPAREN); |
| 7505 | 7542 |
| 7506 // Check whether we have parsed this closure function before, in a previous | 7543 // Check whether we have parsed this closure function before, in a previous |
| 7507 // compilation. If so, reuse the function object, else create a new one | 7544 // compilation. If so, reuse the function object, else create a new one |
| 7508 // and register it in the current class. | 7545 // and register it in the current class. |
| 7509 // Note that we cannot share the same closure function between the closurized | 7546 // Note that we cannot share the same closure function between the closurized |
| 7510 // and non-closurized versions of the same parent function. | 7547 // and non-closurized versions of the same parent function. |
| 7511 Function& function = Function::ZoneHandle(Z); | 7548 Function& function = Function::ZoneHandle(Z); |
| 7512 // TODO(hausner): There could be two different closures at the given | 7549 // TODO(hausner): There could be two different closures at the given |
| 7513 // function_pos, one enclosed in a closurized function and one enclosed in the | 7550 // function_pos, one enclosed in a closurized function and one enclosed in the |
| 7514 // non-closurized version of this same function. | 7551 // non-closurized version of this same function. |
| 7515 function = I->LookupClosureFunction(innermost_function(), function_pos); | 7552 function = I->LookupClosureFunction(innermost_function(), function_pos); |
| 7516 if (function.IsNull()) { | 7553 if (function.IsNull()) { |
| 7517 // The function will be registered in the lookup table by the | 7554 // The function will be registered in the lookup table by the |
| 7518 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 7555 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
| 7519 // function has been properly setup. | 7556 // function has been properly setup. |
| 7520 function = Function::NewClosureFunction(*function_name, | 7557 function = Function::NewClosureFunction(*function_name, |
| 7521 innermost_function(), | 7558 innermost_function(), |
| 7522 function_pos); | 7559 function_pos); |
| 7523 function.set_result_type(result_type); | 7560 function.set_result_type(result_type); |
| 7524 if (FLAG_enable_mirrors && (metadata_pos >= 0)) { | 7561 if (FLAG_enable_mirrors && metadata_pos.IsReal()) { |
| 7525 library_.AddFunctionMetadata(function, metadata_pos); | 7562 library_.AddFunctionMetadata(function, metadata_pos); |
| 7526 } | 7563 } |
| 7527 } | 7564 } |
| 7528 | 7565 |
| 7529 // The function type needs to be finalized at compile time, since the closure | 7566 // The function type needs to be finalized at compile time, since the closure |
| 7530 // may be type checked at run time when assigned to a function variable, | 7567 // may be type checked at run time when assigned to a function variable, |
| 7531 // passed as a function argument, or returned as a function result. | 7568 // passed as a function argument, or returned as a function result. |
| 7532 | 7569 |
| 7533 LocalVariable* function_variable = NULL; | 7570 LocalVariable* function_variable = NULL; |
| 7534 FunctionType& function_type = FunctionType::ZoneHandle(Z); | 7571 FunctionType& function_type = FunctionType::ZoneHandle(Z); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7790 // | const [type] ident (';' | '=' | ',') | 7827 // | const [type] ident (';' | '=' | ',') |
| 7791 // | type ident (';' | '=' | ',') | 7828 // | type ident (';' | '=' | ',') |
| 7792 // Token position remains unchanged. | 7829 // Token position remains unchanged. |
| 7793 bool Parser::IsVariableDeclaration() { | 7830 bool Parser::IsVariableDeclaration() { |
| 7794 if ((CurrentToken() == Token::kVAR) || | 7831 if ((CurrentToken() == Token::kVAR) || |
| 7795 (CurrentToken() == Token::kFINAL)) { | 7832 (CurrentToken() == Token::kFINAL)) { |
| 7796 return true; | 7833 return true; |
| 7797 } | 7834 } |
| 7798 // Skip optional metadata. | 7835 // Skip optional metadata. |
| 7799 if (CurrentToken() == Token::kAT) { | 7836 if (CurrentToken() == Token::kAT) { |
| 7800 const intptr_t saved_pos = TokenPos(); | 7837 const TokenDescriptor saved_pos = TokenPos(); |
| 7801 SkipMetadata(); | 7838 SkipMetadata(); |
| 7802 const bool is_var_decl = IsVariableDeclaration(); | 7839 const bool is_var_decl = IsVariableDeclaration(); |
| 7803 SetPosition(saved_pos); | 7840 SetPosition(saved_pos); |
| 7804 return is_var_decl; | 7841 return is_var_decl; |
| 7805 } | 7842 } |
| 7806 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { | 7843 if ((CurrentToken() != Token::kIDENT) && (CurrentToken() != Token::kCONST)) { |
| 7807 // Not a legal type identifier or const keyword or metadata. | 7844 // Not a legal type identifier or const keyword or metadata. |
| 7808 return false; | 7845 return false; |
| 7809 } | 7846 } |
| 7810 const intptr_t saved_pos = TokenPos(); | 7847 const TokenDescriptor saved_pos = TokenPos(); |
| 7811 bool is_var_decl = false; | 7848 bool is_var_decl = false; |
| 7812 bool have_type = false; | 7849 bool have_type = false; |
| 7813 if (CurrentToken() == Token::kCONST) { | 7850 if (CurrentToken() == Token::kCONST) { |
| 7814 ConsumeToken(); | 7851 ConsumeToken(); |
| 7815 have_type = true; // Type is dynamic. | 7852 have_type = true; // Type is dynamic. |
| 7816 } | 7853 } |
| 7817 if (IsIdentifier()) { // Type or variable name. | 7854 if (IsIdentifier()) { // Type or variable name. |
| 7818 Token::Kind follower = LookaheadToken(1); | 7855 Token::Kind follower = LookaheadToken(1); |
| 7819 if ((follower == Token::kLT) || // Parameterized type. | 7856 if ((follower == Token::kLT) || // Parameterized type. |
| 7820 (follower == Token::kPERIOD) || // Qualified class name of type. | 7857 (follower == Token::kPERIOD) || // Qualified class name of type. |
| 7821 Token::IsIdentifier(follower)) { // Variable name following a type. | 7858 Token::IsIdentifier(follower)) { // Variable name following a type. |
| 7822 // We see the beginning of something that could be a type. | 7859 // We see the beginning of something that could be a type. |
| 7823 const intptr_t type_pos = TokenPos(); | 7860 const TokenDescriptor type_pos = TokenPos(); |
| 7824 if (TryParseOptionalType()) { | 7861 if (TryParseOptionalType()) { |
| 7825 have_type = true; | 7862 have_type = true; |
| 7826 } else { | 7863 } else { |
| 7827 SetPosition(type_pos); | 7864 SetPosition(type_pos); |
| 7828 } | 7865 } |
| 7829 } | 7866 } |
| 7830 if (have_type && IsIdentifier()) { | 7867 if (have_type && IsIdentifier()) { |
| 7831 ConsumeToken(); | 7868 ConsumeToken(); |
| 7832 if ((CurrentToken() == Token::kSEMICOLON) || | 7869 if ((CurrentToken() == Token::kSEMICOLON) || |
| 7833 (CurrentToken() == Token::kCOMMA) || | 7870 (CurrentToken() == Token::kCOMMA) || |
| 7834 (CurrentToken() == Token::kASSIGN)) { | 7871 (CurrentToken() == Token::kASSIGN)) { |
| 7835 is_var_decl = true; | 7872 is_var_decl = true; |
| 7836 } | 7873 } |
| 7837 } | 7874 } |
| 7838 } | 7875 } |
| 7839 SetPosition(saved_pos); | 7876 SetPosition(saved_pos); |
| 7840 return is_var_decl; | 7877 return is_var_decl; |
| 7841 } | 7878 } |
| 7842 | 7879 |
| 7843 | 7880 |
| 7844 // Look ahead to detect whether the next tokens should be parsed as | 7881 // Look ahead to detect whether the next tokens should be parsed as |
| 7845 // a function declaration. Token position remains unchanged. | 7882 // a function declaration. Token position remains unchanged. |
| 7846 bool Parser::IsFunctionDeclaration() { | 7883 bool Parser::IsFunctionDeclaration() { |
| 7847 const intptr_t saved_pos = TokenPos(); | 7884 const TokenDescriptor saved_pos = TokenPos(); |
| 7848 bool is_external = false; | 7885 bool is_external = false; |
| 7849 SkipMetadata(); | 7886 SkipMetadata(); |
| 7850 if (is_top_level_) { | 7887 if (is_top_level_) { |
| 7851 if (is_patch_source() && | 7888 if (is_patch_source() && |
| 7852 (CurrentToken() == Token::kIDENT) && | 7889 (CurrentToken() == Token::kIDENT) && |
| 7853 CurrentLiteral()->Equals("patch") && | 7890 CurrentLiteral()->Equals("patch") && |
| 7854 (LookaheadToken(1) != Token::kLPAREN)) { | 7891 (LookaheadToken(1) != Token::kLPAREN)) { |
| 7855 // Skip over 'patch' for top-level function declarations in patch sources. | 7892 // Skip over 'patch' for top-level function declarations in patch sources. |
| 7856 ConsumeToken(); | 7893 ConsumeToken(); |
| 7857 } else if (CurrentToken() == Token::kEXTERNAL) { | 7894 } else if (CurrentToken() == Token::kEXTERNAL) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 7885 SetPosition(saved_pos); | 7922 SetPosition(saved_pos); |
| 7886 return true; | 7923 return true; |
| 7887 } | 7924 } |
| 7888 } | 7925 } |
| 7889 SetPosition(saved_pos); | 7926 SetPosition(saved_pos); |
| 7890 return false; | 7927 return false; |
| 7891 } | 7928 } |
| 7892 | 7929 |
| 7893 | 7930 |
| 7894 bool Parser::IsTopLevelAccessor() { | 7931 bool Parser::IsTopLevelAccessor() { |
| 7895 const intptr_t saved_pos = TokenPos(); | 7932 const TokenDescriptor saved_pos = TokenPos(); |
| 7896 if (is_patch_source() && IsSymbol(Symbols::Patch())) { | 7933 if (is_patch_source() && IsSymbol(Symbols::Patch())) { |
| 7897 ConsumeToken(); | 7934 ConsumeToken(); |
| 7898 } else if (CurrentToken() == Token::kEXTERNAL) { | 7935 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 7899 ConsumeToken(); | 7936 ConsumeToken(); |
| 7900 } | 7937 } |
| 7901 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 7938 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 7902 SetPosition(saved_pos); | 7939 SetPosition(saved_pos); |
| 7903 return true; | 7940 return true; |
| 7904 } | 7941 } |
| 7905 if (TryParseReturnType()) { | 7942 if (TryParseReturnType()) { |
| 7906 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 7943 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 7907 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 7944 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
| 7908 SetPosition(saved_pos); | 7945 SetPosition(saved_pos); |
| 7909 return true; | 7946 return true; |
| 7910 } | 7947 } |
| 7911 } | 7948 } |
| 7912 } | 7949 } |
| 7913 SetPosition(saved_pos); | 7950 SetPosition(saved_pos); |
| 7914 return false; | 7951 return false; |
| 7915 } | 7952 } |
| 7916 | 7953 |
| 7917 | 7954 |
| 7918 bool Parser::IsFunctionLiteral() { | 7955 bool Parser::IsFunctionLiteral() { |
| 7919 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { | 7956 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { |
| 7920 return false; | 7957 return false; |
| 7921 } | 7958 } |
| 7922 const intptr_t saved_pos = TokenPos(); | 7959 const TokenDescriptor saved_pos = TokenPos(); |
| 7923 bool is_function_literal = false; | 7960 bool is_function_literal = false; |
| 7924 SkipToMatchingParenthesis(); | 7961 SkipToMatchingParenthesis(); |
| 7925 ParseFunctionModifier(); | 7962 ParseFunctionModifier(); |
| 7926 if ((CurrentToken() == Token::kLBRACE) || | 7963 if ((CurrentToken() == Token::kLBRACE) || |
| 7927 (CurrentToken() == Token::kARROW)) { | 7964 (CurrentToken() == Token::kARROW)) { |
| 7928 is_function_literal = true; | 7965 is_function_literal = true; |
| 7929 } | 7966 } |
| 7930 SetPosition(saved_pos); | 7967 SetPosition(saved_pos); |
| 7931 return is_function_literal; | 7968 return is_function_literal; |
| 7932 } | 7969 } |
| 7933 | 7970 |
| 7934 | 7971 |
| 7935 // Current token position is the token after the opening ( of the for | 7972 // Current token position is the token after the opening ( of the for |
| 7936 // statement. Returns true if we recognize a for ( .. in expr) | 7973 // statement. Returns true if we recognize a for ( .. in expr) |
| 7937 // statement. | 7974 // statement. |
| 7938 bool Parser::IsForInStatement() { | 7975 bool Parser::IsForInStatement() { |
| 7939 const intptr_t saved_pos = TokenPos(); | 7976 const TokenDescriptor saved_pos = TokenPos(); |
| 7940 bool result = false; | 7977 bool result = false; |
| 7941 // Allow const modifier as well when recognizing a for-in statement | 7978 // Allow const modifier as well when recognizing a for-in statement |
| 7942 // pattern. We will get an error later if the loop variable is | 7979 // pattern. We will get an error later if the loop variable is |
| 7943 // declared with const. | 7980 // declared with const. |
| 7944 if (CurrentToken() == Token::kVAR || | 7981 if (CurrentToken() == Token::kVAR || |
| 7945 CurrentToken() == Token::kFINAL || | 7982 CurrentToken() == Token::kFINAL || |
| 7946 CurrentToken() == Token::kCONST) { | 7983 CurrentToken() == Token::kCONST) { |
| 7947 ConsumeToken(); | 7984 ConsumeToken(); |
| 7948 } | 7985 } |
| 7949 if (IsIdentifier()) { | 7986 if (IsIdentifier()) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7981 return false; | 8018 return false; |
| 7982 } | 8019 } |
| 7983 | 8020 |
| 7984 | 8021 |
| 7985 void Parser::ParseStatementSequence() { | 8022 void Parser::ParseStatementSequence() { |
| 7986 TRACE_PARSER("ParseStatementSequence"); | 8023 TRACE_PARSER("ParseStatementSequence"); |
| 7987 const bool dead_code_allowed = true; | 8024 const bool dead_code_allowed = true; |
| 7988 bool abrupt_completing_seen = false; | 8025 bool abrupt_completing_seen = false; |
| 7989 RecursionChecker rc(this); | 8026 RecursionChecker rc(this); |
| 7990 while (CurrentToken() != Token::kRBRACE) { | 8027 while (CurrentToken() != Token::kRBRACE) { |
| 7991 const intptr_t statement_pos = TokenPos(); | 8028 const TokenDescriptor statement_pos = TokenPos(); |
| 7992 AstNode* statement = ParseStatement(); | 8029 AstNode* statement = ParseStatement(); |
| 7993 // Do not add statements with no effect (e.g., LoadLocalNode). | 8030 // Do not add statements with no effect (e.g., LoadLocalNode). |
| 7994 if ((statement != NULL) && statement->IsLoadLocalNode()) { | 8031 if ((statement != NULL) && statement->IsLoadLocalNode()) { |
| 7995 // Skip load local. | 8032 // Skip load local. |
| 7996 continue; | 8033 continue; |
| 7997 } | 8034 } |
| 7998 if (statement != NULL) { | 8035 if (statement != NULL) { |
| 7999 if (!dead_code_allowed && abrupt_completing_seen) { | 8036 if (!dead_code_allowed && abrupt_completing_seen) { |
| 8000 ReportError(statement_pos, | 8037 ReportError(statement_pos, |
| 8001 "dead code after abrupt completing statement"); | 8038 "dead code after abrupt completing statement"); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8033 } | 8070 } |
| 8034 } | 8071 } |
| 8035 SequenceNode* sequence = CloseBlock(); | 8072 SequenceNode* sequence = CloseBlock(); |
| 8036 return sequence; | 8073 return sequence; |
| 8037 } | 8074 } |
| 8038 | 8075 |
| 8039 | 8076 |
| 8040 AstNode* Parser::ParseIfStatement(String* label_name) { | 8077 AstNode* Parser::ParseIfStatement(String* label_name) { |
| 8041 TRACE_PARSER("ParseIfStatement"); | 8078 TRACE_PARSER("ParseIfStatement"); |
| 8042 ASSERT(CurrentToken() == Token::kIF); | 8079 ASSERT(CurrentToken() == Token::kIF); |
| 8043 const intptr_t if_pos = TokenPos(); | 8080 const TokenDescriptor if_pos = TokenPos(); |
| 8044 SourceLabel* label = NULL; | 8081 SourceLabel* label = NULL; |
| 8045 if (label_name != NULL) { | 8082 if (label_name != NULL) { |
| 8046 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); | 8083 label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement); |
| 8047 OpenBlock(); | 8084 OpenBlock(); |
| 8048 current_block_->scope->AddLabel(label); | 8085 current_block_->scope->AddLabel(label); |
| 8049 } | 8086 } |
| 8050 ConsumeToken(); | 8087 ConsumeToken(); |
| 8051 ExpectToken(Token::kLPAREN); | 8088 ExpectToken(Token::kLPAREN); |
| 8052 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8089 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8053 ExpectToken(Token::kRPAREN); | 8090 ExpectToken(Token::kRPAREN); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8088 // of a LiteralNode. | 8125 // of a LiteralNode. |
| 8089 RawClass* Parser::CheckCaseExpressions( | 8126 RawClass* Parser::CheckCaseExpressions( |
| 8090 const GrowableArray<LiteralNode*>& values) { | 8127 const GrowableArray<LiteralNode*>& values) { |
| 8091 const intptr_t num_expressions = values.length(); | 8128 const intptr_t num_expressions = values.length(); |
| 8092 if (num_expressions == 0) { | 8129 if (num_expressions == 0) { |
| 8093 return Object::dynamic_class(); | 8130 return Object::dynamic_class(); |
| 8094 } | 8131 } |
| 8095 const Instance& first_value = values[0]->literal(); | 8132 const Instance& first_value = values[0]->literal(); |
| 8096 for (intptr_t i = 0; i < num_expressions; i++) { | 8133 for (intptr_t i = 0; i < num_expressions; i++) { |
| 8097 const Instance& val = values[i]->literal(); | 8134 const Instance& val = values[i]->literal(); |
| 8098 const intptr_t val_pos = values[i]->token_pos(); | 8135 const TokenDescriptor val_pos = values[i]->token_pos(); |
| 8099 if (first_value.IsInteger()) { | 8136 if (first_value.IsInteger()) { |
| 8100 if (!val.IsInteger()) { | 8137 if (!val.IsInteger()) { |
| 8101 ReportError(val_pos, "expected case expression of type int"); | 8138 ReportError(val_pos, "expected case expression of type int"); |
| 8102 } | 8139 } |
| 8103 continue; | 8140 continue; |
| 8104 } | 8141 } |
| 8105 if (first_value.IsString()) { | 8142 if (first_value.IsString()) { |
| 8106 if (!val.IsString()) { | 8143 if (!val.IsString()) { |
| 8107 ReportError(val_pos, "expected case expression of type String"); | 8144 ReportError(val_pos, "expected case expression of type String"); |
| 8108 } | 8145 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 8136 } | 8173 } |
| 8137 return first_value.clazz(); | 8174 return first_value.clazz(); |
| 8138 } | 8175 } |
| 8139 | 8176 |
| 8140 | 8177 |
| 8141 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 8178 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 8142 GrowableArray<LiteralNode*>* case_expr_values, | 8179 GrowableArray<LiteralNode*>* case_expr_values, |
| 8143 SourceLabel* case_label) { | 8180 SourceLabel* case_label) { |
| 8144 TRACE_PARSER("ParseCaseClause"); | 8181 TRACE_PARSER("ParseCaseClause"); |
| 8145 bool default_seen = false; | 8182 bool default_seen = false; |
| 8146 const intptr_t case_pos = TokenPos(); | 8183 const TokenDescriptor case_pos = TokenPos(); |
| 8147 // The case expressions node sequence does not own the enclosing scope. | 8184 // The case expressions node sequence does not own the enclosing scope. |
| 8148 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); | 8185 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); |
| 8149 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 8186 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 8150 if (CurrentToken() == Token::kCASE) { | 8187 if (CurrentToken() == Token::kCASE) { |
| 8151 if (default_seen) { | 8188 if (default_seen) { |
| 8152 ReportError("default clause must be last case"); | 8189 ReportError("default clause must be last case"); |
| 8153 } | 8190 } |
| 8154 ConsumeToken(); // Keyword case. | 8191 ConsumeToken(); // Keyword case. |
| 8155 const intptr_t expr_pos = TokenPos(); | 8192 const TokenDescriptor expr_pos = TokenPos(); |
| 8156 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); | 8193 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
| 8157 ASSERT(expr->IsLiteralNode()); | 8194 ASSERT(expr->IsLiteralNode()); |
| 8158 case_expr_values->Add(expr->AsLiteralNode()); | 8195 case_expr_values->Add(expr->AsLiteralNode()); |
| 8159 | 8196 |
| 8160 AstNode* switch_expr_load = new(Z) LoadLocalNode( | 8197 AstNode* switch_expr_load = new(Z) LoadLocalNode( |
| 8161 case_pos, switch_expr_value); | 8198 case_pos, switch_expr_value); |
| 8162 AstNode* case_comparison = new(Z) ComparisonNode( | 8199 AstNode* case_comparison = new(Z) ComparisonNode( |
| 8163 expr_pos, Token::kEQ, expr, switch_expr_load); | 8200 expr_pos, Token::kEQ, expr, switch_expr_load); |
| 8164 case_expressions->Add(case_comparison); | 8201 case_expressions->Add(case_comparison); |
| 8165 } else { | 8202 } else { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 8188 if (next_token == Token::kRBRACE) { | 8225 if (next_token == Token::kRBRACE) { |
| 8189 // End of switch statement. | 8226 // End of switch statement. |
| 8190 break; | 8227 break; |
| 8191 } | 8228 } |
| 8192 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 8229 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
| 8193 // End of this case clause. If there is a possible fall-through to | 8230 // End of this case clause. If there is a possible fall-through to |
| 8194 // the next case clause, throw an implicit FallThroughError. | 8231 // the next case clause, throw an implicit FallThroughError. |
| 8195 if (!abrupt_completing_seen) { | 8232 if (!abrupt_completing_seen) { |
| 8196 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); | 8233 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); |
| 8197 arguments->Add(new(Z) LiteralNode( | 8234 arguments->Add(new(Z) LiteralNode( |
| 8198 TokenPos(), Integer::ZoneHandle(Z, Integer::New(TokenPos())))); | 8235 TokenPos(), |
| 8236 Integer::ZoneHandle(Z, Integer::New(TokenPos().value())))); |
| 8199 current_block_->statements->Add( | 8237 current_block_->statements->Add( |
| 8200 MakeStaticCall(Symbols::FallThroughError(), | 8238 MakeStaticCall(Symbols::FallThroughError(), |
| 8201 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 8239 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 8202 arguments)); | 8240 arguments)); |
| 8203 } | 8241 } |
| 8204 break; | 8242 break; |
| 8205 } | 8243 } |
| 8206 // The next statement still belongs to this case. | 8244 // The next statement still belongs to this case. |
| 8207 AstNode* statement = ParseStatement(); | 8245 AstNode* statement = ParseStatement(); |
| 8208 if (statement != NULL) { | 8246 if (statement != NULL) { |
| 8209 current_block_->statements->Add(statement); | 8247 current_block_->statements->Add(statement); |
| 8210 abrupt_completing_seen |= IsAbruptCompleting(statement); | 8248 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 8211 } | 8249 } |
| 8212 } | 8250 } |
| 8213 SequenceNode* statements = CloseBlock(); | 8251 SequenceNode* statements = CloseBlock(); |
| 8214 return new(Z) CaseNode(case_pos, case_label, | 8252 return new(Z) CaseNode(case_pos, case_label, |
| 8215 case_expressions, default_seen, switch_expr_value, statements); | 8253 case_expressions, default_seen, switch_expr_value, statements); |
| 8216 } | 8254 } |
| 8217 | 8255 |
| 8218 | 8256 |
| 8219 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 8257 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
| 8220 TRACE_PARSER("ParseSwitchStatement"); | 8258 TRACE_PARSER("ParseSwitchStatement"); |
| 8221 ASSERT(CurrentToken() == Token::kSWITCH); | 8259 ASSERT(CurrentToken() == Token::kSWITCH); |
| 8222 const intptr_t switch_pos = TokenPos(); | 8260 const TokenDescriptor switch_pos = TokenPos(); |
| 8223 SourceLabel* label = | 8261 SourceLabel* label = |
| 8224 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 8262 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
| 8225 ConsumeToken(); | 8263 ConsumeToken(); |
| 8226 ExpectToken(Token::kLPAREN); | 8264 ExpectToken(Token::kLPAREN); |
| 8227 const intptr_t expr_pos = TokenPos(); | 8265 const TokenDescriptor expr_pos = TokenPos(); |
| 8228 AstNode* switch_expr = ParseAwaitableExpr( | 8266 AstNode* switch_expr = ParseAwaitableExpr( |
| 8229 kAllowConst, kConsumeCascades, NULL); | 8267 kAllowConst, kConsumeCascades, NULL); |
| 8230 ExpectToken(Token::kRPAREN); | 8268 ExpectToken(Token::kRPAREN); |
| 8231 ExpectToken(Token::kLBRACE); | 8269 ExpectToken(Token::kLBRACE); |
| 8232 OpenBlock(); | 8270 OpenBlock(); |
| 8233 current_block_->scope->AddLabel(label); | 8271 current_block_->scope->AddLabel(label); |
| 8234 | 8272 |
| 8235 // Store switch expression in temporary local variable. The type of the | 8273 // Store switch expression in temporary local variable. The type of the |
| 8236 // variable is set to dynamic. It will later be patched to match the | 8274 // variable is set to dynamic. It will later be patched to match the |
| 8237 // type of the case clause expressions. Therefore, we have to allocate | 8275 // type of the case clause expressions. Therefore, we have to allocate |
| (...skipping 13 matching lines...) Expand all Loading... |
| 8251 | 8289 |
| 8252 // Parse case clauses | 8290 // Parse case clauses |
| 8253 bool default_seen = false; | 8291 bool default_seen = false; |
| 8254 GrowableArray<LiteralNode*> case_expr_values; | 8292 GrowableArray<LiteralNode*> case_expr_values; |
| 8255 while (true) { | 8293 while (true) { |
| 8256 // Check for statement label | 8294 // Check for statement label |
| 8257 SourceLabel* case_label = NULL; | 8295 SourceLabel* case_label = NULL; |
| 8258 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 8296 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 8259 // Case statements start with a label. | 8297 // Case statements start with a label. |
| 8260 String* label_name = CurrentLiteral(); | 8298 String* label_name = CurrentLiteral(); |
| 8261 const intptr_t label_pos = TokenPos(); | 8299 const TokenDescriptor label_pos = TokenPos(); |
| 8262 ConsumeToken(); // Consume label identifier. | 8300 ConsumeToken(); // Consume label identifier. |
| 8263 ConsumeToken(); // Consume colon. | 8301 ConsumeToken(); // Consume colon. |
| 8264 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 8302 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
| 8265 if (case_label == NULL) { | 8303 if (case_label == NULL) { |
| 8266 // Label does not exist yet. Add it to scope of switch statement. | 8304 // Label does not exist yet. Add it to scope of switch statement. |
| 8267 case_label = new(Z) SourceLabel( | 8305 case_label = new(Z) SourceLabel( |
| 8268 label_pos, *label_name, SourceLabel::kCase); | 8306 label_pos, *label_name, SourceLabel::kCase); |
| 8269 current_block_->scope->AddLabel(case_label); | 8307 current_block_->scope->AddLabel(case_label); |
| 8270 } else if (case_label->kind() == SourceLabel::kForward) { | 8308 } else if (case_label->kind() == SourceLabel::kForward) { |
| 8271 // We have seen a 'continue' with this label name. Resolve | 8309 // We have seen a 'continue' with this label name. Resolve |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8311 } | 8349 } |
| 8312 | 8350 |
| 8313 SequenceNode* switch_body = CloseBlock(); | 8351 SequenceNode* switch_body = CloseBlock(); |
| 8314 ExpectToken(Token::kRBRACE); | 8352 ExpectToken(Token::kRBRACE); |
| 8315 return new(Z) SwitchNode(switch_pos, label, switch_body); | 8353 return new(Z) SwitchNode(switch_pos, label, switch_body); |
| 8316 } | 8354 } |
| 8317 | 8355 |
| 8318 | 8356 |
| 8319 AstNode* Parser::ParseWhileStatement(String* label_name) { | 8357 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 8320 TRACE_PARSER("ParseWhileStatement"); | 8358 TRACE_PARSER("ParseWhileStatement"); |
| 8321 const intptr_t while_pos = TokenPos(); | 8359 const TokenDescriptor while_pos = TokenPos(); |
| 8322 SourceLabel* label = | 8360 SourceLabel* label = |
| 8323 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 8361 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 8324 ConsumeToken(); | 8362 ConsumeToken(); |
| 8325 ExpectToken(Token::kLPAREN); | 8363 ExpectToken(Token::kLPAREN); |
| 8326 SequenceNode* await_preamble = NULL; | 8364 SequenceNode* await_preamble = NULL; |
| 8327 AstNode* cond_expr = ParseAwaitableExpr( | 8365 AstNode* cond_expr = ParseAwaitableExpr( |
| 8328 kAllowConst, kConsumeCascades, &await_preamble); | 8366 kAllowConst, kConsumeCascades, &await_preamble); |
| 8329 ExpectToken(Token::kRPAREN); | 8367 ExpectToken(Token::kRPAREN); |
| 8330 const bool parsing_loop_body = true; | 8368 const bool parsing_loop_body = true; |
| 8331 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 8369 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 8332 WhileNode* while_node = new (Z) WhileNode(while_pos, | 8370 WhileNode* while_node = new (Z) WhileNode(while_pos, |
| 8333 label, | 8371 label, |
| 8334 cond_expr, | 8372 cond_expr, |
| 8335 await_preamble, | 8373 await_preamble, |
| 8336 while_body); | 8374 while_body); |
| 8337 return while_node; | 8375 return while_node; |
| 8338 } | 8376 } |
| 8339 | 8377 |
| 8340 | 8378 |
| 8341 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 8379 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 8342 TRACE_PARSER("ParseDoWhileStatement"); | 8380 TRACE_PARSER("ParseDoWhileStatement"); |
| 8343 const intptr_t do_pos = TokenPos(); | 8381 const TokenDescriptor do_pos = TokenPos(); |
| 8344 SourceLabel* label = | 8382 SourceLabel* label = |
| 8345 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 8383 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 8346 ConsumeToken(); | 8384 ConsumeToken(); |
| 8347 const bool parsing_loop_body = true; | 8385 const bool parsing_loop_body = true; |
| 8348 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 8386 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 8349 ExpectToken(Token::kWHILE); | 8387 ExpectToken(Token::kWHILE); |
| 8350 ExpectToken(Token::kLPAREN); | 8388 ExpectToken(Token::kLPAREN); |
| 8351 SequenceNode* await_preamble = NULL; | 8389 SequenceNode* await_preamble = NULL; |
| 8352 intptr_t expr_pos = TokenPos(); | 8390 TokenDescriptor expr_pos = TokenPos(); |
| 8353 AstNode* cond_expr = | 8391 AstNode* cond_expr = |
| 8354 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); | 8392 ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble); |
| 8355 if (await_preamble != NULL) { | 8393 if (await_preamble != NULL) { |
| 8356 // Prepend the preamble to the condition. | 8394 // Prepend the preamble to the condition. |
| 8357 LetNode* await_cond = new(Z) LetNode(expr_pos); | 8395 LetNode* await_cond = new(Z) LetNode(expr_pos); |
| 8358 await_cond->AddNode(await_preamble); | 8396 await_cond->AddNode(await_preamble); |
| 8359 await_cond->AddNode(cond_expr); | 8397 await_cond->AddNode(cond_expr); |
| 8360 cond_expr = await_cond; | 8398 cond_expr = await_cond; |
| 8361 } | 8399 } |
| 8362 ExpectToken(Token::kRPAREN); | 8400 ExpectToken(Token::kRPAREN); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8443 } | 8481 } |
| 8444 | 8482 |
| 8445 | 8483 |
| 8446 // Build an AST node for static call to Dart function print(str). | 8484 // Build an AST node for static call to Dart function print(str). |
| 8447 // Used during debugging to insert print in generated dart code. | 8485 // Used during debugging to insert print in generated dart code. |
| 8448 AstNode* Parser::DartPrint(const char* str) { | 8486 AstNode* Parser::DartPrint(const char* str) { |
| 8449 const Library& lib = Library::Handle(Library::CoreLibrary()); | 8487 const Library& lib = Library::Handle(Library::CoreLibrary()); |
| 8450 const Function& print_fn = Function::ZoneHandle( | 8488 const Function& print_fn = Function::ZoneHandle( |
| 8451 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); | 8489 Z, lib.LookupFunctionAllowPrivate(Symbols::print())); |
| 8452 ASSERT(!print_fn.IsNull()); | 8490 ASSERT(!print_fn.IsNull()); |
| 8453 ArgumentListNode* one_arg = new(Z) ArgumentListNode(Token::kNoSourcePos); | 8491 ArgumentListNode* one_arg = |
| 8492 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 8454 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); | 8493 String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str)); |
| 8455 one_arg->Add(new(Z) LiteralNode(Token::kNoSourcePos, msg)); | 8494 one_arg->Add(new(Z) LiteralNode(TokenDescriptor::kNoSource, msg)); |
| 8456 AstNode* print_call = | 8495 AstNode* print_call = |
| 8457 new(Z) StaticCallNode(Token::kNoSourcePos, print_fn, one_arg); | 8496 new(Z) StaticCallNode(TokenDescriptor::kNoSource, print_fn, one_arg); |
| 8458 return print_call; | 8497 return print_call; |
| 8459 } | 8498 } |
| 8460 | 8499 |
| 8461 | 8500 |
| 8462 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 8501 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
| 8463 TRACE_PARSER("ParseAwaitForStatement"); | 8502 TRACE_PARSER("ParseAwaitForStatement"); |
| 8464 ASSERT(IsAwaitKeyword()); | 8503 ASSERT(IsAwaitKeyword()); |
| 8465 const intptr_t await_for_pos = TokenPos(); | 8504 const TokenDescriptor await_for_pos = TokenPos(); |
| 8466 ConsumeToken(); // await. | 8505 ConsumeToken(); // await. |
| 8467 ASSERT(CurrentToken() == Token::kFOR); | 8506 ASSERT(CurrentToken() == Token::kFOR); |
| 8468 ConsumeToken(); // for. | 8507 ConsumeToken(); // for. |
| 8469 ExpectToken(Token::kLPAREN); | 8508 ExpectToken(Token::kLPAREN); |
| 8470 | 8509 |
| 8471 if (!innermost_function().IsAsyncFunction() && | 8510 if (!innermost_function().IsAsyncFunction() && |
| 8472 !innermost_function().IsAsyncClosure() && | 8511 !innermost_function().IsAsyncClosure() && |
| 8473 !innermost_function().IsAsyncGenerator() && | 8512 !innermost_function().IsAsyncGenerator() && |
| 8474 !innermost_function().IsAsyncGenClosure()) { | 8513 !innermost_function().IsAsyncGenClosure()) { |
| 8475 ReportError(await_for_pos, | 8514 ReportError(await_for_pos, |
| 8476 "await for loop is only allowed in an asynchronous function"); | 8515 "await for loop is only allowed in an asynchronous function"); |
| 8477 } | 8516 } |
| 8478 | 8517 |
| 8479 // Parse loop variable. | 8518 // Parse loop variable. |
| 8480 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8519 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
| 8481 if (CurrentToken() == Token::kCONST) { | 8520 if (CurrentToken() == Token::kCONST) { |
| 8482 ReportError("Loop variable cannot be 'const'"); | 8521 ReportError("Loop variable cannot be 'const'"); |
| 8483 } | 8522 } |
| 8484 bool new_loop_var = false; | 8523 bool new_loop_var = false; |
| 8485 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8524 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
| 8486 if (LookaheadToken(1) != Token::kIN) { | 8525 if (LookaheadToken(1) != Token::kIN) { |
| 8487 // Declaration of a new loop variable. | 8526 // Declaration of a new loop variable. |
| 8488 // Delay creation of the local variable until we know its actual | 8527 // Delay creation of the local variable until we know its actual |
| 8489 // position, which is inside the loop body. | 8528 // position, which is inside the loop body. |
| 8490 new_loop_var = true; | 8529 new_loop_var = true; |
| 8491 loop_var_type = ParseConstFinalVarOrType( | 8530 loop_var_type = ParseConstFinalVarOrType( |
| 8492 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : | 8531 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
| 8493 ClassFinalizer::kIgnore); | 8532 ClassFinalizer::kIgnore); |
| 8494 } | 8533 } |
| 8495 intptr_t loop_var_pos = TokenPos(); | 8534 TokenDescriptor loop_var_pos = TokenPos(); |
| 8496 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 8535 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
| 8497 | 8536 |
| 8498 // Parse stream expression. | 8537 // Parse stream expression. |
| 8499 ExpectToken(Token::kIN); | 8538 ExpectToken(Token::kIN); |
| 8500 const intptr_t stream_expr_pos = TokenPos(); | 8539 const TokenDescriptor stream_expr_pos = TokenPos(); |
| 8501 AstNode* stream_expr = | 8540 AstNode* stream_expr = |
| 8502 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8541 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8503 ExpectToken(Token::kRPAREN); | 8542 ExpectToken(Token::kRPAREN); |
| 8504 | 8543 |
| 8505 // Open a block for the iterator variable and the try-finally | 8544 // Open a block for the iterator variable and the try-finally |
| 8506 // statement that contains the loop. | 8545 // statement that contains the loop. |
| 8507 OpenBlock(); | 8546 OpenBlock(); |
| 8508 const Block* loop_block = current_block_; | 8547 const Block* loop_block = current_block_; |
| 8509 | 8548 |
| 8510 // Build creation of implicit StreamIterator. | 8549 // Build creation of implicit StreamIterator. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8587 | 8626 |
| 8588 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 8627 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
| 8589 // here, but that does not work well because we have to insert an implicit | 8628 // here, but that does not work well because we have to insert an implicit |
| 8590 // variable assignment and potentially a variable declaration in the | 8629 // variable assignment and potentially a variable declaration in the |
| 8591 // loop body. | 8630 // loop body. |
| 8592 OpenLoopBlock(); | 8631 OpenLoopBlock(); |
| 8593 | 8632 |
| 8594 SourceLabel* label = | 8633 SourceLabel* label = |
| 8595 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); | 8634 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); |
| 8596 current_block_->scope->AddLabel(label); | 8635 current_block_->scope->AddLabel(label); |
| 8597 const intptr_t loop_var_assignment_pos = TokenPos(); | 8636 const TokenDescriptor loop_var_assignment_pos = TokenPos(); |
| 8598 | 8637 |
| 8599 AstNode* iterator_current = new(Z) InstanceGetterNode( | 8638 AstNode* iterator_current = new(Z) InstanceGetterNode( |
| 8600 loop_var_assignment_pos, | 8639 loop_var_assignment_pos, |
| 8601 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 8640 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
| 8602 Symbols::Current()); | 8641 Symbols::Current()); |
| 8603 | 8642 |
| 8604 // Generate assignment of next iterator value to loop variable. | 8643 // Generate assignment of next iterator value to loop variable. |
| 8605 AstNode* loop_var_assignment = NULL; | 8644 AstNode* loop_var_assignment = NULL; |
| 8606 if (new_loop_var) { | 8645 if (new_loop_var) { |
| 8607 // The for loop variable is new for each iteration. | 8646 // The for loop variable is new for each iteration. |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8652 current_block_->statements->Add(while_node); | 8691 current_block_->statements->Add(while_node); |
| 8653 SequenceNode* try_block = CloseBlock(); | 8692 SequenceNode* try_block = CloseBlock(); |
| 8654 | 8693 |
| 8655 // Create an empty "catch all" block that rethrows the current | 8694 // Create an empty "catch all" block that rethrows the current |
| 8656 // exception and stacktrace. | 8695 // exception and stacktrace. |
| 8657 try_stack_->enter_catch(); | 8696 try_stack_->enter_catch(); |
| 8658 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); | 8697 SequenceNode* catch_block = new(Z) SequenceNode(await_for_pos, NULL); |
| 8659 | 8698 |
| 8660 if (outer_saved_try_ctx != NULL) { | 8699 if (outer_saved_try_ctx != NULL) { |
| 8661 catch_block->Add(new (Z) StoreLocalNode( | 8700 catch_block->Add(new (Z) StoreLocalNode( |
| 8662 Token::kNoSourcePos, | 8701 TokenDescriptor::kNoSource, |
| 8663 outer_saved_try_ctx, | 8702 outer_saved_try_ctx, |
| 8664 new (Z) LoadLocalNode(Token::kNoSourcePos, | 8703 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 8665 outer_async_saved_try_ctx))); | 8704 outer_async_saved_try_ctx))); |
| 8666 } | 8705 } |
| 8667 | 8706 |
| 8668 // We don't need to copy the current exception and stack trace variables | 8707 // We don't need to copy the current exception and stack trace variables |
| 8669 // into :saved_exception_var and :saved_stack_trace_var here because there | 8708 // into :saved_exception_var and :saved_stack_trace_var here because there |
| 8670 // is no code in the catch clause that could suspend the function. | 8709 // is no code in the catch clause that could suspend the function. |
| 8671 | 8710 |
| 8672 // Rethrow the exception. | 8711 // Rethrow the exception. |
| 8673 catch_block->Add(new(Z) ThrowNode( | 8712 catch_block->Add(new(Z) ThrowNode( |
| 8674 await_for_pos, | 8713 await_for_pos, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 8686 | 8725 |
| 8687 // Inline the finally block to the exit points in the try block. | 8726 // Inline the finally block to the exit points in the try block. |
| 8688 intptr_t node_index = 0; | 8727 intptr_t node_index = 0; |
| 8689 SequenceNode* finally_clause = NULL; | 8728 SequenceNode* finally_clause = NULL; |
| 8690 if (try_stack_ != NULL) { | 8729 if (try_stack_ != NULL) { |
| 8691 try_stack_->enter_finally(); | 8730 try_stack_->enter_finally(); |
| 8692 } | 8731 } |
| 8693 do { | 8732 do { |
| 8694 OpenBlock(); | 8733 OpenBlock(); |
| 8695 ArgumentListNode* no_args = | 8734 ArgumentListNode* no_args = |
| 8696 new(Z) ArgumentListNode(Token::kNoSourcePos); | 8735 new(Z) ArgumentListNode(TokenDescriptor::kNoSource); |
| 8697 current_block_->statements->Add( | 8736 current_block_->statements->Add( |
| 8698 new(Z) InstanceCallNode(Token::kNoSourcePos, | 8737 new(Z) InstanceCallNode(TokenDescriptor::kNoSource, |
| 8699 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_var), | 8738 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, iterator_var), |
| 8700 Symbols::Cancel(), | 8739 Symbols::Cancel(), |
| 8701 no_args)); | 8740 no_args)); |
| 8702 finally_clause = CloseBlock(); | 8741 finally_clause = CloseBlock(); |
| 8703 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 8742 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
| 8704 if (node_to_inline != NULL) { | 8743 if (node_to_inline != NULL) { |
| 8705 InlinedFinallyNode* node = | 8744 InlinedFinallyNode* node = |
| 8706 new(Z) InlinedFinallyNode(Token::kNoSourcePos, | 8745 new(Z) InlinedFinallyNode(TokenDescriptor::kNoSource, |
| 8707 finally_clause, | 8746 finally_clause, |
| 8708 context_var, | 8747 context_var, |
| 8709 outer_try_index); | 8748 outer_try_index); |
| 8710 finally_clause = NULL; | 8749 finally_clause = NULL; |
| 8711 AddFinallyClauseToNode(true, node_to_inline, node); | 8750 AddFinallyClauseToNode(true, node_to_inline, node); |
| 8712 node_index++; | 8751 node_index++; |
| 8713 } | 8752 } |
| 8714 } while (finally_clause == NULL); | 8753 } while (finally_clause == NULL); |
| 8715 | 8754 |
| 8716 if (try_stack_ != NULL) { | 8755 if (try_stack_ != NULL) { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 8744 try_index, | 8783 try_index, |
| 8745 finally_clause); | 8784 finally_clause); |
| 8746 | 8785 |
| 8747 ASSERT(current_block_ == loop_block); | 8786 ASSERT(current_block_ == loop_block); |
| 8748 loop_block->statements->Add(try_catch_node); | 8787 loop_block->statements->Add(try_catch_node); |
| 8749 | 8788 |
| 8750 return CloseBlock(); // Implicit block around while loop. | 8789 return CloseBlock(); // Implicit block around while loop. |
| 8751 } | 8790 } |
| 8752 | 8791 |
| 8753 | 8792 |
| 8754 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 8793 AstNode* Parser::ParseForInStatement(TokenDescriptor forin_pos, |
| 8755 SourceLabel* label) { | 8794 SourceLabel* label) { |
| 8756 TRACE_PARSER("ParseForInStatement"); | 8795 TRACE_PARSER("ParseForInStatement"); |
| 8757 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 8796 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
| 8758 if (CurrentToken() == Token::kCONST) { | 8797 if (CurrentToken() == Token::kCONST) { |
| 8759 ReportError("Loop variable cannot be 'const'"); | 8798 ReportError("Loop variable cannot be 'const'"); |
| 8760 } | 8799 } |
| 8761 const String* loop_var_name = NULL; | 8800 const String* loop_var_name = NULL; |
| 8762 intptr_t loop_var_pos = Token::kNoSourcePos; | 8801 TokenDescriptor loop_var_pos = TokenDescriptor::kNoSource; |
| 8763 bool new_loop_var = false; | 8802 bool new_loop_var = false; |
| 8764 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); | 8803 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
| 8765 if (LookaheadToken(1) == Token::kIN) { | 8804 if (LookaheadToken(1) == Token::kIN) { |
| 8766 loop_var_pos = TokenPos(); | 8805 loop_var_pos = TokenPos(); |
| 8767 loop_var_name = ExpectIdentifier("variable name expected"); | 8806 loop_var_name = ExpectIdentifier("variable name expected"); |
| 8768 } else { | 8807 } else { |
| 8769 // The case without a type is handled above, so require a type here. | 8808 // The case without a type is handled above, so require a type here. |
| 8770 // Delay creation of the local variable until we know its actual | 8809 // Delay creation of the local variable until we know its actual |
| 8771 // position, which is inside the loop body. | 8810 // position, which is inside the loop body. |
| 8772 new_loop_var = true; | 8811 new_loop_var = true; |
| 8773 loop_var_type = ParseConstFinalVarOrType( | 8812 loop_var_type = ParseConstFinalVarOrType( |
| 8774 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : | 8813 I->flags().type_checks() ? ClassFinalizer::kCanonicalize : |
| 8775 ClassFinalizer::kIgnore); | 8814 ClassFinalizer::kIgnore); |
| 8776 loop_var_name = ExpectIdentifier("variable name expected"); | 8815 loop_var_name = ExpectIdentifier("variable name expected"); |
| 8777 } | 8816 } |
| 8778 ExpectToken(Token::kIN); | 8817 ExpectToken(Token::kIN); |
| 8779 const intptr_t collection_pos = TokenPos(); | 8818 const TokenDescriptor collection_pos = TokenPos(); |
| 8780 AstNode* collection_expr = | 8819 AstNode* collection_expr = |
| 8781 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8820 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8782 ExpectToken(Token::kRPAREN); | 8821 ExpectToken(Token::kRPAREN); |
| 8783 | 8822 |
| 8784 OpenBlock(); // Implicit block around while loop. | 8823 OpenBlock(); // Implicit block around while loop. |
| 8785 | 8824 |
| 8786 // Generate implicit iterator variable and add to scope. | 8825 // Generate implicit iterator variable and add to scope. |
| 8787 // We could set the type of the implicit iterator variable to Iterator<T> | 8826 // We could set the type of the implicit iterator variable to Iterator<T> |
| 8788 // where T is the type of the for loop variable. However, the type error | 8827 // where T is the type of the for loop variable. However, the type error |
| 8789 // would refer to the compiler generated iterator and could confuse the user. | 8828 // would refer to the compiler generated iterator and could confuse the user. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 8808 new(Z) LoadLocalNode(collection_pos, iterator_var), | 8847 new(Z) LoadLocalNode(collection_pos, iterator_var), |
| 8809 Symbols::MoveNext(), | 8848 Symbols::MoveNext(), |
| 8810 no_args); | 8849 no_args); |
| 8811 | 8850 |
| 8812 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 8851 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
| 8813 // here, but that does not work well because we have to insert an implicit | 8852 // here, but that does not work well because we have to insert an implicit |
| 8814 // variable assignment and potentially a variable declaration in the | 8853 // variable assignment and potentially a variable declaration in the |
| 8815 // loop body. | 8854 // loop body. |
| 8816 OpenLoopBlock(); | 8855 OpenLoopBlock(); |
| 8817 current_block_->scope->AddLabel(label); | 8856 current_block_->scope->AddLabel(label); |
| 8818 const intptr_t loop_var_assignment_pos = TokenPos(); | 8857 const TokenDescriptor loop_var_assignment_pos = TokenPos(); |
| 8819 | 8858 |
| 8820 AstNode* iterator_current = new(Z) InstanceGetterNode( | 8859 AstNode* iterator_current = new(Z) InstanceGetterNode( |
| 8821 loop_var_assignment_pos, | 8860 loop_var_assignment_pos, |
| 8822 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 8861 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
| 8823 Symbols::Current()); | 8862 Symbols::Current()); |
| 8824 | 8863 |
| 8825 // Generate assignment of next iterator value to loop variable. | 8864 // Generate assignment of next iterator value to loop variable. |
| 8826 AstNode* loop_var_assignment = NULL; | 8865 AstNode* loop_var_assignment = NULL; |
| 8827 if (new_loop_var) { | 8866 if (new_loop_var) { |
| 8828 // The for loop variable is new for each iteration. | 8867 // The for loop variable is new for each iteration. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8866 AstNode* while_statement = new(Z) WhileNode( | 8905 AstNode* while_statement = new(Z) WhileNode( |
| 8867 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); | 8906 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); |
| 8868 current_block_->statements->Add(while_statement); | 8907 current_block_->statements->Add(while_statement); |
| 8869 | 8908 |
| 8870 return CloseBlock(); // Implicit block around while loop. | 8909 return CloseBlock(); // Implicit block around while loop. |
| 8871 } | 8910 } |
| 8872 | 8911 |
| 8873 | 8912 |
| 8874 AstNode* Parser::ParseForStatement(String* label_name) { | 8913 AstNode* Parser::ParseForStatement(String* label_name) { |
| 8875 TRACE_PARSER("ParseForStatement"); | 8914 TRACE_PARSER("ParseForStatement"); |
| 8876 const intptr_t for_pos = TokenPos(); | 8915 const TokenDescriptor for_pos = TokenPos(); |
| 8877 ConsumeToken(); | 8916 ConsumeToken(); |
| 8878 ExpectToken(Token::kLPAREN); | 8917 ExpectToken(Token::kLPAREN); |
| 8879 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); | 8918 SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor); |
| 8880 if (IsForInStatement()) { | 8919 if (IsForInStatement()) { |
| 8881 return ParseForInStatement(for_pos, label); | 8920 return ParseForInStatement(for_pos, label); |
| 8882 } | 8921 } |
| 8883 // Open a block that contains the loop variable. Make it a loop block so | 8922 // Open a block that contains the loop variable. Make it a loop block so |
| 8884 // that we allocate a new context if the loop variable is captured. | 8923 // that we allocate a new context if the loop variable is captured. |
| 8885 OpenLoopBlock(); | 8924 OpenLoopBlock(); |
| 8886 AstNode* initializer = NULL; | 8925 AstNode* initializer = NULL; |
| 8887 const intptr_t init_pos = TokenPos(); | 8926 const TokenDescriptor init_pos = TokenPos(); |
| 8888 LocalScope* init_scope = current_block_->scope; | 8927 LocalScope* init_scope = current_block_->scope; |
| 8889 if (CurrentToken() != Token::kSEMICOLON) { | 8928 if (CurrentToken() != Token::kSEMICOLON) { |
| 8890 if (IsVariableDeclaration()) { | 8929 if (IsVariableDeclaration()) { |
| 8891 initializer = ParseVariableDeclarationList(); | 8930 initializer = ParseVariableDeclarationList(); |
| 8892 } else { | 8931 } else { |
| 8893 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8932 initializer = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8894 } | 8933 } |
| 8895 } | 8934 } |
| 8896 ExpectSemicolon(); | 8935 ExpectSemicolon(); |
| 8897 AstNode* condition = NULL; | 8936 AstNode* condition = NULL; |
| 8898 SequenceNode* condition_preamble = NULL; | 8937 SequenceNode* condition_preamble = NULL; |
| 8899 if (CurrentToken() != Token::kSEMICOLON) { | 8938 if (CurrentToken() != Token::kSEMICOLON) { |
| 8900 condition = ParseAwaitableExpr( | 8939 condition = ParseAwaitableExpr( |
| 8901 kAllowConst, kConsumeCascades, &condition_preamble); | 8940 kAllowConst, kConsumeCascades, &condition_preamble); |
| 8902 } | 8941 } |
| 8903 ExpectSemicolon(); | 8942 ExpectSemicolon(); |
| 8904 AstNode* increment = NULL; | 8943 AstNode* increment = NULL; |
| 8905 const intptr_t incr_pos = TokenPos(); | 8944 const TokenDescriptor incr_pos = TokenPos(); |
| 8906 if (CurrentToken() != Token::kRPAREN) { | 8945 if (CurrentToken() != Token::kRPAREN) { |
| 8907 increment = ParseAwaitableExprList(); | 8946 increment = ParseAwaitableExprList(); |
| 8908 } | 8947 } |
| 8909 ExpectToken(Token::kRPAREN); | 8948 ExpectToken(Token::kRPAREN); |
| 8910 const bool parsing_loop_body = true; | 8949 const bool parsing_loop_body = true; |
| 8911 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 8950 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
| 8912 | 8951 |
| 8913 // Check whether any of the variables in the initializer part of | 8952 // Check whether any of the variables in the initializer part of |
| 8914 // the for statement are captured by a closure. If so, we insert a | 8953 // the for statement are captured by a closure. If so, we insert a |
| 8915 // node that creates a new Context for the loop variable before | 8954 // node that creates a new Context for the loop variable before |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8948 const Function& func = Function::ZoneHandle(Z, | 8987 const Function& func = Function::ZoneHandle(Z, |
| 8949 Resolver::ResolveStatic(cls, | 8988 Resolver::ResolveStatic(cls, |
| 8950 func_name, | 8989 func_name, |
| 8951 arguments->length(), | 8990 arguments->length(), |
| 8952 arguments->names())); | 8991 arguments->names())); |
| 8953 ASSERT(!func.IsNull()); | 8992 ASSERT(!func.IsNull()); |
| 8954 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); | 8993 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); |
| 8955 } | 8994 } |
| 8956 | 8995 |
| 8957 | 8996 |
| 8958 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { | 8997 AstNode* Parser::MakeAssertCall(TokenDescriptor begin, TokenDescriptor end) { |
| 8959 ArgumentListNode* arguments = new(Z) ArgumentListNode(begin); | 8998 ArgumentListNode* arguments = new(Z) ArgumentListNode(begin); |
| 8960 arguments->Add(new(Z) LiteralNode(begin, | 8999 arguments->Add(new(Z) LiteralNode(begin, |
| 8961 Integer::ZoneHandle(Z, Integer::New(begin)))); | 9000 Integer::ZoneHandle(Z, Integer::New(begin.value())))); |
| 8962 arguments->Add(new(Z) LiteralNode(end, | 9001 arguments->Add(new(Z) LiteralNode(end, |
| 8963 Integer::ZoneHandle(Z, Integer::New(end)))); | 9002 Integer::ZoneHandle(Z, Integer::New(end.value())))); |
| 8964 return MakeStaticCall(Symbols::AssertionError(), | 9003 return MakeStaticCall(Symbols::AssertionError(), |
| 8965 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 9004 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 8966 arguments); | 9005 arguments); |
| 8967 } | 9006 } |
| 8968 | 9007 |
| 8969 | 9008 |
| 8970 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { | 9009 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { |
| 8971 if (condition->IsClosureNode() || | 9010 if (condition->IsClosureNode() || |
| 8972 (condition->IsStoreLocalNode() && | 9011 (condition->IsStoreLocalNode() && |
| 8973 condition->AsStoreLocalNode()->value()->IsClosureNode())) { | 9012 condition->AsStoreLocalNode()->value()->IsClosureNode())) { |
| 8974 // Function literal in assert implies a call. | 9013 // Function literal in assert implies a call. |
| 8975 const intptr_t pos = condition->token_pos(); | 9014 const TokenDescriptor pos = condition->token_pos(); |
| 8976 condition = BuildClosureCall(pos, | 9015 condition = BuildClosureCall(pos, |
| 8977 condition, | 9016 condition, |
| 8978 new(Z) ArgumentListNode(pos)); | 9017 new(Z) ArgumentListNode(pos)); |
| 8979 } else if (condition->IsConditionalExprNode()) { | 9018 } else if (condition->IsConditionalExprNode()) { |
| 8980 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); | 9019 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); |
| 8981 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); | 9020 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); |
| 8982 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 9021 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
| 8983 } | 9022 } |
| 8984 return condition; | 9023 return condition; |
| 8985 } | 9024 } |
| 8986 | 9025 |
| 8987 | 9026 |
| 8988 AstNode* Parser::ParseAssertStatement() { | 9027 AstNode* Parser::ParseAssertStatement() { |
| 8989 TRACE_PARSER("ParseAssertStatement"); | 9028 TRACE_PARSER("ParseAssertStatement"); |
| 8990 ConsumeToken(); // Consume assert keyword. | 9029 ConsumeToken(); // Consume assert keyword. |
| 8991 ExpectToken(Token::kLPAREN); | 9030 ExpectToken(Token::kLPAREN); |
| 8992 const intptr_t condition_pos = TokenPos(); | 9031 const TokenDescriptor condition_pos = TokenPos(); |
| 8993 if (!I->flags().asserts()) { | 9032 if (!I->flags().asserts()) { |
| 8994 SkipExpr(); | 9033 SkipExpr(); |
| 8995 ExpectToken(Token::kRPAREN); | 9034 ExpectToken(Token::kRPAREN); |
| 8996 return NULL; | 9035 return NULL; |
| 8997 } | 9036 } |
| 8998 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9037 AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8999 const intptr_t condition_end = TokenPos(); | 9038 const TokenDescriptor condition_end = TokenPos(); |
| 9000 ExpectToken(Token::kRPAREN); | 9039 ExpectToken(Token::kRPAREN); |
| 9001 condition = InsertClosureCallNodes(condition); | 9040 condition = InsertClosureCallNodes(condition); |
| 9002 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); | 9041 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); |
| 9003 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 9042 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
| 9004 return new(Z) IfNode( | 9043 return new(Z) IfNode( |
| 9005 condition_pos, | 9044 condition_pos, |
| 9006 condition, | 9045 condition, |
| 9007 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 9046 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
| 9008 NULL); | 9047 NULL); |
| 9009 } | 9048 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9053 ASSERT(innermost_function().IsAsyncClosure() || | 9092 ASSERT(innermost_function().IsAsyncClosure() || |
| 9054 innermost_function().IsAsyncFunction() || | 9093 innermost_function().IsAsyncFunction() || |
| 9055 innermost_function().IsSyncGenClosure() || | 9094 innermost_function().IsSyncGenClosure() || |
| 9056 innermost_function().IsSyncGenerator() || | 9095 innermost_function().IsSyncGenerator() || |
| 9057 innermost_function().IsAsyncGenClosure() || | 9096 innermost_function().IsAsyncGenClosure() || |
| 9058 innermost_function().IsAsyncGenerator()); | 9097 innermost_function().IsAsyncGenerator()); |
| 9059 | 9098 |
| 9060 ASSERT(saved_exception_var != NULL); | 9099 ASSERT(saved_exception_var != NULL); |
| 9061 ASSERT(exception_var != NULL); | 9100 ASSERT(exception_var != NULL); |
| 9062 statements->Add(new(Z) StoreLocalNode( | 9101 statements->Add(new(Z) StoreLocalNode( |
| 9063 Token::kNoSourcePos, | 9102 TokenDescriptor::kNoSource, |
| 9064 saved_exception_var, | 9103 saved_exception_var, |
| 9065 new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var))); | 9104 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, exception_var))); |
| 9066 | 9105 |
| 9067 ASSERT(saved_stack_trace_var != NULL); | 9106 ASSERT(saved_stack_trace_var != NULL); |
| 9068 ASSERT(stack_trace_var != NULL); | 9107 ASSERT(stack_trace_var != NULL); |
| 9069 statements->Add(new(Z) StoreLocalNode( | 9108 statements->Add(new(Z) StoreLocalNode( |
| 9070 Token::kNoSourcePos, | 9109 TokenDescriptor::kNoSource, |
| 9071 saved_stack_trace_var, | 9110 saved_stack_trace_var, |
| 9072 new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var))); | 9111 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, stack_trace_var))); |
| 9073 } | 9112 } |
| 9074 | 9113 |
| 9075 | 9114 |
| 9076 SequenceNode* Parser::EnsureFinallyClause( | 9115 SequenceNode* Parser::EnsureFinallyClause( |
| 9077 bool parse, | 9116 bool parse, |
| 9078 bool is_async, | 9117 bool is_async, |
| 9079 LocalVariable* exception_var, | 9118 LocalVariable* exception_var, |
| 9080 LocalVariable* stack_trace_var, | 9119 LocalVariable* stack_trace_var, |
| 9081 LocalVariable* rethrow_exception_var, | 9120 LocalVariable* rethrow_exception_var, |
| 9082 LocalVariable* rethrow_stack_trace_var) { | 9121 LocalVariable* rethrow_stack_trace_var) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 9097 if (try_stack_ != NULL) { | 9136 if (try_stack_ != NULL) { |
| 9098 LocalScope* scope = try_stack_->try_block()->scope; | 9137 LocalScope* scope = try_stack_->try_block()->scope; |
| 9099 if (scope->function_level() == current_block_->scope->function_level()) { | 9138 if (scope->function_level() == current_block_->scope->function_level()) { |
| 9100 LocalVariable* saved_try_ctx = | 9139 LocalVariable* saved_try_ctx = |
| 9101 LookupSavedTryContextVar(scope->parent()); | 9140 LookupSavedTryContextVar(scope->parent()); |
| 9102 LocalVariable* async_saved_try_ctx = | 9141 LocalVariable* async_saved_try_ctx = |
| 9103 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9142 LookupAsyncSavedTryContextVar(async_temp_scope_, |
| 9104 try_stack_->try_index()); | 9143 try_stack_->try_index()); |
| 9105 current_block_->statements->Add( | 9144 current_block_->statements->Add( |
| 9106 new (Z) StoreLocalNode( | 9145 new (Z) StoreLocalNode( |
| 9107 Token::kNoSourcePos, | 9146 TokenDescriptor::kNoSource, |
| 9108 saved_try_ctx, | 9147 saved_try_ctx, |
| 9109 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9148 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 9110 async_saved_try_ctx))); | 9149 async_saved_try_ctx))); |
| 9111 } | 9150 } |
| 9112 } | 9151 } |
| 9113 // We need to save the exception variables as in catch clauses, whether | 9152 // We need to save the exception variables as in catch clauses, whether |
| 9114 // there is an outer try or not. Note that this is only necessary if the | 9153 // there is an outer try or not. Note that this is only necessary if the |
| 9115 // finally clause contains an await or yield. | 9154 // finally clause contains an await or yield. |
| 9116 // TODO(hausner): Optimize. | 9155 // TODO(hausner): Optimize. |
| 9117 SaveExceptionAndStacktrace(current_block_->statements, | 9156 SaveExceptionAndStacktrace(current_block_->statements, |
| 9118 exception_var, | 9157 exception_var, |
| 9119 stack_trace_var, | 9158 stack_trace_var, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9183 return_node->AddInlinedFinallyNode(finally_clause); | 9222 return_node->AddInlinedFinallyNode(finally_clause); |
| 9184 return; | 9223 return; |
| 9185 } | 9224 } |
| 9186 JumpNode* jump_node = node->AsJumpNode(); | 9225 JumpNode* jump_node = node->AsJumpNode(); |
| 9187 ASSERT(jump_node != NULL); | 9226 ASSERT(jump_node != NULL); |
| 9188 jump_node->AddInlinedFinallyNode(finally_clause); | 9227 jump_node->AddInlinedFinallyNode(finally_clause); |
| 9189 } | 9228 } |
| 9190 | 9229 |
| 9191 | 9230 |
| 9192 SequenceNode* Parser::ParseCatchClauses( | 9231 SequenceNode* Parser::ParseCatchClauses( |
| 9193 intptr_t handler_pos, | 9232 TokenDescriptor handler_pos, |
| 9194 bool is_async, | 9233 bool is_async, |
| 9195 LocalVariable* exception_var, | 9234 LocalVariable* exception_var, |
| 9196 LocalVariable* stack_trace_var, | 9235 LocalVariable* stack_trace_var, |
| 9197 LocalVariable* rethrow_exception_var, | 9236 LocalVariable* rethrow_exception_var, |
| 9198 LocalVariable* rethrow_stack_trace_var, | 9237 LocalVariable* rethrow_stack_trace_var, |
| 9199 const GrowableObjectArray& handler_types, | 9238 const GrowableObjectArray& handler_types, |
| 9200 bool* needs_stack_trace) { | 9239 bool* needs_stack_trace) { |
| 9201 // All catch blocks are merged into an if-then-else sequence of the | 9240 // All catch blocks are merged into an if-then-else sequence of the |
| 9202 // different types specified using the 'is' operator. While parsing | 9241 // different types specified using the 'is' operator. While parsing |
| 9203 // record the type tests (either a ComparisonNode or else the LiteralNode | 9242 // record the type tests (either a ComparisonNode or else the LiteralNode |
| 9204 // true for a generic catch) and the catch bodies in a pair of parallel | 9243 // true for a generic catch) and the catch bodies in a pair of parallel |
| 9205 // lists. Afterward, construct the nested if-then-else. | 9244 // lists. Afterward, construct the nested if-then-else. |
| 9206 bool generic_catch_seen = false; | 9245 bool generic_catch_seen = false; |
| 9207 GrowableArray<AstNode*> type_tests; | 9246 GrowableArray<AstNode*> type_tests; |
| 9208 GrowableArray<SequenceNode*> catch_blocks; | 9247 GrowableArray<SequenceNode*> catch_blocks; |
| 9209 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { | 9248 while ((CurrentToken() == Token::kCATCH) || IsSymbol(Symbols::On())) { |
| 9210 // Open a block that contains the if or an unconditional body. It's | 9249 // Open a block that contains the if or an unconditional body. It's |
| 9211 // closed in the loop that builds the if-then-else nest. | 9250 // closed in the loop that builds the if-then-else nest. |
| 9212 OpenBlock(); | 9251 OpenBlock(); |
| 9213 const intptr_t catch_pos = TokenPos(); | 9252 const TokenDescriptor catch_pos = TokenPos(); |
| 9214 CatchParamDesc exception_param; | 9253 CatchParamDesc exception_param; |
| 9215 CatchParamDesc stack_trace_param; | 9254 CatchParamDesc stack_trace_param; |
| 9216 if (IsSymbol(Symbols::On())) { | 9255 if (IsSymbol(Symbols::On())) { |
| 9217 ConsumeToken(); | 9256 ConsumeToken(); |
| 9218 exception_param.type = &AbstractType::ZoneHandle(Z, | 9257 exception_param.type = &AbstractType::ZoneHandle(Z, |
| 9219 ParseType(ClassFinalizer::kCanonicalize)); | 9258 ParseType(ClassFinalizer::kCanonicalize)); |
| 9220 } else { | 9259 } else { |
| 9221 exception_param.type = &Object::dynamic_type(); | 9260 exception_param.type = &Object::dynamic_type(); |
| 9222 } | 9261 } |
| 9223 if (CurrentToken() == Token::kCATCH) { | 9262 if (CurrentToken() == Token::kCATCH) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9370 if (try_block != NULL) { | 9409 if (try_block != NULL) { |
| 9371 LocalScope* scope = try_block->try_block()->scope; | 9410 LocalScope* scope = try_block->try_block()->scope; |
| 9372 if (scope->function_level() == current_block_->scope->function_level()) { | 9411 if (scope->function_level() == current_block_->scope->function_level()) { |
| 9373 LocalVariable* saved_try_ctx = | 9412 LocalVariable* saved_try_ctx = |
| 9374 LookupSavedTryContextVar(scope->parent()); | 9413 LookupSavedTryContextVar(scope->parent()); |
| 9375 LocalVariable* async_saved_try_ctx = | 9414 LocalVariable* async_saved_try_ctx = |
| 9376 LookupAsyncSavedTryContextVar(async_temp_scope_, | 9415 LookupAsyncSavedTryContextVar(async_temp_scope_, |
| 9377 try_block->try_index()); | 9416 try_block->try_index()); |
| 9378 async_code->Add( | 9417 async_code->Add( |
| 9379 new (Z) StoreLocalNode( | 9418 new (Z) StoreLocalNode( |
| 9380 Token::kNoSourcePos, | 9419 TokenDescriptor::kNoSource, |
| 9381 saved_try_ctx, | 9420 saved_try_ctx, |
| 9382 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9421 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 9383 async_saved_try_ctx))); | 9422 async_saved_try_ctx))); |
| 9384 } | 9423 } |
| 9385 } | 9424 } |
| 9386 SaveExceptionAndStacktrace(async_code, | 9425 SaveExceptionAndStacktrace(async_code, |
| 9387 exception_var, | 9426 exception_var, |
| 9388 stack_trace_var, | 9427 stack_trace_var, |
| 9389 rethrow_exception_var, | 9428 rethrow_exception_var, |
| 9390 rethrow_stack_trace_var); | 9429 rethrow_stack_trace_var); |
| 9391 // The async_code node sequence contains code to restore the context (if | 9430 // The async_code node sequence contains code to restore the context (if |
| 9392 // an outer try block is present) and code to save the exception and | 9431 // an outer try block is present) and code to save the exception and |
| 9393 // stack trace variables. | 9432 // stack trace variables. |
| 9394 // This async code is inserted before the current node sequence containing | 9433 // This async code is inserted before the current node sequence containing |
| 9395 // the chain of if/then/else handling all catch clauses. | 9434 // the chain of if/then/else handling all catch clauses. |
| 9396 async_code->Add(current); | 9435 async_code->Add(current); |
| 9397 current = async_code; | 9436 current = async_code; |
| 9398 } | 9437 } |
| 9399 return current; | 9438 return current; |
| 9400 } | 9439 } |
| 9401 | 9440 |
| 9402 | 9441 |
| 9403 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 9442 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
| 9404 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, | 9443 const String& async_saved_try_ctx_name = String::ZoneHandle(Z, |
| 9405 Symbols::NewFormatted("%s%d", | 9444 Symbols::NewFormatted("%s%d", |
| 9406 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), | 9445 Symbols::AsyncSavedTryCtxVarPrefix().ToCString(), |
| 9407 last_used_try_index_ - 1)); | 9446 last_used_try_index_ - 1)); |
| 9408 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( | 9447 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( |
| 9409 Token::kNoSourcePos, | 9448 TokenDescriptor::kNoSource, |
| 9410 async_saved_try_ctx_name, | 9449 async_saved_try_ctx_name, |
| 9411 Object::dynamic_type()); | 9450 Object::dynamic_type()); |
| 9412 ASSERT(async_temp_scope_ != NULL); | 9451 ASSERT(async_temp_scope_ != NULL); |
| 9413 async_temp_scope_->AddVariable(async_saved_try_ctx); | 9452 async_temp_scope_->AddVariable(async_saved_try_ctx); |
| 9414 ASSERT(saved_try_context != NULL); | 9453 ASSERT(saved_try_context != NULL); |
| 9415 current_block_->statements->Add(new(Z) StoreLocalNode( | 9454 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 9416 Token::kNoSourcePos, | 9455 TokenDescriptor::kNoSource, |
| 9417 async_saved_try_ctx, | 9456 async_saved_try_ctx, |
| 9418 new(Z) LoadLocalNode(Token::kNoSourcePos, saved_try_context))); | 9457 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, saved_try_context))); |
| 9419 } | 9458 } |
| 9420 | 9459 |
| 9421 | 9460 |
| 9422 // We create three variables for exceptions: | 9461 // We create three variables for exceptions: |
| 9423 // ':saved_try_context_var' - Used to save the context before the start of | 9462 // ':saved_try_context_var' - Used to save the context before the start of |
| 9424 // the try block. The context register is | 9463 // the try block. The context register is |
| 9425 // restored from this variable before | 9464 // restored from this variable before |
| 9426 // processing the catch block handler. | 9465 // processing the catch block handler. |
| 9427 // ':exception_var' - Used to save the current exception object that was | 9466 // ':exception_var' - Used to save the current exception object that was |
| 9428 // thrown. | 9467 // thrown. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9487 Object::dynamic_type()); | 9526 Object::dynamic_type()); |
| 9488 try_scope->AddVariable(*saved_stack_trace_var); | 9527 try_scope->AddVariable(*saved_stack_trace_var); |
| 9489 } | 9528 } |
| 9490 } | 9529 } |
| 9491 } | 9530 } |
| 9492 | 9531 |
| 9493 | 9532 |
| 9494 AstNode* Parser::ParseTryStatement(String* label_name) { | 9533 AstNode* Parser::ParseTryStatement(String* label_name) { |
| 9495 TRACE_PARSER("ParseTryStatement"); | 9534 TRACE_PARSER("ParseTryStatement"); |
| 9496 | 9535 |
| 9497 const intptr_t try_pos = TokenPos(); | 9536 const TokenDescriptor try_pos = TokenPos(); |
| 9498 SourceLabel* try_label = NULL; | 9537 SourceLabel* try_label = NULL; |
| 9499 if (label_name != NULL) { | 9538 if (label_name != NULL) { |
| 9500 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 9539 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
| 9501 OpenBlock(); | 9540 OpenBlock(); |
| 9502 current_block_->scope->AddLabel(try_label); | 9541 current_block_->scope->AddLabel(try_label); |
| 9503 } | 9542 } |
| 9504 | 9543 |
| 9505 const bool is_async = innermost_function().IsAsyncClosure() || | 9544 const bool is_async = innermost_function().IsAsyncClosure() || |
| 9506 innermost_function().IsAsyncFunction() || | 9545 innermost_function().IsAsyncFunction() || |
| 9507 innermost_function().IsSyncGenClosure() || | 9546 innermost_function().IsSyncGenClosure() || |
| (...skipping 28 matching lines...) Expand all Loading... |
| 9536 ExpectToken(Token::kRBRACE); | 9575 ExpectToken(Token::kRBRACE); |
| 9537 SequenceNode* try_block = CloseBlock(); | 9576 SequenceNode* try_block = CloseBlock(); |
| 9538 | 9577 |
| 9539 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && | 9578 if ((CurrentToken() != Token::kCATCH) && !IsSymbol(Symbols::On()) && |
| 9540 (CurrentToken() != Token::kFINALLY)) { | 9579 (CurrentToken() != Token::kFINALLY)) { |
| 9541 ReportError("catch or finally clause expected"); | 9580 ReportError("catch or finally clause expected"); |
| 9542 } | 9581 } |
| 9543 | 9582 |
| 9544 // Now parse the 'catch' blocks if any. | 9583 // Now parse the 'catch' blocks if any. |
| 9545 try_stack_->enter_catch(); | 9584 try_stack_->enter_catch(); |
| 9546 const intptr_t handler_pos = TokenPos(); | 9585 const TokenDescriptor handler_pos = TokenPos(); |
| 9547 const GrowableObjectArray& handler_types = | 9586 const GrowableObjectArray& handler_types = |
| 9548 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); | 9587 GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld)); |
| 9549 bool needs_stack_trace = false; | 9588 bool needs_stack_trace = false; |
| 9550 SequenceNode* catch_handler_list = | 9589 SequenceNode* catch_handler_list = |
| 9551 ParseCatchClauses(handler_pos, | 9590 ParseCatchClauses(handler_pos, |
| 9552 is_async, | 9591 is_async, |
| 9553 exception_var, | 9592 exception_var, |
| 9554 stack_trace_var, | 9593 stack_trace_var, |
| 9555 is_async ? saved_exception_var : exception_var, | 9594 is_async ? saved_exception_var : exception_var, |
| 9556 is_async ? saved_stack_trace_var : stack_trace_var, | 9595 is_async ? saved_stack_trace_var : stack_trace_var, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9567 // A finally clause is required in async code to restore the saved try context | 9606 // A finally clause is required in async code to restore the saved try context |
| 9568 // of an existing outer try. Generate a finally clause to this purpose if it | 9607 // of an existing outer try. Generate a finally clause to this purpose if it |
| 9569 // is not declared. | 9608 // is not declared. |
| 9570 SequenceNode* finally_clause = NULL; | 9609 SequenceNode* finally_clause = NULL; |
| 9571 SequenceNode* rethrow_clause = NULL; | 9610 SequenceNode* rethrow_clause = NULL; |
| 9572 const bool parse = CurrentToken() == Token::kFINALLY; | 9611 const bool parse = CurrentToken() == Token::kFINALLY; |
| 9573 if (parse || (is_async && (try_stack_ != NULL))) { | 9612 if (parse || (is_async && (try_stack_ != NULL))) { |
| 9574 if (parse) { | 9613 if (parse) { |
| 9575 ConsumeToken(); // Consume the 'finally'. | 9614 ConsumeToken(); // Consume the 'finally'. |
| 9576 } | 9615 } |
| 9577 const intptr_t finally_pos = TokenPos(); | 9616 const TokenDescriptor finally_pos = TokenPos(); |
| 9578 // Add the finally block to the exit points recorded so far. | 9617 // Add the finally block to the exit points recorded so far. |
| 9579 intptr_t node_index = 0; | 9618 intptr_t node_index = 0; |
| 9580 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); | 9619 AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index); |
| 9581 while (node_to_inline != NULL) { | 9620 while (node_to_inline != NULL) { |
| 9582 finally_clause = EnsureFinallyClause( | 9621 finally_clause = EnsureFinallyClause( |
| 9583 parse, | 9622 parse, |
| 9584 is_async, | 9623 is_async, |
| 9585 exception_var, | 9624 exception_var, |
| 9586 stack_trace_var, | 9625 stack_trace_var, |
| 9587 is_async ? saved_exception_var : exception_var, | 9626 is_async ? saved_exception_var : exception_var, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9647 } | 9686 } |
| 9648 | 9687 |
| 9649 return try_catch_node; | 9688 return try_catch_node; |
| 9650 } | 9689 } |
| 9651 | 9690 |
| 9652 | 9691 |
| 9653 AstNode* Parser::ParseJump(String* label_name) { | 9692 AstNode* Parser::ParseJump(String* label_name) { |
| 9654 TRACE_PARSER("ParseJump"); | 9693 TRACE_PARSER("ParseJump"); |
| 9655 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); | 9694 ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE); |
| 9656 Token::Kind jump_kind = CurrentToken(); | 9695 Token::Kind jump_kind = CurrentToken(); |
| 9657 const intptr_t jump_pos = TokenPos(); | 9696 const TokenDescriptor jump_pos = TokenPos(); |
| 9658 SourceLabel* target = NULL; | 9697 SourceLabel* target = NULL; |
| 9659 ConsumeToken(); | 9698 ConsumeToken(); |
| 9660 if (IsIdentifier()) { | 9699 if (IsIdentifier()) { |
| 9661 // Explicit label after break/continue. | 9700 // Explicit label after break/continue. |
| 9662 const String& target_name = *CurrentLiteral(); | 9701 const String& target_name = *CurrentLiteral(); |
| 9663 ConsumeToken(); | 9702 ConsumeToken(); |
| 9664 // Handle pathological cases first. | 9703 // Handle pathological cases first. |
| 9665 if (label_name != NULL && target_name.Equals(*label_name)) { | 9704 if (label_name != NULL && target_name.Equals(*label_name)) { |
| 9666 if (jump_kind == Token::kCONTINUE) { | 9705 if (jump_kind == Token::kCONTINUE) { |
| 9667 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", | 9706 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9712 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 9751 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 9713 ReportError(jump_pos, "'%s' target must be in same function context", | 9752 ReportError(jump_pos, "'%s' target must be in same function context", |
| 9714 Token::Str(jump_kind)); | 9753 Token::Str(jump_kind)); |
| 9715 } | 9754 } |
| 9716 return new(Z) JumpNode(jump_pos, jump_kind, target); | 9755 return new(Z) JumpNode(jump_pos, jump_kind, target); |
| 9717 } | 9756 } |
| 9718 | 9757 |
| 9719 | 9758 |
| 9720 AstNode* Parser::ParseYieldStatement() { | 9759 AstNode* Parser::ParseYieldStatement() { |
| 9721 bool is_yield_each = false; | 9760 bool is_yield_each = false; |
| 9722 const intptr_t yield_pos = TokenPos(); | 9761 const TokenDescriptor yield_pos = TokenPos(); |
| 9723 ConsumeToken(); // yield reserved word. | 9762 ConsumeToken(); // yield reserved word. |
| 9724 if (CurrentToken() == Token::kMUL) { | 9763 if (CurrentToken() == Token::kMUL) { |
| 9725 is_yield_each = true; | 9764 is_yield_each = true; |
| 9726 ConsumeToken(); | 9765 ConsumeToken(); |
| 9727 } | 9766 } |
| 9728 if (!innermost_function().IsGenerator() && | 9767 if (!innermost_function().IsGenerator() && |
| 9729 !innermost_function().IsGeneratorClosure()) { | 9768 !innermost_function().IsGeneratorClosure()) { |
| 9730 ReportError(yield_pos, | 9769 ReportError(yield_pos, |
| 9731 "yield%s statement only allowed in generator functions", | 9770 "yield%s statement only allowed in generator functions", |
| 9732 is_yield_each ? "*" : ""); | 9771 is_yield_each ? "*" : ""); |
| 9733 } | 9772 } |
| 9734 | 9773 |
| 9735 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9774 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 9736 | 9775 |
| 9737 LetNode* yield = new(Z) LetNode(yield_pos); | 9776 LetNode* yield = new(Z) LetNode(yield_pos); |
| 9738 if (innermost_function().IsSyncGenerator() || | 9777 if (innermost_function().IsSyncGenerator() || |
| 9739 innermost_function().IsSyncGenClosure()) { | 9778 innermost_function().IsSyncGenClosure()) { |
| 9740 // Yield statement in sync* function. | 9779 // Yield statement in sync* function. |
| 9741 | 9780 |
| 9742 LocalVariable* iterator_param = | 9781 LocalVariable* iterator_param = |
| 9743 LookupLocalScope(Symbols::IteratorParameter()); | 9782 LookupLocalScope(Symbols::IteratorParameter()); |
| 9744 ASSERT(iterator_param != NULL); | 9783 ASSERT(iterator_param != NULL); |
| 9745 // Generate :iterator.current = expr; | 9784 // Generate :iterator.current = expr; |
| 9746 AstNode* iterator = | 9785 AstNode* iterator = |
| 9747 new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_param); | 9786 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, iterator_param); |
| 9748 AstNode* store_current = | 9787 AstNode* store_current = |
| 9749 new(Z) InstanceSetterNode(Token::kNoSourcePos, | 9788 new(Z) InstanceSetterNode(TokenDescriptor::kNoSource, |
| 9750 iterator, | 9789 iterator, |
| 9751 String::ZoneHandle(Symbols::Current().raw()), | 9790 String::ZoneHandle(Symbols::Current().raw()), |
| 9752 expr); | 9791 expr); |
| 9753 yield->AddNode(store_current); | 9792 yield->AddNode(store_current); |
| 9754 if (is_yield_each) { | 9793 if (is_yield_each) { |
| 9755 // Generate :iterator.isYieldEach = true; | 9794 // Generate :iterator.isYieldEach = true; |
| 9756 AstNode* set_is_yield_each = | 9795 AstNode* set_is_yield_each = |
| 9757 new(Z) InstanceSetterNode(Token::kNoSourcePos, | 9796 new(Z) InstanceSetterNode(TokenDescriptor::kNoSource, |
| 9758 iterator, | 9797 iterator, |
| 9759 String::ZoneHandle(Symbols::IsYieldEach().raw()), | 9798 String::ZoneHandle(Symbols::IsYieldEach().raw()), |
| 9760 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9799 new(Z) LiteralNode(TokenPos(), Bool::True())); |
| 9761 yield->AddNode(set_is_yield_each); | 9800 yield->AddNode(set_is_yield_each); |
| 9762 } | 9801 } |
| 9763 AwaitMarkerNode* await_marker = | 9802 AwaitMarkerNode* await_marker = |
| 9764 new(Z) AwaitMarkerNode(async_temp_scope_, | 9803 new(Z) AwaitMarkerNode(async_temp_scope_, |
| 9765 current_block_->scope, | 9804 current_block_->scope, |
| 9766 Token::kNoSourcePos); | 9805 TokenDescriptor::kNoSource); |
| 9767 yield->AddNode(await_marker); | 9806 yield->AddNode(await_marker); |
| 9768 // Return true to indicate that a value has been generated. | 9807 // Return true to indicate that a value has been generated. |
| 9769 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, | 9808 ReturnNode* return_true = new(Z) ReturnNode(yield_pos, |
| 9770 new(Z) LiteralNode(TokenPos(), Bool::True())); | 9809 new(Z) LiteralNode(TokenPos(), Bool::True())); |
| 9771 return_true->set_return_type(ReturnNode::kContinuationTarget); | 9810 return_true->set_return_type(ReturnNode::kContinuationTarget); |
| 9772 yield->AddNode(return_true); | 9811 yield->AddNode(return_true); |
| 9773 | 9812 |
| 9774 // If this expression is part of a try block, also append the code for | 9813 // If this expression is part of a try block, also append the code for |
| 9775 // restoring the saved try context that lives on the stack and possibly the | 9814 // restoring the saved try context that lives on the stack and possibly the |
| 9776 // saved try context of the outer try block. | 9815 // saved try context of the outer try block. |
| 9777 LocalVariable* saved_try_ctx; | 9816 LocalVariable* saved_try_ctx; |
| 9778 LocalVariable* async_saved_try_ctx; | 9817 LocalVariable* async_saved_try_ctx; |
| 9779 LocalVariable* outer_saved_try_ctx; | 9818 LocalVariable* outer_saved_try_ctx; |
| 9780 LocalVariable* outer_async_saved_try_ctx; | 9819 LocalVariable* outer_async_saved_try_ctx; |
| 9781 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9820 CheckAsyncOpInTryBlock(&saved_try_ctx, |
| 9782 &async_saved_try_ctx, | 9821 &async_saved_try_ctx, |
| 9783 &outer_saved_try_ctx, | 9822 &outer_saved_try_ctx, |
| 9784 &outer_async_saved_try_ctx); | 9823 &outer_async_saved_try_ctx); |
| 9785 if (saved_try_ctx != NULL) { | 9824 if (saved_try_ctx != NULL) { |
| 9786 yield->AddNode(new (Z) StoreLocalNode( | 9825 yield->AddNode(new (Z) StoreLocalNode( |
| 9787 Token::kNoSourcePos, | 9826 TokenDescriptor::kNoSource, |
| 9788 saved_try_ctx, | 9827 saved_try_ctx, |
| 9789 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9828 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 9790 async_saved_try_ctx))); | 9829 async_saved_try_ctx))); |
| 9791 if (outer_saved_try_ctx != NULL) { | 9830 if (outer_saved_try_ctx != NULL) { |
| 9792 yield->AddNode(new (Z) StoreLocalNode( | 9831 yield->AddNode(new (Z) StoreLocalNode( |
| 9793 Token::kNoSourcePos, | 9832 TokenDescriptor::kNoSource, |
| 9794 outer_saved_try_ctx, | 9833 outer_saved_try_ctx, |
| 9795 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9834 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 9796 outer_async_saved_try_ctx))); | 9835 outer_async_saved_try_ctx))); |
| 9797 } | 9836 } |
| 9798 } else { | 9837 } else { |
| 9799 ASSERT(outer_saved_try_ctx == NULL); | 9838 ASSERT(outer_saved_try_ctx == NULL); |
| 9800 } | 9839 } |
| 9801 } else { | 9840 } else { |
| 9802 // yield statement in async* function. | 9841 // yield statement in async* function. |
| 9803 ASSERT(innermost_function().IsAsyncGenerator() || | 9842 ASSERT(innermost_function().IsAsyncGenerator() || |
| 9804 innermost_function().IsAsyncGenClosure()); | 9843 innermost_function().IsAsyncGenClosure()); |
| 9805 | 9844 |
| 9806 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); | 9845 LocalVariable* controller_var = LookupLocalScope(Symbols::Controller()); |
| 9807 ASSERT(controller_var != NULL); | 9846 ASSERT(controller_var != NULL); |
| 9808 // :controller.add[Stream](expr); | 9847 // :controller.add[Stream](expr); |
| 9809 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); | 9848 ArgumentListNode* add_args = new(Z) ArgumentListNode(yield_pos); |
| 9810 add_args->Add(expr); | 9849 add_args->Add(expr); |
| 9811 AstNode* add_call = | 9850 AstNode* add_call = |
| 9812 new(Z) InstanceCallNode(yield_pos, | 9851 new(Z) InstanceCallNode(yield_pos, |
| 9813 new(Z) LoadLocalNode(Token::kNoSourcePos, controller_var), | 9852 new(Z) LoadLocalNode(TokenDescriptor::kNoSource, controller_var), |
| 9814 is_yield_each ? Symbols::AddStream() : Symbols::add(), | 9853 is_yield_each ? Symbols::AddStream() : Symbols::add(), |
| 9815 add_args); | 9854 add_args); |
| 9816 | 9855 |
| 9817 // if (:controller.add[Stream](expr)) { | 9856 // if (:controller.add[Stream](expr)) { |
| 9818 // return; | 9857 // return; |
| 9819 // } | 9858 // } |
| 9820 // await_marker; | 9859 // await_marker; |
| 9821 // continuation_return; | 9860 // continuation_return; |
| 9822 // restore saved_try_context | 9861 // restore saved_try_context |
| 9823 | 9862 |
| 9824 SequenceNode* true_branch = | 9863 SequenceNode* true_branch = |
| 9825 new(Z) SequenceNode(Token::kNoSourcePos, NULL); | 9864 new(Z) SequenceNode(TokenDescriptor::kNoSource, NULL); |
| 9826 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); | 9865 AstNode* return_from_generator = new(Z) ReturnNode(yield_pos); |
| 9827 true_branch->Add(return_from_generator); | 9866 true_branch->Add(return_from_generator); |
| 9828 AddNodeForFinallyInlining(return_from_generator); | 9867 AddNodeForFinallyInlining(return_from_generator); |
| 9829 AstNode* if_is_cancelled = | 9868 AstNode* if_is_cancelled = |
| 9830 new(Z) IfNode(Token::kNoSourcePos, add_call, true_branch, NULL); | 9869 new(Z) IfNode(TokenDescriptor::kNoSource, add_call, true_branch, NULL); |
| 9831 yield->AddNode(if_is_cancelled); | 9870 yield->AddNode(if_is_cancelled); |
| 9832 | 9871 |
| 9833 AwaitMarkerNode* await_marker = | 9872 AwaitMarkerNode* await_marker = |
| 9834 new(Z) AwaitMarkerNode(async_temp_scope_, | 9873 new(Z) AwaitMarkerNode(async_temp_scope_, |
| 9835 current_block_->scope, | 9874 current_block_->scope, |
| 9836 Token::kNoSourcePos); | 9875 TokenDescriptor::kNoSource); |
| 9837 yield->AddNode(await_marker); | 9876 yield->AddNode(await_marker); |
| 9838 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); | 9877 ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos); |
| 9839 continuation_return->set_return_type(ReturnNode::kContinuationTarget); | 9878 continuation_return->set_return_type(ReturnNode::kContinuationTarget); |
| 9840 yield->AddNode(continuation_return); | 9879 yield->AddNode(continuation_return); |
| 9841 | 9880 |
| 9842 // If this expression is part of a try block, also append the code for | 9881 // If this expression is part of a try block, also append the code for |
| 9843 // restoring the saved try context that lives on the stack and possibly the | 9882 // restoring the saved try context that lives on the stack and possibly the |
| 9844 // saved try context of the outer try block. | 9883 // saved try context of the outer try block. |
| 9845 LocalVariable* saved_try_ctx; | 9884 LocalVariable* saved_try_ctx; |
| 9846 LocalVariable* async_saved_try_ctx; | 9885 LocalVariable* async_saved_try_ctx; |
| 9847 LocalVariable* outer_saved_try_ctx; | 9886 LocalVariable* outer_saved_try_ctx; |
| 9848 LocalVariable* outer_async_saved_try_ctx; | 9887 LocalVariable* outer_async_saved_try_ctx; |
| 9849 CheckAsyncOpInTryBlock(&saved_try_ctx, | 9888 CheckAsyncOpInTryBlock(&saved_try_ctx, |
| 9850 &async_saved_try_ctx, | 9889 &async_saved_try_ctx, |
| 9851 &outer_saved_try_ctx, | 9890 &outer_saved_try_ctx, |
| 9852 &outer_async_saved_try_ctx); | 9891 &outer_async_saved_try_ctx); |
| 9853 if (saved_try_ctx != NULL) { | 9892 if (saved_try_ctx != NULL) { |
| 9854 yield->AddNode(new (Z) StoreLocalNode( | 9893 yield->AddNode(new (Z) StoreLocalNode( |
| 9855 Token::kNoSourcePos, | 9894 TokenDescriptor::kNoSource, |
| 9856 saved_try_ctx, | 9895 saved_try_ctx, |
| 9857 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9896 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 9858 async_saved_try_ctx))); | 9897 async_saved_try_ctx))); |
| 9859 if (outer_saved_try_ctx != NULL) { | 9898 if (outer_saved_try_ctx != NULL) { |
| 9860 yield->AddNode(new (Z) StoreLocalNode( | 9899 yield->AddNode(new (Z) StoreLocalNode( |
| 9861 Token::kNoSourcePos, | 9900 TokenDescriptor::kNoSource, |
| 9862 outer_saved_try_ctx, | 9901 outer_saved_try_ctx, |
| 9863 new (Z) LoadLocalNode(Token::kNoSourcePos, | 9902 new (Z) LoadLocalNode(TokenDescriptor::kNoSource, |
| 9864 outer_async_saved_try_ctx))); | 9903 outer_async_saved_try_ctx))); |
| 9865 } | 9904 } |
| 9866 } else { | 9905 } else { |
| 9867 ASSERT(outer_saved_try_ctx == NULL); | 9906 ASSERT(outer_saved_try_ctx == NULL); |
| 9868 } | 9907 } |
| 9869 } | 9908 } |
| 9870 return yield; | 9909 return yield; |
| 9871 } | 9910 } |
| 9872 | 9911 |
| 9873 | 9912 |
| 9874 AstNode* Parser::ParseStatement() { | 9913 AstNode* Parser::ParseStatement() { |
| 9875 TRACE_PARSER("ParseStatement"); | 9914 TRACE_PARSER("ParseStatement"); |
| 9876 AstNode* statement = NULL; | 9915 AstNode* statement = NULL; |
| 9877 intptr_t label_pos = Token::kNoSourcePos; | 9916 TokenDescriptor label_pos = TokenDescriptor::kNoSource; |
| 9878 String* label_name = NULL; | 9917 String* label_name = NULL; |
| 9879 if (IsIdentifier()) { | 9918 if (IsIdentifier()) { |
| 9880 if (LookaheadToken(1) == Token::kCOLON) { | 9919 if (LookaheadToken(1) == Token::kCOLON) { |
| 9881 // Statement starts with a label. | 9920 // Statement starts with a label. |
| 9882 label_name = CurrentLiteral(); | 9921 label_name = CurrentLiteral(); |
| 9883 label_pos = TokenPos(); | 9922 label_pos = TokenPos(); |
| 9884 ASSERT(label_pos >= 0); | 9923 ASSERT(label_pos.IsReal()); |
| 9885 ConsumeToken(); // Consume identifier. | 9924 ConsumeToken(); // Consume identifier. |
| 9886 ConsumeToken(); // Consume colon. | 9925 ConsumeToken(); // Consume colon. |
| 9887 } | 9926 } |
| 9888 } | 9927 } |
| 9889 const intptr_t statement_pos = TokenPos(); | 9928 const TokenDescriptor statement_pos = TokenPos(); |
| 9890 const Token::Kind token = CurrentToken(); | 9929 const Token::Kind token = CurrentToken(); |
| 9891 | 9930 |
| 9892 if (token == Token::kWHILE) { | 9931 if (token == Token::kWHILE) { |
| 9893 statement = ParseWhileStatement(label_name); | 9932 statement = ParseWhileStatement(label_name); |
| 9894 } else if (token == Token::kFOR) { | 9933 } else if (token == Token::kFOR) { |
| 9895 statement = ParseForStatement(label_name); | 9934 statement = ParseForStatement(label_name); |
| 9896 } else if (IsAwaitKeyword() && (LookaheadToken(1) == Token::kFOR)) { | 9935 } else if (IsAwaitKeyword() && (LookaheadToken(1) == Token::kFOR)) { |
| 9897 statement = ParseAwaitForStatement(label_name); | 9936 statement = ParseAwaitForStatement(label_name); |
| 9898 } else if (token == Token::kDO) { | 9937 } else if (token == Token::kDO) { |
| 9899 statement = ParseDoWhileStatement(label_name); | 9938 statement = ParseDoWhileStatement(label_name); |
| 9900 } else if (token == Token::kSWITCH) { | 9939 } else if (token == Token::kSWITCH) { |
| 9901 statement = ParseSwitchStatement(label_name); | 9940 statement = ParseSwitchStatement(label_name); |
| 9902 } else if (token == Token::kTRY) { | 9941 } else if (token == Token::kTRY) { |
| 9903 statement = ParseTryStatement(label_name); | 9942 statement = ParseTryStatement(label_name); |
| 9904 } else if (token == Token::kRETURN) { | 9943 } else if (token == Token::kRETURN) { |
| 9905 const intptr_t return_pos = TokenPos(); | 9944 const TokenDescriptor return_pos = TokenPos(); |
| 9906 ConsumeToken(); | 9945 ConsumeToken(); |
| 9907 if (CurrentToken() != Token::kSEMICOLON) { | 9946 if (CurrentToken() != Token::kSEMICOLON) { |
| 9908 const intptr_t expr_pos = TokenPos(); | 9947 const TokenDescriptor expr_pos = TokenPos(); |
| 9909 if (current_function().IsGenerativeConstructor() && | 9948 if (current_function().IsGenerativeConstructor() && |
| 9910 (current_block_->scope->function_level() == 0)) { | 9949 (current_block_->scope->function_level() == 0)) { |
| 9911 ReportError(expr_pos, | 9950 ReportError(expr_pos, |
| 9912 "return of a value is not allowed in constructors"); | 9951 "return of a value is not allowed in constructors"); |
| 9913 } else if (current_function().IsGeneratorClosure() && | 9952 } else if (current_function().IsGeneratorClosure() && |
| 9914 (current_block_->scope->function_level() == 0)) { | 9953 (current_block_->scope->function_level() == 0)) { |
| 9915 ReportError(expr_pos, "generator functions may not return a value"); | 9954 ReportError(expr_pos, "generator functions may not return a value"); |
| 9916 } | 9955 } |
| 9917 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 9956 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 9918 statement = new(Z) ReturnNode(statement_pos, expr); | 9957 statement = new(Z) ReturnNode(statement_pos, expr); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10014 } | 10053 } |
| 10015 | 10054 |
| 10016 | 10055 |
| 10017 void Parser::ReportError(const Error& error) { | 10056 void Parser::ReportError(const Error& error) { |
| 10018 Report::LongJump(error); | 10057 Report::LongJump(error); |
| 10019 UNREACHABLE(); | 10058 UNREACHABLE(); |
| 10020 } | 10059 } |
| 10021 | 10060 |
| 10022 | 10061 |
| 10023 void Parser::ReportErrors(const Error& prev_error, | 10062 void Parser::ReportErrors(const Error& prev_error, |
| 10024 const Script& script, intptr_t token_pos, | 10063 const Script& script, TokenDescriptor token_pos, |
| 10025 const char* format, ...) { | 10064 const char* format, ...) { |
| 10026 va_list args; | 10065 va_list args; |
| 10027 va_start(args, format); | 10066 va_start(args, format); |
| 10028 Report::LongJumpV(prev_error, script, token_pos, format, args); | 10067 Report::LongJumpV(prev_error, script, token_pos, format, args); |
| 10029 va_end(args); | 10068 va_end(args); |
| 10030 UNREACHABLE(); | 10069 UNREACHABLE(); |
| 10031 } | 10070 } |
| 10032 | 10071 |
| 10033 | 10072 |
| 10034 void Parser::ReportError(intptr_t token_pos, const char* format, ...) const { | 10073 void Parser::ReportError(TokenDescriptor token_pos, |
| 10074 const char* format, ...) const { |
| 10035 va_list args; | 10075 va_list args; |
| 10036 va_start(args, format); | 10076 va_start(args, format); |
| 10037 Report::MessageV(Report::kError, | 10077 Report::MessageV(Report::kError, |
| 10038 script_, token_pos, Report::AtLocation, format, args); | 10078 script_, token_pos, Report::AtLocation, format, args); |
| 10039 va_end(args); | 10079 va_end(args); |
| 10040 UNREACHABLE(); | 10080 UNREACHABLE(); |
| 10041 } | 10081 } |
| 10042 | 10082 |
| 10043 | 10083 |
| 10044 void Parser::ReportErrorBefore(const char* format, ...) { | 10084 void Parser::ReportErrorBefore(const char* format, ...) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 10055 void Parser::ReportError(const char* format, ...) const { | 10095 void Parser::ReportError(const char* format, ...) const { |
| 10056 va_list args; | 10096 va_list args; |
| 10057 va_start(args, format); | 10097 va_start(args, format); |
| 10058 Report::MessageV(Report::kError, | 10098 Report::MessageV(Report::kError, |
| 10059 script_, TokenPos(), Report::AtLocation, format, args); | 10099 script_, TokenPos(), Report::AtLocation, format, args); |
| 10060 va_end(args); | 10100 va_end(args); |
| 10061 UNREACHABLE(); | 10101 UNREACHABLE(); |
| 10062 } | 10102 } |
| 10063 | 10103 |
| 10064 | 10104 |
| 10065 void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const { | 10105 void Parser::ReportWarning(TokenDescriptor token_pos, |
| 10106 const char* format, ...) const { |
| 10066 va_list args; | 10107 va_list args; |
| 10067 va_start(args, format); | 10108 va_start(args, format); |
| 10068 Report::MessageV(Report::kWarning, | 10109 Report::MessageV(Report::kWarning, |
| 10069 script_, token_pos, Report::AtLocation, format, args); | 10110 script_, token_pos, Report::AtLocation, format, args); |
| 10070 va_end(args); | 10111 va_end(args); |
| 10071 } | 10112 } |
| 10072 | 10113 |
| 10073 | 10114 |
| 10074 void Parser::ReportWarning(const char* format, ...) const { | 10115 void Parser::ReportWarning(const char* format, ...) const { |
| 10075 va_list args; | 10116 va_list args; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10155 } | 10196 } |
| 10156 | 10197 |
| 10157 | 10198 |
| 10158 static bool IsPrefixOperator(Token::Kind token) { | 10199 static bool IsPrefixOperator(Token::Kind token) { |
| 10159 return (token == Token::kSUB) || | 10200 return (token == Token::kSUB) || |
| 10160 (token == Token::kNOT) || | 10201 (token == Token::kNOT) || |
| 10161 (token == Token::kBIT_NOT); | 10202 (token == Token::kBIT_NOT); |
| 10162 } | 10203 } |
| 10163 | 10204 |
| 10164 | 10205 |
| 10165 SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos, | 10206 SequenceNode* Parser::NodeAsSequenceNode(TokenDescriptor sequence_pos, |
| 10166 AstNode* node, | 10207 AstNode* node, |
| 10167 LocalScope* scope) { | 10208 LocalScope* scope) { |
| 10168 if ((node == NULL) || !node->IsSequenceNode()) { | 10209 if ((node == NULL) || !node->IsSequenceNode()) { |
| 10169 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); | 10210 SequenceNode* sequence = new SequenceNode(sequence_pos, scope); |
| 10170 if (node != NULL) { | 10211 if (node != NULL) { |
| 10171 sequence->Add(node); | 10212 sequence->Add(node); |
| 10172 } | 10213 } |
| 10173 return sequence; | 10214 return sequence; |
| 10174 } | 10215 } |
| 10175 return node->AsSequenceNode(); | 10216 return node->AsSequenceNode(); |
| 10176 } | 10217 } |
| 10177 | 10218 |
| 10178 | 10219 |
| 10179 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10220 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
| 10180 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type, | 10221 AstNode* Parser::ThrowTypeError(TokenDescriptor type_pos, |
| 10222 const AbstractType& type, |
| 10181 LibraryPrefix* prefix) { | 10223 LibraryPrefix* prefix) { |
| 10182 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); | 10224 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); |
| 10183 | 10225 |
| 10184 String& method_name = String::Handle(Z); | 10226 String& method_name = String::Handle(Z); |
| 10185 if (prefix == NULL) { | 10227 if (prefix == NULL) { |
| 10186 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); | 10228 method_name = Library::PrivateCoreLibName(Symbols::ThrowNew()).raw(); |
| 10187 } else { | 10229 } else { |
| 10188 arguments->Add(new(Z) LiteralNode(type_pos, *prefix)); | 10230 arguments->Add(new(Z) LiteralNode(type_pos, *prefix)); |
| 10189 method_name = Library::PrivateCoreLibName( | 10231 method_name = Library::PrivateCoreLibName( |
| 10190 Symbols::ThrowNewIfNotLoaded()).raw(); | 10232 Symbols::ThrowNewIfNotLoaded()).raw(); |
| 10191 } | 10233 } |
| 10192 // Location argument. | 10234 // Location argument. |
| 10193 arguments->Add(new(Z) LiteralNode( | 10235 arguments->Add(new(Z) LiteralNode( |
| 10194 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos)))); | 10236 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos.value())))); |
| 10195 // Src value argument. | 10237 // Src value argument. |
| 10196 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); | 10238 arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance())); |
| 10197 // Dst type name argument. | 10239 // Dst type name argument. |
| 10198 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed())); | 10240 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed())); |
| 10199 // Dst name argument. | 10241 // Dst name argument. |
| 10200 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); | 10242 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); |
| 10201 // Malformed type error or malbounded type error. | 10243 // Malformed type error or malbounded type error. |
| 10202 const Error& error = Error::Handle(Z, type.error()); | 10244 const Error& error = Error::Handle(Z, type.error()); |
| 10203 ASSERT(!error.IsNull()); | 10245 ASSERT(!error.IsNull()); |
| 10204 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, | 10246 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, |
| 10205 Symbols::New(error.ToErrorCString())))); | 10247 Symbols::New(error.ToErrorCString())))); |
| 10206 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); | 10248 return MakeStaticCall(Symbols::TypeError(), method_name, arguments); |
| 10207 } | 10249 } |
| 10208 | 10250 |
| 10209 | 10251 |
| 10210 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. | 10252 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew. |
| 10211 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 10253 AstNode* Parser::ThrowNoSuchMethodError(TokenDescriptor call_pos, |
| 10212 const Class& cls, | 10254 const Class& cls, |
| 10213 const String& function_name, | 10255 const String& function_name, |
| 10214 ArgumentListNode* function_arguments, | 10256 ArgumentListNode* function_arguments, |
| 10215 InvocationMirror::Call im_call, | 10257 InvocationMirror::Call im_call, |
| 10216 InvocationMirror::Type im_type, | 10258 InvocationMirror::Type im_type, |
| 10217 const Function* func, | 10259 const Function* func, |
| 10218 const LibraryPrefix* prefix) { | 10260 const LibraryPrefix* prefix) { |
| 10219 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); | 10261 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); |
| 10220 | 10262 |
| 10221 String& method_name = String::Handle(Z); | 10263 String& method_name = String::Handle(Z); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10307 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); | 10349 ASSERT(min_preced >= Token::Precedence(Token::kIFNULL)); |
| 10308 AstNode* left_operand = ParseUnaryExpr(); | 10350 AstNode* left_operand = ParseUnaryExpr(); |
| 10309 if (left_operand->IsPrimaryNode() && | 10351 if (left_operand->IsPrimaryNode() && |
| 10310 (left_operand->AsPrimaryNode()->IsSuper())) { | 10352 (left_operand->AsPrimaryNode()->IsSuper())) { |
| 10311 ReportError(left_operand->token_pos(), "illegal use of 'super'"); | 10353 ReportError(left_operand->token_pos(), "illegal use of 'super'"); |
| 10312 } | 10354 } |
| 10313 int current_preced = Token::Precedence(CurrentToken()); | 10355 int current_preced = Token::Precedence(CurrentToken()); |
| 10314 while (current_preced >= min_preced) { | 10356 while (current_preced >= min_preced) { |
| 10315 while (Token::Precedence(CurrentToken()) == current_preced) { | 10357 while (Token::Precedence(CurrentToken()) == current_preced) { |
| 10316 Token::Kind op_kind = CurrentToken(); | 10358 Token::Kind op_kind = CurrentToken(); |
| 10317 const intptr_t op_pos = TokenPos(); | 10359 const TokenDescriptor op_pos = TokenPos(); |
| 10318 ConsumeToken(); | 10360 ConsumeToken(); |
| 10319 AstNode* right_operand = NULL; | 10361 AstNode* right_operand = NULL; |
| 10320 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 10362 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
| 10321 right_operand = ParseBinaryExpr(current_preced + 1); | 10363 right_operand = ParseBinaryExpr(current_preced + 1); |
| 10322 } else { | 10364 } else { |
| 10323 // For 'is' and 'as' we expect the right operand to be a type. | 10365 // For 'is' and 'as' we expect the right operand to be a type. |
| 10324 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { | 10366 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { |
| 10325 ConsumeToken(); | 10367 ConsumeToken(); |
| 10326 op_kind = Token::kISNOT; | 10368 op_kind = Token::kISNOT; |
| 10327 } | 10369 } |
| 10328 const intptr_t type_pos = TokenPos(); | 10370 const TokenDescriptor type_pos = TokenPos(); |
| 10329 const AbstractType& type = AbstractType::ZoneHandle(Z, | 10371 const AbstractType& type = AbstractType::ZoneHandle(Z, |
| 10330 ParseType(ClassFinalizer::kCanonicalize)); | 10372 ParseType(ClassFinalizer::kCanonicalize)); |
| 10331 if (!type.IsInstantiated() && | 10373 if (!type.IsInstantiated() && |
| 10332 (current_block_->scope->function_level() > 0)) { | 10374 (current_block_->scope->function_level() > 0)) { |
| 10333 // Make sure that the instantiator is captured. | 10375 // Make sure that the instantiator is captured. |
| 10334 CaptureInstantiator(); | 10376 CaptureInstantiator(); |
| 10335 } | 10377 } |
| 10336 right_operand = new(Z) TypeNode(type_pos, type); | 10378 right_operand = new(Z) TypeNode(type_pos, type); |
| 10337 // In production mode, the type may be malformed. | 10379 // In production mode, the type may be malformed. |
| 10338 // In checked mode, the type may be malformed or malbounded. | 10380 // In checked mode, the type may be malformed or malbounded. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10396 return expressions; | 10438 return expressions; |
| 10397 } | 10439 } |
| 10398 | 10440 |
| 10399 | 10441 |
| 10400 void Parser::EnsureExpressionTemp() { | 10442 void Parser::EnsureExpressionTemp() { |
| 10401 // Temporary used later by the flow_graph_builder. | 10443 // Temporary used later by the flow_graph_builder. |
| 10402 parsed_function()->EnsureExpressionTemp(); | 10444 parsed_function()->EnsureExpressionTemp(); |
| 10403 } | 10445 } |
| 10404 | 10446 |
| 10405 | 10447 |
| 10406 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 10448 LocalVariable* Parser::CreateTempConstVariable(TokenDescriptor token_pos, |
| 10407 const char* s) { | 10449 const char* s) { |
| 10408 char name[64]; | 10450 char name[64]; |
| 10409 OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos); | 10451 OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value()); |
| 10410 LocalVariable* temp = new(Z) LocalVariable( | 10452 LocalVariable* temp = new(Z) LocalVariable( |
| 10411 token_pos, | 10453 token_pos, |
| 10412 String::ZoneHandle(Z, Symbols::New(name)), | 10454 String::ZoneHandle(Z, Symbols::New(name)), |
| 10413 Object::dynamic_type()); | 10455 Object::dynamic_type()); |
| 10414 temp->set_is_final(); | 10456 temp->set_is_final(); |
| 10415 current_block_->scope->AddVariable(temp); | 10457 current_block_->scope->AddVariable(temp); |
| 10416 return temp; | 10458 return temp; |
| 10417 } | 10459 } |
| 10418 | 10460 |
| 10419 | 10461 |
| 10420 // TODO(srdjan): Implement other optimizations. | 10462 // TODO(srdjan): Implement other optimizations. |
| 10421 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, | 10463 AstNode* Parser::OptimizeBinaryOpNode(TokenDescriptor op_pos, |
| 10422 Token::Kind binary_op, | 10464 Token::Kind binary_op, |
| 10423 AstNode* lhs, | 10465 AstNode* lhs, |
| 10424 AstNode* rhs) { | 10466 AstNode* rhs) { |
| 10425 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 10467 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
| 10426 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 10468 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
| 10427 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 10469 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
| 10428 if (lhs_literal->literal().IsDouble() && | 10470 if (lhs_literal->literal().IsDouble() && |
| 10429 rhs_literal->literal().IsDouble()) { | 10471 rhs_literal->literal().IsDouble()) { |
| 10430 double left_double = Double::Cast(lhs_literal->literal()).value(); | 10472 double left_double = Double::Cast(lhs_literal->literal()).value(); |
| 10431 double right_double = Double::Cast(rhs_literal->literal()).value(); | 10473 double right_double = Double::Cast(rhs_literal->literal()).value(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10469 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); | 10511 expr_value = EvaluateConstExpr(rhs->token_pos(), rhs).raw(); |
| 10470 } | 10512 } |
| 10471 CacheConstantValue(op_pos, expr_value); | 10513 CacheConstantValue(op_pos, expr_value); |
| 10472 } | 10514 } |
| 10473 return new(Z) LiteralNode(op_pos, expr_value); | 10515 return new(Z) LiteralNode(op_pos, expr_value); |
| 10474 } | 10516 } |
| 10475 | 10517 |
| 10476 LetNode* result = new(Z) LetNode(op_pos); | 10518 LetNode* result = new(Z) LetNode(op_pos); |
| 10477 LocalVariable* left_temp = result->AddInitializer(lhs); | 10519 LocalVariable* left_temp = result->AddInitializer(lhs); |
| 10478 left_temp->set_is_final(); | 10520 left_temp->set_is_final(); |
| 10479 const intptr_t no_pos = Token::kNoSourcePos; | 10521 const TokenDescriptor no_pos = TokenDescriptor::kNoSource; |
| 10480 LiteralNode* null_operand = | 10522 LiteralNode* null_operand = |
| 10481 new(Z) LiteralNode(no_pos, Object::null_instance()); | 10523 new(Z) LiteralNode(no_pos, Object::null_instance()); |
| 10482 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); | 10524 LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp); |
| 10483 ComparisonNode* null_compare = | 10525 ComparisonNode* null_compare = |
| 10484 new(Z) ComparisonNode(no_pos, | 10526 new(Z) ComparisonNode(no_pos, |
| 10485 Token::kNE_STRICT, | 10527 Token::kNE_STRICT, |
| 10486 load_left_temp, | 10528 load_left_temp, |
| 10487 null_operand); | 10529 null_operand); |
| 10488 result->AddNode(new(Z) ConditionalExprNode(op_pos, | 10530 result->AddNode(new(Z) ConditionalExprNode(op_pos, |
| 10489 null_compare, | 10531 null_compare, |
| 10490 load_left_temp, | 10532 load_left_temp, |
| 10491 rhs)); | 10533 rhs)); |
| 10492 return result; | 10534 return result; |
| 10493 } | 10535 } |
| 10494 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 10536 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
| 10495 } | 10537 } |
| 10496 | 10538 |
| 10497 | 10539 |
| 10498 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, | 10540 AstNode* Parser::ExpandAssignableOp(TokenDescriptor op_pos, |
| 10499 Token::Kind assignment_op, | 10541 Token::Kind assignment_op, |
| 10500 AstNode* lhs, | 10542 AstNode* lhs, |
| 10501 AstNode* rhs) { | 10543 AstNode* rhs) { |
| 10502 TRACE_PARSER("ExpandAssignableOp"); | 10544 TRACE_PARSER("ExpandAssignableOp"); |
| 10503 switch (assignment_op) { | 10545 switch (assignment_op) { |
| 10504 case Token::kASSIGN: | 10546 case Token::kASSIGN: |
| 10505 return rhs; | 10547 return rhs; |
| 10506 case Token::kASSIGN_ADD: | 10548 case Token::kASSIGN_ADD: |
| 10507 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 10549 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
| 10508 case Token::kASSIGN_SUB: | 10550 case Token::kASSIGN_SUB: |
| (...skipping 23 matching lines...) Expand all Loading... |
| 10532 "internal error: ExpandAssignableOp '%s' unimplemented", | 10574 "internal error: ExpandAssignableOp '%s' unimplemented", |
| 10533 Token::Name(assignment_op)); | 10575 Token::Name(assignment_op)); |
| 10534 UNIMPLEMENTED(); | 10576 UNIMPLEMENTED(); |
| 10535 return NULL; | 10577 return NULL; |
| 10536 } | 10578 } |
| 10537 } | 10579 } |
| 10538 | 10580 |
| 10539 | 10581 |
| 10540 // Evaluates the value of the compile time constant expression | 10582 // Evaluates the value of the compile time constant expression |
| 10541 // and returns a literal node for the value. | 10583 // and returns a literal node for the value. |
| 10542 LiteralNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { | 10584 LiteralNode* Parser::FoldConstExpr(TokenDescriptor expr_pos, AstNode* expr) { |
| 10543 if (expr->IsLiteralNode()) { | 10585 if (expr->IsLiteralNode()) { |
| 10544 return expr->AsLiteralNode(); | 10586 return expr->AsLiteralNode(); |
| 10545 } | 10587 } |
| 10546 if (expr->EvalConstExpr() == NULL) { | 10588 if (expr->EvalConstExpr() == NULL) { |
| 10547 ReportError(expr_pos, "expression is not a valid compile-time constant"); | 10589 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
| 10548 } | 10590 } |
| 10549 return new(Z) LiteralNode( | 10591 return new(Z) LiteralNode( |
| 10550 expr_pos, EvaluateConstExpr(expr_pos, expr)); | 10592 expr_pos, EvaluateConstExpr(expr_pos, expr)); |
| 10551 } | 10593 } |
| 10552 | 10594 |
| 10553 | 10595 |
| 10554 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 10596 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
| 10555 AstNode* node = *expr; | 10597 AstNode* node = *expr; |
| 10556 intptr_t token_pos = node->token_pos(); | 10598 TokenDescriptor token_pos = node->token_pos(); |
| 10557 LetNode* result = new(Z) LetNode(token_pos); | 10599 LetNode* result = new(Z) LetNode(token_pos); |
| 10558 if (node->IsLoadIndexedNode()) { | 10600 if (node->IsLoadIndexedNode()) { |
| 10559 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 10601 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
| 10560 AstNode* array = load_indexed->array(); | 10602 AstNode* array = load_indexed->array(); |
| 10561 AstNode* index = load_indexed->index_expr(); | 10603 AstNode* index = load_indexed->index_expr(); |
| 10562 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 10604 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
| 10563 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 10605 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
| 10564 array = new(Z) LoadLocalNode(token_pos, t0); | 10606 array = new(Z) LoadLocalNode(token_pos, t0); |
| 10565 } | 10607 } |
| 10566 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { | 10608 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 10590 | 10632 |
| 10591 | 10633 |
| 10592 // Check whether the syntax of expression expr is a grammatically legal | 10634 // Check whether the syntax of expression expr is a grammatically legal |
| 10593 // assignable expression. This check is used to detect situations where | 10635 // assignable expression. This check is used to detect situations where |
| 10594 // the expression itself is assignable, but the source is grammatically | 10636 // the expression itself is assignable, but the source is grammatically |
| 10595 // wrong. The AST representation of an expression cannot distinguish | 10637 // wrong. The AST representation of an expression cannot distinguish |
| 10596 // between x = 0 and (x) = 0. The latter is illegal. | 10638 // between x = 0 and (x) = 0. The latter is illegal. |
| 10597 // A syntactically legal assignable expression always ends with an | 10639 // A syntactically legal assignable expression always ends with an |
| 10598 // identifier token or a ] token. We rewind the token iterator and | 10640 // identifier token or a ] token. We rewind the token iterator and |
| 10599 // check whether the token before end_pos is an identifier or ]. | 10641 // check whether the token before end_pos is an identifier or ]. |
| 10600 bool Parser::IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos) { | 10642 bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenDescriptor end_pos) { |
| 10601 ASSERT(expr->token_pos() >= 0); | 10643 ASSERT(expr->token_pos().IsReal()); |
| 10602 ASSERT(expr->token_pos() < end_pos); | 10644 ASSERT(expr->token_pos() < end_pos); |
| 10603 SetPosition(expr->token_pos()); | 10645 SetPosition(expr->token_pos()); |
| 10604 Token::Kind token = Token::kILLEGAL; | 10646 Token::Kind token = Token::kILLEGAL; |
| 10605 while (TokenPos() < end_pos) { | 10647 while (TokenPos() < end_pos) { |
| 10606 token = CurrentToken(); | 10648 token = CurrentToken(); |
| 10607 ConsumeToken(); | 10649 ConsumeToken(); |
| 10608 } | 10650 } |
| 10609 ASSERT(TokenPos() == end_pos); | 10651 ASSERT(TokenPos() == end_pos); |
| 10610 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 10652 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
| 10611 } | 10653 } |
| 10612 | 10654 |
| 10613 | 10655 |
| 10614 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 10656 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
| 10615 AstNode* rhs, | 10657 AstNode* rhs, |
| 10616 const String* left_ident, | 10658 const String* left_ident, |
| 10617 intptr_t left_pos, | 10659 TokenDescriptor left_pos, |
| 10618 bool is_compound /* = false */) { | 10660 bool is_compound /* = false */) { |
| 10619 AstNode* result = original->MakeAssignmentNode(rhs); | 10661 AstNode* result = original->MakeAssignmentNode(rhs); |
| 10620 if (result == NULL) { | 10662 if (result == NULL) { |
| 10621 String& name = String::ZoneHandle(Z); | 10663 String& name = String::ZoneHandle(Z); |
| 10622 const Class* target_cls = ¤t_class(); | 10664 const Class* target_cls = ¤t_class(); |
| 10623 if (original->IsTypeNode()) { | 10665 if (original->IsTypeNode()) { |
| 10624 name = Symbols::New(original->AsTypeNode()->TypeName()); | 10666 name = Symbols::New(original->AsTypeNode()->TypeName()); |
| 10625 } else if (original->IsLoadStaticFieldNode()) { | 10667 } else if (original->IsLoadStaticFieldNode()) { |
| 10626 name = original->AsLoadStaticFieldNode()->field().name(); | 10668 name = original->AsLoadStaticFieldNode()->field().name(); |
| 10627 target_cls = &Class::Handle(Z, | 10669 target_cls = &Class::Handle(Z, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10665 result = OptimizeBinaryOpNode(ifnull->token_pos(), | 10707 result = OptimizeBinaryOpNode(ifnull->token_pos(), |
| 10666 ifnull->kind(), | 10708 ifnull->kind(), |
| 10667 ifnull->left(), | 10709 ifnull->left(), |
| 10668 modified_assign); | 10710 modified_assign); |
| 10669 } | 10711 } |
| 10670 return result; | 10712 return result; |
| 10671 } | 10713 } |
| 10672 | 10714 |
| 10673 | 10715 |
| 10674 AstNode* Parser::ParseCascades(AstNode* expr) { | 10716 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 10675 intptr_t cascade_pos = TokenPos(); | 10717 TokenDescriptor cascade_pos = TokenPos(); |
| 10676 LetNode* cascade = new(Z) LetNode(cascade_pos); | 10718 LetNode* cascade = new(Z) LetNode(cascade_pos); |
| 10677 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 10719 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| 10678 while (CurrentToken() == Token::kCASCADE) { | 10720 while (CurrentToken() == Token::kCASCADE) { |
| 10679 cascade_pos = TokenPos(); | 10721 cascade_pos = TokenPos(); |
| 10680 LoadLocalNode* load_cascade_receiver = | 10722 LoadLocalNode* load_cascade_receiver = |
| 10681 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); | 10723 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); |
| 10682 if (Token::IsIdentifier(LookaheadToken(1))) { | 10724 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 10683 // Replace .. with . for ParseSelectors(). | 10725 // Replace .. with . for ParseSelectors(). |
| 10684 token_kind_ = Token::kPERIOD; | 10726 token_kind_ = Token::kPERIOD; |
| 10685 } else if (LookaheadToken(1) == Token::kLBRACK) { | 10727 } else if (LookaheadToken(1) == Token::kLBRACK) { |
| 10686 ConsumeToken(); | 10728 ConsumeToken(); |
| 10687 } else { | 10729 } else { |
| 10688 ReportError("identifier or [ expected after .."); | 10730 ReportError("identifier or [ expected after .."); |
| 10689 } | 10731 } |
| 10690 String* expr_ident = | 10732 String* expr_ident = |
| 10691 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10733 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 10692 const intptr_t expr_pos = TokenPos(); | 10734 const TokenDescriptor expr_pos = TokenPos(); |
| 10693 expr = ParseSelectors(load_cascade_receiver, true); | 10735 expr = ParseSelectors(load_cascade_receiver, true); |
| 10694 | 10736 |
| 10695 // Assignments after a cascade are part of the cascade. The | 10737 // Assignments after a cascade are part of the cascade. The |
| 10696 // assigned expression must not contain cascades. | 10738 // assigned expression must not contain cascades. |
| 10697 if (Token::IsAssignmentOperator(CurrentToken())) { | 10739 if (Token::IsAssignmentOperator(CurrentToken())) { |
| 10698 Token::Kind assignment_op = CurrentToken(); | 10740 Token::Kind assignment_op = CurrentToken(); |
| 10699 const intptr_t assignment_pos = TokenPos(); | 10741 const TokenDescriptor assignment_pos = TokenPos(); |
| 10700 ConsumeToken(); | 10742 ConsumeToken(); |
| 10701 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); | 10743 AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades); |
| 10702 if (assignment_op != Token::kASSIGN) { | 10744 if (assignment_op != Token::kASSIGN) { |
| 10703 // Compound assignment: store inputs with side effects into | 10745 // Compound assignment: store inputs with side effects into |
| 10704 // temporary locals. | 10746 // temporary locals. |
| 10705 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10747 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10706 right_expr = | 10748 right_expr = |
| 10707 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10749 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10708 AstNode* assign_expr = | 10750 AstNode* assign_expr = |
| 10709 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true); | 10751 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos, true); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10769 } | 10811 } |
| 10770 return expr; | 10812 return expr; |
| 10771 } | 10813 } |
| 10772 | 10814 |
| 10773 | 10815 |
| 10774 AstNode* Parser::ParseExpr(bool require_compiletime_const, | 10816 AstNode* Parser::ParseExpr(bool require_compiletime_const, |
| 10775 bool consume_cascades) { | 10817 bool consume_cascades) { |
| 10776 TRACE_PARSER("ParseExpr"); | 10818 TRACE_PARSER("ParseExpr"); |
| 10777 String* expr_ident = | 10819 String* expr_ident = |
| 10778 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10820 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 10779 const intptr_t expr_pos = TokenPos(); | 10821 const TokenDescriptor expr_pos = TokenPos(); |
| 10780 | 10822 |
| 10781 RecursionChecker rc(this); | 10823 RecursionChecker rc(this); |
| 10782 | 10824 |
| 10783 if (CurrentToken() == Token::kTHROW) { | 10825 if (CurrentToken() == Token::kTHROW) { |
| 10784 if (require_compiletime_const) { | 10826 if (require_compiletime_const) { |
| 10785 ReportError("'throw expr' is not a valid compile-time constant"); | 10827 ReportError("'throw expr' is not a valid compile-time constant"); |
| 10786 } | 10828 } |
| 10787 ConsumeToken(); | 10829 ConsumeToken(); |
| 10788 if (CurrentToken() == Token::kSEMICOLON) { | 10830 if (CurrentToken() == Token::kSEMICOLON) { |
| 10789 ReportError("expression expected after throw"); | 10831 ReportError("expression expected after throw"); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 10815 } else { | 10857 } else { |
| 10816 expr = LiteralIfStaticConst(Z, expr); | 10858 expr = LiteralIfStaticConst(Z, expr); |
| 10817 } | 10859 } |
| 10818 return expr; | 10860 return expr; |
| 10819 } | 10861 } |
| 10820 // Assignment expressions. | 10862 // Assignment expressions. |
| 10821 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 10863 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 10822 ReportError(expr_pos, "expression is not assignable"); | 10864 ReportError(expr_pos, "expression is not assignable"); |
| 10823 } | 10865 } |
| 10824 const Token::Kind assignment_op = CurrentToken(); | 10866 const Token::Kind assignment_op = CurrentToken(); |
| 10825 const intptr_t assignment_pos = TokenPos(); | 10867 const TokenDescriptor assignment_pos = TokenPos(); |
| 10826 ConsumeToken(); | 10868 ConsumeToken(); |
| 10827 const intptr_t right_expr_pos = TokenPos(); | 10869 const TokenDescriptor right_expr_pos = TokenPos(); |
| 10828 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 10870 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 10829 ReportError(right_expr_pos, | 10871 ReportError(right_expr_pos, |
| 10830 "expression is not a valid compile-time constant"); | 10872 "expression is not a valid compile-time constant"); |
| 10831 } | 10873 } |
| 10832 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 10874 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 10833 if (assignment_op != Token::kASSIGN) { | 10875 if (assignment_op != Token::kASSIGN) { |
| 10834 // Compound assignment: store inputs with side effects into temp. locals. | 10876 // Compound assignment: store inputs with side effects into temp. locals. |
| 10835 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10877 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10836 AstNode* assigned_value = | 10878 AstNode* assigned_value = |
| 10837 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 10879 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 10838 AstNode* assign_expr = | 10880 AstNode* assign_expr = |
| 10839 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true); | 10881 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos, true); |
| 10840 ASSERT(assign_expr != NULL); | 10882 ASSERT(assign_expr != NULL); |
| 10841 let_expr->AddNode(assign_expr); | 10883 let_expr->AddNode(assign_expr); |
| 10842 return let_expr; | 10884 return let_expr; |
| 10843 } else { | 10885 } else { |
| 10844 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); | 10886 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
| 10845 AstNode* assign_expr = | 10887 AstNode* assign_expr = |
| 10846 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 10888 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
| 10847 ASSERT(assign_expr != NULL); | 10889 ASSERT(assign_expr != NULL); |
| 10848 return assign_expr; | 10890 return assign_expr; |
| 10849 } | 10891 } |
| 10850 } | 10892 } |
| 10851 | 10893 |
| 10852 | 10894 |
| 10853 LiteralNode* Parser::ParseConstExpr() { | 10895 LiteralNode* Parser::ParseConstExpr() { |
| 10854 TRACE_PARSER("ParseConstExpr"); | 10896 TRACE_PARSER("ParseConstExpr"); |
| 10855 intptr_t expr_pos = TokenPos(); | 10897 TokenDescriptor expr_pos = TokenPos(); |
| 10856 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 10898 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
| 10857 if (!expr->IsLiteralNode()) { | 10899 if (!expr->IsLiteralNode()) { |
| 10858 ReportError(expr_pos, "expression must be a compile-time constant"); | 10900 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 10859 } | 10901 } |
| 10860 return expr->AsLiteralNode(); | 10902 return expr->AsLiteralNode(); |
| 10861 } | 10903 } |
| 10862 | 10904 |
| 10863 | 10905 |
| 10864 AstNode* Parser::ParseConditionalExpr() { | 10906 AstNode* Parser::ParseConditionalExpr() { |
| 10865 TRACE_PARSER("ParseConditionalExpr"); | 10907 TRACE_PARSER("ParseConditionalExpr"); |
| 10866 const intptr_t expr_pos = TokenPos(); | 10908 const TokenDescriptor expr_pos = TokenPos(); |
| 10867 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); | 10909 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL)); |
| 10868 if (CurrentToken() == Token::kCONDITIONAL) { | 10910 if (CurrentToken() == Token::kCONDITIONAL) { |
| 10869 EnsureExpressionTemp(); | 10911 EnsureExpressionTemp(); |
| 10870 ConsumeToken(); | 10912 ConsumeToken(); |
| 10871 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 10913 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
| 10872 ExpectToken(Token::kCOLON); | 10914 ExpectToken(Token::kCOLON); |
| 10873 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 10915 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
| 10874 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 10916 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 10875 } | 10917 } |
| 10876 return expr; | 10918 return expr; |
| 10877 } | 10919 } |
| 10878 | 10920 |
| 10879 | 10921 |
| 10880 AstNode* Parser::ParseUnaryExpr() { | 10922 AstNode* Parser::ParseUnaryExpr() { |
| 10881 TRACE_PARSER("ParseUnaryExpr"); | 10923 TRACE_PARSER("ParseUnaryExpr"); |
| 10882 AstNode* expr = NULL; | 10924 AstNode* expr = NULL; |
| 10883 const intptr_t op_pos = TokenPos(); | 10925 const TokenDescriptor op_pos = TokenPos(); |
| 10884 if (IsAwaitKeyword()) { | 10926 if (IsAwaitKeyword()) { |
| 10885 TRACE_PARSER("ParseAwaitExpr"); | 10927 TRACE_PARSER("ParseAwaitExpr"); |
| 10886 if (!innermost_function().IsAsyncFunction() && | 10928 if (!innermost_function().IsAsyncFunction() && |
| 10887 !innermost_function().IsAsyncClosure() && | 10929 !innermost_function().IsAsyncClosure() && |
| 10888 !innermost_function().IsAsyncGenerator() && | 10930 !innermost_function().IsAsyncGenerator() && |
| 10889 !innermost_function().IsAsyncGenClosure()) { | 10931 !innermost_function().IsAsyncGenClosure()) { |
| 10890 ReportError("await operator is only allowed in an asynchronous function"); | 10932 ReportError("await operator is only allowed in an asynchronous function"); |
| 10891 } | 10933 } |
| 10892 ConsumeToken(); | 10934 ConsumeToken(); |
| 10893 parsed_function()->record_await(); | 10935 parsed_function()->record_await(); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 10917 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { | 10959 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { |
| 10918 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); | 10960 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); |
| 10919 } else { | 10961 } else { |
| 10920 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 10962 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
| 10921 } | 10963 } |
| 10922 } else if (IsIncrementOperator(CurrentToken())) { | 10964 } else if (IsIncrementOperator(CurrentToken())) { |
| 10923 Token::Kind incr_op = CurrentToken(); | 10965 Token::Kind incr_op = CurrentToken(); |
| 10924 ConsumeToken(); | 10966 ConsumeToken(); |
| 10925 String* expr_ident = | 10967 String* expr_ident = |
| 10926 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 10968 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 10927 const intptr_t expr_pos = TokenPos(); | 10969 const TokenDescriptor expr_pos = TokenPos(); |
| 10928 expr = ParseUnaryExpr(); | 10970 expr = ParseUnaryExpr(); |
| 10929 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 10971 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 10930 ReportError(expr_pos, "expression is not assignable"); | 10972 ReportError(expr_pos, "expression is not assignable"); |
| 10931 } | 10973 } |
| 10932 // Is prefix. | 10974 // Is prefix. |
| 10933 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 10975 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 10934 Token::Kind binary_op = | 10976 Token::Kind binary_op = |
| 10935 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 10977 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 10936 BinaryOpNode* add = new(Z) BinaryOpNode( | 10978 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 10937 op_pos, | 10979 op_pos, |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10998 SetAllowFunctionLiterals(saved_mode); | 11040 SetAllowFunctionLiterals(saved_mode); |
| 10999 if (named_argument_seen) { | 11041 if (named_argument_seen) { |
| 11000 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); | 11042 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); |
| 11001 } | 11043 } |
| 11002 return arguments; | 11044 return arguments; |
| 11003 } | 11045 } |
| 11004 | 11046 |
| 11005 | 11047 |
| 11006 AstNode* Parser::ParseStaticCall(const Class& cls, | 11048 AstNode* Parser::ParseStaticCall(const Class& cls, |
| 11007 const String& func_name, | 11049 const String& func_name, |
| 11008 intptr_t ident_pos) { | 11050 TokenDescriptor ident_pos) { |
| 11009 TRACE_PARSER("ParseStaticCall"); | 11051 TRACE_PARSER("ParseStaticCall"); |
| 11010 const intptr_t call_pos = TokenPos(); | 11052 const TokenDescriptor call_pos = TokenPos(); |
| 11011 ASSERT(CurrentToken() == Token::kLPAREN); | 11053 ASSERT(CurrentToken() == Token::kLPAREN); |
| 11012 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11054 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 11013 const int num_arguments = arguments->length(); | 11055 const int num_arguments = arguments->length(); |
| 11014 const Function& func = Function::ZoneHandle(Z, | 11056 const Function& func = Function::ZoneHandle(Z, |
| 11015 Resolver::ResolveStatic(cls, | 11057 Resolver::ResolveStatic(cls, |
| 11016 func_name, | 11058 func_name, |
| 11017 num_arguments, | 11059 num_arguments, |
| 11018 arguments->names())); | 11060 arguments->names())); |
| 11019 if (func.IsNull()) { | 11061 if (func.IsNull()) { |
| 11020 // Check if there is a static field of the same name, it could be a closure | 11062 // Check if there is a static field of the same name, it could be a closure |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11086 arguments->NodeAt(0), | 11128 arguments->NodeAt(0), |
| 11087 arguments->NodeAt(1)); | 11129 arguments->NodeAt(1)); |
| 11088 } | 11130 } |
| 11089 } | 11131 } |
| 11090 return new(Z) StaticCallNode(ident_pos, func, arguments); | 11132 return new(Z) StaticCallNode(ident_pos, func, arguments); |
| 11091 } | 11133 } |
| 11092 | 11134 |
| 11093 | 11135 |
| 11094 AstNode* Parser::ParseInstanceCall(AstNode* receiver, | 11136 AstNode* Parser::ParseInstanceCall(AstNode* receiver, |
| 11095 const String& func_name, | 11137 const String& func_name, |
| 11096 intptr_t ident_pos, | 11138 TokenDescriptor ident_pos, |
| 11097 bool is_conditional) { | 11139 bool is_conditional) { |
| 11098 TRACE_PARSER("ParseInstanceCall"); | 11140 TRACE_PARSER("ParseInstanceCall"); |
| 11099 CheckToken(Token::kLPAREN); | 11141 CheckToken(Token::kLPAREN); |
| 11100 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11142 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 11101 return new(Z) InstanceCallNode(ident_pos, | 11143 return new(Z) InstanceCallNode(ident_pos, |
| 11102 receiver, | 11144 receiver, |
| 11103 func_name, | 11145 func_name, |
| 11104 arguments, | 11146 arguments, |
| 11105 is_conditional); | 11147 is_conditional); |
| 11106 } | 11148 } |
| 11107 | 11149 |
| 11108 | 11150 |
| 11109 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 11151 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
| 11110 TRACE_PARSER("ParseClosureCall"); | 11152 TRACE_PARSER("ParseClosureCall"); |
| 11111 const intptr_t call_pos = TokenPos(); | 11153 const TokenDescriptor call_pos = TokenPos(); |
| 11112 ASSERT(CurrentToken() == Token::kLPAREN); | 11154 ASSERT(CurrentToken() == Token::kLPAREN); |
| 11113 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 11155 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 11114 return BuildClosureCall(call_pos, closure, arguments); | 11156 return BuildClosureCall(call_pos, closure, arguments); |
| 11115 } | 11157 } |
| 11116 | 11158 |
| 11117 | 11159 |
| 11118 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 11160 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
| 11119 intptr_t ident_pos) { | 11161 TokenDescriptor ident_pos) { |
| 11120 // If the static field has an initializer, initialize the field at compile | 11162 // If the static field has an initializer, initialize the field at compile |
| 11121 // time, which is only possible if the field is const. | 11163 // time, which is only possible if the field is const. |
| 11122 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 11164 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
| 11123 if (initializing_getter != NULL) { | 11165 if (initializing_getter != NULL) { |
| 11124 // The field is not yet initialized and could not be initialized at compile | 11166 // The field is not yet initialized and could not be initialized at compile |
| 11125 // time. The getter will initialize the field. | 11167 // time. The getter will initialize the field. |
| 11126 return initializing_getter; | 11168 return initializing_getter; |
| 11127 } | 11169 } |
| 11128 // The field is initialized. | 11170 // The field is initialized. |
| 11129 ASSERT(field.is_static()); | 11171 ASSERT(field.is_static()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 11143 NULL, // Receiver. | 11185 NULL, // Receiver. |
| 11144 field_owner, | 11186 field_owner, |
| 11145 field_name); | 11187 field_name); |
| 11146 } | 11188 } |
| 11147 } | 11189 } |
| 11148 | 11190 |
| 11149 | 11191 |
| 11150 // Reference to 'field_name' with explicit class as primary. | 11192 // Reference to 'field_name' with explicit class as primary. |
| 11151 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, | 11193 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls, |
| 11152 const String& field_name, | 11194 const String& field_name, |
| 11153 intptr_t ident_pos) { | 11195 TokenDescriptor ident_pos) { |
| 11154 AstNode* access = NULL; | 11196 AstNode* access = NULL; |
| 11155 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); | 11197 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); |
| 11156 Function& func = Function::ZoneHandle(Z); | 11198 Function& func = Function::ZoneHandle(Z); |
| 11157 if (field.IsNull()) { | 11199 if (field.IsNull()) { |
| 11158 // No field, check if we have an explicit getter function. | 11200 // No field, check if we have an explicit getter function. |
| 11159 func = cls.LookupGetterFunction(field_name); | 11201 func = cls.LookupGetterFunction(field_name); |
| 11160 if (func.IsNull() || func.IsDynamicFunction()) { | 11202 if (func.IsNull() || func.IsDynamicFunction()) { |
| 11161 // We might be referring to an implicit closure, check to see if | 11203 // We might be referring to an implicit closure, check to see if |
| 11162 // there is a function of the same name. | 11204 // there is a function of the same name. |
| 11163 func = cls.LookupStaticFunction(field_name); | 11205 func = cls.LookupStaticFunction(field_name); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11250 AstNode* left = primary; | 11292 AstNode* left = primary; |
| 11251 while (true) { | 11293 while (true) { |
| 11252 AstNode* selector = NULL; | 11294 AstNode* selector = NULL; |
| 11253 if ((CurrentToken() == Token::kPERIOD) || | 11295 if ((CurrentToken() == Token::kPERIOD) || |
| 11254 (CurrentToken() == Token::kQM_PERIOD)) { | 11296 (CurrentToken() == Token::kQM_PERIOD)) { |
| 11255 // Unconditional or conditional property extraction or method call. | 11297 // Unconditional or conditional property extraction or method call. |
| 11256 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; | 11298 bool is_conditional = CurrentToken() == Token::kQM_PERIOD; |
| 11257 ConsumeToken(); | 11299 ConsumeToken(); |
| 11258 if (left->IsPrimaryNode()) { | 11300 if (left->IsPrimaryNode()) { |
| 11259 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11301 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 11260 const intptr_t primary_pos = primary_node->token_pos(); | 11302 const TokenDescriptor primary_pos = primary_node->token_pos(); |
| 11261 if (primary_node->primary().IsFunction()) { | 11303 if (primary_node->primary().IsFunction()) { |
| 11262 left = LoadClosure(primary_node); | 11304 left = LoadClosure(primary_node); |
| 11263 } else if (primary_node->primary().IsTypeParameter()) { | 11305 } else if (primary_node->primary().IsTypeParameter()) { |
| 11264 if (ParsingStaticMember()) { | 11306 if (ParsingStaticMember()) { |
| 11265 const String& name = String::Handle(Z, | 11307 const String& name = String::Handle(Z, |
| 11266 TypeParameter::Cast(primary_node->primary()).name()); | 11308 TypeParameter::Cast(primary_node->primary()).name()); |
| 11267 ReportError(primary_pos, | 11309 ReportError(primary_pos, |
| 11268 "cannot access type parameter '%s' " | 11310 "cannot access type parameter '%s' " |
| 11269 "from static function", | 11311 "from static function", |
| 11270 name.ToCString()); | 11312 name.ToCString()); |
| 11271 } | 11313 } |
| 11272 if (current_block_->scope->function_level() > 0) { | 11314 if (current_block_->scope->function_level() > 0) { |
| 11273 // Make sure that the instantiator is captured. | 11315 // Make sure that the instantiator is captured. |
| 11274 CaptureInstantiator(); | 11316 CaptureInstantiator(); |
| 11275 } | 11317 } |
| 11276 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); | 11318 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
| 11277 type_parameter ^= ClassFinalizer::FinalizeType( | 11319 type_parameter ^= ClassFinalizer::FinalizeType( |
| 11278 current_class(), | 11320 current_class(), |
| 11279 TypeParameter::Cast(primary_node->primary()), | 11321 TypeParameter::Cast(primary_node->primary()), |
| 11280 ClassFinalizer::kCanonicalize); | 11322 ClassFinalizer::kCanonicalize); |
| 11281 ASSERT(!type_parameter.IsMalformed()); | 11323 ASSERT(!type_parameter.IsMalformed()); |
| 11282 left = new(Z) TypeNode(primary->token_pos(), type_parameter); | 11324 left = new(Z) TypeNode(primary->token_pos(), type_parameter); |
| 11283 } else { | 11325 } else { |
| 11284 // Super field access handled in ParseSuperFieldAccess(), | 11326 // Super field access handled in ParseSuperFieldAccess(), |
| 11285 // super calls handled in ParseSuperCall(). | 11327 // super calls handled in ParseSuperCall(). |
| 11286 ASSERT(!primary_node->IsSuper()); | 11328 ASSERT(!primary_node->IsSuper()); |
| 11287 left = LoadFieldIfUnresolved(left); | 11329 left = LoadFieldIfUnresolved(left); |
| 11288 } | 11330 } |
| 11289 } | 11331 } |
| 11290 const intptr_t ident_pos = TokenPos(); | 11332 const TokenDescriptor ident_pos = TokenPos(); |
| 11291 String* ident = ExpectIdentifier("identifier expected"); | 11333 String* ident = ExpectIdentifier("identifier expected"); |
| 11292 if (CurrentToken() == Token::kLPAREN) { | 11334 if (CurrentToken() == Token::kLPAREN) { |
| 11293 // Identifier followed by a opening paren: method call. | 11335 // Identifier followed by a opening paren: method call. |
| 11294 if (left->IsPrimaryNode() && | 11336 if (left->IsPrimaryNode() && |
| 11295 left->AsPrimaryNode()->primary().IsClass()) { | 11337 left->AsPrimaryNode()->primary().IsClass()) { |
| 11296 // Static method call prefixed with class name. | 11338 // Static method call prefixed with class name. |
| 11297 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | 11339 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); |
| 11298 selector = ParseStaticCall(cls, *ident, ident_pos); | 11340 selector = ParseStaticCall(cls, *ident, ident_pos); |
| 11299 } else { | 11341 } else { |
| 11300 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); | 11342 selector = ParseInstanceCall(left, *ident, ident_pos, is_conditional); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 11326 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 11368 selector->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
| 11327 } else if (selector->IsStaticGetterNode()) { | 11369 } else if (selector->IsStaticGetterNode()) { |
| 11328 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); | 11370 selector->AsStaticGetterNode()->set_is_deferred(is_deferred); |
| 11329 } | 11371 } |
| 11330 } | 11372 } |
| 11331 } | 11373 } |
| 11332 } else if (CurrentToken() == Token::kLBRACK) { | 11374 } else if (CurrentToken() == Token::kLBRACK) { |
| 11333 // Super index operator handled in ParseSuperOperator(). | 11375 // Super index operator handled in ParseSuperOperator(). |
| 11334 ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper()); | 11376 ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper()); |
| 11335 | 11377 |
| 11336 const intptr_t bracket_pos = TokenPos(); | 11378 const TokenDescriptor bracket_pos = TokenPos(); |
| 11337 ConsumeToken(); | 11379 ConsumeToken(); |
| 11338 left = LoadFieldIfUnresolved(left); | 11380 left = LoadFieldIfUnresolved(left); |
| 11339 const bool saved_mode = SetAllowFunctionLiterals(true); | 11381 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 11340 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); | 11382 AstNode* index = ParseExpr(kAllowConst, kConsumeCascades); |
| 11341 SetAllowFunctionLiterals(saved_mode); | 11383 SetAllowFunctionLiterals(saved_mode); |
| 11342 ExpectToken(Token::kRBRACK); | 11384 ExpectToken(Token::kRBRACK); |
| 11343 AstNode* array = left; | 11385 AstNode* array = left; |
| 11344 if (left->IsPrimaryNode()) { | 11386 if (left->IsPrimaryNode()) { |
| 11345 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11387 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 11346 const intptr_t primary_pos = primary_node->token_pos(); | 11388 const TokenDescriptor primary_pos = primary_node->token_pos(); |
| 11347 if (primary_node->primary().IsFunction()) { | 11389 if (primary_node->primary().IsFunction()) { |
| 11348 array = LoadClosure(primary_node); | 11390 array = LoadClosure(primary_node); |
| 11349 } else if (primary_node->primary().IsClass()) { | 11391 } else if (primary_node->primary().IsClass()) { |
| 11350 const Class& type_class = Class::Cast(primary_node->primary()); | 11392 const Class& type_class = Class::Cast(primary_node->primary()); |
| 11351 AbstractType& type = Type::ZoneHandle(Z, | 11393 AbstractType& type = Type::ZoneHandle(Z, |
| 11352 Type::New(type_class, TypeArguments::Handle(Z), | 11394 Type::New(type_class, TypeArguments::Handle(Z), |
| 11353 primary_pos, Heap::kOld)); | 11395 primary_pos, Heap::kOld)); |
| 11354 type ^= ClassFinalizer::FinalizeType( | 11396 type ^= ClassFinalizer::FinalizeType( |
| 11355 current_class(), type, ClassFinalizer::kCanonicalize); | 11397 current_class(), type, ClassFinalizer::kCanonicalize); |
| 11356 // Type may be malbounded, but not malformed. | 11398 // Type may be malbounded, but not malformed. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 11378 array = new(Z) TypeNode(primary_pos, type_parameter); | 11420 array = new(Z) TypeNode(primary_pos, type_parameter); |
| 11379 } else { | 11421 } else { |
| 11380 UNREACHABLE(); // Internal parser error. | 11422 UNREACHABLE(); // Internal parser error. |
| 11381 } | 11423 } |
| 11382 } | 11424 } |
| 11383 selector = new(Z) LoadIndexedNode( | 11425 selector = new(Z) LoadIndexedNode( |
| 11384 bracket_pos, array, index, Class::ZoneHandle(Z)); | 11426 bracket_pos, array, index, Class::ZoneHandle(Z)); |
| 11385 } else if (CurrentToken() == Token::kLPAREN) { | 11427 } else if (CurrentToken() == Token::kLPAREN) { |
| 11386 if (left->IsPrimaryNode()) { | 11428 if (left->IsPrimaryNode()) { |
| 11387 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11429 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 11388 const intptr_t primary_pos = primary_node->token_pos(); | 11430 const TokenDescriptor primary_pos = primary_node->token_pos(); |
| 11389 if (primary_node->primary().IsFunction()) { | 11431 if (primary_node->primary().IsFunction()) { |
| 11390 const Function& func = Function::Cast(primary_node->primary()); | 11432 const Function& func = Function::Cast(primary_node->primary()); |
| 11391 const String& func_name = String::ZoneHandle(Z, func.name()); | 11433 const String& func_name = String::ZoneHandle(Z, func.name()); |
| 11392 if (func.is_static()) { | 11434 if (func.is_static()) { |
| 11393 // Parse static function call. | 11435 // Parse static function call. |
| 11394 Class& cls = Class::Handle(Z, func.Owner()); | 11436 Class& cls = Class::Handle(Z, func.Owner()); |
| 11395 selector = ParseStaticCall(cls, func_name, primary_pos); | 11437 selector = ParseStaticCall(cls, func_name, primary_pos); |
| 11396 } else { | 11438 } else { |
| 11397 // Dynamic function call on implicit "this" parameter. | 11439 // Dynamic function call on implicit "this" parameter. |
| 11398 if (current_function().is_static()) { | 11440 if (current_function().is_static()) { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11454 } else { | 11496 } else { |
| 11455 // Left is not a primary node; this must be a closure call. | 11497 // Left is not a primary node; this must be a closure call. |
| 11456 AstNode* closure = left; | 11498 AstNode* closure = left; |
| 11457 selector = ParseClosureCall(closure); | 11499 selector = ParseClosureCall(closure); |
| 11458 } | 11500 } |
| 11459 } else { | 11501 } else { |
| 11460 // No (more) selectors to parse. | 11502 // No (more) selectors to parse. |
| 11461 left = LoadFieldIfUnresolved(left); | 11503 left = LoadFieldIfUnresolved(left); |
| 11462 if (left->IsPrimaryNode()) { | 11504 if (left->IsPrimaryNode()) { |
| 11463 PrimaryNode* primary_node = left->AsPrimaryNode(); | 11505 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 11464 const intptr_t primary_pos = primary->token_pos(); | 11506 const TokenDescriptor primary_pos = primary->token_pos(); |
| 11465 if (primary_node->primary().IsFunction()) { | 11507 if (primary_node->primary().IsFunction()) { |
| 11466 // Treat as implicit closure. | 11508 // Treat as implicit closure. |
| 11467 left = LoadClosure(primary_node); | 11509 left = LoadClosure(primary_node); |
| 11468 } else if (primary_node->primary().IsClass()) { | 11510 } else if (primary_node->primary().IsClass()) { |
| 11469 const Class& type_class = Class::Cast(primary_node->primary()); | 11511 const Class& type_class = Class::Cast(primary_node->primary()); |
| 11470 AbstractType& type = Type::ZoneHandle(Z, Type::New( | 11512 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
| 11471 type_class, TypeArguments::Handle(Z), primary_pos)); | 11513 type_class, TypeArguments::Handle(Z), primary_pos)); |
| 11472 type = ClassFinalizer::FinalizeType( | 11514 type = ClassFinalizer::FinalizeType( |
| 11473 current_class(), type, ClassFinalizer::kCanonicalize); | 11515 current_class(), type, ClassFinalizer::kCanonicalize); |
| 11474 // Type may be malbounded, but not malformed. | 11516 // Type may be malbounded, but not malformed. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11507 } | 11549 } |
| 11508 ASSERT(selector != NULL); | 11550 ASSERT(selector != NULL); |
| 11509 left = selector; | 11551 left = selector; |
| 11510 } | 11552 } |
| 11511 } | 11553 } |
| 11512 | 11554 |
| 11513 | 11555 |
| 11514 // Closurization e#m of getter, setter, method or operator. | 11556 // Closurization e#m of getter, setter, method or operator. |
| 11515 AstNode* Parser::ParseClosurization(AstNode* primary) { | 11557 AstNode* Parser::ParseClosurization(AstNode* primary) { |
| 11516 ExpectToken(Token::kHASH); | 11558 ExpectToken(Token::kHASH); |
| 11517 intptr_t property_pos = TokenPos(); | 11559 TokenDescriptor property_pos = TokenPos(); |
| 11518 bool is_setter_name = false; | 11560 bool is_setter_name = false; |
| 11519 | 11561 |
| 11520 String& extractor_name = String::ZoneHandle(Z); | 11562 String& extractor_name = String::ZoneHandle(Z); |
| 11521 if (IsIdentifier()) { | 11563 if (IsIdentifier()) { |
| 11522 extractor_name = CurrentLiteral()->raw(); | 11564 extractor_name = CurrentLiteral()->raw(); |
| 11523 ConsumeToken(); | 11565 ConsumeToken(); |
| 11524 if (CurrentToken() == Token::kASSIGN) { | 11566 if (CurrentToken() == Token::kASSIGN) { |
| 11525 ConsumeToken(); | 11567 ConsumeToken(); |
| 11526 is_setter_name = true; | 11568 is_setter_name = true; |
| 11527 } | 11569 } |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11648 pieces.Add(extractor_name); | 11690 pieces.Add(extractor_name); |
| 11649 extractor_name = Symbols::FromConcatAll(pieces); | 11691 extractor_name = Symbols::FromConcatAll(pieces); |
| 11650 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); | 11692 return new(Z) InstanceGetterNode(property_pos, primary, extractor_name); |
| 11651 } | 11693 } |
| 11652 | 11694 |
| 11653 | 11695 |
| 11654 AstNode* Parser::ParsePostfixExpr() { | 11696 AstNode* Parser::ParsePostfixExpr() { |
| 11655 TRACE_PARSER("ParsePostfixExpr"); | 11697 TRACE_PARSER("ParsePostfixExpr"); |
| 11656 String* expr_ident = | 11698 String* expr_ident = |
| 11657 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 11699 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 11658 const intptr_t expr_pos = TokenPos(); | 11700 const TokenDescriptor expr_pos = TokenPos(); |
| 11659 AstNode* expr = ParsePrimary(); | 11701 AstNode* expr = ParsePrimary(); |
| 11660 if (CurrentToken() == Token::kHASH) { | 11702 if (CurrentToken() == Token::kHASH) { |
| 11661 expr = LoadFieldIfUnresolved(expr); | 11703 expr = LoadFieldIfUnresolved(expr); |
| 11662 expr = ParseClosurization(expr); | 11704 expr = ParseClosurization(expr); |
| 11663 } else { | 11705 } else { |
| 11664 expr = ParseSelectors(expr, false); | 11706 expr = ParseSelectors(expr, false); |
| 11665 } | 11707 } |
| 11666 if (IsIncrementOperator(CurrentToken())) { | 11708 if (IsIncrementOperator(CurrentToken())) { |
| 11667 TRACE_PARSER("IncrementOperator"); | 11709 TRACE_PARSER("IncrementOperator"); |
| 11668 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 11710 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 11669 ReportError(expr_pos, "expression is not assignable"); | 11711 ReportError(expr_pos, "expression is not assignable"); |
| 11670 } | 11712 } |
| 11671 Token::Kind incr_op = CurrentToken(); | 11713 Token::Kind incr_op = CurrentToken(); |
| 11672 const intptr_t op_pos = TokenPos(); | 11714 const TokenDescriptor op_pos = TokenPos(); |
| 11673 ConsumeToken(); | 11715 ConsumeToken(); |
| 11674 // Not prefix. | 11716 // Not prefix. |
| 11675 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 11717 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 11676 LocalVariable* temp = let_expr->AddInitializer(expr); | 11718 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 11677 Token::Kind binary_op = | 11719 Token::Kind binary_op = |
| 11678 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 11720 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 11679 BinaryOpNode* add = new(Z) BinaryOpNode( | 11721 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 11680 op_pos, | 11722 op_pos, |
| 11681 binary_op, | 11723 binary_op, |
| 11682 new(Z) LoadLocalNode(op_pos, temp), | 11724 new(Z) LoadLocalNode(op_pos, temp), |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11795 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 11837 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
| 11796 if (current_block_ == NULL) { | 11838 if (current_block_ == NULL) { |
| 11797 return NULL; | 11839 return NULL; |
| 11798 } | 11840 } |
| 11799 // A found name is treated as accessed and possibly marked as captured. | 11841 // A found name is treated as accessed and possibly marked as captured. |
| 11800 const bool kTestOnly = false; | 11842 const bool kTestOnly = false; |
| 11801 return current_block_->scope->LookupVariable(ident, kTestOnly); | 11843 return current_block_->scope->LookupVariable(ident, kTestOnly); |
| 11802 } | 11844 } |
| 11803 | 11845 |
| 11804 | 11846 |
| 11805 void Parser::CheckInstanceFieldAccess(intptr_t field_pos, | 11847 void Parser::CheckInstanceFieldAccess(TokenDescriptor field_pos, |
| 11806 const String& field_name) { | 11848 const String& field_name) { |
| 11807 // Fields are not accessible from a static function, except from a | 11849 // Fields are not accessible from a static function, except from a |
| 11808 // constructor, which is considered as non-static by the compiler. | 11850 // constructor, which is considered as non-static by the compiler. |
| 11809 if (current_function().is_static()) { | 11851 if (current_function().is_static()) { |
| 11810 ReportError(field_pos, | 11852 ReportError(field_pos, |
| 11811 "cannot access instance field '%s' from a static function", | 11853 "cannot access instance field '%s' from a static function", |
| 11812 field_name.ToCString()); | 11854 field_name.ToCString()); |
| 11813 } | 11855 } |
| 11814 } | 11856 } |
| 11815 | 11857 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11858 // We cache computed compile-time constants in a map so we can look them | 11900 // We cache computed compile-time constants in a map so we can look them |
| 11859 // up when the same code gets compiled again. The map key is a pair | 11901 // up when the same code gets compiled again. The map key is a pair |
| 11860 // (script url, token position) which is encoded in an array with 2 | 11902 // (script url, token position) which is encoded in an array with 2 |
| 11861 // elements: | 11903 // elements: |
| 11862 // - key[0] contains the canonicalized url of the script. | 11904 // - key[0] contains the canonicalized url of the script. |
| 11863 // - key[1] contains the token position of the constant in the script. | 11905 // - key[1] contains the token position of the constant in the script. |
| 11864 | 11906 |
| 11865 // ConstantPosKey allows us to look up a constant in the map without | 11907 // ConstantPosKey allows us to look up a constant in the map without |
| 11866 // allocating a key pair (array). | 11908 // allocating a key pair (array). |
| 11867 struct ConstantPosKey : ValueObject { | 11909 struct ConstantPosKey : ValueObject { |
| 11868 ConstantPosKey(const String& url, intptr_t pos) | 11910 ConstantPosKey(const String& url, TokenDescriptor pos) |
| 11869 : script_url(url), token_pos(pos) { } | 11911 : script_url(url), token_pos(pos) { } |
| 11870 const String& script_url; | 11912 const String& script_url; |
| 11871 intptr_t token_pos; | 11913 TokenDescriptor token_pos; |
| 11872 }; | 11914 }; |
| 11873 | 11915 |
| 11874 | 11916 |
| 11875 class ConstMapKeyEqualsTraits { | 11917 class ConstMapKeyEqualsTraits { |
| 11876 public: | 11918 public: |
| 11877 static bool IsMatch(const Object& a, const Object& b) { | 11919 static bool IsMatch(const Object& a, const Object& b) { |
| 11878 const Array& key1 = Array::Cast(a); | 11920 const Array& key1 = Array::Cast(a); |
| 11879 const Array& key2 = Array::Cast(b); | 11921 const Array& key2 = Array::Cast(b); |
| 11880 // Compare raw strings of script url symbol and raw smi of token positon. | 11922 // Compare raw strings of script url symbol and raw smi of token positon. |
| 11881 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); | 11923 return (key1.At(0) == key2.At(0)) && (key1.At(1) == key2.At(1)); |
| 11882 } | 11924 } |
| 11883 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { | 11925 static bool IsMatch(const ConstantPosKey& key1, const Object& b) { |
| 11884 const Array& key2 = Array::Cast(b); | 11926 const Array& key2 = Array::Cast(b); |
| 11885 // Compare raw strings of script url symbol and token positon. | 11927 // Compare raw strings of script url symbol and token positon. |
| 11886 return (key1.script_url.raw() == key2.At(0)) | 11928 return (key1.script_url.raw() == key2.At(0)) |
| 11887 && (key1.token_pos == Smi::Value(Smi::RawCast(key2.At(1)))); | 11929 && (key1.token_pos.value() == Smi::Value(Smi::RawCast(key2.At(1)))); |
| 11888 } | 11930 } |
| 11889 static uword Hash(const Object& obj) { | 11931 static uword Hash(const Object& obj) { |
| 11890 const Array& key = Array::Cast(obj); | 11932 const Array& key = Array::Cast(obj); |
| 11891 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); | 11933 intptr_t url_hash = String::HashRawSymbol(String::RawCast(key.At(0))); |
| 11892 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); | 11934 intptr_t pos = Smi::Value(Smi::RawCast(key.At(1))); |
| 11893 return HashValue(url_hash, pos); | 11935 return HashValue(url_hash, pos); |
| 11894 } | 11936 } |
| 11895 static uword Hash(const ConstantPosKey& key) { | 11937 static uword Hash(const ConstantPosKey& key) { |
| 11896 return HashValue(String::HashRawSymbol(key.script_url.raw()), | 11938 return HashValue(String::HashRawSymbol(key.script_url.raw()), |
| 11897 key.token_pos); | 11939 key.token_pos.value()); |
| 11898 } | 11940 } |
| 11899 // Used by CachConstantValue if a new constant is added to the map. | 11941 // Used by CachConstantValue if a new constant is added to the map. |
| 11900 static RawObject* NewKey(const ConstantPosKey& key) { | 11942 static RawObject* NewKey(const ConstantPosKey& key) { |
| 11901 const Array& key_obj = Array::Handle(Array::New(2)); | 11943 const Array& key_obj = Array::Handle(Array::New(2)); |
| 11902 key_obj.SetAt(0, key.script_url); | 11944 key_obj.SetAt(0, key.script_url); |
| 11903 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos))); | 11945 key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value()))); |
| 11904 return key_obj.raw();; | 11946 return key_obj.raw();; |
| 11905 } | 11947 } |
| 11906 | 11948 |
| 11907 private: | 11949 private: |
| 11908 static uword HashValue(intptr_t url_hash, intptr_t pos) { | 11950 static uword HashValue(intptr_t url_hash, intptr_t pos) { |
| 11909 return url_hash * pos % (Smi::kMaxValue - 13); | 11951 return url_hash * pos % (Smi::kMaxValue - 13); |
| 11910 } | 11952 } |
| 11911 }; | 11953 }; |
| 11912 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; | 11954 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap; |
| 11913 | 11955 |
| 11914 | 11956 |
| 11915 void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) { | 11957 void Parser::CacheConstantValue(TokenDescriptor token_pos, |
| 11958 const Instance& value) { |
| 11916 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); | 11959 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
| 11917 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11960 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
| 11918 const intptr_t kInitialConstMapSize = 16; | 11961 const intptr_t kInitialConstMapSize = 16; |
| 11919 isolate()->object_store()->set_compile_time_constants( | 11962 isolate()->object_store()->set_compile_time_constants( |
| 11920 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, | 11963 Array::Handle(Z, HashTables::New<ConstantsMap>(kInitialConstMapSize, |
| 11921 Heap::kNew))); | 11964 Heap::kNew))); |
| 11922 } | 11965 } |
| 11923 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11966 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
| 11924 constants.InsertNewOrGetValue(key, value); | 11967 constants.InsertNewOrGetValue(key, value); |
| 11925 if (FLAG_compiler_stats) { | 11968 if (FLAG_compiler_stats) { |
| 11926 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); | 11969 isolate_->compiler_stats()->num_cached_consts = constants.NumOccupied(); |
| 11927 } | 11970 } |
| 11928 isolate()->object_store()->set_compile_time_constants(constants.Release()); | 11971 isolate()->object_store()->set_compile_time_constants(constants.Release()); |
| 11929 } | 11972 } |
| 11930 | 11973 |
| 11931 | 11974 |
| 11932 bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) { | 11975 bool Parser::GetCachedConstant(TokenDescriptor token_pos, Instance* value) { |
| 11933 if (isolate()->object_store()->compile_time_constants() == Array::null()) { | 11976 if (isolate()->object_store()->compile_time_constants() == Array::null()) { |
| 11934 return false; | 11977 return false; |
| 11935 } | 11978 } |
| 11936 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); | 11979 ConstantPosKey key(String::Handle(Z, script_.url()), token_pos); |
| 11937 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); | 11980 ConstantsMap constants(isolate()->object_store()->compile_time_constants()); |
| 11938 bool is_present = false; | 11981 bool is_present = false; |
| 11939 *value ^= constants.GetOrNull(key, &is_present); | 11982 *value ^= constants.GetOrNull(key, &is_present); |
| 11940 // Mutator compiler thread may add constants while background compiler | 11983 // Mutator compiler thread may add constants while background compiler |
| 11941 // is running , and thus change the value of 'compile_time_constants'; | 11984 // is running , and thus change the value of 'compile_time_constants'; |
| 11942 // do not assert that 'compile_time_constants' has not changed. | 11985 // do not assert that 'compile_time_constants' has not changed. |
| 11943 constants.Release(); | 11986 constants.Release(); |
| 11944 if (FLAG_compiler_stats && is_present) { | 11987 if (FLAG_compiler_stats && is_present) { |
| 11945 isolate_->compiler_stats()->num_const_cache_hits++; | 11988 isolate_->compiler_stats()->num_const_cache_hits++; |
| 11946 } | 11989 } |
| 11947 return is_present; | 11990 return is_present; |
| 11948 } | 11991 } |
| 11949 | 11992 |
| 11950 | 11993 |
| 11951 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 11994 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
| 11952 intptr_t token_pos) { | 11995 TokenDescriptor token_pos) { |
| 11953 if (instance.IsNull()) { | 11996 if (instance.IsNull()) { |
| 11954 return instance.raw(); | 11997 return instance.raw(); |
| 11955 } | 11998 } |
| 11956 const char* error_str = NULL; | 11999 const char* error_str = NULL; |
| 11957 Instance& result = | 12000 Instance& result = |
| 11958 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); | 12001 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); |
| 11959 if (result.IsNull()) { | 12002 if (result.IsNull()) { |
| 11960 ReportError(token_pos, "Invalid const object %s", error_str); | 12003 ReportError(token_pos, "Invalid const object %s", error_str); |
| 11961 } | 12004 } |
| 11962 return result.raw(); | 12005 return result.raw(); |
| 11963 } | 12006 } |
| 11964 | 12007 |
| 11965 | 12008 |
| 11966 // If the field is already initialized, return no ast (NULL). | 12009 // If the field is already initialized, return no ast (NULL). |
| 11967 // Otherwise, if the field is constant, initialize the field and return no ast. | 12010 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 11968 // If the field is not initialized and not const, return the ast for the getter. | 12011 // If the field is not initialized and not const, return the ast for the getter. |
| 11969 StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field, | 12012 StaticGetterNode* Parser::RunStaticFieldInitializer( |
| 11970 intptr_t field_ref_pos) { | 12013 const Field& field, TokenDescriptor field_ref_pos) { |
| 11971 ASSERT(field.is_static()); | 12014 ASSERT(field.is_static()); |
| 11972 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); | 12015 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); |
| 11973 const String& field_name = String::ZoneHandle(Z, field.name()); | 12016 const String& field_name = String::ZoneHandle(Z, field.name()); |
| 11974 const String& getter_name = | 12017 const String& getter_name = |
| 11975 String::Handle(Z, Field::GetterSymbol(field_name)); | 12018 String::Handle(Z, Field::GetterSymbol(field_name)); |
| 11976 const Function& getter = Function::Handle(Z, | 12019 const Function& getter = Function::Handle(Z, |
| 11977 field_owner.LookupStaticFunction(getter_name)); | 12020 field_owner.LookupStaticFunction(getter_name)); |
| 11978 const Instance& value = Instance::Handle(Z, field.StaticValue()); | 12021 const Instance& value = Instance::Handle(Z, field.StaticValue()); |
| 11979 if (value.raw() == Object::transition_sentinel().raw()) { | 12022 if (value.raw() == Object::transition_sentinel().raw()) { |
| 11980 if (field.is_const()) { | 12023 if (field.is_const()) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12097 instance ^= result.raw(); | 12140 instance ^= result.raw(); |
| 12098 } | 12141 } |
| 12099 return TryCanonicalize(instance, TokenPos()); | 12142 return TryCanonicalize(instance, TokenPos()); |
| 12100 } | 12143 } |
| 12101 } | 12144 } |
| 12102 | 12145 |
| 12103 | 12146 |
| 12104 // Do a lookup for the identifier in the block scope and the class scope | 12147 // Do a lookup for the identifier in the block scope and the class scope |
| 12105 // return true if the identifier is found, false otherwise. | 12148 // return true if the identifier is found, false otherwise. |
| 12106 // If node is non NULL return an AST node corresponding to the identifier. | 12149 // If node is non NULL return an AST node corresponding to the identifier. |
| 12107 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 12150 bool Parser::ResolveIdentInLocalScope(TokenDescriptor ident_pos, |
| 12108 const String &ident, | 12151 const String &ident, |
| 12109 AstNode** node) { | 12152 AstNode** node) { |
| 12110 TRACE_PARSER("ResolveIdentInLocalScope"); | 12153 TRACE_PARSER("ResolveIdentInLocalScope"); |
| 12111 // First try to find the identifier in the nested local scopes. | 12154 // First try to find the identifier in the nested local scopes. |
| 12112 LocalVariable* local = LookupLocalScope(ident); | 12155 LocalVariable* local = LookupLocalScope(ident); |
| 12113 if (current_block_ != NULL) { | 12156 if (current_block_ != NULL) { |
| 12114 current_block_->scope->AddReferencedName(ident_pos, ident); | 12157 current_block_->scope->AddReferencedName(ident_pos, ident); |
| 12115 } | 12158 } |
| 12116 if (local != NULL) { | 12159 if (local != NULL) { |
| 12117 if (node != NULL) { | 12160 if (node != NULL) { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12202 if (node != NULL) { | 12245 if (node != NULL) { |
| 12203 *node = NULL; | 12246 *node = NULL; |
| 12204 } | 12247 } |
| 12205 return false; | 12248 return false; |
| 12206 } | 12249 } |
| 12207 | 12250 |
| 12208 | 12251 |
| 12209 // Resolve an identifier by checking the global scope of the current | 12252 // Resolve an identifier by checking the global scope of the current |
| 12210 // library. If not found in the current library, then look in the scopes | 12253 // library. If not found in the current library, then look in the scopes |
| 12211 // of all libraries that are imported without a library prefix. | 12254 // of all libraries that are imported without a library prefix. |
| 12212 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 12255 AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenDescriptor ident_pos, |
| 12213 const String& ident) { | 12256 const String& ident) { |
| 12214 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 12257 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
| 12215 HANDLESCOPE(thread()); | 12258 HANDLESCOPE(thread()); |
| 12216 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); | 12259 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); |
| 12217 if (obj.IsClass()) { | 12260 if (obj.IsClass()) { |
| 12218 const Class& cls = Class::Cast(obj); | 12261 const Class& cls = Class::Cast(obj); |
| 12219 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); | 12262 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
| 12220 } else if (obj.IsField()) { | 12263 } else if (obj.IsField()) { |
| 12221 const Field& field = Field::Cast(obj); | 12264 const Field& field = Field::Cast(obj); |
| 12222 ASSERT(field.is_static()); | 12265 ASSERT(field.is_static()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 12248 ASSERT(obj.IsNull()); | 12291 ASSERT(obj.IsNull()); |
| 12249 } | 12292 } |
| 12250 // Lexically unresolved primary identifiers are referenced by their name. | 12293 // Lexically unresolved primary identifiers are referenced by their name. |
| 12251 return new(Z) PrimaryNode(ident_pos, ident); | 12294 return new(Z) PrimaryNode(ident_pos, ident); |
| 12252 } | 12295 } |
| 12253 | 12296 |
| 12254 | 12297 |
| 12255 // Do a lookup for the identifier in the scope of the specified | 12298 // Do a lookup for the identifier in the scope of the specified |
| 12256 // library prefix. This means trying to resolve it locally in all of the | 12299 // library prefix. This means trying to resolve it locally in all of the |
| 12257 // libraries present in the library prefix. | 12300 // libraries present in the library prefix. |
| 12258 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 12301 AstNode* Parser::ResolveIdentInPrefixScope(TokenDescriptor ident_pos, |
| 12259 const LibraryPrefix& prefix, | 12302 const LibraryPrefix& prefix, |
| 12260 const String& ident) { | 12303 const String& ident) { |
| 12261 TRACE_PARSER("ResolveIdentInPrefixScope"); | 12304 TRACE_PARSER("ResolveIdentInPrefixScope"); |
| 12262 HANDLESCOPE(thread()); | 12305 HANDLESCOPE(thread()); |
| 12263 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 12306 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
| 12264 // Private names are not exported by libraries. The name mangling | 12307 // Private names are not exported by libraries. The name mangling |
| 12265 // of private names with a library-specific suffix usually ensures | 12308 // of private names with a library-specific suffix usually ensures |
| 12266 // that _x in library A is not found when looked up from library B. | 12309 // that _x in library A is not found when looked up from library B. |
| 12267 // In the pathological case where a library imports itself with | 12310 // In the pathological case where a library imports itself with |
| 12268 // a prefix, the name mangling would not help in hiding the private | 12311 // a prefix, the name mangling would not help in hiding the private |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12327 UNREACHABLE(); | 12370 UNREACHABLE(); |
| 12328 return NULL; | 12371 return NULL; |
| 12329 } | 12372 } |
| 12330 | 12373 |
| 12331 | 12374 |
| 12332 // Resolve identifier. Issue an error message if | 12375 // Resolve identifier. Issue an error message if |
| 12333 // the ident refers to a method and allow_closure_names is false. | 12376 // the ident refers to a method and allow_closure_names is false. |
| 12334 // If the name cannot be resolved, turn it into an instance field access | 12377 // If the name cannot be resolved, turn it into an instance field access |
| 12335 // if we're compiling an instance method, or generate | 12378 // if we're compiling an instance method, or generate |
| 12336 // throw NoSuchMethodError if we're compiling a static method. | 12379 // throw NoSuchMethodError if we're compiling a static method. |
| 12337 AstNode* Parser::ResolveIdent(intptr_t ident_pos, | 12380 AstNode* Parser::ResolveIdent(TokenDescriptor ident_pos, |
| 12338 const String& ident, | 12381 const String& ident, |
| 12339 bool allow_closure_names) { | 12382 bool allow_closure_names) { |
| 12340 TRACE_PARSER("ResolveIdent"); | 12383 TRACE_PARSER("ResolveIdent"); |
| 12341 // First try to find the variable in the local scope (block scope or | 12384 // First try to find the variable in the local scope (block scope or |
| 12342 // class scope). | 12385 // class scope). |
| 12343 AstNode* resolved = NULL; | 12386 AstNode* resolved = NULL; |
| 12344 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 12387 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
| 12345 if (resolved == NULL) { | 12388 if (resolved == NULL) { |
| 12346 // Check whether the identifier is a type parameter. | 12389 // Check whether the identifier is a type parameter. |
| 12347 if (!current_class().IsNull()) { | 12390 if (!current_class().IsNull()) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 12358 return new(Z) TypeNode(ident_pos, type_parameter); | 12401 return new(Z) TypeNode(ident_pos, type_parameter); |
| 12359 } | 12402 } |
| 12360 } | 12403 } |
| 12361 // Not found in the local scope, and the name is not a type parameter. | 12404 // Not found in the local scope, and the name is not a type parameter. |
| 12362 // Try finding the variable in the library scope (current library | 12405 // Try finding the variable in the library scope (current library |
| 12363 // and all libraries imported by it without a library prefix). | 12406 // and all libraries imported by it without a library prefix). |
| 12364 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 12407 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
| 12365 } | 12408 } |
| 12366 if (resolved->IsPrimaryNode()) { | 12409 if (resolved->IsPrimaryNode()) { |
| 12367 PrimaryNode* primary = resolved->AsPrimaryNode(); | 12410 PrimaryNode* primary = resolved->AsPrimaryNode(); |
| 12368 const intptr_t primary_pos = primary->token_pos(); | 12411 const TokenDescriptor primary_pos = primary->token_pos(); |
| 12369 if (primary->primary().IsString()) { | 12412 if (primary->primary().IsString()) { |
| 12370 // We got an unresolved name. If we are compiling a static | 12413 // We got an unresolved name. If we are compiling a static |
| 12371 // method, evaluation of an unresolved identifier causes a | 12414 // method, evaluation of an unresolved identifier causes a |
| 12372 // NoSuchMethodError to be thrown. In an instance method, we convert | 12415 // NoSuchMethodError to be thrown. In an instance method, we convert |
| 12373 // the unresolved name to an instance field access, since a | 12416 // the unresolved name to an instance field access, since a |
| 12374 // subclass might define a field with this name. | 12417 // subclass might define a field with this name. |
| 12375 if (current_function().is_static()) { | 12418 if (current_function().is_static()) { |
| 12376 resolved = ThrowNoSuchMethodError(ident_pos, | 12419 resolved = ThrowNoSuchMethodError(ident_pos, |
| 12377 current_class(), | 12420 current_class(), |
| 12378 ident, | 12421 ident, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12417 | 12460 |
| 12418 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 12461 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
| 12419 // finalize it according to the given type finalization mode. Returns prefix. | 12462 // finalize it according to the given type finalization mode. Returns prefix. |
| 12420 RawAbstractType* Parser::ParseType( | 12463 RawAbstractType* Parser::ParseType( |
| 12421 ClassFinalizer::FinalizationKind finalization, | 12464 ClassFinalizer::FinalizationKind finalization, |
| 12422 bool allow_deferred_type, | 12465 bool allow_deferred_type, |
| 12423 bool consume_unresolved_prefix, | 12466 bool consume_unresolved_prefix, |
| 12424 LibraryPrefix* prefix) { | 12467 LibraryPrefix* prefix) { |
| 12425 TRACE_PARSER("ParseType"); | 12468 TRACE_PARSER("ParseType"); |
| 12426 CheckToken(Token::kIDENT, "type name expected"); | 12469 CheckToken(Token::kIDENT, "type name expected"); |
| 12427 intptr_t ident_pos = TokenPos(); | 12470 TokenDescriptor ident_pos = TokenPos(); |
| 12428 String& type_name = String::Handle(Z); | 12471 String& type_name = String::Handle(Z); |
| 12429 | 12472 |
| 12430 if (finalization == ClassFinalizer::kIgnore) { | 12473 if (finalization == ClassFinalizer::kIgnore) { |
| 12431 if (!is_top_level_ && (current_block_ != NULL)) { | 12474 if (!is_top_level_ && (current_block_ != NULL)) { |
| 12432 // Add the library prefix or type class name to the list of referenced | 12475 // Add the library prefix or type class name to the list of referenced |
| 12433 // names of this scope, even if the type is ignored. | 12476 // names of this scope, even if the type is ignored. |
| 12434 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 12477 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
| 12435 } | 12478 } |
| 12436 SkipQualIdent(); | 12479 SkipQualIdent(); |
| 12437 } else { | 12480 } else { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12530 ResolveTypeFromClass(current_class(), finalization, &type); | 12573 ResolveTypeFromClass(current_class(), finalization, &type); |
| 12531 if (finalization >= ClassFinalizer::kCanonicalize) { | 12574 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 12532 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 12575 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
| 12533 } | 12576 } |
| 12534 } | 12577 } |
| 12535 return type.raw(); | 12578 return type.raw(); |
| 12536 } | 12579 } |
| 12537 | 12580 |
| 12538 | 12581 |
| 12539 void Parser::CheckConstructorCallTypeArguments( | 12582 void Parser::CheckConstructorCallTypeArguments( |
| 12540 intptr_t pos, const Function& constructor, | 12583 TokenDescriptor pos, const Function& constructor, |
| 12541 const TypeArguments& type_arguments) { | 12584 const TypeArguments& type_arguments) { |
| 12542 if (!type_arguments.IsNull()) { | 12585 if (!type_arguments.IsNull()) { |
| 12543 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); | 12586 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); |
| 12544 ASSERT(!constructor_class.IsNull()); | 12587 ASSERT(!constructor_class.IsNull()); |
| 12545 ASSERT(constructor_class.is_finalized()); | 12588 ASSERT(constructor_class.is_finalized()); |
| 12546 ASSERT(type_arguments.IsCanonical()); | 12589 ASSERT(type_arguments.IsCanonical()); |
| 12547 // Do not report the expected vs. actual number of type arguments, because | 12590 // Do not report the expected vs. actual number of type arguments, because |
| 12548 // the type argument vector is flattened and raw types are allowed. | 12591 // the type argument vector is flattened and raw types are allowed. |
| 12549 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 12592 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
| 12550 ReportError(pos, "wrong number of type arguments passed to constructor"); | 12593 ReportError(pos, "wrong number of type arguments passed to constructor"); |
| 12551 } | 12594 } |
| 12552 } | 12595 } |
| 12553 } | 12596 } |
| 12554 | 12597 |
| 12555 | 12598 |
| 12556 // Parse "[" [ expr { "," expr } ["," ] "]". | 12599 // Parse "[" [ expr { "," expr } ["," ] "]". |
| 12557 // Note: if the list literal is empty and the brackets have no whitespace | 12600 // Note: if the list literal is empty and the brackets have no whitespace |
| 12558 // between them, the scanner recognizes the opening and closing bracket | 12601 // between them, the scanner recognizes the opening and closing bracket |
| 12559 // as one token of type Token::kINDEX. | 12602 // as one token of type Token::kINDEX. |
| 12560 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 12603 AstNode* Parser::ParseListLiteral(TokenDescriptor type_pos, |
| 12561 bool is_const, | 12604 bool is_const, |
| 12562 const TypeArguments& type_arguments) { | 12605 const TypeArguments& type_arguments) { |
| 12563 TRACE_PARSER("ParseListLiteral"); | 12606 TRACE_PARSER("ParseListLiteral"); |
| 12564 ASSERT(type_pos >= 0); | 12607 ASSERT(type_pos.IsReal()); |
| 12565 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 12608 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 12566 const intptr_t literal_pos = TokenPos(); | 12609 const TokenDescriptor literal_pos = TokenPos(); |
| 12567 | 12610 |
| 12568 if (is_const) { | 12611 if (is_const) { |
| 12569 Instance& existing_const = Instance::ZoneHandle(Z); | 12612 Instance& existing_const = Instance::ZoneHandle(Z); |
| 12570 if (GetCachedConstant(literal_pos, &existing_const)) { | 12613 if (GetCachedConstant(literal_pos, &existing_const)) { |
| 12571 SkipListLiteral(); | 12614 SkipListLiteral(); |
| 12572 return new(Z) LiteralNode(literal_pos, existing_const); | 12615 return new(Z) LiteralNode(literal_pos, existing_const); |
| 12573 } | 12616 } |
| 12574 } | 12617 } |
| 12575 | 12618 |
| 12576 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 12619 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12610 Type& type = Type::ZoneHandle(Z, | 12653 Type& type = Type::ZoneHandle(Z, |
| 12611 Type::New(array_class, list_type_arguments, type_pos)); | 12654 Type::New(array_class, list_type_arguments, type_pos)); |
| 12612 type ^= ClassFinalizer::FinalizeType( | 12655 type ^= ClassFinalizer::FinalizeType( |
| 12613 current_class(), type, ClassFinalizer::kCanonicalize); | 12656 current_class(), type, ClassFinalizer::kCanonicalize); |
| 12614 GrowableArray<AstNode*> element_list; | 12657 GrowableArray<AstNode*> element_list; |
| 12615 // Parse the list elements. Note: there may be an optional extra | 12658 // Parse the list elements. Note: there may be an optional extra |
| 12616 // comma after the last element. | 12659 // comma after the last element. |
| 12617 if (!is_empty_literal) { | 12660 if (!is_empty_literal) { |
| 12618 const bool saved_mode = SetAllowFunctionLiterals(true); | 12661 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 12619 while (CurrentToken() != Token::kRBRACK) { | 12662 while (CurrentToken() != Token::kRBRACK) { |
| 12620 const intptr_t element_pos = TokenPos(); | 12663 const TokenDescriptor element_pos = TokenPos(); |
| 12621 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 12664 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
| 12622 if (I->flags().type_checks() && | 12665 if (I->flags().type_checks() && |
| 12623 !is_const && | 12666 !is_const && |
| 12624 !element_type.IsDynamicType()) { | 12667 !element_type.IsDynamicType()) { |
| 12625 element = new(Z) AssignableNode(element_pos, | 12668 element = new(Z) AssignableNode(element_pos, |
| 12626 element, | 12669 element, |
| 12627 element_type, | 12670 element_type, |
| 12628 Symbols::ListLiteralElement()); | 12671 Symbols::ListLiteralElement()); |
| 12629 } | 12672 } |
| 12630 element_list.Add(element); | 12673 element_list.Add(element); |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12716 } | 12759 } |
| 12717 return CreateConstructorCallNode(literal_pos, | 12760 return CreateConstructorCallNode(literal_pos, |
| 12718 factory_type_args, | 12761 factory_type_args, |
| 12719 factory_method, | 12762 factory_method, |
| 12720 factory_param); | 12763 factory_param); |
| 12721 } | 12764 } |
| 12722 } | 12765 } |
| 12723 | 12766 |
| 12724 | 12767 |
| 12725 ConstructorCallNode* Parser::CreateConstructorCallNode( | 12768 ConstructorCallNode* Parser::CreateConstructorCallNode( |
| 12726 intptr_t token_pos, | 12769 TokenDescriptor token_pos, |
| 12727 const TypeArguments& type_arguments, | 12770 const TypeArguments& type_arguments, |
| 12728 const Function& constructor, | 12771 const Function& constructor, |
| 12729 ArgumentListNode* arguments) { | 12772 ArgumentListNode* arguments) { |
| 12730 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 12773 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
| 12731 EnsureExpressionTemp(); | 12774 EnsureExpressionTemp(); |
| 12732 } | 12775 } |
| 12733 return new(Z) ConstructorCallNode( | 12776 return new(Z) ConstructorCallNode( |
| 12734 token_pos, type_arguments, constructor, arguments); | 12777 token_pos, type_arguments, constructor, arguments); |
| 12735 } | 12778 } |
| 12736 | 12779 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 12753 (*pairs)[i + 1] = value; | 12796 (*pairs)[i + 1] = value; |
| 12754 return; | 12797 return; |
| 12755 } | 12798 } |
| 12756 } | 12799 } |
| 12757 } | 12800 } |
| 12758 pairs->Add(key); | 12801 pairs->Add(key); |
| 12759 pairs->Add(value); | 12802 pairs->Add(value); |
| 12760 } | 12803 } |
| 12761 | 12804 |
| 12762 | 12805 |
| 12763 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 12806 AstNode* Parser::ParseMapLiteral(TokenDescriptor type_pos, |
| 12764 bool is_const, | 12807 bool is_const, |
| 12765 const TypeArguments& type_arguments) { | 12808 const TypeArguments& type_arguments) { |
| 12766 TRACE_PARSER("ParseMapLiteral"); | 12809 TRACE_PARSER("ParseMapLiteral"); |
| 12767 ASSERT(type_pos >= 0); | 12810 ASSERT(type_pos.IsReal()); |
| 12768 ASSERT(CurrentToken() == Token::kLBRACE); | 12811 ASSERT(CurrentToken() == Token::kLBRACE); |
| 12769 const intptr_t literal_pos = TokenPos(); | 12812 const TokenDescriptor literal_pos = TokenPos(); |
| 12770 | 12813 |
| 12771 if (is_const) { | 12814 if (is_const) { |
| 12772 Instance& existing_const = Instance::ZoneHandle(Z); | 12815 Instance& existing_const = Instance::ZoneHandle(Z); |
| 12773 if (GetCachedConstant(literal_pos, &existing_const)) { | 12816 if (GetCachedConstant(literal_pos, &existing_const)) { |
| 12774 SkipMapLiteral(); | 12817 SkipMapLiteral(); |
| 12775 return new(Z) LiteralNode(literal_pos, existing_const); | 12818 return new(Z) LiteralNode(literal_pos, existing_const); |
| 12776 } | 12819 } |
| 12777 } | 12820 } |
| 12778 | 12821 |
| 12779 ConsumeToken(); // Opening brace. | 12822 ConsumeToken(); // Opening brace. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12812 } | 12855 } |
| 12813 } | 12856 } |
| 12814 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); | 12857 ASSERT(map_type_arguments.IsNull() || (map_type_arguments.Length() == 2)); |
| 12815 map_type_arguments ^= map_type_arguments.Canonicalize(); | 12858 map_type_arguments ^= map_type_arguments.Canonicalize(); |
| 12816 | 12859 |
| 12817 GrowableArray<AstNode*> kv_pairs_list; | 12860 GrowableArray<AstNode*> kv_pairs_list; |
| 12818 // Parse the map entries. Note: there may be an optional extra | 12861 // Parse the map entries. Note: there may be an optional extra |
| 12819 // comma after the last entry. | 12862 // comma after the last entry. |
| 12820 while (CurrentToken() != Token::kRBRACE) { | 12863 while (CurrentToken() != Token::kRBRACE) { |
| 12821 const bool saved_mode = SetAllowFunctionLiterals(true); | 12864 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 12822 const intptr_t key_pos = TokenPos(); | 12865 const TokenDescriptor key_pos = TokenPos(); |
| 12823 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 12866 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
| 12824 if (I->flags().type_checks() && | 12867 if (I->flags().type_checks() && |
| 12825 !is_const && | 12868 !is_const && |
| 12826 !key_type.IsDynamicType()) { | 12869 !key_type.IsDynamicType()) { |
| 12827 key = new(Z) AssignableNode( | 12870 key = new(Z) AssignableNode( |
| 12828 key_pos, key, key_type, Symbols::ListLiteralElement()); | 12871 key_pos, key, key_type, Symbols::ListLiteralElement()); |
| 12829 } | 12872 } |
| 12830 if (is_const) { | 12873 if (is_const) { |
| 12831 ASSERT(key->IsLiteralNode()); | 12874 ASSERT(key->IsLiteralNode()); |
| 12832 const Instance& key_value = key->AsLiteralNode()->literal(); | 12875 const Instance& key_value = key->AsLiteralNode()->literal(); |
| 12833 if (key_value.IsDouble()) { | 12876 if (key_value.IsDouble()) { |
| 12834 ReportError(key_pos, "key value must not be of type double"); | 12877 ReportError(key_pos, "key value must not be of type double"); |
| 12835 } | 12878 } |
| 12836 if (!key_value.IsInteger() && | 12879 if (!key_value.IsInteger() && |
| 12837 !key_value.IsString() && | 12880 !key_value.IsString() && |
| 12838 (key_value.clazz() != I->object_store()->symbol_class()) && | 12881 (key_value.clazz() != I->object_store()->symbol_class()) && |
| 12839 ImplementsEqualOperator(key_value)) { | 12882 ImplementsEqualOperator(key_value)) { |
| 12840 ReportError(key_pos, "key value must not implement operator =="); | 12883 ReportError(key_pos, "key value must not implement operator =="); |
| 12841 } | 12884 } |
| 12842 } | 12885 } |
| 12843 ExpectToken(Token::kCOLON); | 12886 ExpectToken(Token::kCOLON); |
| 12844 const intptr_t value_pos = TokenPos(); | 12887 const TokenDescriptor value_pos = TokenPos(); |
| 12845 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 12888 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
| 12846 SetAllowFunctionLiterals(saved_mode); | 12889 SetAllowFunctionLiterals(saved_mode); |
| 12847 if (I->flags().type_checks() && | 12890 if (I->flags().type_checks() && |
| 12848 !is_const && | 12891 !is_const && |
| 12849 !value_type.IsDynamicType()) { | 12892 !value_type.IsDynamicType()) { |
| 12850 value = new(Z) AssignableNode( | 12893 value = new(Z) AssignableNode( |
| 12851 value_pos, value, value_type, Symbols::ListLiteralElement()); | 12894 value_pos, value, value_type, Symbols::ListLiteralElement()); |
| 12852 } | 12895 } |
| 12853 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 12896 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
| 12854 | 12897 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12984 } | 13027 } |
| 12985 | 13028 |
| 12986 | 13029 |
| 12987 AstNode* Parser::ParseCompoundLiteral() { | 13030 AstNode* Parser::ParseCompoundLiteral() { |
| 12988 TRACE_PARSER("ParseCompoundLiteral"); | 13031 TRACE_PARSER("ParseCompoundLiteral"); |
| 12989 bool is_const = false; | 13032 bool is_const = false; |
| 12990 if (CurrentToken() == Token::kCONST) { | 13033 if (CurrentToken() == Token::kCONST) { |
| 12991 is_const = true; | 13034 is_const = true; |
| 12992 ConsumeToken(); | 13035 ConsumeToken(); |
| 12993 } | 13036 } |
| 12994 const intptr_t type_pos = TokenPos(); | 13037 const TokenDescriptor type_pos = TokenPos(); |
| 12995 TypeArguments& type_arguments = TypeArguments::Handle(Z, | 13038 TypeArguments& type_arguments = TypeArguments::Handle(Z, |
| 12996 ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 13039 ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
| 12997 // Malformed type arguments are mapped to dynamic, so we will not encounter | 13040 // Malformed type arguments are mapped to dynamic, so we will not encounter |
| 12998 // them here. | 13041 // them here. |
| 12999 // Map and List interfaces do not declare bounds on their type parameters, so | 13042 // Map and List interfaces do not declare bounds on their type parameters, so |
| 13000 // we will not see malbounded type arguments here. | 13043 // we will not see malbounded type arguments here. |
| 13001 AstNode* primary = NULL; | 13044 AstNode* primary = NULL; |
| 13002 if ((CurrentToken() == Token::kLBRACK) || | 13045 if ((CurrentToken() == Token::kLBRACK) || |
| 13003 (CurrentToken() == Token::kINDEX)) { | 13046 (CurrentToken() == Token::kINDEX)) { |
| 13004 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 13047 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 13005 } else if (CurrentToken() == Token::kLBRACE) { | 13048 } else if (CurrentToken() == Token::kLBRACE) { |
| 13006 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 13049 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 13007 } else { | 13050 } else { |
| 13008 UnexpectedToken(); | 13051 UnexpectedToken(); |
| 13009 } | 13052 } |
| 13010 return primary; | 13053 return primary; |
| 13011 } | 13054 } |
| 13012 | 13055 |
| 13013 | 13056 |
| 13014 AstNode* Parser::ParseSymbolLiteral() { | 13057 AstNode* Parser::ParseSymbolLiteral() { |
| 13015 ASSERT(CurrentToken() == Token::kHASH); | 13058 ASSERT(CurrentToken() == Token::kHASH); |
| 13016 ConsumeToken(); | 13059 ConsumeToken(); |
| 13017 intptr_t symbol_pos = TokenPos(); | 13060 TokenDescriptor symbol_pos = TokenPos(); |
| 13018 String& symbol = String::ZoneHandle(Z); | 13061 String& symbol = String::ZoneHandle(Z); |
| 13019 if (IsIdentifier()) { | 13062 if (IsIdentifier()) { |
| 13020 symbol = CurrentLiteral()->raw(); | 13063 symbol = CurrentLiteral()->raw(); |
| 13021 ConsumeToken(); | 13064 ConsumeToken(); |
| 13022 GrowableHandlePtrArray<const String> pieces(Z, 3); | 13065 GrowableHandlePtrArray<const String> pieces(Z, 3); |
| 13023 pieces.Add(symbol); | 13066 pieces.Add(symbol); |
| 13024 while (CurrentToken() == Token::kPERIOD) { | 13067 while (CurrentToken() == Token::kPERIOD) { |
| 13025 pieces.Add(Symbols::Dot()); | 13068 pieces.Add(Symbols::Dot()); |
| 13026 ConsumeToken(); | 13069 ConsumeToken(); |
| 13027 pieces.Add(*ExpectIdentifier("identifier expected")); | 13070 pieces.Add(*ExpectIdentifier("identifier expected")); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 13057 ReportErrors(Error::Cast(result), | 13100 ReportErrors(Error::Cast(result), |
| 13058 script_, symbol_pos, | 13101 script_, symbol_pos, |
| 13059 "error executing const Symbol constructor"); | 13102 "error executing const Symbol constructor"); |
| 13060 } | 13103 } |
| 13061 symbol_instance ^= result.raw(); | 13104 symbol_instance ^= result.raw(); |
| 13062 CacheConstantValue(symbol_pos, symbol_instance); | 13105 CacheConstantValue(symbol_pos, symbol_instance); |
| 13063 return new(Z) LiteralNode(symbol_pos, symbol_instance); | 13106 return new(Z) LiteralNode(symbol_pos, symbol_instance); |
| 13064 } | 13107 } |
| 13065 | 13108 |
| 13066 | 13109 |
| 13067 RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr, | 13110 RawFunction* Parser::BuildConstructorClosureFunction( |
| 13068 intptr_t token_pos) { | 13111 const Function& ctr, TokenDescriptor token_pos) { |
| 13069 ASSERT(ctr.kind() == RawFunction::kConstructor); | 13112 ASSERT(ctr.kind() == RawFunction::kConstructor); |
| 13070 Function& closure = Function::Handle(Z); | 13113 Function& closure = Function::Handle(Z); |
| 13071 closure = I->LookupClosureFunction(innermost_function(), token_pos); | 13114 closure = I->LookupClosureFunction(innermost_function(), token_pos); |
| 13072 if (!closure.IsNull()) { | 13115 if (!closure.IsNull()) { |
| 13073 ASSERT(closure.IsConstructorClosureFunction()); | 13116 ASSERT(closure.IsConstructorClosureFunction()); |
| 13074 return closure.raw(); | 13117 return closure.raw(); |
| 13075 } | 13118 } |
| 13076 | 13119 |
| 13077 String& closure_name = String::Handle(Z, ctr.name()); | 13120 String& closure_name = String::Handle(Z, ctr.name()); |
| 13078 closure_name = Symbols::FromConcat(Symbols::ConstructorClosurePrefix(), | 13121 closure_name = Symbols::FromConcat(Symbols::ConstructorClosurePrefix(), |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13175 } | 13218 } |
| 13176 *type_arguments = type.arguments(); | 13219 *type_arguments = type.arguments(); |
| 13177 *constructor = constructor->RedirectionTarget(); | 13220 *constructor = constructor->RedirectionTarget(); |
| 13178 } | 13221 } |
| 13179 } | 13222 } |
| 13180 } | 13223 } |
| 13181 | 13224 |
| 13182 | 13225 |
| 13183 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { | 13226 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) { |
| 13184 TRACE_PARSER("ParseNewOperator"); | 13227 TRACE_PARSER("ParseNewOperator"); |
| 13185 const intptr_t new_pos = TokenPos(); | 13228 const TokenDescriptor new_pos = TokenPos(); |
| 13186 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 13229 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
| 13187 bool is_const = (op_kind == Token::kCONST); | 13230 bool is_const = (op_kind == Token::kCONST); |
| 13188 if (!IsIdentifier()) { | 13231 if (!IsIdentifier()) { |
| 13189 ReportError("type name expected"); | 13232 ReportError("type name expected"); |
| 13190 } | 13233 } |
| 13191 intptr_t type_pos = TokenPos(); | 13234 TokenDescriptor type_pos = TokenPos(); |
| 13192 // Can't allocate const objects of a deferred type. | 13235 // Can't allocate const objects of a deferred type. |
| 13193 const bool allow_deferred_type = !is_const; | 13236 const bool allow_deferred_type = !is_const; |
| 13194 const Token::Kind la3 = LookaheadToken(3); | 13237 const Token::Kind la3 = LookaheadToken(3); |
| 13195 const bool consume_unresolved_prefix = | 13238 const bool consume_unresolved_prefix = |
| 13196 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); | 13239 (la3 == Token::kLT) || (la3 == Token::kPERIOD) || (la3 == Token::kHASH); |
| 13197 | 13240 |
| 13198 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); | 13241 LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z); |
| 13199 AbstractType& type = AbstractType::Handle(Z, | 13242 AbstractType& type = AbstractType::Handle(Z, |
| 13200 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 13243 ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
| 13201 allow_deferred_type, | 13244 allow_deferred_type, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13252 ConsumeToken(); | 13295 ConsumeToken(); |
| 13253 if (IsIdentifier()) { | 13296 if (IsIdentifier()) { |
| 13254 named_constructor = ExpectIdentifier("name of constructor expected"); | 13297 named_constructor = ExpectIdentifier("name of constructor expected"); |
| 13255 } | 13298 } |
| 13256 } else if (CurrentToken() == Token::kPERIOD) { | 13299 } else if (CurrentToken() == Token::kPERIOD) { |
| 13257 ConsumeToken(); | 13300 ConsumeToken(); |
| 13258 named_constructor = ExpectIdentifier("name of constructor expected"); | 13301 named_constructor = ExpectIdentifier("name of constructor expected"); |
| 13259 } | 13302 } |
| 13260 | 13303 |
| 13261 // Parse constructor parameters. | 13304 // Parse constructor parameters. |
| 13262 intptr_t call_pos = TokenPos(); | 13305 TokenDescriptor call_pos = TokenPos(); |
| 13263 ArgumentListNode* arguments = NULL; | 13306 ArgumentListNode* arguments = NULL; |
| 13264 if (!is_tearoff_expression) { | 13307 if (!is_tearoff_expression) { |
| 13265 CheckToken(Token::kLPAREN); | 13308 CheckToken(Token::kLPAREN); |
| 13266 call_pos = TokenPos(); | 13309 call_pos = TokenPos(); |
| 13267 arguments = ParseActualParameters(NULL, is_const); | 13310 arguments = ParseActualParameters(NULL, is_const); |
| 13268 } else { | 13311 } else { |
| 13269 // Allocate dummy node with no arguments so we don't have to deal | 13312 // Allocate dummy node with no arguments so we don't have to deal |
| 13270 // with the NULL corner case below. | 13313 // with the NULL corner case below. |
| 13271 arguments = new(Z) ArgumentListNode(TokenPos()); | 13314 arguments = new(Z) ArgumentListNode(TokenPos()); |
| 13272 } | 13315 } |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13392 // It is ok to call a factory method of an abstract class, but it is | 13435 // It is ok to call a factory method of an abstract class, but it is |
| 13393 // a dynamic error to instantiate an abstract class. | 13436 // a dynamic error to instantiate an abstract class. |
| 13394 if (type_class.is_abstract() && !constructor.IsFactory()) { | 13437 if (type_class.is_abstract() && !constructor.IsFactory()) { |
| 13395 // Evaluate arguments before throwing. | 13438 // Evaluate arguments before throwing. |
| 13396 LetNode* result = new(Z) LetNode(call_pos); | 13439 LetNode* result = new(Z) LetNode(call_pos); |
| 13397 for (intptr_t i = 0; i < arguments->length(); ++i) { | 13440 for (intptr_t i = 0; i < arguments->length(); ++i) { |
| 13398 result->AddNode(arguments->NodeAt(i)); | 13441 result->AddNode(arguments->NodeAt(i)); |
| 13399 } | 13442 } |
| 13400 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); | 13443 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); |
| 13401 error_arguments->Add(new(Z) LiteralNode( | 13444 error_arguments->Add(new(Z) LiteralNode( |
| 13402 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos)))); | 13445 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos.value())))); |
| 13403 error_arguments->Add(new(Z) LiteralNode( | 13446 error_arguments->Add(new(Z) LiteralNode( |
| 13404 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); | 13447 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); |
| 13405 result->AddNode( | 13448 result->AddNode( |
| 13406 MakeStaticCall(Symbols::AbstractClassInstantiationError(), | 13449 MakeStaticCall(Symbols::AbstractClassInstantiationError(), |
| 13407 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 13450 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 13408 error_arguments)); | 13451 error_arguments)); |
| 13409 return result; | 13452 return result; |
| 13410 } | 13453 } |
| 13411 | 13454 |
| 13412 type_arguments ^= type_arguments.Canonicalize(); | 13455 type_arguments ^= type_arguments.Canonicalize(); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13570 | 13613 |
| 13571 // A string literal consists of the concatenation of the next n tokens | 13614 // A string literal consists of the concatenation of the next n tokens |
| 13572 // that satisfy the EBNF grammar: | 13615 // that satisfy the EBNF grammar: |
| 13573 // literal = kSTRING {{ interpol } kSTRING } | 13616 // literal = kSTRING {{ interpol } kSTRING } |
| 13574 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 13617 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 13575 // In other words, the scanner breaks down interpolated strings so that | 13618 // In other words, the scanner breaks down interpolated strings so that |
| 13576 // a string literal always begins and ends with a kSTRING token. | 13619 // a string literal always begins and ends with a kSTRING token. |
| 13577 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 13620 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
| 13578 TRACE_PARSER("ParseStringLiteral"); | 13621 TRACE_PARSER("ParseStringLiteral"); |
| 13579 AstNode* primary = NULL; | 13622 AstNode* primary = NULL; |
| 13580 const intptr_t literal_start = TokenPos(); | 13623 const TokenDescriptor literal_start = TokenPos(); |
| 13581 ASSERT(CurrentToken() == Token::kSTRING); | 13624 ASSERT(CurrentToken() == Token::kSTRING); |
| 13582 Token::Kind l1_token = LookaheadToken(1); | 13625 Token::Kind l1_token = LookaheadToken(1); |
| 13583 if ((l1_token != Token::kSTRING) && | 13626 if ((l1_token != Token::kSTRING) && |
| 13584 (l1_token != Token::kINTERPOL_VAR) && | 13627 (l1_token != Token::kINTERPOL_VAR) && |
| 13585 (l1_token != Token::kINTERPOL_START)) { | 13628 (l1_token != Token::kINTERPOL_START)) { |
| 13586 // Common case: no interpolation. | 13629 // Common case: no interpolation. |
| 13587 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); | 13630 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); |
| 13588 ConsumeToken(); | 13631 ConsumeToken(); |
| 13589 return primary; | 13632 return primary; |
| 13590 } | 13633 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 13609 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); | 13652 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); |
| 13610 } | 13653 } |
| 13611 ConsumeToken(); | 13654 ConsumeToken(); |
| 13612 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 13655 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 13613 (CurrentToken() == Token::kINTERPOL_START)) { | 13656 (CurrentToken() == Token::kINTERPOL_START)) { |
| 13614 if (!allow_interpolation) { | 13657 if (!allow_interpolation) { |
| 13615 ReportError("string interpolation not allowed in this context"); | 13658 ReportError("string interpolation not allowed in this context"); |
| 13616 } | 13659 } |
| 13617 has_interpolation = true; | 13660 has_interpolation = true; |
| 13618 AstNode* expr = NULL; | 13661 AstNode* expr = NULL; |
| 13619 const intptr_t expr_pos = TokenPos(); | 13662 const TokenDescriptor expr_pos = TokenPos(); |
| 13620 if (CurrentToken() == Token::kINTERPOL_VAR) { | 13663 if (CurrentToken() == Token::kINTERPOL_VAR) { |
| 13621 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); | 13664 expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true); |
| 13622 ConsumeToken(); | 13665 ConsumeToken(); |
| 13623 } else { | 13666 } else { |
| 13624 ASSERT(CurrentToken() == Token::kINTERPOL_START); | 13667 ASSERT(CurrentToken() == Token::kINTERPOL_START); |
| 13625 ConsumeToken(); | 13668 ConsumeToken(); |
| 13626 const bool saved_mode = SetAllowFunctionLiterals(true); | 13669 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 13627 expr = ParseExpr(kAllowConst, kConsumeCascades); | 13670 expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 13628 SetAllowFunctionLiterals(saved_mode); | 13671 SetAllowFunctionLiterals(saved_mode); |
| 13629 ExpectToken(Token::kINTERPOL_END); | 13672 ExpectToken(Token::kINTERPOL_END); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13682 ASSERT(!is_top_level_); | 13725 ASSERT(!is_top_level_); |
| 13683 AstNode* primary = NULL; | 13726 AstNode* primary = NULL; |
| 13684 const Token::Kind token = CurrentToken(); | 13727 const Token::Kind token = CurrentToken(); |
| 13685 if (IsFunctionLiteral()) { | 13728 if (IsFunctionLiteral()) { |
| 13686 // The name of a literal function is visible from inside the function, but | 13729 // The name of a literal function is visible from inside the function, but |
| 13687 // must not collide with names in the scope declaring the literal. | 13730 // must not collide with names in the scope declaring the literal. |
| 13688 OpenBlock(); | 13731 OpenBlock(); |
| 13689 primary = ParseFunctionStatement(true); | 13732 primary = ParseFunctionStatement(true); |
| 13690 CloseBlock(); | 13733 CloseBlock(); |
| 13691 } else if (IsIdentifier()) { | 13734 } else if (IsIdentifier()) { |
| 13692 intptr_t qual_ident_pos = TokenPos(); | 13735 TokenDescriptor qual_ident_pos = TokenPos(); |
| 13693 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); | 13736 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
| 13694 if (!prefix.IsNull()) { | 13737 if (!prefix.IsNull()) { |
| 13695 if (CurrentToken() == Token::kHASH) { | 13738 if (CurrentToken() == Token::kHASH) { |
| 13696 // Closurization of top-level entity in prefix scope. | 13739 // Closurization of top-level entity in prefix scope. |
| 13697 return new(Z) LiteralNode(qual_ident_pos, prefix); | 13740 return new(Z) LiteralNode(qual_ident_pos, prefix); |
| 13698 } else { | 13741 } else { |
| 13699 ExpectToken(Token::kPERIOD); | 13742 ExpectToken(Token::kPERIOD); |
| 13700 } | 13743 } |
| 13701 } | 13744 } |
| 13702 String& ident = *CurrentLiteral(); | 13745 String& ident = *CurrentLiteral(); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13841 } else if (token == Token::kHASH) { | 13884 } else if (token == Token::kHASH) { |
| 13842 primary = ParseSymbolLiteral(); | 13885 primary = ParseSymbolLiteral(); |
| 13843 } else if (token == Token::kSUPER) { | 13886 } else if (token == Token::kSUPER) { |
| 13844 if (current_function().is_static()) { | 13887 if (current_function().is_static()) { |
| 13845 ReportError("cannot access superclass from static method"); | 13888 ReportError("cannot access superclass from static method"); |
| 13846 } | 13889 } |
| 13847 if (current_class().SuperClass() == Class::null()) { | 13890 if (current_class().SuperClass() == Class::null()) { |
| 13848 ReportError("class '%s' does not have a superclass", | 13891 ReportError("class '%s' does not have a superclass", |
| 13849 String::Handle(Z, current_class().Name()).ToCString()); | 13892 String::Handle(Z, current_class().Name()).ToCString()); |
| 13850 } | 13893 } |
| 13851 const intptr_t super_pos = TokenPos(); | 13894 const TokenDescriptor super_pos = TokenPos(); |
| 13852 ConsumeToken(); | 13895 ConsumeToken(); |
| 13853 if (CurrentToken() == Token::kPERIOD) { | 13896 if (CurrentToken() == Token::kPERIOD) { |
| 13854 ConsumeToken(); | 13897 ConsumeToken(); |
| 13855 const intptr_t ident_pos = TokenPos(); | 13898 const TokenDescriptor ident_pos = TokenPos(); |
| 13856 const String& ident = *ExpectIdentifier("identifier expected"); | 13899 const String& ident = *ExpectIdentifier("identifier expected"); |
| 13857 if (CurrentToken() == Token::kLPAREN) { | 13900 if (CurrentToken() == Token::kLPAREN) { |
| 13858 primary = ParseSuperCall(ident); | 13901 primary = ParseSuperCall(ident); |
| 13859 } else { | 13902 } else { |
| 13860 primary = ParseSuperFieldAccess(ident, ident_pos); | 13903 primary = ParseSuperFieldAccess(ident, ident_pos); |
| 13861 } | 13904 } |
| 13862 } else if ((CurrentToken() == Token::kLBRACK) || | 13905 } else if ((CurrentToken() == Token::kLBRACK) || |
| 13863 Token::CanBeOverloaded(CurrentToken()) || | 13906 Token::CanBeOverloaded(CurrentToken()) || |
| 13864 (CurrentToken() == Token::kNE)) { | 13907 (CurrentToken() == Token::kNE)) { |
| 13865 primary = ParseSuperOperator(); | 13908 primary = ParseSuperOperator(); |
| 13866 } else if (CurrentToken() == Token::kQM_PERIOD) { | 13909 } else if (CurrentToken() == Token::kQM_PERIOD) { |
| 13867 ReportError("super call or super getter may not use ?."); | 13910 ReportError("super call or super getter may not use ?."); |
| 13868 } else { | 13911 } else { |
| 13869 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); | 13912 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); |
| 13870 } | 13913 } |
| 13871 } else { | 13914 } else { |
| 13872 UnexpectedToken(); | 13915 UnexpectedToken(); |
| 13873 } | 13916 } |
| 13874 return primary; | 13917 return primary; |
| 13875 } | 13918 } |
| 13876 | 13919 |
| 13877 | 13920 |
| 13878 // Evaluate expression in expr and return the value. The expression must | 13921 // Evaluate expression in expr and return the value. The expression must |
| 13879 // be a compile time constant. | 13922 // be a compile time constant. |
| 13880 const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) { | 13923 const Instance& Parser::EvaluateConstExpr(TokenDescriptor expr_pos, |
| 13924 AstNode* expr) { |
| 13881 if (expr->IsLiteralNode()) { | 13925 if (expr->IsLiteralNode()) { |
| 13882 return expr->AsLiteralNode()->literal(); | 13926 return expr->AsLiteralNode()->literal(); |
| 13883 } else if (expr->IsLoadLocalNode() && | 13927 } else if (expr->IsLoadLocalNode() && |
| 13884 expr->AsLoadLocalNode()->local().IsConst()) { | 13928 expr->AsLoadLocalNode()->local().IsConst()) { |
| 13885 return *expr->AsLoadLocalNode()->local().ConstValue(); | 13929 return *expr->AsLoadLocalNode()->local().ConstValue(); |
| 13886 } else if (expr->IsLoadStaticFieldNode()) { | 13930 } else if (expr->IsLoadStaticFieldNode()) { |
| 13887 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 13931 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
| 13888 // We already checked that this field is const and has been | 13932 // We already checked that this field is const and has been |
| 13889 // initialized. | 13933 // initialized. |
| 13890 ASSERT(field.is_const()); | 13934 ASSERT(field.is_const()); |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 14342 } | 14386 } |
| 14343 | 14387 |
| 14344 | 14388 |
| 14345 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 14389 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
| 14346 UNREACHABLE(); | 14390 UNREACHABLE(); |
| 14347 return NULL; | 14391 return NULL; |
| 14348 } | 14392 } |
| 14349 | 14393 |
| 14350 | 14394 |
| 14351 ArgumentListNode* Parser::BuildNoSuchMethodArguments( | 14395 ArgumentListNode* Parser::BuildNoSuchMethodArguments( |
| 14352 intptr_t call_pos, | 14396 TokenDescriptor call_pos, |
| 14353 const String& function_name, | 14397 const String& function_name, |
| 14354 const ArgumentListNode& function_args, | 14398 const ArgumentListNode& function_args, |
| 14355 const LocalVariable* temp_for_last_arg, | 14399 const LocalVariable* temp_for_last_arg, |
| 14356 bool is_super_invocation) { | 14400 bool is_super_invocation) { |
| 14357 UNREACHABLE(); | 14401 UNREACHABLE(); |
| 14358 return NULL; | 14402 return NULL; |
| 14359 } | 14403 } |
| 14360 | 14404 |
| 14361 } // namespace dart | 14405 } // namespace dart |
| 14362 | 14406 |
| 14363 #endif // DART_PRECOMPILED_RUNTIME | 14407 #endif // DART_PRECOMPILED_RUNTIME |
| OLD | NEW |