Chromium Code Reviews| 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 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "platform/utils.h" | 8 #include "platform/utils.h" |
| 9 #include "vm/ast_transformer.h" | 9 #include "vm/ast_transformer.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 55 // equivalent to setting --enable-asserts and --enable-type-checks. | 55 // equivalent to setting --enable-asserts and --enable-type-checks. |
| 56 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 56 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
| 57 enable_checked_mode, | 57 enable_checked_mode, |
| 58 "Enable checked mode."); | 58 "Enable checked mode."); |
| 59 | 59 |
| 60 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 60 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
| 61 checked, | 61 checked, |
| 62 "Enable checked mode."); | 62 "Enable checked mode."); |
| 63 | 63 |
| 64 | 64 |
| 65 // Quick access to the locally defined isolate() method. | 65 // Quick access to the current isolate and zone. |
| 66 #define I (isolate()) | 66 #define I (thread()->isolate()) |
|
siva
2015/01/23 19:29:27
Is I still used?
koda
2015/01/23 21:09:42
Yes in ~15 places, mostly to access the object_sto
| |
| 67 #define Z (zone()) | |
| 67 | 68 |
| 68 | 69 |
| 69 #if defined(DEBUG) | 70 #if defined(DEBUG) |
| 70 class TraceParser : public ValueObject { | 71 class TraceParser : public ValueObject { |
| 71 public: | 72 public: |
| 72 TraceParser(intptr_t token_pos, const Script& script, const char* msg) { | 73 TraceParser(intptr_t token_pos, const Script& script, const char* msg) { |
| 73 if (FLAG_trace_parser) { | 74 if (FLAG_trace_parser) { |
| 74 // Skips tracing of bootstrap libraries. | 75 // Skips tracing of bootstrap libraries. |
| 75 if (script.HasSource()) { | 76 if (script.HasSource()) { |
| 76 intptr_t line, column; | 77 intptr_t line, column; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 } | 126 } |
| 126 // Cannot canonicalize TypeArgument yet as its types may not have been | 127 // Cannot canonicalize TypeArgument yet as its types may not have been |
| 127 // finalized yet. | 128 // finalized yet. |
| 128 return a.raw(); | 129 return a.raw(); |
| 129 } | 130 } |
| 130 | 131 |
| 131 | 132 |
| 132 LocalVariable* ParsedFunction::EnsureExpressionTemp() { | 133 LocalVariable* ParsedFunction::EnsureExpressionTemp() { |
| 133 if (!has_expression_temp_var()) { | 134 if (!has_expression_temp_var()) { |
| 134 LocalVariable* temp = | 135 LocalVariable* temp = |
| 135 new (I) LocalVariable(function_.token_pos(), | 136 new (Z) LocalVariable(function_.token_pos(), |
| 136 Symbols::ExprTemp(), | 137 Symbols::ExprTemp(), |
| 137 Type::ZoneHandle(Type::DynamicType())); | 138 Type::ZoneHandle(Type::DynamicType())); |
| 138 ASSERT(temp != NULL); | 139 ASSERT(temp != NULL); |
| 139 set_expression_temp_var(temp); | 140 set_expression_temp_var(temp); |
| 140 } | 141 } |
| 141 ASSERT(has_expression_temp_var()); | 142 ASSERT(has_expression_temp_var()); |
| 142 return expression_temp_var(); | 143 return expression_temp_var(); |
| 143 } | 144 } |
| 144 | 145 |
| 145 | 146 |
| 146 void ParsedFunction::EnsureFinallyReturnTemp() { | 147 void ParsedFunction::EnsureFinallyReturnTemp() { |
| 147 if (!has_finally_return_temp_var()) { | 148 if (!has_finally_return_temp_var()) { |
| 148 LocalVariable* temp = new(I) LocalVariable( | 149 LocalVariable* temp = new(Z) LocalVariable( |
| 149 function_.token_pos(), | 150 function_.token_pos(), |
| 150 String::ZoneHandle(I, Symbols::New(":finally_ret_val")), | 151 String::ZoneHandle(Z, Symbols::New(":finally_ret_val")), |
| 151 Type::ZoneHandle(I, Type::DynamicType())); | 152 Type::ZoneHandle(Z, Type::DynamicType())); |
| 152 ASSERT(temp != NULL); | 153 ASSERT(temp != NULL); |
| 153 temp->set_is_final(); | 154 temp->set_is_final(); |
| 154 set_finally_return_temp_var(temp); | 155 set_finally_return_temp_var(temp); |
| 155 } | 156 } |
| 156 ASSERT(has_finally_return_temp_var()); | 157 ASSERT(has_finally_return_temp_var()); |
| 157 } | 158 } |
| 158 | 159 |
| 159 | 160 |
| 160 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { | 161 void ParsedFunction::SetNodeSequence(SequenceNode* node_sequence) { |
| 161 ASSERT(node_sequence_ == NULL); | 162 ASSERT(node_sequence_ == NULL); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 173 | 174 |
| 174 | 175 |
| 175 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { | 176 void ParsedFunction::AddDeferredPrefix(const LibraryPrefix& prefix) { |
| 176 ASSERT(prefix.is_deferred_load()); | 177 ASSERT(prefix.is_deferred_load()); |
| 177 ASSERT(!prefix.is_loaded()); | 178 ASSERT(!prefix.is_loaded()); |
| 178 for (intptr_t i = 0; i < deferred_prefixes_->length(); i++) { | 179 for (intptr_t i = 0; i < deferred_prefixes_->length(); i++) { |
| 179 if ((*deferred_prefixes_)[i]->raw() == prefix.raw()) { | 180 if ((*deferred_prefixes_)[i]->raw() == prefix.raw()) { |
| 180 return; | 181 return; |
| 181 } | 182 } |
| 182 } | 183 } |
| 183 deferred_prefixes_->Add(&LibraryPrefix::ZoneHandle(I, prefix.raw())); | 184 deferred_prefixes_->Add(&LibraryPrefix::ZoneHandle(Z, prefix.raw())); |
| 184 } | 185 } |
| 185 | 186 |
| 186 | 187 |
| 187 void ParsedFunction::AllocateVariables() { | 188 void ParsedFunction::AllocateVariables() { |
| 188 ASSERT(!function().IsIrregexpFunction()); | 189 ASSERT(!function().IsIrregexpFunction()); |
| 189 LocalScope* scope = node_sequence()->scope(); | 190 LocalScope* scope = node_sequence()->scope(); |
| 190 const intptr_t num_fixed_params = function().num_fixed_parameters(); | 191 const intptr_t num_fixed_params = function().num_fixed_parameters(); |
| 191 const intptr_t num_opt_params = function().NumOptionalParameters(); | 192 const intptr_t num_opt_params = function().NumOptionalParameters(); |
| 192 const intptr_t num_params = num_fixed_params + num_opt_params; | 193 const intptr_t num_params = num_fixed_params + num_opt_params; |
| 193 // Compute start indices to parameters and locals, and the number of | 194 // Compute start indices to parameters and locals, and the number of |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 301 }; | 302 }; |
| 302 | 303 |
| 303 | 304 |
| 304 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { | 305 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { |
| 305 inlined_finally_nodes_.Add(node); | 306 inlined_finally_nodes_.Add(node); |
| 306 } | 307 } |
| 307 | 308 |
| 308 | 309 |
| 309 // For parsing a compilation unit. | 310 // For parsing a compilation unit. |
| 310 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) | 311 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) |
| 311 : isolate_(Isolate::Current()), | 312 : thread_(Thread::Current()), |
| 312 script_(Script::Handle(isolate_, script.raw())), | 313 script_(Script::Handle(zone(), script.raw())), |
| 313 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), | 314 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
| 314 token_pos), | 315 token_pos), |
| 315 token_kind_(Token::kILLEGAL), | 316 token_kind_(Token::kILLEGAL), |
| 316 current_block_(NULL), | 317 current_block_(NULL), |
| 317 is_top_level_(false), | 318 is_top_level_(false), |
| 318 await_is_keyword_(false), | 319 await_is_keyword_(false), |
| 319 current_member_(NULL), | 320 current_member_(NULL), |
| 320 allow_function_literals_(true), | 321 allow_function_literals_(true), |
| 321 parsed_function_(NULL), | 322 parsed_function_(NULL), |
| 322 innermost_function_(Function::Handle(isolate_)), | 323 innermost_function_(Function::Handle(zone())), |
| 323 literal_token_(LiteralToken::Handle(isolate_)), | 324 literal_token_(LiteralToken::Handle(zone())), |
| 324 current_class_(Class::Handle(isolate_)), | 325 current_class_(Class::Handle(zone())), |
| 325 library_(Library::Handle(isolate_, library.raw())), | 326 library_(Library::Handle(zone(), library.raw())), |
| 326 try_blocks_list_(NULL), | 327 try_blocks_list_(NULL), |
| 327 last_used_try_index_(0), | 328 last_used_try_index_(0), |
| 328 unregister_pending_function_(false), | 329 unregister_pending_function_(false), |
| 329 async_temp_scope_(NULL) { | 330 async_temp_scope_(NULL) { |
| 330 ASSERT(tokens_iterator_.IsValid()); | 331 ASSERT(tokens_iterator_.IsValid()); |
| 331 ASSERT(!library.IsNull()); | 332 ASSERT(!library.IsNull()); |
| 332 } | 333 } |
| 333 | 334 |
| 334 | 335 |
| 335 // For parsing a function. | 336 // For parsing a function. |
| 336 Parser::Parser(const Script& script, | 337 Parser::Parser(const Script& script, |
| 337 ParsedFunction* parsed_function, | 338 ParsedFunction* parsed_function, |
| 338 intptr_t token_position) | 339 intptr_t token_position) |
| 339 : isolate_(Isolate::Current()), | 340 : thread_(Thread::Current()), |
| 340 script_(Script::Handle(isolate_, script.raw())), | 341 script_(Script::Handle(zone(), script.raw())), |
| 341 tokens_iterator_(TokenStream::Handle(isolate_, script.tokens()), | 342 tokens_iterator_(TokenStream::Handle(zone(), script.tokens()), |
| 342 token_position), | 343 token_position), |
| 343 token_kind_(Token::kILLEGAL), | 344 token_kind_(Token::kILLEGAL), |
| 344 current_block_(NULL), | 345 current_block_(NULL), |
| 345 is_top_level_(false), | 346 is_top_level_(false), |
| 346 await_is_keyword_(false), | 347 await_is_keyword_(false), |
| 347 current_member_(NULL), | 348 current_member_(NULL), |
| 348 allow_function_literals_(true), | 349 allow_function_literals_(true), |
| 349 parsed_function_(parsed_function), | 350 parsed_function_(parsed_function), |
| 350 innermost_function_(Function::Handle(isolate_, | 351 innermost_function_(Function::Handle(zone(), |
| 351 parsed_function->function().raw())), | 352 parsed_function->function().raw())), |
| 352 literal_token_(LiteralToken::Handle(isolate_)), | 353 literal_token_(LiteralToken::Handle(zone())), |
| 353 current_class_(Class::Handle(isolate_, | 354 current_class_(Class::Handle(zone(), |
| 354 parsed_function->function().Owner())), | 355 parsed_function->function().Owner())), |
| 355 library_(Library::Handle(isolate_, Class::Handle( | 356 library_(Library::Handle(zone(), Class::Handle( |
| 356 isolate_, | 357 zone(), |
| 357 parsed_function->function().origin()).library())), | 358 parsed_function->function().origin()).library())), |
| 358 try_blocks_list_(NULL), | 359 try_blocks_list_(NULL), |
| 359 last_used_try_index_(0), | 360 last_used_try_index_(0), |
| 360 unregister_pending_function_(false), | 361 unregister_pending_function_(false), |
| 361 async_temp_scope_(NULL) { | 362 async_temp_scope_(NULL) { |
| 362 ASSERT(tokens_iterator_.IsValid()); | 363 ASSERT(tokens_iterator_.IsValid()); |
| 363 ASSERT(!current_function().IsNull()); | 364 ASSERT(!current_function().IsNull()); |
| 364 if (FLAG_enable_type_checks) { | 365 if (FLAG_enable_type_checks) { |
| 365 EnsureExpressionTemp(); | 366 EnsureExpressionTemp(); |
| 366 } | 367 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 385 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { | 386 if (!Utils::IsInt(16, last_used_try_index_ - 1)) { |
| 386 ReportError("too many nested try statements"); | 387 ReportError("too many nested try statements"); |
| 387 } | 388 } |
| 388 return last_used_try_index_++; | 389 return last_used_try_index_++; |
| 389 } | 390 } |
| 390 | 391 |
| 391 | 392 |
| 392 void Parser::SetScript(const Script& script, intptr_t token_pos) { | 393 void Parser::SetScript(const Script& script, intptr_t token_pos) { |
| 393 script_ = script.raw(); | 394 script_ = script.raw(); |
| 394 tokens_iterator_.SetStream( | 395 tokens_iterator_.SetStream( |
| 395 TokenStream::Handle(I, script.tokens()), token_pos); | 396 TokenStream::Handle(Z, script.tokens()), token_pos); |
| 396 token_kind_ = Token::kILLEGAL; | 397 token_kind_ = Token::kILLEGAL; |
| 397 } | 398 } |
| 398 | 399 |
| 399 | 400 |
| 400 bool Parser::SetAllowFunctionLiterals(bool value) { | 401 bool Parser::SetAllowFunctionLiterals(bool value) { |
| 401 bool current_value = allow_function_literals_; | 402 bool current_value = allow_function_literals_; |
| 402 allow_function_literals_ = value; | 403 allow_function_literals_ = value; |
| 403 return current_value; | 404 return current_value; |
| 404 } | 405 } |
| 405 | 406 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 | 457 |
| 457 Token::Kind Parser::LookaheadToken(int num_tokens) { | 458 Token::Kind Parser::LookaheadToken(int num_tokens) { |
| 458 CompilerStats::num_tokens_lookahead++; | 459 CompilerStats::num_tokens_lookahead++; |
| 459 CompilerStats::num_token_checks++; | 460 CompilerStats::num_token_checks++; |
| 460 return tokens_iterator_.LookaheadTokenKind(num_tokens); | 461 return tokens_iterator_.LookaheadTokenKind(num_tokens); |
| 461 } | 462 } |
| 462 | 463 |
| 463 | 464 |
| 464 String* Parser::CurrentLiteral() const { | 465 String* Parser::CurrentLiteral() const { |
| 465 String& result = | 466 String& result = |
| 466 String::ZoneHandle(I, tokens_iterator_.CurrentLiteral()); | 467 String::ZoneHandle(Z, tokens_iterator_.CurrentLiteral()); |
| 467 return &result; | 468 return &result; |
| 468 } | 469 } |
| 469 | 470 |
| 470 | 471 |
| 471 RawDouble* Parser::CurrentDoubleLiteral() const { | 472 RawDouble* Parser::CurrentDoubleLiteral() const { |
| 472 literal_token_ ^= tokens_iterator_.CurrentToken(); | 473 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 473 ASSERT(literal_token_.kind() == Token::kDOUBLE); | 474 ASSERT(literal_token_.kind() == Token::kDOUBLE); |
| 474 return Double::RawCast(literal_token_.value()); | 475 return Double::RawCast(literal_token_.value()); |
| 475 } | 476 } |
| 476 | 477 |
| 477 | 478 |
| 478 RawInteger* Parser::CurrentIntegerLiteral() const { | 479 RawInteger* Parser::CurrentIntegerLiteral() const { |
| 479 literal_token_ ^= tokens_iterator_.CurrentToken(); | 480 literal_token_ ^= tokens_iterator_.CurrentToken(); |
| 480 ASSERT(literal_token_.kind() == Token::kINTEGER); | 481 ASSERT(literal_token_.kind() == Token::kINTEGER); |
| 481 RawInteger* ri = Integer::RawCast(literal_token_.value()); | 482 RawInteger* ri = Integer::RawCast(literal_token_.value()); |
| 482 if (FLAG_throw_on_javascript_int_overflow) { | 483 if (FLAG_throw_on_javascript_int_overflow) { |
| 483 const Integer& i = Integer::Handle(I, ri); | 484 const Integer& i = Integer::Handle(Z, ri); |
| 484 if (i.CheckJavascriptIntegerOverflow()) { | 485 if (i.CheckJavascriptIntegerOverflow()) { |
| 485 ReportError(TokenPos(), | 486 ReportError(TokenPos(), |
| 486 "Integer literal does not fit in a Javascript integer: %s.", | 487 "Integer literal does not fit in a Javascript integer: %s.", |
| 487 i.ToCString()); | 488 i.ToCString()); |
| 488 } | 489 } |
| 489 } | 490 } |
| 490 return ri; | 491 return ri; |
| 491 } | 492 } |
| 492 | 493 |
| 493 | 494 |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 782 const Script& script = Script::Handle(isolate, cls.script()); | 783 const Script& script = Script::Handle(isolate, cls.script()); |
| 783 const Library& lib = Library::Handle(isolate, cls.library()); | 784 const Library& lib = Library::Handle(isolate, cls.library()); |
| 784 Parser parser(script, lib, cls.token_pos()); | 785 Parser parser(script, lib, cls.token_pos()); |
| 785 parser.ParseEnumDefinition(cls); | 786 parser.ParseEnumDefinition(cls); |
| 786 } | 787 } |
| 787 } | 788 } |
| 788 | 789 |
| 789 | 790 |
| 790 RawObject* Parser::ParseFunctionParameters(const Function& func) { | 791 RawObject* Parser::ParseFunctionParameters(const Function& func) { |
| 791 ASSERT(!func.IsNull()); | 792 ASSERT(!func.IsNull()); |
| 792 Isolate* isolate = Isolate::Current(); | 793 Thread* thread = Thread::Current(); |
| 793 StackZone zone(isolate); | 794 Isolate* isolate = thread->isolate(); |
| 795 StackZone stack_zone(isolate); | |
| 796 Zone* zone = stack_zone.GetZone(); | |
| 794 LongJumpScope jump; | 797 LongJumpScope jump; |
| 795 if (setjmp(*jump.Set()) == 0) { | 798 if (setjmp(*jump.Set()) == 0) { |
| 796 const Script& script = Script::Handle(isolate, func.script()); | 799 const Script& script = Script::Handle(zone, func.script()); |
| 797 const Class& owner = Class::Handle(isolate, func.Owner()); | 800 const Class& owner = Class::Handle(zone, func.Owner()); |
| 798 ASSERT(!owner.IsNull()); | 801 ASSERT(!owner.IsNull()); |
| 799 ParsedFunction* parsed_function = new ParsedFunction( | 802 ParsedFunction* parsed_function = new ParsedFunction( |
| 800 isolate, Function::ZoneHandle(isolate, func.raw())); | 803 thread, Function::ZoneHandle(zone, func.raw())); |
| 801 Parser parser(script, parsed_function, func.token_pos()); | 804 Parser parser(script, parsed_function, func.token_pos()); |
| 802 parser.SkipFunctionPreamble(); | 805 parser.SkipFunctionPreamble(); |
| 803 ParamList params; | 806 ParamList params; |
| 804 parser.ParseFormalParameterList(true, true, ¶ms); | 807 parser.ParseFormalParameterList(true, true, ¶ms); |
| 805 ParamDesc* param = params.parameters->data(); | 808 ParamDesc* param = params.parameters->data(); |
| 806 const int param_cnt = params.num_fixed_parameters + | 809 const int param_cnt = params.num_fixed_parameters + |
| 807 params.num_optional_parameters; | 810 params.num_optional_parameters; |
| 808 const Array& param_descriptor = | 811 const Array& param_descriptor = |
| 809 Array::Handle(Array::New(param_cnt * kParameterEntrySize)); | 812 Array::Handle(Array::New(param_cnt * kParameterEntrySize)); |
| 810 for (int i = 0, j = 0; i < param_cnt; i++, j += kParameterEntrySize) { | 813 for (int i = 0, j = 0; i < param_cnt; i++, j += kParameterEntrySize) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 827 error = isolate->object_store()->sticky_error(); | 830 error = isolate->object_store()->sticky_error(); |
| 828 isolate->object_store()->clear_sticky_error(); | 831 isolate->object_store()->clear_sticky_error(); |
| 829 return error.raw(); | 832 return error.raw(); |
| 830 } | 833 } |
| 831 UNREACHABLE(); | 834 UNREACHABLE(); |
| 832 return Object::null(); | 835 return Object::null(); |
| 833 } | 836 } |
| 834 | 837 |
| 835 | 838 |
| 836 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 839 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 837 Isolate* isolate = Isolate::Current(); | 840 Isolate* isolate = parsed_function->isolate(); |
| 841 Zone* zone = parsed_function->zone(); | |
| 838 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 842 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 839 CompilerStats::num_functions_compiled++; | 843 CompilerStats::num_functions_compiled++; |
| 840 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 844 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 841 ASSERT(parsed_function != NULL); | 845 ASSERT(parsed_function != NULL); |
| 842 const Function& func = parsed_function->function(); | 846 const Function& func = parsed_function->function(); |
| 843 const Script& script = Script::Handle(isolate, func.script()); | 847 const Script& script = Script::Handle(zone, func.script()); |
| 844 Parser parser(script, parsed_function, func.token_pos()); | 848 Parser parser(script, parsed_function, func.token_pos()); |
| 845 SequenceNode* node_sequence = NULL; | 849 SequenceNode* node_sequence = NULL; |
| 846 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); | 850 Array& default_parameter_values = Array::ZoneHandle(zone, Array::null()); |
| 847 switch (func.kind()) { | 851 switch (func.kind()) { |
| 848 case RawFunction::kRegularFunction: | 852 case RawFunction::kRegularFunction: |
| 849 case RawFunction::kClosureFunction: | 853 case RawFunction::kClosureFunction: |
| 850 case RawFunction::kGetterFunction: | 854 case RawFunction::kGetterFunction: |
| 851 case RawFunction::kSetterFunction: | 855 case RawFunction::kSetterFunction: |
| 852 case RawFunction::kConstructor: | 856 case RawFunction::kConstructor: |
| 853 // The call to a redirecting factory is redirected. | 857 // The call to a redirecting factory is redirected. |
| 854 ASSERT(!func.IsRedirectingFactory()); | 858 ASSERT(!func.IsRedirectingFactory()); |
| 855 if (!func.IsImplicitConstructor()) { | 859 if (!func.IsImplicitConstructor()) { |
| 856 parser.SkipFunctionPreamble(); | 860 parser.SkipFunctionPreamble(); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 918 ((instantiator != NULL) && instantiator->is_captured())) { | 922 ((instantiator != NULL) && instantiator->is_captured())) { |
| 919 parsed_function->set_instantiator(instantiator); | 923 parsed_function->set_instantiator(instantiator); |
| 920 } | 924 } |
| 921 } | 925 } |
| 922 | 926 |
| 923 parsed_function->set_default_parameter_values(default_parameter_values); | 927 parsed_function->set_default_parameter_values(default_parameter_values); |
| 924 } | 928 } |
| 925 | 929 |
| 926 | 930 |
| 927 RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) { | 931 RawObject* Parser::ParseMetadata(const Class& cls, intptr_t token_pos) { |
| 928 Isolate* isolate = Isolate::Current(); | 932 Thread* thread = Thread::Current(); |
| 929 StackZone zone(isolate); | 933 Isolate* isolate = thread->isolate(); |
| 934 StackZone stack_zone(isolate); | |
| 935 Zone* zone = stack_zone.GetZone(); | |
| 930 LongJumpScope jump; | 936 LongJumpScope jump; |
| 931 if (setjmp(*jump.Set()) == 0) { | 937 if (setjmp(*jump.Set()) == 0) { |
| 932 const Script& script = Script::Handle(isolate, cls.script()); | 938 const Script& script = Script::Handle(zone, cls.script()); |
| 933 // Parsing metadata can involve following paths in the parser that are | 939 // Parsing metadata can involve following paths in the parser that are |
| 934 // normally used for expressions and assume current_function is non-null, | 940 // normally used for expressions and assume current_function is non-null, |
| 935 // so we create a fake function to use as the current_function rather than | 941 // so we create a fake function to use as the current_function rather than |
| 936 // scattering special cases throughout the parser. | 942 // scattering special cases throughout the parser. |
| 937 const Function& fake_function = Function::ZoneHandle(Function::New( | 943 const Function& fake_function = Function::ZoneHandle(zone, Function::New( |
| 938 Symbols::At(), | 944 Symbols::At(), |
| 939 RawFunction::kRegularFunction, | 945 RawFunction::kRegularFunction, |
| 940 true, // is_static | 946 true, // is_static |
| 941 false, // is_const | 947 false, // is_const |
| 942 false, // is_abstract | 948 false, // is_abstract |
| 943 false, // is_external | 949 false, // is_external |
| 944 false, // is_native | 950 false, // is_native |
| 945 cls, | 951 cls, |
| 946 token_pos)); | 952 token_pos)); |
| 947 fake_function.set_is_debuggable(false); | 953 fake_function.set_is_debuggable(false); |
| 948 ParsedFunction* parsed_function = | 954 ParsedFunction* parsed_function = |
| 949 new ParsedFunction(isolate, fake_function); | 955 new ParsedFunction(thread, fake_function); |
| 950 Parser parser(script, parsed_function, token_pos); | 956 Parser parser(script, parsed_function, token_pos); |
| 951 parser.set_current_class(cls); | 957 parser.set_current_class(cls); |
| 952 | 958 |
| 953 RawObject* metadata = parser.EvaluateMetadata(); | 959 RawObject* metadata = parser.EvaluateMetadata(); |
| 954 return metadata; | 960 return metadata; |
| 955 } else { | 961 } else { |
| 956 Error& error = Error::Handle(isolate); | 962 Error& error = Error::Handle(zone); |
| 957 error = isolate->object_store()->sticky_error(); | 963 error = isolate->object_store()->sticky_error(); |
| 958 isolate->object_store()->clear_sticky_error(); | 964 isolate->object_store()->clear_sticky_error(); |
| 959 return error.raw(); | 965 return error.raw(); |
| 960 } | 966 } |
| 961 UNREACHABLE(); | 967 UNREACHABLE(); |
| 962 return Object::null(); | 968 return Object::null(); |
| 963 } | 969 } |
| 964 | 970 |
| 965 | 971 |
| 966 RawArray* Parser::EvaluateMetadata() { | 972 RawArray* Parser::EvaluateMetadata() { |
| 967 CheckToken(Token::kAT, "Metadata character '@' expected"); | 973 CheckToken(Token::kAT, "Metadata character '@' expected"); |
| 968 GrowableObjectArray& meta_values = | 974 GrowableObjectArray& meta_values = |
| 969 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 975 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 970 while (CurrentToken() == Token::kAT) { | 976 while (CurrentToken() == Token::kAT) { |
| 971 ConsumeToken(); | 977 ConsumeToken(); |
| 972 intptr_t expr_pos = TokenPos(); | 978 intptr_t expr_pos = TokenPos(); |
| 973 if (!IsIdentifier()) { | 979 if (!IsIdentifier()) { |
| 974 ExpectIdentifier("identifier expected"); | 980 ExpectIdentifier("identifier expected"); |
| 975 } | 981 } |
| 976 // Reject expressions with deferred library prefix eagerly. | 982 // Reject expressions with deferred library prefix eagerly. |
| 977 Object& obj = Object::Handle(I, | 983 Object& obj = Object::Handle(Z, |
| 978 library_.LookupLocalObject(*CurrentLiteral())); | 984 library_.LookupLocalObject(*CurrentLiteral())); |
| 979 if (!obj.IsNull() && obj.IsLibraryPrefix()) { | 985 if (!obj.IsNull() && obj.IsLibraryPrefix()) { |
| 980 if (LibraryPrefix::Cast(obj).is_deferred_load()) { | 986 if (LibraryPrefix::Cast(obj).is_deferred_load()) { |
| 981 ReportError("Metadata must be compile-time constant"); | 987 ReportError("Metadata must be compile-time constant"); |
| 982 } | 988 } |
| 983 } | 989 } |
| 984 AstNode* expr = NULL; | 990 AstNode* expr = NULL; |
| 985 if ((LookaheadToken(1) == Token::kLPAREN) || | 991 if ((LookaheadToken(1) == Token::kLPAREN) || |
| 986 ((LookaheadToken(1) == Token::kPERIOD) && | 992 ((LookaheadToken(1) == Token::kPERIOD) && |
| 987 (LookaheadToken(3) == Token::kLPAREN)) || | 993 (LookaheadToken(3) == Token::kLPAREN)) || |
| 988 ((LookaheadToken(1) == Token::kPERIOD) && | 994 ((LookaheadToken(1) == Token::kPERIOD) && |
| 989 (LookaheadToken(3) == Token::kPERIOD) && | 995 (LookaheadToken(3) == Token::kPERIOD) && |
| 990 (LookaheadToken(5) == Token::kLPAREN))) { | 996 (LookaheadToken(5) == Token::kLPAREN))) { |
| 991 expr = ParseNewOperator(Token::kCONST); | 997 expr = ParseNewOperator(Token::kCONST); |
| 992 } else { | 998 } else { |
| 993 // Can be x, C.x, or L.C.x. | 999 // Can be x, C.x, or L.C.x. |
| 994 expr = ParsePrimary(); // Consumes x, C or L.C. | 1000 expr = ParsePrimary(); // Consumes x, C or L.C. |
| 995 Class& cls = Class::Handle(I); | 1001 Class& cls = Class::Handle(Z); |
| 996 if (expr->IsPrimaryNode()) { | 1002 if (expr->IsPrimaryNode()) { |
| 997 PrimaryNode* primary_node = expr->AsPrimaryNode(); | 1003 PrimaryNode* primary_node = expr->AsPrimaryNode(); |
| 998 if (primary_node->primary().IsClass()) { | 1004 if (primary_node->primary().IsClass()) { |
| 999 // If the primary node referred to a class we are loading a | 1005 // If the primary node referred to a class we are loading a |
| 1000 // qualified static field. | 1006 // qualified static field. |
| 1001 cls ^= primary_node->primary().raw(); | 1007 cls ^= primary_node->primary().raw(); |
| 1002 } else { | 1008 } else { |
| 1003 ReportError(expr_pos, | 1009 ReportError(expr_pos, |
| 1004 "Metadata expressions must refer to a const field " | 1010 "Metadata expressions must refer to a const field " |
| 1005 "or constructor"); | 1011 "or constructor"); |
| 1006 } | 1012 } |
| 1007 } | 1013 } |
| 1008 if (CurrentToken() == Token::kPERIOD) { | 1014 if (CurrentToken() == Token::kPERIOD) { |
| 1009 // C.x or L.C.X. | 1015 // C.x or L.C.X. |
| 1010 if (cls.IsNull()) { | 1016 if (cls.IsNull()) { |
| 1011 ReportError(expr_pos, | 1017 ReportError(expr_pos, |
| 1012 "Metadata expressions must refer to a const field " | 1018 "Metadata expressions must refer to a const field " |
| 1013 "or constructor"); | 1019 "or constructor"); |
| 1014 } | 1020 } |
| 1015 ConsumeToken(); | 1021 ConsumeToken(); |
| 1016 const intptr_t ident_pos = TokenPos(); | 1022 const intptr_t ident_pos = TokenPos(); |
| 1017 String* ident = ExpectIdentifier("identifier expected"); | 1023 String* ident = ExpectIdentifier("identifier expected"); |
| 1018 const Field& field = Field::Handle(I, cls.LookupStaticField(*ident)); | 1024 const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident)); |
| 1019 if (field.IsNull()) { | 1025 if (field.IsNull()) { |
| 1020 ReportError(ident_pos, | 1026 ReportError(ident_pos, |
| 1021 "Class '%s' has no field '%s'", | 1027 "Class '%s' has no field '%s'", |
| 1022 cls.ToCString(), | 1028 cls.ToCString(), |
| 1023 ident->ToCString()); | 1029 ident->ToCString()); |
| 1024 } | 1030 } |
| 1025 if (!field.is_const()) { | 1031 if (!field.is_const()) { |
| 1026 ReportError(ident_pos, | 1032 ReportError(ident_pos, |
| 1027 "Field '%s' of class '%s' is not const", | 1033 "Field '%s' of class '%s' is not const", |
| 1028 ident->ToCString(), | 1034 ident->ToCString(), |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1041 } | 1047 } |
| 1042 | 1048 |
| 1043 | 1049 |
| 1044 SequenceNode* Parser::ParseStaticInitializer() { | 1050 SequenceNode* Parser::ParseStaticInitializer() { |
| 1045 ExpectIdentifier("field name expected"); | 1051 ExpectIdentifier("field name expected"); |
| 1046 CheckToken(Token::kASSIGN, "field initialier expected"); | 1052 CheckToken(Token::kASSIGN, "field initialier expected"); |
| 1047 ConsumeToken(); | 1053 ConsumeToken(); |
| 1048 OpenFunctionBlock(parsed_function()->function()); | 1054 OpenFunctionBlock(parsed_function()->function()); |
| 1049 intptr_t expr_pos = TokenPos(); | 1055 intptr_t expr_pos = TokenPos(); |
| 1050 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1056 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1051 ReturnNode* ret = new(I) ReturnNode(expr_pos, expr); | 1057 ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr); |
| 1052 current_block_->statements->Add(ret); | 1058 current_block_->statements->Add(ret); |
| 1053 return CloseBlock(); | 1059 return CloseBlock(); |
| 1054 } | 1060 } |
| 1055 | 1061 |
| 1056 | 1062 |
| 1057 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { | 1063 ParsedFunction* Parser::ParseStaticFieldInitializer(const Field& field) { |
| 1058 ASSERT(field.is_static()); | 1064 ASSERT(field.is_static()); |
| 1059 ASSERT(field.value() == Object::transition_sentinel().raw()); | 1065 ASSERT(field.value() == Object::transition_sentinel().raw()); |
| 1060 Isolate* isolate = Isolate::Current(); | 1066 Thread* thread = Thread::Current(); |
| 1067 // TODO(koda): Should there be a StackZone here? | |
| 1068 Zone* zone = thread->zone(); | |
| 1061 | 1069 |
| 1062 const Class& script_cls = Class::Handle(isolate, field.origin()); | 1070 const Class& script_cls = Class::Handle(zone, field.origin()); |
| 1063 const Script& script = Script::Handle(isolate, script_cls.script()); | 1071 const Script& script = Script::Handle(zone, script_cls.script()); |
| 1064 | 1072 |
| 1065 const String& field_name = String::Handle(isolate, field.name()); | 1073 const String& field_name = String::Handle(zone, field.name()); |
| 1066 String& init_name = String::Handle(isolate, | 1074 String& init_name = String::Handle(zone, |
| 1067 String::Concat(Symbols::InitPrefix(), field_name)); | 1075 String::Concat(Symbols::InitPrefix(), field_name)); |
| 1068 init_name = Symbols::New(init_name); | 1076 init_name = Symbols::New(init_name); |
| 1069 | 1077 |
| 1070 const Function& initializer = Function::ZoneHandle(isolate, | 1078 const Function& initializer = Function::ZoneHandle(zone, |
| 1071 Function::New(init_name, | 1079 Function::New(init_name, |
| 1072 RawFunction::kRegularFunction, | 1080 RawFunction::kRegularFunction, |
| 1073 true, // static | 1081 true, // static |
| 1074 false, // !const | 1082 false, // !const |
| 1075 false, // !abstract | 1083 false, // !abstract |
| 1076 false, // !external | 1084 false, // !external |
| 1077 false, // !native | 1085 false, // !native |
| 1078 Class::Handle(field.owner()), | 1086 Class::Handle(field.owner()), |
| 1079 field.token_pos())); | 1087 field.token_pos())); |
| 1080 initializer.set_result_type(AbstractType::Handle(isolate, field.type())); | 1088 initializer.set_result_type(AbstractType::Handle(zone, field.type())); |
| 1081 // Static initializer functions are hidden from the user. | 1089 // Static initializer functions are hidden from the user. |
| 1082 // Since they are only executed once, we avoid optimizing | 1090 // Since they are only executed once, we avoid optimizing |
| 1083 // and inlining them. After the field is initialized, the | 1091 // and inlining them. After the field is initialized, the |
| 1084 // compiler can eliminate the call to the static initializer. | 1092 // compiler can eliminate the call to the static initializer. |
| 1085 initializer.set_is_visible(false); | 1093 initializer.set_is_visible(false); |
| 1086 initializer.set_is_debuggable(false); | 1094 initializer.set_is_debuggable(false); |
| 1087 initializer.SetIsOptimizable(false); | 1095 initializer.SetIsOptimizable(false); |
| 1088 initializer.set_is_inlinable(false); | 1096 initializer.set_is_inlinable(false); |
| 1089 | 1097 |
| 1090 ParsedFunction* parsed_function = new ParsedFunction(isolate, initializer); | 1098 ParsedFunction* parsed_function = new ParsedFunction(thread, initializer); |
| 1091 Parser parser(script, parsed_function, field.token_pos()); | 1099 Parser parser(script, parsed_function, field.token_pos()); |
| 1092 | 1100 |
| 1093 SequenceNode* body = parser.ParseStaticInitializer(); | 1101 SequenceNode* body = parser.ParseStaticInitializer(); |
| 1094 parsed_function->SetNodeSequence(body); | 1102 parsed_function->SetNodeSequence(body); |
| 1095 parsed_function->set_default_parameter_values(Object::null_array()); | 1103 parsed_function->set_default_parameter_values(Object::null_array()); |
| 1096 | 1104 |
| 1097 if (parsed_function->has_expression_temp_var()) { | 1105 if (parsed_function->has_expression_temp_var()) { |
| 1098 body->scope()->AddVariable(parsed_function->expression_temp_var()); | 1106 body->scope()->AddVariable(parsed_function->expression_temp_var()); |
| 1099 } | 1107 } |
| 1100 body->scope()->AddVariable(parsed_function->current_context_var()); | 1108 body->scope()->AddVariable(parsed_function->current_context_var()); |
| 1101 if (parsed_function->has_finally_return_temp_var()) { | 1109 if (parsed_function->has_finally_return_temp_var()) { |
| 1102 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); | 1110 body->scope()->AddVariable(parsed_function->finally_return_temp_var()); |
| 1103 } | 1111 } |
| 1104 // The instantiator is not required in a static expression. | 1112 // The instantiator is not required in a static expression. |
| 1105 ASSERT(!parser.IsInstantiatorRequired()); | 1113 ASSERT(!parser.IsInstantiatorRequired()); |
| 1106 | 1114 |
| 1107 return parsed_function; | 1115 return parsed_function; |
| 1108 } | 1116 } |
| 1109 | 1117 |
| 1110 | 1118 |
| 1111 RawObject* Parser::ParseFunctionFromSource(const Class& owning_class, | 1119 RawObject* Parser::ParseFunctionFromSource(const Class& owning_class, |
| 1112 const String& source) { | 1120 const String& source) { |
| 1113 Isolate* isolate = Isolate::Current(); | 1121 Thread* thread = Thread::Current(); |
| 1114 StackZone zone(isolate); | 1122 Isolate* isolate = thread->isolate(); |
| 1123 StackZone stack_zone(isolate); | |
| 1115 LongJumpScope jump; | 1124 LongJumpScope jump; |
| 1116 if (setjmp(*jump.Set()) == 0) { | 1125 if (setjmp(*jump.Set()) == 0) { |
| 1117 const String& uri = String::Handle(Symbols::New("dynamically-added")); | 1126 const String& uri = String::Handle(Symbols::New("dynamically-added")); |
| 1118 const Script& script = Script::Handle( | 1127 const Script& script = Script::Handle( |
| 1119 Script::New(uri, source, RawScript::kSourceTag)); | 1128 Script::New(uri, source, RawScript::kSourceTag)); |
| 1120 const Library& owning_library = Library::Handle(owning_class.library()); | 1129 const Library& owning_library = Library::Handle(owning_class.library()); |
| 1121 const String& private_key = String::Handle(owning_library.private_key()); | 1130 const String& private_key = String::Handle(owning_library.private_key()); |
| 1122 script.Tokenize(private_key); | 1131 script.Tokenize(private_key); |
| 1123 const intptr_t token_pos = 0; | 1132 const intptr_t token_pos = 0; |
| 1124 Parser parser(script, owning_library, token_pos); | 1133 Parser parser(script, owning_library, token_pos); |
| 1125 parser.is_top_level_ = true; | 1134 parser.is_top_level_ = true; |
| 1126 parser.set_current_class(owning_class); | 1135 parser.set_current_class(owning_class); |
| 1127 const String& class_name = String::Handle(owning_class.Name()); | 1136 const String& class_name = String::Handle(owning_class.Name()); |
| 1128 ClassDesc members(owning_class, class_name, false, token_pos); | 1137 ClassDesc members(owning_class, class_name, false, token_pos); |
| 1129 const intptr_t metadata_pos = parser.SkipMetadata(); | 1138 const intptr_t metadata_pos = parser.SkipMetadata(); |
| 1130 parser.ParseClassMemberDefinition(&members, metadata_pos); | 1139 parser.ParseClassMemberDefinition(&members, metadata_pos); |
| 1131 ASSERT(members.functions().Length() == 1); | 1140 ASSERT(members.functions().Length() == 1); |
| 1132 const Function& func = | 1141 const Function& func = |
| 1133 Function::ZoneHandle(Function::RawCast(members.functions().At(0))); | 1142 Function::ZoneHandle(Function::RawCast(members.functions().At(0))); |
| 1134 func.set_eval_script(script); | 1143 func.set_eval_script(script); |
| 1135 ParsedFunction* parsed_function = new ParsedFunction(isolate, func); | 1144 ParsedFunction* parsed_function = new ParsedFunction(thread, func); |
| 1136 Parser::ParseFunction(parsed_function); | 1145 Parser::ParseFunction(parsed_function); |
| 1137 return func.raw(); | 1146 return func.raw(); |
| 1138 } else { | 1147 } else { |
| 1139 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); | 1148 const Error& error = Error::Handle(isolate->object_store()->sticky_error()); |
| 1140 isolate->object_store()->clear_sticky_error(); | 1149 isolate->object_store()->clear_sticky_error(); |
| 1141 return error.raw(); | 1150 return error.raw(); |
| 1142 } | 1151 } |
| 1143 UNREACHABLE(); | 1152 UNREACHABLE(); |
| 1144 return Object::null(); | 1153 return Object::null(); |
| 1145 } | 1154 } |
| 1146 | 1155 |
| 1147 | 1156 |
| 1148 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { | 1157 SequenceNode* Parser::ParseStaticFinalGetter(const Function& func) { |
| 1149 TRACE_PARSER("ParseStaticFinalGetter"); | 1158 TRACE_PARSER("ParseStaticFinalGetter"); |
| 1150 ParamList params; | 1159 ParamList params; |
| 1151 ASSERT(func.num_fixed_parameters() == 0); // static. | 1160 ASSERT(func.num_fixed_parameters() == 0); // static. |
| 1152 ASSERT(!func.HasOptionalParameters()); | 1161 ASSERT(!func.HasOptionalParameters()); |
| 1153 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 1162 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 1154 | 1163 |
| 1155 // Build local scope for function and populate with the formal parameters. | 1164 // Build local scope for function and populate with the formal parameters. |
| 1156 OpenFunctionBlock(func); | 1165 OpenFunctionBlock(func); |
| 1157 AddFormalParamsToScope(¶ms, current_block_->scope); | 1166 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1158 | 1167 |
| 1159 intptr_t ident_pos = TokenPos(); | 1168 intptr_t ident_pos = TokenPos(); |
| 1160 const String& field_name = *ExpectIdentifier("field name expected"); | 1169 const String& field_name = *ExpectIdentifier("field name expected"); |
| 1161 const Class& field_class = Class::Handle(I, func.Owner()); | 1170 const Class& field_class = Class::Handle(Z, func.Owner()); |
| 1162 const Field& field = | 1171 const Field& field = |
| 1163 Field::ZoneHandle(I, field_class.LookupStaticField(field_name)); | 1172 Field::ZoneHandle(Z, field_class.LookupStaticField(field_name)); |
| 1164 | 1173 |
| 1165 // Static final fields must have an initializer. | 1174 // Static final fields must have an initializer. |
| 1166 ExpectToken(Token::kASSIGN); | 1175 ExpectToken(Token::kASSIGN); |
| 1167 | 1176 |
| 1168 const intptr_t expr_pos = TokenPos(); | 1177 const intptr_t expr_pos = TokenPos(); |
| 1169 if (field.is_const()) { | 1178 if (field.is_const()) { |
| 1170 // We don't want to use ParseConstExpr() here because we don't want | 1179 // We don't want to use ParseConstExpr() here because we don't want |
| 1171 // the constant folding code to create, compile and execute a code | 1180 // the constant folding code to create, compile and execute a code |
| 1172 // fragment to evaluate the expression. Instead, we just make sure | 1181 // fragment to evaluate the expression. Instead, we just make sure |
| 1173 // the static const field initializer is a constant expression and | 1182 // the static const field initializer is a constant expression and |
| 1174 // leave the evaluation to the getter function. | 1183 // leave the evaluation to the getter function. |
| 1175 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); | 1184 AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 1176 // This getter will only be called once at compile time. | 1185 // This getter will only be called once at compile time. |
| 1177 if (expr->EvalConstExpr() == NULL) { | 1186 if (expr->EvalConstExpr() == NULL) { |
| 1178 ReportError(expr_pos, "initializer is not a valid compile-time constant"); | 1187 ReportError(expr_pos, "initializer is not a valid compile-time constant"); |
| 1179 } | 1188 } |
| 1180 ReturnNode* return_node = new ReturnNode(ident_pos, expr); | 1189 ReturnNode* return_node = new ReturnNode(ident_pos, expr); |
| 1181 current_block_->statements->Add(return_node); | 1190 current_block_->statements->Add(return_node); |
| 1182 } else { | 1191 } else { |
| 1183 // This getter may be called each time the static field is accessed. | 1192 // This getter may be called each time the static field is accessed. |
| 1184 // Call runtime support to parse and evaluate the initializer expression. | 1193 // Call runtime support to parse and evaluate the initializer expression. |
| 1185 // The runtime function will detect circular dependencies in expressions | 1194 // The runtime function will detect circular dependencies in expressions |
| 1186 // and handle errors while evaluating the expression. | 1195 // and handle errors while evaluating the expression. |
| 1187 current_block_->statements->Add( | 1196 current_block_->statements->Add( |
| 1188 new (I) InitStaticFieldNode(ident_pos, field)); | 1197 new (Z) InitStaticFieldNode(ident_pos, field)); |
| 1189 ReturnNode* return_node = | 1198 ReturnNode* return_node = |
| 1190 new ReturnNode(ident_pos, | 1199 new ReturnNode(ident_pos, |
| 1191 new LoadStaticFieldNode(ident_pos, field)); | 1200 new LoadStaticFieldNode(ident_pos, field)); |
| 1192 current_block_->statements->Add(return_node); | 1201 current_block_->statements->Add(return_node); |
| 1193 } | 1202 } |
| 1194 return CloseBlock(); | 1203 return CloseBlock(); |
| 1195 } | 1204 } |
| 1196 | 1205 |
| 1197 | 1206 |
| 1198 // Create AstNodes for an implicit instance getter method: | 1207 // Create AstNodes for an implicit instance getter method: |
| 1199 // LoadLocalNode 0 ('this'); | 1208 // LoadLocalNode 0 ('this'); |
| 1200 // LoadInstanceFieldNode (field_name); | 1209 // LoadInstanceFieldNode (field_name); |
| 1201 // ReturnNode (field's value); | 1210 // ReturnNode (field's value); |
| 1202 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { | 1211 SequenceNode* Parser::ParseInstanceGetter(const Function& func) { |
| 1203 TRACE_PARSER("ParseInstanceGetter"); | 1212 TRACE_PARSER("ParseInstanceGetter"); |
| 1204 ParamList params; | 1213 ParamList params; |
| 1205 // func.token_pos() points to the name of the field. | 1214 // func.token_pos() points to the name of the field. |
| 1206 const intptr_t ident_pos = func.token_pos(); | 1215 const intptr_t ident_pos = func.token_pos(); |
| 1207 ASSERT(current_class().raw() == func.Owner()); | 1216 ASSERT(current_class().raw() == func.Owner()); |
| 1208 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1217 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1209 ASSERT(func.num_fixed_parameters() == 1); // receiver. | 1218 ASSERT(func.num_fixed_parameters() == 1); // receiver. |
| 1210 ASSERT(!func.HasOptionalParameters()); | 1219 ASSERT(!func.HasOptionalParameters()); |
| 1211 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 1220 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 1212 | 1221 |
| 1213 // Build local scope for function and populate with the formal parameters. | 1222 // Build local scope for function and populate with the formal parameters. |
| 1214 OpenFunctionBlock(func); | 1223 OpenFunctionBlock(func); |
| 1215 AddFormalParamsToScope(¶ms, current_block_->scope); | 1224 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1216 | 1225 |
| 1217 // Receiver is local 0. | 1226 // Receiver is local 0. |
| 1218 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1227 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1219 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1228 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1220 String& field_name = String::Handle(I, func.name()); | 1229 String& field_name = String::Handle(Z, func.name()); |
| 1221 field_name = Field::NameFromGetter(field_name); | 1230 field_name = Field::NameFromGetter(field_name); |
| 1222 | 1231 |
| 1223 const Class& field_class = Class::Handle(I, func.Owner()); | 1232 const Class& field_class = Class::Handle(Z, func.Owner()); |
| 1224 const Field& field = | 1233 const Field& field = |
| 1225 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); | 1234 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
| 1226 ASSERT(!field.IsNull()); | 1235 ASSERT(!field.IsNull()); |
| 1227 | 1236 |
| 1228 LoadInstanceFieldNode* load_field = | 1237 LoadInstanceFieldNode* load_field = |
| 1229 new LoadInstanceFieldNode(ident_pos, load_receiver, field); | 1238 new LoadInstanceFieldNode(ident_pos, load_receiver, field); |
| 1230 | 1239 |
| 1231 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, load_field); | 1240 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, load_field); |
| 1232 current_block_->statements->Add(return_node); | 1241 current_block_->statements->Add(return_node); |
| 1233 return CloseBlock(); | 1242 return CloseBlock(); |
| 1234 } | 1243 } |
| 1235 | 1244 |
| 1236 | 1245 |
| 1237 // Create AstNodes for an implicit instance setter method: | 1246 // Create AstNodes for an implicit instance setter method: |
| 1238 // LoadLocalNode 0 ('this') | 1247 // LoadLocalNode 0 ('this') |
| 1239 // LoadLocalNode 1 ('value') | 1248 // LoadLocalNode 1 ('value') |
| 1240 // SetInstanceField (field_name); | 1249 // SetInstanceField (field_name); |
| 1241 // ReturnNode (void); | 1250 // ReturnNode (void); |
| 1242 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { | 1251 SequenceNode* Parser::ParseInstanceSetter(const Function& func) { |
| 1243 TRACE_PARSER("ParseInstanceSetter"); | 1252 TRACE_PARSER("ParseInstanceSetter"); |
| 1244 // func.token_pos() points to the name of the field. | 1253 // func.token_pos() points to the name of the field. |
| 1245 const intptr_t ident_pos = func.token_pos(); | 1254 const intptr_t ident_pos = func.token_pos(); |
| 1246 const String& field_name = *CurrentLiteral(); | 1255 const String& field_name = *CurrentLiteral(); |
| 1247 const Class& field_class = Class::ZoneHandle(I, func.Owner()); | 1256 const Class& field_class = Class::ZoneHandle(Z, func.Owner()); |
| 1248 const Field& field = | 1257 const Field& field = |
| 1249 Field::ZoneHandle(I, field_class.LookupInstanceField(field_name)); | 1258 Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name)); |
| 1250 const AbstractType& field_type = AbstractType::ZoneHandle(I, field.type()); | 1259 const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type()); |
| 1251 | 1260 |
| 1252 ParamList params; | 1261 ParamList params; |
| 1253 ASSERT(current_class().raw() == func.Owner()); | 1262 ASSERT(current_class().raw() == func.Owner()); |
| 1254 params.AddReceiver(ReceiverType(current_class()), ident_pos); | 1263 params.AddReceiver(ReceiverType(current_class()), ident_pos); |
| 1255 params.AddFinalParameter(ident_pos, | 1264 params.AddFinalParameter(ident_pos, |
| 1256 &Symbols::Value(), | 1265 &Symbols::Value(), |
| 1257 &field_type); | 1266 &field_type); |
| 1258 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. | 1267 ASSERT(func.num_fixed_parameters() == 2); // receiver, value. |
| 1259 ASSERT(!func.HasOptionalParameters()); | 1268 ASSERT(!func.HasOptionalParameters()); |
| 1260 ASSERT(AbstractType::Handle(I, func.result_type()).IsVoidType()); | 1269 ASSERT(AbstractType::Handle(Z, func.result_type()).IsVoidType()); |
| 1261 | 1270 |
| 1262 // Build local scope for function and populate with the formal parameters. | 1271 // Build local scope for function and populate with the formal parameters. |
| 1263 OpenFunctionBlock(func); | 1272 OpenFunctionBlock(func); |
| 1264 AddFormalParamsToScope(¶ms, current_block_->scope); | 1273 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1265 | 1274 |
| 1266 LoadLocalNode* receiver = | 1275 LoadLocalNode* receiver = |
| 1267 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); | 1276 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(0)); |
| 1268 LoadLocalNode* value = | 1277 LoadLocalNode* value = |
| 1269 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); | 1278 new LoadLocalNode(ident_pos, current_block_->scope->VariableAt(1)); |
| 1270 | 1279 |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1291 // Build local scope for function and populate with the formal parameters. | 1300 // Build local scope for function and populate with the formal parameters. |
| 1292 OpenFunctionBlock(func); | 1301 OpenFunctionBlock(func); |
| 1293 AddFormalParamsToScope(¶ms, current_block_->scope); | 1302 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1294 | 1303 |
| 1295 // Receiver is local 0. | 1304 // Receiver is local 0. |
| 1296 LocalVariable* receiver = current_block_->scope->VariableAt(0); | 1305 LocalVariable* receiver = current_block_->scope->VariableAt(0); |
| 1297 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); | 1306 LoadLocalNode* load_receiver = new LoadLocalNode(ident_pos, receiver); |
| 1298 | 1307 |
| 1299 ClosureNode* closure = new ClosureNode( | 1308 ClosureNode* closure = new ClosureNode( |
| 1300 ident_pos, | 1309 ident_pos, |
| 1301 Function::ZoneHandle(I, func.extracted_method_closure()), | 1310 Function::ZoneHandle(Z, func.extracted_method_closure()), |
| 1302 load_receiver, | 1311 load_receiver, |
| 1303 NULL); | 1312 NULL); |
| 1304 | 1313 |
| 1305 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure); | 1314 ReturnNode* return_node = new ReturnNode(Scanner::kNoSourcePos, closure); |
| 1306 current_block_->statements->Add(return_node); | 1315 current_block_->statements->Add(return_node); |
| 1307 return CloseBlock(); | 1316 return CloseBlock(); |
| 1308 } | 1317 } |
| 1309 | 1318 |
| 1310 | 1319 |
| 1311 void Parser::BuildDispatcherScope(const Function& func, | 1320 void Parser::BuildDispatcherScope(const Function& func, |
| 1312 const ArgumentsDescriptor& desc, | 1321 const ArgumentsDescriptor& desc, |
| 1313 Array* default_values) { | 1322 Array* default_values) { |
| 1314 ParamList params; | 1323 ParamList params; |
| 1315 // Receiver first. | 1324 // Receiver first. |
| 1316 intptr_t token_pos = func.token_pos(); | 1325 intptr_t token_pos = func.token_pos(); |
| 1317 params.AddReceiver(ReceiverType(current_class()), token_pos); | 1326 params.AddReceiver(ReceiverType(current_class()), token_pos); |
| 1318 // Remaining positional parameters. | 1327 // Remaining positional parameters. |
| 1319 intptr_t i = 1; | 1328 intptr_t i = 1; |
| 1320 for (; i < desc.PositionalCount(); ++i) { | 1329 for (; i < desc.PositionalCount(); ++i) { |
| 1321 ParamDesc p; | 1330 ParamDesc p; |
| 1322 char name[64]; | 1331 char name[64]; |
| 1323 OS::SNPrint(name, 64, ":p%" Pd, i); | 1332 OS::SNPrint(name, 64, ":p%" Pd, i); |
| 1324 p.name = &String::ZoneHandle(I, Symbols::New(name)); | 1333 p.name = &String::ZoneHandle(Z, Symbols::New(name)); |
| 1325 p.type = &Type::ZoneHandle(I, Type::DynamicType()); | 1334 p.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 1326 params.parameters->Add(p); | 1335 params.parameters->Add(p); |
| 1327 params.num_fixed_parameters++; | 1336 params.num_fixed_parameters++; |
| 1328 } | 1337 } |
| 1329 ASSERT(desc.PositionalCount() == params.num_fixed_parameters); | 1338 ASSERT(desc.PositionalCount() == params.num_fixed_parameters); |
| 1330 | 1339 |
| 1331 // Named parameters. | 1340 // Named parameters. |
| 1332 for (; i < desc.Count(); ++i) { | 1341 for (; i < desc.Count(); ++i) { |
| 1333 ParamDesc p; | 1342 ParamDesc p; |
| 1334 intptr_t index = i - desc.PositionalCount(); | 1343 intptr_t index = i - desc.PositionalCount(); |
| 1335 p.name = &String::ZoneHandle(I, desc.NameAt(index)); | 1344 p.name = &String::ZoneHandle(Z, desc.NameAt(index)); |
| 1336 p.type = &Type::ZoneHandle(I, Type::DynamicType()); | 1345 p.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 1337 p.default_value = &Object::null_object(); | 1346 p.default_value = &Object::null_object(); |
| 1338 params.parameters->Add(p); | 1347 params.parameters->Add(p); |
| 1339 params.num_optional_parameters++; | 1348 params.num_optional_parameters++; |
| 1340 params.has_optional_named_parameters = true; | 1349 params.has_optional_named_parameters = true; |
| 1341 } | 1350 } |
| 1342 ASSERT(desc.NamedCount() == params.num_optional_parameters); | 1351 ASSERT(desc.NamedCount() == params.num_optional_parameters); |
| 1343 | 1352 |
| 1344 SetupDefaultsForOptionalParams(¶ms, default_values); | 1353 SetupDefaultsForOptionalParams(¶ms, default_values); |
| 1345 | 1354 |
| 1346 // Build local scope for function and populate with the formal parameters. | 1355 // Build local scope for function and populate with the formal parameters. |
| 1347 OpenFunctionBlock(func); | 1356 OpenFunctionBlock(func); |
| 1348 AddFormalParamsToScope(¶ms, current_block_->scope); | 1357 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 1349 } | 1358 } |
| 1350 | 1359 |
| 1351 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, | 1360 SequenceNode* Parser::ParseNoSuchMethodDispatcher(const Function& func, |
| 1352 Array* default_values) { | 1361 Array* default_values) { |
| 1353 TRACE_PARSER("ParseNoSuchMethodDispatcher"); | 1362 TRACE_PARSER("ParseNoSuchMethodDispatcher"); |
| 1354 | 1363 |
| 1355 ASSERT(func.IsNoSuchMethodDispatcher()); | 1364 ASSERT(func.IsNoSuchMethodDispatcher()); |
| 1356 intptr_t token_pos = func.token_pos(); | 1365 intptr_t token_pos = func.token_pos(); |
| 1357 ASSERT(func.token_pos() == 0); | 1366 ASSERT(func.token_pos() == 0); |
| 1358 ASSERT(current_class().raw() == func.Owner()); | 1367 ASSERT(current_class().raw() == func.Owner()); |
| 1359 | 1368 |
| 1360 ArgumentsDescriptor desc(Array::Handle(I, func.saved_args_desc())); | 1369 ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc())); |
| 1361 ASSERT(desc.Count() > 0); | 1370 ASSERT(desc.Count() > 0); |
| 1362 | 1371 |
| 1363 // Set up scope for this function. | 1372 // Set up scope for this function. |
| 1364 BuildDispatcherScope(func, desc, default_values); | 1373 BuildDispatcherScope(func, desc, default_values); |
| 1365 | 1374 |
| 1366 // Receiver is local 0. | 1375 // Receiver is local 0. |
| 1367 LocalScope* scope = current_block_->scope; | 1376 LocalScope* scope = current_block_->scope; |
| 1368 ArgumentListNode* func_args = new ArgumentListNode(token_pos); | 1377 ArgumentListNode* func_args = new ArgumentListNode(token_pos); |
| 1369 for (intptr_t i = 0; i < desc.Count(); ++i) { | 1378 for (intptr_t i = 0; i < desc.Count(); ++i) { |
| 1370 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1379 func_args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
| 1371 } | 1380 } |
| 1372 | 1381 |
| 1373 if (desc.NamedCount() > 0) { | 1382 if (desc.NamedCount() > 0) { |
| 1374 const Array& arg_names = | 1383 const Array& arg_names = |
| 1375 Array::ZoneHandle(I, Array::New(desc.NamedCount())); | 1384 Array::ZoneHandle(Z, Array::New(desc.NamedCount())); |
| 1376 for (intptr_t i = 0; i < arg_names.Length(); ++i) { | 1385 for (intptr_t i = 0; i < arg_names.Length(); ++i) { |
| 1377 arg_names.SetAt(i, String::Handle(I, desc.NameAt(i))); | 1386 arg_names.SetAt(i, String::Handle(Z, desc.NameAt(i))); |
| 1378 } | 1387 } |
| 1379 func_args->set_names(arg_names); | 1388 func_args->set_names(arg_names); |
| 1380 } | 1389 } |
| 1381 | 1390 |
| 1382 const String& func_name = String::ZoneHandle(I, func.name()); | 1391 const String& func_name = String::ZoneHandle(Z, func.name()); |
| 1383 ArgumentListNode* arguments = BuildNoSuchMethodArguments( | 1392 ArgumentListNode* arguments = BuildNoSuchMethodArguments( |
| 1384 token_pos, func_name, *func_args, NULL, false); | 1393 token_pos, func_name, *func_args, NULL, false); |
| 1385 const intptr_t kNumArguments = 2; // Receiver, InvocationMirror. | 1394 const intptr_t kNumArguments = 2; // Receiver, InvocationMirror. |
| 1386 ArgumentsDescriptor args_desc( | 1395 ArgumentsDescriptor args_desc( |
| 1387 Array::Handle(I, ArgumentsDescriptor::New(kNumArguments))); | 1396 Array::Handle(Z, ArgumentsDescriptor::New(kNumArguments))); |
| 1388 Function& no_such_method = Function::ZoneHandle(I, | 1397 Function& no_such_method = Function::ZoneHandle(Z, |
| 1389 Resolver::ResolveDynamicForReceiverClass(Class::Handle(I, func.Owner()), | 1398 Resolver::ResolveDynamicForReceiverClass(Class::Handle(Z, func.Owner()), |
| 1390 Symbols::NoSuchMethod(), | 1399 Symbols::NoSuchMethod(), |
| 1391 args_desc)); | 1400 args_desc)); |
| 1392 if (no_such_method.IsNull()) { | 1401 if (no_such_method.IsNull()) { |
| 1393 // If noSuchMethod(i) is not found, call Object:noSuchMethod. | 1402 // If noSuchMethod(i) is not found, call Object:noSuchMethod. |
| 1394 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( | 1403 no_such_method ^= Resolver::ResolveDynamicForReceiverClass( |
| 1395 Class::Handle(I, I->object_store()->object_class()), | 1404 Class::Handle(Z, I->object_store()->object_class()), |
| 1396 Symbols::NoSuchMethod(), | 1405 Symbols::NoSuchMethod(), |
| 1397 args_desc); | 1406 args_desc); |
| 1398 } | 1407 } |
| 1399 StaticCallNode* call = | 1408 StaticCallNode* call = |
| 1400 new StaticCallNode(token_pos, no_such_method, arguments); | 1409 new StaticCallNode(token_pos, no_such_method, arguments); |
| 1401 | 1410 |
| 1402 ReturnNode* return_node = new ReturnNode(token_pos, call); | 1411 ReturnNode* return_node = new ReturnNode(token_pos, call); |
| 1403 current_block_->statements->Add(return_node); | 1412 current_block_->statements->Add(return_node); |
| 1404 return CloseBlock(); | 1413 return CloseBlock(); |
| 1405 } | 1414 } |
| 1406 | 1415 |
| 1407 | 1416 |
| 1408 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, | 1417 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func, |
| 1409 Array* default_values) { | 1418 Array* default_values) { |
| 1410 TRACE_PARSER("ParseInvokeFieldDispatcher"); | 1419 TRACE_PARSER("ParseInvokeFieldDispatcher"); |
| 1411 | 1420 |
| 1412 ASSERT(func.IsInvokeFieldDispatcher()); | 1421 ASSERT(func.IsInvokeFieldDispatcher()); |
| 1413 intptr_t token_pos = func.token_pos(); | 1422 intptr_t token_pos = func.token_pos(); |
| 1414 ASSERT(func.token_pos() == 0); | 1423 ASSERT(func.token_pos() == 0); |
| 1415 ASSERT(current_class().raw() == func.Owner()); | 1424 ASSERT(current_class().raw() == func.Owner()); |
| 1416 | 1425 |
| 1417 const Array& args_desc = Array::Handle(I, func.saved_args_desc()); | 1426 const Array& args_desc = Array::Handle(Z, func.saved_args_desc()); |
| 1418 ArgumentsDescriptor desc(args_desc); | 1427 ArgumentsDescriptor desc(args_desc); |
| 1419 ASSERT(desc.Count() > 0); | 1428 ASSERT(desc.Count() > 0); |
| 1420 | 1429 |
| 1421 // Set up scope for this function. | 1430 // Set up scope for this function. |
| 1422 BuildDispatcherScope(func, desc, default_values); | 1431 BuildDispatcherScope(func, desc, default_values); |
| 1423 | 1432 |
| 1424 // Receiver is local 0. | 1433 // Receiver is local 0. |
| 1425 LocalScope* scope = current_block_->scope; | 1434 LocalScope* scope = current_block_->scope; |
| 1426 ArgumentListNode* no_args = new ArgumentListNode(token_pos); | 1435 ArgumentListNode* no_args = new ArgumentListNode(token_pos); |
| 1427 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0)); | 1436 LoadLocalNode* receiver = new LoadLocalNode(token_pos, scope->VariableAt(0)); |
| 1428 | 1437 |
| 1429 const String& name = String::Handle(I, func.name()); | 1438 const String& name = String::Handle(Z, func.name()); |
| 1430 const String& getter_name = String::ZoneHandle(I, | 1439 const String& getter_name = String::ZoneHandle(Z, |
| 1431 Symbols::New(String::Handle(I, Field::GetterName(name)))); | 1440 Symbols::New(String::Handle(Z, Field::GetterName(name)))); |
| 1432 InstanceCallNode* getter_call = new(I) InstanceCallNode( | 1441 InstanceCallNode* getter_call = new(Z) InstanceCallNode( |
| 1433 token_pos, receiver, getter_name, no_args); | 1442 token_pos, receiver, getter_name, no_args); |
| 1434 | 1443 |
| 1435 // Pass arguments 1..n to the closure call. | 1444 // Pass arguments 1..n to the closure call. |
| 1436 ArgumentListNode* args = new(I) ArgumentListNode(token_pos); | 1445 ArgumentListNode* args = new(Z) ArgumentListNode(token_pos); |
| 1437 const Array& names = Array::Handle( | 1446 const Array& names = Array::Handle( |
| 1438 I, Array::New(desc.NamedCount(), Heap::kOld)); | 1447 Z, Array::New(desc.NamedCount(), Heap::kOld)); |
| 1439 // Positional parameters. | 1448 // Positional parameters. |
| 1440 intptr_t i = 1; | 1449 intptr_t i = 1; |
| 1441 for (; i < desc.PositionalCount(); ++i) { | 1450 for (; i < desc.PositionalCount(); ++i) { |
| 1442 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); | 1451 args->Add(new LoadLocalNode(token_pos, scope->VariableAt(i))); |
| 1443 } | 1452 } |
| 1444 // Named parameters. | 1453 // Named parameters. |
| 1445 for (; i < desc.Count(); i++) { | 1454 for (; i < desc.Count(); i++) { |
| 1446 args->Add(new(I) LoadLocalNode(token_pos, scope->VariableAt(i))); | 1455 args->Add(new(Z) LoadLocalNode(token_pos, scope->VariableAt(i))); |
| 1447 intptr_t index = i - desc.PositionalCount(); | 1456 intptr_t index = i - desc.PositionalCount(); |
| 1448 names.SetAt(index, String::Handle(I, desc.NameAt(index))); | 1457 names.SetAt(index, String::Handle(Z, desc.NameAt(index))); |
| 1449 } | 1458 } |
| 1450 args->set_names(names); | 1459 args->set_names(names); |
| 1451 | 1460 |
| 1452 const Class& owner = Class::Handle(I, func.Owner()); | 1461 const Class& owner = Class::Handle(Z, func.Owner()); |
| 1453 ASSERT(!owner.IsNull()); | 1462 ASSERT(!owner.IsNull()); |
| 1454 AstNode* result = NULL; | 1463 AstNode* result = NULL; |
| 1455 if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) { | 1464 if (owner.IsSignatureClass() && name.Equals(Symbols::Call())) { |
| 1456 result = new ClosureCallNode(token_pos, getter_call, args); | 1465 result = new ClosureCallNode(token_pos, getter_call, args); |
| 1457 } else { | 1466 } else { |
| 1458 result = BuildClosureCall(token_pos, getter_call, args); | 1467 result = BuildClosureCall(token_pos, getter_call, args); |
| 1459 } | 1468 } |
| 1460 | 1469 |
| 1461 ReturnNode* return_node = new ReturnNode(token_pos, result); | 1470 ReturnNode* return_node = new ReturnNode(token_pos, result); |
| 1462 current_block_->statements->Add(return_node); | 1471 current_block_->statements->Add(return_node); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1522 | 1531 |
| 1523 void Parser::ParseFormalParameter(bool allow_explicit_default_value, | 1532 void Parser::ParseFormalParameter(bool allow_explicit_default_value, |
| 1524 bool evaluate_metadata, | 1533 bool evaluate_metadata, |
| 1525 ParamList* params) { | 1534 ParamList* params) { |
| 1526 TRACE_PARSER("ParseFormalParameter"); | 1535 TRACE_PARSER("ParseFormalParameter"); |
| 1527 ParamDesc parameter; | 1536 ParamDesc parameter; |
| 1528 bool var_seen = false; | 1537 bool var_seen = false; |
| 1529 bool this_seen = false; | 1538 bool this_seen = false; |
| 1530 | 1539 |
| 1531 if (evaluate_metadata && (CurrentToken() == Token::kAT)) { | 1540 if (evaluate_metadata && (CurrentToken() == Token::kAT)) { |
| 1532 parameter.metadata = &Array::ZoneHandle(I, EvaluateMetadata()); | 1541 parameter.metadata = &Array::ZoneHandle(Z, EvaluateMetadata()); |
| 1533 } else { | 1542 } else { |
| 1534 SkipMetadata(); | 1543 SkipMetadata(); |
| 1535 } | 1544 } |
| 1536 | 1545 |
| 1537 if (CurrentToken() == Token::kFINAL) { | 1546 if (CurrentToken() == Token::kFINAL) { |
| 1538 ConsumeToken(); | 1547 ConsumeToken(); |
| 1539 parameter.is_final = true; | 1548 parameter.is_final = true; |
| 1540 } else if (CurrentToken() == Token::kVAR) { | 1549 } else if (CurrentToken() == Token::kVAR) { |
| 1541 ConsumeToken(); | 1550 ConsumeToken(); |
| 1542 var_seen = true; | 1551 var_seen = true; |
| 1543 // The parameter type is the 'dynamic' type. | 1552 // The parameter type is the 'dynamic' type. |
| 1544 // If this is an initializing formal, its type will be set to the type of | 1553 // If this is an initializing formal, its type will be set to the type of |
| 1545 // the respective field when the constructor is fully parsed. | 1554 // the respective field when the constructor is fully parsed. |
| 1546 parameter.type = &Type::ZoneHandle(I, Type::DynamicType()); | 1555 parameter.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 1547 } | 1556 } |
| 1548 if (CurrentToken() == Token::kTHIS) { | 1557 if (CurrentToken() == Token::kTHIS) { |
| 1549 ConsumeToken(); | 1558 ConsumeToken(); |
| 1550 ExpectToken(Token::kPERIOD); | 1559 ExpectToken(Token::kPERIOD); |
| 1551 this_seen = true; | 1560 this_seen = true; |
| 1552 parameter.is_field_initializer = true; | 1561 parameter.is_field_initializer = true; |
| 1553 } | 1562 } |
| 1554 if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) { | 1563 if ((parameter.type == NULL) && (CurrentToken() == Token::kVOID)) { |
| 1555 ConsumeToken(); | 1564 ConsumeToken(); |
| 1556 // This must later be changed to a closure type if we recognize | 1565 // This must later be changed to a closure type if we recognize |
| 1557 // a closure/function type parameter. We check this at the end | 1566 // a closure/function type parameter. We check this at the end |
| 1558 // of ParseFormalParameter. | 1567 // of ParseFormalParameter. |
| 1559 parameter.type = &Type::ZoneHandle(I, Type::VoidType()); | 1568 parameter.type = &Type::ZoneHandle(Z, Type::VoidType()); |
| 1560 } | 1569 } |
| 1561 if (parameter.type == NULL) { | 1570 if (parameter.type == NULL) { |
| 1562 // At this point, we must see an identifier for the type or the | 1571 // At this point, we must see an identifier for the type or the |
| 1563 // function parameter. | 1572 // function parameter. |
| 1564 if (!IsIdentifier()) { | 1573 if (!IsIdentifier()) { |
| 1565 ReportError("parameter name or type expected"); | 1574 ReportError("parameter name or type expected"); |
| 1566 } | 1575 } |
| 1567 // We have not seen a parameter type yet, so we check if the next | 1576 // We have not seen a parameter type yet, so we check if the next |
| 1568 // identifier could represent a type before parsing it. | 1577 // identifier could represent a type before parsing it. |
| 1569 Token::Kind follower = LookaheadToken(1); | 1578 Token::Kind follower = LookaheadToken(1); |
| 1570 // We have an identifier followed by a 'follower' token. | 1579 // We have an identifier followed by a 'follower' token. |
| 1571 // We either parse a type or assume that no type is specified. | 1580 // We either parse a type or assume that no type is specified. |
| 1572 if ((follower == Token::kLT) || // Parameterized type. | 1581 if ((follower == Token::kLT) || // Parameterized type. |
| 1573 (follower == Token::kPERIOD) || // Qualified class name of type. | 1582 (follower == Token::kPERIOD) || // Qualified class name of type. |
| 1574 Token::IsIdentifier(follower) || // Parameter name following a type. | 1583 Token::IsIdentifier(follower) || // Parameter name following a type. |
| 1575 (follower == Token::kTHIS)) { // Field parameter following a type. | 1584 (follower == Token::kTHIS)) { // Field parameter following a type. |
| 1576 // The types of formal parameters are never ignored, even in unchecked | 1585 // The types of formal parameters are never ignored, even in unchecked |
| 1577 // mode, because they are part of the function type of closurized | 1586 // mode, because they are part of the function type of closurized |
| 1578 // functions appearing in type tests with typedefs. | 1587 // functions appearing in type tests with typedefs. |
| 1579 parameter.has_explicit_type = true; | 1588 parameter.has_explicit_type = true; |
| 1580 parameter.type = &AbstractType::ZoneHandle(I, | 1589 parameter.type = &AbstractType::ZoneHandle(Z, |
| 1581 ParseType(is_top_level_ ? ClassFinalizer::kResolveTypeParameters : | 1590 ParseType(is_top_level_ ? ClassFinalizer::kResolveTypeParameters : |
| 1582 ClassFinalizer::kCanonicalize)); | 1591 ClassFinalizer::kCanonicalize)); |
| 1583 } else { | 1592 } else { |
| 1584 // If this is an initializing formal, its type will be set to the type of | 1593 // If this is an initializing formal, its type will be set to the type of |
| 1585 // the respective field when the constructor is fully parsed. | 1594 // the respective field when the constructor is fully parsed. |
| 1586 parameter.type = &Type::ZoneHandle(I, Type::DynamicType()); | 1595 parameter.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 1587 } | 1596 } |
| 1588 } | 1597 } |
| 1589 if (!this_seen && (CurrentToken() == Token::kTHIS)) { | 1598 if (!this_seen && (CurrentToken() == Token::kTHIS)) { |
| 1590 ConsumeToken(); | 1599 ConsumeToken(); |
| 1591 ExpectToken(Token::kPERIOD); | 1600 ExpectToken(Token::kPERIOD); |
| 1592 this_seen = true; | 1601 this_seen = true; |
| 1593 parameter.is_field_initializer = true; | 1602 parameter.is_field_initializer = true; |
| 1594 } | 1603 } |
| 1595 | 1604 |
| 1596 // At this point, we must see an identifier for the parameter name. | 1605 // At this point, we must see an identifier for the parameter name. |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 1616 } | 1625 } |
| 1617 } | 1626 } |
| 1618 | 1627 |
| 1619 if (CurrentToken() == Token::kLPAREN) { | 1628 if (CurrentToken() == Token::kLPAREN) { |
| 1620 // This parameter is probably a closure. If we saw the keyword 'var' | 1629 // This parameter is probably a closure. If we saw the keyword 'var' |
| 1621 // or 'final', a closure is not legal here and we ignore the | 1630 // or 'final', a closure is not legal here and we ignore the |
| 1622 // opening parens. | 1631 // opening parens. |
| 1623 if (!var_seen && !parameter.is_final) { | 1632 if (!var_seen && !parameter.is_final) { |
| 1624 // The parsed parameter type is actually the function result type. | 1633 // The parsed parameter type is actually the function result type. |
| 1625 const AbstractType& result_type = | 1634 const AbstractType& result_type = |
| 1626 AbstractType::Handle(I, parameter.type->raw()); | 1635 AbstractType::Handle(Z, parameter.type->raw()); |
| 1627 | 1636 |
| 1628 // Finish parsing the function type parameter. | 1637 // Finish parsing the function type parameter. |
| 1629 ParamList func_params; | 1638 ParamList func_params; |
| 1630 | 1639 |
| 1631 // Add implicit closure object parameter. | 1640 // Add implicit closure object parameter. |
| 1632 func_params.AddFinalParameter( | 1641 func_params.AddFinalParameter( |
| 1633 TokenPos(), | 1642 TokenPos(), |
| 1634 &Symbols::ClosureParameter(), | 1643 &Symbols::ClosureParameter(), |
| 1635 &Type::ZoneHandle(I, Type::DynamicType())); | 1644 &Type::ZoneHandle(Z, Type::DynamicType())); |
| 1636 | 1645 |
| 1637 const bool no_explicit_default_values = false; | 1646 const bool no_explicit_default_values = false; |
| 1638 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 1647 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
| 1639 | 1648 |
| 1640 // The field 'is_static' has no meaning for signature functions. | 1649 // The field 'is_static' has no meaning for signature functions. |
| 1641 const Function& signature_function = Function::Handle(I, | 1650 const Function& signature_function = Function::Handle(Z, |
| 1642 Function::New(*parameter.name, | 1651 Function::New(*parameter.name, |
| 1643 RawFunction::kSignatureFunction, | 1652 RawFunction::kSignatureFunction, |
| 1644 /* is_static = */ false, | 1653 /* is_static = */ false, |
| 1645 /* is_const = */ false, | 1654 /* is_const = */ false, |
| 1646 /* is_abstract = */ false, | 1655 /* is_abstract = */ false, |
| 1647 /* is_external = */ false, | 1656 /* is_external = */ false, |
| 1648 /* is_native = */ false, | 1657 /* is_native = */ false, |
| 1649 current_class(), | 1658 current_class(), |
| 1650 parameter.name_pos)); | 1659 parameter.name_pos)); |
| 1651 signature_function.set_result_type(result_type); | 1660 signature_function.set_result_type(result_type); |
| 1652 signature_function.set_is_debuggable(false); | 1661 signature_function.set_is_debuggable(false); |
| 1653 AddFormalParamsToFunction(&func_params, signature_function); | 1662 AddFormalParamsToFunction(&func_params, signature_function); |
| 1654 const String& signature = String::Handle(I, | 1663 const String& signature = String::Handle(Z, |
| 1655 signature_function.Signature()); | 1664 signature_function.Signature()); |
| 1656 // Lookup the signature class, i.e. the class whose name is the signature. | 1665 // Lookup the signature class, i.e. the class whose name is the signature. |
| 1657 // We only lookup in the current library, but not in its imports, and only | 1666 // We only lookup in the current library, but not in its imports, and only |
| 1658 // create a new canonical signature class if it does not exist yet. | 1667 // create a new canonical signature class if it does not exist yet. |
| 1659 Class& signature_class = Class::ZoneHandle(I, | 1668 Class& signature_class = Class::ZoneHandle(Z, |
| 1660 library_.LookupLocalClass(signature)); | 1669 library_.LookupLocalClass(signature)); |
| 1661 if (signature_class.IsNull()) { | 1670 if (signature_class.IsNull()) { |
| 1662 signature_class = Class::NewSignatureClass(signature, | 1671 signature_class = Class::NewSignatureClass(signature, |
| 1663 signature_function, | 1672 signature_function, |
| 1664 script_, | 1673 script_, |
| 1665 parameter.name_pos); | 1674 parameter.name_pos); |
| 1666 // Record the function signature class in the current library, unless | 1675 // Record the function signature class in the current library, unless |
| 1667 // we are currently skipping a formal parameter list, in which case | 1676 // we are currently skipping a formal parameter list, in which case |
| 1668 // the signature class could remain unfinalized. | 1677 // the signature class could remain unfinalized. |
| 1669 if (!params->skipped) { | 1678 if (!params->skipped) { |
| 1670 library_.AddClass(signature_class); | 1679 library_.AddClass(signature_class); |
| 1671 } | 1680 } |
| 1672 } else { | 1681 } else { |
| 1673 signature_function.set_signature_class(signature_class); | 1682 signature_function.set_signature_class(signature_class); |
| 1674 } | 1683 } |
| 1675 ASSERT(signature_function.signature_class() == signature_class.raw()); | 1684 ASSERT(signature_function.signature_class() == signature_class.raw()); |
| 1676 Type& signature_type = | 1685 Type& signature_type = |
| 1677 Type::ZoneHandle(I, signature_class.SignatureType()); | 1686 Type::ZoneHandle(Z, signature_class.SignatureType()); |
| 1678 if (!is_top_level_ && !signature_type.IsFinalized()) { | 1687 if (!is_top_level_ && !signature_type.IsFinalized()) { |
| 1679 signature_type ^= ClassFinalizer::FinalizeType( | 1688 signature_type ^= ClassFinalizer::FinalizeType( |
| 1680 signature_class, signature_type, ClassFinalizer::kCanonicalize); | 1689 signature_class, signature_type, ClassFinalizer::kCanonicalize); |
| 1681 } | 1690 } |
| 1682 // A signature type itself cannot be malformed or malbounded, only its | 1691 // A signature type itself cannot be malformed or malbounded, only its |
| 1683 // signature function's result type or parameter types may be. | 1692 // signature function's result type or parameter types may be. |
| 1684 ASSERT(!signature_type.IsMalformed()); | 1693 ASSERT(!signature_type.IsMalformed()); |
| 1685 ASSERT(!signature_type.IsMalbounded()); | 1694 ASSERT(!signature_type.IsMalbounded()); |
| 1686 // The type of the parameter is now the signature type. | 1695 // The type of the parameter is now the signature type. |
| 1687 parameter.type = &signature_type; | 1696 parameter.type = &signature_type; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1807 | 1816 |
| 1808 // Resolve and return the dynamic function of the given name in the superclass. | 1817 // Resolve and return the dynamic function of the given name in the superclass. |
| 1809 // If it is not found, and resolve_getter is true, try to resolve a getter of | 1818 // If it is not found, and resolve_getter is true, try to resolve a getter of |
| 1810 // the same name. If it is still not found, return noSuchMethod and | 1819 // the same name. If it is still not found, return noSuchMethod and |
| 1811 // set is_no_such_method to true.. | 1820 // set is_no_such_method to true.. |
| 1812 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, | 1821 RawFunction* Parser::GetSuperFunction(intptr_t token_pos, |
| 1813 const String& name, | 1822 const String& name, |
| 1814 ArgumentListNode* arguments, | 1823 ArgumentListNode* arguments, |
| 1815 bool resolve_getter, | 1824 bool resolve_getter, |
| 1816 bool* is_no_such_method) { | 1825 bool* is_no_such_method) { |
| 1817 const Class& super_class = Class::Handle(I, current_class().SuperClass()); | 1826 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
| 1818 if (super_class.IsNull()) { | 1827 if (super_class.IsNull()) { |
| 1819 ReportError(token_pos, "class '%s' does not have a superclass", | 1828 ReportError(token_pos, "class '%s' does not have a superclass", |
| 1820 String::Handle(I, current_class().Name()).ToCString()); | 1829 String::Handle(Z, current_class().Name()).ToCString()); |
| 1821 } | 1830 } |
| 1822 Function& super_func = Function::Handle(I, | 1831 Function& super_func = Function::Handle(Z, |
| 1823 Resolver::ResolveDynamicAnyArgs(super_class, name)); | 1832 Resolver::ResolveDynamicAnyArgs(super_class, name)); |
| 1824 if (!super_func.IsNull() && | 1833 if (!super_func.IsNull() && |
| 1825 !super_func.AreValidArguments(arguments->length(), | 1834 !super_func.AreValidArguments(arguments->length(), |
| 1826 arguments->names(), | 1835 arguments->names(), |
| 1827 NULL)) { | 1836 NULL)) { |
| 1828 super_func = Function::null(); | 1837 super_func = Function::null(); |
| 1829 } else if (super_func.IsNull() && resolve_getter) { | 1838 } else if (super_func.IsNull() && resolve_getter) { |
| 1830 const String& getter_name = String::ZoneHandle(I, Field::GetterName(name)); | 1839 const String& getter_name = String::ZoneHandle(Z, Field::GetterName(name)); |
| 1831 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); | 1840 super_func = Resolver::ResolveDynamicAnyArgs(super_class, getter_name); |
| 1832 ASSERT(super_func.IsNull() || | 1841 ASSERT(super_func.IsNull() || |
| 1833 (super_func.kind() != RawFunction::kImplicitStaticFinalGetter)); | 1842 (super_func.kind() != RawFunction::kImplicitStaticFinalGetter)); |
| 1834 } | 1843 } |
| 1835 if (super_func.IsNull()) { | 1844 if (super_func.IsNull()) { |
| 1836 super_func = | 1845 super_func = |
| 1837 Resolver::ResolveDynamicAnyArgs(super_class, Symbols::NoSuchMethod()); | 1846 Resolver::ResolveDynamicAnyArgs(super_class, Symbols::NoSuchMethod()); |
| 1838 ASSERT(!super_func.IsNull()); | 1847 ASSERT(!super_func.IsNull()); |
| 1839 *is_no_such_method = true; | 1848 *is_no_such_method = true; |
| 1840 } else { | 1849 } else { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1919 const intptr_t supercall_pos = TokenPos(); | 1928 const intptr_t supercall_pos = TokenPos(); |
| 1920 | 1929 |
| 1921 // 'this' parameter is the first argument to super call. | 1930 // 'this' parameter is the first argument to super call. |
| 1922 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 1931 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 1923 AstNode* receiver = LoadReceiver(supercall_pos); | 1932 AstNode* receiver = LoadReceiver(supercall_pos); |
| 1924 arguments->Add(receiver); | 1933 arguments->Add(receiver); |
| 1925 ParseActualParameters(arguments, kAllowConst); | 1934 ParseActualParameters(arguments, kAllowConst); |
| 1926 | 1935 |
| 1927 const bool kResolveGetter = true; | 1936 const bool kResolveGetter = true; |
| 1928 bool is_no_such_method = false; | 1937 bool is_no_such_method = false; |
| 1929 const Function& super_function = Function::ZoneHandle(I, | 1938 const Function& super_function = Function::ZoneHandle(Z, |
| 1930 GetSuperFunction(supercall_pos, | 1939 GetSuperFunction(supercall_pos, |
| 1931 function_name, | 1940 function_name, |
| 1932 arguments, | 1941 arguments, |
| 1933 kResolveGetter, | 1942 kResolveGetter, |
| 1934 &is_no_such_method)); | 1943 &is_no_such_method)); |
| 1935 if (super_function.IsGetterFunction() || | 1944 if (super_function.IsGetterFunction() || |
| 1936 super_function.IsImplicitGetterFunction()) { | 1945 super_function.IsImplicitGetterFunction()) { |
| 1937 const Class& super_class = | 1946 const Class& super_class = |
| 1938 Class::ZoneHandle(I, current_class().SuperClass()); | 1947 Class::ZoneHandle(Z, current_class().SuperClass()); |
| 1939 AstNode* closure = new StaticGetterNode(supercall_pos, | 1948 AstNode* closure = new StaticGetterNode(supercall_pos, |
| 1940 LoadReceiver(supercall_pos), | 1949 LoadReceiver(supercall_pos), |
| 1941 /* is_super_getter */ true, | 1950 /* is_super_getter */ true, |
| 1942 super_class, | 1951 super_class, |
| 1943 function_name); | 1952 function_name); |
| 1944 // 'this' is not passed as parameter to the closure. | 1953 // 'this' is not passed as parameter to the closure. |
| 1945 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); | 1954 ArgumentListNode* closure_arguments = new ArgumentListNode(supercall_pos); |
| 1946 for (int i = 1; i < arguments->length(); i++) { | 1955 for (int i = 1; i < arguments->length(); i++) { |
| 1947 closure_arguments->Add(arguments->NodeAt(i)); | 1956 closure_arguments->Add(arguments->NodeAt(i)); |
| 1948 } | 1957 } |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1963 | 1972 |
| 1964 | 1973 |
| 1965 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { | 1974 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) { |
| 1966 ASSERT(super->IsSuper()); | 1975 ASSERT(super->IsSuper()); |
| 1967 AstNode* super_op = NULL; | 1976 AstNode* super_op = NULL; |
| 1968 const intptr_t super_pos = super->token_pos(); | 1977 const intptr_t super_pos = super->token_pos(); |
| 1969 if ((op == Token::kNEGATE) || | 1978 if ((op == Token::kNEGATE) || |
| 1970 (op == Token::kBIT_NOT)) { | 1979 (op == Token::kBIT_NOT)) { |
| 1971 // Resolve the operator function in the superclass. | 1980 // Resolve the operator function in the superclass. |
| 1972 const String& operator_function_name = | 1981 const String& operator_function_name = |
| 1973 String::ZoneHandle(I, Symbols::New(Token::Str(op))); | 1982 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); |
| 1974 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); | 1983 ArgumentListNode* op_arguments = new ArgumentListNode(super_pos); |
| 1975 AstNode* receiver = LoadReceiver(super_pos); | 1984 AstNode* receiver = LoadReceiver(super_pos); |
| 1976 op_arguments->Add(receiver); | 1985 op_arguments->Add(receiver); |
| 1977 const bool kResolveGetter = false; | 1986 const bool kResolveGetter = false; |
| 1978 bool is_no_such_method = false; | 1987 bool is_no_such_method = false; |
| 1979 const Function& super_operator = Function::ZoneHandle(I, | 1988 const Function& super_operator = Function::ZoneHandle(Z, |
| 1980 GetSuperFunction(super_pos, | 1989 GetSuperFunction(super_pos, |
| 1981 operator_function_name, | 1990 operator_function_name, |
| 1982 op_arguments, | 1991 op_arguments, |
| 1983 kResolveGetter, | 1992 kResolveGetter, |
| 1984 &is_no_such_method)); | 1993 &is_no_such_method)); |
| 1985 if (is_no_such_method) { | 1994 if (is_no_such_method) { |
| 1986 op_arguments = BuildNoSuchMethodArguments( | 1995 op_arguments = BuildNoSuchMethodArguments( |
| 1987 super_pos, operator_function_name, *op_arguments, NULL, true); | 1996 super_pos, operator_function_name, *op_arguments, NULL, true); |
| 1988 } | 1997 } |
| 1989 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); | 1998 super_op = new StaticCallNode(super_pos, super_operator, op_arguments); |
| 1990 } else { | 1999 } else { |
| 1991 ReportError(super_pos, "illegal super operator call"); | 2000 ReportError(super_pos, "illegal super operator call"); |
| 1992 } | 2001 } |
| 1993 return super_op; | 2002 return super_op; |
| 1994 } | 2003 } |
| 1995 | 2004 |
| 1996 | 2005 |
| 1997 AstNode* Parser::ParseSuperOperator() { | 2006 AstNode* Parser::ParseSuperOperator() { |
| 1998 TRACE_PARSER("ParseSuperOperator"); | 2007 TRACE_PARSER("ParseSuperOperator"); |
| 1999 AstNode* super_op = NULL; | 2008 AstNode* super_op = NULL; |
| 2000 const intptr_t operator_pos = TokenPos(); | 2009 const intptr_t operator_pos = TokenPos(); |
| 2001 | 2010 |
| 2002 if (CurrentToken() == Token::kLBRACK) { | 2011 if (CurrentToken() == Token::kLBRACK) { |
| 2003 ConsumeToken(); | 2012 ConsumeToken(); |
| 2004 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2013 AstNode* index_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2005 ExpectToken(Token::kRBRACK); | 2014 ExpectToken(Token::kRBRACK); |
| 2006 AstNode* receiver = LoadReceiver(operator_pos); | 2015 AstNode* receiver = LoadReceiver(operator_pos); |
| 2007 const Class& super_class = | 2016 const Class& super_class = |
| 2008 Class::ZoneHandle(I, current_class().SuperClass()); | 2017 Class::ZoneHandle(Z, current_class().SuperClass()); |
| 2009 ASSERT(!super_class.IsNull()); | 2018 ASSERT(!super_class.IsNull()); |
| 2010 super_op = | 2019 super_op = |
| 2011 new LoadIndexedNode(operator_pos, receiver, index_expr, super_class); | 2020 new LoadIndexedNode(operator_pos, receiver, index_expr, super_class); |
| 2012 } else { | 2021 } else { |
| 2013 ASSERT(Token::CanBeOverloaded(CurrentToken()) || | 2022 ASSERT(Token::CanBeOverloaded(CurrentToken()) || |
| 2014 (CurrentToken() == Token::kNE)); | 2023 (CurrentToken() == Token::kNE)); |
| 2015 Token::Kind op = CurrentToken(); | 2024 Token::Kind op = CurrentToken(); |
| 2016 ConsumeToken(); | 2025 ConsumeToken(); |
| 2017 | 2026 |
| 2018 bool negate_result = false; | 2027 bool negate_result = false; |
| 2019 if (op == Token::kNE) { | 2028 if (op == Token::kNE) { |
| 2020 op = Token::kEQ; | 2029 op = Token::kEQ; |
| 2021 negate_result = true; | 2030 negate_result = true; |
| 2022 } | 2031 } |
| 2023 | 2032 |
| 2024 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kEQ)); | 2033 ASSERT(Token::Precedence(op) >= Token::Precedence(Token::kEQ)); |
| 2025 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); | 2034 AstNode* other_operand = ParseBinaryExpr(Token::Precedence(op) + 1); |
| 2026 | 2035 |
| 2027 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); | 2036 ArgumentListNode* op_arguments = new ArgumentListNode(operator_pos); |
| 2028 AstNode* receiver = LoadReceiver(operator_pos); | 2037 AstNode* receiver = LoadReceiver(operator_pos); |
| 2029 op_arguments->Add(receiver); | 2038 op_arguments->Add(receiver); |
| 2030 op_arguments->Add(other_operand); | 2039 op_arguments->Add(other_operand); |
| 2031 | 2040 |
| 2032 // Resolve the operator function in the superclass. | 2041 // Resolve the operator function in the superclass. |
| 2033 const String& operator_function_name = | 2042 const String& operator_function_name = |
| 2034 String::ZoneHandle(I, Symbols::New(Token::Str(op))); | 2043 String::ZoneHandle(Z, Symbols::New(Token::Str(op))); |
| 2035 const bool kResolveGetter = false; | 2044 const bool kResolveGetter = false; |
| 2036 bool is_no_such_method = false; | 2045 bool is_no_such_method = false; |
| 2037 const Function& super_operator = Function::ZoneHandle(I, | 2046 const Function& super_operator = Function::ZoneHandle(Z, |
| 2038 GetSuperFunction(operator_pos, | 2047 GetSuperFunction(operator_pos, |
| 2039 operator_function_name, | 2048 operator_function_name, |
| 2040 op_arguments, | 2049 op_arguments, |
| 2041 kResolveGetter, | 2050 kResolveGetter, |
| 2042 &is_no_such_method)); | 2051 &is_no_such_method)); |
| 2043 if (is_no_such_method) { | 2052 if (is_no_such_method) { |
| 2044 op_arguments = BuildNoSuchMethodArguments( | 2053 op_arguments = BuildNoSuchMethodArguments( |
| 2045 operator_pos, operator_function_name, *op_arguments, NULL, true); | 2054 operator_pos, operator_function_name, *op_arguments, NULL, true); |
| 2046 } | 2055 } |
| 2047 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); | 2056 super_op = new StaticCallNode(operator_pos, super_operator, op_arguments); |
| 2048 if (negate_result) { | 2057 if (negate_result) { |
| 2049 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); | 2058 super_op = new UnaryOpNode(operator_pos, Token::kNOT, super_op); |
| 2050 } | 2059 } |
| 2051 } | 2060 } |
| 2052 return super_op; | 2061 return super_op; |
| 2053 } | 2062 } |
| 2054 | 2063 |
| 2055 | 2064 |
| 2056 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, | 2065 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func, |
| 2057 intptr_t token_pos, | 2066 intptr_t token_pos, |
| 2058 AstNode* receiver) { | 2067 AstNode* receiver) { |
| 2059 Function& implicit_closure_function = | 2068 Function& implicit_closure_function = |
| 2060 Function::ZoneHandle(I, func.ImplicitClosureFunction()); | 2069 Function::ZoneHandle(Z, func.ImplicitClosureFunction()); |
| 2061 if (receiver != NULL) { | 2070 if (receiver != NULL) { |
| 2062 // If we create an implicit instance closure from inside a closure of a | 2071 // If we create an implicit instance closure from inside a closure of a |
| 2063 // parameterized class, make sure that the receiver is captured as | 2072 // parameterized class, make sure that the receiver is captured as |
| 2064 // instantiator. | 2073 // instantiator. |
| 2065 if (current_block_->scope->function_level() > 0) { | 2074 if (current_block_->scope->function_level() > 0) { |
| 2066 const Class& signature_class = Class::Handle(I, | 2075 const Class& signature_class = Class::Handle(Z, |
| 2067 implicit_closure_function.signature_class()); | 2076 implicit_closure_function.signature_class()); |
| 2068 if (signature_class.NumTypeParameters() > 0) { | 2077 if (signature_class.NumTypeParameters() > 0) { |
| 2069 CaptureInstantiator(); | 2078 CaptureInstantiator(); |
| 2070 } | 2079 } |
| 2071 } | 2080 } |
| 2072 } | 2081 } |
| 2073 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); | 2082 return new ClosureNode(token_pos, implicit_closure_function, receiver, NULL); |
| 2074 } | 2083 } |
| 2075 | 2084 |
| 2076 | 2085 |
| 2077 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, | 2086 AstNode* Parser::ParseSuperFieldAccess(const String& field_name, |
| 2078 intptr_t field_pos) { | 2087 intptr_t field_pos) { |
| 2079 TRACE_PARSER("ParseSuperFieldAccess"); | 2088 TRACE_PARSER("ParseSuperFieldAccess"); |
| 2080 const Class& super_class = Class::ZoneHandle(I, current_class().SuperClass()); | 2089 const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass()); |
| 2081 if (super_class.IsNull()) { | 2090 if (super_class.IsNull()) { |
| 2082 ReportError("class '%s' does not have a superclass", | 2091 ReportError("class '%s' does not have a superclass", |
| 2083 String::Handle(I, current_class().Name()).ToCString()); | 2092 String::Handle(Z, current_class().Name()).ToCString()); |
| 2084 } | 2093 } |
| 2085 AstNode* implicit_argument = LoadReceiver(field_pos); | 2094 AstNode* implicit_argument = LoadReceiver(field_pos); |
| 2086 | 2095 |
| 2087 const String& getter_name = | 2096 const String& getter_name = |
| 2088 String::ZoneHandle(I, Field::GetterName(field_name)); | 2097 String::ZoneHandle(Z, Field::GetterName(field_name)); |
| 2089 const Function& super_getter = Function::ZoneHandle(I, | 2098 const Function& super_getter = Function::ZoneHandle(Z, |
| 2090 Resolver::ResolveDynamicAnyArgs(super_class, getter_name)); | 2099 Resolver::ResolveDynamicAnyArgs(super_class, getter_name)); |
| 2091 if (super_getter.IsNull()) { | 2100 if (super_getter.IsNull()) { |
| 2092 const String& setter_name = | 2101 const String& setter_name = |
| 2093 String::ZoneHandle(I, Field::SetterName(field_name)); | 2102 String::ZoneHandle(Z, Field::SetterName(field_name)); |
| 2094 const Function& super_setter = Function::ZoneHandle(I, | 2103 const Function& super_setter = Function::ZoneHandle(Z, |
| 2095 Resolver::ResolveDynamicAnyArgs(super_class, setter_name)); | 2104 Resolver::ResolveDynamicAnyArgs(super_class, setter_name)); |
| 2096 if (super_setter.IsNull()) { | 2105 if (super_setter.IsNull()) { |
| 2097 // Check if this is an access to an implicit closure using 'super'. | 2106 // Check if this is an access to an implicit closure using 'super'. |
| 2098 // If a function exists of the specified field_name then try | 2107 // If a function exists of the specified field_name then try |
| 2099 // accessing it as a getter, at runtime we will handle this by | 2108 // accessing it as a getter, at runtime we will handle this by |
| 2100 // creating an implicit closure of the function and returning it. | 2109 // creating an implicit closure of the function and returning it. |
| 2101 const Function& super_function = Function::ZoneHandle(I, | 2110 const Function& super_function = Function::ZoneHandle(Z, |
| 2102 Resolver::ResolveDynamicAnyArgs(super_class, field_name)); | 2111 Resolver::ResolveDynamicAnyArgs(super_class, field_name)); |
| 2103 if (!super_function.IsNull()) { | 2112 if (!super_function.IsNull()) { |
| 2104 // In case CreateAssignmentNode is called later on this | 2113 // In case CreateAssignmentNode is called later on this |
| 2105 // CreateImplicitClosureNode, it will be replaced by a StaticSetterNode. | 2114 // CreateImplicitClosureNode, it will be replaced by a StaticSetterNode. |
| 2106 return CreateImplicitClosureNode(super_function, | 2115 return CreateImplicitClosureNode(super_function, |
| 2107 field_pos, | 2116 field_pos, |
| 2108 implicit_argument); | 2117 implicit_argument); |
| 2109 } | 2118 } |
| 2110 // No function or field exists of the specified field_name. | 2119 // No function or field exists of the specified field_name. |
| 2111 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. | 2120 // Emit a StaticGetterNode anyway, so that noSuchMethod gets called. |
| 2112 } | 2121 } |
| 2113 } | 2122 } |
| 2114 return new StaticGetterNode( | 2123 return new StaticGetterNode( |
| 2115 field_pos, implicit_argument, true, super_class, field_name); | 2124 field_pos, implicit_argument, true, super_class, field_name); |
| 2116 } | 2125 } |
| 2117 | 2126 |
| 2118 | 2127 |
| 2119 void Parser::GenerateSuperConstructorCall(const Class& cls, | 2128 void Parser::GenerateSuperConstructorCall(const Class& cls, |
| 2120 intptr_t supercall_pos, | 2129 intptr_t supercall_pos, |
| 2121 LocalVariable* receiver, | 2130 LocalVariable* receiver, |
| 2122 ArgumentListNode* forwarding_args) { | 2131 ArgumentListNode* forwarding_args) { |
| 2123 const Class& super_class = Class::Handle(I, cls.SuperClass()); | 2132 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
| 2124 // Omit the implicit super() if there is no super class (i.e. | 2133 // Omit the implicit super() if there is no super class (i.e. |
| 2125 // we're not compiling class Object), or if the super class is an | 2134 // we're not compiling class Object), or if the super class is an |
| 2126 // artificially generated "wrapper class" that has no constructor. | 2135 // artificially generated "wrapper class" that has no constructor. |
| 2127 if (super_class.IsNull() || | 2136 if (super_class.IsNull() || |
| 2128 (super_class.num_native_fields() > 0 && | 2137 (super_class.num_native_fields() > 0 && |
| 2129 Class::Handle(I, super_class.SuperClass()).IsObjectClass())) { | 2138 Class::Handle(Z, super_class.SuperClass()).IsObjectClass())) { |
| 2130 return; | 2139 return; |
| 2131 } | 2140 } |
| 2132 String& super_ctor_name = String::Handle(I, super_class.Name()); | 2141 String& super_ctor_name = String::Handle(Z, super_class.Name()); |
| 2133 super_ctor_name = String::Concat(super_ctor_name, Symbols::Dot()); | 2142 super_ctor_name = String::Concat(super_ctor_name, Symbols::Dot()); |
| 2134 | 2143 |
| 2135 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2144 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 2136 // Implicit 'this' parameter is the first argument. | 2145 // Implicit 'this' parameter is the first argument. |
| 2137 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2146 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
| 2138 arguments->Add(implicit_argument); | 2147 arguments->Add(implicit_argument); |
| 2139 // Implicit construction phase parameter is second argument. | 2148 // Implicit construction phase parameter is second argument. |
| 2140 AstNode* phase_parameter = | 2149 AstNode* phase_parameter = |
| 2141 new LiteralNode(supercall_pos, | 2150 new LiteralNode(supercall_pos, |
| 2142 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll))); | 2151 Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))); |
| 2143 arguments->Add(phase_parameter); | 2152 arguments->Add(phase_parameter); |
| 2144 | 2153 |
| 2145 // If this is a super call in a forwarding constructor, add the user- | 2154 // If this is a super call in a forwarding constructor, add the user- |
| 2146 // defined arguments to the super call and adjust the the super | 2155 // defined arguments to the super call and adjust the the super |
| 2147 // constructor name to the respective named constructor if necessary. | 2156 // constructor name to the respective named constructor if necessary. |
| 2148 if (forwarding_args != NULL) { | 2157 if (forwarding_args != NULL) { |
| 2149 for (int i = 0; i < forwarding_args->length(); i++) { | 2158 for (int i = 0; i < forwarding_args->length(); i++) { |
| 2150 arguments->Add(forwarding_args->NodeAt(i)); | 2159 arguments->Add(forwarding_args->NodeAt(i)); |
| 2151 } | 2160 } |
| 2152 String& ctor_name = String::Handle(I, current_function().name()); | 2161 String& ctor_name = String::Handle(Z, current_function().name()); |
| 2153 String& class_name = String::Handle(I, cls.Name()); | 2162 String& class_name = String::Handle(Z, cls.Name()); |
| 2154 if (ctor_name.Length() > class_name.Length() + 1) { | 2163 if (ctor_name.Length() > class_name.Length() + 1) { |
| 2155 // Generating a forwarding call to a named constructor 'C.n'. | 2164 // Generating a forwarding call to a named constructor 'C.n'. |
| 2156 // Add the constructor name 'n' to the super constructor. | 2165 // Add the constructor name 'n' to the super constructor. |
| 2157 ctor_name = String::SubString(ctor_name, class_name.Length() + 1); | 2166 ctor_name = String::SubString(ctor_name, class_name.Length() + 1); |
| 2158 super_ctor_name = String::Concat(super_ctor_name, ctor_name); | 2167 super_ctor_name = String::Concat(super_ctor_name, ctor_name); |
| 2159 } | 2168 } |
| 2160 } | 2169 } |
| 2161 | 2170 |
| 2162 // Resolve super constructor function and check arguments. | 2171 // Resolve super constructor function and check arguments. |
| 2163 const Function& super_ctor = Function::ZoneHandle(I, | 2172 const Function& super_ctor = Function::ZoneHandle(Z, |
| 2164 super_class.LookupConstructor(super_ctor_name)); | 2173 super_class.LookupConstructor(super_ctor_name)); |
| 2165 if (super_ctor.IsNull()) { | 2174 if (super_ctor.IsNull()) { |
| 2166 ReportError(supercall_pos, | 2175 ReportError(supercall_pos, |
| 2167 "unresolved implicit call to super constructor '%s()'", | 2176 "unresolved implicit call to super constructor '%s()'", |
| 2168 String::Handle(I, super_class.Name()).ToCString()); | 2177 String::Handle(Z, super_class.Name()).ToCString()); |
| 2169 } | 2178 } |
| 2170 if (current_function().is_const() && !super_ctor.is_const()) { | 2179 if (current_function().is_const() && !super_ctor.is_const()) { |
| 2171 ReportError(supercall_pos, "implicit call to non-const super constructor"); | 2180 ReportError(supercall_pos, "implicit call to non-const super constructor"); |
| 2172 } | 2181 } |
| 2173 | 2182 |
| 2174 String& error_message = String::Handle(I); | 2183 String& error_message = String::Handle(Z); |
| 2175 if (!super_ctor.AreValidArguments(arguments->length(), | 2184 if (!super_ctor.AreValidArguments(arguments->length(), |
| 2176 arguments->names(), | 2185 arguments->names(), |
| 2177 &error_message)) { | 2186 &error_message)) { |
| 2178 ReportError(supercall_pos, | 2187 ReportError(supercall_pos, |
| 2179 "invalid arguments passed to super constructor '%s()': %s", | 2188 "invalid arguments passed to super constructor '%s()': %s", |
| 2180 String::Handle(I, super_class.Name()).ToCString(), | 2189 String::Handle(Z, super_class.Name()).ToCString(), |
| 2181 error_message.ToCString()); | 2190 error_message.ToCString()); |
| 2182 } | 2191 } |
| 2183 current_block_->statements->Add( | 2192 current_block_->statements->Add( |
| 2184 new StaticCallNode(supercall_pos, super_ctor, arguments)); | 2193 new StaticCallNode(supercall_pos, super_ctor, arguments)); |
| 2185 } | 2194 } |
| 2186 | 2195 |
| 2187 | 2196 |
| 2188 AstNode* Parser::ParseSuperInitializer(const Class& cls, | 2197 AstNode* Parser::ParseSuperInitializer(const Class& cls, |
| 2189 LocalVariable* receiver) { | 2198 LocalVariable* receiver) { |
| 2190 TRACE_PARSER("ParseSuperInitializer"); | 2199 TRACE_PARSER("ParseSuperInitializer"); |
| 2191 ASSERT(CurrentToken() == Token::kSUPER); | 2200 ASSERT(CurrentToken() == Token::kSUPER); |
| 2192 const intptr_t supercall_pos = TokenPos(); | 2201 const intptr_t supercall_pos = TokenPos(); |
| 2193 ConsumeToken(); | 2202 ConsumeToken(); |
| 2194 const Class& super_class = Class::Handle(I, cls.SuperClass()); | 2203 const Class& super_class = Class::Handle(Z, cls.SuperClass()); |
| 2195 ASSERT(!super_class.IsNull()); | 2204 ASSERT(!super_class.IsNull()); |
| 2196 String& ctor_name = String::Handle(I, super_class.Name()); | 2205 String& ctor_name = String::Handle(Z, super_class.Name()); |
| 2197 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 2206 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 2198 if (CurrentToken() == Token::kPERIOD) { | 2207 if (CurrentToken() == Token::kPERIOD) { |
| 2199 ConsumeToken(); | 2208 ConsumeToken(); |
| 2200 ctor_name = String::Concat(ctor_name, | 2209 ctor_name = String::Concat(ctor_name, |
| 2201 *ExpectIdentifier("constructor name expected")); | 2210 *ExpectIdentifier("constructor name expected")); |
| 2202 } | 2211 } |
| 2203 CheckToken(Token::kLPAREN, "parameter list expected"); | 2212 CheckToken(Token::kLPAREN, "parameter list expected"); |
| 2204 | 2213 |
| 2205 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); | 2214 ArgumentListNode* arguments = new ArgumentListNode(supercall_pos); |
| 2206 // 'this' parameter is the first argument to super class constructor. | 2215 // 'this' parameter is the first argument to super class constructor. |
| 2207 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); | 2216 AstNode* implicit_argument = new LoadLocalNode(supercall_pos, receiver); |
| 2208 arguments->Add(implicit_argument); | 2217 arguments->Add(implicit_argument); |
| 2209 // Second implicit parameter is the construction phase. We optimistically | 2218 // Second implicit parameter is the construction phase. We optimistically |
| 2210 // assume that we can execute both the super initializer and the super | 2219 // assume that we can execute both the super initializer and the super |
| 2211 // constructor body. We may later change this to only execute the | 2220 // constructor body. We may later change this to only execute the |
| 2212 // super initializer. | 2221 // super initializer. |
| 2213 AstNode* phase_parameter = | 2222 AstNode* phase_parameter = |
| 2214 new LiteralNode(supercall_pos, | 2223 new LiteralNode(supercall_pos, |
| 2215 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseAll))); | 2224 Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseAll))); |
| 2216 arguments->Add(phase_parameter); | 2225 arguments->Add(phase_parameter); |
| 2217 // 'this' parameter must not be accessible to the other super call arguments. | 2226 // 'this' parameter must not be accessible to the other super call arguments. |
| 2218 receiver->set_invisible(true); | 2227 receiver->set_invisible(true); |
| 2219 ParseActualParameters(arguments, kAllowConst); | 2228 ParseActualParameters(arguments, kAllowConst); |
| 2220 receiver->set_invisible(false); | 2229 receiver->set_invisible(false); |
| 2221 | 2230 |
| 2222 // Resolve the constructor. | 2231 // Resolve the constructor. |
| 2223 const Function& super_ctor = Function::ZoneHandle(I, | 2232 const Function& super_ctor = Function::ZoneHandle(Z, |
| 2224 super_class.LookupConstructor(ctor_name)); | 2233 super_class.LookupConstructor(ctor_name)); |
| 2225 if (super_ctor.IsNull()) { | 2234 if (super_ctor.IsNull()) { |
| 2226 ReportError(supercall_pos, | 2235 ReportError(supercall_pos, |
| 2227 "super class constructor '%s' not found", | 2236 "super class constructor '%s' not found", |
| 2228 ctor_name.ToCString()); | 2237 ctor_name.ToCString()); |
| 2229 } | 2238 } |
| 2230 if (current_function().is_const() && !super_ctor.is_const()) { | 2239 if (current_function().is_const() && !super_ctor.is_const()) { |
| 2231 ReportError(supercall_pos, "super constructor must be const"); | 2240 ReportError(supercall_pos, "super constructor must be const"); |
| 2232 } | 2241 } |
| 2233 String& error_message = String::Handle(I); | 2242 String& error_message = String::Handle(Z); |
| 2234 if (!super_ctor.AreValidArguments(arguments->length(), | 2243 if (!super_ctor.AreValidArguments(arguments->length(), |
| 2235 arguments->names(), | 2244 arguments->names(), |
| 2236 &error_message)) { | 2245 &error_message)) { |
| 2237 ReportError(supercall_pos, | 2246 ReportError(supercall_pos, |
| 2238 "invalid arguments passed to super class constructor '%s': %s", | 2247 "invalid arguments passed to super class constructor '%s': %s", |
| 2239 ctor_name.ToCString(), | 2248 ctor_name.ToCString(), |
| 2240 error_message.ToCString()); | 2249 error_message.ToCString()); |
| 2241 } | 2250 } |
| 2242 return new StaticCallNode(supercall_pos, super_ctor, arguments); | 2251 return new StaticCallNode(supercall_pos, super_ctor, arguments); |
| 2243 } | 2252 } |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2261 AstNode* init_expr = ParseConditionalExpr(); | 2270 AstNode* init_expr = ParseConditionalExpr(); |
| 2262 if (CurrentToken() == Token::kCASCADE) { | 2271 if (CurrentToken() == Token::kCASCADE) { |
| 2263 init_expr = ParseCascades(init_expr); | 2272 init_expr = ParseCascades(init_expr); |
| 2264 } | 2273 } |
| 2265 receiver->set_invisible(false); | 2274 receiver->set_invisible(false); |
| 2266 SetAllowFunctionLiterals(saved_mode); | 2275 SetAllowFunctionLiterals(saved_mode); |
| 2267 if (current_function().is_const() && !init_expr->IsPotentiallyConst()) { | 2276 if (current_function().is_const() && !init_expr->IsPotentiallyConst()) { |
| 2268 ReportError(field_pos, | 2277 ReportError(field_pos, |
| 2269 "initializer expression must be compile time constant."); | 2278 "initializer expression must be compile time constant."); |
| 2270 } | 2279 } |
| 2271 Field& field = Field::ZoneHandle(I, cls.LookupInstanceField(field_name)); | 2280 Field& field = Field::ZoneHandle(Z, cls.LookupInstanceField(field_name)); |
| 2272 if (field.IsNull()) { | 2281 if (field.IsNull()) { |
| 2273 ReportError(field_pos, "unresolved reference to instance field '%s'", | 2282 ReportError(field_pos, "unresolved reference to instance field '%s'", |
| 2274 field_name.ToCString()); | 2283 field_name.ToCString()); |
| 2275 } | 2284 } |
| 2276 EnsureExpressionTemp(); | 2285 EnsureExpressionTemp(); |
| 2277 AstNode* instance = new(I) LoadLocalNode(field_pos, receiver); | 2286 AstNode* instance = new(Z) LoadLocalNode(field_pos, receiver); |
| 2278 AstNode* initializer = CheckDuplicateFieldInit(field_pos, | 2287 AstNode* initializer = CheckDuplicateFieldInit(field_pos, |
| 2279 initialized_fields, instance, &field, init_expr); | 2288 initialized_fields, instance, &field, init_expr); |
| 2280 if (initializer == NULL) { | 2289 if (initializer == NULL) { |
| 2281 initializer = | 2290 initializer = |
| 2282 new(I) StoreInstanceFieldNode(field_pos, instance, field, init_expr); | 2291 new(Z) StoreInstanceFieldNode(field_pos, instance, field, init_expr); |
| 2283 } | 2292 } |
| 2284 return initializer; | 2293 return initializer; |
| 2285 } | 2294 } |
| 2286 | 2295 |
| 2287 | 2296 |
| 2288 void Parser::CheckFieldsInitialized(const Class& cls) { | 2297 void Parser::CheckFieldsInitialized(const Class& cls) { |
| 2289 const Array& fields = Array::Handle(I, cls.fields()); | 2298 const Array& fields = Array::Handle(Z, cls.fields()); |
| 2290 Field& field = Field::Handle(I); | 2299 Field& field = Field::Handle(Z); |
| 2291 SequenceNode* initializers = current_block_->statements; | 2300 SequenceNode* initializers = current_block_->statements; |
| 2292 for (int field_num = 0; field_num < fields.Length(); field_num++) { | 2301 for (int field_num = 0; field_num < fields.Length(); field_num++) { |
| 2293 field ^= fields.At(field_num); | 2302 field ^= fields.At(field_num); |
| 2294 if (field.is_static()) { | 2303 if (field.is_static()) { |
| 2295 continue; | 2304 continue; |
| 2296 } | 2305 } |
| 2297 | 2306 |
| 2298 bool found = false; | 2307 bool found = false; |
| 2299 for (int i = 0; i < initializers->length(); i++) { | 2308 for (int i = 0; i < initializers->length(); i++) { |
| 2300 found = false; | 2309 found = false; |
| 2301 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { | 2310 if (initializers->NodeAt(i)->IsStoreInstanceFieldNode()) { |
| 2302 StoreInstanceFieldNode* initializer = | 2311 StoreInstanceFieldNode* initializer = |
| 2303 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); | 2312 initializers->NodeAt(i)->AsStoreInstanceFieldNode(); |
| 2304 if (initializer->field().raw() == field.raw()) { | 2313 if (initializer->field().raw() == field.raw()) { |
| 2305 found = true; | 2314 found = true; |
| 2306 break; | 2315 break; |
| 2307 } | 2316 } |
| 2308 } | 2317 } |
| 2309 } | 2318 } |
| 2310 | 2319 |
| 2311 if (found) continue; | 2320 if (found) continue; |
| 2312 | 2321 |
| 2313 field.RecordStore(Object::Handle(I)); | 2322 field.RecordStore(Object::Handle(Z)); |
| 2314 } | 2323 } |
| 2315 } | 2324 } |
| 2316 | 2325 |
| 2317 | 2326 |
| 2318 AstNode* Parser::ParseExternalInitializedField(const Field& field) { | 2327 AstNode* Parser::ParseExternalInitializedField(const Field& field) { |
| 2319 // Only use this function if the initialized field originates | 2328 // Only use this function if the initialized field originates |
| 2320 // from a different class. We need to save and restore current | 2329 // from a different class. We need to save and restore current |
| 2321 // class, library, and token stream (script). | 2330 // class, library, and token stream (script). |
| 2322 ASSERT(current_class().raw() != field.origin()); | 2331 ASSERT(current_class().raw() != field.origin()); |
| 2323 const Class& saved_class = Class::Handle(I, current_class().raw()); | 2332 const Class& saved_class = Class::Handle(Z, current_class().raw()); |
| 2324 const Library& saved_library = Library::Handle(I, library().raw()); | 2333 const Library& saved_library = Library::Handle(Z, library().raw()); |
| 2325 const Script& saved_script = Script::Handle(I, script().raw()); | 2334 const Script& saved_script = Script::Handle(Z, script().raw()); |
| 2326 const intptr_t saved_token_pos = TokenPos(); | 2335 const intptr_t saved_token_pos = TokenPos(); |
| 2327 | 2336 |
| 2328 set_current_class(Class::Handle(I, field.origin())); | 2337 set_current_class(Class::Handle(Z, field.origin())); |
| 2329 set_library(Library::Handle(I, current_class().library())); | 2338 set_library(Library::Handle(Z, current_class().library())); |
| 2330 SetScript(Script::Handle(I, current_class().script()), | 2339 SetScript(Script::Handle(Z, current_class().script()), |
| 2331 field.token_pos()); | 2340 field.token_pos()); |
| 2332 | 2341 |
| 2333 ASSERT(IsIdentifier()); | 2342 ASSERT(IsIdentifier()); |
| 2334 ConsumeToken(); | 2343 ConsumeToken(); |
| 2335 ExpectToken(Token::kASSIGN); | 2344 ExpectToken(Token::kASSIGN); |
| 2336 AstNode* init_expr = NULL; | 2345 AstNode* init_expr = NULL; |
| 2337 intptr_t expr_pos = TokenPos(); | 2346 intptr_t expr_pos = TokenPos(); |
| 2338 if (field.is_const()) { | 2347 if (field.is_const()) { |
| 2339 init_expr = ParseConstExpr(); | 2348 init_expr = ParseConstExpr(); |
| 2340 } else { | 2349 } else { |
| 2341 init_expr = ParseExpr(kAllowConst, kConsumeCascades); | 2350 init_expr = ParseExpr(kAllowConst, kConsumeCascades); |
| 2342 if (init_expr->EvalConstExpr() != NULL) { | 2351 if (init_expr->EvalConstExpr() != NULL) { |
| 2343 init_expr = | 2352 init_expr = |
| 2344 new LiteralNode(field.token_pos(), | 2353 new LiteralNode(field.token_pos(), |
| 2345 EvaluateConstExpr(expr_pos, init_expr)); | 2354 EvaluateConstExpr(expr_pos, init_expr)); |
| 2346 } | 2355 } |
| 2347 } | 2356 } |
| 2348 set_current_class(saved_class); | 2357 set_current_class(saved_class); |
| 2349 set_library(saved_library); | 2358 set_library(saved_library); |
| 2350 SetScript(saved_script, saved_token_pos); | 2359 SetScript(saved_script, saved_token_pos); |
| 2351 return init_expr; | 2360 return init_expr; |
| 2352 } | 2361 } |
| 2353 | 2362 |
| 2354 | 2363 |
| 2355 void Parser::ParseInitializedInstanceFields(const Class& cls, | 2364 void Parser::ParseInitializedInstanceFields(const Class& cls, |
| 2356 LocalVariable* receiver, | 2365 LocalVariable* receiver, |
| 2357 GrowableArray<Field*>* initialized_fields) { | 2366 GrowableArray<Field*>* initialized_fields) { |
| 2358 TRACE_PARSER("ParseInitializedInstanceFields"); | 2367 TRACE_PARSER("ParseInitializedInstanceFields"); |
| 2359 const Array& fields = Array::Handle(I, cls.fields()); | 2368 const Array& fields = Array::Handle(Z, cls.fields()); |
| 2360 Field& f = Field::Handle(I); | 2369 Field& f = Field::Handle(Z); |
| 2361 const intptr_t saved_pos = TokenPos(); | 2370 const intptr_t saved_pos = TokenPos(); |
| 2362 for (int i = 0; i < fields.Length(); i++) { | 2371 for (int i = 0; i < fields.Length(); i++) { |
| 2363 f ^= fields.At(i); | 2372 f ^= fields.At(i); |
| 2364 if (!f.is_static() && f.has_initializer()) { | 2373 if (!f.is_static() && f.has_initializer()) { |
| 2365 Field& field = Field::ZoneHandle(I); | 2374 Field& field = Field::ZoneHandle(Z); |
| 2366 field ^= fields.At(i); | 2375 field ^= fields.At(i); |
| 2367 if (field.is_final()) { | 2376 if (field.is_final()) { |
| 2368 // Final fields with initializer expression may not be initialized | 2377 // Final fields with initializer expression may not be initialized |
| 2369 // again by constructors. Remember that this field is already | 2378 // again by constructors. Remember that this field is already |
| 2370 // initialized. | 2379 // initialized. |
| 2371 initialized_fields->Add(&field); | 2380 initialized_fields->Add(&field); |
| 2372 } | 2381 } |
| 2373 AstNode* init_expr = NULL; | 2382 AstNode* init_expr = NULL; |
| 2374 if (current_class().raw() != field.origin()) { | 2383 if (current_class().raw() != field.origin()) { |
| 2375 init_expr = ParseExternalInitializedField(field); | 2384 init_expr = ParseExternalInitializedField(field); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2436 ASSERT(field->is_final()); | 2445 ASSERT(field->is_final()); |
| 2437 | 2446 |
| 2438 // Build a call to NoSuchMethodError::_throwNew( | 2447 // Build a call to NoSuchMethodError::_throwNew( |
| 2439 // Object receiver, | 2448 // Object receiver, |
| 2440 // String memberName, | 2449 // String memberName, |
| 2441 // int invocation_type, | 2450 // int invocation_type, |
| 2442 // List arguments, | 2451 // List arguments, |
| 2443 // List argumentNames, | 2452 // List argumentNames, |
| 2444 // List existingArgumentNames); | 2453 // List existingArgumentNames); |
| 2445 | 2454 |
| 2446 ArgumentListNode* nsm_args = new(I) ArgumentListNode(init_pos); | 2455 ArgumentListNode* nsm_args = new(Z) ArgumentListNode(init_pos); |
| 2447 // Object receiver. | 2456 // Object receiver. |
| 2448 nsm_args->Add(instance); | 2457 nsm_args->Add(instance); |
| 2449 | 2458 |
| 2450 // String memberName. | 2459 // String memberName. |
| 2451 String& setter_name = String::ZoneHandle(field->name()); | 2460 String& setter_name = String::ZoneHandle(field->name()); |
| 2452 setter_name = Field::SetterSymbol(setter_name); | 2461 setter_name = Field::SetterSymbol(setter_name); |
| 2453 nsm_args->Add(new(I) LiteralNode(init_pos, setter_name)); | 2462 nsm_args->Add(new(Z) LiteralNode(init_pos, setter_name)); |
| 2454 | 2463 |
| 2455 // Smi invocation_type. | 2464 // Smi invocation_type. |
| 2456 const int invocation_type = | 2465 const int invocation_type = |
| 2457 InvocationMirror::EncodeType(InvocationMirror::kDynamic, | 2466 InvocationMirror::EncodeType(InvocationMirror::kDynamic, |
| 2458 InvocationMirror::kSetter); | 2467 InvocationMirror::kSetter); |
| 2459 nsm_args->Add(new(I) LiteralNode( | 2468 nsm_args->Add(new(Z) LiteralNode( |
| 2460 init_pos, Smi::ZoneHandle(I, Smi::New(invocation_type)))); | 2469 init_pos, Smi::ZoneHandle(Z, Smi::New(invocation_type)))); |
| 2461 | 2470 |
| 2462 // List arguments. | 2471 // List arguments. |
| 2463 GrowableArray<AstNode*> setter_args; | 2472 GrowableArray<AstNode*> setter_args; |
| 2464 setter_args.Add(init_value); | 2473 setter_args.Add(init_value); |
| 2465 ArrayNode* setter_args_array = new(I) ArrayNode( | 2474 ArrayNode* setter_args_array = new(Z) ArrayNode( |
| 2466 init_pos, | 2475 init_pos, |
| 2467 Type::ZoneHandle(I, Type::ArrayType()), | 2476 Type::ZoneHandle(Z, Type::ArrayType()), |
| 2468 setter_args); | 2477 setter_args); |
| 2469 nsm_args->Add(setter_args_array); | 2478 nsm_args->Add(setter_args_array); |
| 2470 | 2479 |
| 2471 // List argumentNames. | 2480 // List argumentNames. |
| 2472 // The missing implicit setter of the field has no argument names. | 2481 // The missing implicit setter of the field has no argument names. |
| 2473 nsm_args->Add(new(I) LiteralNode(init_pos, Array::ZoneHandle(I))); | 2482 nsm_args->Add(new(Z) LiteralNode(init_pos, Array::ZoneHandle(Z))); |
| 2474 | 2483 |
| 2475 // List existingArgumentNames. | 2484 // List existingArgumentNames. |
| 2476 // There is no setter for the final field, thus there are | 2485 // There is no setter for the final field, thus there are |
| 2477 // no existing names. | 2486 // no existing names. |
| 2478 nsm_args->Add(new(I) LiteralNode(init_pos, Array::ZoneHandle(I))); | 2487 nsm_args->Add(new(Z) LiteralNode(init_pos, Array::ZoneHandle(Z))); |
| 2479 | 2488 |
| 2480 AstNode* nsm_call = | 2489 AstNode* nsm_call = |
| 2481 MakeStaticCall(Symbols::NoSuchMethodError(), | 2490 MakeStaticCall(Symbols::NoSuchMethodError(), |
| 2482 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 2491 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 2483 nsm_args); | 2492 nsm_args); |
| 2484 | 2493 |
| 2485 LetNode* let = new(I) LetNode(init_pos); | 2494 LetNode* let = new(Z) LetNode(init_pos); |
| 2486 let->AddNode(init_value); | 2495 let->AddNode(init_value); |
| 2487 let->AddNode(nsm_call); | 2496 let->AddNode(nsm_call); |
| 2488 result = let; | 2497 result = let; |
| 2489 } | 2498 } |
| 2490 } | 2499 } |
| 2491 // The remaining elements in initialized_fields are fields that | 2500 // The remaining elements in initialized_fields are fields that |
| 2492 // are initialized through initializing formal parameters, or | 2501 // are initialized through initializing formal parameters, or |
| 2493 // in the constructor's initializer list. If there is a duplicate, | 2502 // in the constructor's initializer list. If there is a duplicate, |
| 2494 // it is a compile time error. | 2503 // it is a compile time error. |
| 2495 while (initializer_idx < initialized_fields->length()) { | 2504 while (initializer_idx < initialized_fields->length()) { |
| 2496 Field* initialized_field = (*initialized_fields)[initializer_idx]; | 2505 Field* initialized_field = (*initialized_fields)[initializer_idx]; |
| 2497 initializer_idx++; | 2506 initializer_idx++; |
| 2498 if (initialized_field->raw() == field->raw()) { | 2507 if (initialized_field->raw() == field->raw()) { |
| 2499 ReportError(init_pos, | 2508 ReportError(init_pos, |
| 2500 "duplicate initializer for field %s", | 2509 "duplicate initializer for field %s", |
| 2501 String::Handle(I, field->name()).ToCString()); | 2510 String::Handle(Z, field->name()).ToCString()); |
| 2502 } | 2511 } |
| 2503 } | 2512 } |
| 2504 initialized_fields->Add(field); | 2513 initialized_fields->Add(field); |
| 2505 return result; | 2514 return result; |
| 2506 } | 2515 } |
| 2507 | 2516 |
| 2508 | 2517 |
| 2509 void Parser::ParseInitializers(const Class& cls, | 2518 void Parser::ParseInitializers(const Class& cls, |
| 2510 LocalVariable* receiver, | 2519 LocalVariable* receiver, |
| 2511 GrowableArray<Field*>* initialized_fields) { | 2520 GrowableArray<Field*>* initialized_fields) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 2536 } | 2545 } |
| 2537 | 2546 |
| 2538 | 2547 |
| 2539 void Parser::ParseConstructorRedirection(const Class& cls, | 2548 void Parser::ParseConstructorRedirection(const Class& cls, |
| 2540 LocalVariable* receiver) { | 2549 LocalVariable* receiver) { |
| 2541 TRACE_PARSER("ParseConstructorRedirection"); | 2550 TRACE_PARSER("ParseConstructorRedirection"); |
| 2542 ExpectToken(Token::kCOLON); | 2551 ExpectToken(Token::kCOLON); |
| 2543 ASSERT(CurrentToken() == Token::kTHIS); | 2552 ASSERT(CurrentToken() == Token::kTHIS); |
| 2544 const intptr_t call_pos = TokenPos(); | 2553 const intptr_t call_pos = TokenPos(); |
| 2545 ConsumeToken(); | 2554 ConsumeToken(); |
| 2546 String& ctor_name = String::Handle(I, cls.Name()); | 2555 String& ctor_name = String::Handle(Z, cls.Name()); |
| 2547 | 2556 |
| 2548 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 2557 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 2549 if (CurrentToken() == Token::kPERIOD) { | 2558 if (CurrentToken() == Token::kPERIOD) { |
| 2550 ConsumeToken(); | 2559 ConsumeToken(); |
| 2551 ctor_name = String::Concat(ctor_name, | 2560 ctor_name = String::Concat(ctor_name, |
| 2552 *ExpectIdentifier("constructor name expected")); | 2561 *ExpectIdentifier("constructor name expected")); |
| 2553 } | 2562 } |
| 2554 CheckToken(Token::kLPAREN, "parameter list expected"); | 2563 CheckToken(Token::kLPAREN, "parameter list expected"); |
| 2555 | 2564 |
| 2556 ArgumentListNode* arguments = new ArgumentListNode(call_pos); | 2565 ArgumentListNode* arguments = new ArgumentListNode(call_pos); |
| 2557 // 'this' parameter is the first argument to constructor. | 2566 // 'this' parameter is the first argument to constructor. |
| 2558 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); | 2567 AstNode* implicit_argument = new LoadLocalNode(call_pos, receiver); |
| 2559 arguments->Add(implicit_argument); | 2568 arguments->Add(implicit_argument); |
| 2560 // Construction phase parameter is second argument. | 2569 // Construction phase parameter is second argument. |
| 2561 LocalVariable* phase_param = LookupPhaseParameter(); | 2570 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2562 ASSERT(phase_param != NULL); | 2571 ASSERT(phase_param != NULL); |
| 2563 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); | 2572 AstNode* phase_argument = new LoadLocalNode(call_pos, phase_param); |
| 2564 arguments->Add(phase_argument); | 2573 arguments->Add(phase_argument); |
| 2565 receiver->set_invisible(true); | 2574 receiver->set_invisible(true); |
| 2566 ParseActualParameters(arguments, kAllowConst); | 2575 ParseActualParameters(arguments, kAllowConst); |
| 2567 receiver->set_invisible(false); | 2576 receiver->set_invisible(false); |
| 2568 // Resolve the constructor. | 2577 // Resolve the constructor. |
| 2569 const Function& redirect_ctor = Function::ZoneHandle(I, | 2578 const Function& redirect_ctor = Function::ZoneHandle(Z, |
| 2570 cls.LookupConstructor(ctor_name)); | 2579 cls.LookupConstructor(ctor_name)); |
| 2571 if (redirect_ctor.IsNull()) { | 2580 if (redirect_ctor.IsNull()) { |
| 2572 ReportError(call_pos, "constructor '%s' not found", ctor_name.ToCString()); | 2581 ReportError(call_pos, "constructor '%s' not found", ctor_name.ToCString()); |
| 2573 } | 2582 } |
| 2574 String& error_message = String::Handle(I); | 2583 String& error_message = String::Handle(Z); |
| 2575 if (!redirect_ctor.AreValidArguments(arguments->length(), | 2584 if (!redirect_ctor.AreValidArguments(arguments->length(), |
| 2576 arguments->names(), | 2585 arguments->names(), |
| 2577 &error_message)) { | 2586 &error_message)) { |
| 2578 ReportError(call_pos, | 2587 ReportError(call_pos, |
| 2579 "invalid arguments passed to constructor '%s': %s", | 2588 "invalid arguments passed to constructor '%s': %s", |
| 2580 ctor_name.ToCString(), | 2589 ctor_name.ToCString(), |
| 2581 error_message.ToCString()); | 2590 error_message.ToCString()); |
| 2582 } | 2591 } |
| 2583 current_block_->statements->Add( | 2592 current_block_->statements->Add( |
| 2584 new StaticCallNode(call_pos, redirect_ctor, arguments)); | 2593 new StaticCallNode(call_pos, redirect_ctor, arguments)); |
| 2585 } | 2594 } |
| 2586 | 2595 |
| 2587 | 2596 |
| 2588 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { | 2597 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) { |
| 2589 ASSERT(func.IsConstructor()); | 2598 ASSERT(func.IsConstructor()); |
| 2590 ASSERT(func.Owner() == current_class().raw()); | 2599 ASSERT(func.Owner() == current_class().raw()); |
| 2591 const intptr_t ctor_pos = TokenPos(); | 2600 const intptr_t ctor_pos = TokenPos(); |
| 2592 OpenFunctionBlock(func); | 2601 OpenFunctionBlock(func); |
| 2593 | 2602 |
| 2594 LocalVariable* receiver = new LocalVariable( | 2603 LocalVariable* receiver = new LocalVariable( |
| 2595 Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); | 2604 Scanner::kNoSourcePos, Symbols::This(), *ReceiverType(current_class())); |
| 2596 current_block_->scope->InsertParameterAt(0, receiver); | 2605 current_block_->scope->InsertParameterAt(0, receiver); |
| 2597 | 2606 |
| 2598 LocalVariable* phase_parameter = | 2607 LocalVariable* phase_parameter = |
| 2599 new LocalVariable(Scanner::kNoSourcePos, | 2608 new LocalVariable(Scanner::kNoSourcePos, |
| 2600 Symbols::PhaseParameter(), | 2609 Symbols::PhaseParameter(), |
| 2601 Type::ZoneHandle(I, Type::SmiType())); | 2610 Type::ZoneHandle(Z, Type::SmiType())); |
| 2602 current_block_->scope->InsertParameterAt(1, phase_parameter); | 2611 current_block_->scope->InsertParameterAt(1, phase_parameter); |
| 2603 | 2612 |
| 2604 // Parse expressions of instance fields that have an explicit | 2613 // Parse expressions of instance fields that have an explicit |
| 2605 // initializer expression. | 2614 // initializer expression. |
| 2606 // The receiver must not be visible to field initializer expressions. | 2615 // The receiver must not be visible to field initializer expressions. |
| 2607 receiver->set_invisible(true); | 2616 receiver->set_invisible(true); |
| 2608 GrowableArray<Field*> initialized_fields; | 2617 GrowableArray<Field*> initialized_fields; |
| 2609 ParseInitializedInstanceFields( | 2618 ParseInitializedInstanceFields( |
| 2610 current_class(), receiver, &initialized_fields); | 2619 current_class(), receiver, &initialized_fields); |
| 2611 receiver->set_invisible(false); | 2620 receiver->set_invisible(false); |
| 2612 | 2621 |
| 2613 // If the class of this implicit constructor is a mixin application alias, | 2622 // If the class of this implicit constructor is a mixin application alias, |
| 2614 // it is a forwarding constructor of the aliased mixin application class. | 2623 // it is a forwarding constructor of the aliased mixin application class. |
| 2615 // If the class of this implicit constructor is a mixin application class, | 2624 // If the class of this implicit constructor is a mixin application class, |
| 2616 // it is a forwarding constructor of the mixin. The forwarding | 2625 // it is a forwarding constructor of the mixin. The forwarding |
| 2617 // constructor initializes the instance fields that have initializer | 2626 // constructor initializes the instance fields that have initializer |
| 2618 // expressions and then calls the respective super constructor with | 2627 // expressions and then calls the respective super constructor with |
| 2619 // the same name and number of parameters. | 2628 // the same name and number of parameters. |
| 2620 ArgumentListNode* forwarding_args = NULL; | 2629 ArgumentListNode* forwarding_args = NULL; |
| 2621 if (current_class().is_mixin_app_alias() || | 2630 if (current_class().is_mixin_app_alias() || |
| 2622 current_class().IsMixinApplication()) { | 2631 current_class().IsMixinApplication()) { |
| 2623 // At this point we don't support forwarding constructors | 2632 // At this point we don't support forwarding constructors |
| 2624 // that have optional parameters because we don't know the default | 2633 // that have optional parameters because we don't know the default |
| 2625 // values of the optional parameters. We would have to compile the super | 2634 // values of the optional parameters. We would have to compile the super |
| 2626 // constructor to get the default values. Also, the spec is not clear | 2635 // constructor to get the default values. Also, the spec is not clear |
| 2627 // whether optional parameters are even allowed in this situation. | 2636 // whether optional parameters are even allowed in this situation. |
| 2628 // TODO(hausner): Remove this limitation if the language spec indeed | 2637 // TODO(hausner): Remove this limitation if the language spec indeed |
| 2629 // allows optional parameters. | 2638 // allows optional parameters. |
| 2630 if (func.HasOptionalParameters()) { | 2639 if (func.HasOptionalParameters()) { |
| 2631 const Class& super_class = Class::Handle(I, current_class().SuperClass()); | 2640 const Class& super_class = Class::Handle(Z, current_class().SuperClass()); |
| 2632 ReportError(ctor_pos, | 2641 ReportError(ctor_pos, |
| 2633 "cannot generate an implicit mixin application constructor " | 2642 "cannot generate an implicit mixin application constructor " |
| 2634 "forwarding to a super class constructor with optional " | 2643 "forwarding to a super class constructor with optional " |
| 2635 "parameters; add a constructor without optional parameters " | 2644 "parameters; add a constructor without optional parameters " |
| 2636 "to class '%s' that redirects to the constructor with " | 2645 "to class '%s' that redirects to the constructor with " |
| 2637 "optional parameters and invoke it via super from a " | 2646 "optional parameters and invoke it via super from a " |
| 2638 "constructor of the class extending the mixin application", | 2647 "constructor of the class extending the mixin application", |
| 2639 String::Handle(I, super_class.Name()).ToCString()); | 2648 String::Handle(Z, super_class.Name()).ToCString()); |
| 2640 } | 2649 } |
| 2641 | 2650 |
| 2642 // Prepare user-defined arguments to be forwarded to super call. | 2651 // Prepare user-defined arguments to be forwarded to super call. |
| 2643 // The first user-defined argument is at position 2. | 2652 // The first user-defined argument is at position 2. |
| 2644 forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos); | 2653 forwarding_args = new ArgumentListNode(Scanner::kNoSourcePos); |
| 2645 for (int i = 2; i < func.NumParameters(); i++) { | 2654 for (int i = 2; i < func.NumParameters(); i++) { |
| 2646 LocalVariable* param = new LocalVariable( | 2655 LocalVariable* param = new LocalVariable( |
| 2647 Scanner::kNoSourcePos, | 2656 Scanner::kNoSourcePos, |
| 2648 String::ZoneHandle(I, func.ParameterNameAt(i)), | 2657 String::ZoneHandle(Z, func.ParameterNameAt(i)), |
| 2649 Type::ZoneHandle(I, Type::DynamicType())); | 2658 Type::ZoneHandle(Z, Type::DynamicType())); |
| 2650 current_block_->scope->InsertParameterAt(i, param); | 2659 current_block_->scope->InsertParameterAt(i, param); |
| 2651 forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param)); | 2660 forwarding_args->Add(new LoadLocalNode(Scanner::kNoSourcePos, param)); |
| 2652 } | 2661 } |
| 2653 } | 2662 } |
| 2654 | 2663 |
| 2655 GenerateSuperConstructorCall(current_class(), | 2664 GenerateSuperConstructorCall(current_class(), |
| 2656 Scanner::kNoSourcePos, | 2665 Scanner::kNoSourcePos, |
| 2657 receiver, | 2666 receiver, |
| 2658 forwarding_args); | 2667 forwarding_args); |
| 2659 CheckFieldsInitialized(current_class()); | 2668 CheckFieldsInitialized(current_class()); |
| 2660 | 2669 |
| 2661 // Empty constructor body. | 2670 // Empty constructor body. |
| 2662 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); | 2671 current_block_->statements->Add(new ReturnNode(Scanner::kNoSourcePos)); |
| 2663 SequenceNode* statements = CloseBlock(); | 2672 SequenceNode* statements = CloseBlock(); |
| 2664 return statements; | 2673 return statements; |
| 2665 } | 2674 } |
| 2666 | 2675 |
| 2667 | 2676 |
| 2668 void Parser::CheckRecursiveInvocation() { | 2677 void Parser::CheckRecursiveInvocation() { |
| 2669 const GrowableObjectArray& pending_functions = | 2678 const GrowableObjectArray& pending_functions = |
| 2670 GrowableObjectArray::Handle(I, | 2679 GrowableObjectArray::Handle(Z, |
| 2671 I->object_store()->pending_functions()); | 2680 I->object_store()->pending_functions()); |
| 2672 for (int i = 0; i < pending_functions.Length(); i++) { | 2681 for (int i = 0; i < pending_functions.Length(); i++) { |
| 2673 if (pending_functions.At(i) == current_function().raw()) { | 2682 if (pending_functions.At(i) == current_function().raw()) { |
| 2674 const String& fname = | 2683 const String& fname = |
| 2675 String::Handle(I, current_function().UserVisibleName()); | 2684 String::Handle(Z, current_function().UserVisibleName()); |
| 2676 ReportError("circular dependency for function %s", fname.ToCString()); | 2685 ReportError("circular dependency for function %s", fname.ToCString()); |
| 2677 } | 2686 } |
| 2678 } | 2687 } |
| 2679 ASSERT(!unregister_pending_function_); | 2688 ASSERT(!unregister_pending_function_); |
| 2680 pending_functions.Add(current_function()); | 2689 pending_functions.Add(current_function()); |
| 2681 unregister_pending_function_ = true; | 2690 unregister_pending_function_ = true; |
| 2682 } | 2691 } |
| 2683 | 2692 |
| 2684 | 2693 |
| 2685 // Parser is at the opening parenthesis of the formal parameter declaration | 2694 // Parser is at the opening parenthesis of the formal parameter declaration |
| 2686 // of function. Parse the formal parameters, initializers and code. | 2695 // of function. Parse the formal parameters, initializers and code. |
| 2687 SequenceNode* Parser::ParseConstructor(const Function& func, | 2696 SequenceNode* Parser::ParseConstructor(const Function& func, |
| 2688 Array* default_parameter_values) { | 2697 Array* default_parameter_values) { |
| 2689 TRACE_PARSER("ParseConstructor"); | 2698 TRACE_PARSER("ParseConstructor"); |
| 2690 ASSERT(func.IsConstructor()); | 2699 ASSERT(func.IsConstructor()); |
| 2691 ASSERT(!func.IsFactory()); | 2700 ASSERT(!func.IsFactory()); |
| 2692 ASSERT(!func.is_static()); | 2701 ASSERT(!func.is_static()); |
| 2693 ASSERT(!func.IsLocalFunction()); | 2702 ASSERT(!func.IsLocalFunction()); |
| 2694 const Class& cls = Class::Handle(I, func.Owner()); | 2703 const Class& cls = Class::Handle(Z, func.Owner()); |
| 2695 ASSERT(!cls.IsNull()); | 2704 ASSERT(!cls.IsNull()); |
| 2696 | 2705 |
| 2697 CheckRecursiveInvocation(); | 2706 CheckRecursiveInvocation(); |
| 2698 | 2707 |
| 2699 if (func.IsImplicitConstructor()) { | 2708 if (func.IsImplicitConstructor()) { |
| 2700 // Special case: implicit constructor. | 2709 // Special case: implicit constructor. |
| 2701 // The parser adds an implicit default constructor when a class | 2710 // The parser adds an implicit default constructor when a class |
| 2702 // does not have any explicit constructor or factory (see | 2711 // does not have any explicit constructor or factory (see |
| 2703 // Parser::AddImplicitConstructor). | 2712 // Parser::AddImplicitConstructor). |
| 2704 // There is no source text to parse. We just build the | 2713 // There is no source text to parse. We just build the |
| 2705 // sequence node by hand. | 2714 // sequence node by hand. |
| 2706 return MakeImplicitConstructor(func); | 2715 return MakeImplicitConstructor(func); |
| 2707 } | 2716 } |
| 2708 | 2717 |
| 2709 OpenFunctionBlock(func); | 2718 OpenFunctionBlock(func); |
| 2710 ParamList params; | 2719 ParamList params; |
| 2711 const bool allow_explicit_default_values = true; | 2720 const bool allow_explicit_default_values = true; |
| 2712 ASSERT(CurrentToken() == Token::kLPAREN); | 2721 ASSERT(CurrentToken() == Token::kLPAREN); |
| 2713 | 2722 |
| 2714 // Add implicit receiver parameter which is passed the allocated | 2723 // Add implicit receiver parameter which is passed the allocated |
| 2715 // but uninitialized instance to construct. | 2724 // but uninitialized instance to construct. |
| 2716 ASSERT(current_class().raw() == func.Owner()); | 2725 ASSERT(current_class().raw() == func.Owner()); |
| 2717 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 2726 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
| 2718 | 2727 |
| 2719 // Add implicit parameter for construction phase. | 2728 // Add implicit parameter for construction phase. |
| 2720 params.AddFinalParameter( | 2729 params.AddFinalParameter( |
| 2721 TokenPos(), | 2730 TokenPos(), |
| 2722 &Symbols::PhaseParameter(), | 2731 &Symbols::PhaseParameter(), |
| 2723 &Type::ZoneHandle(I, Type::SmiType())); | 2732 &Type::ZoneHandle(Z, Type::SmiType())); |
| 2724 | 2733 |
| 2725 if (func.is_const()) { | 2734 if (func.is_const()) { |
| 2726 params.SetImplicitlyFinal(); | 2735 params.SetImplicitlyFinal(); |
| 2727 } | 2736 } |
| 2728 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 2737 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 2729 | 2738 |
| 2730 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 2739 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 2731 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 2740 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 2732 ASSERT(func.NumParameters() == params.parameters->length()); | 2741 ASSERT(func.NumParameters() == params.parameters->length()); |
| 2733 | 2742 |
| 2734 // Now populate function scope with the formal parameters. | 2743 // Now populate function scope with the formal parameters. |
| 2735 AddFormalParamsToScope(¶ms, current_block_->scope); | 2744 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 2736 | 2745 |
| 2737 const bool is_redirecting_constructor = | 2746 const bool is_redirecting_constructor = |
| 2738 (CurrentToken() == Token::kCOLON) && | 2747 (CurrentToken() == Token::kCOLON) && |
| 2739 ((LookaheadToken(1) == Token::kTHIS) && | 2748 ((LookaheadToken(1) == Token::kTHIS) && |
| 2740 ((LookaheadToken(2) == Token::kLPAREN) || | 2749 ((LookaheadToken(2) == Token::kLPAREN) || |
| 2741 ((LookaheadToken(2) == Token::kPERIOD) && | 2750 ((LookaheadToken(2) == Token::kPERIOD) && |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 2761 | 2770 |
| 2762 // Turn formal field parameters into field initializers. | 2771 // Turn formal field parameters into field initializers. |
| 2763 if (params.has_field_initializer) { | 2772 if (params.has_field_initializer) { |
| 2764 // First two parameters are implicit receiver and phase. | 2773 // First two parameters are implicit receiver and phase. |
| 2765 ASSERT(params.parameters->length() >= 2); | 2774 ASSERT(params.parameters->length() >= 2); |
| 2766 for (int i = 2; i < params.parameters->length(); i++) { | 2775 for (int i = 2; i < params.parameters->length(); i++) { |
| 2767 ParamDesc& param = (*params.parameters)[i]; | 2776 ParamDesc& param = (*params.parameters)[i]; |
| 2768 if (param.is_field_initializer) { | 2777 if (param.is_field_initializer) { |
| 2769 const String& field_name = *param.name; | 2778 const String& field_name = *param.name; |
| 2770 Field& field = | 2779 Field& field = |
| 2771 Field::ZoneHandle(I, cls.LookupInstanceField(field_name)); | 2780 Field::ZoneHandle(Z, cls.LookupInstanceField(field_name)); |
| 2772 if (field.IsNull()) { | 2781 if (field.IsNull()) { |
| 2773 ReportError(param.name_pos, | 2782 ReportError(param.name_pos, |
| 2774 "unresolved reference to instance field '%s'", | 2783 "unresolved reference to instance field '%s'", |
| 2775 field_name.ToCString()); | 2784 field_name.ToCString()); |
| 2776 } | 2785 } |
| 2777 if (is_redirecting_constructor) { | 2786 if (is_redirecting_constructor) { |
| 2778 ReportError(param.name_pos, | 2787 ReportError(param.name_pos, |
| 2779 "redirecting constructors may not have " | 2788 "redirecting constructors may not have " |
| 2780 "initializing formal parameters"); | 2789 "initializing formal parameters"); |
| 2781 } | 2790 } |
| 2782 | 2791 |
| 2783 if (!param.has_explicit_type) { | 2792 if (!param.has_explicit_type) { |
| 2784 const AbstractType& field_type = | 2793 const AbstractType& field_type = |
| 2785 AbstractType::ZoneHandle(I, field.type()); | 2794 AbstractType::ZoneHandle(Z, field.type()); |
| 2786 param.type = &field_type; | 2795 param.type = &field_type; |
| 2787 // Parameter type was already set to dynamic when parsing the class | 2796 // Parameter type was already set to dynamic when parsing the class |
| 2788 // declaration: fix it. | 2797 // declaration: fix it. |
| 2789 func.SetParameterTypeAt(i, field_type); | 2798 func.SetParameterTypeAt(i, field_type); |
| 2790 } | 2799 } |
| 2791 | 2800 |
| 2792 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); | 2801 AstNode* instance = new LoadLocalNode(param.name_pos, receiver); |
| 2793 // Initializing formals cannot be used in the explicit initializer | 2802 // Initializing formals cannot be used in the explicit initializer |
| 2794 // list, nor can they be used in the constructor body. | 2803 // list, nor can they be used in the constructor body. |
| 2795 // Thus, they are set to be invisible when added to the scope. | 2804 // Thus, they are set to be invisible when added to the scope. |
| 2796 LocalVariable* p = param.var; | 2805 LocalVariable* p = param.var; |
| 2797 ASSERT(p != NULL); | 2806 ASSERT(p != NULL); |
| 2798 ASSERT(p->is_invisible()); | 2807 ASSERT(p->is_invisible()); |
| 2799 AstNode* value = new LoadLocalNode(param.name_pos, p); | 2808 AstNode* value = new LoadLocalNode(param.name_pos, p); |
| 2800 EnsureExpressionTemp(); | 2809 EnsureExpressionTemp(); |
| 2801 AstNode* initializer = | 2810 AstNode* initializer = |
| 2802 CheckDuplicateFieldInit(param.name_pos, | 2811 CheckDuplicateFieldInit(param.name_pos, |
| 2803 &initialized_fields, | 2812 &initialized_fields, |
| 2804 instance, | 2813 instance, |
| 2805 &field, | 2814 &field, |
| 2806 value); | 2815 value); |
| 2807 if (initializer == NULL) { | 2816 if (initializer == NULL) { |
| 2808 initializer = new(I) StoreInstanceFieldNode( | 2817 initializer = new(Z) StoreInstanceFieldNode( |
| 2809 param.name_pos, instance, field, value); | 2818 param.name_pos, instance, field, value); |
| 2810 } | 2819 } |
| 2811 current_block_->statements->Add(initializer); | 2820 current_block_->statements->Add(initializer); |
| 2812 } | 2821 } |
| 2813 } | 2822 } |
| 2814 } | 2823 } |
| 2815 | 2824 |
| 2816 if (is_redirecting_constructor) { | 2825 if (is_redirecting_constructor) { |
| 2817 ParseConstructorRedirection(cls, receiver); | 2826 ParseConstructorRedirection(cls, receiver); |
| 2818 } else { | 2827 } else { |
| 2819 ParseInitializers(cls, receiver, &initialized_fields); | 2828 ParseInitializers(cls, receiver, &initialized_fields); |
| 2820 } | 2829 } |
| 2821 | 2830 |
| 2822 SequenceNode* init_statements = CloseBlock(); | 2831 SequenceNode* init_statements = CloseBlock(); |
| 2823 if (is_redirecting_constructor) { | 2832 if (is_redirecting_constructor) { |
| 2824 // A redirecting super constructor simply passes the phase parameter on to | 2833 // A redirecting super constructor simply passes the phase parameter on to |
| 2825 // the target which executes the corresponding phase. | 2834 // the target which executes the corresponding phase. |
| 2826 current_block_->statements->Add(init_statements); | 2835 current_block_->statements->Add(init_statements); |
| 2827 } else if (init_statements->length() > 0) { | 2836 } else if (init_statements->length() > 0) { |
| 2828 // Generate guard around the initializer code. | 2837 // Generate guard around the initializer code. |
| 2829 LocalVariable* phase_param = LookupPhaseParameter(); | 2838 LocalVariable* phase_param = LookupPhaseParameter(); |
| 2830 AstNode* phase_value = new | 2839 AstNode* phase_value = new |
| 2831 LoadLocalNode(Scanner::kNoSourcePos, phase_param); | 2840 LoadLocalNode(Scanner::kNoSourcePos, phase_param); |
| 2832 AstNode* phase_check = new BinaryOpNode( | 2841 AstNode* phase_check = new BinaryOpNode( |
| 2833 Scanner::kNoSourcePos, Token::kBIT_AND, phase_value, | 2842 Scanner::kNoSourcePos, Token::kBIT_AND, phase_value, |
| 2834 new LiteralNode(Scanner::kNoSourcePos, | 2843 new LiteralNode(Scanner::kNoSourcePos, |
| 2835 Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseInit)))); | 2844 Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit)))); |
| 2836 AstNode* comparison = | 2845 AstNode* comparison = |
| 2837 new ComparisonNode(Scanner::kNoSourcePos, | 2846 new ComparisonNode(Scanner::kNoSourcePos, |
| 2838 Token::kNE_STRICT, | 2847 Token::kNE_STRICT, |
| 2839 phase_check, | 2848 phase_check, |
| 2840 new LiteralNode(TokenPos(), | 2849 new LiteralNode(TokenPos(), |
| 2841 Smi::ZoneHandle(I, Smi::New(0)))); | 2850 Smi::ZoneHandle(Z, Smi::New(0)))); |
| 2842 AstNode* guarded_init_statements = | 2851 AstNode* guarded_init_statements = |
| 2843 new IfNode(Scanner::kNoSourcePos, | 2852 new IfNode(Scanner::kNoSourcePos, |
| 2844 comparison, | 2853 comparison, |
| 2845 init_statements, | 2854 init_statements, |
| 2846 NULL); | 2855 NULL); |
| 2847 current_block_->statements->Add(guarded_init_statements); | 2856 current_block_->statements->Add(guarded_init_statements); |
| 2848 } | 2857 } |
| 2849 | 2858 |
| 2850 // Parsing of initializers done. Now we parse the constructor body | 2859 // Parsing of initializers done. Now we parse the constructor body |
| 2851 // and add the implicit super call to the super constructor's body | 2860 // and add the implicit super call to the super constructor's body |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2894 } | 2903 } |
| 2895 OpenBlock(); // Block to collect constructor body nodes. | 2904 OpenBlock(); // Block to collect constructor body nodes. |
| 2896 intptr_t body_pos = TokenPos(); | 2905 intptr_t body_pos = TokenPos(); |
| 2897 | 2906 |
| 2898 // Insert the implicit super call to the super constructor body. | 2907 // Insert the implicit super call to the super constructor body. |
| 2899 if (super_call != NULL) { | 2908 if (super_call != NULL) { |
| 2900 ArgumentListNode* initializer_args = super_call->arguments(); | 2909 ArgumentListNode* initializer_args = super_call->arguments(); |
| 2901 const Function& super_ctor = super_call->function(); | 2910 const Function& super_ctor = super_call->function(); |
| 2902 // Patch the initializer call so it only executes the super initializer. | 2911 // Patch the initializer call so it only executes the super initializer. |
| 2903 initializer_args->SetNodeAt(1, new LiteralNode( | 2912 initializer_args->SetNodeAt(1, new LiteralNode( |
| 2904 body_pos, Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseInit)))); | 2913 body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseInit)))); |
| 2905 | 2914 |
| 2906 ArgumentListNode* super_call_args = new ArgumentListNode(body_pos); | 2915 ArgumentListNode* super_call_args = new ArgumentListNode(body_pos); |
| 2907 // First argument is the receiver. | 2916 // First argument is the receiver. |
| 2908 super_call_args->Add(new LoadLocalNode(body_pos, receiver)); | 2917 super_call_args->Add(new LoadLocalNode(body_pos, receiver)); |
| 2909 // Second argument is the construction phase argument. | 2918 // Second argument is the construction phase argument. |
| 2910 AstNode* phase_parameter = new(I) LiteralNode( | 2919 AstNode* phase_parameter = new(Z) LiteralNode( |
| 2911 body_pos, Smi::ZoneHandle(I, Smi::New(Function::kCtorPhaseBody))); | 2920 body_pos, Smi::ZoneHandle(Z, Smi::New(Function::kCtorPhaseBody))); |
| 2912 super_call_args->Add(phase_parameter); | 2921 super_call_args->Add(phase_parameter); |
| 2913 super_call_args->set_names(initializer_args->names()); | 2922 super_call_args->set_names(initializer_args->names()); |
| 2914 for (int i = 2; i < initializer_args->length(); i++) { | 2923 for (int i = 2; i < initializer_args->length(); i++) { |
| 2915 AstNode* arg = initializer_args->NodeAt(i); | 2924 AstNode* arg = initializer_args->NodeAt(i); |
| 2916 if (arg->IsLiteralNode()) { | 2925 if (arg->IsLiteralNode()) { |
| 2917 LiteralNode* lit = arg->AsLiteralNode(); | 2926 LiteralNode* lit = arg->AsLiteralNode(); |
| 2918 super_call_args->Add(new LiteralNode(body_pos, lit->literal())); | 2927 super_call_args->Add(new LiteralNode(body_pos, lit->literal())); |
| 2919 } else { | 2928 } else { |
| 2920 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); | 2929 ASSERT(arg->IsLoadLocalNode() || arg->IsStoreLocalNode()); |
| 2921 if (arg->IsLoadLocalNode()) { | 2930 if (arg->IsLoadLocalNode()) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2991 } | 3000 } |
| 2992 | 3001 |
| 2993 | 3002 |
| 2994 // Parser is at the opening parenthesis of the formal parameter | 3003 // Parser is at the opening parenthesis of the formal parameter |
| 2995 // declaration of the function or constructor. | 3004 // declaration of the function or constructor. |
| 2996 // Parse the formal parameters and code. | 3005 // Parse the formal parameters and code. |
| 2997 SequenceNode* Parser::ParseFunc(const Function& func, | 3006 SequenceNode* Parser::ParseFunc(const Function& func, |
| 2998 Array* default_parameter_values) { | 3007 Array* default_parameter_values) { |
| 2999 TRACE_PARSER("ParseFunc"); | 3008 TRACE_PARSER("ParseFunc"); |
| 3000 Function& saved_innermost_function = | 3009 Function& saved_innermost_function = |
| 3001 Function::Handle(I, innermost_function().raw()); | 3010 Function::Handle(Z, innermost_function().raw()); |
| 3002 innermost_function_ = func.raw(); | 3011 innermost_function_ = func.raw(); |
| 3003 | 3012 |
| 3004 // Save current try index. Try index starts at zero for each function. | 3013 // Save current try index. Try index starts at zero for each function. |
| 3005 intptr_t saved_try_index = last_used_try_index_; | 3014 intptr_t saved_try_index = last_used_try_index_; |
| 3006 last_used_try_index_ = 0; | 3015 last_used_try_index_ = 0; |
| 3007 | 3016 |
| 3008 // In case of nested async functions we also need to save the currently saved | 3017 // In case of nested async functions we also need to save the currently saved |
| 3009 // try context, the corresponding stack variable, and the scope where | 3018 // try context, the corresponding stack variable, and the scope where |
| 3010 // temporaries are added. | 3019 // temporaries are added. |
| 3011 LocalVariable* saved_saved_try_ctx = parsed_function()->saved_try_ctx(); | 3020 LocalVariable* saved_saved_try_ctx = parsed_function()->saved_try_ctx(); |
| 3012 const String& saved_async_saved_try_ctx_name = | 3021 const String& saved_async_saved_try_ctx_name = |
| 3013 String::Handle(I, parsed_function()->async_saved_try_ctx_name()); | 3022 String::Handle(Z, parsed_function()->async_saved_try_ctx_name()); |
| 3014 parsed_function()->reset_saved_try_ctx_vars(); | 3023 parsed_function()->reset_saved_try_ctx_vars(); |
| 3015 LocalScope* saved_async_temp_scope = async_temp_scope_; | 3024 LocalScope* saved_async_temp_scope = async_temp_scope_; |
| 3016 | 3025 |
| 3017 if (func.IsConstructor()) { | 3026 if (func.IsConstructor()) { |
| 3018 SequenceNode* statements = ParseConstructor(func, default_parameter_values); | 3027 SequenceNode* statements = ParseConstructor(func, default_parameter_values); |
| 3019 innermost_function_ = saved_innermost_function.raw(); | 3028 innermost_function_ = saved_innermost_function.raw(); |
| 3020 last_used_try_index_ = saved_try_index; | 3029 last_used_try_index_ = saved_try_index; |
| 3021 return statements; | 3030 return statements; |
| 3022 } | 3031 } |
| 3023 | 3032 |
| 3024 ASSERT(!func.IsConstructor()); | 3033 ASSERT(!func.IsConstructor()); |
| 3025 OpenFunctionBlock(func); // Build local scope for function. | 3034 OpenFunctionBlock(func); // Build local scope for function. |
| 3026 | 3035 |
| 3027 ParamList params; | 3036 ParamList params; |
| 3028 // An instance closure function may capture and access the receiver, but via | 3037 // An instance closure function may capture and access the receiver, but via |
| 3029 // the context and not via the first formal parameter. | 3038 // the context and not via the first formal parameter. |
| 3030 if (func.IsClosureFunction()) { | 3039 if (func.IsClosureFunction()) { |
| 3031 // The first parameter of a closure function is the closure object. | 3040 // The first parameter of a closure function is the closure object. |
| 3032 ASSERT(!func.is_const()); // Closure functions cannot be const. | 3041 ASSERT(!func.is_const()); // Closure functions cannot be const. |
| 3033 params.AddFinalParameter( | 3042 params.AddFinalParameter( |
| 3034 TokenPos(), | 3043 TokenPos(), |
| 3035 &Symbols::ClosureParameter(), | 3044 &Symbols::ClosureParameter(), |
| 3036 &Type::ZoneHandle(I, Type::DynamicType())); | 3045 &Type::ZoneHandle(Z, Type::DynamicType())); |
| 3037 } else if (!func.is_static()) { | 3046 } else if (!func.is_static()) { |
| 3038 // Static functions do not have a receiver. | 3047 // Static functions do not have a receiver. |
| 3039 ASSERT(current_class().raw() == func.Owner()); | 3048 ASSERT(current_class().raw() == func.Owner()); |
| 3040 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); | 3049 params.AddReceiver(ReceiverType(current_class()), func.token_pos()); |
| 3041 } else if (func.IsFactory()) { | 3050 } else if (func.IsFactory()) { |
| 3042 // The first parameter of a factory is the TypeArguments vector of | 3051 // The first parameter of a factory is the TypeArguments vector of |
| 3043 // the type of the instance to be allocated. | 3052 // the type of the instance to be allocated. |
| 3044 params.AddFinalParameter( | 3053 params.AddFinalParameter( |
| 3045 TokenPos(), | 3054 TokenPos(), |
| 3046 &Symbols::TypeArgumentsParameter(), | 3055 &Symbols::TypeArgumentsParameter(), |
| 3047 &Type::ZoneHandle(I, Type::DynamicType())); | 3056 &Type::ZoneHandle(Z, Type::DynamicType())); |
| 3048 } | 3057 } |
| 3049 ASSERT((CurrentToken() == Token::kLPAREN) || | 3058 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 3050 func.IsGetterFunction() || | 3059 func.IsGetterFunction() || |
| 3051 func.is_async_closure()); | 3060 func.is_async_closure()); |
| 3052 const bool allow_explicit_default_values = true; | 3061 const bool allow_explicit_default_values = true; |
| 3053 if (func.IsGetterFunction()) { | 3062 if (func.IsGetterFunction()) { |
| 3054 // Populate function scope with the formal parameters. Since in this case | 3063 // Populate function scope with the formal parameters. Since in this case |
| 3055 // we are compiling a getter this will at most populate the receiver. | 3064 // we are compiling a getter this will at most populate the receiver. |
| 3056 AddFormalParamsToScope(¶ms, current_block_->scope); | 3065 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 3057 } else if (func.is_async_closure()) { | 3066 } else if (func.is_async_closure()) { |
| 3058 // Async closures have two optional parameters: | 3067 // Async closures have two optional parameters: |
| 3059 // * A continuation result. | 3068 // * A continuation result. |
| 3060 // * A continuation error. | 3069 // * A continuation error. |
| 3061 // | 3070 // |
| 3062 // If the error!=null we rethrow the error at the next await. | 3071 // If the error!=null we rethrow the error at the next await. |
| 3063 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType()); | 3072 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 3064 ParamDesc result_param; | 3073 ParamDesc result_param; |
| 3065 result_param.name = &Symbols::AsyncOperationParam(); | 3074 result_param.name = &Symbols::AsyncOperationParam(); |
| 3066 result_param.default_value = &Object::null_instance(); | 3075 result_param.default_value = &Object::null_instance(); |
| 3067 result_param.type = &dynamic_type; | 3076 result_param.type = &dynamic_type; |
| 3068 ParamDesc error_param; | 3077 ParamDesc error_param; |
| 3069 error_param.name = &Symbols::AsyncOperationErrorParam(); | 3078 error_param.name = &Symbols::AsyncOperationErrorParam(); |
| 3070 error_param.default_value = &Object::null_instance(); | 3079 error_param.default_value = &Object::null_instance(); |
| 3071 error_param.type = &dynamic_type; | 3080 error_param.type = &dynamic_type; |
| 3072 params.parameters->Add(result_param); | 3081 params.parameters->Add(result_param); |
| 3073 params.parameters->Add(error_param); | 3082 params.parameters->Add(error_param); |
| 3074 params.num_optional_parameters += 2; | 3083 params.num_optional_parameters += 2; |
| 3075 params.has_optional_positional_parameters = true; | 3084 params.has_optional_positional_parameters = true; |
| 3076 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3085 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 3077 AddFormalParamsToScope(¶ms, current_block_->scope); | 3086 AddFormalParamsToScope(¶ms, current_block_->scope); |
| 3078 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 3087 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 3079 ASSERT(func.NumParameters() == params.parameters->length()); | 3088 ASSERT(func.NumParameters() == params.parameters->length()); |
| 3080 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { | 3089 if (!Function::Handle(func.parent_function()).IsGetterFunction()) { |
| 3081 // Parse and discard any formal parameters. They are accessed as | 3090 // Parse and discard any formal parameters. They are accessed as |
| 3082 // context variables. | 3091 // context variables. |
| 3083 ParamList parse_away; | 3092 ParamList parse_away; |
| 3084 ParseFormalParameterList(allow_explicit_default_values, | 3093 ParseFormalParameterList(allow_explicit_default_values, |
| 3085 false, | 3094 false, |
| 3086 &parse_away); | 3095 &parse_away); |
| 3087 } | 3096 } |
| 3088 } else { | 3097 } else { |
| 3089 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 3098 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 3090 | 3099 |
| 3091 // The number of parameters and their type are not yet set in local | 3100 // The number of parameters and their type are not yet set in local |
| 3092 // functions, since they are not 'top-level' parsed. | 3101 // functions, since they are not 'top-level' parsed. |
| 3093 if (func.IsLocalFunction()) { | 3102 if (func.IsLocalFunction()) { |
| 3094 AddFormalParamsToFunction(¶ms, func); | 3103 AddFormalParamsToFunction(¶ms, func); |
| 3095 } | 3104 } |
| 3096 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); | 3105 SetupDefaultsForOptionalParams(¶ms, default_parameter_values); |
| 3097 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 3106 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 3098 ASSERT(func.NumParameters() == params.parameters->length()); | 3107 ASSERT(func.NumParameters() == params.parameters->length()); |
| 3099 | 3108 |
| 3100 // Check whether the function has any field initializer formal parameters, | 3109 // Check whether the function has any field initializer formal parameters, |
| 3101 // which are not allowed in non-constructor functions. | 3110 // which are not allowed in non-constructor functions. |
| 3102 if (params.has_field_initializer) { | 3111 if (params.has_field_initializer) { |
| 3103 for (int i = 0; i < params.parameters->length(); i++) { | 3112 for (int i = 0; i < params.parameters->length(); i++) { |
| 3104 ParamDesc& param = (*params.parameters)[i]; | 3113 ParamDesc& param = (*params.parameters)[i]; |
| 3105 if (param.is_field_initializer) { | 3114 if (param.is_field_initializer) { |
| 3106 ReportError(param.name_pos, | 3115 ReportError(param.name_pos, |
| 3107 "field initializer only allowed in constructors"); | 3116 "field initializer only allowed in constructors"); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 3123 CaptureInstantiator(); | 3132 CaptureInstantiator(); |
| 3124 } | 3133 } |
| 3125 } | 3134 } |
| 3126 } | 3135 } |
| 3127 | 3136 |
| 3128 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); | 3137 RawFunction::AsyncModifier func_modifier = ParseFunctionModifier(); |
| 3129 func.set_modifier(func_modifier); | 3138 func.set_modifier(func_modifier); |
| 3130 | 3139 |
| 3131 OpenBlock(); // Open a nested scope for the outermost function block. | 3140 OpenBlock(); // Open a nested scope for the outermost function block. |
| 3132 | 3141 |
| 3133 Function& async_closure = Function::ZoneHandle(I); | 3142 Function& async_closure = Function::ZoneHandle(Z); |
| 3134 if (func.IsAsyncFunction() && !func.is_async_closure()) { | 3143 if (func.IsAsyncFunction() && !func.is_async_closure()) { |
| 3135 // The code of an async function is synthesized. Disable debugging. | 3144 // The code of an async function is synthesized. Disable debugging. |
| 3136 func.set_is_debuggable(false); | 3145 func.set_is_debuggable(false); |
| 3137 async_closure = OpenAsyncFunction(func.token_pos()); | 3146 async_closure = OpenAsyncFunction(func.token_pos()); |
| 3138 } else if (func.is_async_closure()) { | 3147 } else if (func.is_async_closure()) { |
| 3139 // The closure containing the body of an async function is debuggable. | 3148 // The closure containing the body of an async function is debuggable. |
| 3140 ASSERT(func.is_debuggable()); | 3149 ASSERT(func.is_debuggable()); |
| 3141 OpenAsyncClosure(); | 3150 OpenAsyncClosure(); |
| 3142 } | 3151 } |
| 3143 | 3152 |
| 3144 BoolScope allow_await(&this->await_is_keyword_, | 3153 BoolScope allow_await(&this->await_is_keyword_, |
| 3145 func.IsAsyncFunction() || func.is_async_closure()); | 3154 func.IsAsyncFunction() || func.is_async_closure()); |
| 3146 intptr_t end_token_pos = 0; | 3155 intptr_t end_token_pos = 0; |
| 3147 if (CurrentToken() == Token::kLBRACE) { | 3156 if (CurrentToken() == Token::kLBRACE) { |
| 3148 ConsumeToken(); | 3157 ConsumeToken(); |
| 3149 if (String::Handle(I, func.name()).Equals(Symbols::EqualOperator())) { | 3158 if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) { |
| 3150 const Class& owner = Class::Handle(I, func.Owner()); | 3159 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3151 if (!owner.IsObjectClass()) { | 3160 if (!owner.IsObjectClass()) { |
| 3152 AddEqualityNullCheck(); | 3161 AddEqualityNullCheck(); |
| 3153 } | 3162 } |
| 3154 } | 3163 } |
| 3155 ParseStatementSequence(); | 3164 ParseStatementSequence(); |
| 3156 end_token_pos = TokenPos(); | 3165 end_token_pos = TokenPos(); |
| 3157 ExpectToken(Token::kRBRACE); | 3166 ExpectToken(Token::kRBRACE); |
| 3158 } else if (CurrentToken() == Token::kARROW) { | 3167 } else if (CurrentToken() == Token::kARROW) { |
| 3159 ConsumeToken(); | 3168 ConsumeToken(); |
| 3160 if (String::Handle(I, func.name()).Equals( | 3169 if (String::Handle(Z, func.name()).Equals( |
| 3161 Symbols::EqualOperator())) { | 3170 Symbols::EqualOperator())) { |
| 3162 const Class& owner = Class::Handle(I, func.Owner()); | 3171 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3163 if (!owner.IsObjectClass()) { | 3172 if (!owner.IsObjectClass()) { |
| 3164 AddEqualityNullCheck(); | 3173 AddEqualityNullCheck(); |
| 3165 } | 3174 } |
| 3166 } | 3175 } |
| 3167 const intptr_t expr_pos = TokenPos(); | 3176 const intptr_t expr_pos = TokenPos(); |
| 3168 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 3177 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 3169 ASSERT(expr != NULL); | 3178 ASSERT(expr != NULL); |
| 3170 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); | 3179 current_block_->statements->Add(new ReturnNode(expr_pos, expr)); |
| 3171 end_token_pos = TokenPos(); | 3180 end_token_pos = TokenPos(); |
| 3172 } else if (IsLiteral("native")) { | 3181 } else if (IsLiteral("native")) { |
| 3173 if (String::Handle(I, func.name()).Equals( | 3182 if (String::Handle(Z, func.name()).Equals( |
| 3174 Symbols::EqualOperator())) { | 3183 Symbols::EqualOperator())) { |
| 3175 const Class& owner = Class::Handle(I, func.Owner()); | 3184 const Class& owner = Class::Handle(Z, func.Owner()); |
| 3176 if (!owner.IsObjectClass()) { | 3185 if (!owner.IsObjectClass()) { |
| 3177 AddEqualityNullCheck(); | 3186 AddEqualityNullCheck(); |
| 3178 } | 3187 } |
| 3179 } | 3188 } |
| 3180 ParseNativeFunctionBlock(¶ms, func); | 3189 ParseNativeFunctionBlock(¶ms, func); |
| 3181 end_token_pos = TokenPos(); | 3190 end_token_pos = TokenPos(); |
| 3182 ExpectSemicolon(); | 3191 ExpectSemicolon(); |
| 3183 } else if (func.is_external()) { | 3192 } else if (func.is_external()) { |
| 3184 // Body of an external method contains a single throw. | 3193 // Body of an external method contains a single throw. |
| 3185 const String& function_name = String::ZoneHandle(I, func.name()); | 3194 const String& function_name = String::ZoneHandle(Z, func.name()); |
| 3186 current_block_->statements->Add( | 3195 current_block_->statements->Add( |
| 3187 ThrowNoSuchMethodError(TokenPos(), | 3196 ThrowNoSuchMethodError(TokenPos(), |
| 3188 Class::Handle(func.Owner()), | 3197 Class::Handle(func.Owner()), |
| 3189 function_name, | 3198 function_name, |
| 3190 NULL, // Ignore arguments. | 3199 NULL, // Ignore arguments. |
| 3191 func.is_static() ? | 3200 func.is_static() ? |
| 3192 InvocationMirror::kStatic : | 3201 InvocationMirror::kStatic : |
| 3193 InvocationMirror::kDynamic, | 3202 InvocationMirror::kDynamic, |
| 3194 InvocationMirror::kMethod, | 3203 InvocationMirror::kMethod, |
| 3195 &func)); // Unpatched external function. | 3204 &func)); // Unpatched external function. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 3217 saved_async_saved_try_ctx_name); | 3226 saved_async_saved_try_ctx_name); |
| 3218 return CloseBlock(); | 3227 return CloseBlock(); |
| 3219 } | 3228 } |
| 3220 | 3229 |
| 3221 | 3230 |
| 3222 void Parser::AddEqualityNullCheck() { | 3231 void Parser::AddEqualityNullCheck() { |
| 3223 AstNode* argument = | 3232 AstNode* argument = |
| 3224 new LoadLocalNode(Scanner::kNoSourcePos, | 3233 new LoadLocalNode(Scanner::kNoSourcePos, |
| 3225 current_block_->scope->parent()->VariableAt(1)); | 3234 current_block_->scope->parent()->VariableAt(1)); |
| 3226 LiteralNode* null_operand = | 3235 LiteralNode* null_operand = |
| 3227 new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(I)); | 3236 new LiteralNode(Scanner::kNoSourcePos, Instance::ZoneHandle(Z)); |
| 3228 ComparisonNode* check_arg = | 3237 ComparisonNode* check_arg = |
| 3229 new ComparisonNode(Scanner::kNoSourcePos, | 3238 new ComparisonNode(Scanner::kNoSourcePos, |
| 3230 Token::kEQ_STRICT, | 3239 Token::kEQ_STRICT, |
| 3231 argument, | 3240 argument, |
| 3232 null_operand); | 3241 null_operand); |
| 3233 ComparisonNode* result = | 3242 ComparisonNode* result = |
| 3234 new ComparisonNode(Scanner::kNoSourcePos, | 3243 new ComparisonNode(Scanner::kNoSourcePos, |
| 3235 Token::kEQ_STRICT, | 3244 Token::kEQ_STRICT, |
| 3236 LoadReceiver(Scanner::kNoSourcePos), | 3245 LoadReceiver(Scanner::kNoSourcePos), |
| 3237 null_operand); | 3246 null_operand); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3305 if (LookaheadToken(1) != Token::kPERIOD) { | 3314 if (LookaheadToken(1) != Token::kPERIOD) { |
| 3306 return LibraryPrefix::null(); | 3315 return LibraryPrefix::null(); |
| 3307 } | 3316 } |
| 3308 const String& ident = *CurrentLiteral(); | 3317 const String& ident = *CurrentLiteral(); |
| 3309 | 3318 |
| 3310 // It is relatively fast to look up a name in the library dictionary, | 3319 // It is relatively fast to look up a name in the library dictionary, |
| 3311 // compared to searching the nested local scopes. Look up the name | 3320 // compared to searching the nested local scopes. Look up the name |
| 3312 // in the library scope and return in the common case where ident is | 3321 // in the library scope and return in the common case where ident is |
| 3313 // not a library prefix. | 3322 // not a library prefix. |
| 3314 LibraryPrefix& prefix = | 3323 LibraryPrefix& prefix = |
| 3315 LibraryPrefix::Handle(I, library_.LookupLocalLibraryPrefix(ident)); | 3324 LibraryPrefix::Handle(Z, library_.LookupLocalLibraryPrefix(ident)); |
| 3316 if (prefix.IsNull()) { | 3325 if (prefix.IsNull()) { |
| 3317 return LibraryPrefix::null(); | 3326 return LibraryPrefix::null(); |
| 3318 } | 3327 } |
| 3319 | 3328 |
| 3320 // A library prefix with the name exists. Now check whether it is | 3329 // A library prefix with the name exists. Now check whether it is |
| 3321 // shadowed by a local definition. | 3330 // shadowed by a local definition. |
| 3322 if (!is_top_level_ && | 3331 if (!is_top_level_ && |
| 3323 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { | 3332 ResolveIdentInLocalScope(TokenPos(), ident, NULL)) { |
| 3324 return LibraryPrefix::null(); | 3333 return LibraryPrefix::null(); |
| 3325 } | 3334 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3372 method->params.Clear(); | 3381 method->params.Clear(); |
| 3373 // Static functions do not have a receiver. | 3382 // Static functions do not have a receiver. |
| 3374 // The first parameter of a factory is the TypeArguments vector of | 3383 // The first parameter of a factory is the TypeArguments vector of |
| 3375 // the type of the instance to be allocated. | 3384 // the type of the instance to be allocated. |
| 3376 if (!method->has_static || method->IsConstructor()) { | 3385 if (!method->has_static || method->IsConstructor()) { |
| 3377 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); | 3386 method->params.AddReceiver(ReceiverType(current_class()), formal_param_pos); |
| 3378 } else if (method->IsFactory()) { | 3387 } else if (method->IsFactory()) { |
| 3379 method->params.AddFinalParameter( | 3388 method->params.AddFinalParameter( |
| 3380 formal_param_pos, | 3389 formal_param_pos, |
| 3381 &Symbols::TypeArgumentsParameter(), | 3390 &Symbols::TypeArgumentsParameter(), |
| 3382 &Type::ZoneHandle(I, Type::DynamicType())); | 3391 &Type::ZoneHandle(Z, Type::DynamicType())); |
| 3383 } | 3392 } |
| 3384 // Constructors have an implicit parameter for the construction phase. | 3393 // Constructors have an implicit parameter for the construction phase. |
| 3385 if (method->IsConstructor()) { | 3394 if (method->IsConstructor()) { |
| 3386 method->params.AddFinalParameter( | 3395 method->params.AddFinalParameter( |
| 3387 TokenPos(), | 3396 TokenPos(), |
| 3388 &Symbols::PhaseParameter(), | 3397 &Symbols::PhaseParameter(), |
| 3389 &Type::ZoneHandle(I, Type::SmiType())); | 3398 &Type::ZoneHandle(Z, Type::SmiType())); |
| 3390 } | 3399 } |
| 3391 if (are_implicitly_final) { | 3400 if (are_implicitly_final) { |
| 3392 method->params.SetImplicitlyFinal(); | 3401 method->params.SetImplicitlyFinal(); |
| 3393 } | 3402 } |
| 3394 if (!method->IsGetter()) { | 3403 if (!method->IsGetter()) { |
| 3395 ParseFormalParameterList(allow_explicit_default_values, | 3404 ParseFormalParameterList(allow_explicit_default_values, |
| 3396 false, | 3405 false, |
| 3397 &method->params); | 3406 &method->params); |
| 3398 } | 3407 } |
| 3399 | 3408 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 3410 CheckOperatorArity(*method); | 3419 CheckOperatorArity(*method); |
| 3411 } | 3420 } |
| 3412 | 3421 |
| 3413 // Mangle the name for getter and setter functions and check function | 3422 // Mangle the name for getter and setter functions and check function |
| 3414 // arity. | 3423 // arity. |
| 3415 if (method->IsGetter() || method->IsSetter()) { | 3424 if (method->IsGetter() || method->IsSetter()) { |
| 3416 int expected_num_parameters = 0; | 3425 int expected_num_parameters = 0; |
| 3417 if (method->IsGetter()) { | 3426 if (method->IsGetter()) { |
| 3418 expected_num_parameters = (method->has_static) ? 0 : 1; | 3427 expected_num_parameters = (method->has_static) ? 0 : 1; |
| 3419 method->dict_name = method->name; | 3428 method->dict_name = method->name; |
| 3420 method->name = &String::ZoneHandle(I, Field::GetterSymbol(*method->name)); | 3429 method->name = &String::ZoneHandle(Z, Field::GetterSymbol(*method->name)); |
| 3421 } else { | 3430 } else { |
| 3422 ASSERT(method->IsSetter()); | 3431 ASSERT(method->IsSetter()); |
| 3423 expected_num_parameters = (method->has_static) ? 1 : 2; | 3432 expected_num_parameters = (method->has_static) ? 1 : 2; |
| 3424 method->dict_name = &String::ZoneHandle(I, | 3433 method->dict_name = &String::ZoneHandle(Z, |
| 3425 String::Concat(*method->name, Symbols::Equals())); | 3434 String::Concat(*method->name, Symbols::Equals())); |
| 3426 method->name = &String::ZoneHandle(I, Field::SetterSymbol(*method->name)); | 3435 method->name = &String::ZoneHandle(Z, Field::SetterSymbol(*method->name)); |
| 3427 } | 3436 } |
| 3428 if ((method->params.num_fixed_parameters != expected_num_parameters) || | 3437 if ((method->params.num_fixed_parameters != expected_num_parameters) || |
| 3429 (method->params.num_optional_parameters != 0)) { | 3438 (method->params.num_optional_parameters != 0)) { |
| 3430 ReportError(method->name_pos, "illegal %s parameters", | 3439 ReportError(method->name_pos, "illegal %s parameters", |
| 3431 method->IsGetter() ? "getter" : "setter"); | 3440 method->IsGetter() ? "getter" : "setter"); |
| 3432 } | 3441 } |
| 3433 } | 3442 } |
| 3434 | 3443 |
| 3435 // Parse redirecting factory constructor. | 3444 // Parse redirecting factory constructor. |
| 3436 Type& redirection_type = Type::Handle(I); | 3445 Type& redirection_type = Type::Handle(Z); |
| 3437 String& redirection_identifier = String::Handle(I); | 3446 String& redirection_identifier = String::Handle(Z); |
| 3438 bool is_redirecting = false; | 3447 bool is_redirecting = false; |
| 3439 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { | 3448 if (method->IsFactory() && (CurrentToken() == Token::kASSIGN)) { |
| 3440 // Default parameter values are disallowed in redirecting factories. | 3449 // Default parameter values are disallowed in redirecting factories. |
| 3441 if (method->params.has_explicit_default_values) { | 3450 if (method->params.has_explicit_default_values) { |
| 3442 ReportError("redirecting factory '%s' may not specify default values " | 3451 ReportError("redirecting factory '%s' may not specify default values " |
| 3443 "for optional parameters", | 3452 "for optional parameters", |
| 3444 method->name->ToCString()); | 3453 method->name->ToCString()); |
| 3445 } | 3454 } |
| 3446 if (method->has_external) { | 3455 if (method->has_external) { |
| 3447 ReportError(TokenPos(), | 3456 ReportError(TokenPos(), |
| 3448 "external factory constructor '%s' may not have redirection", | 3457 "external factory constructor '%s' may not have redirection", |
| 3449 method->name->ToCString()); | 3458 method->name->ToCString()); |
| 3450 } | 3459 } |
| 3451 ConsumeToken(); | 3460 ConsumeToken(); |
| 3452 const intptr_t type_pos = TokenPos(); | 3461 const intptr_t type_pos = TokenPos(); |
| 3453 is_redirecting = true; | 3462 is_redirecting = true; |
| 3454 const bool consume_unresolved_prefix = | 3463 const bool consume_unresolved_prefix = |
| 3455 (LookaheadToken(3) == Token::kLT) || | 3464 (LookaheadToken(3) == Token::kLT) || |
| 3456 (LookaheadToken(3) == Token::kPERIOD); | 3465 (LookaheadToken(3) == Token::kPERIOD); |
| 3457 const AbstractType& type = AbstractType::Handle(I, | 3466 const AbstractType& type = AbstractType::Handle(Z, |
| 3458 ParseType(ClassFinalizer::kResolveTypeParameters, | 3467 ParseType(ClassFinalizer::kResolveTypeParameters, |
| 3459 false, // Deferred types not allowed. | 3468 false, // Deferred types not allowed. |
| 3460 consume_unresolved_prefix)); | 3469 consume_unresolved_prefix)); |
| 3461 if (!type.IsMalformed() && type.IsTypeParameter()) { | 3470 if (!type.IsMalformed() && type.IsTypeParameter()) { |
| 3462 // Replace the type with a malformed type and compile a throw when called. | 3471 // Replace the type with a malformed type and compile a throw when called. |
| 3463 redirection_type = ClassFinalizer::NewFinalizedMalformedType( | 3472 redirection_type = ClassFinalizer::NewFinalizedMalformedType( |
| 3464 Error::Handle(I), // No previous error. | 3473 Error::Handle(Z), // No previous error. |
| 3465 script_, | 3474 script_, |
| 3466 type_pos, | 3475 type_pos, |
| 3467 "factory '%s' may not redirect to type parameter '%s'", | 3476 "factory '%s' may not redirect to type parameter '%s'", |
| 3468 method->name->ToCString(), | 3477 method->name->ToCString(), |
| 3469 String::Handle(I, type.UserVisibleName()).ToCString()); | 3478 String::Handle(Z, type.UserVisibleName()).ToCString()); |
| 3470 } else { | 3479 } else { |
| 3471 // We handle malformed and malbounded redirection type at run time. | 3480 // We handle malformed and malbounded redirection type at run time. |
| 3472 redirection_type ^= type.raw(); | 3481 redirection_type ^= type.raw(); |
| 3473 } | 3482 } |
| 3474 if (CurrentToken() == Token::kPERIOD) { | 3483 if (CurrentToken() == Token::kPERIOD) { |
| 3475 // Named constructor or factory. | 3484 // Named constructor or factory. |
| 3476 ConsumeToken(); | 3485 ConsumeToken(); |
| 3477 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); | 3486 redirection_identifier = ExpectIdentifier("identifier expected")->raw(); |
| 3478 } | 3487 } |
| 3479 } else if (CurrentToken() == Token::kCOLON) { | 3488 } else if (CurrentToken() == Token::kCOLON) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 3492 // Redirected constructor: either this(...) or this.xxx(...). | 3501 // Redirected constructor: either this(...) or this.xxx(...). |
| 3493 is_redirecting = true; | 3502 is_redirecting = true; |
| 3494 if (method->params.has_field_initializer) { | 3503 if (method->params.has_field_initializer) { |
| 3495 // Constructors that redirect to another constructor must not | 3504 // Constructors that redirect to another constructor must not |
| 3496 // initialize any fields using field initializer parameters. | 3505 // initialize any fields using field initializer parameters. |
| 3497 ReportError(formal_param_pos, "Redirecting constructor " | 3506 ReportError(formal_param_pos, "Redirecting constructor " |
| 3498 "may not use field initializer parameters"); | 3507 "may not use field initializer parameters"); |
| 3499 } | 3508 } |
| 3500 ConsumeToken(); // Colon. | 3509 ConsumeToken(); // Colon. |
| 3501 ExpectToken(Token::kTHIS); | 3510 ExpectToken(Token::kTHIS); |
| 3502 String& redir_name = String::ZoneHandle(I, | 3511 String& redir_name = String::ZoneHandle(Z, |
| 3503 String::Concat(members->class_name(), Symbols::Dot())); | 3512 String::Concat(members->class_name(), Symbols::Dot())); |
| 3504 if (CurrentToken() == Token::kPERIOD) { | 3513 if (CurrentToken() == Token::kPERIOD) { |
| 3505 ConsumeToken(); | 3514 ConsumeToken(); |
| 3506 redir_name = String::Concat(redir_name, | 3515 redir_name = String::Concat(redir_name, |
| 3507 *ExpectIdentifier("constructor name expected")); | 3516 *ExpectIdentifier("constructor name expected")); |
| 3508 } | 3517 } |
| 3509 method->redirect_name = &redir_name; | 3518 method->redirect_name = &redir_name; |
| 3510 CheckToken(Token::kLPAREN); | 3519 CheckToken(Token::kLPAREN); |
| 3511 SkipToMatchingParenthesis(); | 3520 SkipToMatchingParenthesis(); |
| 3512 } else { | 3521 } else { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3630 RawFunction::Kind function_kind; | 3639 RawFunction::Kind function_kind; |
| 3631 if (method->IsFactoryOrConstructor()) { | 3640 if (method->IsFactoryOrConstructor()) { |
| 3632 function_kind = RawFunction::kConstructor; | 3641 function_kind = RawFunction::kConstructor; |
| 3633 } else if (method->IsGetter()) { | 3642 } else if (method->IsGetter()) { |
| 3634 function_kind = RawFunction::kGetterFunction; | 3643 function_kind = RawFunction::kGetterFunction; |
| 3635 } else if (method->IsSetter()) { | 3644 } else if (method->IsSetter()) { |
| 3636 function_kind = RawFunction::kSetterFunction; | 3645 function_kind = RawFunction::kSetterFunction; |
| 3637 } else { | 3646 } else { |
| 3638 function_kind = RawFunction::kRegularFunction; | 3647 function_kind = RawFunction::kRegularFunction; |
| 3639 } | 3648 } |
| 3640 Function& func = Function::Handle(I, | 3649 Function& func = Function::Handle(Z, |
| 3641 Function::New(*method->name, | 3650 Function::New(*method->name, |
| 3642 function_kind, | 3651 function_kind, |
| 3643 method->has_static, | 3652 method->has_static, |
| 3644 method->has_const, | 3653 method->has_const, |
| 3645 method->has_abstract, | 3654 method->has_abstract, |
| 3646 method->has_external, | 3655 method->has_external, |
| 3647 method->has_native, | 3656 method->has_native, |
| 3648 current_class(), | 3657 current_class(), |
| 3649 method->decl_begin_pos)); | 3658 method->decl_begin_pos)); |
| 3650 func.set_result_type(*method->type); | 3659 func.set_result_type(*method->type); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3692 } | 3701 } |
| 3693 if (field->has_external) { | 3702 if (field->has_external) { |
| 3694 ReportError("keyword 'external' not allowed in field declaration"); | 3703 ReportError("keyword 'external' not allowed in field declaration"); |
| 3695 } | 3704 } |
| 3696 if (field->has_factory) { | 3705 if (field->has_factory) { |
| 3697 ReportError("keyword 'factory' not allowed in field declaration"); | 3706 ReportError("keyword 'factory' not allowed in field declaration"); |
| 3698 } | 3707 } |
| 3699 if (!field->has_static && field->has_const) { | 3708 if (!field->has_static && field->has_const) { |
| 3700 ReportError(field->name_pos, "instance field may not be 'const'"); | 3709 ReportError(field->name_pos, "instance field may not be 'const'"); |
| 3701 } | 3710 } |
| 3702 Function& getter = Function::Handle(I); | 3711 Function& getter = Function::Handle(Z); |
| 3703 Function& setter = Function::Handle(I); | 3712 Function& setter = Function::Handle(Z); |
| 3704 Field& class_field = Field::ZoneHandle(I); | 3713 Field& class_field = Field::ZoneHandle(Z); |
| 3705 Instance& init_value = Instance::Handle(I); | 3714 Instance& init_value = Instance::Handle(Z); |
| 3706 while (true) { | 3715 while (true) { |
| 3707 bool has_initializer = CurrentToken() == Token::kASSIGN; | 3716 bool has_initializer = CurrentToken() == Token::kASSIGN; |
| 3708 bool has_simple_literal = false; | 3717 bool has_simple_literal = false; |
| 3709 if (has_initializer) { | 3718 if (has_initializer) { |
| 3710 ConsumeToken(); | 3719 ConsumeToken(); |
| 3711 init_value = Object::sentinel().raw(); | 3720 init_value = Object::sentinel().raw(); |
| 3712 // For static fields, the initialization expression will be parsed | 3721 // For static fields, the initialization expression will be parsed |
| 3713 // through the kImplicitStaticFinalGetter method invocation/compilation. | 3722 // through the kImplicitStaticFinalGetter method invocation/compilation. |
| 3714 // For instance fields, the expression is parsed when a constructor | 3723 // For instance fields, the expression is parsed when a constructor |
| 3715 // is compiled. | 3724 // is compiled. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3757 // and rules out many fields from being unnecessary unboxing candidates. | 3766 // and rules out many fields from being unnecessary unboxing candidates. |
| 3758 if (!field->has_static && has_initializer && has_simple_literal) { | 3767 if (!field->has_static && has_initializer && has_simple_literal) { |
| 3759 class_field.RecordStore(init_value); | 3768 class_field.RecordStore(init_value); |
| 3760 } | 3769 } |
| 3761 | 3770 |
| 3762 // For static final fields (this includes static const fields), set value to | 3771 // For static final fields (this includes static const fields), set value to |
| 3763 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. | 3772 // "uninitialized" and create a kImplicitStaticFinalGetter getter method. |
| 3764 if (field->has_static && has_initializer) { | 3773 if (field->has_static && has_initializer) { |
| 3765 class_field.set_value(init_value); | 3774 class_field.set_value(init_value); |
| 3766 if (!has_simple_literal) { | 3775 if (!has_simple_literal) { |
| 3767 String& getter_name = String::Handle(I, | 3776 String& getter_name = String::Handle(Z, |
| 3768 Field::GetterSymbol(*field->name)); | 3777 Field::GetterSymbol(*field->name)); |
| 3769 getter = Function::New(getter_name, | 3778 getter = Function::New(getter_name, |
| 3770 RawFunction::kImplicitStaticFinalGetter, | 3779 RawFunction::kImplicitStaticFinalGetter, |
| 3771 field->has_static, | 3780 field->has_static, |
| 3772 field->has_const, | 3781 field->has_const, |
| 3773 /* is_abstract = */ false, | 3782 /* is_abstract = */ false, |
| 3774 /* is_external = */ false, | 3783 /* is_external = */ false, |
| 3775 /* is_native = */ false, | 3784 /* is_native = */ false, |
| 3776 current_class(), | 3785 current_class(), |
| 3777 field->name_pos); | 3786 field->name_pos); |
| 3778 getter.set_result_type(*field->type); | 3787 getter.set_result_type(*field->type); |
| 3779 getter.set_is_debuggable(false); | 3788 getter.set_is_debuggable(false); |
| 3780 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { | 3789 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { |
| 3781 getter.set_is_visible(false); | 3790 getter.set_is_visible(false); |
| 3782 } | 3791 } |
| 3783 members->AddFunction(getter); | 3792 members->AddFunction(getter); |
| 3784 } | 3793 } |
| 3785 } | 3794 } |
| 3786 | 3795 |
| 3787 // For instance fields, we create implicit getter and setter methods. | 3796 // For instance fields, we create implicit getter and setter methods. |
| 3788 if (!field->has_static) { | 3797 if (!field->has_static) { |
| 3789 String& getter_name = String::Handle(I, | 3798 String& getter_name = String::Handle(Z, |
| 3790 Field::GetterSymbol(*field->name)); | 3799 Field::GetterSymbol(*field->name)); |
| 3791 getter = Function::New(getter_name, RawFunction::kImplicitGetter, | 3800 getter = Function::New(getter_name, RawFunction::kImplicitGetter, |
| 3792 field->has_static, | 3801 field->has_static, |
| 3793 field->has_final, | 3802 field->has_final, |
| 3794 /* is_abstract = */ false, | 3803 /* is_abstract = */ false, |
| 3795 /* is_external = */ false, | 3804 /* is_external = */ false, |
| 3796 /* is_native = */ false, | 3805 /* is_native = */ false, |
| 3797 current_class(), | 3806 current_class(), |
| 3798 field->name_pos); | 3807 field->name_pos); |
| 3799 ParamList params; | 3808 ParamList params; |
| 3800 ASSERT(current_class().raw() == getter.Owner()); | 3809 ASSERT(current_class().raw() == getter.Owner()); |
| 3801 params.AddReceiver(ReceiverType(current_class()), field->name_pos); | 3810 params.AddReceiver(ReceiverType(current_class()), field->name_pos); |
| 3802 getter.set_result_type(*field->type); | 3811 getter.set_result_type(*field->type); |
| 3803 getter.set_is_debuggable(false); | 3812 getter.set_is_debuggable(false); |
| 3804 AddFormalParamsToFunction(¶ms, getter); | 3813 AddFormalParamsToFunction(¶ms, getter); |
| 3805 members->AddFunction(getter); | 3814 members->AddFunction(getter); |
| 3806 if (!field->has_final) { | 3815 if (!field->has_final) { |
| 3807 // Build a setter accessor for non-const fields. | 3816 // Build a setter accessor for non-const fields. |
| 3808 String& setter_name = String::Handle(I, | 3817 String& setter_name = String::Handle(Z, |
| 3809 Field::SetterSymbol(*field->name)); | 3818 Field::SetterSymbol(*field->name)); |
| 3810 setter = Function::New(setter_name, RawFunction::kImplicitSetter, | 3819 setter = Function::New(setter_name, RawFunction::kImplicitSetter, |
| 3811 field->has_static, | 3820 field->has_static, |
| 3812 field->has_final, | 3821 field->has_final, |
| 3813 /* is_abstract = */ false, | 3822 /* is_abstract = */ false, |
| 3814 /* is_external = */ false, | 3823 /* is_external = */ false, |
| 3815 /* is_native = */ false, | 3824 /* is_native = */ false, |
| 3816 current_class(), | 3825 current_class(), |
| 3817 field->name_pos); | 3826 field->name_pos); |
| 3818 ParamList params; | 3827 ParamList params; |
| 3819 ASSERT(current_class().raw() == setter.Owner()); | 3828 ASSERT(current_class().raw() == setter.Owner()); |
| 3820 params.AddReceiver(ReceiverType(current_class()), field->name_pos); | 3829 params.AddReceiver(ReceiverType(current_class()), field->name_pos); |
| 3821 params.AddFinalParameter(TokenPos(), | 3830 params.AddFinalParameter(TokenPos(), |
| 3822 &Symbols::Value(), | 3831 &Symbols::Value(), |
| 3823 field->type); | 3832 field->type); |
| 3824 setter.set_result_type(Type::Handle(I, Type::VoidType())); | 3833 setter.set_result_type(Type::Handle(Z, Type::VoidType())); |
| 3825 setter.set_is_debuggable(false); | 3834 setter.set_is_debuggable(false); |
| 3826 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { | 3835 if (library_.is_dart_scheme() && library_.IsPrivate(*field->name)) { |
| 3827 setter.set_is_visible(false); | 3836 setter.set_is_visible(false); |
| 3828 } | 3837 } |
| 3829 AddFormalParamsToFunction(¶ms, setter); | 3838 AddFormalParamsToFunction(¶ms, setter); |
| 3830 members->AddFunction(setter); | 3839 members->AddFunction(setter); |
| 3831 } | 3840 } |
| 3832 } | 3841 } |
| 3833 | 3842 |
| 3834 if (CurrentToken() != Token::kCOMMA) { | 3843 if (CurrentToken() != Token::kCOMMA) { |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3918 if (CurrentToken() == Token::kVAR) { | 3927 if (CurrentToken() == Token::kVAR) { |
| 3919 if (member.has_const) { | 3928 if (member.has_const) { |
| 3920 ReportError("identifier expected after 'const'"); | 3929 ReportError("identifier expected after 'const'"); |
| 3921 } | 3930 } |
| 3922 if (member.has_final) { | 3931 if (member.has_final) { |
| 3923 ReportError("identifier expected after 'final'"); | 3932 ReportError("identifier expected after 'final'"); |
| 3924 } | 3933 } |
| 3925 ConsumeToken(); | 3934 ConsumeToken(); |
| 3926 member.has_var = true; | 3935 member.has_var = true; |
| 3927 // The member type is the 'dynamic' type. | 3936 // The member type is the 'dynamic' type. |
| 3928 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 3937 member.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 3929 } else if (CurrentToken() == Token::kFACTORY) { | 3938 } else if (CurrentToken() == Token::kFACTORY) { |
| 3930 ConsumeToken(); | 3939 ConsumeToken(); |
| 3931 if (member.has_static) { | 3940 if (member.has_static) { |
| 3932 ReportError("factory method cannot be explicitly marked static"); | 3941 ReportError("factory method cannot be explicitly marked static"); |
| 3933 } | 3942 } |
| 3934 member.has_factory = true; | 3943 member.has_factory = true; |
| 3935 member.has_static = true; | 3944 member.has_static = true; |
| 3936 // The result type depends on the name of the factory method. | 3945 // The result type depends on the name of the factory method. |
| 3937 } | 3946 } |
| 3938 // Optionally parse a type. | 3947 // Optionally parse a type. |
| 3939 if (CurrentToken() == Token::kVOID) { | 3948 if (CurrentToken() == Token::kVOID) { |
| 3940 if (member.has_var || member.has_factory) { | 3949 if (member.has_var || member.has_factory) { |
| 3941 ReportError("void not expected"); | 3950 ReportError("void not expected"); |
| 3942 } | 3951 } |
| 3943 ConsumeToken(); | 3952 ConsumeToken(); |
| 3944 ASSERT(member.type == NULL); | 3953 ASSERT(member.type == NULL); |
| 3945 member.type = &Type::ZoneHandle(I, Type::VoidType()); | 3954 member.type = &Type::ZoneHandle(Z, Type::VoidType()); |
| 3946 } else if (CurrentToken() == Token::kIDENT) { | 3955 } else if (CurrentToken() == Token::kIDENT) { |
| 3947 // This is either a type name or the name of a method/constructor/field. | 3956 // This is either a type name or the name of a method/constructor/field. |
| 3948 if ((member.type == NULL) && !member.has_factory) { | 3957 if ((member.type == NULL) && !member.has_factory) { |
| 3949 // We have not seen a member type yet, so we check if the next | 3958 // We have not seen a member type yet, so we check if the next |
| 3950 // identifier could represent a type before parsing it. | 3959 // identifier could represent a type before parsing it. |
| 3951 Token::Kind follower = LookaheadToken(1); | 3960 Token::Kind follower = LookaheadToken(1); |
| 3952 // We have an identifier followed by a 'follower' token. | 3961 // We have an identifier followed by a 'follower' token. |
| 3953 // We either parse a type or assume that no type is specified. | 3962 // We either parse a type or assume that no type is specified. |
| 3954 if ((follower == Token::kLT) || // Parameterized type. | 3963 if ((follower == Token::kLT) || // Parameterized type. |
| 3955 (follower == Token::kGET) || // Getter following a type. | 3964 (follower == Token::kGET) || // Getter following a type. |
| 3956 (follower == Token::kSET) || // Setter following a type. | 3965 (follower == Token::kSET) || // Setter following a type. |
| 3957 (follower == Token::kOPERATOR) || // Operator following a type. | 3966 (follower == Token::kOPERATOR) || // Operator following a type. |
| 3958 (Token::IsIdentifier(follower)) || // Member name following a type. | 3967 (Token::IsIdentifier(follower)) || // Member name following a type. |
| 3959 ((follower == Token::kPERIOD) && // Qualified class name of type, | 3968 ((follower == Token::kPERIOD) && // Qualified class name of type, |
| 3960 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. | 3969 (LookaheadToken(3) != Token::kLPAREN))) { // but not a named constr. |
| 3961 ASSERT(is_top_level_); | 3970 ASSERT(is_top_level_); |
| 3962 // The declared type of fields is never ignored, even in unchecked mode, | 3971 // The declared type of fields is never ignored, even in unchecked mode, |
| 3963 // because getters and setters could be closurized at some time (not | 3972 // because getters and setters could be closurized at some time (not |
| 3964 // supported yet). | 3973 // supported yet). |
| 3965 member.type = &AbstractType::ZoneHandle(I, | 3974 member.type = &AbstractType::ZoneHandle(Z, |
| 3966 ParseType(ClassFinalizer::kResolveTypeParameters)); | 3975 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 3967 } | 3976 } |
| 3968 } | 3977 } |
| 3969 } | 3978 } |
| 3970 | 3979 |
| 3971 // Optionally parse a (possibly named) constructor name or factory. | 3980 // Optionally parse a (possibly named) constructor name or factory. |
| 3972 if (IsIdentifier() && | 3981 if (IsIdentifier() && |
| 3973 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { | 3982 (CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) { |
| 3974 member.name_pos = TokenPos(); | 3983 member.name_pos = TokenPos(); |
| 3975 member.name = CurrentLiteral(); // Unqualified identifier. | 3984 member.name = CurrentLiteral(); // Unqualified identifier. |
| 3976 ConsumeToken(); | 3985 ConsumeToken(); |
| 3977 if (member.has_factory) { | 3986 if (member.has_factory) { |
| 3978 // The factory name may be qualified, but the first identifier must match | 3987 // The factory name may be qualified, but the first identifier must match |
| 3979 // the name of the immediately enclosing class. | 3988 // the name of the immediately enclosing class. |
| 3980 if (!member.name->Equals(members->class_name())) { | 3989 if (!member.name->Equals(members->class_name())) { |
| 3981 ReportError(member.name_pos, "factory name must be '%s'", | 3990 ReportError(member.name_pos, "factory name must be '%s'", |
| 3982 members->class_name().ToCString()); | 3991 members->class_name().ToCString()); |
| 3983 } | 3992 } |
| 3984 } else if (member.has_static) { | 3993 } else if (member.has_static) { |
| 3985 ReportError(member.name_pos, "constructor cannot be static"); | 3994 ReportError(member.name_pos, "constructor cannot be static"); |
| 3986 } | 3995 } |
| 3987 if (member.type != NULL) { | 3996 if (member.type != NULL) { |
| 3988 ReportError(member.name_pos, "constructor must not specify return type"); | 3997 ReportError(member.name_pos, "constructor must not specify return type"); |
| 3989 } | 3998 } |
| 3990 // Do not bypass class resolution by using current_class() directly, since | 3999 // Do not bypass class resolution by using current_class() directly, since |
| 3991 // it may be a patch class. | 4000 // it may be a patch class. |
| 3992 const Object& result_type_class = Object::Handle(I, | 4001 const Object& result_type_class = Object::Handle(Z, |
| 3993 UnresolvedClass::New(LibraryPrefix::Handle(I), | 4002 UnresolvedClass::New(LibraryPrefix::Handle(Z), |
| 3994 *member.name, | 4003 *member.name, |
| 3995 member.name_pos)); | 4004 member.name_pos)); |
| 3996 // The type arguments of the result type are the type parameters of the | 4005 // The type arguments of the result type are the type parameters of the |
| 3997 // current class. Note that in the case of a patch class, they are copied | 4006 // current class. Note that in the case of a patch class, they are copied |
| 3998 // from the class being patched. | 4007 // from the class being patched. |
| 3999 member.type = &Type::ZoneHandle(I, Type::New( | 4008 member.type = &Type::ZoneHandle(Z, Type::New( |
| 4000 result_type_class, | 4009 result_type_class, |
| 4001 TypeArguments::Handle(I, current_class().type_parameters()), | 4010 TypeArguments::Handle(Z, current_class().type_parameters()), |
| 4002 member.name_pos)); | 4011 member.name_pos)); |
| 4003 | 4012 |
| 4004 // We must be dealing with a constructor or named constructor. | 4013 // We must be dealing with a constructor or named constructor. |
| 4005 member.kind = RawFunction::kConstructor; | 4014 member.kind = RawFunction::kConstructor; |
| 4006 *member.name = String::Concat(*member.name, Symbols::Dot()); | 4015 *member.name = String::Concat(*member.name, Symbols::Dot()); |
| 4007 if (CurrentToken() == Token::kPERIOD) { | 4016 if (CurrentToken() == Token::kPERIOD) { |
| 4008 // Named constructor. | 4017 // Named constructor. |
| 4009 ConsumeToken(); | 4018 ConsumeToken(); |
| 4010 member.dict_name = ExpectIdentifier("identifier expected"); | 4019 member.dict_name = ExpectIdentifier("identifier expected"); |
| 4011 *member.name = String::Concat(*member.name, *member.dict_name); | 4020 *member.name = String::Concat(*member.name, *member.dict_name); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 4030 (LookaheadToken(1) != Token::kCOMMA) && | 4039 (LookaheadToken(1) != Token::kCOMMA) && |
| 4031 (LookaheadToken(1) != Token::kSEMICOLON)) { | 4040 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 4032 ConsumeToken(); | 4041 ConsumeToken(); |
| 4033 member.kind = RawFunction::kSetterFunction; | 4042 member.kind = RawFunction::kSetterFunction; |
| 4034 member.name_pos = this->TokenPos(); | 4043 member.name_pos = this->TokenPos(); |
| 4035 member.name = ExpectIdentifier("identifier expected"); | 4044 member.name = ExpectIdentifier("identifier expected"); |
| 4036 CheckToken(Token::kLPAREN); | 4045 CheckToken(Token::kLPAREN); |
| 4037 // The grammar allows a return type, so member.type is not always NULL here. | 4046 // The grammar allows a return type, so member.type is not always NULL here. |
| 4038 // If no return type is specified, the return type of the setter is dynamic. | 4047 // If no return type is specified, the return type of the setter is dynamic. |
| 4039 if (member.type == NULL) { | 4048 if (member.type == NULL) { |
| 4040 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 4049 member.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 4041 } | 4050 } |
| 4042 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && | 4051 } else if ((CurrentToken() == Token::kOPERATOR) && !member.has_var && |
| 4043 (LookaheadToken(1) != Token::kLPAREN) && | 4052 (LookaheadToken(1) != Token::kLPAREN) && |
| 4044 (LookaheadToken(1) != Token::kASSIGN) && | 4053 (LookaheadToken(1) != Token::kASSIGN) && |
| 4045 (LookaheadToken(1) != Token::kCOMMA) && | 4054 (LookaheadToken(1) != Token::kCOMMA) && |
| 4046 (LookaheadToken(1) != Token::kSEMICOLON)) { | 4055 (LookaheadToken(1) != Token::kSEMICOLON)) { |
| 4047 ConsumeToken(); | 4056 ConsumeToken(); |
| 4048 if (!Token::CanBeOverloaded(CurrentToken())) { | 4057 if (!Token::CanBeOverloaded(CurrentToken())) { |
| 4049 ReportError("invalid operator overloading"); | 4058 ReportError("invalid operator overloading"); |
| 4050 } | 4059 } |
| 4051 if (member.has_static) { | 4060 if (member.has_static) { |
| 4052 ReportError("operator overloading functions cannot be static"); | 4061 ReportError("operator overloading functions cannot be static"); |
| 4053 } | 4062 } |
| 4054 member.operator_token = CurrentToken(); | 4063 member.operator_token = CurrentToken(); |
| 4055 member.has_operator = true; | 4064 member.has_operator = true; |
| 4056 member.kind = RawFunction::kRegularFunction; | 4065 member.kind = RawFunction::kRegularFunction; |
| 4057 member.name_pos = this->TokenPos(); | 4066 member.name_pos = this->TokenPos(); |
| 4058 member.name = | 4067 member.name = |
| 4059 &String::ZoneHandle(I, Symbols::New(Token::Str(member.operator_token))); | 4068 &String::ZoneHandle(Z, Symbols::New(Token::Str(member.operator_token))); |
| 4060 ConsumeToken(); | 4069 ConsumeToken(); |
| 4061 } else if (IsIdentifier()) { | 4070 } else if (IsIdentifier()) { |
| 4062 member.name = CurrentLiteral(); | 4071 member.name = CurrentLiteral(); |
| 4063 member.name_pos = TokenPos(); | 4072 member.name_pos = TokenPos(); |
| 4064 ConsumeToken(); | 4073 ConsumeToken(); |
| 4065 } else { | 4074 } else { |
| 4066 ReportError("identifier expected"); | 4075 ReportError("identifier expected"); |
| 4067 } | 4076 } |
| 4068 | 4077 |
| 4069 ASSERT(member.name != NULL); | 4078 ASSERT(member.name != NULL); |
| 4070 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { | 4079 if (CurrentToken() == Token::kLPAREN || member.IsGetter()) { |
| 4071 // Constructor or method. | 4080 // Constructor or method. |
| 4072 if (member.type == NULL) { | 4081 if (member.type == NULL) { |
| 4073 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 4082 member.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 4074 } | 4083 } |
| 4075 ASSERT(member.IsFactory() == member.has_factory); | 4084 ASSERT(member.IsFactory() == member.has_factory); |
| 4076 ParseMethodOrConstructor(members, &member); | 4085 ParseMethodOrConstructor(members, &member); |
| 4077 } else if (CurrentToken() == Token::kSEMICOLON || | 4086 } else if (CurrentToken() == Token::kSEMICOLON || |
| 4078 CurrentToken() == Token::kCOMMA || | 4087 CurrentToken() == Token::kCOMMA || |
| 4079 CurrentToken() == Token::kASSIGN) { | 4088 CurrentToken() == Token::kASSIGN) { |
| 4080 // Field definition. | 4089 // Field definition. |
| 4081 if (member.has_const) { | 4090 if (member.has_const) { |
| 4082 // const fields are implicitly final. | 4091 // const fields are implicitly final. |
| 4083 member.has_final = true; | 4092 member.has_final = true; |
| 4084 } | 4093 } |
| 4085 if (member.type == NULL) { | 4094 if (member.type == NULL) { |
| 4086 if (member.has_final) { | 4095 if (member.has_final) { |
| 4087 member.type = &Type::ZoneHandle(I, Type::DynamicType()); | 4096 member.type = &Type::ZoneHandle(Z, Type::DynamicType()); |
| 4088 } else { | 4097 } else { |
| 4089 ReportError("missing 'var', 'final', 'const' or type" | 4098 ReportError("missing 'var', 'final', 'const' or type" |
| 4090 " in field declaration"); | 4099 " in field declaration"); |
| 4091 } | 4100 } |
| 4092 } | 4101 } |
| 4093 ParseFieldDefinition(members, &member); | 4102 ParseFieldDefinition(members, &member); |
| 4094 } else { | 4103 } else { |
| 4095 UnexpectedToken(); | 4104 UnexpectedToken(); |
| 4096 } | 4105 } |
| 4097 current_member_ = NULL; | 4106 current_member_ = NULL; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 4123 break; | 4132 break; |
| 4124 } | 4133 } |
| 4125 } else if (CurrentToken() == Token::kRBRACE) { | 4134 } else if (CurrentToken() == Token::kRBRACE) { |
| 4126 break; | 4135 break; |
| 4127 } else { | 4136 } else { |
| 4128 ReportError(", or } expected"); | 4137 ReportError(", or } expected"); |
| 4129 } | 4138 } |
| 4130 } | 4139 } |
| 4131 ExpectToken(Token::kRBRACE); | 4140 ExpectToken(Token::kRBRACE); |
| 4132 | 4141 |
| 4133 Object& obj = Object::Handle(I, library_.LookupLocalObject(*enum_name)); | 4142 Object& obj = Object::Handle(Z, library_.LookupLocalObject(*enum_name)); |
| 4134 if (!obj.IsNull()) { | 4143 if (!obj.IsNull()) { |
| 4135 ReportError(enum_pos, "'%s' is already defined", enum_name->ToCString()); | 4144 ReportError(enum_pos, "'%s' is already defined", enum_name->ToCString()); |
| 4136 } | 4145 } |
| 4137 Class& cls = Class::Handle(I); | 4146 Class& cls = Class::Handle(Z); |
| 4138 cls = Class::New(*enum_name, script_, enum_pos); | 4147 cls = Class::New(*enum_name, script_, enum_pos); |
| 4139 cls.set_library(library_); | 4148 cls.set_library(library_); |
| 4140 library_.AddClass(cls); | 4149 library_.AddClass(cls); |
| 4141 cls.set_is_synthesized_class(); | 4150 cls.set_is_synthesized_class(); |
| 4142 cls.set_is_enum_class(); | 4151 cls.set_is_enum_class(); |
| 4143 if (metadata_pos >= 0) { | 4152 if (metadata_pos >= 0) { |
| 4144 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); | 4153 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 4145 } | 4154 } |
| 4146 cls.set_super_type(Type::Handle(I, Type::ObjectType())); | 4155 cls.set_super_type(Type::Handle(Z, Type::ObjectType())); |
| 4147 pending_classes.Add(cls, Heap::kOld); | 4156 pending_classes.Add(cls, Heap::kOld); |
| 4148 } | 4157 } |
| 4149 | 4158 |
| 4150 | 4159 |
| 4151 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, | 4160 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes, |
| 4152 const Class& toplevel_class, | 4161 const Class& toplevel_class, |
| 4153 intptr_t metadata_pos) { | 4162 intptr_t metadata_pos) { |
| 4154 TRACE_PARSER("ParseClassDeclaration"); | 4163 TRACE_PARSER("ParseClassDeclaration"); |
| 4155 bool is_patch = false; | 4164 bool is_patch = false; |
| 4156 bool is_abstract = false; | 4165 bool is_abstract = false; |
| 4157 if (is_patch_source() && | 4166 if (is_patch_source() && |
| 4158 (CurrentToken() == Token::kIDENT) && | 4167 (CurrentToken() == Token::kIDENT) && |
| 4159 CurrentLiteral()->Equals("patch")) { | 4168 CurrentLiteral()->Equals("patch")) { |
| 4160 ConsumeToken(); | 4169 ConsumeToken(); |
| 4161 is_patch = true; | 4170 is_patch = true; |
| 4162 } else if (CurrentToken() == Token::kABSTRACT) { | 4171 } else if (CurrentToken() == Token::kABSTRACT) { |
| 4163 is_abstract = true; | 4172 is_abstract = true; |
| 4164 ConsumeToken(); | 4173 ConsumeToken(); |
| 4165 } | 4174 } |
| 4166 ExpectToken(Token::kCLASS); | 4175 ExpectToken(Token::kCLASS); |
| 4167 const intptr_t classname_pos = TokenPos(); | 4176 const intptr_t classname_pos = TokenPos(); |
| 4168 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4177 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4169 if (FLAG_trace_parser) { | 4178 if (FLAG_trace_parser) { |
| 4170 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 4179 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 4171 } | 4180 } |
| 4172 Class& cls = Class::Handle(I); | 4181 Class& cls = Class::Handle(Z); |
| 4173 TypeArguments& orig_type_parameters = TypeArguments::Handle(I); | 4182 TypeArguments& orig_type_parameters = TypeArguments::Handle(Z); |
| 4174 Object& obj = Object::Handle(I, library_.LookupLocalObject(class_name)); | 4183 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
| 4175 if (obj.IsNull()) { | 4184 if (obj.IsNull()) { |
| 4176 if (is_patch) { | 4185 if (is_patch) { |
| 4177 ReportError(classname_pos, "missing class '%s' cannot be patched", | 4186 ReportError(classname_pos, "missing class '%s' cannot be patched", |
| 4178 class_name.ToCString()); | 4187 class_name.ToCString()); |
| 4179 } | 4188 } |
| 4180 cls = Class::New(class_name, script_, classname_pos); | 4189 cls = Class::New(class_name, script_, classname_pos); |
| 4181 library_.AddClass(cls); | 4190 library_.AddClass(cls); |
| 4182 } else { | 4191 } else { |
| 4183 if (!obj.IsClass()) { | 4192 if (!obj.IsClass()) { |
| 4184 ReportError(classname_pos, "'%s' is already defined", | 4193 ReportError(classname_pos, "'%s' is already defined", |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 4208 cls.set_token_pos(classname_pos); | 4217 cls.set_token_pos(classname_pos); |
| 4209 } | 4218 } |
| 4210 } | 4219 } |
| 4211 ASSERT(!cls.IsNull()); | 4220 ASSERT(!cls.IsNull()); |
| 4212 ASSERT(cls.functions() == Object::empty_array().raw()); | 4221 ASSERT(cls.functions() == Object::empty_array().raw()); |
| 4213 set_current_class(cls); | 4222 set_current_class(cls); |
| 4214 ParseTypeParameters(cls); | 4223 ParseTypeParameters(cls); |
| 4215 if (is_patch) { | 4224 if (is_patch) { |
| 4216 // Check that the new type parameters are identical to the original ones. | 4225 // Check that the new type parameters are identical to the original ones. |
| 4217 const TypeArguments& new_type_parameters = | 4226 const TypeArguments& new_type_parameters = |
| 4218 TypeArguments::Handle(I, cls.type_parameters()); | 4227 TypeArguments::Handle(Z, cls.type_parameters()); |
| 4219 const int new_type_params_count = | 4228 const int new_type_params_count = |
| 4220 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); | 4229 new_type_parameters.IsNull() ? 0 : new_type_parameters.Length(); |
| 4221 const int orig_type_params_count = | 4230 const int orig_type_params_count = |
| 4222 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); | 4231 orig_type_parameters.IsNull() ? 0 : orig_type_parameters.Length(); |
| 4223 if (new_type_params_count != orig_type_params_count) { | 4232 if (new_type_params_count != orig_type_params_count) { |
| 4224 ReportError(classname_pos, | 4233 ReportError(classname_pos, |
| 4225 "class '%s' must be patched with identical type parameters", | 4234 "class '%s' must be patched with identical type parameters", |
| 4226 class_name.ToCString()); | 4235 class_name.ToCString()); |
| 4227 } | 4236 } |
| 4228 TypeParameter& new_type_param = TypeParameter::Handle(I); | 4237 TypeParameter& new_type_param = TypeParameter::Handle(Z); |
| 4229 TypeParameter& orig_type_param = TypeParameter::Handle(I); | 4238 TypeParameter& orig_type_param = TypeParameter::Handle(Z); |
| 4230 String& new_name = String::Handle(I); | 4239 String& new_name = String::Handle(Z); |
| 4231 String& orig_name = String::Handle(I); | 4240 String& orig_name = String::Handle(Z); |
| 4232 AbstractType& new_bound = AbstractType::Handle(I); | 4241 AbstractType& new_bound = AbstractType::Handle(Z); |
| 4233 AbstractType& orig_bound = AbstractType::Handle(I); | 4242 AbstractType& orig_bound = AbstractType::Handle(Z); |
| 4234 for (int i = 0; i < new_type_params_count; i++) { | 4243 for (int i = 0; i < new_type_params_count; i++) { |
| 4235 new_type_param ^= new_type_parameters.TypeAt(i); | 4244 new_type_param ^= new_type_parameters.TypeAt(i); |
| 4236 orig_type_param ^= orig_type_parameters.TypeAt(i); | 4245 orig_type_param ^= orig_type_parameters.TypeAt(i); |
| 4237 new_name = new_type_param.name(); | 4246 new_name = new_type_param.name(); |
| 4238 orig_name = orig_type_param.name(); | 4247 orig_name = orig_type_param.name(); |
| 4239 if (!new_name.Equals(orig_name)) { | 4248 if (!new_name.Equals(orig_name)) { |
| 4240 ReportError(new_type_param.token_pos(), | 4249 ReportError(new_type_param.token_pos(), |
| 4241 "type parameter '%s' of patch class '%s' does not match " | 4250 "type parameter '%s' of patch class '%s' does not match " |
| 4242 "original type parameter '%s'", | 4251 "original type parameter '%s'", |
| 4243 new_name.ToCString(), | 4252 new_name.ToCString(), |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 4266 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); | 4275 library_.AddClassMetadata(cls, toplevel_class, metadata_pos); |
| 4267 } | 4276 } |
| 4268 | 4277 |
| 4269 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); | 4278 const bool is_mixin_declaration = (CurrentToken() == Token::kASSIGN); |
| 4270 if (is_mixin_declaration && is_patch) { | 4279 if (is_mixin_declaration && is_patch) { |
| 4271 ReportError(classname_pos, | 4280 ReportError(classname_pos, |
| 4272 "mixin application '%s' may not be a patch class", | 4281 "mixin application '%s' may not be a patch class", |
| 4273 class_name.ToCString()); | 4282 class_name.ToCString()); |
| 4274 } | 4283 } |
| 4275 | 4284 |
| 4276 AbstractType& super_type = Type::Handle(I); | 4285 AbstractType& super_type = Type::Handle(Z); |
| 4277 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { | 4286 if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) { |
| 4278 ConsumeToken(); // extends or = | 4287 ConsumeToken(); // extends or = |
| 4279 const intptr_t type_pos = TokenPos(); | 4288 const intptr_t type_pos = TokenPos(); |
| 4280 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4289 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4281 if (super_type.IsMalformedOrMalbounded()) { | 4290 if (super_type.IsMalformedOrMalbounded()) { |
| 4282 ReportError(Error::Handle(I, super_type.error())); | 4291 ReportError(Error::Handle(Z, super_type.error())); |
| 4283 } | 4292 } |
| 4284 if (super_type.IsDynamicType()) { | 4293 if (super_type.IsDynamicType()) { |
| 4285 // Unlikely here, since super type is not resolved yet. | 4294 // Unlikely here, since super type is not resolved yet. |
| 4286 ReportError(type_pos, | 4295 ReportError(type_pos, |
| 4287 "class '%s' may not extend 'dynamic'", | 4296 "class '%s' may not extend 'dynamic'", |
| 4288 class_name.ToCString()); | 4297 class_name.ToCString()); |
| 4289 } | 4298 } |
| 4290 if (super_type.IsTypeParameter()) { | 4299 if (super_type.IsTypeParameter()) { |
| 4291 ReportError(type_pos, | 4300 ReportError(type_pos, |
| 4292 "class '%s' may not extend type parameter '%s'", | 4301 "class '%s' may not extend type parameter '%s'", |
| 4293 class_name.ToCString(), | 4302 class_name.ToCString(), |
| 4294 String::Handle(I, | 4303 String::Handle(Z, |
| 4295 super_type.UserVisibleName()).ToCString()); | 4304 super_type.UserVisibleName()).ToCString()); |
| 4296 } | 4305 } |
| 4297 // The class finalizer will check whether the super type is malbounded. | 4306 // The class finalizer will check whether the super type is malbounded. |
| 4298 if (is_mixin_declaration) { | 4307 if (is_mixin_declaration) { |
| 4299 if (CurrentToken() != Token::kWITH) { | 4308 if (CurrentToken() != Token::kWITH) { |
| 4300 ReportError("mixin application clause 'with type' expected"); | 4309 ReportError("mixin application clause 'with type' expected"); |
| 4301 } | 4310 } |
| 4302 cls.set_is_mixin_app_alias(); | 4311 cls.set_is_mixin_app_alias(); |
| 4303 cls.set_is_synthesized_class(); | 4312 cls.set_is_synthesized_class(); |
| 4304 } | 4313 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4337 ExpectToken(Token::kRBRACE); | 4346 ExpectToken(Token::kRBRACE); |
| 4338 } | 4347 } |
| 4339 } | 4348 } |
| 4340 | 4349 |
| 4341 | 4350 |
| 4342 void Parser::ParseClassDefinition(const Class& cls) { | 4351 void Parser::ParseClassDefinition(const Class& cls) { |
| 4343 TRACE_PARSER("ParseClassDefinition"); | 4352 TRACE_PARSER("ParseClassDefinition"); |
| 4344 CompilerStats::num_classes_compiled++; | 4353 CompilerStats::num_classes_compiled++; |
| 4345 set_current_class(cls); | 4354 set_current_class(cls); |
| 4346 is_top_level_ = true; | 4355 is_top_level_ = true; |
| 4347 String& class_name = String::Handle(I, cls.Name()); | 4356 String& class_name = String::Handle(Z, cls.Name()); |
| 4348 const intptr_t class_pos = TokenPos(); | 4357 const intptr_t class_pos = TokenPos(); |
| 4349 ClassDesc members(cls, class_name, false, class_pos); | 4358 ClassDesc members(cls, class_name, false, class_pos); |
| 4350 while (CurrentToken() != Token::kLBRACE) { | 4359 while (CurrentToken() != Token::kLBRACE) { |
| 4351 ConsumeToken(); | 4360 ConsumeToken(); |
| 4352 } | 4361 } |
| 4353 ExpectToken(Token::kLBRACE); | 4362 ExpectToken(Token::kLBRACE); |
| 4354 while (CurrentToken() != Token::kRBRACE) { | 4363 while (CurrentToken() != Token::kRBRACE) { |
| 4355 intptr_t metadata_pos = SkipMetadata(); | 4364 intptr_t metadata_pos = SkipMetadata(); |
| 4356 ParseClassMemberDefinition(&members, metadata_pos); | 4365 ParseClassMemberDefinition(&members, metadata_pos); |
| 4357 } | 4366 } |
| 4358 ExpectToken(Token::kRBRACE); | 4367 ExpectToken(Token::kRBRACE); |
| 4359 | 4368 |
| 4360 CheckConstructors(&members); | 4369 CheckConstructors(&members); |
| 4361 | 4370 |
| 4362 // Need to compute this here since MakeArray() will clear the | 4371 // Need to compute this here since MakeArray() will clear the |
| 4363 // functions array in members. | 4372 // functions array in members. |
| 4364 const bool need_implicit_constructor = | 4373 const bool need_implicit_constructor = |
| 4365 !members.has_constructor() && !cls.is_patch(); | 4374 !members.has_constructor() && !cls.is_patch(); |
| 4366 | 4375 |
| 4367 cls.AddFields(members.fields()); | 4376 cls.AddFields(members.fields()); |
| 4368 | 4377 |
| 4369 // Creating a new array for functions marks the class as parsed. | 4378 // Creating a new array for functions marks the class as parsed. |
| 4370 const Array& array = Array::Handle(I, Array::MakeArray(members.functions())); | 4379 const Array& array = Array::Handle(Z, Array::MakeArray(members.functions())); |
| 4371 cls.SetFunctions(array); | 4380 cls.SetFunctions(array); |
| 4372 | 4381 |
| 4373 // Add an implicit constructor if no explicit constructor is present. | 4382 // Add an implicit constructor if no explicit constructor is present. |
| 4374 // No implicit constructors are needed for patch classes. | 4383 // No implicit constructors are needed for patch classes. |
| 4375 if (need_implicit_constructor) { | 4384 if (need_implicit_constructor) { |
| 4376 AddImplicitConstructor(cls); | 4385 AddImplicitConstructor(cls); |
| 4377 } | 4386 } |
| 4378 | 4387 |
| 4379 if (cls.is_patch()) { | 4388 if (cls.is_patch()) { |
| 4380 // Apply the changes to the patched class looked up above. | 4389 // Apply the changes to the patched class looked up above. |
| 4381 Object& obj = Object::Handle(I, library_.LookupLocalObject(class_name)); | 4390 Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
| 4382 // The patched class must not be finalized yet. | 4391 // The patched class must not be finalized yet. |
| 4383 const Class& orig_class = Class::Cast(obj); | 4392 const Class& orig_class = Class::Cast(obj); |
| 4384 ASSERT(!orig_class.is_finalized()); | 4393 ASSERT(!orig_class.is_finalized()); |
| 4385 Error& error = Error::Handle(I); | 4394 Error& error = Error::Handle(Z); |
| 4386 if (!orig_class.ApplyPatch(cls, &error)) { | 4395 if (!orig_class.ApplyPatch(cls, &error)) { |
| 4387 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); | 4396 Report::LongJumpF(error, script_, class_pos, "applying patch failed"); |
| 4388 } | 4397 } |
| 4389 } | 4398 } |
| 4390 } | 4399 } |
| 4391 | 4400 |
| 4392 | 4401 |
| 4393 void Parser::ParseEnumDefinition(const Class& cls) { | 4402 void Parser::ParseEnumDefinition(const Class& cls) { |
| 4394 TRACE_PARSER("ParseEnumDefinition"); | 4403 TRACE_PARSER("ParseEnumDefinition"); |
| 4395 CompilerStats::num_classes_compiled++; | 4404 CompilerStats::num_classes_compiled++; |
| 4396 | 4405 |
| 4397 const String& enum_name = String::Handle(I, cls.Name()); | 4406 const String& enum_name = String::Handle(Z, cls.Name()); |
| 4398 ClassDesc enum_members(cls, enum_name, false, cls.token_pos()); | 4407 ClassDesc enum_members(cls, enum_name, false, cls.token_pos()); |
| 4399 | 4408 |
| 4400 // Add instance field 'final int index'. | 4409 // Add instance field 'final int index'. |
| 4401 Field& index_field = Field::ZoneHandle(I); | 4410 Field& index_field = Field::ZoneHandle(Z); |
| 4402 const Type& int_type = Type::Handle(I, Type::IntType()); | 4411 const Type& int_type = Type::Handle(Z, Type::IntType()); |
| 4403 const Type& dynamic_type = Type::Handle(Type::DynamicType()); | 4412 const Type& dynamic_type = Type::Handle(Type::DynamicType()); |
| 4404 index_field = Field::New(Symbols::Index(), | 4413 index_field = Field::New(Symbols::Index(), |
| 4405 false, // Not static. | 4414 false, // Not static. |
| 4406 true, // Field is final. | 4415 true, // Field is final. |
| 4407 false, // Not const. | 4416 false, // Not const. |
| 4408 false, // Not synthetic. | 4417 false, // Not synthetic. |
| 4409 cls, | 4418 cls, |
| 4410 cls.token_pos()); | 4419 cls.token_pos()); |
| 4411 index_field.set_type(int_type); | 4420 index_field.set_type(int_type); |
| 4412 enum_members.AddField(index_field); | 4421 enum_members.AddField(index_field); |
| 4413 | 4422 |
| 4414 // Add implicit getter for index field. | 4423 // Add implicit getter for index field. |
| 4415 const String& getter_name = | 4424 const String& getter_name = |
| 4416 String::Handle(I, Field::GetterSymbol(Symbols::Index())); | 4425 String::Handle(Z, Field::GetterSymbol(Symbols::Index())); |
| 4417 Function& getter = Function::Handle(I); | 4426 Function& getter = Function::Handle(Z); |
| 4418 getter = Function::New(getter_name, | 4427 getter = Function::New(getter_name, |
| 4419 RawFunction::kImplicitGetter, | 4428 RawFunction::kImplicitGetter, |
| 4420 /* is_static = */ false, | 4429 /* is_static = */ false, |
| 4421 /* is_const = */ true, | 4430 /* is_const = */ true, |
| 4422 /* is_abstract = */ false, | 4431 /* is_abstract = */ false, |
| 4423 /* is_external = */ false, | 4432 /* is_external = */ false, |
| 4424 /* is_native = */ false, | 4433 /* is_native = */ false, |
| 4425 cls, | 4434 cls, |
| 4426 cls.token_pos()); | 4435 cls.token_pos()); |
| 4427 getter.set_result_type(int_type); | 4436 getter.set_result_type(int_type); |
| 4428 getter.set_is_debuggable(false); | 4437 getter.set_is_debuggable(false); |
| 4429 ParamList params; | 4438 ParamList params; |
| 4430 params.AddReceiver(&dynamic_type, cls.token_pos()); | 4439 params.AddReceiver(&dynamic_type, cls.token_pos()); |
| 4431 AddFormalParamsToFunction(¶ms, getter); | 4440 AddFormalParamsToFunction(¶ms, getter); |
| 4432 enum_members.AddFunction(getter); | 4441 enum_members.AddFunction(getter); |
| 4433 | 4442 |
| 4434 GrowableObjectArray& enum_names = GrowableObjectArray::Handle(I, | 4443 GrowableObjectArray& enum_names = GrowableObjectArray::Handle(Z, |
| 4435 GrowableObjectArray::New(8, Heap::kOld)); | 4444 GrowableObjectArray::New(8, Heap::kOld)); |
| 4436 const String& name_prefix = | 4445 const String& name_prefix = |
| 4437 String::Handle(String::Concat(enum_name, Symbols::Dot())); | 4446 String::Handle(String::Concat(enum_name, Symbols::Dot())); |
| 4438 | 4447 |
| 4439 ASSERT(IsIdentifier()); | 4448 ASSERT(IsIdentifier()); |
| 4440 ASSERT(CurrentLiteral()->raw() == cls.Name()); | 4449 ASSERT(CurrentLiteral()->raw() == cls.Name()); |
| 4441 | 4450 |
| 4442 ConsumeToken(); // Enum type name. | 4451 ConsumeToken(); // Enum type name. |
| 4443 ExpectToken(Token::kLBRACE); | 4452 ExpectToken(Token::kLBRACE); |
| 4444 Field& enum_value = Field::Handle(I); | 4453 Field& enum_value = Field::Handle(Z); |
| 4445 String& enum_value_name = String::Handle(I); | 4454 String& enum_value_name = String::Handle(Z); |
| 4446 intptr_t i = 0; | 4455 intptr_t i = 0; |
| 4447 GrowableArray<String*> declared_names(8); | 4456 GrowableArray<String*> declared_names(8); |
| 4448 | 4457 |
| 4449 while (IsIdentifier()) { | 4458 while (IsIdentifier()) { |
| 4450 String* enum_ident = CurrentLiteral(); | 4459 String* enum_ident = CurrentLiteral(); |
| 4451 | 4460 |
| 4452 // Check for name conflicts. | 4461 // Check for name conflicts. |
| 4453 if (enum_ident->raw() == cls.Name()) { | 4462 if (enum_ident->raw() == cls.Name()) { |
| 4454 ReportError("enum identifier '%s' cannot be equal to enum type name", | 4463 ReportError("enum identifier '%s' cannot be equal to enum type name", |
| 4455 CurrentLiteral()->ToCString()); | 4464 CurrentLiteral()->ToCString()); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 4478 /* is_final = */ true, | 4487 /* is_final = */ true, |
| 4479 /* is_const = */ true, | 4488 /* is_const = */ true, |
| 4480 /* is_synthetic = */ false, | 4489 /* is_synthetic = */ false, |
| 4481 cls, | 4490 cls, |
| 4482 cls.token_pos()); | 4491 cls.token_pos()); |
| 4483 enum_value.set_type(dynamic_type); | 4492 enum_value.set_type(dynamic_type); |
| 4484 enum_value.set_has_initializer(false); | 4493 enum_value.set_has_initializer(false); |
| 4485 enum_members.AddField(enum_value); | 4494 enum_members.AddField(enum_value); |
| 4486 // Initialize the field with the ordinal value. It will be patched | 4495 // Initialize the field with the ordinal value. It will be patched |
| 4487 // later with the enum constant instance. | 4496 // later with the enum constant instance. |
| 4488 const Smi& ordinal_value = Smi::Handle(I, Smi::New(i)); | 4497 const Smi& ordinal_value = Smi::Handle(Z, Smi::New(i)); |
| 4489 enum_value.set_value(ordinal_value); | 4498 enum_value.set_value(ordinal_value); |
| 4490 enum_value.RecordStore(ordinal_value); | 4499 enum_value.RecordStore(ordinal_value); |
| 4491 i++; | 4500 i++; |
| 4492 | 4501 |
| 4493 // For the user-visible name of the enumeration value, we need to | 4502 // For the user-visible name of the enumeration value, we need to |
| 4494 // unmangle private names. | 4503 // unmangle private names. |
| 4495 if (enum_ident->CharAt(0) == '_') { | 4504 if (enum_ident->CharAt(0) == '_') { |
| 4496 *enum_ident = String::IdentifierPrettyName(*enum_ident); | 4505 *enum_ident = String::IdentifierPrettyName(*enum_ident); |
| 4497 } | 4506 } |
| 4498 enum_value_name = Symbols::FromConcat(name_prefix, *enum_ident); | 4507 enum_value_name = Symbols::FromConcat(name_prefix, *enum_ident); |
| 4499 enum_names.Add(enum_value_name, Heap::kOld); | 4508 enum_names.Add(enum_value_name, Heap::kOld); |
| 4500 | 4509 |
| 4501 ConsumeToken(); // Enum value name. | 4510 ConsumeToken(); // Enum value name. |
| 4502 if (CurrentToken() == Token::kCOMMA) { | 4511 if (CurrentToken() == Token::kCOMMA) { |
| 4503 ConsumeToken(); | 4512 ConsumeToken(); |
| 4504 } | 4513 } |
| 4505 } | 4514 } |
| 4506 ExpectToken(Token::kRBRACE); | 4515 ExpectToken(Token::kRBRACE); |
| 4507 | 4516 |
| 4508 const Class& helper_class = | 4517 const Class& helper_class = |
| 4509 Class::Handle(I, Library::LookupCoreClass(Symbols::_EnumHelper())); | 4518 Class::Handle(Z, Library::LookupCoreClass(Symbols::_EnumHelper())); |
| 4510 ASSERT(!helper_class.IsNull()); | 4519 ASSERT(!helper_class.IsNull()); |
| 4511 | 4520 |
| 4512 // Add static field 'const List values'. | 4521 // Add static field 'const List values'. |
| 4513 Field& values_field = Field::ZoneHandle(I); | 4522 Field& values_field = Field::ZoneHandle(Z); |
| 4514 values_field = Field::New(Symbols::Values(), | 4523 values_field = Field::New(Symbols::Values(), |
| 4515 /* is_static = */ true, | 4524 /* is_static = */ true, |
| 4516 /* is_final = */ true, | 4525 /* is_final = */ true, |
| 4517 /* is_const = */ true, | 4526 /* is_const = */ true, |
| 4518 /* is_synthetic = */ false, | 4527 /* is_synthetic = */ false, |
| 4519 cls, | 4528 cls, |
| 4520 cls.token_pos()); | 4529 cls.token_pos()); |
| 4521 values_field.set_type(Type::Handle(I, Type::ArrayType())); | 4530 values_field.set_type(Type::Handle(Z, Type::ArrayType())); |
| 4522 enum_members.AddField(values_field); | 4531 enum_members.AddField(values_field); |
| 4523 | 4532 |
| 4524 // Allocate the immutable array containing the enumeration values. | 4533 // Allocate the immutable array containing the enumeration values. |
| 4525 // The actual enum instance values will be patched in later. | 4534 // The actual enum instance values will be patched in later. |
| 4526 const Array& values_array = Array::Handle(I, Array::New(i, Heap::kOld)); | 4535 const Array& values_array = Array::Handle(Z, Array::New(i, Heap::kOld)); |
| 4527 values_field.set_value(values_array); | 4536 values_field.set_value(values_array); |
| 4528 values_field.RecordStore(values_array); | 4537 values_field.RecordStore(values_array); |
| 4529 | 4538 |
| 4530 // Create a static field that contains the list of enumeration names. | 4539 // Create a static field that contains the list of enumeration names. |
| 4531 // Clone the _enum_names field from the helper class. | 4540 // Clone the _enum_names field from the helper class. |
| 4532 Field& names_field = Field::Handle(I, | 4541 Field& names_field = Field::Handle(Z, |
| 4533 helper_class.LookupStaticField(Symbols::_EnumNames())); | 4542 helper_class.LookupStaticField(Symbols::_EnumNames())); |
| 4534 ASSERT(!names_field.IsNull()); | 4543 ASSERT(!names_field.IsNull()); |
| 4535 names_field = names_field.Clone(cls); | 4544 names_field = names_field.Clone(cls); |
| 4536 enum_members.AddField(names_field); | 4545 enum_members.AddField(names_field); |
| 4537 const Array& names_array = Array::Handle(Array::MakeArray(enum_names)); | 4546 const Array& names_array = Array::Handle(Array::MakeArray(enum_names)); |
| 4538 names_field.set_value(names_array); | 4547 names_field.set_value(names_array); |
| 4539 names_field.RecordStore(names_array); | 4548 names_field.RecordStore(names_array); |
| 4540 | 4549 |
| 4541 // Clone the toString() function from the helper class. | 4550 // Clone the toString() function from the helper class. |
| 4542 Function& to_string_func = Function::Handle(I, | 4551 Function& to_string_func = Function::Handle(Z, |
| 4543 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); | 4552 helper_class.LookupDynamicFunctionAllowPrivate(Symbols::toString())); |
| 4544 ASSERT(!to_string_func.IsNull()); | 4553 ASSERT(!to_string_func.IsNull()); |
| 4545 to_string_func = to_string_func.Clone(cls); | 4554 to_string_func = to_string_func.Clone(cls); |
| 4546 enum_members.AddFunction(to_string_func); | 4555 enum_members.AddFunction(to_string_func); |
| 4547 | 4556 |
| 4548 cls.AddFields(enum_members.fields()); | 4557 cls.AddFields(enum_members.fields()); |
| 4549 const Array& functions = | 4558 const Array& functions = |
| 4550 Array::Handle(I, Array::MakeArray(enum_members.functions())); | 4559 Array::Handle(Z, Array::MakeArray(enum_members.functions())); |
| 4551 cls.SetFunctions(functions); | 4560 cls.SetFunctions(functions); |
| 4552 } | 4561 } |
| 4553 | 4562 |
| 4554 | 4563 |
| 4555 // Add an implicit constructor to the given class. | 4564 // Add an implicit constructor to the given class. |
| 4556 void Parser::AddImplicitConstructor(const Class& cls) { | 4565 void Parser::AddImplicitConstructor(const Class& cls) { |
| 4557 // The implicit constructor is unnamed, has no explicit parameter. | 4566 // The implicit constructor is unnamed, has no explicit parameter. |
| 4558 String& ctor_name = String::ZoneHandle(I, cls.Name()); | 4567 String& ctor_name = String::ZoneHandle(Z, cls.Name()); |
| 4559 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 4568 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| 4560 ctor_name = Symbols::New(ctor_name); | 4569 ctor_name = Symbols::New(ctor_name); |
| 4561 // To indicate that this is an implicit constructor, we set the | 4570 // To indicate that this is an implicit constructor, we set the |
| 4562 // token position and end token position of the function | 4571 // token position and end token position of the function |
| 4563 // to the token position of the class. | 4572 // to the token position of the class. |
| 4564 Function& ctor = Function::Handle(I, | 4573 Function& ctor = Function::Handle(Z, |
| 4565 Function::New(ctor_name, | 4574 Function::New(ctor_name, |
| 4566 RawFunction::kConstructor, | 4575 RawFunction::kConstructor, |
| 4567 /* is_static = */ false, | 4576 /* is_static = */ false, |
| 4568 /* is_const = */ false, | 4577 /* is_const = */ false, |
| 4569 /* is_abstract = */ false, | 4578 /* is_abstract = */ false, |
| 4570 /* is_external = */ false, | 4579 /* is_external = */ false, |
| 4571 /* is_native = */ false, | 4580 /* is_native = */ false, |
| 4572 cls, | 4581 cls, |
| 4573 cls.token_pos())); | 4582 cls.token_pos())); |
| 4574 ctor.set_end_token_pos(ctor.token_pos()); | 4583 ctor.set_end_token_pos(ctor.token_pos()); |
| 4575 ctor.set_is_debuggable(false); | 4584 ctor.set_is_debuggable(false); |
| 4576 if (library_.is_dart_scheme() && library_.IsPrivate(ctor_name)) { | 4585 if (library_.is_dart_scheme() && library_.IsPrivate(ctor_name)) { |
| 4577 ctor.set_is_visible(false); | 4586 ctor.set_is_visible(false); |
| 4578 } | 4587 } |
| 4579 | 4588 |
| 4580 ParamList params; | 4589 ParamList params; |
| 4581 // Add implicit 'this' parameter. | 4590 // Add implicit 'this' parameter. |
| 4582 const AbstractType* receiver_type = ReceiverType(cls); | 4591 const AbstractType* receiver_type = ReceiverType(cls); |
| 4583 params.AddReceiver(receiver_type, cls.token_pos()); | 4592 params.AddReceiver(receiver_type, cls.token_pos()); |
| 4584 // Add implicit parameter for construction phase. | 4593 // Add implicit parameter for construction phase. |
| 4585 params.AddFinalParameter(cls.token_pos(), | 4594 params.AddFinalParameter(cls.token_pos(), |
| 4586 &Symbols::PhaseParameter(), | 4595 &Symbols::PhaseParameter(), |
| 4587 &Type::ZoneHandle(I, Type::SmiType())); | 4596 &Type::ZoneHandle(Z, Type::SmiType())); |
| 4588 | 4597 |
| 4589 AddFormalParamsToFunction(¶ms, ctor); | 4598 AddFormalParamsToFunction(¶ms, ctor); |
| 4590 // The body of the constructor cannot modify the type of the constructed | 4599 // The body of the constructor cannot modify the type of the constructed |
| 4591 // instance, which is passed in as the receiver. | 4600 // instance, which is passed in as the receiver. |
| 4592 ctor.set_result_type(*receiver_type); | 4601 ctor.set_result_type(*receiver_type); |
| 4593 cls.AddFunction(ctor); | 4602 cls.AddFunction(ctor); |
| 4594 } | 4603 } |
| 4595 | 4604 |
| 4596 | 4605 |
| 4597 // Check for cycles in constructor redirection. | 4606 // Check for cycles in constructor redirection. |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4629 const GrowableObjectArray& pending_classes, | 4638 const GrowableObjectArray& pending_classes, |
| 4630 const Class& toplevel_class, | 4639 const Class& toplevel_class, |
| 4631 intptr_t metadata_pos) { | 4640 intptr_t metadata_pos) { |
| 4632 TRACE_PARSER("ParseMixinAppAlias"); | 4641 TRACE_PARSER("ParseMixinAppAlias"); |
| 4633 const intptr_t classname_pos = TokenPos(); | 4642 const intptr_t classname_pos = TokenPos(); |
| 4634 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 4643 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 4635 if (FLAG_trace_parser) { | 4644 if (FLAG_trace_parser) { |
| 4636 OS::Print("toplevel parsing mixin application alias class '%s'\n", | 4645 OS::Print("toplevel parsing mixin application alias class '%s'\n", |
| 4637 class_name.ToCString()); | 4646 class_name.ToCString()); |
| 4638 } | 4647 } |
| 4639 const Object& obj = Object::Handle(I, library_.LookupLocalObject(class_name)); | 4648 const Object& obj = Object::Handle(Z, library_.LookupLocalObject(class_name)); |
| 4640 if (!obj.IsNull()) { | 4649 if (!obj.IsNull()) { |
| 4641 ReportError(classname_pos, "'%s' is already defined", | 4650 ReportError(classname_pos, "'%s' is already defined", |
| 4642 class_name.ToCString()); | 4651 class_name.ToCString()); |
| 4643 } | 4652 } |
| 4644 const Class& mixin_application = | 4653 const Class& mixin_application = |
| 4645 Class::Handle(I, Class::New(class_name, script_, classname_pos)); | 4654 Class::Handle(Z, Class::New(class_name, script_, classname_pos)); |
| 4646 mixin_application.set_is_mixin_app_alias(); | 4655 mixin_application.set_is_mixin_app_alias(); |
| 4647 library_.AddClass(mixin_application); | 4656 library_.AddClass(mixin_application); |
| 4648 set_current_class(mixin_application); | 4657 set_current_class(mixin_application); |
| 4649 ParseTypeParameters(mixin_application); | 4658 ParseTypeParameters(mixin_application); |
| 4650 | 4659 |
| 4651 ExpectToken(Token::kASSIGN); | 4660 ExpectToken(Token::kASSIGN); |
| 4652 | 4661 |
| 4653 if (CurrentToken() == Token::kABSTRACT) { | 4662 if (CurrentToken() == Token::kABSTRACT) { |
| 4654 mixin_application.set_is_abstract(); | 4663 mixin_application.set_is_abstract(); |
| 4655 ConsumeToken(); | 4664 ConsumeToken(); |
| 4656 } | 4665 } |
| 4657 | 4666 |
| 4658 const intptr_t type_pos = TokenPos(); | 4667 const intptr_t type_pos = TokenPos(); |
| 4659 AbstractType& type = | 4668 AbstractType& type = |
| 4660 AbstractType::Handle(I, | 4669 AbstractType::Handle(Z, |
| 4661 ParseType(ClassFinalizer::kResolveTypeParameters)); | 4670 ParseType(ClassFinalizer::kResolveTypeParameters)); |
| 4662 if (type.IsTypeParameter()) { | 4671 if (type.IsTypeParameter()) { |
| 4663 ReportError(type_pos, | 4672 ReportError(type_pos, |
| 4664 "class '%s' may not extend type parameter '%s'", | 4673 "class '%s' may not extend type parameter '%s'", |
| 4665 class_name.ToCString(), | 4674 class_name.ToCString(), |
| 4666 String::Handle(I, type.UserVisibleName()).ToCString()); | 4675 String::Handle(Z, type.UserVisibleName()).ToCString()); |
| 4667 } | 4676 } |
| 4668 | 4677 |
| 4669 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); | 4678 CheckToken(Token::kWITH, "mixin application 'with Type' expected"); |
| 4670 type = ParseMixins(type); | 4679 type = ParseMixins(type); |
| 4671 | 4680 |
| 4672 mixin_application.set_super_type(type); | 4681 mixin_application.set_super_type(type); |
| 4673 mixin_application.set_is_synthesized_class(); | 4682 mixin_application.set_is_synthesized_class(); |
| 4674 | 4683 |
| 4675 // This mixin application alias needs an implicit constructor, but it is | 4684 // This mixin application alias needs an implicit constructor, but it is |
| 4676 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4685 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4734 | 4743 |
| 4735 if (IsMixinAppAlias()) { | 4744 if (IsMixinAppAlias()) { |
| 4736 if (FLAG_warn_mixin_typedef) { | 4745 if (FLAG_warn_mixin_typedef) { |
| 4737 ReportWarning(TokenPos(), "deprecated mixin application typedef"); | 4746 ReportWarning(TokenPos(), "deprecated mixin application typedef"); |
| 4738 } | 4747 } |
| 4739 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); | 4748 ParseMixinAppAlias(pending_classes, toplevel_class, metadata_pos); |
| 4740 return; | 4749 return; |
| 4741 } | 4750 } |
| 4742 | 4751 |
| 4743 // Parse the result type of the function type. | 4752 // Parse the result type of the function type. |
| 4744 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); | 4753 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
| 4745 if (CurrentToken() == Token::kVOID) { | 4754 if (CurrentToken() == Token::kVOID) { |
| 4746 ConsumeToken(); | 4755 ConsumeToken(); |
| 4747 result_type = Type::VoidType(); | 4756 result_type = Type::VoidType(); |
| 4748 } else if (!IsFunctionTypeAliasName()) { | 4757 } else if (!IsFunctionTypeAliasName()) { |
| 4749 // Type annotations in typedef are never ignored, even in production mode. | 4758 // Type annotations in typedef are never ignored, even in production mode. |
| 4750 // Wait until we have an owner class before resolving the result type. | 4759 // Wait until we have an owner class before resolving the result type. |
| 4751 result_type = ParseType(ClassFinalizer::kDoNotResolve); | 4760 result_type = ParseType(ClassFinalizer::kDoNotResolve); |
| 4752 } | 4761 } |
| 4753 | 4762 |
| 4754 const intptr_t alias_name_pos = TokenPos(); | 4763 const intptr_t alias_name_pos = TokenPos(); |
| 4755 const String* alias_name = | 4764 const String* alias_name = |
| 4756 ExpectUserDefinedTypeIdentifier("function alias name expected"); | 4765 ExpectUserDefinedTypeIdentifier("function alias name expected"); |
| 4757 | 4766 |
| 4758 // Lookup alias name and report an error if it is already defined in | 4767 // Lookup alias name and report an error if it is already defined in |
| 4759 // the library scope. | 4768 // the library scope. |
| 4760 const Object& obj = | 4769 const Object& obj = |
| 4761 Object::Handle(I, library_.LookupLocalObject(*alias_name)); | 4770 Object::Handle(Z, library_.LookupLocalObject(*alias_name)); |
| 4762 if (!obj.IsNull()) { | 4771 if (!obj.IsNull()) { |
| 4763 ReportError(alias_name_pos, | 4772 ReportError(alias_name_pos, |
| 4764 "'%s' is already defined", alias_name->ToCString()); | 4773 "'%s' is already defined", alias_name->ToCString()); |
| 4765 } | 4774 } |
| 4766 | 4775 |
| 4767 // Create the function type alias signature class. It will be linked to its | 4776 // Create the function type alias signature class. It will be linked to its |
| 4768 // signature function after it has been parsed. The type parameters, in order | 4777 // signature function after it has been parsed. The type parameters, in order |
| 4769 // to be properly finalized, need to be associated to this signature class as | 4778 // to be properly finalized, need to be associated to this signature class as |
| 4770 // they are parsed. | 4779 // they are parsed. |
| 4771 const Class& function_type_alias = Class::Handle(I, | 4780 const Class& function_type_alias = Class::Handle(Z, |
| 4772 Class::NewSignatureClass(*alias_name, | 4781 Class::NewSignatureClass(*alias_name, |
| 4773 Function::Handle(I), | 4782 Function::Handle(Z), |
| 4774 script_, | 4783 script_, |
| 4775 alias_name_pos)); | 4784 alias_name_pos)); |
| 4776 library_.AddClass(function_type_alias); | 4785 library_.AddClass(function_type_alias); |
| 4777 set_current_class(function_type_alias); | 4786 set_current_class(function_type_alias); |
| 4778 // Parse the type parameters of the function type. | 4787 // Parse the type parameters of the function type. |
| 4779 ParseTypeParameters(function_type_alias); | 4788 ParseTypeParameters(function_type_alias); |
| 4780 // At this point, the type parameters have been parsed, so we can resolve the | 4789 // At this point, the type parameters have been parsed, so we can resolve the |
| 4781 // result type. | 4790 // result type. |
| 4782 if (!result_type.IsNull()) { | 4791 if (!result_type.IsNull()) { |
| 4783 ResolveTypeFromClass(function_type_alias, | 4792 ResolveTypeFromClass(function_type_alias, |
| 4784 ClassFinalizer::kResolveTypeParameters, | 4793 ClassFinalizer::kResolveTypeParameters, |
| 4785 &result_type); | 4794 &result_type); |
| 4786 } | 4795 } |
| 4787 // Parse the formal parameters of the function type. | 4796 // Parse the formal parameters of the function type. |
| 4788 CheckToken(Token::kLPAREN, "formal parameter list expected"); | 4797 CheckToken(Token::kLPAREN, "formal parameter list expected"); |
| 4789 ParamList func_params; | 4798 ParamList func_params; |
| 4790 | 4799 |
| 4791 // Add implicit closure object parameter. | 4800 // Add implicit closure object parameter. |
| 4792 func_params.AddFinalParameter( | 4801 func_params.AddFinalParameter( |
| 4793 TokenPos(), | 4802 TokenPos(), |
| 4794 &Symbols::ClosureParameter(), | 4803 &Symbols::ClosureParameter(), |
| 4795 &Type::ZoneHandle(I, Type::DynamicType())); | 4804 &Type::ZoneHandle(Z, Type::DynamicType())); |
| 4796 | 4805 |
| 4797 const bool no_explicit_default_values = false; | 4806 const bool no_explicit_default_values = false; |
| 4798 ParseFormalParameterList(no_explicit_default_values, false, &func_params); | 4807 ParseFormalParameterList(no_explicit_default_values, false, &func_params); |
| 4799 ExpectSemicolon(); | 4808 ExpectSemicolon(); |
| 4800 // The field 'is_static' has no meaning for signature functions. | 4809 // The field 'is_static' has no meaning for signature functions. |
| 4801 Function& signature_function = Function::Handle(I, | 4810 Function& signature_function = Function::Handle(Z, |
| 4802 Function::New(*alias_name, | 4811 Function::New(*alias_name, |
| 4803 RawFunction::kSignatureFunction, | 4812 RawFunction::kSignatureFunction, |
| 4804 /* is_static = */ false, | 4813 /* is_static = */ false, |
| 4805 /* is_const = */ false, | 4814 /* is_const = */ false, |
| 4806 /* is_abstract = */ false, | 4815 /* is_abstract = */ false, |
| 4807 /* is_external = */ false, | 4816 /* is_external = */ false, |
| 4808 /* is_native = */ false, | 4817 /* is_native = */ false, |
| 4809 function_type_alias, | 4818 function_type_alias, |
| 4810 alias_name_pos)); | 4819 alias_name_pos)); |
| 4811 signature_function.set_result_type(result_type); | 4820 signature_function.set_result_type(result_type); |
| 4812 signature_function.set_is_debuggable(false); | 4821 signature_function.set_is_debuggable(false); |
| 4813 AddFormalParamsToFunction(&func_params, signature_function); | 4822 AddFormalParamsToFunction(&func_params, signature_function); |
| 4814 | 4823 |
| 4815 // Patch the signature function in the signature class. | 4824 // Patch the signature function in the signature class. |
| 4816 function_type_alias.PatchSignatureFunction(signature_function); | 4825 function_type_alias.PatchSignatureFunction(signature_function); |
| 4817 | 4826 |
| 4818 const String& signature = String::Handle(I, | 4827 const String& signature = String::Handle(Z, |
| 4819 signature_function.Signature()); | 4828 signature_function.Signature()); |
| 4820 if (FLAG_trace_parser) { | 4829 if (FLAG_trace_parser) { |
| 4821 OS::Print("TopLevel parsing function type alias '%s'\n", | 4830 OS::Print("TopLevel parsing function type alias '%s'\n", |
| 4822 signature.ToCString()); | 4831 signature.ToCString()); |
| 4823 } | 4832 } |
| 4824 // Lookup the signature class, i.e. the class whose name is the signature. | 4833 // Lookup the signature class, i.e. the class whose name is the signature. |
| 4825 // We only lookup in the current library, but not in its imports, and only | 4834 // We only lookup in the current library, but not in its imports, and only |
| 4826 // create a new canonical signature class if it does not exist yet. | 4835 // create a new canonical signature class if it does not exist yet. |
| 4827 Class& signature_class = | 4836 Class& signature_class = |
| 4828 Class::ZoneHandle(I, library_.LookupLocalClass(signature)); | 4837 Class::ZoneHandle(Z, library_.LookupLocalClass(signature)); |
| 4829 if (signature_class.IsNull()) { | 4838 if (signature_class.IsNull()) { |
| 4830 signature_class = Class::NewSignatureClass(signature, | 4839 signature_class = Class::NewSignatureClass(signature, |
| 4831 signature_function, | 4840 signature_function, |
| 4832 script_, | 4841 script_, |
| 4833 alias_name_pos); | 4842 alias_name_pos); |
| 4834 // Record the function signature class in the current library. | 4843 // Record the function signature class in the current library. |
| 4835 library_.AddClass(signature_class); | 4844 library_.AddClass(signature_class); |
| 4836 } else { | 4845 } else { |
| 4837 // Forget the just created signature function and use the existing one. | 4846 // Forget the just created signature function and use the existing one. |
| 4838 signature_function = signature_class.signature_function(); | 4847 signature_function = signature_class.signature_function(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4922 } | 4931 } |
| 4923 SkipTypeArguments(); | 4932 SkipTypeArguments(); |
| 4924 } | 4933 } |
| 4925 } | 4934 } |
| 4926 | 4935 |
| 4927 | 4936 |
| 4928 void Parser::ParseTypeParameters(const Class& cls) { | 4937 void Parser::ParseTypeParameters(const Class& cls) { |
| 4929 TRACE_PARSER("ParseTypeParameters"); | 4938 TRACE_PARSER("ParseTypeParameters"); |
| 4930 if (CurrentToken() == Token::kLT) { | 4939 if (CurrentToken() == Token::kLT) { |
| 4931 const GrowableObjectArray& type_parameters_array = | 4940 const GrowableObjectArray& type_parameters_array = |
| 4932 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 4941 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 4933 intptr_t index = 0; | 4942 intptr_t index = 0; |
| 4934 TypeParameter& type_parameter = TypeParameter::Handle(I); | 4943 TypeParameter& type_parameter = TypeParameter::Handle(Z); |
| 4935 TypeParameter& existing_type_parameter = TypeParameter::Handle(I); | 4944 TypeParameter& existing_type_parameter = TypeParameter::Handle(Z); |
| 4936 String& existing_type_parameter_name = String::Handle(I); | 4945 String& existing_type_parameter_name = String::Handle(Z); |
| 4937 AbstractType& type_parameter_bound = Type::Handle(I); | 4946 AbstractType& type_parameter_bound = Type::Handle(Z); |
| 4938 do { | 4947 do { |
| 4939 ConsumeToken(); | 4948 ConsumeToken(); |
| 4940 const intptr_t metadata_pos = SkipMetadata(); | 4949 const intptr_t metadata_pos = SkipMetadata(); |
| 4941 const intptr_t type_parameter_pos = TokenPos(); | 4950 const intptr_t type_parameter_pos = TokenPos(); |
| 4942 String& type_parameter_name = | 4951 String& type_parameter_name = |
| 4943 *ExpectUserDefinedTypeIdentifier("type parameter expected"); | 4952 *ExpectUserDefinedTypeIdentifier("type parameter expected"); |
| 4944 // Check for duplicate type parameters. | 4953 // Check for duplicate type parameters. |
| 4945 for (intptr_t i = 0; i < index; i++) { | 4954 for (intptr_t i = 0; i < index; i++) { |
| 4946 existing_type_parameter ^= type_parameters_array.At(i); | 4955 existing_type_parameter ^= type_parameters_array.At(i); |
| 4947 existing_type_parameter_name = existing_type_parameter.name(); | 4956 existing_type_parameter_name = existing_type_parameter.name(); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 4971 } | 4980 } |
| 4972 index++; | 4981 index++; |
| 4973 } while (CurrentToken() == Token::kCOMMA); | 4982 } while (CurrentToken() == Token::kCOMMA); |
| 4974 Token::Kind token = CurrentToken(); | 4983 Token::Kind token = CurrentToken(); |
| 4975 if ((token == Token::kGT) || (token == Token::kSHR)) { | 4984 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 4976 ConsumeRightAngleBracket(); | 4985 ConsumeRightAngleBracket(); |
| 4977 } else { | 4986 } else { |
| 4978 ReportError("right angle bracket expected"); | 4987 ReportError("right angle bracket expected"); |
| 4979 } | 4988 } |
| 4980 const TypeArguments& type_parameters = | 4989 const TypeArguments& type_parameters = |
| 4981 TypeArguments::Handle(I, | 4990 TypeArguments::Handle(Z, |
| 4982 NewTypeArguments(type_parameters_array)); | 4991 NewTypeArguments(type_parameters_array)); |
| 4983 cls.set_type_parameters(type_parameters); | 4992 cls.set_type_parameters(type_parameters); |
| 4984 // Try to resolve the upper bounds, which will at least resolve the | 4993 // Try to resolve the upper bounds, which will at least resolve the |
| 4985 // referenced type parameters. | 4994 // referenced type parameters. |
| 4986 const intptr_t num_types = type_parameters.Length(); | 4995 const intptr_t num_types = type_parameters.Length(); |
| 4987 for (intptr_t i = 0; i < num_types; i++) { | 4996 for (intptr_t i = 0; i < num_types; i++) { |
| 4988 type_parameter ^= type_parameters.TypeAt(i); | 4997 type_parameter ^= type_parameters.TypeAt(i); |
| 4989 type_parameter_bound = type_parameter.bound(); | 4998 type_parameter_bound = type_parameter.bound(); |
| 4990 ResolveTypeFromClass(cls, | 4999 ResolveTypeFromClass(cls, |
| 4991 ClassFinalizer::kResolveTypeParameters, | 5000 ClassFinalizer::kResolveTypeParameters, |
| 4992 &type_parameter_bound); | 5001 &type_parameter_bound); |
| 4993 type_parameter.set_bound(type_parameter_bound); | 5002 type_parameter.set_bound(type_parameter_bound); |
| 4994 } | 5003 } |
| 4995 } | 5004 } |
| 4996 } | 5005 } |
| 4997 | 5006 |
| 4998 | 5007 |
| 4999 RawTypeArguments* Parser::ParseTypeArguments( | 5008 RawTypeArguments* Parser::ParseTypeArguments( |
| 5000 ClassFinalizer::FinalizationKind finalization) { | 5009 ClassFinalizer::FinalizationKind finalization) { |
| 5001 TRACE_PARSER("ParseTypeArguments"); | 5010 TRACE_PARSER("ParseTypeArguments"); |
| 5002 if (CurrentToken() == Token::kLT) { | 5011 if (CurrentToken() == Token::kLT) { |
| 5003 const GrowableObjectArray& types = | 5012 const GrowableObjectArray& types = |
| 5004 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 5013 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 5005 AbstractType& type = AbstractType::Handle(I); | 5014 AbstractType& type = AbstractType::Handle(Z); |
| 5006 do { | 5015 do { |
| 5007 ConsumeToken(); | 5016 ConsumeToken(); |
| 5008 type = ParseType(finalization); | 5017 type = ParseType(finalization); |
| 5009 // Map a malformed type argument to dynamic. | 5018 // Map a malformed type argument to dynamic. |
| 5010 if (type.IsMalformed()) { | 5019 if (type.IsMalformed()) { |
| 5011 type = Type::DynamicType(); | 5020 type = Type::DynamicType(); |
| 5012 } | 5021 } |
| 5013 types.Add(type); | 5022 types.Add(type); |
| 5014 } while (CurrentToken() == Token::kCOMMA); | 5023 } while (CurrentToken() == Token::kCOMMA); |
| 5015 Token::Kind token = CurrentToken(); | 5024 Token::Kind token = CurrentToken(); |
| 5016 if ((token == Token::kGT) || (token == Token::kSHR)) { | 5025 if ((token == Token::kGT) || (token == Token::kSHR)) { |
| 5017 ConsumeRightAngleBracket(); | 5026 ConsumeRightAngleBracket(); |
| 5018 } else { | 5027 } else { |
| 5019 ReportError("right angle bracket expected"); | 5028 ReportError("right angle bracket expected"); |
| 5020 } | 5029 } |
| 5021 if (finalization != ClassFinalizer::kIgnore) { | 5030 if (finalization != ClassFinalizer::kIgnore) { |
| 5022 return NewTypeArguments(types); | 5031 return NewTypeArguments(types); |
| 5023 } | 5032 } |
| 5024 } | 5033 } |
| 5025 return TypeArguments::null(); | 5034 return TypeArguments::null(); |
| 5026 } | 5035 } |
| 5027 | 5036 |
| 5028 | 5037 |
| 5029 // Parse interface list and add to class cls. | 5038 // Parse interface list and add to class cls. |
| 5030 void Parser::ParseInterfaceList(const Class& cls) { | 5039 void Parser::ParseInterfaceList(const Class& cls) { |
| 5031 TRACE_PARSER("ParseInterfaceList"); | 5040 TRACE_PARSER("ParseInterfaceList"); |
| 5032 ASSERT(CurrentToken() == Token::kIMPLEMENTS); | 5041 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
| 5033 const GrowableObjectArray& all_interfaces = | 5042 const GrowableObjectArray& all_interfaces = |
| 5034 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 5043 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 5035 AbstractType& interface = AbstractType::Handle(I); | 5044 AbstractType& interface = AbstractType::Handle(Z); |
| 5036 // First get all the interfaces already implemented by class. | 5045 // First get all the interfaces already implemented by class. |
| 5037 Array& cls_interfaces = Array::Handle(I, cls.interfaces()); | 5046 Array& cls_interfaces = Array::Handle(Z, cls.interfaces()); |
| 5038 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | 5047 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 5039 interface ^= cls_interfaces.At(i); | 5048 interface ^= cls_interfaces.At(i); |
| 5040 all_interfaces.Add(interface); | 5049 all_interfaces.Add(interface); |
| 5041 } | 5050 } |
| 5042 // Now parse and add the new interfaces. | 5051 // Now parse and add the new interfaces. |
| 5043 do { | 5052 do { |
| 5044 ConsumeToken(); | 5053 ConsumeToken(); |
| 5045 intptr_t interface_pos = TokenPos(); | 5054 intptr_t interface_pos = TokenPos(); |
| 5046 interface = ParseType(ClassFinalizer::kResolveTypeParameters); | 5055 interface = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 5047 if (interface.IsTypeParameter()) { | 5056 if (interface.IsTypeParameter()) { |
| 5048 ReportError(interface_pos, | 5057 ReportError(interface_pos, |
| 5049 "type parameter '%s' may not be used in interface list", | 5058 "type parameter '%s' may not be used in interface list", |
| 5050 String::Handle(I, interface.UserVisibleName()).ToCString()); | 5059 String::Handle(Z, interface.UserVisibleName()).ToCString()); |
| 5051 } | 5060 } |
| 5052 all_interfaces.Add(interface); | 5061 all_interfaces.Add(interface); |
| 5053 } while (CurrentToken() == Token::kCOMMA); | 5062 } while (CurrentToken() == Token::kCOMMA); |
| 5054 cls_interfaces = Array::MakeArray(all_interfaces); | 5063 cls_interfaces = Array::MakeArray(all_interfaces); |
| 5055 cls.set_interfaces(cls_interfaces); | 5064 cls.set_interfaces(cls_interfaces); |
| 5056 } | 5065 } |
| 5057 | 5066 |
| 5058 | 5067 |
| 5059 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 5068 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
| 5060 TRACE_PARSER("ParseMixins"); | 5069 TRACE_PARSER("ParseMixins"); |
| 5061 ASSERT(CurrentToken() == Token::kWITH); | 5070 ASSERT(CurrentToken() == Token::kWITH); |
| 5062 const GrowableObjectArray& mixin_types = | 5071 const GrowableObjectArray& mixin_types = |
| 5063 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 5072 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 5064 AbstractType& mixin_type = AbstractType::Handle(I); | 5073 AbstractType& mixin_type = AbstractType::Handle(Z); |
| 5065 do { | 5074 do { |
| 5066 ConsumeToken(); | 5075 ConsumeToken(); |
| 5067 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 5076 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 5068 if (mixin_type.IsDynamicType()) { | 5077 if (mixin_type.IsDynamicType()) { |
| 5069 // The string 'dynamic' is not resolved yet at this point, but a malformed | 5078 // The string 'dynamic' is not resolved yet at this point, but a malformed |
| 5070 // type mapped to dynamic can be encountered here. | 5079 // type mapped to dynamic can be encountered here. |
| 5071 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); | 5080 ReportError(mixin_type.token_pos(), "illegal mixin of a malformed type"); |
| 5072 } | 5081 } |
| 5073 if (mixin_type.IsTypeParameter()) { | 5082 if (mixin_type.IsTypeParameter()) { |
| 5074 ReportError(mixin_type.token_pos(), | 5083 ReportError(mixin_type.token_pos(), |
| 5075 "mixin type '%s' may not be a type parameter", | 5084 "mixin type '%s' may not be a type parameter", |
| 5076 String::Handle(I, mixin_type.UserVisibleName()).ToCString()); | 5085 String::Handle(Z, mixin_type.UserVisibleName()).ToCString()); |
| 5077 } | 5086 } |
| 5078 mixin_types.Add(mixin_type); | 5087 mixin_types.Add(mixin_type); |
| 5079 } while (CurrentToken() == Token::kCOMMA); | 5088 } while (CurrentToken() == Token::kCOMMA); |
| 5080 return MixinAppType::New(super_type, | 5089 return MixinAppType::New(super_type, |
| 5081 Array::Handle(I, Array::MakeArray(mixin_types))); | 5090 Array::Handle(Z, Array::MakeArray(mixin_types))); |
| 5082 } | 5091 } |
| 5083 | 5092 |
| 5084 | 5093 |
| 5085 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 5094 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
| 5086 intptr_t metadata_pos) { | 5095 intptr_t metadata_pos) { |
| 5087 TRACE_PARSER("ParseTopLevelVariable"); | 5096 TRACE_PARSER("ParseTopLevelVariable"); |
| 5088 const bool is_const = (CurrentToken() == Token::kCONST); | 5097 const bool is_const = (CurrentToken() == Token::kCONST); |
| 5089 // Const fields are implicitly final. | 5098 // Const fields are implicitly final. |
| 5090 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 5099 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 5091 const bool is_static = true; | 5100 const bool is_static = true; |
| 5092 const bool is_synthetic = false; | 5101 const bool is_synthetic = false; |
| 5093 const AbstractType& type = AbstractType::ZoneHandle(I, | 5102 const AbstractType& type = AbstractType::ZoneHandle(Z, |
| 5094 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); | 5103 ParseConstFinalVarOrType(ClassFinalizer::kResolveTypeParameters)); |
| 5095 Field& field = Field::Handle(I); | 5104 Field& field = Field::Handle(Z); |
| 5096 Function& getter = Function::Handle(I); | 5105 Function& getter = Function::Handle(Z); |
| 5097 while (true) { | 5106 while (true) { |
| 5098 const intptr_t name_pos = TokenPos(); | 5107 const intptr_t name_pos = TokenPos(); |
| 5099 String& var_name = *ExpectIdentifier("variable name expected"); | 5108 String& var_name = *ExpectIdentifier("variable name expected"); |
| 5100 | 5109 |
| 5101 if (library_.LookupLocalObject(var_name) != Object::null()) { | 5110 if (library_.LookupLocalObject(var_name) != Object::null()) { |
| 5102 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); | 5111 ReportError(name_pos, "'%s' is already defined", var_name.ToCString()); |
| 5103 } | 5112 } |
| 5104 | 5113 |
| 5105 // Check whether a getter or setter for this name exists. A const | 5114 // Check whether a getter or setter for this name exists. A const |
| 5106 // or final field implies a setter which throws a NoSuchMethodError, | 5115 // or final field implies a setter which throws a NoSuchMethodError, |
| 5107 // thus we need to check for conflicts with existing setters and | 5116 // thus we need to check for conflicts with existing setters and |
| 5108 // getters. | 5117 // getters. |
| 5109 String& accessor_name = String::Handle(I, | 5118 String& accessor_name = String::Handle(Z, |
| 5110 Field::GetterName(var_name)); | 5119 Field::GetterName(var_name)); |
| 5111 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5120 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 5112 ReportError(name_pos, "getter for '%s' is already defined", | 5121 ReportError(name_pos, "getter for '%s' is already defined", |
| 5113 var_name.ToCString()); | 5122 var_name.ToCString()); |
| 5114 } | 5123 } |
| 5115 accessor_name = Field::SetterName(var_name); | 5124 accessor_name = Field::SetterName(var_name); |
| 5116 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5125 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 5117 ReportError(name_pos, "setter for '%s' is already defined", | 5126 ReportError(name_pos, "setter for '%s' is already defined", |
| 5118 var_name.ToCString()); | 5127 var_name.ToCString()); |
| 5119 } | 5128 } |
| 5120 | 5129 |
| 5121 field = Field::New(var_name, is_static, is_final, is_const, is_synthetic, | 5130 field = Field::New(var_name, is_static, is_final, is_const, is_synthetic, |
| 5122 current_class(), name_pos); | 5131 current_class(), name_pos); |
| 5123 field.set_type(type); | 5132 field.set_type(type); |
| 5124 field.set_value(Instance::Handle(I, Instance::null())); | 5133 field.set_value(Instance::Handle(Z, Instance::null())); |
| 5125 top_level->fields.Add(field); | 5134 top_level->fields.Add(field); |
| 5126 library_.AddObject(field, var_name); | 5135 library_.AddObject(field, var_name); |
| 5127 if (metadata_pos >= 0) { | 5136 if (metadata_pos >= 0) { |
| 5128 library_.AddFieldMetadata(field, metadata_pos); | 5137 library_.AddFieldMetadata(field, metadata_pos); |
| 5129 } | 5138 } |
| 5130 if (CurrentToken() == Token::kASSIGN) { | 5139 if (CurrentToken() == Token::kASSIGN) { |
| 5131 ConsumeToken(); | 5140 ConsumeToken(); |
| 5132 Instance& field_value = Instance::Handle(I, | 5141 Instance& field_value = Instance::Handle(Z, |
| 5133 Object::sentinel().raw()); | 5142 Object::sentinel().raw()); |
| 5134 bool has_simple_literal = false; | 5143 bool has_simple_literal = false; |
| 5135 if (LookaheadToken(1) == Token::kSEMICOLON) { | 5144 if (LookaheadToken(1) == Token::kSEMICOLON) { |
| 5136 has_simple_literal = IsSimpleLiteral(type, &field_value); | 5145 has_simple_literal = IsSimpleLiteral(type, &field_value); |
| 5137 } | 5146 } |
| 5138 SkipExpr(); | 5147 SkipExpr(); |
| 5139 field.set_value(field_value); | 5148 field.set_value(field_value); |
| 5140 if (!has_simple_literal) { | 5149 if (!has_simple_literal) { |
| 5141 // Create a static final getter. | 5150 // Create a static final getter. |
| 5142 String& getter_name = String::Handle(I, | 5151 String& getter_name = String::Handle(Z, |
| 5143 Field::GetterSymbol(var_name)); | 5152 Field::GetterSymbol(var_name)); |
| 5144 getter = Function::New(getter_name, | 5153 getter = Function::New(getter_name, |
| 5145 RawFunction::kImplicitStaticFinalGetter, | 5154 RawFunction::kImplicitStaticFinalGetter, |
| 5146 is_static, | 5155 is_static, |
| 5147 is_const, | 5156 is_const, |
| 5148 /* is_abstract = */ false, | 5157 /* is_abstract = */ false, |
| 5149 /* is_external = */ false, | 5158 /* is_external = */ false, |
| 5150 /* is_native = */ false, | 5159 /* is_native = */ false, |
| 5151 current_class(), | 5160 current_class(), |
| 5152 name_pos); | 5161 name_pos); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 5182 return RawFunction::kAsync; | 5191 return RawFunction::kAsync; |
| 5183 } | 5192 } |
| 5184 return RawFunction::kNoModifier; | 5193 return RawFunction::kNoModifier; |
| 5185 } | 5194 } |
| 5186 | 5195 |
| 5187 | 5196 |
| 5188 void Parser::ParseTopLevelFunction(TopLevel* top_level, | 5197 void Parser::ParseTopLevelFunction(TopLevel* top_level, |
| 5189 intptr_t metadata_pos) { | 5198 intptr_t metadata_pos) { |
| 5190 TRACE_PARSER("ParseTopLevelFunction"); | 5199 TRACE_PARSER("ParseTopLevelFunction"); |
| 5191 const intptr_t decl_begin_pos = TokenPos(); | 5200 const intptr_t decl_begin_pos = TokenPos(); |
| 5192 AbstractType& result_type = Type::Handle(I, Type::DynamicType()); | 5201 AbstractType& result_type = Type::Handle(Z, Type::DynamicType()); |
| 5193 const bool is_static = true; | 5202 const bool is_static = true; |
| 5194 bool is_external = false; | 5203 bool is_external = false; |
| 5195 bool is_patch = false; | 5204 bool is_patch = false; |
| 5196 if (is_patch_source() && | 5205 if (is_patch_source() && |
| 5197 (CurrentToken() == Token::kIDENT) && | 5206 (CurrentToken() == Token::kIDENT) && |
| 5198 CurrentLiteral()->Equals("patch") && | 5207 CurrentLiteral()->Equals("patch") && |
| 5199 (LookaheadToken(1) != Token::kLPAREN)) { | 5208 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5200 ConsumeToken(); | 5209 ConsumeToken(); |
| 5201 is_patch = true; | 5210 is_patch = true; |
| 5202 } else if (CurrentToken() == Token::kEXTERNAL) { | 5211 } else if (CurrentToken() == Token::kEXTERNAL) { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 5216 const intptr_t name_pos = TokenPos(); | 5225 const intptr_t name_pos = TokenPos(); |
| 5217 const String& func_name = *ExpectIdentifier("function name expected"); | 5226 const String& func_name = *ExpectIdentifier("function name expected"); |
| 5218 | 5227 |
| 5219 bool found = library_.LookupLocalObject(func_name) != Object::null(); | 5228 bool found = library_.LookupLocalObject(func_name) != Object::null(); |
| 5220 if (found && !is_patch) { | 5229 if (found && !is_patch) { |
| 5221 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); | 5230 ReportError(name_pos, "'%s' is already defined", func_name.ToCString()); |
| 5222 } else if (!found && is_patch) { | 5231 } else if (!found && is_patch) { |
| 5223 ReportError(name_pos, "missing '%s' cannot be patched", | 5232 ReportError(name_pos, "missing '%s' cannot be patched", |
| 5224 func_name.ToCString()); | 5233 func_name.ToCString()); |
| 5225 } | 5234 } |
| 5226 String& accessor_name = String::Handle(I, | 5235 String& accessor_name = String::Handle(Z, |
| 5227 Field::GetterName(func_name)); | 5236 Field::GetterName(func_name)); |
| 5228 if (library_.LookupLocalObject(accessor_name) != Object::null()) { | 5237 if (library_.LookupLocalObject(accessor_name) != Object::null()) { |
| 5229 ReportError(name_pos, "'%s' is already defined as getter", | 5238 ReportError(name_pos, "'%s' is already defined as getter", |
| 5230 func_name.ToCString()); | 5239 func_name.ToCString()); |
| 5231 } | 5240 } |
| 5232 // A setter named x= may co-exist with a function named x, thus we do | 5241 // A setter named x= may co-exist with a function named x, thus we do |
| 5233 // not need to check setters. | 5242 // not need to check setters. |
| 5234 | 5243 |
| 5235 CheckToken(Token::kLPAREN); | 5244 CheckToken(Token::kLPAREN); |
| 5236 const intptr_t function_pos = TokenPos(); | 5245 const intptr_t function_pos = TokenPos(); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 5257 function_end_pos = TokenPos(); | 5266 function_end_pos = TokenPos(); |
| 5258 ExpectSemicolon(); | 5267 ExpectSemicolon(); |
| 5259 } else if (IsLiteral("native")) { | 5268 } else if (IsLiteral("native")) { |
| 5260 ParseNativeDeclaration(); | 5269 ParseNativeDeclaration(); |
| 5261 function_end_pos = TokenPos(); | 5270 function_end_pos = TokenPos(); |
| 5262 ExpectSemicolon(); | 5271 ExpectSemicolon(); |
| 5263 is_native = true; | 5272 is_native = true; |
| 5264 } else { | 5273 } else { |
| 5265 ReportError("function block expected"); | 5274 ReportError("function block expected"); |
| 5266 } | 5275 } |
| 5267 Function& func = Function::Handle(I, | 5276 Function& func = Function::Handle(Z, |
| 5268 Function::New(func_name, | 5277 Function::New(func_name, |
| 5269 RawFunction::kRegularFunction, | 5278 RawFunction::kRegularFunction, |
| 5270 is_static, | 5279 is_static, |
| 5271 /* is_const = */ false, | 5280 /* is_const = */ false, |
| 5272 /* is_abstract = */ false, | 5281 /* is_abstract = */ false, |
| 5273 is_external, | 5282 is_external, |
| 5274 is_native, | 5283 is_native, |
| 5275 current_class(), | 5284 current_class(), |
| 5276 decl_begin_pos)); | 5285 decl_begin_pos)); |
| 5277 func.set_result_type(result_type); | 5286 func.set_result_type(result_type); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 5296 } | 5305 } |
| 5297 | 5306 |
| 5298 | 5307 |
| 5299 void Parser::ParseTopLevelAccessor(TopLevel* top_level, | 5308 void Parser::ParseTopLevelAccessor(TopLevel* top_level, |
| 5300 intptr_t metadata_pos) { | 5309 intptr_t metadata_pos) { |
| 5301 TRACE_PARSER("ParseTopLevelAccessor"); | 5310 TRACE_PARSER("ParseTopLevelAccessor"); |
| 5302 const intptr_t decl_begin_pos = TokenPos(); | 5311 const intptr_t decl_begin_pos = TokenPos(); |
| 5303 const bool is_static = true; | 5312 const bool is_static = true; |
| 5304 bool is_external = false; | 5313 bool is_external = false; |
| 5305 bool is_patch = false; | 5314 bool is_patch = false; |
| 5306 AbstractType& result_type = AbstractType::Handle(I); | 5315 AbstractType& result_type = AbstractType::Handle(Z); |
| 5307 if (is_patch_source() && | 5316 if (is_patch_source() && |
| 5308 (CurrentToken() == Token::kIDENT) && | 5317 (CurrentToken() == Token::kIDENT) && |
| 5309 CurrentLiteral()->Equals("patch")) { | 5318 CurrentLiteral()->Equals("patch")) { |
| 5310 ConsumeToken(); | 5319 ConsumeToken(); |
| 5311 is_patch = true; | 5320 is_patch = true; |
| 5312 } else if (CurrentToken() == Token::kEXTERNAL) { | 5321 } else if (CurrentToken() == Token::kEXTERNAL) { |
| 5313 ConsumeToken(); | 5322 ConsumeToken(); |
| 5314 is_external = true; | 5323 is_external = true; |
| 5315 } | 5324 } |
| 5316 bool is_getter = (CurrentToken() == Token::kGET); | 5325 bool is_getter = (CurrentToken() == Token::kGET); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 5335 const intptr_t name_pos = TokenPos(); | 5344 const intptr_t name_pos = TokenPos(); |
| 5336 const String* field_name = ExpectIdentifier("accessor name expected"); | 5345 const String* field_name = ExpectIdentifier("accessor name expected"); |
| 5337 | 5346 |
| 5338 const intptr_t accessor_pos = TokenPos(); | 5347 const intptr_t accessor_pos = TokenPos(); |
| 5339 ParamList params; | 5348 ParamList params; |
| 5340 | 5349 |
| 5341 if (!is_getter) { | 5350 if (!is_getter) { |
| 5342 const bool allow_explicit_default_values = true; | 5351 const bool allow_explicit_default_values = true; |
| 5343 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); | 5352 ParseFormalParameterList(allow_explicit_default_values, false, ¶ms); |
| 5344 } | 5353 } |
| 5345 String& accessor_name = String::ZoneHandle(I); | 5354 String& accessor_name = String::ZoneHandle(Z); |
| 5346 int expected_num_parameters = -1; | 5355 int expected_num_parameters = -1; |
| 5347 if (is_getter) { | 5356 if (is_getter) { |
| 5348 expected_num_parameters = 0; | 5357 expected_num_parameters = 0; |
| 5349 accessor_name = Field::GetterSymbol(*field_name); | 5358 accessor_name = Field::GetterSymbol(*field_name); |
| 5350 } else { | 5359 } else { |
| 5351 expected_num_parameters = 1; | 5360 expected_num_parameters = 1; |
| 5352 accessor_name = Field::SetterSymbol(*field_name); | 5361 accessor_name = Field::SetterSymbol(*field_name); |
| 5353 } | 5362 } |
| 5354 if ((params.num_fixed_parameters != expected_num_parameters) || | 5363 if ((params.num_fixed_parameters != expected_num_parameters) || |
| 5355 (params.num_optional_parameters != 0)) { | 5364 (params.num_optional_parameters != 0)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5399 accessor_end_pos = TokenPos(); | 5408 accessor_end_pos = TokenPos(); |
| 5400 ExpectSemicolon(); | 5409 ExpectSemicolon(); |
| 5401 } else if (IsLiteral("native")) { | 5410 } else if (IsLiteral("native")) { |
| 5402 ParseNativeDeclaration(); | 5411 ParseNativeDeclaration(); |
| 5403 accessor_end_pos = TokenPos(); | 5412 accessor_end_pos = TokenPos(); |
| 5404 ExpectSemicolon(); | 5413 ExpectSemicolon(); |
| 5405 is_native = true; | 5414 is_native = true; |
| 5406 } else { | 5415 } else { |
| 5407 ReportError("function block expected"); | 5416 ReportError("function block expected"); |
| 5408 } | 5417 } |
| 5409 Function& func = Function::Handle(I, | 5418 Function& func = Function::Handle(Z, |
| 5410 Function::New(accessor_name, | 5419 Function::New(accessor_name, |
| 5411 is_getter ? RawFunction::kGetterFunction : | 5420 is_getter ? RawFunction::kGetterFunction : |
| 5412 RawFunction::kSetterFunction, | 5421 RawFunction::kSetterFunction, |
| 5413 is_static, | 5422 is_static, |
| 5414 /* is_const = */ false, | 5423 /* is_const = */ false, |
| 5415 /* is_abstract = */ false, | 5424 /* is_abstract = */ false, |
| 5416 is_external, | 5425 is_external, |
| 5417 is_native, | 5426 is_native, |
| 5418 current_class(), | 5427 current_class(), |
| 5419 decl_begin_pos)); | 5428 decl_begin_pos)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5456 // tag handler. | 5465 // tag handler. |
| 5457 I->BlockClassFinalization(); | 5466 I->BlockClassFinalization(); |
| 5458 Api::Scope api_scope(I); | 5467 Api::Scope api_scope(I); |
| 5459 Dart_Handle result = handler(tag, | 5468 Dart_Handle result = handler(tag, |
| 5460 Api::NewHandle(I, library_.raw()), | 5469 Api::NewHandle(I, library_.raw()), |
| 5461 Api::NewHandle(I, url.raw())); | 5470 Api::NewHandle(I, url.raw())); |
| 5462 I->UnblockClassFinalization(); | 5471 I->UnblockClassFinalization(); |
| 5463 if (Dart_IsError(result)) { | 5472 if (Dart_IsError(result)) { |
| 5464 // In case of an error we append an explanatory error message to the | 5473 // In case of an error we append an explanatory error message to the |
| 5465 // error obtained from the library tag handler. | 5474 // error obtained from the library tag handler. |
| 5466 Error& prev_error = Error::Handle(I); | 5475 Error& prev_error = Error::Handle(Z); |
| 5467 prev_error ^= Api::UnwrapHandle(result); | 5476 prev_error ^= Api::UnwrapHandle(result); |
| 5468 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); | 5477 Report::LongJumpF(prev_error, script_, token_pos, "library handler failed"); |
| 5469 } | 5478 } |
| 5470 if (tag == Dart_kCanonicalizeUrl) { | 5479 if (tag == Dart_kCanonicalizeUrl) { |
| 5471 if (!Dart_IsString(result)) { | 5480 if (!Dart_IsString(result)) { |
| 5472 ReportError(token_pos, "library handler failed URI canonicalization"); | 5481 ReportError(token_pos, "library handler failed URI canonicalization"); |
| 5473 } | 5482 } |
| 5474 } | 5483 } |
| 5475 return Api::UnwrapHandle(result); | 5484 return Api::UnwrapHandle(result); |
| 5476 } | 5485 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5522 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); | 5531 const String& url = String::Cast(url_literal->AsLiteralNode()->literal()); |
| 5523 if (url.Length() == 0) { | 5532 if (url.Length() == 0) { |
| 5524 ReportError("library url expected"); | 5533 ReportError("library url expected"); |
| 5525 } | 5534 } |
| 5526 bool is_deferred_import = false; | 5535 bool is_deferred_import = false; |
| 5527 if (is_import && (IsLiteral("deferred"))) { | 5536 if (is_import && (IsLiteral("deferred"))) { |
| 5528 is_deferred_import = true; | 5537 is_deferred_import = true; |
| 5529 ConsumeToken(); | 5538 ConsumeToken(); |
| 5530 CheckToken(Token::kAS, "'as' expected"); | 5539 CheckToken(Token::kAS, "'as' expected"); |
| 5531 } | 5540 } |
| 5532 String& prefix = String::Handle(I); | 5541 String& prefix = String::Handle(Z); |
| 5533 intptr_t prefix_pos = 0; | 5542 intptr_t prefix_pos = 0; |
| 5534 if (is_import && (CurrentToken() == Token::kAS)) { | 5543 if (is_import && (CurrentToken() == Token::kAS)) { |
| 5535 ConsumeToken(); | 5544 ConsumeToken(); |
| 5536 prefix_pos = TokenPos(); | 5545 prefix_pos = TokenPos(); |
| 5537 prefix = ExpectIdentifier("prefix identifier expected")->raw(); | 5546 prefix = ExpectIdentifier("prefix identifier expected")->raw(); |
| 5538 } | 5547 } |
| 5539 | 5548 |
| 5540 Array& show_names = Array::Handle(I); | 5549 Array& show_names = Array::Handle(Z); |
| 5541 Array& hide_names = Array::Handle(I); | 5550 Array& hide_names = Array::Handle(Z); |
| 5542 if (is_deferred_import || IsLiteral("show") || IsLiteral("hide")) { | 5551 if (is_deferred_import || IsLiteral("show") || IsLiteral("hide")) { |
| 5543 GrowableObjectArray& show_list = | 5552 GrowableObjectArray& show_list = |
| 5544 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 5553 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 5545 GrowableObjectArray& hide_list = | 5554 GrowableObjectArray& hide_list = |
| 5546 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 5555 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 5547 // Libraries imported through deferred import automatically hide | 5556 // Libraries imported through deferred import automatically hide |
| 5548 // the name 'loadLibrary'. | 5557 // the name 'loadLibrary'. |
| 5549 if (is_deferred_import) { | 5558 if (is_deferred_import) { |
| 5550 hide_list.Add(Symbols::LoadLibrary()); | 5559 hide_list.Add(Symbols::LoadLibrary()); |
| 5551 } | 5560 } |
| 5552 for (;;) { | 5561 for (;;) { |
| 5553 if (IsLiteral("show")) { | 5562 if (IsLiteral("show")) { |
| 5554 ConsumeToken(); | 5563 ConsumeToken(); |
| 5555 ParseIdentList(&show_list); | 5564 ParseIdentList(&show_list); |
| 5556 } else if (IsLiteral("hide")) { | 5565 } else if (IsLiteral("hide")) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 5567 hide_names = Array::MakeArray(hide_list); | 5576 hide_names = Array::MakeArray(hide_list); |
| 5568 } | 5577 } |
| 5569 } | 5578 } |
| 5570 ExpectSemicolon(); | 5579 ExpectSemicolon(); |
| 5571 | 5580 |
| 5572 // Canonicalize library URL. | 5581 // Canonicalize library URL. |
| 5573 const String& canon_url = String::CheckedHandle( | 5582 const String& canon_url = String::CheckedHandle( |
| 5574 CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url)); | 5583 CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url)); |
| 5575 | 5584 |
| 5576 // Create a new library if it does not exist yet. | 5585 // Create a new library if it does not exist yet. |
| 5577 Library& library = Library::Handle(I, Library::LookupLibrary(canon_url)); | 5586 Library& library = Library::Handle(Z, Library::LookupLibrary(canon_url)); |
| 5578 if (library.IsNull()) { | 5587 if (library.IsNull()) { |
| 5579 library = Library::New(canon_url); | 5588 library = Library::New(canon_url); |
| 5580 library.Register(); | 5589 library.Register(); |
| 5581 } | 5590 } |
| 5582 | 5591 |
| 5583 // If loading hasn't been requested yet, and if this is not a deferred | 5592 // If loading hasn't been requested yet, and if this is not a deferred |
| 5584 // library import, call the library tag handler to request loading | 5593 // library import, call the library tag handler to request loading |
| 5585 // the library. | 5594 // the library. |
| 5586 if (library.LoadNotStarted() && !is_deferred_import) { | 5595 if (library.LoadNotStarted() && !is_deferred_import) { |
| 5587 library.SetLoadRequested(); | 5596 library.SetLoadRequested(); |
| 5588 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); | 5597 CallLibraryTagHandler(Dart_kImportTag, import_pos, canon_url); |
| 5589 } | 5598 } |
| 5590 | 5599 |
| 5591 Namespace& ns = Namespace::Handle(I, | 5600 Namespace& ns = Namespace::Handle(Z, |
| 5592 Namespace::New(library, show_names, hide_names)); | 5601 Namespace::New(library, show_names, hide_names)); |
| 5593 if (metadata_pos >= 0) { | 5602 if (metadata_pos >= 0) { |
| 5594 ns.AddMetadata(metadata_pos, current_class()); | 5603 ns.AddMetadata(metadata_pos, current_class()); |
| 5595 } | 5604 } |
| 5596 | 5605 |
| 5597 if (is_import) { | 5606 if (is_import) { |
| 5598 // Ensure that private dart:_ libraries are only imported into dart: | 5607 // Ensure that private dart:_ libraries are only imported into dart: |
| 5599 // libraries. | 5608 // libraries. |
| 5600 const String& lib_url = String::Handle(I, library_.url()); | 5609 const String& lib_url = String::Handle(Z, library_.url()); |
| 5601 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && | 5610 if (canon_url.StartsWith(Symbols::DartSchemePrivate()) && |
| 5602 !lib_url.StartsWith(Symbols::DartScheme())) { | 5611 !lib_url.StartsWith(Symbols::DartScheme())) { |
| 5603 ReportError(import_pos, "private library is not accessible"); | 5612 ReportError(import_pos, "private library is not accessible"); |
| 5604 } | 5613 } |
| 5605 if (prefix.IsNull() || (prefix.Length() == 0)) { | 5614 if (prefix.IsNull() || (prefix.Length() == 0)) { |
| 5606 ASSERT(!is_deferred_import); | 5615 ASSERT(!is_deferred_import); |
| 5607 library_.AddImport(ns); | 5616 library_.AddImport(ns); |
| 5608 } else { | 5617 } else { |
| 5609 LibraryPrefix& library_prefix = LibraryPrefix::Handle(I); | 5618 LibraryPrefix& library_prefix = LibraryPrefix::Handle(Z); |
| 5610 library_prefix = library_.LookupLocalLibraryPrefix(prefix); | 5619 library_prefix = library_.LookupLocalLibraryPrefix(prefix); |
| 5611 if (!library_prefix.IsNull()) { | 5620 if (!library_prefix.IsNull()) { |
| 5612 // Check that prefix names of deferred import clauses are | 5621 // Check that prefix names of deferred import clauses are |
| 5613 // unique. | 5622 // unique. |
| 5614 if (!is_deferred_import && library_prefix.is_deferred_load()) { | 5623 if (!is_deferred_import && library_prefix.is_deferred_load()) { |
| 5615 ReportError(prefix_pos, | 5624 ReportError(prefix_pos, |
| 5616 "prefix '%s' already used in a deferred import clause", | 5625 "prefix '%s' already used in a deferred import clause", |
| 5617 prefix.ToCString()); | 5626 prefix.ToCString()); |
| 5618 } | 5627 } |
| 5619 if (is_deferred_import) { | 5628 if (is_deferred_import) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5678 } | 5687 } |
| 5679 while ((CurrentToken() == Token::kIMPORT) || | 5688 while ((CurrentToken() == Token::kIMPORT) || |
| 5680 (CurrentToken() == Token::kEXPORT)) { | 5689 (CurrentToken() == Token::kEXPORT)) { |
| 5681 ParseLibraryImportExport(metadata_pos); | 5690 ParseLibraryImportExport(metadata_pos); |
| 5682 rewind_pos = TokenPos(); | 5691 rewind_pos = TokenPos(); |
| 5683 metadata_pos = SkipMetadata(); | 5692 metadata_pos = SkipMetadata(); |
| 5684 } | 5693 } |
| 5685 // Core lib has not been explicitly imported, so we implicitly | 5694 // Core lib has not been explicitly imported, so we implicitly |
| 5686 // import it here. | 5695 // import it here. |
| 5687 if (!library_.ImportsCorelib()) { | 5696 if (!library_.ImportsCorelib()) { |
| 5688 Library& core_lib = Library::Handle(I, Library::CoreLibrary()); | 5697 Library& core_lib = Library::Handle(Z, Library::CoreLibrary()); |
| 5689 ASSERT(!core_lib.IsNull()); | 5698 ASSERT(!core_lib.IsNull()); |
| 5690 const Namespace& core_ns = Namespace::Handle(I, | 5699 const Namespace& core_ns = Namespace::Handle(Z, |
| 5691 Namespace::New(core_lib, Object::null_array(), Object::null_array())); | 5700 Namespace::New(core_lib, Object::null_array(), Object::null_array())); |
| 5692 library_.AddImport(core_ns); | 5701 library_.AddImport(core_ns); |
| 5693 } | 5702 } |
| 5694 while (CurrentToken() == Token::kPART) { | 5703 while (CurrentToken() == Token::kPART) { |
| 5695 ParseLibraryPart(); | 5704 ParseLibraryPart(); |
| 5696 rewind_pos = TokenPos(); | 5705 rewind_pos = TokenPos(); |
| 5697 metadata_pos = SkipMetadata(); | 5706 metadata_pos = SkipMetadata(); |
| 5698 } | 5707 } |
| 5699 SetPosition(rewind_pos); | 5708 SetPosition(rewind_pos); |
| 5700 } | 5709 } |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 5719 } | 5728 } |
| 5720 | 5729 |
| 5721 | 5730 |
| 5722 void Parser::ParseTopLevel() { | 5731 void Parser::ParseTopLevel() { |
| 5723 TRACE_PARSER("ParseTopLevel"); | 5732 TRACE_PARSER("ParseTopLevel"); |
| 5724 // Collect the classes found at the top level in this growable array. | 5733 // Collect the classes found at the top level in this growable array. |
| 5725 // They need to be registered with class finalization after parsing | 5734 // They need to be registered with class finalization after parsing |
| 5726 // has been completed. | 5735 // has been completed. |
| 5727 ObjectStore* object_store = I->object_store(); | 5736 ObjectStore* object_store = I->object_store(); |
| 5728 const GrowableObjectArray& pending_classes = | 5737 const GrowableObjectArray& pending_classes = |
| 5729 GrowableObjectArray::Handle(I, object_store->pending_classes()); | 5738 GrowableObjectArray::Handle(Z, object_store->pending_classes()); |
| 5730 SetPosition(0); | 5739 SetPosition(0); |
| 5731 is_top_level_ = true; | 5740 is_top_level_ = true; |
| 5732 TopLevel top_level; | 5741 TopLevel top_level; |
| 5733 Class& toplevel_class = Class::Handle(I, | 5742 Class& toplevel_class = Class::Handle(Z, |
| 5734 Class::New(Symbols::TopLevel(), script_, TokenPos())); | 5743 Class::New(Symbols::TopLevel(), script_, TokenPos())); |
| 5735 toplevel_class.set_library(library_); | 5744 toplevel_class.set_library(library_); |
| 5736 | 5745 |
| 5737 if (is_library_source() || is_patch_source()) { | 5746 if (is_library_source() || is_patch_source()) { |
| 5738 set_current_class(toplevel_class); | 5747 set_current_class(toplevel_class); |
| 5739 ParseLibraryDefinition(); | 5748 ParseLibraryDefinition(); |
| 5740 } else if (is_part_source()) { | 5749 } else if (is_part_source()) { |
| 5741 ParsePartHeader(); | 5750 ParsePartHeader(); |
| 5742 } | 5751 } |
| 5743 | 5752 |
| 5744 const Class& cls = Class::Handle(I); | 5753 const Class& cls = Class::Handle(Z); |
| 5745 while (true) { | 5754 while (true) { |
| 5746 set_current_class(cls); // No current class. | 5755 set_current_class(cls); // No current class. |
| 5747 intptr_t metadata_pos = SkipMetadata(); | 5756 intptr_t metadata_pos = SkipMetadata(); |
| 5748 if (CurrentToken() == Token::kCLASS) { | 5757 if (CurrentToken() == Token::kCLASS) { |
| 5749 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); | 5758 ParseClassDeclaration(pending_classes, toplevel_class, metadata_pos); |
| 5750 } else if (CurrentToken() == Token::kENUM) { | 5759 } else if (CurrentToken() == Token::kENUM) { |
| 5751 ParseEnumDeclaration(pending_classes, toplevel_class, metadata_pos); | 5760 ParseEnumDeclaration(pending_classes, toplevel_class, metadata_pos); |
| 5752 } else if ((CurrentToken() == Token::kTYPEDEF) && | 5761 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 5753 (LookaheadToken(1) != Token::kLPAREN)) { | 5762 (LookaheadToken(1) != Token::kLPAREN)) { |
| 5754 set_current_class(toplevel_class); | 5763 set_current_class(toplevel_class); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 5770 } else if (CurrentToken() == Token::kEOS) { | 5779 } else if (CurrentToken() == Token::kEOS) { |
| 5771 break; | 5780 break; |
| 5772 } else { | 5781 } else { |
| 5773 UnexpectedToken(); | 5782 UnexpectedToken(); |
| 5774 } | 5783 } |
| 5775 } | 5784 } |
| 5776 } | 5785 } |
| 5777 if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) { | 5786 if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) { |
| 5778 toplevel_class.AddFields(top_level.fields); | 5787 toplevel_class.AddFields(top_level.fields); |
| 5779 | 5788 |
| 5780 const Array& array = Array::Handle(I, | 5789 const Array& array = Array::Handle(Z, |
| 5781 Array::MakeArray(top_level.functions)); | 5790 Array::MakeArray(top_level.functions)); |
| 5782 toplevel_class.SetFunctions(array); | 5791 toplevel_class.SetFunctions(array); |
| 5783 | 5792 |
| 5784 library_.AddAnonymousClass(toplevel_class); | 5793 library_.AddAnonymousClass(toplevel_class); |
| 5785 pending_classes.Add(toplevel_class, Heap::kOld); | 5794 pending_classes.Add(toplevel_class, Heap::kOld); |
| 5786 } | 5795 } |
| 5787 } | 5796 } |
| 5788 | 5797 |
| 5789 | 5798 |
| 5790 void Parser::ChainNewBlock(LocalScope* outer_scope) { | 5799 void Parser::ChainNewBlock(LocalScope* outer_scope) { |
| 5791 Block* block = new(I) Block( | 5800 Block* block = new(Z) Block( |
| 5792 current_block_, | 5801 current_block_, |
| 5793 outer_scope, | 5802 outer_scope, |
| 5794 new(I) SequenceNode(TokenPos(), outer_scope)); | 5803 new(Z) SequenceNode(TokenPos(), outer_scope)); |
| 5795 current_block_ = block; | 5804 current_block_ = block; |
| 5796 } | 5805 } |
| 5797 | 5806 |
| 5798 | 5807 |
| 5799 void Parser::OpenBlock() { | 5808 void Parser::OpenBlock() { |
| 5800 ASSERT(current_block_ != NULL); | 5809 ASSERT(current_block_ != NULL); |
| 5801 LocalScope* outer_scope = current_block_->scope; | 5810 LocalScope* outer_scope = current_block_->scope; |
| 5802 ChainNewBlock(new(I) LocalScope( | 5811 ChainNewBlock(new(Z) LocalScope( |
| 5803 outer_scope, outer_scope->function_level(), outer_scope->loop_level())); | 5812 outer_scope, outer_scope->function_level(), outer_scope->loop_level())); |
| 5804 } | 5813 } |
| 5805 | 5814 |
| 5806 | 5815 |
| 5807 void Parser::OpenLoopBlock() { | 5816 void Parser::OpenLoopBlock() { |
| 5808 ASSERT(current_block_ != NULL); | 5817 ASSERT(current_block_ != NULL); |
| 5809 LocalScope* outer_scope = current_block_->scope; | 5818 LocalScope* outer_scope = current_block_->scope; |
| 5810 ChainNewBlock(new(I) LocalScope( | 5819 ChainNewBlock(new(Z) LocalScope( |
| 5811 outer_scope, | 5820 outer_scope, |
| 5812 outer_scope->function_level(), | 5821 outer_scope->function_level(), |
| 5813 outer_scope->loop_level() + 1)); | 5822 outer_scope->loop_level() + 1)); |
| 5814 } | 5823 } |
| 5815 | 5824 |
| 5816 | 5825 |
| 5817 void Parser::OpenFunctionBlock(const Function& func) { | 5826 void Parser::OpenFunctionBlock(const Function& func) { |
| 5818 LocalScope* outer_scope; | 5827 LocalScope* outer_scope; |
| 5819 if (current_block_ == NULL) { | 5828 if (current_block_ == NULL) { |
| 5820 if (!func.IsLocalFunction()) { | 5829 if (!func.IsLocalFunction()) { |
| 5821 // We are compiling a non-nested function. | 5830 // We are compiling a non-nested function. |
| 5822 outer_scope = new(I) LocalScope(NULL, 0, 0); | 5831 outer_scope = new(Z) LocalScope(NULL, 0, 0); |
| 5823 } else { | 5832 } else { |
| 5824 // We are compiling the function of an invoked closure. | 5833 // We are compiling the function of an invoked closure. |
| 5825 // Restore the outer scope containing all captured variables. | 5834 // Restore the outer scope containing all captured variables. |
| 5826 const ContextScope& context_scope = | 5835 const ContextScope& context_scope = |
| 5827 ContextScope::Handle(I, func.context_scope()); | 5836 ContextScope::Handle(Z, func.context_scope()); |
| 5828 ASSERT(!context_scope.IsNull()); | 5837 ASSERT(!context_scope.IsNull()); |
| 5829 outer_scope = new(I) LocalScope( | 5838 outer_scope = new(Z) LocalScope( |
| 5830 LocalScope::RestoreOuterScope(context_scope), 0, 0); | 5839 LocalScope::RestoreOuterScope(context_scope), 0, 0); |
| 5831 } | 5840 } |
| 5832 } else { | 5841 } else { |
| 5833 // We are parsing a nested function while compiling the enclosing function. | 5842 // We are parsing a nested function while compiling the enclosing function. |
| 5834 outer_scope = | 5843 outer_scope = |
| 5835 new(I) LocalScope(current_block_->scope, | 5844 new(Z) LocalScope(current_block_->scope, |
| 5836 current_block_->scope->function_level() + 1, | 5845 current_block_->scope->function_level() + 1, |
| 5837 0); | 5846 0); |
| 5838 } | 5847 } |
| 5839 ChainNewBlock(outer_scope); | 5848 ChainNewBlock(outer_scope); |
| 5840 } | 5849 } |
| 5841 | 5850 |
| 5842 | 5851 |
| 5843 void Parser::OpenAsyncClosure() { | 5852 void Parser::OpenAsyncClosure() { |
| 5844 TRACE_PARSER("OpenAsyncClosure"); | 5853 TRACE_PARSER("OpenAsyncClosure"); |
| 5845 | 5854 |
| 5846 async_temp_scope_ = current_block_->scope; | 5855 async_temp_scope_ = current_block_->scope; |
| 5847 | 5856 |
| 5848 OpenAsyncTryBlock(); | 5857 OpenAsyncTryBlock(); |
| 5849 } | 5858 } |
| 5850 | 5859 |
| 5851 | 5860 |
| 5852 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { | 5861 SequenceNode* Parser::CloseAsyncTryBlock(SequenceNode* try_block) { |
| 5853 try_blocks_list_->enter_catch(); | 5862 try_blocks_list_->enter_catch(); |
| 5854 | 5863 |
| 5855 OpenBlock(); | 5864 OpenBlock(); |
| 5856 OpenBlock(); | 5865 OpenBlock(); |
| 5857 const AbstractType& dynamic_type = | 5866 const AbstractType& dynamic_type = |
| 5858 AbstractType::ZoneHandle(I, Type::DynamicType()); | 5867 AbstractType::ZoneHandle(Z, Type::DynamicType()); |
| 5859 CatchParamDesc exception_param; | 5868 CatchParamDesc exception_param; |
| 5860 CatchParamDesc stack_trace_param; | 5869 CatchParamDesc stack_trace_param; |
| 5861 exception_param.token_pos = Scanner::kNoSourcePos; | 5870 exception_param.token_pos = Scanner::kNoSourcePos; |
| 5862 exception_param.type = &dynamic_type; | 5871 exception_param.type = &dynamic_type; |
| 5863 exception_param.name = &Symbols::ExceptionParameter(); | 5872 exception_param.name = &Symbols::ExceptionParameter(); |
| 5864 stack_trace_param.token_pos = Scanner::kNoSourcePos; | 5873 stack_trace_param.token_pos = Scanner::kNoSourcePos; |
| 5865 stack_trace_param.type = &dynamic_type; | 5874 stack_trace_param.type = &dynamic_type; |
| 5866 stack_trace_param.name = &Symbols::StackTraceParameter(); | 5875 stack_trace_param.name = &Symbols::StackTraceParameter(); |
| 5867 | 5876 |
| 5868 AddCatchParamsToScope( | 5877 AddCatchParamsToScope( |
| 5869 &exception_param, &stack_trace_param, current_block_->scope); | 5878 &exception_param, &stack_trace_param, current_block_->scope); |
| 5870 | 5879 |
| 5871 LocalVariable* context_var = current_block_->scope->LookupVariable( | 5880 LocalVariable* context_var = current_block_->scope->LookupVariable( |
| 5872 Symbols::SavedTryContextVar(), false); | 5881 Symbols::SavedTryContextVar(), false); |
| 5873 ASSERT(context_var != NULL); | 5882 ASSERT(context_var != NULL); |
| 5874 LocalVariable* exception_var = current_block_->scope->LookupVariable( | 5883 LocalVariable* exception_var = current_block_->scope->LookupVariable( |
| 5875 Symbols::ExceptionVar(), false); | 5884 Symbols::ExceptionVar(), false); |
| 5876 if (exception_param.var != NULL) { | 5885 if (exception_param.var != NULL) { |
| 5877 // Generate code to load the exception object (:exception_var) into | 5886 // Generate code to load the exception object (:exception_var) into |
| 5878 // the exception variable specified in this block. | 5887 // the exception variable specified in this block. |
| 5879 ASSERT(exception_var != NULL); | 5888 ASSERT(exception_var != NULL); |
| 5880 current_block_->statements->Add(new(I) StoreLocalNode( | 5889 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 5881 Scanner::kNoSourcePos, | 5890 Scanner::kNoSourcePos, |
| 5882 exception_param.var, | 5891 exception_param.var, |
| 5883 new(I) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); | 5892 new(Z) LoadLocalNode(Scanner::kNoSourcePos, exception_var))); |
| 5884 } | 5893 } |
| 5885 LocalVariable* stack_trace_var = | 5894 LocalVariable* stack_trace_var = |
| 5886 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); | 5895 current_block_->scope->LookupVariable(Symbols::StackTraceVar(), false); |
| 5887 if (stack_trace_param.var != NULL) { | 5896 if (stack_trace_param.var != NULL) { |
| 5888 // A stack trace variable is specified in this block, so generate code | 5897 // A stack trace variable is specified in this block, so generate code |
| 5889 // to load the stack trace object (:stack_trace_var) into the stack | 5898 // to load the stack trace object (:stack_trace_var) into the stack |
| 5890 // trace variable specified in this block. | 5899 // trace variable specified in this block. |
| 5891 ArgumentListNode* no_args = new(I) ArgumentListNode(Scanner::kNoSourcePos); | 5900 ArgumentListNode* no_args = new(Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 5892 ASSERT(stack_trace_var != NULL); | 5901 ASSERT(stack_trace_var != NULL); |
| 5893 current_block_->statements->Add(new(I) StoreLocalNode( | 5902 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 5894 Scanner::kNoSourcePos, | 5903 Scanner::kNoSourcePos, |
| 5895 stack_trace_param.var, | 5904 stack_trace_param.var, |
| 5896 new(I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); | 5905 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_var))); |
| 5897 current_block_->statements->Add(new(I) InstanceCallNode( | 5906 current_block_->statements->Add(new(Z) InstanceCallNode( |
| 5898 Scanner::kNoSourcePos, | 5907 Scanner::kNoSourcePos, |
| 5899 new(I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var), | 5908 new(Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var), |
| 5900 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 5909 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
| 5901 no_args)); | 5910 no_args)); |
| 5902 } | 5911 } |
| 5903 | 5912 |
| 5904 ASSERT(try_blocks_list_ != NULL); | 5913 ASSERT(try_blocks_list_ != NULL); |
| 5905 if (innermost_function().is_async_closure() || | 5914 if (innermost_function().is_async_closure() || |
| 5906 innermost_function().IsAsyncFunction()) { | 5915 innermost_function().IsAsyncFunction()) { |
| 5907 if ((try_blocks_list_->outer_try_block() != NULL) && | 5916 if ((try_blocks_list_->outer_try_block() != NULL) && |
| 5908 (try_blocks_list_->outer_try_block()->try_block() | 5917 (try_blocks_list_->outer_try_block()->try_block() |
| 5909 ->scope->function_level() == | 5918 ->scope->function_level() == |
| 5910 current_block_->scope->function_level())) { | 5919 current_block_->scope->function_level())) { |
| 5911 // We need to unchain three scope levels: catch clause, catch | 5920 // We need to unchain three scope levels: catch clause, catch |
| 5912 // parameters, and the general try block. | 5921 // parameters, and the general try block. |
| 5913 RestoreSavedTryContext( | 5922 RestoreSavedTryContext( |
| 5914 current_block_->scope->parent()->parent()->parent(), | 5923 current_block_->scope->parent()->parent()->parent(), |
| 5915 try_blocks_list_->outer_try_block()->try_index(), | 5924 try_blocks_list_->outer_try_block()->try_index(), |
| 5916 current_block_->statements); | 5925 current_block_->statements); |
| 5917 } else { | 5926 } else { |
| 5918 parsed_function()->reset_saved_try_ctx_vars(); | 5927 parsed_function()->reset_saved_try_ctx_vars(); |
| 5919 } | 5928 } |
| 5920 } | 5929 } |
| 5921 | 5930 |
| 5922 // Complete the async future with an error. | 5931 // Complete the async future with an error. |
| 5923 // Since we control the catch block there is no need to generate a nested | 5932 // Since we control the catch block there is no need to generate a nested |
| 5924 // if/then/else. | 5933 // if/then/else. |
| 5925 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 5934 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
| 5926 Symbols::AsyncCompleter(), false); | 5935 Symbols::AsyncCompleter(), false); |
| 5927 ASSERT(async_completer != NULL); | 5936 ASSERT(async_completer != NULL); |
| 5928 ArgumentListNode* completer_args = | 5937 ArgumentListNode* completer_args = |
| 5929 new (I) ArgumentListNode(Scanner::kNoSourcePos); | 5938 new (Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 5930 completer_args->Add( | 5939 completer_args->Add( |
| 5931 new (I) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); | 5940 new (Z) LoadLocalNode(Scanner::kNoSourcePos, exception_param.var)); |
| 5932 completer_args->Add( | 5941 completer_args->Add( |
| 5933 new (I) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); | 5942 new (Z) LoadLocalNode(Scanner::kNoSourcePos, stack_trace_param.var)); |
| 5934 current_block_->statements->Add(new (I) InstanceCallNode( | 5943 current_block_->statements->Add(new (Z) InstanceCallNode( |
| 5935 Scanner::kNoSourcePos, | 5944 Scanner::kNoSourcePos, |
| 5936 new (I) LoadLocalNode(Scanner::kNoSourcePos, async_completer), | 5945 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_completer), |
| 5937 Symbols::CompleterCompleteError(), | 5946 Symbols::CompleterCompleteError(), |
| 5938 completer_args)); | 5947 completer_args)); |
| 5939 ReturnNode* return_node = new (I) ReturnNode(Scanner::kNoSourcePos); | 5948 ReturnNode* return_node = new (Z) ReturnNode(Scanner::kNoSourcePos); |
| 5940 // Behavior like a continuation return, i.e,. don't call a completer. | 5949 // Behavior like a continuation return, i.e,. don't call a completer. |
| 5941 return_node->set_return_type(ReturnNode::kContinuation); | 5950 return_node->set_return_type(ReturnNode::kContinuation); |
| 5942 current_block_->statements->Add(return_node); | 5951 current_block_->statements->Add(return_node); |
| 5943 AstNode* catch_block = CloseBlock(); | 5952 AstNode* catch_block = CloseBlock(); |
| 5944 current_block_->statements->Add(catch_block); | 5953 current_block_->statements->Add(catch_block); |
| 5945 SequenceNode* catch_handler_list = CloseBlock(); | 5954 SequenceNode* catch_handler_list = CloseBlock(); |
| 5946 | 5955 |
| 5947 const GrowableObjectArray& handler_types = | 5956 const GrowableObjectArray& handler_types = |
| 5948 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 5957 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 5949 handler_types.SetLength(0); | 5958 handler_types.SetLength(0); |
| 5950 handler_types.Add(*exception_param.type); | 5959 handler_types.Add(*exception_param.type); |
| 5951 | 5960 |
| 5952 TryBlocks* inner_try_block = PopTryBlock(); | 5961 TryBlocks* inner_try_block = PopTryBlock(); |
| 5953 const intptr_t try_index = inner_try_block->try_index(); | 5962 const intptr_t try_index = inner_try_block->try_index(); |
| 5954 | 5963 |
| 5955 CatchClauseNode* catch_clause = new (I) CatchClauseNode( | 5964 CatchClauseNode* catch_clause = new (Z) CatchClauseNode( |
| 5956 Scanner::kNoSourcePos, | 5965 Scanner::kNoSourcePos, |
| 5957 catch_handler_list, | 5966 catch_handler_list, |
| 5958 Array::ZoneHandle(I, Array::MakeArray(handler_types)), | 5967 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 5959 context_var, | 5968 context_var, |
| 5960 exception_var, | 5969 exception_var, |
| 5961 stack_trace_var, | 5970 stack_trace_var, |
| 5962 CatchClauseNode::kInvalidTryIndex, | 5971 CatchClauseNode::kInvalidTryIndex, |
| 5963 true); | 5972 true); |
| 5964 AstNode* try_catch_node = new (I) TryCatchNode( | 5973 AstNode* try_catch_node = new (Z) TryCatchNode( |
| 5965 Scanner::kNoSourcePos, | 5974 Scanner::kNoSourcePos, |
| 5966 try_block, | 5975 try_block, |
| 5967 context_var, | 5976 context_var, |
| 5968 catch_clause, | 5977 catch_clause, |
| 5969 NULL, | 5978 NULL, |
| 5970 try_index); | 5979 try_index); |
| 5971 current_block_->statements->Add(try_catch_node); | 5980 current_block_->statements->Add(try_catch_node); |
| 5972 return CloseBlock(); | 5981 return CloseBlock(); |
| 5973 } | 5982 } |
| 5974 | 5983 |
| 5975 | 5984 |
| 5976 void Parser::OpenAsyncTryBlock() { | 5985 void Parser::OpenAsyncTryBlock() { |
| 5977 // Manually wrapping the actual body into a try/catch block. | 5986 // Manually wrapping the actual body into a try/catch block. |
| 5978 LocalVariable* context_var = | 5987 LocalVariable* context_var = |
| 5979 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 5988 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 5980 if (context_var == NULL) { | 5989 if (context_var == NULL) { |
| 5981 context_var = new(I) LocalVariable( | 5990 context_var = new(Z) LocalVariable( |
| 5982 TokenPos(), | 5991 TokenPos(), |
| 5983 Symbols::SavedTryContextVar(), | 5992 Symbols::SavedTryContextVar(), |
| 5984 Type::ZoneHandle(I, Type::DynamicType())); | 5993 Type::ZoneHandle(Z, Type::DynamicType())); |
| 5985 current_block_->scope->AddVariable(context_var); | 5994 current_block_->scope->AddVariable(context_var); |
| 5986 } | 5995 } |
| 5987 LocalVariable* exception_var = | 5996 LocalVariable* exception_var = |
| 5988 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); | 5997 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 5989 if (exception_var == NULL) { | 5998 if (exception_var == NULL) { |
| 5990 exception_var = new(I) LocalVariable( | 5999 exception_var = new(Z) LocalVariable( |
| 5991 TokenPos(), | 6000 TokenPos(), |
| 5992 Symbols::ExceptionVar(), | 6001 Symbols::ExceptionVar(), |
| 5993 Type::ZoneHandle(I, Type::DynamicType())); | 6002 Type::ZoneHandle(Z, Type::DynamicType())); |
| 5994 current_block_->scope->AddVariable(exception_var); | 6003 current_block_->scope->AddVariable(exception_var); |
| 5995 } | 6004 } |
| 5996 LocalVariable* stack_trace_var = | 6005 LocalVariable* stack_trace_var = |
| 5997 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); | 6006 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 5998 if (stack_trace_var == NULL) { | 6007 if (stack_trace_var == NULL) { |
| 5999 stack_trace_var = new(I) LocalVariable( | 6008 stack_trace_var = new(Z) LocalVariable( |
| 6000 TokenPos(), | 6009 TokenPos(), |
| 6001 Symbols::StackTraceVar(), | 6010 Symbols::StackTraceVar(), |
| 6002 Type::ZoneHandle(I, Type::DynamicType())); | 6011 Type::ZoneHandle(Z, Type::DynamicType())); |
| 6003 current_block_->scope->AddVariable(stack_trace_var); | 6012 current_block_->scope->AddVariable(stack_trace_var); |
| 6004 } | 6013 } |
| 6005 | 6014 |
| 6006 // Open the try block. | 6015 // Open the try block. |
| 6007 OpenBlock(); | 6016 OpenBlock(); |
| 6008 PushTryBlock(current_block_); | 6017 PushTryBlock(current_block_); |
| 6009 | 6018 |
| 6010 if (innermost_function().is_async_closure() || | 6019 if (innermost_function().is_async_closure() || |
| 6011 innermost_function().IsAsyncFunction()) { | 6020 innermost_function().IsAsyncFunction()) { |
| 6012 SetupSavedTryContext(context_var); | 6021 SetupSavedTryContext(context_var); |
| 6013 } | 6022 } |
| 6014 } | 6023 } |
| 6015 | 6024 |
| 6016 | 6025 |
| 6017 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { | 6026 RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) { |
| 6018 TRACE_PARSER("OpenAsyncFunction"); | 6027 TRACE_PARSER("OpenAsyncFunction"); |
| 6019 AddAsyncClosureVariables(); | 6028 AddAsyncClosureVariables(); |
| 6020 Function& closure = Function::Handle(I); | 6029 Function& closure = Function::Handle(Z); |
| 6021 bool is_new_closure = false; | 6030 bool is_new_closure = false; |
| 6022 | 6031 |
| 6023 // Check whether a function for the asynchronous function body of | 6032 // Check whether a function for the asynchronous function body of |
| 6024 // this async function has already been created by a previous | 6033 // this async function has already been created by a previous |
| 6025 // compilation of this function. | 6034 // compilation of this function. |
| 6026 const Function& found_func = Function::Handle( | 6035 const Function& found_func = Function::Handle( |
| 6027 I, current_class().LookupClosureFunction(async_func_pos)); | 6036 Z, current_class().LookupClosureFunction(async_func_pos)); |
| 6028 if (!found_func.IsNull() && | 6037 if (!found_func.IsNull() && |
| 6029 (found_func.token_pos() == async_func_pos) && | 6038 (found_func.token_pos() == async_func_pos) && |
| 6030 (found_func.script() == innermost_function().script()) && | 6039 (found_func.script() == innermost_function().script()) && |
| 6031 (found_func.parent_function() == innermost_function().raw())) { | 6040 (found_func.parent_function() == innermost_function().raw())) { |
| 6032 ASSERT(found_func.is_async_closure()); | 6041 ASSERT(found_func.is_async_closure()); |
| 6033 closure = found_func.raw(); | 6042 closure = found_func.raw(); |
| 6034 } else { | 6043 } else { |
| 6035 // Create the closure containing the body of this async function. | 6044 // Create the closure containing the body of this async function. |
| 6036 const String& async_func_name = | 6045 const String& async_func_name = |
| 6037 String::Handle(I, innermost_function().name()); | 6046 String::Handle(Z, innermost_function().name()); |
| 6038 String& closure_name = String::Handle(I, | 6047 String& closure_name = String::Handle(Z, |
| 6039 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); | 6048 String::NewFormatted("<%s_async_body>", async_func_name.ToCString())); |
| 6040 closure = Function::NewClosureFunction( | 6049 closure = Function::NewClosureFunction( |
| 6041 String::Handle(I, Symbols::New(closure_name)), | 6050 String::Handle(Z, Symbols::New(closure_name)), |
| 6042 innermost_function(), | 6051 innermost_function(), |
| 6043 async_func_pos); | 6052 async_func_pos); |
| 6044 closure.set_is_async_closure(true); | 6053 closure.set_is_async_closure(true); |
| 6045 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); | 6054 closure.set_result_type(AbstractType::Handle(Type::DynamicType())); |
| 6046 is_new_closure = true; | 6055 is_new_closure = true; |
| 6047 } | 6056 } |
| 6048 // Create the parameter list for the async body closure. | 6057 // Create the parameter list for the async body closure. |
| 6049 ParamList closure_params; | 6058 ParamList closure_params; |
| 6050 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType()); | 6059 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 6051 closure_params.AddFinalParameter( | 6060 closure_params.AddFinalParameter( |
| 6052 async_func_pos, &Symbols::ClosureParameter(), &dynamic_type); | 6061 async_func_pos, &Symbols::ClosureParameter(), &dynamic_type); |
| 6053 ParamDesc result_param; | 6062 ParamDesc result_param; |
| 6054 result_param.name = &Symbols::AsyncOperationParam(); | 6063 result_param.name = &Symbols::AsyncOperationParam(); |
| 6055 result_param.default_value = &Object::null_instance(); | 6064 result_param.default_value = &Object::null_instance(); |
| 6056 result_param.type = &dynamic_type; | 6065 result_param.type = &dynamic_type; |
| 6057 closure_params.parameters->Add(result_param); | 6066 closure_params.parameters->Add(result_param); |
| 6058 ParamDesc error_param; | 6067 ParamDesc error_param; |
| 6059 error_param.name = &Symbols::AsyncOperationErrorParam(); | 6068 error_param.name = &Symbols::AsyncOperationErrorParam(); |
| 6060 error_param.default_value = &Object::null_instance(); | 6069 error_param.default_value = &Object::null_instance(); |
| 6061 error_param.type = &dynamic_type; | 6070 error_param.type = &dynamic_type; |
| 6062 closure_params.parameters->Add(error_param); | 6071 closure_params.parameters->Add(error_param); |
| 6063 closure_params.has_optional_positional_parameters = true; | 6072 closure_params.has_optional_positional_parameters = true; |
| 6064 closure_params.num_optional_parameters += 2; | 6073 closure_params.num_optional_parameters += 2; |
| 6065 | 6074 |
| 6066 if (is_new_closure) { | 6075 if (is_new_closure) { |
| 6067 // Add the parameters to the newly created closure. | 6076 // Add the parameters to the newly created closure. |
| 6068 AddFormalParamsToFunction(&closure_params, closure); | 6077 AddFormalParamsToFunction(&closure_params, closure); |
| 6069 | 6078 |
| 6070 // Create and set the signature class of the closure. | 6079 // Create and set the signature class of the closure. |
| 6071 const String& sig = String::Handle(I, closure.Signature()); | 6080 const String& sig = String::Handle(Z, closure.Signature()); |
| 6072 Class& sig_cls = Class::Handle(I, library_.LookupLocalClass(sig)); | 6081 Class& sig_cls = Class::Handle(Z, library_.LookupLocalClass(sig)); |
| 6073 if (sig_cls.IsNull()) { | 6082 if (sig_cls.IsNull()) { |
| 6074 sig_cls = | 6083 sig_cls = |
| 6075 Class::NewSignatureClass(sig, closure, script_, closure.token_pos()); | 6084 Class::NewSignatureClass(sig, closure, script_, closure.token_pos()); |
| 6076 library_.AddClass(sig_cls); | 6085 library_.AddClass(sig_cls); |
| 6077 } | 6086 } |
| 6078 closure.set_signature_class(sig_cls); | 6087 closure.set_signature_class(sig_cls); |
| 6079 const Type& sig_type = Type::Handle(I, sig_cls.SignatureType()); | 6088 const Type& sig_type = Type::Handle(Z, sig_cls.SignatureType()); |
| 6080 if (!sig_type.IsFinalized()) { | 6089 if (!sig_type.IsFinalized()) { |
| 6081 ClassFinalizer::FinalizeType( | 6090 ClassFinalizer::FinalizeType( |
| 6082 sig_cls, sig_type, ClassFinalizer::kCanonicalize); | 6091 sig_cls, sig_type, ClassFinalizer::kCanonicalize); |
| 6083 } | 6092 } |
| 6084 ASSERT(AbstractType::Handle(I, closure.result_type()).IsResolved()); | 6093 ASSERT(AbstractType::Handle(Z, closure.result_type()).IsResolved()); |
| 6085 ASSERT(closure.NumParameters() == closure_params.parameters->length()); | 6094 ASSERT(closure.NumParameters() == closure_params.parameters->length()); |
| 6086 } | 6095 } |
| 6087 OpenFunctionBlock(closure); | 6096 OpenFunctionBlock(closure); |
| 6088 AddFormalParamsToScope(&closure_params, current_block_->scope); | 6097 AddFormalParamsToScope(&closure_params, current_block_->scope); |
| 6089 OpenBlock(); | 6098 OpenBlock(); |
| 6090 async_temp_scope_ = current_block_->scope; | 6099 async_temp_scope_ = current_block_->scope; |
| 6091 return closure.raw(); | 6100 return closure.raw(); |
| 6092 } | 6101 } |
| 6093 | 6102 |
| 6094 | 6103 |
| 6095 void Parser::AddAsyncClosureVariables() { | 6104 void Parser::AddAsyncClosureVariables() { |
| 6096 // Add to AST: | 6105 // Add to AST: |
| 6097 // var :await_jump_var; | 6106 // var :await_jump_var; |
| 6098 // var :await_ctx_var; | 6107 // var :await_ctx_var; |
| 6099 // var :async_op; | 6108 // var :async_op; |
| 6100 // var :async_completer; | 6109 // var :async_completer; |
| 6101 const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType()); | 6110 const Type& dynamic_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 6102 LocalVariable* await_jump_var = new (I) LocalVariable( | 6111 LocalVariable* await_jump_var = new (Z) LocalVariable( |
| 6103 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type); | 6112 Scanner::kNoSourcePos, Symbols::AwaitJumpVar(), dynamic_type); |
| 6104 current_block_->scope->AddVariable(await_jump_var); | 6113 current_block_->scope->AddVariable(await_jump_var); |
| 6105 current_block_->scope->CaptureVariable(Symbols::AwaitJumpVar()); | 6114 current_block_->scope->CaptureVariable(Symbols::AwaitJumpVar()); |
| 6106 await_jump_var->set_is_captured(); | 6115 await_jump_var->set_is_captured(); |
| 6107 LocalVariable* await_ctx_var = new (I) LocalVariable( | 6116 LocalVariable* await_ctx_var = new (Z) LocalVariable( |
| 6108 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type); | 6117 Scanner::kNoSourcePos, Symbols::AwaitContextVar(), dynamic_type); |
| 6109 current_block_->scope->AddVariable(await_ctx_var); | 6118 current_block_->scope->AddVariable(await_ctx_var); |
| 6110 current_block_->scope->CaptureVariable(Symbols::AwaitContextVar()); | 6119 current_block_->scope->CaptureVariable(Symbols::AwaitContextVar()); |
| 6111 await_ctx_var->set_is_captured(); | 6120 await_ctx_var->set_is_captured(); |
| 6112 LocalVariable* async_op_var = new (I) LocalVariable( | 6121 LocalVariable* async_op_var = new (Z) LocalVariable( |
| 6113 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type); | 6122 Scanner::kNoSourcePos, Symbols::AsyncOperation(), dynamic_type); |
| 6114 current_block_->scope->AddVariable(async_op_var); | 6123 current_block_->scope->AddVariable(async_op_var); |
| 6115 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); | 6124 current_block_->scope->CaptureVariable(Symbols::AsyncOperation()); |
| 6116 async_op_var->set_is_captured(); | 6125 async_op_var->set_is_captured(); |
| 6117 LocalVariable* async_completer = new (I) LocalVariable( | 6126 LocalVariable* async_completer = new (Z) LocalVariable( |
| 6118 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); | 6127 Scanner::kNoSourcePos, Symbols::AsyncCompleter(), dynamic_type); |
| 6119 current_block_->scope->AddVariable(async_completer); | 6128 current_block_->scope->AddVariable(async_completer); |
| 6120 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); | 6129 current_block_->scope->CaptureVariable(Symbols::AsyncCompleter()); |
| 6121 async_completer->set_is_captured(); | 6130 async_completer->set_is_captured(); |
| 6122 } | 6131 } |
| 6123 | 6132 |
| 6124 | 6133 |
| 6125 SequenceNode* Parser::CloseBlock() { | 6134 SequenceNode* Parser::CloseBlock() { |
| 6126 SequenceNode* statements = current_block_->statements; | 6135 SequenceNode* statements = current_block_->statements; |
| 6127 if (current_block_->scope != NULL) { | 6136 if (current_block_->scope != NULL) { |
| 6128 // Record the begin and end token index of the scope. | 6137 // Record the begin and end token index of the scope. |
| 6129 ASSERT(statements != NULL); | 6138 ASSERT(statements != NULL); |
| 6130 current_block_->scope->set_begin_token_pos(statements->token_pos()); | 6139 current_block_->scope->set_begin_token_pos(statements->token_pos()); |
| 6131 current_block_->scope->set_end_token_pos(TokenPos()); | 6140 current_block_->scope->set_end_token_pos(TokenPos()); |
| 6132 } | 6141 } |
| 6133 current_block_ = current_block_->parent; | 6142 current_block_ = current_block_->parent; |
| 6134 return statements; | 6143 return statements; |
| 6135 } | 6144 } |
| 6136 | 6145 |
| 6137 | 6146 |
| 6138 static inline String& BuildAsyncSavedTryContextName(Isolate* isolate, | 6147 static inline String& BuildAsyncSavedTryContextName(Zone* zone, |
| 6139 int16_t id) { | 6148 int16_t id) { |
| 6140 const char* async_saved_prefix = ":async_saved_try_ctx_var_"; | 6149 const char* async_saved_prefix = ":async_saved_try_ctx_var_"; |
| 6141 // Can be a regular handle since we only use it to build an actual symbol. | 6150 // Can be a regular handle since we only use it to build an actual symbol. |
| 6142 const String& cnt_str = String::Handle( | 6151 const String& cnt_str = String::Handle(zone, |
| 6143 String::NewFormatted("%s%d", async_saved_prefix, id)); | 6152 String::NewFormatted("%s%d", async_saved_prefix, id)); |
| 6144 return String::ZoneHandle(isolate, Symbols::New(cnt_str)); | 6153 return String::ZoneHandle(zone, Symbols::New(cnt_str)); |
| 6145 } | 6154 } |
| 6146 | 6155 |
| 6147 | 6156 |
| 6148 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, | 6157 SequenceNode* Parser::CloseAsyncFunction(const Function& closure, |
| 6149 SequenceNode* closure_body) { | 6158 SequenceNode* closure_body) { |
| 6150 TRACE_PARSER("CloseAsyncFunction"); | 6159 TRACE_PARSER("CloseAsyncFunction"); |
| 6151 ASSERT(!closure.IsNull()); | 6160 ASSERT(!closure.IsNull()); |
| 6152 ASSERT(closure_body != NULL); | 6161 ASSERT(closure_body != NULL); |
| 6153 // The block for the async closure body has already been closed. Close the | 6162 // The block for the async closure body has already been closed. Close the |
| 6154 // corresponding function block. | 6163 // corresponding function block. |
| 6155 CloseBlock(); | 6164 CloseBlock(); |
| 6156 | 6165 |
| 6157 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); | 6166 closure_body->scope()->LookupVariable(Symbols::AwaitJumpVar(), false); |
| 6158 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); | 6167 closure_body->scope()->LookupVariable(Symbols::AwaitContextVar(), false); |
| 6159 closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter()); | 6168 closure_body->scope()->CaptureVariable(Symbols::AsyncCompleter()); |
| 6160 | 6169 |
| 6161 // Create and return a new future that executes a closure with the current | 6170 // Create and return a new future that executes a closure with the current |
| 6162 // body. | 6171 // body. |
| 6163 | 6172 |
| 6164 // No need to capture parameters or other variables, since they have already | 6173 // No need to capture parameters or other variables, since they have already |
| 6165 // been captured in the corresponding scope as the body has been parsed within | 6174 // been captured in the corresponding scope as the body has been parsed within |
| 6166 // a nested block (contained in the async funtion's block). | 6175 // a nested block (contained in the async funtion's block). |
| 6167 const Class& future = | 6176 const Class& future = |
| 6168 Class::ZoneHandle(I, I->object_store()->future_class()); | 6177 Class::ZoneHandle(Z, I->object_store()->future_class()); |
| 6169 ASSERT(!future.IsNull()); | 6178 ASSERT(!future.IsNull()); |
| 6170 const Function& constructor = Function::ZoneHandle(I, | 6179 const Function& constructor = Function::ZoneHandle(Z, |
| 6171 future.LookupFunction(Symbols::FutureMicrotask())); | 6180 future.LookupFunction(Symbols::FutureMicrotask())); |
| 6172 ASSERT(!constructor.IsNull()); | 6181 ASSERT(!constructor.IsNull()); |
| 6173 const Class& completer = | 6182 const Class& completer = |
| 6174 Class::ZoneHandle(I, I->object_store()->completer_class()); | 6183 Class::ZoneHandle(Z, I->object_store()->completer_class()); |
| 6175 ASSERT(!completer.IsNull()); | 6184 ASSERT(!completer.IsNull()); |
| 6176 const Function& completer_constructor = Function::ZoneHandle(I, | 6185 const Function& completer_constructor = Function::ZoneHandle(Z, |
| 6177 completer.LookupFunction(Symbols::CompleterConstructor())); | 6186 completer.LookupFunction(Symbols::CompleterConstructor())); |
| 6178 ASSERT(!completer_constructor.IsNull()); | 6187 ASSERT(!completer_constructor.IsNull()); |
| 6179 | 6188 |
| 6180 LocalVariable* async_completer = current_block_->scope->LookupVariable( | 6189 LocalVariable* async_completer = current_block_->scope->LookupVariable( |
| 6181 Symbols::AsyncCompleter(), false); | 6190 Symbols::AsyncCompleter(), false); |
| 6182 | 6191 |
| 6183 // Add to AST: | 6192 // Add to AST: |
| 6184 // :async_completer = new Completer(); | 6193 // :async_completer = new Completer(); |
| 6185 ArgumentListNode* empty_args = | 6194 ArgumentListNode* empty_args = |
| 6186 new (I) ArgumentListNode(Scanner::kNoSourcePos); | 6195 new (Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 6187 ConstructorCallNode* completer_constructor_node = new (I) ConstructorCallNode( | 6196 ConstructorCallNode* completer_constructor_node = new (Z) ConstructorCallNode( |
| 6188 Scanner::kNoSourcePos, | 6197 Scanner::kNoSourcePos, |
| 6189 TypeArguments::ZoneHandle(I), | 6198 TypeArguments::ZoneHandle(Z), |
| 6190 completer_constructor, | 6199 completer_constructor, |
| 6191 empty_args); | 6200 empty_args); |
| 6192 StoreLocalNode* store_completer = new (I) StoreLocalNode( | 6201 StoreLocalNode* store_completer = new (Z) StoreLocalNode( |
| 6193 Scanner::kNoSourcePos, | 6202 Scanner::kNoSourcePos, |
| 6194 async_completer, | 6203 async_completer, |
| 6195 completer_constructor_node); | 6204 completer_constructor_node); |
| 6196 current_block_->statements->Add(store_completer); | 6205 current_block_->statements->Add(store_completer); |
| 6197 | 6206 |
| 6198 // :await_jump_var = -1; | 6207 // :await_jump_var = -1; |
| 6199 LocalVariable* jump_var = current_block_->scope->LookupVariable( | 6208 LocalVariable* jump_var = current_block_->scope->LookupVariable( |
| 6200 Symbols::AwaitJumpVar(), false); | 6209 Symbols::AwaitJumpVar(), false); |
| 6201 LiteralNode* init_value = | 6210 LiteralNode* init_value = |
| 6202 new(I) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); | 6211 new(Z) LiteralNode(Scanner::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1))); |
| 6203 current_block_->statements->Add( | 6212 current_block_->statements->Add( |
| 6204 new (I) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); | 6213 new (Z) StoreLocalNode(Scanner::kNoSourcePos, jump_var, init_value)); |
| 6205 | 6214 |
| 6206 // Add to AST: | 6215 // Add to AST: |
| 6207 // :async_op = <closure>; (containing the original body) | 6216 // :async_op = <closure>; (containing the original body) |
| 6208 LocalVariable* async_op_var = current_block_->scope->LookupVariable( | 6217 LocalVariable* async_op_var = current_block_->scope->LookupVariable( |
| 6209 Symbols::AsyncOperation(), false); | 6218 Symbols::AsyncOperation(), false); |
| 6210 ClosureNode* cn = new(I) ClosureNode( | 6219 ClosureNode* cn = new(Z) ClosureNode( |
| 6211 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); | 6220 Scanner::kNoSourcePos, closure, NULL, closure_body->scope()); |
| 6212 StoreLocalNode* store_async_op = new (I) StoreLocalNode( | 6221 StoreLocalNode* store_async_op = new (Z) StoreLocalNode( |
| 6213 Scanner::kNoSourcePos, | 6222 Scanner::kNoSourcePos, |
| 6214 async_op_var, | 6223 async_op_var, |
| 6215 cn); | 6224 cn); |
| 6216 current_block_->statements->Add(store_async_op); | 6225 current_block_->statements->Add(store_async_op); |
| 6217 | 6226 |
| 6218 // Add to AST: | 6227 // Add to AST: |
| 6219 // new Future(:async_op); | 6228 // new Future(:async_op); |
| 6220 ArgumentListNode* arguments = new (I) ArgumentListNode(Scanner::kNoSourcePos); | 6229 ArgumentListNode* arguments = new (Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 6221 arguments->Add(new (I) LoadLocalNode( | 6230 arguments->Add(new (Z) LoadLocalNode( |
| 6222 Scanner::kNoSourcePos, async_op_var)); | 6231 Scanner::kNoSourcePos, async_op_var)); |
| 6223 ConstructorCallNode* future_node = new (I) ConstructorCallNode( | 6232 ConstructorCallNode* future_node = new (Z) ConstructorCallNode( |
| 6224 Scanner::kNoSourcePos, TypeArguments::ZoneHandle(I), constructor, | 6233 Scanner::kNoSourcePos, TypeArguments::ZoneHandle(Z), constructor, |
| 6225 arguments); | 6234 arguments); |
| 6226 current_block_->statements->Add(future_node); | 6235 current_block_->statements->Add(future_node); |
| 6227 | 6236 |
| 6228 // Add to AST: | 6237 // Add to AST: |
| 6229 // return :async_completer.future; | 6238 // return :async_completer.future; |
| 6230 ReturnNode* return_node = new (I) ReturnNode( | 6239 ReturnNode* return_node = new (Z) ReturnNode( |
| 6231 Scanner::kNoSourcePos, | 6240 Scanner::kNoSourcePos, |
| 6232 new (I) InstanceGetterNode( | 6241 new (Z) InstanceGetterNode( |
| 6233 Scanner::kNoSourcePos, | 6242 Scanner::kNoSourcePos, |
| 6234 new (I) LoadLocalNode( | 6243 new (Z) LoadLocalNode( |
| 6235 Scanner::kNoSourcePos, | 6244 Scanner::kNoSourcePos, |
| 6236 async_completer), | 6245 async_completer), |
| 6237 Symbols::CompleterFuture())); | 6246 Symbols::CompleterFuture())); |
| 6238 current_block_->statements->Add(return_node); | 6247 current_block_->statements->Add(return_node); |
| 6239 return CloseBlock(); | 6248 return CloseBlock(); |
| 6240 } | 6249 } |
| 6241 | 6250 |
| 6242 | 6251 |
| 6243 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { | 6252 SequenceNode* Parser::CloseAsyncClosure(SequenceNode* body) { |
| 6244 TRACE_PARSER("CloseAsyncClosure"); | 6253 TRACE_PARSER("CloseAsyncClosure"); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6310 // Populate local scope with the formal parameters. | 6319 // Populate local scope with the formal parameters. |
| 6311 void Parser::AddFormalParamsToScope(const ParamList* params, | 6320 void Parser::AddFormalParamsToScope(const ParamList* params, |
| 6312 LocalScope* scope) { | 6321 LocalScope* scope) { |
| 6313 ASSERT((params != NULL) && (params->parameters != NULL)); | 6322 ASSERT((params != NULL) && (params->parameters != NULL)); |
| 6314 ASSERT(scope != NULL); | 6323 ASSERT(scope != NULL); |
| 6315 const int num_parameters = params->parameters->length(); | 6324 const int num_parameters = params->parameters->length(); |
| 6316 for (int i = 0; i < num_parameters; i++) { | 6325 for (int i = 0; i < num_parameters; i++) { |
| 6317 ParamDesc& param_desc = (*params->parameters)[i]; | 6326 ParamDesc& param_desc = (*params->parameters)[i]; |
| 6318 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); | 6327 ASSERT(!is_top_level_ || param_desc.type->IsResolved()); |
| 6319 const String* name = param_desc.name; | 6328 const String* name = param_desc.name; |
| 6320 LocalVariable* parameter = new(I) LocalVariable( | 6329 LocalVariable* parameter = new(Z) LocalVariable( |
| 6321 param_desc.name_pos, *name, *param_desc.type); | 6330 param_desc.name_pos, *name, *param_desc.type); |
| 6322 if (!scope->InsertParameterAt(i, parameter)) { | 6331 if (!scope->InsertParameterAt(i, parameter)) { |
| 6323 ReportError(param_desc.name_pos, | 6332 ReportError(param_desc.name_pos, |
| 6324 "name '%s' already exists in scope", | 6333 "name '%s' already exists in scope", |
| 6325 param_desc.name->ToCString()); | 6334 param_desc.name->ToCString()); |
| 6326 } | 6335 } |
| 6327 param_desc.var = parameter; | 6336 param_desc.var = parameter; |
| 6328 if (param_desc.is_final) { | 6337 if (param_desc.is_final) { |
| 6329 parameter->set_is_final(); | 6338 parameter->set_is_final(); |
| 6330 } | 6339 } |
| 6331 if (param_desc.is_field_initializer) { | 6340 if (param_desc.is_field_initializer) { |
| 6332 parameter->set_invisible(true); | 6341 parameter->set_invisible(true); |
| 6333 } | 6342 } |
| 6334 } | 6343 } |
| 6335 } | 6344 } |
| 6336 | 6345 |
| 6337 | 6346 |
| 6338 // Builds ReturnNode/NativeBodyNode for a native function. | 6347 // Builds ReturnNode/NativeBodyNode for a native function. |
| 6339 void Parser::ParseNativeFunctionBlock(const ParamList* params, | 6348 void Parser::ParseNativeFunctionBlock(const ParamList* params, |
| 6340 const Function& func) { | 6349 const Function& func) { |
| 6341 ASSERT(func.is_native()); | 6350 ASSERT(func.is_native()); |
| 6342 TRACE_PARSER("ParseNativeFunctionBlock"); | 6351 TRACE_PARSER("ParseNativeFunctionBlock"); |
| 6343 const Class& cls = Class::Handle(I, func.Owner()); | 6352 const Class& cls = Class::Handle(Z, func.Owner()); |
| 6344 const Library& library = Library::Handle(I, cls.library()); | 6353 const Library& library = Library::Handle(Z, cls.library()); |
| 6345 ASSERT(func.NumParameters() == params->parameters->length()); | 6354 ASSERT(func.NumParameters() == params->parameters->length()); |
| 6346 | 6355 |
| 6347 // Parse the function name out. | 6356 // Parse the function name out. |
| 6348 const intptr_t native_pos = TokenPos(); | 6357 const intptr_t native_pos = TokenPos(); |
| 6349 const String& native_name = ParseNativeDeclaration(); | 6358 const String& native_name = ParseNativeDeclaration(); |
| 6350 | 6359 |
| 6351 // Now resolve the native function to the corresponding native entrypoint. | 6360 // Now resolve the native function to the corresponding native entrypoint. |
| 6352 const int num_params = NativeArguments::ParameterCountForResolution(func); | 6361 const int num_params = NativeArguments::ParameterCountForResolution(func); |
| 6353 bool auto_setup_scope = true; | 6362 bool auto_setup_scope = true; |
| 6354 NativeFunction native_function = NativeEntry::ResolveNative( | 6363 NativeFunction native_function = NativeEntry::ResolveNative( |
| 6355 library, native_name, num_params, &auto_setup_scope); | 6364 library, native_name, num_params, &auto_setup_scope); |
| 6356 if (native_function == NULL) { | 6365 if (native_function == NULL) { |
| 6357 ReportError(native_pos, | 6366 ReportError(native_pos, |
| 6358 "native function '%s' (%" Pd " arguments) cannot be found", | 6367 "native function '%s' (%" Pd " arguments) cannot be found", |
| 6359 native_name.ToCString(), func.NumParameters()); | 6368 native_name.ToCString(), func.NumParameters()); |
| 6360 } | 6369 } |
| 6361 func.SetIsNativeAutoSetupScope(auto_setup_scope); | 6370 func.SetIsNativeAutoSetupScope(auto_setup_scope); |
| 6362 | 6371 |
| 6363 // Now add the NativeBodyNode and return statement. | 6372 // Now add the NativeBodyNode and return statement. |
| 6364 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); | 6373 Dart_NativeEntryResolver resolver = library.native_entry_resolver(); |
| 6365 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); | 6374 bool is_bootstrap_native = Bootstrap::IsBootstapResolver(resolver); |
| 6366 current_block_->statements->Add(new(I) ReturnNode( | 6375 current_block_->statements->Add(new(Z) ReturnNode( |
| 6367 TokenPos(), | 6376 TokenPos(), |
| 6368 new(I) NativeBodyNode( | 6377 new(Z) NativeBodyNode( |
| 6369 TokenPos(), | 6378 TokenPos(), |
| 6370 Function::ZoneHandle(I, func.raw()), | 6379 Function::ZoneHandle(Z, func.raw()), |
| 6371 native_name, | 6380 native_name, |
| 6372 native_function, | 6381 native_function, |
| 6373 current_block_->scope, | 6382 current_block_->scope, |
| 6374 is_bootstrap_native))); | 6383 is_bootstrap_native))); |
| 6375 } | 6384 } |
| 6376 | 6385 |
| 6377 | 6386 |
| 6378 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { | 6387 LocalVariable* Parser::LookupReceiver(LocalScope* from_scope, bool test_only) { |
| 6379 ASSERT(!current_function().is_static()); | 6388 ASSERT(!current_function().is_static()); |
| 6380 return from_scope->LookupVariable(Symbols::This(), test_only); | 6389 return from_scope->LookupVariable(Symbols::This(), test_only); |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 6410 | 6419 |
| 6411 | 6420 |
| 6412 AstNode* Parser::LoadReceiver(intptr_t token_pos) { | 6421 AstNode* Parser::LoadReceiver(intptr_t token_pos) { |
| 6413 // A nested function may access 'this', referring to the receiver of the | 6422 // A nested function may access 'this', referring to the receiver of the |
| 6414 // outermost enclosing function. | 6423 // outermost enclosing function. |
| 6415 const bool kTestOnly = false; | 6424 const bool kTestOnly = false; |
| 6416 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); | 6425 LocalVariable* receiver = LookupReceiver(current_block_->scope, kTestOnly); |
| 6417 if (receiver == NULL) { | 6426 if (receiver == NULL) { |
| 6418 ReportError(token_pos, "illegal implicit access to receiver 'this'"); | 6427 ReportError(token_pos, "illegal implicit access to receiver 'this'"); |
| 6419 } | 6428 } |
| 6420 return new(I) LoadLocalNode(TokenPos(), receiver); | 6429 return new(Z) LoadLocalNode(TokenPos(), receiver); |
| 6421 } | 6430 } |
| 6422 | 6431 |
| 6423 | 6432 |
| 6424 AstNode* Parser::CallGetter(intptr_t token_pos, | 6433 AstNode* Parser::CallGetter(intptr_t token_pos, |
| 6425 AstNode* object, | 6434 AstNode* object, |
| 6426 const String& name) { | 6435 const String& name) { |
| 6427 return new(I) InstanceGetterNode(token_pos, object, name); | 6436 return new(Z) InstanceGetterNode(token_pos, object, name); |
| 6428 } | 6437 } |
| 6429 | 6438 |
| 6430 | 6439 |
| 6431 // Returns ast nodes of the variable initialization. | 6440 // Returns ast nodes of the variable initialization. |
| 6432 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, | 6441 AstNode* Parser::ParseVariableDeclaration(const AbstractType& type, |
| 6433 bool is_final, | 6442 bool is_final, |
| 6434 bool is_const, | 6443 bool is_const, |
| 6435 SequenceNode** await_preamble) { | 6444 SequenceNode** await_preamble) { |
| 6436 TRACE_PARSER("ParseVariableDeclaration"); | 6445 TRACE_PARSER("ParseVariableDeclaration"); |
| 6437 ASSERT(IsIdentifier()); | 6446 ASSERT(IsIdentifier()); |
| 6438 const intptr_t ident_pos = TokenPos(); | 6447 const intptr_t ident_pos = TokenPos(); |
| 6439 const String& ident = *CurrentLiteral(); | 6448 const String& ident = *CurrentLiteral(); |
| 6440 LocalVariable* variable = new(I) LocalVariable( | 6449 LocalVariable* variable = new(Z) LocalVariable( |
| 6441 ident_pos, ident, type); | 6450 ident_pos, ident, type); |
| 6442 ConsumeToken(); // Variable identifier. | 6451 ConsumeToken(); // Variable identifier. |
| 6443 AstNode* initialization = NULL; | 6452 AstNode* initialization = NULL; |
| 6444 if (CurrentToken() == Token::kASSIGN) { | 6453 if (CurrentToken() == Token::kASSIGN) { |
| 6445 // Variable initialization. | 6454 // Variable initialization. |
| 6446 const intptr_t assign_pos = TokenPos(); | 6455 const intptr_t assign_pos = TokenPos(); |
| 6447 ConsumeToken(); | 6456 ConsumeToken(); |
| 6448 AstNode* expr = ParseAwaitableExpr( | 6457 AstNode* expr = ParseAwaitableExpr( |
| 6449 is_const, kConsumeCascades, await_preamble); | 6458 is_const, kConsumeCascades, await_preamble); |
| 6450 initialization = new(I) StoreLocalNode( | 6459 initialization = new(Z) StoreLocalNode( |
| 6451 assign_pos, variable, expr); | 6460 assign_pos, variable, expr); |
| 6452 if (is_const) { | 6461 if (is_const) { |
| 6453 ASSERT(expr->IsLiteralNode()); | 6462 ASSERT(expr->IsLiteralNode()); |
| 6454 variable->SetConstValue(expr->AsLiteralNode()->literal()); | 6463 variable->SetConstValue(expr->AsLiteralNode()->literal()); |
| 6455 } | 6464 } |
| 6456 } else if (is_final || is_const) { | 6465 } else if (is_final || is_const) { |
| 6457 ReportError(ident_pos, | 6466 ReportError(ident_pos, |
| 6458 "missing initialization of 'final' or 'const' variable"); | 6467 "missing initialization of 'final' or 'const' variable"); |
| 6459 } else { | 6468 } else { |
| 6460 // Initialize variable with null. | 6469 // Initialize variable with null. |
| 6461 AstNode* null_expr = new(I) LiteralNode( | 6470 AstNode* null_expr = new(Z) LiteralNode( |
| 6462 ident_pos, Instance::ZoneHandle(I)); | 6471 ident_pos, Instance::ZoneHandle(Z)); |
| 6463 initialization = new(I) StoreLocalNode( | 6472 initialization = new(Z) StoreLocalNode( |
| 6464 ident_pos, variable, null_expr); | 6473 ident_pos, variable, null_expr); |
| 6465 } | 6474 } |
| 6466 | 6475 |
| 6467 ASSERT(current_block_ != NULL); | 6476 ASSERT(current_block_ != NULL); |
| 6468 const intptr_t previous_pos = | 6477 const intptr_t previous_pos = |
| 6469 current_block_->scope->PreviousReferencePos(ident); | 6478 current_block_->scope->PreviousReferencePos(ident); |
| 6470 if (previous_pos >= 0) { | 6479 if (previous_pos >= 0) { |
| 6471 ASSERT(!script_.IsNull()); | 6480 ASSERT(!script_.IsNull()); |
| 6472 if (previous_pos > ident_pos) { | 6481 if (previous_pos > ident_pos) { |
| 6473 ReportError(ident_pos, | 6482 ReportError(ident_pos, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6545 | 6554 |
| 6546 | 6555 |
| 6547 // Returns ast nodes of the variable initialization. Variables without an | 6556 // Returns ast nodes of the variable initialization. Variables without an |
| 6548 // explicit initializer are initialized to null. If several variables are | 6557 // explicit initializer are initialized to null. If several variables are |
| 6549 // declared, the individual initializers are collected in a sequence node. | 6558 // declared, the individual initializers are collected in a sequence node. |
| 6550 AstNode* Parser::ParseVariableDeclarationList() { | 6559 AstNode* Parser::ParseVariableDeclarationList() { |
| 6551 TRACE_PARSER("ParseVariableDeclarationList"); | 6560 TRACE_PARSER("ParseVariableDeclarationList"); |
| 6552 SkipMetadata(); | 6561 SkipMetadata(); |
| 6553 bool is_final = (CurrentToken() == Token::kFINAL); | 6562 bool is_final = (CurrentToken() == Token::kFINAL); |
| 6554 bool is_const = (CurrentToken() == Token::kCONST); | 6563 bool is_const = (CurrentToken() == Token::kCONST); |
| 6555 const AbstractType& type = AbstractType::ZoneHandle(I, | 6564 const AbstractType& type = AbstractType::ZoneHandle(Z, |
| 6556 ParseConstFinalVarOrType(FLAG_enable_type_checks ? | 6565 ParseConstFinalVarOrType(FLAG_enable_type_checks ? |
| 6557 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); | 6566 ClassFinalizer::kCanonicalize : ClassFinalizer::kIgnore)); |
| 6558 if (!IsIdentifier()) { | 6567 if (!IsIdentifier()) { |
| 6559 ReportError("identifier expected"); | 6568 ReportError("identifier expected"); |
| 6560 } | 6569 } |
| 6561 | 6570 |
| 6562 SequenceNode* preamble = NULL; | 6571 SequenceNode* preamble = NULL; |
| 6563 AstNode* initializers = | 6572 AstNode* initializers = |
| 6564 ParseVariableDeclaration(type, is_final, is_const, &preamble); | 6573 ParseVariableDeclaration(type, is_final, is_const, &preamble); |
| 6565 ASSERT(initializers != NULL); | 6574 ASSERT(initializers != NULL); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 6585 } | 6594 } |
| 6586 sequence->Add(declaration); | 6595 sequence->Add(declaration); |
| 6587 initializers = sequence; | 6596 initializers = sequence; |
| 6588 } | 6597 } |
| 6589 return initializers; | 6598 return initializers; |
| 6590 } | 6599 } |
| 6591 | 6600 |
| 6592 | 6601 |
| 6593 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 6602 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
| 6594 TRACE_PARSER("ParseFunctionStatement"); | 6603 TRACE_PARSER("ParseFunctionStatement"); |
| 6595 AbstractType& result_type = AbstractType::Handle(I); | 6604 AbstractType& result_type = AbstractType::Handle(Z); |
| 6596 const String* variable_name = NULL; | 6605 const String* variable_name = NULL; |
| 6597 const String* function_name = NULL; | 6606 const String* function_name = NULL; |
| 6598 | 6607 |
| 6599 result_type = Type::DynamicType(); | 6608 result_type = Type::DynamicType(); |
| 6600 | 6609 |
| 6601 const intptr_t function_pos = TokenPos(); | 6610 const intptr_t function_pos = TokenPos(); |
| 6602 if (is_literal) { | 6611 if (is_literal) { |
| 6603 ASSERT(CurrentToken() == Token::kLPAREN); | 6612 ASSERT(CurrentToken() == Token::kLPAREN); |
| 6604 function_name = &Symbols::AnonymousClosure(); | 6613 function_name = &Symbols::AnonymousClosure(); |
| 6605 } else { | 6614 } else { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 6629 line_number); | 6638 line_number); |
| 6630 } | 6639 } |
| 6631 } | 6640 } |
| 6632 CheckToken(Token::kLPAREN); | 6641 CheckToken(Token::kLPAREN); |
| 6633 | 6642 |
| 6634 // Check whether we have parsed this closure function before, in a previous | 6643 // Check whether we have parsed this closure function before, in a previous |
| 6635 // compilation. If so, reuse the function object, else create a new one | 6644 // compilation. If so, reuse the function object, else create a new one |
| 6636 // and register it in the current class. | 6645 // and register it in the current class. |
| 6637 // Note that we cannot share the same closure function between the closurized | 6646 // Note that we cannot share the same closure function between the closurized |
| 6638 // and non-closurized versions of the same parent function. | 6647 // and non-closurized versions of the same parent function. |
| 6639 Function& function = Function::ZoneHandle(I); | 6648 Function& function = Function::ZoneHandle(Z); |
| 6640 bool is_new_closure = false; | 6649 bool is_new_closure = false; |
| 6641 // TODO(hausner): There could be two different closures at the given | 6650 // TODO(hausner): There could be two different closures at the given |
| 6642 // function_pos, one enclosed in a closurized function and one enclosed in the | 6651 // function_pos, one enclosed in a closurized function and one enclosed in the |
| 6643 // non-closurized version of this same function. | 6652 // non-closurized version of this same function. |
| 6644 function = current_class().LookupClosureFunction(function_pos); | 6653 function = current_class().LookupClosureFunction(function_pos); |
| 6645 if (function.IsNull() || (function.token_pos() != function_pos) || | 6654 if (function.IsNull() || (function.token_pos() != function_pos) || |
| 6646 (function.parent_function() != innermost_function().raw())) { | 6655 (function.parent_function() != innermost_function().raw())) { |
| 6647 // The function will be registered in the lookup table by the | 6656 // The function will be registered in the lookup table by the |
| 6648 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure | 6657 // EffectGraphVisitor::VisitClosureNode when the newly allocated closure |
| 6649 // function has been properly setup. | 6658 // function has been properly setup. |
| 6650 is_new_closure = true; | 6659 is_new_closure = true; |
| 6651 function = Function::NewClosureFunction(*function_name, | 6660 function = Function::NewClosureFunction(*function_name, |
| 6652 innermost_function(), | 6661 innermost_function(), |
| 6653 function_pos); | 6662 function_pos); |
| 6654 function.set_result_type(result_type); | 6663 function.set_result_type(result_type); |
| 6655 } | 6664 } |
| 6656 | 6665 |
| 6657 // The function type needs to be finalized at compile time, since the closure | 6666 // The function type needs to be finalized at compile time, since the closure |
| 6658 // may be type checked at run time when assigned to a function variable, | 6667 // may be type checked at run time when assigned to a function variable, |
| 6659 // passed as a function argument, or returned as a function result. | 6668 // passed as a function argument, or returned as a function result. |
| 6660 | 6669 |
| 6661 LocalVariable* function_variable = NULL; | 6670 LocalVariable* function_variable = NULL; |
| 6662 Type& function_type = Type::ZoneHandle(I); | 6671 Type& function_type = Type::ZoneHandle(Z); |
| 6663 if (variable_name != NULL) { | 6672 if (variable_name != NULL) { |
| 6664 // Since the function type depends on the signature of the closure function, | 6673 // Since the function type depends on the signature of the closure function, |
| 6665 // it cannot be determined before the formal parameter list of the closure | 6674 // it cannot be determined before the formal parameter list of the closure |
| 6666 // function is parsed. Therefore, we set the function type to a new | 6675 // function is parsed. Therefore, we set the function type to a new |
| 6667 // parameterized type to be patched after the actual type is known. | 6676 // parameterized type to be patched after the actual type is known. |
| 6668 // We temporarily use the class of the Function interface. | 6677 // We temporarily use the class of the Function interface. |
| 6669 const Class& unknown_signature_class = Class::Handle(I, | 6678 const Class& unknown_signature_class = Class::Handle(Z, |
| 6670 Type::Handle(I, Type::Function()).type_class()); | 6679 Type::Handle(Z, Type::Function()).type_class()); |
| 6671 function_type = Type::New(unknown_signature_class, | 6680 function_type = Type::New(unknown_signature_class, |
| 6672 TypeArguments::Handle(I), function_pos); | 6681 TypeArguments::Handle(Z), function_pos); |
| 6673 function_type.SetIsFinalized(); // No finalization needed. | 6682 function_type.SetIsFinalized(); // No finalization needed. |
| 6674 | 6683 |
| 6675 // Add the function variable to the scope before parsing the function in | 6684 // Add the function variable to the scope before parsing the function in |
| 6676 // order to allow self reference from inside the function. | 6685 // order to allow self reference from inside the function. |
| 6677 function_variable = new(I) LocalVariable(function_pos, | 6686 function_variable = new(Z) LocalVariable(function_pos, |
| 6678 *variable_name, | 6687 *variable_name, |
| 6679 function_type); | 6688 function_type); |
| 6680 function_variable->set_is_final(); | 6689 function_variable->set_is_final(); |
| 6681 ASSERT(current_block_ != NULL); | 6690 ASSERT(current_block_ != NULL); |
| 6682 ASSERT(current_block_->scope != NULL); | 6691 ASSERT(current_block_->scope != NULL); |
| 6683 if (!current_block_->scope->AddVariable(function_variable)) { | 6692 if (!current_block_->scope->AddVariable(function_variable)) { |
| 6684 LocalVariable* existing_var = | 6693 LocalVariable* existing_var = |
| 6685 current_block_->scope->LookupVariable(function_variable->name(), | 6694 current_block_->scope->LookupVariable(function_variable->name(), |
| 6686 true); | 6695 true); |
| 6687 ASSERT(existing_var != NULL); | 6696 ASSERT(existing_var != NULL); |
| 6688 if (existing_var->owner() == current_block_->scope) { | 6697 if (existing_var->owner() == current_block_->scope) { |
| 6689 ReportError(function_pos, "identifier '%s' already defined", | 6698 ReportError(function_pos, "identifier '%s' already defined", |
| 6690 function_variable->name().ToCString()); | 6699 function_variable->name().ToCString()); |
| 6691 } else { | 6700 } else { |
| 6692 ReportError(function_pos, | 6701 ReportError(function_pos, |
| 6693 "'%s' from outer scope has already been used, " | 6702 "'%s' from outer scope has already been used, " |
| 6694 "cannot redefine", | 6703 "cannot redefine", |
| 6695 function_variable->name().ToCString()); | 6704 function_variable->name().ToCString()); |
| 6696 } | 6705 } |
| 6697 } | 6706 } |
| 6698 } | 6707 } |
| 6699 | 6708 |
| 6700 // Parse the local function. | 6709 // Parse the local function. |
| 6701 Array& default_parameter_values = Array::Handle(I); | 6710 Array& default_parameter_values = Array::Handle(Z); |
| 6702 SequenceNode* statements = Parser::ParseFunc(function, | 6711 SequenceNode* statements = Parser::ParseFunc(function, |
| 6703 &default_parameter_values); | 6712 &default_parameter_values); |
| 6704 | 6713 |
| 6705 // Now that the local function has formal parameters, lookup the signature | 6714 // Now that the local function has formal parameters, lookup the signature |
| 6706 // class in the current library (but not in its imports) and only create a new | 6715 // class in the current library (but not in its imports) and only create a new |
| 6707 // canonical signature class if it does not exist yet. | 6716 // canonical signature class if it does not exist yet. |
| 6708 const String& signature = String::Handle(I, function.Signature()); | 6717 const String& signature = String::Handle(Z, function.Signature()); |
| 6709 Class& signature_class = Class::ZoneHandle(I); | 6718 Class& signature_class = Class::ZoneHandle(Z); |
| 6710 if (!is_new_closure) { | 6719 if (!is_new_closure) { |
| 6711 signature_class = function.signature_class(); | 6720 signature_class = function.signature_class(); |
| 6712 } | 6721 } |
| 6713 if (signature_class.IsNull()) { | 6722 if (signature_class.IsNull()) { |
| 6714 signature_class = library_.LookupLocalClass(signature); | 6723 signature_class = library_.LookupLocalClass(signature); |
| 6715 } | 6724 } |
| 6716 if (signature_class.IsNull()) { | 6725 if (signature_class.IsNull()) { |
| 6717 // If we don't have a signature class yet, this must be a closure we | 6726 // If we don't have a signature class yet, this must be a closure we |
| 6718 // have not parsed before. | 6727 // have not parsed before. |
| 6719 ASSERT(is_new_closure); | 6728 ASSERT(is_new_closure); |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 6734 ASSERT(current_class().is_finalized()); | 6743 ASSERT(current_class().is_finalized()); |
| 6735 | 6744 |
| 6736 // Make sure that the instantiator is captured. | 6745 // Make sure that the instantiator is captured. |
| 6737 if ((signature_class.NumTypeParameters() > 0) && | 6746 if ((signature_class.NumTypeParameters() > 0) && |
| 6738 (current_block_->scope->function_level() > 0)) { | 6747 (current_block_->scope->function_level() > 0)) { |
| 6739 CaptureInstantiator(); | 6748 CaptureInstantiator(); |
| 6740 } | 6749 } |
| 6741 | 6750 |
| 6742 // Since the signature type is cached by the signature class, it may have | 6751 // Since the signature type is cached by the signature class, it may have |
| 6743 // been finalized already. | 6752 // been finalized already. |
| 6744 Type& signature_type = Type::Handle(I, | 6753 Type& signature_type = Type::Handle(Z, |
| 6745 signature_class.SignatureType()); | 6754 signature_class.SignatureType()); |
| 6746 TypeArguments& signature_type_arguments = TypeArguments::Handle(I, | 6755 TypeArguments& signature_type_arguments = TypeArguments::Handle(Z, |
| 6747 signature_type.arguments()); | 6756 signature_type.arguments()); |
| 6748 | 6757 |
| 6749 if (!signature_type.IsFinalized()) { | 6758 if (!signature_type.IsFinalized()) { |
| 6750 signature_type ^= ClassFinalizer::FinalizeType( | 6759 signature_type ^= ClassFinalizer::FinalizeType( |
| 6751 signature_class, signature_type, ClassFinalizer::kCanonicalize); | 6760 signature_class, signature_type, ClassFinalizer::kCanonicalize); |
| 6752 | 6761 |
| 6753 // The call to ClassFinalizer::FinalizeType may have | 6762 // The call to ClassFinalizer::FinalizeType may have |
| 6754 // extended the vector of type arguments. | 6763 // extended the vector of type arguments. |
| 6755 signature_type_arguments = signature_type.arguments(); | 6764 signature_type_arguments = signature_type.arguments(); |
| 6756 ASSERT(signature_type_arguments.IsNull() || | 6765 ASSERT(signature_type_arguments.IsNull() || |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6792 // captured. The captured variables will be recorded along with their | 6801 // captured. The captured variables will be recorded along with their |
| 6793 // allocation information in a Scope object stored in the function object. | 6802 // allocation information in a Scope object stored in the function object. |
| 6794 // This Scope object is then provided to the compiler when compiling the local | 6803 // This Scope object is then provided to the compiler when compiling the local |
| 6795 // function. It would be too early to record the captured variables here, | 6804 // function. It would be too early to record the captured variables here, |
| 6796 // since further closure functions may capture more variables. | 6805 // since further closure functions may capture more variables. |
| 6797 // This Scope object is constructed after all variables have been allocated. | 6806 // This Scope object is constructed after all variables have been allocated. |
| 6798 // The local scope of the parsed function can be pruned, since contained | 6807 // The local scope of the parsed function can be pruned, since contained |
| 6799 // variables are not relevant for the compilation of the enclosing function. | 6808 // variables are not relevant for the compilation of the enclosing function. |
| 6800 // This pruning is done by omitting to hook the local scope in its parent | 6809 // This pruning is done by omitting to hook the local scope in its parent |
| 6801 // scope in the constructor of LocalScope. | 6810 // scope in the constructor of LocalScope. |
| 6802 AstNode* closure = new(I) ClosureNode( | 6811 AstNode* closure = new(Z) ClosureNode( |
| 6803 function_pos, function, NULL, statements->scope()); | 6812 function_pos, function, NULL, statements->scope()); |
| 6804 | 6813 |
| 6805 if (function_variable == NULL) { | 6814 if (function_variable == NULL) { |
| 6806 ASSERT(is_literal); | 6815 ASSERT(is_literal); |
| 6807 return closure; | 6816 return closure; |
| 6808 } else { | 6817 } else { |
| 6809 AstNode* initialization = new(I) StoreLocalNode( | 6818 AstNode* initialization = new(Z) StoreLocalNode( |
| 6810 function_pos, function_variable, closure); | 6819 function_pos, function_variable, closure); |
| 6811 return initialization; | 6820 return initialization; |
| 6812 } | 6821 } |
| 6813 } | 6822 } |
| 6814 | 6823 |
| 6815 | 6824 |
| 6816 // Returns true if the current and next tokens can be parsed as type | 6825 // Returns true if the current and next tokens can be parsed as type |
| 6817 // parameters. Current token position is not saved and restored. | 6826 // parameters. Current token position is not saved and restored. |
| 6818 bool Parser::TryParseTypeParameters() { | 6827 bool Parser::TryParseTypeParameters() { |
| 6819 if (CurrentToken() == Token::kLT) { | 6828 if (CurrentToken() == Token::kLT) { |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7208 ExpectToken(Token::kLPAREN); | 7217 ExpectToken(Token::kLPAREN); |
| 7209 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 7218 AstNode* cond_expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7210 ExpectToken(Token::kRPAREN); | 7219 ExpectToken(Token::kRPAREN); |
| 7211 const bool parsing_loop_body = false; | 7220 const bool parsing_loop_body = false; |
| 7212 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); | 7221 SequenceNode* true_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 7213 SequenceNode* false_branch = NULL; | 7222 SequenceNode* false_branch = NULL; |
| 7214 if (CurrentToken() == Token::kELSE) { | 7223 if (CurrentToken() == Token::kELSE) { |
| 7215 ConsumeToken(); | 7224 ConsumeToken(); |
| 7216 false_branch = ParseNestedStatement(parsing_loop_body, NULL); | 7225 false_branch = ParseNestedStatement(parsing_loop_body, NULL); |
| 7217 } | 7226 } |
| 7218 AstNode* if_node = new(I) IfNode( | 7227 AstNode* if_node = new(Z) IfNode( |
| 7219 if_pos, cond_expr, true_branch, false_branch); | 7228 if_pos, cond_expr, true_branch, false_branch); |
| 7220 if (label != NULL) { | 7229 if (label != NULL) { |
| 7221 current_block_->statements->Add(if_node); | 7230 current_block_->statements->Add(if_node); |
| 7222 SequenceNode* sequence = CloseBlock(); | 7231 SequenceNode* sequence = CloseBlock(); |
| 7223 sequence->set_label(label); | 7232 sequence->set_label(label); |
| 7224 if_node = sequence; | 7233 if_node = sequence; |
| 7225 } | 7234 } |
| 7226 return if_node; | 7235 return if_node; |
| 7227 } | 7236 } |
| 7228 | 7237 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7280 // Check this only in the first loop iteration since all values | 7289 // Check this only in the first loop iteration since all values |
| 7281 // are of the same type, which we check above. | 7290 // are of the same type, which we check above. |
| 7282 if (ImplementsEqualOperator(val)) { | 7291 if (ImplementsEqualOperator(val)) { |
| 7283 ReportError(val_pos, | 7292 ReportError(val_pos, |
| 7284 "type class of case expression must not " | 7293 "type class of case expression must not " |
| 7285 "implement operator =="); | 7294 "implement operator =="); |
| 7286 } | 7295 } |
| 7287 } | 7296 } |
| 7288 } | 7297 } |
| 7289 if (first_value.IsInteger()) { | 7298 if (first_value.IsInteger()) { |
| 7290 return Type::Handle(I, Type::IntType()).type_class(); | 7299 return Type::Handle(Z, Type::IntType()).type_class(); |
| 7291 } else if (first_value.IsString()) { | 7300 } else if (first_value.IsString()) { |
| 7292 return Type::Handle(I, Type::StringType()).type_class(); | 7301 return Type::Handle(Z, Type::StringType()).type_class(); |
| 7293 } | 7302 } |
| 7294 return first_value.clazz(); | 7303 return first_value.clazz(); |
| 7295 } | 7304 } |
| 7296 | 7305 |
| 7297 | 7306 |
| 7298 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, | 7307 CaseNode* Parser::ParseCaseClause(LocalVariable* switch_expr_value, |
| 7299 GrowableArray<LiteralNode*>* case_expr_values, | 7308 GrowableArray<LiteralNode*>* case_expr_values, |
| 7300 SourceLabel* case_label) { | 7309 SourceLabel* case_label) { |
| 7301 TRACE_PARSER("ParseCaseClause"); | 7310 TRACE_PARSER("ParseCaseClause"); |
| 7302 bool default_seen = false; | 7311 bool default_seen = false; |
| 7303 const intptr_t case_pos = TokenPos(); | 7312 const intptr_t case_pos = TokenPos(); |
| 7304 // The case expressions node sequence does not own the enclosing scope. | 7313 // The case expressions node sequence does not own the enclosing scope. |
| 7305 SequenceNode* case_expressions = new(I) SequenceNode(case_pos, NULL); | 7314 SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL); |
| 7306 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { | 7315 while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) { |
| 7307 if (CurrentToken() == Token::kCASE) { | 7316 if (CurrentToken() == Token::kCASE) { |
| 7308 if (default_seen) { | 7317 if (default_seen) { |
| 7309 ReportError("default clause must be last case"); | 7318 ReportError("default clause must be last case"); |
| 7310 } | 7319 } |
| 7311 ConsumeToken(); // Keyword case. | 7320 ConsumeToken(); // Keyword case. |
| 7312 const intptr_t expr_pos = TokenPos(); | 7321 const intptr_t expr_pos = TokenPos(); |
| 7313 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); | 7322 AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades); |
| 7314 ASSERT(expr->IsLiteralNode()); | 7323 ASSERT(expr->IsLiteralNode()); |
| 7315 case_expr_values->Add(expr->AsLiteralNode()); | 7324 case_expr_values->Add(expr->AsLiteralNode()); |
| 7316 | 7325 |
| 7317 AstNode* switch_expr_load = new(I) LoadLocalNode( | 7326 AstNode* switch_expr_load = new(Z) LoadLocalNode( |
| 7318 case_pos, switch_expr_value); | 7327 case_pos, switch_expr_value); |
| 7319 AstNode* case_comparison = new(I) ComparisonNode( | 7328 AstNode* case_comparison = new(Z) ComparisonNode( |
| 7320 expr_pos, Token::kEQ, expr, switch_expr_load); | 7329 expr_pos, Token::kEQ, expr, switch_expr_load); |
| 7321 case_expressions->Add(case_comparison); | 7330 case_expressions->Add(case_comparison); |
| 7322 } else { | 7331 } else { |
| 7323 if (default_seen) { | 7332 if (default_seen) { |
| 7324 ReportError("only one default clause is allowed"); | 7333 ReportError("only one default clause is allowed"); |
| 7325 } | 7334 } |
| 7326 ConsumeToken(); // Keyword default. | 7335 ConsumeToken(); // Keyword default. |
| 7327 default_seen = true; | 7336 default_seen = true; |
| 7328 // The default case always succeeds. | 7337 // The default case always succeeds. |
| 7329 } | 7338 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 7343 next_token = CurrentToken(); | 7352 next_token = CurrentToken(); |
| 7344 } | 7353 } |
| 7345 if (next_token == Token::kRBRACE) { | 7354 if (next_token == Token::kRBRACE) { |
| 7346 // End of switch statement. | 7355 // End of switch statement. |
| 7347 break; | 7356 break; |
| 7348 } | 7357 } |
| 7349 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { | 7358 if ((next_token == Token::kCASE) || (next_token == Token::kDEFAULT)) { |
| 7350 // End of this case clause. If there is a possible fall-through to | 7359 // End of this case clause. If there is a possible fall-through to |
| 7351 // the next case clause, throw an implicit FallThroughError. | 7360 // the next case clause, throw an implicit FallThroughError. |
| 7352 if (!abrupt_completing_seen) { | 7361 if (!abrupt_completing_seen) { |
| 7353 ArgumentListNode* arguments = new(I) ArgumentListNode(TokenPos()); | 7362 ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos()); |
| 7354 arguments->Add(new(I) LiteralNode( | 7363 arguments->Add(new(Z) LiteralNode( |
| 7355 TokenPos(), Integer::ZoneHandle(I, Integer::New(TokenPos())))); | 7364 TokenPos(), Integer::ZoneHandle(Z, Integer::New(TokenPos())))); |
| 7356 current_block_->statements->Add( | 7365 current_block_->statements->Add( |
| 7357 MakeStaticCall(Symbols::FallThroughError(), | 7366 MakeStaticCall(Symbols::FallThroughError(), |
| 7358 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 7367 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 7359 arguments)); | 7368 arguments)); |
| 7360 } | 7369 } |
| 7361 break; | 7370 break; |
| 7362 } | 7371 } |
| 7363 // The next statement still belongs to this case. | 7372 // The next statement still belongs to this case. |
| 7364 AstNode* statement = ParseStatement(); | 7373 AstNode* statement = ParseStatement(); |
| 7365 if (statement != NULL) { | 7374 if (statement != NULL) { |
| 7366 current_block_->statements->Add(statement); | 7375 current_block_->statements->Add(statement); |
| 7367 abrupt_completing_seen |= IsAbruptCompleting(statement); | 7376 abrupt_completing_seen |= IsAbruptCompleting(statement); |
| 7368 } | 7377 } |
| 7369 } | 7378 } |
| 7370 SequenceNode* statements = CloseBlock(); | 7379 SequenceNode* statements = CloseBlock(); |
| 7371 return new(I) CaseNode(case_pos, case_label, | 7380 return new(Z) CaseNode(case_pos, case_label, |
| 7372 case_expressions, default_seen, switch_expr_value, statements); | 7381 case_expressions, default_seen, switch_expr_value, statements); |
| 7373 } | 7382 } |
| 7374 | 7383 |
| 7375 | 7384 |
| 7376 AstNode* Parser::ParseSwitchStatement(String* label_name) { | 7385 AstNode* Parser::ParseSwitchStatement(String* label_name) { |
| 7377 TRACE_PARSER("ParseSwitchStatement"); | 7386 TRACE_PARSER("ParseSwitchStatement"); |
| 7378 ASSERT(CurrentToken() == Token::kSWITCH); | 7387 ASSERT(CurrentToken() == Token::kSWITCH); |
| 7379 const intptr_t switch_pos = TokenPos(); | 7388 const intptr_t switch_pos = TokenPos(); |
| 7380 SourceLabel* label = | 7389 SourceLabel* label = |
| 7381 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); | 7390 SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch); |
| 7382 ConsumeToken(); | 7391 ConsumeToken(); |
| 7383 ExpectToken(Token::kLPAREN); | 7392 ExpectToken(Token::kLPAREN); |
| 7384 const intptr_t expr_pos = TokenPos(); | 7393 const intptr_t expr_pos = TokenPos(); |
| 7385 AstNode* switch_expr = ParseAwaitableExpr( | 7394 AstNode* switch_expr = ParseAwaitableExpr( |
| 7386 kAllowConst, kConsumeCascades, NULL); | 7395 kAllowConst, kConsumeCascades, NULL); |
| 7387 ExpectToken(Token::kRPAREN); | 7396 ExpectToken(Token::kRPAREN); |
| 7388 ExpectToken(Token::kLBRACE); | 7397 ExpectToken(Token::kLBRACE); |
| 7389 OpenBlock(); | 7398 OpenBlock(); |
| 7390 current_block_->scope->AddLabel(label); | 7399 current_block_->scope->AddLabel(label); |
| 7391 | 7400 |
| 7392 // Store switch expression in temporary local variable. The type of the | 7401 // Store switch expression in temporary local variable. The type of the |
| 7393 // variable is set to dynamic. It will later be patched to match the | 7402 // variable is set to dynamic. It will later be patched to match the |
| 7394 // type of the case clause expressions. Therefore, we have to allocate | 7403 // type of the case clause expressions. Therefore, we have to allocate |
| 7395 // a new type representing dynamic and can't reuse the canonical | 7404 // a new type representing dynamic and can't reuse the canonical |
| 7396 // type object for dynamic. | 7405 // type object for dynamic. |
| 7397 const Type& temp_var_type = Type::ZoneHandle(I, | 7406 const Type& temp_var_type = Type::ZoneHandle(Z, |
| 7398 Type::New(Class::Handle(I, Object::dynamic_class()), | 7407 Type::New(Class::Handle(Z, Object::dynamic_class()), |
| 7399 TypeArguments::Handle(I), | 7408 TypeArguments::Handle(Z), |
| 7400 expr_pos)); | 7409 expr_pos)); |
| 7401 temp_var_type.SetIsFinalized(); | 7410 temp_var_type.SetIsFinalized(); |
| 7402 LocalVariable* temp_variable = new(I) LocalVariable( | 7411 LocalVariable* temp_variable = new(Z) LocalVariable( |
| 7403 expr_pos, Symbols::SwitchExpr(), temp_var_type); | 7412 expr_pos, Symbols::SwitchExpr(), temp_var_type); |
| 7404 current_block_->scope->AddVariable(temp_variable); | 7413 current_block_->scope->AddVariable(temp_variable); |
| 7405 AstNode* save_switch_expr = new(I) StoreLocalNode( | 7414 AstNode* save_switch_expr = new(Z) StoreLocalNode( |
| 7406 expr_pos, temp_variable, switch_expr); | 7415 expr_pos, temp_variable, switch_expr); |
| 7407 current_block_->statements->Add(save_switch_expr); | 7416 current_block_->statements->Add(save_switch_expr); |
| 7408 | 7417 |
| 7409 // Parse case clauses | 7418 // Parse case clauses |
| 7410 bool default_seen = false; | 7419 bool default_seen = false; |
| 7411 GrowableArray<LiteralNode*> case_expr_values; | 7420 GrowableArray<LiteralNode*> case_expr_values; |
| 7412 while (true) { | 7421 while (true) { |
| 7413 // Check for statement label | 7422 // Check for statement label |
| 7414 SourceLabel* case_label = NULL; | 7423 SourceLabel* case_label = NULL; |
| 7415 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { | 7424 if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) { |
| 7416 // Case statements start with a label. | 7425 // Case statements start with a label. |
| 7417 String* label_name = CurrentLiteral(); | 7426 String* label_name = CurrentLiteral(); |
| 7418 const intptr_t label_pos = TokenPos(); | 7427 const intptr_t label_pos = TokenPos(); |
| 7419 ConsumeToken(); // Consume label identifier. | 7428 ConsumeToken(); // Consume label identifier. |
| 7420 ConsumeToken(); // Consume colon. | 7429 ConsumeToken(); // Consume colon. |
| 7421 case_label = current_block_->scope->LocalLookupLabel(*label_name); | 7430 case_label = current_block_->scope->LocalLookupLabel(*label_name); |
| 7422 if (case_label == NULL) { | 7431 if (case_label == NULL) { |
| 7423 // Label does not exist yet. Add it to scope of switch statement. | 7432 // Label does not exist yet. Add it to scope of switch statement. |
| 7424 case_label = new(I) SourceLabel( | 7433 case_label = new(Z) SourceLabel( |
| 7425 label_pos, *label_name, SourceLabel::kCase); | 7434 label_pos, *label_name, SourceLabel::kCase); |
| 7426 current_block_->scope->AddLabel(case_label); | 7435 current_block_->scope->AddLabel(case_label); |
| 7427 } else if (case_label->kind() == SourceLabel::kForward) { | 7436 } else if (case_label->kind() == SourceLabel::kForward) { |
| 7428 // We have seen a 'continue' with this label name. Resolve | 7437 // We have seen a 'continue' with this label name. Resolve |
| 7429 // the forward reference. | 7438 // the forward reference. |
| 7430 case_label->ResolveForwardReference(); | 7439 case_label->ResolveForwardReference(); |
| 7431 } else { | 7440 } else { |
| 7432 ReportError(label_pos, "label '%s' already exists in scope", | 7441 ReportError(label_pos, "label '%s' already exists in scope", |
| 7433 label_name->ToCString()); | 7442 label_name->ToCString()); |
| 7434 } | 7443 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 7450 } else { | 7459 } else { |
| 7451 break; | 7460 break; |
| 7452 } | 7461 } |
| 7453 } | 7462 } |
| 7454 | 7463 |
| 7455 // Check that all expressions in case clauses are of the same class, | 7464 // Check that all expressions in case clauses are of the same class, |
| 7456 // or implement int, double or String. Patch the type of the temporary | 7465 // or implement int, double or String. Patch the type of the temporary |
| 7457 // variable holding the switch expression to match the type of the | 7466 // variable holding the switch expression to match the type of the |
| 7458 // case clause constants. | 7467 // case clause constants. |
| 7459 temp_var_type.set_type_class( | 7468 temp_var_type.set_type_class( |
| 7460 Class::Handle(I, CheckCaseExpressions(case_expr_values))); | 7469 Class::Handle(Z, CheckCaseExpressions(case_expr_values))); |
| 7461 | 7470 |
| 7462 // Check for unresolved label references. | 7471 // Check for unresolved label references. |
| 7463 SourceLabel* unresolved_label = | 7472 SourceLabel* unresolved_label = |
| 7464 current_block_->scope->CheckUnresolvedLabels(); | 7473 current_block_->scope->CheckUnresolvedLabels(); |
| 7465 if (unresolved_label != NULL) { | 7474 if (unresolved_label != NULL) { |
| 7466 ReportError("unresolved reference to label '%s'", | 7475 ReportError("unresolved reference to label '%s'", |
| 7467 unresolved_label->name().ToCString()); | 7476 unresolved_label->name().ToCString()); |
| 7468 } | 7477 } |
| 7469 | 7478 |
| 7470 SequenceNode* switch_body = CloseBlock(); | 7479 SequenceNode* switch_body = CloseBlock(); |
| 7471 ExpectToken(Token::kRBRACE); | 7480 ExpectToken(Token::kRBRACE); |
| 7472 return new(I) SwitchNode(switch_pos, label, switch_body); | 7481 return new(Z) SwitchNode(switch_pos, label, switch_body); |
| 7473 } | 7482 } |
| 7474 | 7483 |
| 7475 | 7484 |
| 7476 AstNode* Parser::ParseWhileStatement(String* label_name) { | 7485 AstNode* Parser::ParseWhileStatement(String* label_name) { |
| 7477 TRACE_PARSER("ParseWhileStatement"); | 7486 TRACE_PARSER("ParseWhileStatement"); |
| 7478 const intptr_t while_pos = TokenPos(); | 7487 const intptr_t while_pos = TokenPos(); |
| 7479 SourceLabel* label = | 7488 SourceLabel* label = |
| 7480 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); | 7489 SourceLabel::New(while_pos, label_name, SourceLabel::kWhile); |
| 7481 ConsumeToken(); | 7490 ConsumeToken(); |
| 7482 ExpectToken(Token::kLPAREN); | 7491 ExpectToken(Token::kLPAREN); |
| 7483 SequenceNode* await_preamble = NULL; | 7492 SequenceNode* await_preamble = NULL; |
| 7484 AstNode* cond_expr = ParseAwaitableExpr( | 7493 AstNode* cond_expr = ParseAwaitableExpr( |
| 7485 kAllowConst, kConsumeCascades, &await_preamble); | 7494 kAllowConst, kConsumeCascades, &await_preamble); |
| 7486 ExpectToken(Token::kRPAREN); | 7495 ExpectToken(Token::kRPAREN); |
| 7487 const bool parsing_loop_body = true; | 7496 const bool parsing_loop_body = true; |
| 7488 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); | 7497 SequenceNode* while_body = ParseNestedStatement(parsing_loop_body, label); |
| 7489 WhileNode* while_node = new (I) WhileNode(while_pos, | 7498 WhileNode* while_node = new (Z) WhileNode(while_pos, |
| 7490 label, | 7499 label, |
| 7491 cond_expr, | 7500 cond_expr, |
| 7492 await_preamble, | 7501 await_preamble, |
| 7493 while_body); | 7502 while_body); |
| 7494 return while_node; | 7503 return while_node; |
| 7495 } | 7504 } |
| 7496 | 7505 |
| 7497 | 7506 |
| 7498 AstNode* Parser::ParseDoWhileStatement(String* label_name) { | 7507 AstNode* Parser::ParseDoWhileStatement(String* label_name) { |
| 7499 TRACE_PARSER("ParseDoWhileStatement"); | 7508 TRACE_PARSER("ParseDoWhileStatement"); |
| 7500 const intptr_t do_pos = TokenPos(); | 7509 const intptr_t do_pos = TokenPos(); |
| 7501 SourceLabel* label = | 7510 SourceLabel* label = |
| 7502 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); | 7511 SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile); |
| 7503 ConsumeToken(); | 7512 ConsumeToken(); |
| 7504 const bool parsing_loop_body = true; | 7513 const bool parsing_loop_body = true; |
| 7505 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); | 7514 SequenceNode* dowhile_body = ParseNestedStatement(parsing_loop_body, label); |
| 7506 ExpectToken(Token::kWHILE); | 7515 ExpectToken(Token::kWHILE); |
| 7507 ExpectToken(Token::kLPAREN); | 7516 ExpectToken(Token::kLPAREN); |
| 7508 SequenceNode* await_preamble = NULL; | 7517 SequenceNode* await_preamble = NULL; |
| 7509 AstNode* cond_expr = ParseAwaitableExpr( | 7518 AstNode* cond_expr = ParseAwaitableExpr( |
| 7510 kAllowConst, kConsumeCascades, &await_preamble); | 7519 kAllowConst, kConsumeCascades, &await_preamble); |
| 7511 // No need for special handling of the await preamble as we can just append o | 7520 // No need for special handling of the await preamble as we can just append o |
| 7512 // it to the loop body. | 7521 // it to the loop body. |
| 7513 if (await_preamble != NULL) { | 7522 if (await_preamble != NULL) { |
| 7514 dowhile_body->Add(await_preamble); | 7523 dowhile_body->Add(await_preamble); |
| 7515 } | 7524 } |
| 7516 ExpectToken(Token::kRPAREN); | 7525 ExpectToken(Token::kRPAREN); |
| 7517 ExpectSemicolon(); | 7526 ExpectSemicolon(); |
| 7518 return new(I) DoWhileNode(do_pos, label, cond_expr, dowhile_body); | 7527 return new(Z) DoWhileNode(do_pos, label, cond_expr, dowhile_body); |
| 7519 } | 7528 } |
| 7520 | 7529 |
| 7521 | 7530 |
| 7522 AstNode* Parser::ParseAwaitForStatement(String* label_name) { | 7531 AstNode* Parser::ParseAwaitForStatement(String* label_name) { |
| 7523 TRACE_PARSER("ParseAwaitForStatement"); | 7532 TRACE_PARSER("ParseAwaitForStatement"); |
| 7524 ASSERT(IsAwaitKeyword()); | 7533 ASSERT(IsAwaitKeyword()); |
| 7525 const intptr_t await_for_pos = TokenPos(); | 7534 const intptr_t await_for_pos = TokenPos(); |
| 7526 ConsumeToken(); // await. | 7535 ConsumeToken(); // await. |
| 7527 ASSERT(CurrentToken() == Token::kFOR); | 7536 ASSERT(CurrentToken() == Token::kFOR); |
| 7528 ConsumeToken(); // for. | 7537 ConsumeToken(); // for. |
| 7529 ExpectToken(Token::kLPAREN); | 7538 ExpectToken(Token::kLPAREN); |
| 7530 | 7539 |
| 7531 // Parse loop variable. | 7540 // Parse loop variable. |
| 7532 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 7541 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
| 7533 if (CurrentToken() == Token::kCONST) { | 7542 if (CurrentToken() == Token::kCONST) { |
| 7534 ReportError("Loop variable cannot be 'const'"); | 7543 ReportError("Loop variable cannot be 'const'"); |
| 7535 } | 7544 } |
| 7536 bool new_loop_var = false; | 7545 bool new_loop_var = false; |
| 7537 AbstractType& loop_var_type = AbstractType::ZoneHandle(I); | 7546 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
| 7538 if (LookaheadToken(1) != Token::kIN) { | 7547 if (LookaheadToken(1) != Token::kIN) { |
| 7539 // Declaration of a new loop variable. | 7548 // Declaration of a new loop variable. |
| 7540 // Delay creation of the local variable until we know its actual | 7549 // Delay creation of the local variable until we know its actual |
| 7541 // position, which is inside the loop body. | 7550 // position, which is inside the loop body. |
| 7542 new_loop_var = true; | 7551 new_loop_var = true; |
| 7543 loop_var_type = ParseConstFinalVarOrType( | 7552 loop_var_type = ParseConstFinalVarOrType( |
| 7544 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : | 7553 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : |
| 7545 ClassFinalizer::kIgnore); | 7554 ClassFinalizer::kIgnore); |
| 7546 } | 7555 } |
| 7547 intptr_t loop_var_pos = TokenPos(); | 7556 intptr_t loop_var_pos = TokenPos(); |
| 7548 const String* loop_var_name = ExpectIdentifier("variable name expected"); | 7557 const String* loop_var_name = ExpectIdentifier("variable name expected"); |
| 7549 | 7558 |
| 7550 // Parse stream expression. | 7559 // Parse stream expression. |
| 7551 ExpectToken(Token::kIN); | 7560 ExpectToken(Token::kIN); |
| 7552 const intptr_t stream_pos = TokenPos(); | 7561 const intptr_t stream_pos = TokenPos(); |
| 7553 AstNode* stream_expr = | 7562 AstNode* stream_expr = |
| 7554 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 7563 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7555 ExpectToken(Token::kRPAREN); | 7564 ExpectToken(Token::kRPAREN); |
| 7556 | 7565 |
| 7557 OpenBlock(); | 7566 OpenBlock(); |
| 7558 | 7567 |
| 7559 // Build creation of implicit StreamIterator. | 7568 // Build creation of implicit StreamIterator. |
| 7560 // var :for-in-iter = new StreamIterator(stream_expr). | 7569 // var :for-in-iter = new StreamIterator(stream_expr). |
| 7561 const Class& stream_iterator_cls = | 7570 const Class& stream_iterator_cls = |
| 7562 Class::ZoneHandle(I, I->object_store()->stream_iterator_class()); | 7571 Class::ZoneHandle(Z, I->object_store()->stream_iterator_class()); |
| 7563 ASSERT(!stream_iterator_cls.IsNull()); | 7572 ASSERT(!stream_iterator_cls.IsNull()); |
| 7564 const Function& iterator_ctor = | 7573 const Function& iterator_ctor = |
| 7565 Function::ZoneHandle(I, stream_iterator_cls.LookupFunction( | 7574 Function::ZoneHandle(Z, stream_iterator_cls.LookupFunction( |
| 7566 Symbols::StreamIteratorConstructor())); | 7575 Symbols::StreamIteratorConstructor())); |
| 7567 ASSERT(!iterator_ctor.IsNull()); | 7576 ASSERT(!iterator_ctor.IsNull()); |
| 7568 ArgumentListNode* ctor_args = new (I) ArgumentListNode(Scanner::kNoSourcePos); | 7577 ArgumentListNode* ctor_args = new (Z) ArgumentListNode(Scanner::kNoSourcePos); |
| 7569 ctor_args->Add(stream_expr); | 7578 ctor_args->Add(stream_expr); |
| 7570 ConstructorCallNode* ctor_call = | 7579 ConstructorCallNode* ctor_call = |
| 7571 new (I) ConstructorCallNode(Scanner::kNoSourcePos, | 7580 new (Z) ConstructorCallNode(Scanner::kNoSourcePos, |
| 7572 TypeArguments::ZoneHandle(I), | 7581 TypeArguments::ZoneHandle(Z), |
| 7573 iterator_ctor, | 7582 iterator_ctor, |
| 7574 ctor_args); | 7583 ctor_args); |
| 7575 const AbstractType& iterator_type = Type::ZoneHandle(I, Type::DynamicType()); | 7584 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 7576 LocalVariable* iterator_var = new(I) LocalVariable( | 7585 LocalVariable* iterator_var = new(Z) LocalVariable( |
| 7577 stream_pos, Symbols::ForInIter(), iterator_type); | 7586 stream_pos, Symbols::ForInIter(), iterator_type); |
| 7578 current_block_->scope->AddVariable(iterator_var); | 7587 current_block_->scope->AddVariable(iterator_var); |
| 7579 AstNode* iterator_init = | 7588 AstNode* iterator_init = |
| 7580 new(I) StoreLocalNode(stream_pos, iterator_var, ctor_call); | 7589 new(Z) StoreLocalNode(stream_pos, iterator_var, ctor_call); |
| 7581 current_block_->statements->Add(iterator_init); | 7590 current_block_->statements->Add(iterator_init); |
| 7582 | 7591 |
| 7583 // Build while loop condition. | 7592 // Build while loop condition. |
| 7584 // while (await :for-in-iter.moveNext()) | 7593 // while (await :for-in-iter.moveNext()) |
| 7585 ArgumentListNode* no_args = new(I) ArgumentListNode(stream_pos); | 7594 ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos); |
| 7586 AstNode* iterator_moveNext = new(I) InstanceCallNode( | 7595 AstNode* iterator_moveNext = new(Z) InstanceCallNode( |
| 7587 stream_pos, | 7596 stream_pos, |
| 7588 new(I) LoadLocalNode(stream_pos, iterator_var), | 7597 new(Z) LoadLocalNode(stream_pos, iterator_var), |
| 7589 Symbols::MoveNext(), | 7598 Symbols::MoveNext(), |
| 7590 no_args); | 7599 no_args); |
| 7591 AstNode* await_moveNext = new (I) AwaitNode(stream_pos, iterator_moveNext); | 7600 AstNode* await_moveNext = new (Z) AwaitNode(stream_pos, iterator_moveNext); |
| 7592 OpenBlock(); | 7601 OpenBlock(); |
| 7593 AwaitTransformer at(current_block_->statements, | 7602 AwaitTransformer at(current_block_->statements, |
| 7594 parsed_function(), | 7603 parsed_function(), |
| 7595 async_temp_scope_); | 7604 async_temp_scope_); |
| 7596 AstNode* transformed_await = at.Transform(await_moveNext); | 7605 AstNode* transformed_await = at.Transform(await_moveNext); |
| 7597 SequenceNode* await_preamble = CloseBlock(); | 7606 SequenceNode* await_preamble = CloseBlock(); |
| 7598 | 7607 |
| 7599 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 7608 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
| 7600 // here, but that does not work well because we have to insert an implicit | 7609 // here, but that does not work well because we have to insert an implicit |
| 7601 // variable assignment and potentially a variable declaration in the | 7610 // variable assignment and potentially a variable declaration in the |
| 7602 // loop body. | 7611 // loop body. |
| 7603 OpenLoopBlock(); | 7612 OpenLoopBlock(); |
| 7604 SourceLabel* label = | 7613 SourceLabel* label = |
| 7605 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); | 7614 SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor); |
| 7606 current_block_->scope->AddLabel(label); | 7615 current_block_->scope->AddLabel(label); |
| 7607 const intptr_t loop_var_assignment_pos = TokenPos(); | 7616 const intptr_t loop_var_assignment_pos = TokenPos(); |
| 7608 | 7617 |
| 7609 AstNode* iterator_current = new(I) InstanceGetterNode( | 7618 AstNode* iterator_current = new(Z) InstanceGetterNode( |
| 7610 loop_var_assignment_pos, | 7619 loop_var_assignment_pos, |
| 7611 new(I) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 7620 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
| 7612 Symbols::Current()); | 7621 Symbols::Current()); |
| 7613 | 7622 |
| 7614 // Generate assignment of next iterator value to loop variable. | 7623 // Generate assignment of next iterator value to loop variable. |
| 7615 AstNode* loop_var_assignment = NULL; | 7624 AstNode* loop_var_assignment = NULL; |
| 7616 if (new_loop_var) { | 7625 if (new_loop_var) { |
| 7617 // The for loop variable is new for each iteration. | 7626 // The for loop variable is new for each iteration. |
| 7618 // Create a variable and add it to the loop body scope. | 7627 // Create a variable and add it to the loop body scope. |
| 7619 // Note that the variable token position needs to be inside the | 7628 // Note that the variable token position needs to be inside the |
| 7620 // loop block, so it gets put in the loop context level. | 7629 // loop block, so it gets put in the loop context level. |
| 7621 LocalVariable* loop_var = | 7630 LocalVariable* loop_var = |
| 7622 new(I) LocalVariable(loop_var_assignment_pos, | 7631 new(Z) LocalVariable(loop_var_assignment_pos, |
| 7623 *loop_var_name, | 7632 *loop_var_name, |
| 7624 loop_var_type);; | 7633 loop_var_type);; |
| 7625 if (loop_var_is_final) { | 7634 if (loop_var_is_final) { |
| 7626 loop_var->set_is_final(); | 7635 loop_var->set_is_final(); |
| 7627 } | 7636 } |
| 7628 current_block_->scope->AddVariable(loop_var); | 7637 current_block_->scope->AddVariable(loop_var); |
| 7629 loop_var_assignment = new(I) StoreLocalNode( | 7638 loop_var_assignment = new(Z) StoreLocalNode( |
| 7630 loop_var_assignment_pos, loop_var, iterator_current); | 7639 loop_var_assignment_pos, loop_var, iterator_current); |
| 7631 } else { | 7640 } else { |
| 7632 AstNode* loop_var_primary = | 7641 AstNode* loop_var_primary = |
| 7633 ResolveIdent(loop_var_pos, *loop_var_name, false); | 7642 ResolveIdent(loop_var_pos, *loop_var_name, false); |
| 7634 ASSERT(!loop_var_primary->IsPrimaryNode()); | 7643 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 7635 loop_var_assignment = CreateAssignmentNode(loop_var_primary, | 7644 loop_var_assignment = CreateAssignmentNode(loop_var_primary, |
| 7636 iterator_current, | 7645 iterator_current, |
| 7637 loop_var_name, | 7646 loop_var_name, |
| 7638 loop_var_assignment_pos); | 7647 loop_var_assignment_pos); |
| 7639 ASSERT(loop_var_assignment != NULL); | 7648 ASSERT(loop_var_assignment != NULL); |
| 7640 } | 7649 } |
| 7641 current_block_->statements->Add(loop_var_assignment); | 7650 current_block_->statements->Add(loop_var_assignment); |
| 7642 | 7651 |
| 7643 // Now parse the for-in loop statement or block. | 7652 // Now parse the for-in loop statement or block. |
| 7644 if (CurrentToken() == Token::kLBRACE) { | 7653 if (CurrentToken() == Token::kLBRACE) { |
| 7645 ConsumeToken(); | 7654 ConsumeToken(); |
| 7646 ParseStatementSequence(); | 7655 ParseStatementSequence(); |
| 7647 ExpectToken(Token::kRBRACE); | 7656 ExpectToken(Token::kRBRACE); |
| 7648 } else { | 7657 } else { |
| 7649 AstNode* statement = ParseStatement(); | 7658 AstNode* statement = ParseStatement(); |
| 7650 if (statement != NULL) { | 7659 if (statement != NULL) { |
| 7651 current_block_->statements->Add(statement); | 7660 current_block_->statements->Add(statement); |
| 7652 } | 7661 } |
| 7653 } | 7662 } |
| 7654 SequenceNode* for_loop_statement = CloseBlock(); | 7663 SequenceNode* for_loop_statement = CloseBlock(); |
| 7655 | 7664 |
| 7656 WhileNode* while_node = new (I) WhileNode(await_for_pos, | 7665 WhileNode* while_node = new (Z) WhileNode(await_for_pos, |
| 7657 label, | 7666 label, |
| 7658 transformed_await, | 7667 transformed_await, |
| 7659 await_preamble, | 7668 await_preamble, |
| 7660 for_loop_statement); | 7669 for_loop_statement); |
| 7661 current_block_->statements->Add(while_node); | 7670 current_block_->statements->Add(while_node); |
| 7662 | 7671 |
| 7663 return CloseBlock(); // Implicit block around while loop. | 7672 return CloseBlock(); // Implicit block around while loop. |
| 7664 } | 7673 } |
| 7665 | 7674 |
| 7666 | 7675 |
| 7667 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, | 7676 AstNode* Parser::ParseForInStatement(intptr_t forin_pos, |
| 7668 SourceLabel* label) { | 7677 SourceLabel* label) { |
| 7669 TRACE_PARSER("ParseForInStatement"); | 7678 TRACE_PARSER("ParseForInStatement"); |
| 7670 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); | 7679 bool loop_var_is_final = (CurrentToken() == Token::kFINAL); |
| 7671 if (CurrentToken() == Token::kCONST) { | 7680 if (CurrentToken() == Token::kCONST) { |
| 7672 ReportError("Loop variable cannot be 'const'"); | 7681 ReportError("Loop variable cannot be 'const'"); |
| 7673 } | 7682 } |
| 7674 const String* loop_var_name = NULL; | 7683 const String* loop_var_name = NULL; |
| 7675 intptr_t loop_var_pos = 0; | 7684 intptr_t loop_var_pos = 0; |
| 7676 bool new_loop_var = false; | 7685 bool new_loop_var = false; |
| 7677 AbstractType& loop_var_type = AbstractType::ZoneHandle(I); | 7686 AbstractType& loop_var_type = AbstractType::ZoneHandle(Z); |
| 7678 if (LookaheadToken(1) == Token::kIN) { | 7687 if (LookaheadToken(1) == Token::kIN) { |
| 7679 loop_var_pos = TokenPos(); | 7688 loop_var_pos = TokenPos(); |
| 7680 loop_var_name = ExpectIdentifier("variable name expected"); | 7689 loop_var_name = ExpectIdentifier("variable name expected"); |
| 7681 } else { | 7690 } else { |
| 7682 // The case without a type is handled above, so require a type here. | 7691 // The case without a type is handled above, so require a type here. |
| 7683 // Delay creation of the local variable until we know its actual | 7692 // Delay creation of the local variable until we know its actual |
| 7684 // position, which is inside the loop body. | 7693 // position, which is inside the loop body. |
| 7685 new_loop_var = true; | 7694 new_loop_var = true; |
| 7686 loop_var_type = ParseConstFinalVarOrType( | 7695 loop_var_type = ParseConstFinalVarOrType( |
| 7687 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : | 7696 FLAG_enable_type_checks ? ClassFinalizer::kCanonicalize : |
| 7688 ClassFinalizer::kIgnore); | 7697 ClassFinalizer::kIgnore); |
| 7689 loop_var_name = ExpectIdentifier("variable name expected"); | 7698 loop_var_name = ExpectIdentifier("variable name expected"); |
| 7690 } | 7699 } |
| 7691 ExpectToken(Token::kIN); | 7700 ExpectToken(Token::kIN); |
| 7692 const intptr_t collection_pos = TokenPos(); | 7701 const intptr_t collection_pos = TokenPos(); |
| 7693 AstNode* collection_expr = | 7702 AstNode* collection_expr = |
| 7694 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 7703 ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 7695 ExpectToken(Token::kRPAREN); | 7704 ExpectToken(Token::kRPAREN); |
| 7696 | 7705 |
| 7697 OpenBlock(); // Implicit block around while loop. | 7706 OpenBlock(); // Implicit block around while loop. |
| 7698 | 7707 |
| 7699 // Generate implicit iterator variable and add to scope. | 7708 // Generate implicit iterator variable and add to scope. |
| 7700 // We could set the type of the implicit iterator variable to Iterator<T> | 7709 // We could set the type of the implicit iterator variable to Iterator<T> |
| 7701 // where T is the type of the for loop variable. However, the type error | 7710 // where T is the type of the for loop variable. However, the type error |
| 7702 // would refer to the compiler generated iterator and could confuse the user. | 7711 // would refer to the compiler generated iterator and could confuse the user. |
| 7703 // It is better to leave the iterator untyped and postpone the type error | 7712 // It is better to leave the iterator untyped and postpone the type error |
| 7704 // until the loop variable is assigned to. | 7713 // until the loop variable is assigned to. |
| 7705 const AbstractType& iterator_type = Type::ZoneHandle(I, Type::DynamicType()); | 7714 const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 7706 LocalVariable* iterator_var = new(I) LocalVariable( | 7715 LocalVariable* iterator_var = new(Z) LocalVariable( |
| 7707 collection_pos, Symbols::ForInIter(), iterator_type); | 7716 collection_pos, Symbols::ForInIter(), iterator_type); |
| 7708 current_block_->scope->AddVariable(iterator_var); | 7717 current_block_->scope->AddVariable(iterator_var); |
| 7709 | 7718 |
| 7710 // Generate initialization of iterator variable. | 7719 // Generate initialization of iterator variable. |
| 7711 ArgumentListNode* no_args = new(I) ArgumentListNode(collection_pos); | 7720 ArgumentListNode* no_args = new(Z) ArgumentListNode(collection_pos); |
| 7712 AstNode* get_iterator = new(I) InstanceGetterNode( | 7721 AstNode* get_iterator = new(Z) InstanceGetterNode( |
| 7713 collection_pos, collection_expr, Symbols::GetIterator()); | 7722 collection_pos, collection_expr, Symbols::GetIterator()); |
| 7714 AstNode* iterator_init = | 7723 AstNode* iterator_init = |
| 7715 new(I) StoreLocalNode(collection_pos, iterator_var, get_iterator); | 7724 new(Z) StoreLocalNode(collection_pos, iterator_var, get_iterator); |
| 7716 current_block_->statements->Add(iterator_init); | 7725 current_block_->statements->Add(iterator_init); |
| 7717 | 7726 |
| 7718 // Generate while loop condition. | 7727 // Generate while loop condition. |
| 7719 AstNode* iterator_moveNext = new(I) InstanceCallNode( | 7728 AstNode* iterator_moveNext = new(Z) InstanceCallNode( |
| 7720 collection_pos, | 7729 collection_pos, |
| 7721 new(I) LoadLocalNode(collection_pos, iterator_var), | 7730 new(Z) LoadLocalNode(collection_pos, iterator_var), |
| 7722 Symbols::MoveNext(), | 7731 Symbols::MoveNext(), |
| 7723 no_args); | 7732 no_args); |
| 7724 | 7733 |
| 7725 // Parse the for loop body. Ideally, we would use ParseNestedStatement() | 7734 // Parse the for loop body. Ideally, we would use ParseNestedStatement() |
| 7726 // here, but that does not work well because we have to insert an implicit | 7735 // here, but that does not work well because we have to insert an implicit |
| 7727 // variable assignment and potentially a variable declaration in the | 7736 // variable assignment and potentially a variable declaration in the |
| 7728 // loop body. | 7737 // loop body. |
| 7729 OpenLoopBlock(); | 7738 OpenLoopBlock(); |
| 7730 current_block_->scope->AddLabel(label); | 7739 current_block_->scope->AddLabel(label); |
| 7731 const intptr_t loop_var_assignment_pos = TokenPos(); | 7740 const intptr_t loop_var_assignment_pos = TokenPos(); |
| 7732 | 7741 |
| 7733 AstNode* iterator_current = new(I) InstanceGetterNode( | 7742 AstNode* iterator_current = new(Z) InstanceGetterNode( |
| 7734 loop_var_assignment_pos, | 7743 loop_var_assignment_pos, |
| 7735 new(I) LoadLocalNode(loop_var_assignment_pos, iterator_var), | 7744 new(Z) LoadLocalNode(loop_var_assignment_pos, iterator_var), |
| 7736 Symbols::Current()); | 7745 Symbols::Current()); |
| 7737 | 7746 |
| 7738 // Generate assignment of next iterator value to loop variable. | 7747 // Generate assignment of next iterator value to loop variable. |
| 7739 AstNode* loop_var_assignment = NULL; | 7748 AstNode* loop_var_assignment = NULL; |
| 7740 if (new_loop_var) { | 7749 if (new_loop_var) { |
| 7741 // The for loop variable is new for each iteration. | 7750 // The for loop variable is new for each iteration. |
| 7742 // Create a variable and add it to the loop body scope. | 7751 // Create a variable and add it to the loop body scope. |
| 7743 LocalVariable* loop_var = | 7752 LocalVariable* loop_var = |
| 7744 new(I) LocalVariable(loop_var_assignment_pos, | 7753 new(Z) LocalVariable(loop_var_assignment_pos, |
| 7745 *loop_var_name, | 7754 *loop_var_name, |
| 7746 loop_var_type);; | 7755 loop_var_type);; |
| 7747 if (loop_var_is_final) { | 7756 if (loop_var_is_final) { |
| 7748 loop_var->set_is_final(); | 7757 loop_var->set_is_final(); |
| 7749 } | 7758 } |
| 7750 current_block_->scope->AddVariable(loop_var); | 7759 current_block_->scope->AddVariable(loop_var); |
| 7751 loop_var_assignment = new(I) StoreLocalNode( | 7760 loop_var_assignment = new(Z) StoreLocalNode( |
| 7752 loop_var_assignment_pos, loop_var, iterator_current); | 7761 loop_var_assignment_pos, loop_var, iterator_current); |
| 7753 } else { | 7762 } else { |
| 7754 AstNode* loop_var_primary = | 7763 AstNode* loop_var_primary = |
| 7755 ResolveIdent(loop_var_pos, *loop_var_name, false); | 7764 ResolveIdent(loop_var_pos, *loop_var_name, false); |
| 7756 ASSERT(!loop_var_primary->IsPrimaryNode()); | 7765 ASSERT(!loop_var_primary->IsPrimaryNode()); |
| 7757 loop_var_assignment = CreateAssignmentNode(loop_var_primary, | 7766 loop_var_assignment = CreateAssignmentNode(loop_var_primary, |
| 7758 iterator_current, | 7767 iterator_current, |
| 7759 loop_var_name, | 7768 loop_var_name, |
| 7760 loop_var_assignment_pos); | 7769 loop_var_assignment_pos); |
| 7761 ASSERT(loop_var_assignment != NULL); | 7770 ASSERT(loop_var_assignment != NULL); |
| 7762 } | 7771 } |
| 7763 current_block_->statements->Add(loop_var_assignment); | 7772 current_block_->statements->Add(loop_var_assignment); |
| 7764 | 7773 |
| 7765 // Now parse the for-in loop statement or block. | 7774 // Now parse the for-in loop statement or block. |
| 7766 if (CurrentToken() == Token::kLBRACE) { | 7775 if (CurrentToken() == Token::kLBRACE) { |
| 7767 ConsumeToken(); | 7776 ConsumeToken(); |
| 7768 ParseStatementSequence(); | 7777 ParseStatementSequence(); |
| 7769 ExpectToken(Token::kRBRACE); | 7778 ExpectToken(Token::kRBRACE); |
| 7770 } else { | 7779 } else { |
| 7771 AstNode* statement = ParseStatement(); | 7780 AstNode* statement = ParseStatement(); |
| 7772 if (statement != NULL) { | 7781 if (statement != NULL) { |
| 7773 current_block_->statements->Add(statement); | 7782 current_block_->statements->Add(statement); |
| 7774 } | 7783 } |
| 7775 } | 7784 } |
| 7776 | 7785 |
| 7777 SequenceNode* for_loop_statement = CloseBlock(); | 7786 SequenceNode* for_loop_statement = CloseBlock(); |
| 7778 | 7787 |
| 7779 AstNode* while_statement = new(I) WhileNode( | 7788 AstNode* while_statement = new(Z) WhileNode( |
| 7780 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); | 7789 forin_pos, label, iterator_moveNext, NULL, for_loop_statement); |
| 7781 current_block_->statements->Add(while_statement); | 7790 current_block_->statements->Add(while_statement); |
| 7782 | 7791 |
| 7783 return CloseBlock(); // Implicit block around while loop. | 7792 return CloseBlock(); // Implicit block around while loop. |
| 7784 } | 7793 } |
| 7785 | 7794 |
| 7786 | 7795 |
| 7787 AstNode* Parser::ParseForStatement(String* label_name) { | 7796 AstNode* Parser::ParseForStatement(String* label_name) { |
| 7788 TRACE_PARSER("ParseForStatement"); | 7797 TRACE_PARSER("ParseForStatement"); |
| 7789 const intptr_t for_pos = TokenPos(); | 7798 const intptr_t for_pos = TokenPos(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7823 const bool parsing_loop_body = true; | 7832 const bool parsing_loop_body = true; |
| 7824 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); | 7833 SequenceNode* body = ParseNestedStatement(parsing_loop_body, label); |
| 7825 | 7834 |
| 7826 // Check whether any of the variables in the initializer part of | 7835 // Check whether any of the variables in the initializer part of |
| 7827 // the for statement are captured by a closure. If so, we insert a | 7836 // the for statement are captured by a closure. If so, we insert a |
| 7828 // node that creates a new Context for the loop variable before | 7837 // node that creates a new Context for the loop variable before |
| 7829 // the increment expression is evaluated. | 7838 // the increment expression is evaluated. |
| 7830 for (int i = 0; i < init_scope->num_variables(); i++) { | 7839 for (int i = 0; i < init_scope->num_variables(); i++) { |
| 7831 if (init_scope->VariableAt(i)->is_captured() && | 7840 if (init_scope->VariableAt(i)->is_captured() && |
| 7832 (init_scope->VariableAt(i)->owner() == init_scope)) { | 7841 (init_scope->VariableAt(i)->owner() == init_scope)) { |
| 7833 SequenceNode* incr_sequence = new(I) SequenceNode(incr_pos, NULL); | 7842 SequenceNode* incr_sequence = new(Z) SequenceNode(incr_pos, NULL); |
| 7834 incr_sequence->Add(new(I) CloneContextNode(for_pos)); | 7843 incr_sequence->Add(new(Z) CloneContextNode(for_pos)); |
| 7835 if (increment != NULL) { | 7844 if (increment != NULL) { |
| 7836 incr_sequence->Add(increment); | 7845 incr_sequence->Add(increment); |
| 7837 } | 7846 } |
| 7838 increment = incr_sequence; | 7847 increment = incr_sequence; |
| 7839 break; | 7848 break; |
| 7840 } | 7849 } |
| 7841 } | 7850 } |
| 7842 AstNode* for_node = new(I) ForNode( | 7851 AstNode* for_node = new(Z) ForNode( |
| 7843 for_pos, | 7852 for_pos, |
| 7844 label, | 7853 label, |
| 7845 NodeAsSequenceNode(init_pos, initializer, NULL), | 7854 NodeAsSequenceNode(init_pos, initializer, NULL), |
| 7846 condition, | 7855 condition, |
| 7847 condition_preamble, | 7856 condition_preamble, |
| 7848 NodeAsSequenceNode(incr_pos, increment, NULL), | 7857 NodeAsSequenceNode(incr_pos, increment, NULL), |
| 7849 body); | 7858 body); |
| 7850 current_block_->statements->Add(for_node); | 7859 current_block_->statements->Add(for_node); |
| 7851 return CloseBlock(); | 7860 return CloseBlock(); |
| 7852 } | 7861 } |
| 7853 | 7862 |
| 7854 | 7863 |
| 7855 // Calling VM-internal helpers, uses implementation core library. | 7864 // Calling VM-internal helpers, uses implementation core library. |
| 7856 AstNode* Parser::MakeStaticCall(const String& cls_name, | 7865 AstNode* Parser::MakeStaticCall(const String& cls_name, |
| 7857 const String& func_name, | 7866 const String& func_name, |
| 7858 ArgumentListNode* arguments) { | 7867 ArgumentListNode* arguments) { |
| 7859 const Class& cls = Class::Handle(I, Library::LookupCoreClass(cls_name)); | 7868 const Class& cls = Class::Handle(Z, Library::LookupCoreClass(cls_name)); |
| 7860 ASSERT(!cls.IsNull()); | 7869 ASSERT(!cls.IsNull()); |
| 7861 const Function& func = Function::ZoneHandle(I, | 7870 const Function& func = Function::ZoneHandle(Z, |
| 7862 Resolver::ResolveStatic(cls, | 7871 Resolver::ResolveStatic(cls, |
| 7863 func_name, | 7872 func_name, |
| 7864 arguments->length(), | 7873 arguments->length(), |
| 7865 arguments->names())); | 7874 arguments->names())); |
| 7866 ASSERT(!func.IsNull()); | 7875 ASSERT(!func.IsNull()); |
| 7867 return new(I) StaticCallNode(arguments->token_pos(), func, arguments); | 7876 return new(Z) StaticCallNode(arguments->token_pos(), func, arguments); |
| 7868 } | 7877 } |
| 7869 | 7878 |
| 7870 | 7879 |
| 7871 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { | 7880 AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) { |
| 7872 ArgumentListNode* arguments = new(I) ArgumentListNode(begin); | 7881 ArgumentListNode* arguments = new(Z) ArgumentListNode(begin); |
| 7873 arguments->Add(new(I) LiteralNode(begin, | 7882 arguments->Add(new(Z) LiteralNode(begin, |
| 7874 Integer::ZoneHandle(I, Integer::New(begin)))); | 7883 Integer::ZoneHandle(Z, Integer::New(begin)))); |
| 7875 arguments->Add(new(I) LiteralNode(end, | 7884 arguments->Add(new(Z) LiteralNode(end, |
| 7876 Integer::ZoneHandle(I, Integer::New(end)))); | 7885 Integer::ZoneHandle(Z, Integer::New(end)))); |
| 7877 return MakeStaticCall(Symbols::AssertionError(), | 7886 return MakeStaticCall(Symbols::AssertionError(), |
| 7878 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 7887 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 7879 arguments); | 7888 arguments); |
| 7880 } | 7889 } |
| 7881 | 7890 |
| 7882 | 7891 |
| 7883 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { | 7892 AstNode* Parser::InsertClosureCallNodes(AstNode* condition) { |
| 7884 if (condition->IsClosureNode() || | 7893 if (condition->IsClosureNode() || |
| 7885 (condition->IsStoreLocalNode() && | 7894 (condition->IsStoreLocalNode() && |
| 7886 condition->AsStoreLocalNode()->value()->IsClosureNode())) { | 7895 condition->AsStoreLocalNode()->value()->IsClosureNode())) { |
| 7887 // Function literal in assert implies a call. | 7896 // Function literal in assert implies a call. |
| 7888 const intptr_t pos = condition->token_pos(); | 7897 const intptr_t pos = condition->token_pos(); |
| 7889 condition = BuildClosureCall(pos, | 7898 condition = BuildClosureCall(pos, |
| 7890 condition, | 7899 condition, |
| 7891 new(I) ArgumentListNode(pos)); | 7900 new(Z) ArgumentListNode(pos)); |
| 7892 } else if (condition->IsConditionalExprNode()) { | 7901 } else if (condition->IsConditionalExprNode()) { |
| 7893 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); | 7902 ConditionalExprNode* cond_expr = condition->AsConditionalExprNode(); |
| 7894 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); | 7903 cond_expr->set_true_expr(InsertClosureCallNodes(cond_expr->true_expr())); |
| 7895 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); | 7904 cond_expr->set_false_expr(InsertClosureCallNodes(cond_expr->false_expr())); |
| 7896 } | 7905 } |
| 7897 return condition; | 7906 return condition; |
| 7898 } | 7907 } |
| 7899 | 7908 |
| 7900 | 7909 |
| 7901 AstNode* Parser::ParseAssertStatement() { | 7910 AstNode* Parser::ParseAssertStatement() { |
| 7902 TRACE_PARSER("ParseAssertStatement"); | 7911 TRACE_PARSER("ParseAssertStatement"); |
| 7903 ConsumeToken(); // Consume assert keyword. | 7912 ConsumeToken(); // Consume assert keyword. |
| 7904 ExpectToken(Token::kLPAREN); | 7913 ExpectToken(Token::kLPAREN); |
| 7905 const intptr_t condition_pos = TokenPos(); | 7914 const intptr_t condition_pos = TokenPos(); |
| 7906 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { | 7915 if (!FLAG_enable_asserts && !FLAG_enable_type_checks) { |
| 7907 SkipExpr(); | 7916 SkipExpr(); |
| 7908 ExpectToken(Token::kRPAREN); | 7917 ExpectToken(Token::kRPAREN); |
| 7909 return NULL; | 7918 return NULL; |
| 7910 } | 7919 } |
| 7911 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades); | 7920 AstNode* condition = ParseExpr(kAllowConst, kConsumeCascades); |
| 7912 const intptr_t condition_end = TokenPos(); | 7921 const intptr_t condition_end = TokenPos(); |
| 7913 ExpectToken(Token::kRPAREN); | 7922 ExpectToken(Token::kRPAREN); |
| 7914 condition = InsertClosureCallNodes(condition); | 7923 condition = InsertClosureCallNodes(condition); |
| 7915 condition = new(I) UnaryOpNode(condition_pos, Token::kNOT, condition); | 7924 condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition); |
| 7916 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); | 7925 AstNode* assert_throw = MakeAssertCall(condition_pos, condition_end); |
| 7917 return new(I) IfNode( | 7926 return new(Z) IfNode( |
| 7918 condition_pos, | 7927 condition_pos, |
| 7919 condition, | 7928 condition, |
| 7920 NodeAsSequenceNode(condition_pos, assert_throw, NULL), | 7929 NodeAsSequenceNode(condition_pos, assert_throw, NULL), |
| 7921 NULL); | 7930 NULL); |
| 7922 } | 7931 } |
| 7923 | 7932 |
| 7924 | 7933 |
| 7925 // Populate local scope of the catch block with the catch parameters. | 7934 // Populate local scope of the catch block with the catch parameters. |
| 7926 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, | 7935 void Parser::AddCatchParamsToScope(CatchParamDesc* exception_param, |
| 7927 CatchParamDesc* stack_trace_param, | 7936 CatchParamDesc* stack_trace_param, |
| 7928 LocalScope* scope) { | 7937 LocalScope* scope) { |
| 7929 if (exception_param->name != NULL) { | 7938 if (exception_param->name != NULL) { |
| 7930 LocalVariable* var = new(I) LocalVariable( | 7939 LocalVariable* var = new(Z) LocalVariable( |
| 7931 exception_param->token_pos, | 7940 exception_param->token_pos, |
| 7932 *exception_param->name, | 7941 *exception_param->name, |
| 7933 *exception_param->type); | 7942 *exception_param->type); |
| 7934 var->set_is_final(); | 7943 var->set_is_final(); |
| 7935 bool added_to_scope = scope->AddVariable(var); | 7944 bool added_to_scope = scope->AddVariable(var); |
| 7936 ASSERT(added_to_scope); | 7945 ASSERT(added_to_scope); |
| 7937 exception_param->var = var; | 7946 exception_param->var = var; |
| 7938 } | 7947 } |
| 7939 if (stack_trace_param->name != NULL) { | 7948 if (stack_trace_param->name != NULL) { |
| 7940 LocalVariable* var = new(I) LocalVariable( | 7949 LocalVariable* var = new(Z) LocalVariable( |
| 7941 stack_trace_param->token_pos, | 7950 stack_trace_param->token_pos, |
| 7942 *stack_trace_param->name, | 7951 *stack_trace_param->name, |
| 7943 *stack_trace_param->type); | 7952 *stack_trace_param->type); |
| 7944 var->set_is_final(); | 7953 var->set_is_final(); |
| 7945 bool added_to_scope = scope->AddVariable(var); | 7954 bool added_to_scope = scope->AddVariable(var); |
| 7946 if (!added_to_scope) { | 7955 if (!added_to_scope) { |
| 7947 ReportError(stack_trace_param->token_pos, | 7956 ReportError(stack_trace_param->token_pos, |
| 7948 "name '%s' already exists in scope", | 7957 "name '%s' already exists in scope", |
| 7949 stack_trace_param->name->ToCString()); | 7958 stack_trace_param->name->ToCString()); |
| 7950 } | 7959 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 7974 | 7983 |
| 7975 ParseStatementSequence(); | 7984 ParseStatementSequence(); |
| 7976 ExpectToken(Token::kRBRACE); | 7985 ExpectToken(Token::kRBRACE); |
| 7977 SequenceNode* finally_block = CloseBlock(); | 7986 SequenceNode* finally_block = CloseBlock(); |
| 7978 return finally_block; | 7987 return finally_block; |
| 7979 } | 7988 } |
| 7980 | 7989 |
| 7981 | 7990 |
| 7982 void Parser::PushTryBlock(Block* try_block) { | 7991 void Parser::PushTryBlock(Block* try_block) { |
| 7983 intptr_t try_index = AllocateTryIndex(); | 7992 intptr_t try_index = AllocateTryIndex(); |
| 7984 TryBlocks* block = new(I) TryBlocks( | 7993 TryBlocks* block = new(Z) TryBlocks( |
| 7985 try_block, try_blocks_list_, try_index); | 7994 try_block, try_blocks_list_, try_index); |
| 7986 try_blocks_list_ = block; | 7995 try_blocks_list_ = block; |
| 7987 } | 7996 } |
| 7988 | 7997 |
| 7989 | 7998 |
| 7990 Parser::TryBlocks* Parser::PopTryBlock() { | 7999 Parser::TryBlocks* Parser::PopTryBlock() { |
| 7991 TryBlocks* innermost_try_block = try_blocks_list_; | 8000 TryBlocks* innermost_try_block = try_blocks_list_; |
| 7992 try_blocks_list_ = try_blocks_list_->outer_try_block(); | 8001 try_blocks_list_ = try_blocks_list_->outer_try_block(); |
| 7993 return innermost_try_block; | 8002 return innermost_try_block; |
| 7994 } | 8003 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8052 GrowableArray<SequenceNode*> catch_blocks; | 8061 GrowableArray<SequenceNode*> catch_blocks; |
| 8053 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { | 8062 while ((CurrentToken() == Token::kCATCH) || IsLiteral("on")) { |
| 8054 // Open a block that contains the if or an unconditional body. It's | 8063 // Open a block that contains the if or an unconditional body. It's |
| 8055 // closed in the loop that builds the if-then-else nest. | 8064 // closed in the loop that builds the if-then-else nest. |
| 8056 OpenBlock(); | 8065 OpenBlock(); |
| 8057 const intptr_t catch_pos = TokenPos(); | 8066 const intptr_t catch_pos = TokenPos(); |
| 8058 CatchParamDesc exception_param; | 8067 CatchParamDesc exception_param; |
| 8059 CatchParamDesc stack_trace_param; | 8068 CatchParamDesc stack_trace_param; |
| 8060 if (IsLiteral("on")) { | 8069 if (IsLiteral("on")) { |
| 8061 ConsumeToken(); | 8070 ConsumeToken(); |
| 8062 exception_param.type = &AbstractType::ZoneHandle(I, | 8071 exception_param.type = &AbstractType::ZoneHandle(Z, |
| 8063 ParseType(ClassFinalizer::kCanonicalize)); | 8072 ParseType(ClassFinalizer::kCanonicalize)); |
| 8064 } else { | 8073 } else { |
| 8065 exception_param.type = &AbstractType::ZoneHandle(I, Type::DynamicType()); | 8074 exception_param.type = &AbstractType::ZoneHandle(Z, Type::DynamicType()); |
| 8066 } | 8075 } |
| 8067 if (CurrentToken() == Token::kCATCH) { | 8076 if (CurrentToken() == Token::kCATCH) { |
| 8068 ConsumeToken(); // Consume the 'catch'. | 8077 ConsumeToken(); // Consume the 'catch'. |
| 8069 ExpectToken(Token::kLPAREN); | 8078 ExpectToken(Token::kLPAREN); |
| 8070 exception_param.token_pos = TokenPos(); | 8079 exception_param.token_pos = TokenPos(); |
| 8071 exception_param.name = ExpectIdentifier("identifier expected"); | 8080 exception_param.name = ExpectIdentifier("identifier expected"); |
| 8072 if (CurrentToken() == Token::kCOMMA) { | 8081 if (CurrentToken() == Token::kCOMMA) { |
| 8073 ConsumeToken(); | 8082 ConsumeToken(); |
| 8074 // TODO(hausner): Make implicit type be StackTrace, not dynamic. | 8083 // TODO(hausner): Make implicit type be StackTrace, not dynamic. |
| 8075 stack_trace_param.type = | 8084 stack_trace_param.type = |
| 8076 &AbstractType::ZoneHandle(I, Type::DynamicType()); | 8085 &AbstractType::ZoneHandle(Z, Type::DynamicType()); |
| 8077 stack_trace_param.token_pos = TokenPos(); | 8086 stack_trace_param.token_pos = TokenPos(); |
| 8078 stack_trace_param.name = ExpectIdentifier("identifier expected"); | 8087 stack_trace_param.name = ExpectIdentifier("identifier expected"); |
| 8079 } | 8088 } |
| 8080 ExpectToken(Token::kRPAREN); | 8089 ExpectToken(Token::kRPAREN); |
| 8081 } | 8090 } |
| 8082 | 8091 |
| 8083 // Create a block containing the catch clause parameters and the | 8092 // Create a block containing the catch clause parameters and the |
| 8084 // following code: | 8093 // following code: |
| 8085 // 1) Store exception object and stack trace object into user-defined | 8094 // 1) Store exception object and stack trace object into user-defined |
| 8086 // variables (as needed). | 8095 // variables (as needed). |
| 8087 // 2) Nested block with source code from catch clause block. | 8096 // 2) Nested block with source code from catch clause block. |
| 8088 OpenBlock(); | 8097 OpenBlock(); |
| 8089 AddCatchParamsToScope(&exception_param, &stack_trace_param, | 8098 AddCatchParamsToScope(&exception_param, &stack_trace_param, |
| 8090 current_block_->scope); | 8099 current_block_->scope); |
| 8091 | 8100 |
| 8092 if (exception_param.var != NULL) { | 8101 if (exception_param.var != NULL) { |
| 8093 // Generate code to load the exception object (:exception_var) into | 8102 // Generate code to load the exception object (:exception_var) into |
| 8094 // the exception variable specified in this block. | 8103 // the exception variable specified in this block. |
| 8095 ASSERT(exception_var != NULL); | 8104 ASSERT(exception_var != NULL); |
| 8096 current_block_->statements->Add(new(I) StoreLocalNode( | 8105 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 8097 catch_pos, exception_param.var, new(I) LoadLocalNode( | 8106 catch_pos, exception_param.var, new(Z) LoadLocalNode( |
| 8098 catch_pos, exception_var))); | 8107 catch_pos, exception_var))); |
| 8099 } | 8108 } |
| 8100 if (stack_trace_param.var != NULL) { | 8109 if (stack_trace_param.var != NULL) { |
| 8101 // A stack trace variable is specified in this block, so generate code | 8110 // A stack trace variable is specified in this block, so generate code |
| 8102 // to load the stack trace object (:stack_trace_var) into the stack | 8111 // to load the stack trace object (:stack_trace_var) into the stack |
| 8103 // trace variable specified in this block. | 8112 // trace variable specified in this block. |
| 8104 *needs_stack_trace = true; | 8113 *needs_stack_trace = true; |
| 8105 ArgumentListNode* no_args = new(I) ArgumentListNode(catch_pos); | 8114 ArgumentListNode* no_args = new(Z) ArgumentListNode(catch_pos); |
| 8106 ASSERT(stack_trace_var != NULL); | 8115 ASSERT(stack_trace_var != NULL); |
| 8107 current_block_->statements->Add(new(I) StoreLocalNode( | 8116 current_block_->statements->Add(new(Z) StoreLocalNode( |
| 8108 catch_pos, stack_trace_param.var, new(I) LoadLocalNode( | 8117 catch_pos, stack_trace_param.var, new(Z) LoadLocalNode( |
| 8109 catch_pos, stack_trace_var))); | 8118 catch_pos, stack_trace_var))); |
| 8110 current_block_->statements->Add(new(I) InstanceCallNode( | 8119 current_block_->statements->Add(new(Z) InstanceCallNode( |
| 8111 catch_pos, | 8120 catch_pos, |
| 8112 new(I) LoadLocalNode(catch_pos, stack_trace_param.var), | 8121 new(Z) LoadLocalNode(catch_pos, stack_trace_param.var), |
| 8113 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), | 8122 Library::PrivateCoreLibName(Symbols::_setupFullStackTrace()), |
| 8114 no_args)); | 8123 no_args)); |
| 8115 } | 8124 } |
| 8116 | 8125 |
| 8117 // Add nested block with user-defined code. This blocks allows | 8126 // Add nested block with user-defined code. This blocks allows |
| 8118 // declarations in the body to shadow the catch parameters. | 8127 // declarations in the body to shadow the catch parameters. |
| 8119 CheckToken(Token::kLBRACE); | 8128 CheckToken(Token::kLBRACE); |
| 8120 | 8129 |
| 8121 // In case of async closures we need to restore the saved try index of an | 8130 // In case of async closures we need to restore the saved try index of an |
| 8122 // outer try block (if it exists). | 8131 // outer try block (if it exists). |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 8142 catch_blocks.Add(CloseBlock()); | 8151 catch_blocks.Add(CloseBlock()); |
| 8143 | 8152 |
| 8144 const bool is_bad_type = | 8153 const bool is_bad_type = |
| 8145 exception_param.type->IsMalformed() || | 8154 exception_param.type->IsMalformed() || |
| 8146 exception_param.type->IsMalbounded(); | 8155 exception_param.type->IsMalbounded(); |
| 8147 if (exception_param.type->IsDynamicType() || is_bad_type) { | 8156 if (exception_param.type->IsDynamicType() || is_bad_type) { |
| 8148 // There is no exception type or else it is malformed or malbounded. | 8157 // There is no exception type or else it is malformed or malbounded. |
| 8149 // In the first case, unconditionally execute the catch body. In the | 8158 // In the first case, unconditionally execute the catch body. In the |
| 8150 // second case, unconditionally throw. | 8159 // second case, unconditionally throw. |
| 8151 generic_catch_seen = true; | 8160 generic_catch_seen = true; |
| 8152 type_tests.Add(new(I) LiteralNode(catch_pos, Bool::True())); | 8161 type_tests.Add(new(Z) LiteralNode(catch_pos, Bool::True())); |
| 8153 if (is_bad_type) { | 8162 if (is_bad_type) { |
| 8154 // Replace the body with one that throws. | 8163 // Replace the body with one that throws. |
| 8155 SequenceNode* block = new(I) SequenceNode(catch_pos, NULL); | 8164 SequenceNode* block = new(Z) SequenceNode(catch_pos, NULL); |
| 8156 block->Add(ThrowTypeError(catch_pos, *exception_param.type)); | 8165 block->Add(ThrowTypeError(catch_pos, *exception_param.type)); |
| 8157 catch_blocks.Last() = block; | 8166 catch_blocks.Last() = block; |
| 8158 } | 8167 } |
| 8159 // This catch clause will handle all exceptions. We can safely forget | 8168 // This catch clause will handle all exceptions. We can safely forget |
| 8160 // all previous catch clause types. | 8169 // all previous catch clause types. |
| 8161 handler_types.SetLength(0); | 8170 handler_types.SetLength(0); |
| 8162 handler_types.Add(*exception_param.type); | 8171 handler_types.Add(*exception_param.type); |
| 8163 } else { | 8172 } else { |
| 8164 // Has a type specification that is not malformed or malbounded. Now | 8173 // Has a type specification that is not malformed or malbounded. Now |
| 8165 // form an 'if type check' to guard the catch handler code. | 8174 // form an 'if type check' to guard the catch handler code. |
| 8166 if (!exception_param.type->IsInstantiated() && | 8175 if (!exception_param.type->IsInstantiated() && |
| 8167 (current_block_->scope->function_level() > 0)) { | 8176 (current_block_->scope->function_level() > 0)) { |
| 8168 // Make sure that the instantiator is captured. | 8177 // Make sure that the instantiator is captured. |
| 8169 CaptureInstantiator(); | 8178 CaptureInstantiator(); |
| 8170 } | 8179 } |
| 8171 TypeNode* exception_type = new(I) TypeNode( | 8180 TypeNode* exception_type = new(Z) TypeNode( |
| 8172 catch_pos, *exception_param.type); | 8181 catch_pos, *exception_param.type); |
| 8173 AstNode* exception_value = new(I) LoadLocalNode( | 8182 AstNode* exception_value = new(Z) LoadLocalNode( |
| 8174 catch_pos, exception_var); | 8183 catch_pos, exception_var); |
| 8175 if (!exception_type->type().IsInstantiated()) { | 8184 if (!exception_type->type().IsInstantiated()) { |
| 8176 EnsureExpressionTemp(); | 8185 EnsureExpressionTemp(); |
| 8177 } | 8186 } |
| 8178 type_tests.Add(new(I) ComparisonNode( | 8187 type_tests.Add(new(Z) ComparisonNode( |
| 8179 catch_pos, Token::kIS, exception_value, exception_type)); | 8188 catch_pos, Token::kIS, exception_value, exception_type)); |
| 8180 | 8189 |
| 8181 // Do not add uninstantiated types (e.g. type parameter T or generic | 8190 // Do not add uninstantiated types (e.g. type parameter T or generic |
| 8182 // type List<T>), since the debugger won't be able to instantiate it | 8191 // type List<T>), since the debugger won't be able to instantiate it |
| 8183 // when walking the stack. | 8192 // when walking the stack. |
| 8184 // | 8193 // |
| 8185 // This means that the debugger is not able to determine whether an | 8194 // This means that the debugger is not able to determine whether an |
| 8186 // exception is caught if the catch clause uses generic types. It | 8195 // exception is caught if the catch clause uses generic types. It |
| 8187 // will report the exception as uncaught when in fact it might be | 8196 // will report the exception as uncaught when in fact it might be |
| 8188 // caught and handled when we unwind the stack. | 8197 // caught and handled when we unwind the stack. |
| 8189 if (!generic_catch_seen && exception_param.type->IsInstantiated()) { | 8198 if (!generic_catch_seen && exception_param.type->IsInstantiated()) { |
| 8190 handler_types.Add(*exception_param.type); | 8199 handler_types.Add(*exception_param.type); |
| 8191 } | 8200 } |
| 8192 } | 8201 } |
| 8193 | 8202 |
| 8194 ASSERT(type_tests.length() == catch_blocks.length()); | 8203 ASSERT(type_tests.length() == catch_blocks.length()); |
| 8195 } | 8204 } |
| 8196 | 8205 |
| 8197 // Build the if/then/else nest from the inside out. Keep the AST simple | 8206 // Build the if/then/else nest from the inside out. Keep the AST simple |
| 8198 // for the case of a single generic catch clause. The initial value of | 8207 // for the case of a single generic catch clause. The initial value of |
| 8199 // current is the last (innermost) else block if there were any catch | 8208 // current is the last (innermost) else block if there were any catch |
| 8200 // clauses. | 8209 // clauses. |
| 8201 SequenceNode* current = NULL; | 8210 SequenceNode* current = NULL; |
| 8202 if (!generic_catch_seen) { | 8211 if (!generic_catch_seen) { |
| 8203 // There isn't a generic catch clause so create a clause body that | 8212 // There isn't a generic catch clause so create a clause body that |
| 8204 // rethrows the exception. This includes the case that there were no | 8213 // rethrows the exception. This includes the case that there were no |
| 8205 // catch clauses. | 8214 // catch clauses. |
| 8206 current = new(I) SequenceNode(handler_pos, NULL); | 8215 current = new(Z) SequenceNode(handler_pos, NULL); |
| 8207 current->Add(new(I) ThrowNode( | 8216 current->Add(new(Z) ThrowNode( |
| 8208 handler_pos, | 8217 handler_pos, |
| 8209 new(I) LoadLocalNode(handler_pos, exception_var), | 8218 new(Z) LoadLocalNode(handler_pos, exception_var), |
| 8210 new(I) LoadLocalNode(handler_pos, stack_trace_var))); | 8219 new(Z) LoadLocalNode(handler_pos, stack_trace_var))); |
| 8211 } else if (type_tests.Last()->IsLiteralNode()) { | 8220 } else if (type_tests.Last()->IsLiteralNode()) { |
| 8212 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == | 8221 ASSERT(type_tests.Last()->AsLiteralNode()->literal().raw() == |
| 8213 Bool::True().raw()); | 8222 Bool::True().raw()); |
| 8214 // The last body is entered unconditionally. Start building the | 8223 // The last body is entered unconditionally. Start building the |
| 8215 // if/then/else nest with that body as the innermost else block. | 8224 // if/then/else nest with that body as the innermost else block. |
| 8216 // Note that it is nested inside an extra block which we opened | 8225 // Note that it is nested inside an extra block which we opened |
| 8217 // before we knew the body was entered unconditionally. | 8226 // before we knew the body was entered unconditionally. |
| 8218 type_tests.RemoveLast(); | 8227 type_tests.RemoveLast(); |
| 8219 current_block_->statements->Add(catch_blocks.RemoveLast()); | 8228 current_block_->statements->Add(catch_blocks.RemoveLast()); |
| 8220 current = CloseBlock(); | 8229 current = CloseBlock(); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 8239 // parameters, and the general try block. | 8248 // parameters, and the general try block. |
| 8240 RestoreSavedTryContext( | 8249 RestoreSavedTryContext( |
| 8241 current_block_->scope->parent()->parent(), | 8250 current_block_->scope->parent()->parent(), |
| 8242 try_blocks_list_->outer_try_block()->try_index(), | 8251 try_blocks_list_->outer_try_block()->try_index(), |
| 8243 current_block_->statements); | 8252 current_block_->statements); |
| 8244 } else { | 8253 } else { |
| 8245 parsed_function()->reset_saved_try_ctx_vars(); | 8254 parsed_function()->reset_saved_try_ctx_vars(); |
| 8246 } | 8255 } |
| 8247 } | 8256 } |
| 8248 | 8257 |
| 8249 current_block_->statements->Add(new(I) IfNode( | 8258 current_block_->statements->Add(new(Z) IfNode( |
| 8250 type_test->token_pos(), type_test, catch_block, current)); | 8259 type_test->token_pos(), type_test, catch_block, current)); |
| 8251 current = CloseBlock(); | 8260 current = CloseBlock(); |
| 8252 } | 8261 } |
| 8253 return current; | 8262 return current; |
| 8254 } | 8263 } |
| 8255 | 8264 |
| 8256 | 8265 |
| 8257 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { | 8266 void Parser::SetupSavedTryContext(LocalVariable* saved_try_context) { |
| 8258 const String& async_saved_try_ctx_name = | 8267 const String& async_saved_try_ctx_name = |
| 8259 BuildAsyncSavedTryContextName(I, last_used_try_index_ - 1); | 8268 BuildAsyncSavedTryContextName(Z, last_used_try_index_ - 1); |
| 8260 LocalVariable* async_saved_try_ctx = new (I) LocalVariable( | 8269 LocalVariable* async_saved_try_ctx = new (Z) LocalVariable( |
| 8261 Scanner::kNoSourcePos, | 8270 Scanner::kNoSourcePos, |
| 8262 async_saved_try_ctx_name, | 8271 async_saved_try_ctx_name, |
| 8263 Type::ZoneHandle(I, Type::DynamicType())); | 8272 Type::ZoneHandle(Z, Type::DynamicType())); |
| 8264 async_temp_scope_->AddVariable(async_saved_try_ctx); | 8273 async_temp_scope_->AddVariable(async_saved_try_ctx); |
| 8265 async_saved_try_ctx->set_is_captured(); | 8274 async_saved_try_ctx->set_is_captured(); |
| 8266 async_saved_try_ctx = current_block_->scope->LookupVariable( | 8275 async_saved_try_ctx = current_block_->scope->LookupVariable( |
| 8267 async_saved_try_ctx_name, false); | 8276 async_saved_try_ctx_name, false); |
| 8268 ASSERT(async_saved_try_ctx != NULL); | 8277 ASSERT(async_saved_try_ctx != NULL); |
| 8269 ASSERT(saved_try_context != NULL); | 8278 ASSERT(saved_try_context != NULL); |
| 8270 current_block_->statements->Add(new (I) StoreLocalNode( | 8279 current_block_->statements->Add(new (Z) StoreLocalNode( |
| 8271 Scanner::kNoSourcePos, async_saved_try_ctx, new (I) LoadLocalNode( | 8280 Scanner::kNoSourcePos, async_saved_try_ctx, new (Z) LoadLocalNode( |
| 8272 Scanner::kNoSourcePos, saved_try_context))); | 8281 Scanner::kNoSourcePos, saved_try_context))); |
| 8273 parsed_function()->set_saved_try_ctx(saved_try_context); | 8282 parsed_function()->set_saved_try_ctx(saved_try_context); |
| 8274 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); | 8283 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); |
| 8275 } | 8284 } |
| 8276 | 8285 |
| 8277 | 8286 |
| 8278 // Set up the currently relevant :saved_try_context_var on the stack: | 8287 // Set up the currently relevant :saved_try_context_var on the stack: |
| 8279 // * Try blocks: Set the context variable for this try block. | 8288 // * Try blocks: Set the context variable for this try block. |
| 8280 // * Catch/finally blocks: Set the context variable for any outer try block (if | 8289 // * Catch/finally blocks: Set the context variable for any outer try block (if |
| 8281 // existent). | 8290 // existent). |
| 8282 // | 8291 // |
| 8283 // Also save the captured variable and the stack variable to be able to set | 8292 // Also save the captured variable and the stack variable to be able to set |
| 8284 // it after a function continues execution (await). | 8293 // it after a function continues execution (await). |
| 8285 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, | 8294 void Parser::RestoreSavedTryContext(LocalScope* saved_try_context_scope, |
| 8286 int16_t try_index, | 8295 int16_t try_index, |
| 8287 SequenceNode* target) { | 8296 SequenceNode* target) { |
| 8288 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( | 8297 LocalVariable* saved_try_ctx = saved_try_context_scope->LookupVariable( |
| 8289 Symbols::SavedTryContextVar(), false); | 8298 Symbols::SavedTryContextVar(), false); |
| 8290 ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured()); | 8299 ASSERT((saved_try_ctx != NULL) && !saved_try_ctx->is_captured()); |
| 8291 const String& async_saved_try_ctx_name = | 8300 const String& async_saved_try_ctx_name = |
| 8292 BuildAsyncSavedTryContextName(I, try_index); | 8301 BuildAsyncSavedTryContextName(Z, try_index); |
| 8293 LocalVariable* async_saved_try_ctx = | 8302 LocalVariable* async_saved_try_ctx = |
| 8294 target->scope()->LookupVariable(async_saved_try_ctx_name, false); | 8303 target->scope()->LookupVariable(async_saved_try_ctx_name, false); |
| 8295 ASSERT(async_saved_try_ctx != NULL); | 8304 ASSERT(async_saved_try_ctx != NULL); |
| 8296 ASSERT(async_saved_try_ctx->is_captured()); | 8305 ASSERT(async_saved_try_ctx->is_captured()); |
| 8297 target->Add(new (I) StoreLocalNode( | 8306 target->Add(new (Z) StoreLocalNode( |
| 8298 Scanner::kNoSourcePos, | 8307 Scanner::kNoSourcePos, |
| 8299 saved_try_ctx, | 8308 saved_try_ctx, |
| 8300 new (I) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx))); | 8309 new (Z) LoadLocalNode(Scanner::kNoSourcePos, async_saved_try_ctx))); |
| 8301 | 8310 |
| 8302 parsed_function()->set_saved_try_ctx(saved_try_ctx); | 8311 parsed_function()->set_saved_try_ctx(saved_try_ctx); |
| 8303 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); | 8312 parsed_function()->set_async_saved_try_ctx_name(async_saved_try_ctx_name); |
| 8304 } | 8313 } |
| 8305 | 8314 |
| 8306 | 8315 |
| 8307 AstNode* Parser::ParseTryStatement(String* label_name) { | 8316 AstNode* Parser::ParseTryStatement(String* label_name) { |
| 8308 TRACE_PARSER("ParseTryStatement"); | 8317 TRACE_PARSER("ParseTryStatement"); |
| 8309 | 8318 |
| 8310 // We create three variables for exceptions here: | 8319 // We create three variables for exceptions here: |
| 8311 // ':saved_try_context_var' - Used to save the context before the start of | 8320 // ':saved_try_context_var' - Used to save the context before the start of |
| 8312 // the try block. The context register is | 8321 // the try block. The context register is |
| 8313 // restored from this variable before | 8322 // restored from this variable before |
| 8314 // processing the catch block handler. | 8323 // processing the catch block handler. |
| 8315 // ':exception_var' - Used to save the current exception object that was | 8324 // ':exception_var' - Used to save the current exception object that was |
| 8316 // thrown. | 8325 // thrown. |
| 8317 // ':stack_trace_var' - Used to save the current stack trace object which | 8326 // ':stack_trace_var' - Used to save the current stack trace object which |
| 8318 // the stack trace was copied into when an exception | 8327 // the stack trace was copied into when an exception |
| 8319 // was thrown. | 8328 // was thrown. |
| 8320 // :exception_var and :stack_trace_var get set with the exception object | 8329 // :exception_var and :stack_trace_var get set with the exception object |
| 8321 // and the stack trace object when an exception is thrown. These three | 8330 // and the stack trace object when an exception is thrown. These three |
| 8322 // implicit variables can never be captured. | 8331 // implicit variables can never be captured. |
| 8323 LocalVariable* context_var = | 8332 LocalVariable* context_var = |
| 8324 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); | 8333 current_block_->scope->LocalLookupVariable(Symbols::SavedTryContextVar()); |
| 8325 if (context_var == NULL) { | 8334 if (context_var == NULL) { |
| 8326 context_var = new(I) LocalVariable( | 8335 context_var = new(Z) LocalVariable( |
| 8327 TokenPos(), | 8336 TokenPos(), |
| 8328 Symbols::SavedTryContextVar(), | 8337 Symbols::SavedTryContextVar(), |
| 8329 Type::ZoneHandle(I, Type::DynamicType())); | 8338 Type::ZoneHandle(Z, Type::DynamicType())); |
| 8330 current_block_->scope->AddVariable(context_var); | 8339 current_block_->scope->AddVariable(context_var); |
| 8331 } | 8340 } |
| 8332 LocalVariable* exception_var = | 8341 LocalVariable* exception_var = |
| 8333 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); | 8342 current_block_->scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 8334 if (exception_var == NULL) { | 8343 if (exception_var == NULL) { |
| 8335 exception_var = new(I) LocalVariable( | 8344 exception_var = new(Z) LocalVariable( |
| 8336 TokenPos(), | 8345 TokenPos(), |
| 8337 Symbols::ExceptionVar(), | 8346 Symbols::ExceptionVar(), |
| 8338 Type::ZoneHandle(I, Type::DynamicType())); | 8347 Type::ZoneHandle(Z, Type::DynamicType())); |
| 8339 current_block_->scope->AddVariable(exception_var); | 8348 current_block_->scope->AddVariable(exception_var); |
| 8340 } | 8349 } |
| 8341 LocalVariable* stack_trace_var = | 8350 LocalVariable* stack_trace_var = |
| 8342 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); | 8351 current_block_->scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 8343 if (stack_trace_var == NULL) { | 8352 if (stack_trace_var == NULL) { |
| 8344 stack_trace_var = new(I) LocalVariable( | 8353 stack_trace_var = new(Z) LocalVariable( |
| 8345 TokenPos(), | 8354 TokenPos(), |
| 8346 Symbols::StackTraceVar(), | 8355 Symbols::StackTraceVar(), |
| 8347 Type::ZoneHandle(I, Type::DynamicType())); | 8356 Type::ZoneHandle(Z, Type::DynamicType())); |
| 8348 current_block_->scope->AddVariable(stack_trace_var); | 8357 current_block_->scope->AddVariable(stack_trace_var); |
| 8349 } | 8358 } |
| 8350 | 8359 |
| 8351 const intptr_t try_pos = TokenPos(); | 8360 const intptr_t try_pos = TokenPos(); |
| 8352 ConsumeToken(); // Consume the 'try'. | 8361 ConsumeToken(); // Consume the 'try'. |
| 8353 | 8362 |
| 8354 SourceLabel* try_label = NULL; | 8363 SourceLabel* try_label = NULL; |
| 8355 if (label_name != NULL) { | 8364 if (label_name != NULL) { |
| 8356 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); | 8365 try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement); |
| 8357 OpenBlock(); | 8366 OpenBlock(); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 8374 | 8383 |
| 8375 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && | 8384 if ((CurrentToken() != Token::kCATCH) && !IsLiteral("on") && |
| 8376 (CurrentToken() != Token::kFINALLY)) { | 8385 (CurrentToken() != Token::kFINALLY)) { |
| 8377 ReportError("catch or finally clause expected"); | 8386 ReportError("catch or finally clause expected"); |
| 8378 } | 8387 } |
| 8379 | 8388 |
| 8380 // Now parse the 'catch' blocks if any. | 8389 // Now parse the 'catch' blocks if any. |
| 8381 try_blocks_list_->enter_catch(); | 8390 try_blocks_list_->enter_catch(); |
| 8382 const intptr_t handler_pos = TokenPos(); | 8391 const intptr_t handler_pos = TokenPos(); |
| 8383 const GrowableObjectArray& handler_types = | 8392 const GrowableObjectArray& handler_types = |
| 8384 GrowableObjectArray::Handle(I, GrowableObjectArray::New()); | 8393 GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); |
| 8385 bool needs_stack_trace = false; | 8394 bool needs_stack_trace = false; |
| 8386 SequenceNode* catch_handler_list = | 8395 SequenceNode* catch_handler_list = |
| 8387 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, | 8396 ParseCatchClauses(handler_pos, exception_var, stack_trace_var, |
| 8388 handler_types, &needs_stack_trace); | 8397 handler_types, &needs_stack_trace); |
| 8389 | 8398 |
| 8390 TryBlocks* inner_try_block = PopTryBlock(); | 8399 TryBlocks* inner_try_block = PopTryBlock(); |
| 8391 const intptr_t try_index = inner_try_block->try_index(); | 8400 const intptr_t try_index = inner_try_block->try_index(); |
| 8392 TryBlocks* outer_try_block = try_blocks_list_; | 8401 TryBlocks* outer_try_block = try_blocks_list_; |
| 8393 const intptr_t outer_try_index = (outer_try_block != NULL) | 8402 const intptr_t outer_try_index = (outer_try_block != NULL) |
| 8394 ? outer_try_block->try_index() | 8403 ? outer_try_block->try_index() |
| 8395 : CatchClauseNode::kInvalidTryIndex; | 8404 : CatchClauseNode::kInvalidTryIndex; |
| 8396 | 8405 |
| 8397 // Finally parse the 'finally' block. | 8406 // Finally parse the 'finally' block. |
| 8398 SequenceNode* finally_block = NULL; | 8407 SequenceNode* finally_block = NULL; |
| 8399 if (CurrentToken() == Token::kFINALLY) { | 8408 if (CurrentToken() == Token::kFINALLY) { |
| 8400 ConsumeToken(); // Consume the 'finally'. | 8409 ConsumeToken(); // Consume the 'finally'. |
| 8401 const intptr_t finally_pos = TokenPos(); | 8410 const intptr_t finally_pos = TokenPos(); |
| 8402 // Add the finally block to the exit points recorded so far. | 8411 // Add the finally block to the exit points recorded so far. |
| 8403 intptr_t node_index = 0; | 8412 intptr_t node_index = 0; |
| 8404 AstNode* node_to_inline = | 8413 AstNode* node_to_inline = |
| 8405 inner_try_block->GetNodeToInlineFinally(node_index); | 8414 inner_try_block->GetNodeToInlineFinally(node_index); |
| 8406 while (node_to_inline != NULL) { | 8415 while (node_to_inline != NULL) { |
| 8407 finally_block = ParseFinallyBlock(); | 8416 finally_block = ParseFinallyBlock(); |
| 8408 InlinedFinallyNode* node = new(I) InlinedFinallyNode(finally_pos, | 8417 InlinedFinallyNode* node = new(Z) InlinedFinallyNode(finally_pos, |
| 8409 finally_block, | 8418 finally_block, |
| 8410 context_var, | 8419 context_var, |
| 8411 outer_try_index); | 8420 outer_try_index); |
| 8412 AddFinallyBlockToNode(node_to_inline, node); | 8421 AddFinallyBlockToNode(node_to_inline, node); |
| 8413 node_index += 1; | 8422 node_index += 1; |
| 8414 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); | 8423 node_to_inline = inner_try_block->GetNodeToInlineFinally(node_index); |
| 8415 tokens_iterator_.SetCurrentPosition(finally_pos); | 8424 tokens_iterator_.SetCurrentPosition(finally_pos); |
| 8416 } | 8425 } |
| 8417 finally_block = ParseFinallyBlock(); | 8426 finally_block = ParseFinallyBlock(); |
| 8418 } | 8427 } |
| 8419 | 8428 |
| 8420 CatchClauseNode* catch_clause = new(I) CatchClauseNode( | 8429 CatchClauseNode* catch_clause = new(Z) CatchClauseNode( |
| 8421 handler_pos, | 8430 handler_pos, |
| 8422 catch_handler_list, | 8431 catch_handler_list, |
| 8423 Array::ZoneHandle(I, Array::MakeArray(handler_types)), | 8432 Array::ZoneHandle(Z, Array::MakeArray(handler_types)), |
| 8424 context_var, | 8433 context_var, |
| 8425 exception_var, | 8434 exception_var, |
| 8426 stack_trace_var, | 8435 stack_trace_var, |
| 8427 (finally_block != NULL) ? | 8436 (finally_block != NULL) ? |
| 8428 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, | 8437 AllocateTryIndex() : CatchClauseNode::kInvalidTryIndex, |
| 8429 needs_stack_trace); | 8438 needs_stack_trace); |
| 8430 | 8439 |
| 8431 // Now create the try/catch ast node and return it. If there is a label | 8440 // Now create the try/catch ast node and return it. If there is a label |
| 8432 // on the try/catch, close the block that's embedding the try statement | 8441 // on the try/catch, close the block that's embedding the try statement |
| 8433 // and attach the label to it. | 8442 // and attach the label to it. |
| 8434 AstNode* try_catch_node = new(I) TryCatchNode( | 8443 AstNode* try_catch_node = new(Z) TryCatchNode( |
| 8435 try_pos, try_block, context_var, catch_clause, finally_block, try_index); | 8444 try_pos, try_block, context_var, catch_clause, finally_block, try_index); |
| 8436 | 8445 |
| 8437 if (try_label != NULL) { | 8446 if (try_label != NULL) { |
| 8438 current_block_->statements->Add(try_catch_node); | 8447 current_block_->statements->Add(try_catch_node); |
| 8439 SequenceNode* sequence = CloseBlock(); | 8448 SequenceNode* sequence = CloseBlock(); |
| 8440 sequence->set_label(try_label); | 8449 sequence->set_label(try_label); |
| 8441 try_catch_node = sequence; | 8450 try_catch_node = sequence; |
| 8442 } | 8451 } |
| 8443 | 8452 |
| 8444 return try_catch_node; | 8453 return try_catch_node; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 8467 } | 8476 } |
| 8468 target = current_block_->scope->LookupLabel(target_name); | 8477 target = current_block_->scope->LookupLabel(target_name); |
| 8469 if (target == NULL && jump_kind == Token::kCONTINUE) { | 8478 if (target == NULL && jump_kind == Token::kCONTINUE) { |
| 8470 // Either a reference to a non-existent label, or a forward reference | 8479 // Either a reference to a non-existent label, or a forward reference |
| 8471 // to a case label that we haven't seen yet. If we are inside a switch | 8480 // to a case label that we haven't seen yet. If we are inside a switch |
| 8472 // statement, create a "forward reference" label in the scope of | 8481 // statement, create a "forward reference" label in the scope of |
| 8473 // the switch statement. | 8482 // the switch statement. |
| 8474 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); | 8483 LocalScope* switch_scope = current_block_->scope->LookupSwitchScope(); |
| 8475 if (switch_scope != NULL) { | 8484 if (switch_scope != NULL) { |
| 8476 // We found a switch scope. Enter a forward reference to the label. | 8485 // We found a switch scope. Enter a forward reference to the label. |
| 8477 target = new(I) SourceLabel( | 8486 target = new(Z) SourceLabel( |
| 8478 TokenPos(), target_name, SourceLabel::kForward); | 8487 TokenPos(), target_name, SourceLabel::kForward); |
| 8479 switch_scope->AddLabel(target); | 8488 switch_scope->AddLabel(target); |
| 8480 } | 8489 } |
| 8481 } | 8490 } |
| 8482 if (target == NULL) { | 8491 if (target == NULL) { |
| 8483 ReportError(jump_pos, "label '%s' not found", target_name.ToCString()); | 8492 ReportError(jump_pos, "label '%s' not found", target_name.ToCString()); |
| 8484 } | 8493 } |
| 8485 } else { | 8494 } else { |
| 8486 target = current_block_->scope->LookupInnermostLabel(jump_kind); | 8495 target = current_block_->scope->LookupInnermostLabel(jump_kind); |
| 8487 if (target == NULL) { | 8496 if (target == NULL) { |
| 8488 ReportError(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); | 8497 ReportError(jump_pos, "'%s' is illegal here", Token::Str(jump_kind)); |
| 8489 } | 8498 } |
| 8490 } | 8499 } |
| 8491 ASSERT(target != NULL); | 8500 ASSERT(target != NULL); |
| 8492 if (jump_kind == Token::kCONTINUE) { | 8501 if (jump_kind == Token::kCONTINUE) { |
| 8493 if (target->kind() == SourceLabel::kSwitch) { | 8502 if (target->kind() == SourceLabel::kSwitch) { |
| 8494 ReportError(jump_pos, "'continue' jump to switch statement is illegal"); | 8503 ReportError(jump_pos, "'continue' jump to switch statement is illegal"); |
| 8495 } else if (target->kind() == SourceLabel::kStatement) { | 8504 } else if (target->kind() == SourceLabel::kStatement) { |
| 8496 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", | 8505 ReportError(jump_pos, "'continue' jump to label '%s' is illegal", |
| 8497 target->name().ToCString()); | 8506 target->name().ToCString()); |
| 8498 } | 8507 } |
| 8499 } | 8508 } |
| 8500 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { | 8509 if (jump_kind == Token::kBREAK && target->kind() == SourceLabel::kCase) { |
| 8501 ReportError(jump_pos, "'break' to case clause label is illegal"); | 8510 ReportError(jump_pos, "'break' to case clause label is illegal"); |
| 8502 } | 8511 } |
| 8503 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 8512 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 8504 ReportError(jump_pos, "'%s' target must be in same function context", | 8513 ReportError(jump_pos, "'%s' target must be in same function context", |
| 8505 Token::Str(jump_kind)); | 8514 Token::Str(jump_kind)); |
| 8506 } | 8515 } |
| 8507 return new(I) JumpNode(jump_pos, jump_kind, target); | 8516 return new(Z) JumpNode(jump_pos, jump_kind, target); |
| 8508 } | 8517 } |
| 8509 | 8518 |
| 8510 | 8519 |
| 8511 AstNode* Parser::ParseStatement() { | 8520 AstNode* Parser::ParseStatement() { |
| 8512 TRACE_PARSER("ParseStatement"); | 8521 TRACE_PARSER("ParseStatement"); |
| 8513 AstNode* statement = NULL; | 8522 AstNode* statement = NULL; |
| 8514 intptr_t label_pos = 0; | 8523 intptr_t label_pos = 0; |
| 8515 String* label_name = NULL; | 8524 String* label_name = NULL; |
| 8516 if (IsIdentifier()) { | 8525 if (IsIdentifier()) { |
| 8517 if (LookaheadToken(1) == Token::kCOLON) { | 8526 if (LookaheadToken(1) == Token::kCOLON) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 8541 } else if (token == Token::kRETURN) { | 8550 } else if (token == Token::kRETURN) { |
| 8542 const intptr_t return_pos = TokenPos(); | 8551 const intptr_t return_pos = TokenPos(); |
| 8543 ConsumeToken(); | 8552 ConsumeToken(); |
| 8544 if (CurrentToken() != Token::kSEMICOLON) { | 8553 if (CurrentToken() != Token::kSEMICOLON) { |
| 8545 if (current_function().IsConstructor() && | 8554 if (current_function().IsConstructor() && |
| 8546 (current_block_->scope->function_level() == 0)) { | 8555 (current_block_->scope->function_level() == 0)) { |
| 8547 ReportError(return_pos, | 8556 ReportError(return_pos, |
| 8548 "return of a value not allowed in constructors"); | 8557 "return of a value not allowed in constructors"); |
| 8549 } | 8558 } |
| 8550 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8559 AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8551 statement = new(I) ReturnNode(statement_pos, expr); | 8560 statement = new(Z) ReturnNode(statement_pos, expr); |
| 8552 } else { | 8561 } else { |
| 8553 statement = new(I) ReturnNode(statement_pos); | 8562 statement = new(Z) ReturnNode(statement_pos); |
| 8554 } | 8563 } |
| 8555 AddNodeForFinallyInlining(statement); | 8564 AddNodeForFinallyInlining(statement); |
| 8556 ExpectSemicolon(); | 8565 ExpectSemicolon(); |
| 8557 } else if (token == Token::kIF) { | 8566 } else if (token == Token::kIF) { |
| 8558 statement = ParseIfStatement(label_name); | 8567 statement = ParseIfStatement(label_name); |
| 8559 } else if (token == Token::kASSERT) { | 8568 } else if (token == Token::kASSERT) { |
| 8560 statement = ParseAssertStatement(); | 8569 statement = ParseAssertStatement(); |
| 8561 ExpectSemicolon(); | 8570 ExpectSemicolon(); |
| 8562 } else if (IsVariableDeclaration()) { | 8571 } else if (IsVariableDeclaration()) { |
| 8563 statement = ParseVariableDeclarationList(); | 8572 statement = ParseVariableDeclarationList(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8600 // The exception and stack trace variables are bound in the block | 8609 // The exception and stack trace variables are bound in the block |
| 8601 // containing the try. | 8610 // containing the try. |
| 8602 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); | 8611 LocalScope* scope = try_blocks_list_->try_block()->scope->parent(); |
| 8603 ASSERT(scope != NULL); | 8612 ASSERT(scope != NULL); |
| 8604 LocalVariable* excp_var = | 8613 LocalVariable* excp_var = |
| 8605 scope->LocalLookupVariable(Symbols::ExceptionVar()); | 8614 scope->LocalLookupVariable(Symbols::ExceptionVar()); |
| 8606 ASSERT(excp_var != NULL); | 8615 ASSERT(excp_var != NULL); |
| 8607 LocalVariable* trace_var = | 8616 LocalVariable* trace_var = |
| 8608 scope->LocalLookupVariable(Symbols::StackTraceVar()); | 8617 scope->LocalLookupVariable(Symbols::StackTraceVar()); |
| 8609 ASSERT(trace_var != NULL); | 8618 ASSERT(trace_var != NULL); |
| 8610 statement = new(I) ThrowNode( | 8619 statement = new(Z) ThrowNode( |
| 8611 statement_pos, | 8620 statement_pos, |
| 8612 new(I) LoadLocalNode(statement_pos, excp_var), | 8621 new(Z) LoadLocalNode(statement_pos, excp_var), |
| 8613 new(I) LoadLocalNode(statement_pos, trace_var)); | 8622 new(Z) LoadLocalNode(statement_pos, trace_var)); |
| 8614 } else { | 8623 } else { |
| 8615 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); | 8624 statement = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL); |
| 8616 ExpectSemicolon(); | 8625 ExpectSemicolon(); |
| 8617 } | 8626 } |
| 8618 return statement; | 8627 return statement; |
| 8619 } | 8628 } |
| 8620 | 8629 |
| 8621 | 8630 |
| 8622 void Parser::ReportError(const Error& error) { | 8631 void Parser::ReportError(const Error& error) { |
| 8623 Report::LongJump(error); | 8632 Report::LongJump(error); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8759 if (node != NULL) { | 8768 if (node != NULL) { |
| 8760 sequence->Add(node); | 8769 sequence->Add(node); |
| 8761 } | 8770 } |
| 8762 return sequence; | 8771 return sequence; |
| 8763 } | 8772 } |
| 8764 return node->AsSequenceNode(); | 8773 return node->AsSequenceNode(); |
| 8765 } | 8774 } |
| 8766 | 8775 |
| 8767 | 8776 |
| 8768 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { | 8777 AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type) { |
| 8769 ArgumentListNode* arguments = new(I) ArgumentListNode(type_pos); | 8778 ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos); |
| 8770 // Location argument. | 8779 // Location argument. |
| 8771 arguments->Add(new(I) LiteralNode( | 8780 arguments->Add(new(Z) LiteralNode( |
| 8772 type_pos, Integer::ZoneHandle(I, Integer::New(type_pos)))); | 8781 type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos)))); |
| 8773 // Src value argument. | 8782 // Src value argument. |
| 8774 arguments->Add(new(I) LiteralNode(type_pos, Instance::ZoneHandle(I))); | 8783 arguments->Add(new(Z) LiteralNode(type_pos, Instance::ZoneHandle(Z))); |
| 8775 // Dst type name argument. | 8784 // Dst type name argument. |
| 8776 arguments->Add(new(I) LiteralNode(type_pos, Symbols::Malformed())); | 8785 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Malformed())); |
| 8777 // Dst name argument. | 8786 // Dst name argument. |
| 8778 arguments->Add(new(I) LiteralNode(type_pos, Symbols::Empty())); | 8787 arguments->Add(new(Z) LiteralNode(type_pos, Symbols::Empty())); |
| 8779 // Malformed type error or malbounded type error. | 8788 // Malformed type error or malbounded type error. |
| 8780 const Error& error = Error::Handle(I, type.error()); | 8789 const Error& error = Error::Handle(Z, type.error()); |
| 8781 ASSERT(!error.IsNull()); | 8790 ASSERT(!error.IsNull()); |
| 8782 arguments->Add(new(I) LiteralNode(type_pos, String::ZoneHandle(I, | 8791 arguments->Add(new(Z) LiteralNode(type_pos, String::ZoneHandle(Z, |
| 8783 Symbols::New(error.ToErrorCString())))); | 8792 Symbols::New(error.ToErrorCString())))); |
| 8784 return MakeStaticCall(Symbols::TypeError(), | 8793 return MakeStaticCall(Symbols::TypeError(), |
| 8785 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 8794 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 8786 arguments); | 8795 arguments); |
| 8787 } | 8796 } |
| 8788 | 8797 |
| 8789 | 8798 |
| 8790 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, | 8799 AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos, |
| 8791 const Class& cls, | 8800 const Class& cls, |
| 8792 const String& function_name, | 8801 const String& function_name, |
| 8793 ArgumentListNode* function_arguments, | 8802 ArgumentListNode* function_arguments, |
| 8794 InvocationMirror::Call im_call, | 8803 InvocationMirror::Call im_call, |
| 8795 InvocationMirror::Type im_type, | 8804 InvocationMirror::Type im_type, |
| 8796 const Function* func) { | 8805 const Function* func) { |
| 8797 ArgumentListNode* arguments = new(I) ArgumentListNode(call_pos); | 8806 ArgumentListNode* arguments = new(Z) ArgumentListNode(call_pos); |
| 8798 // Object receiver. | 8807 // Object receiver. |
| 8799 // If the function is external and dynamic, pass the actual receiver, | 8808 // If the function is external and dynamic, pass the actual receiver, |
| 8800 // otherwise, pass a class literal of the unresolved method's owner. | 8809 // otherwise, pass a class literal of the unresolved method's owner. |
| 8801 if ((func != NULL) && !func->IsNull() && | 8810 if ((func != NULL) && !func->IsNull() && |
| 8802 func->is_external() && !func->is_static()) { | 8811 func->is_external() && !func->is_static()) { |
| 8803 arguments->Add(LoadReceiver(func->token_pos())); | 8812 arguments->Add(LoadReceiver(func->token_pos())); |
| 8804 } else { | 8813 } else { |
| 8805 Type& type = Type::ZoneHandle(I, | 8814 Type& type = Type::ZoneHandle(Z, |
| 8806 Type::New(cls, TypeArguments::Handle(I), call_pos, Heap::kOld)); | 8815 Type::New(cls, TypeArguments::Handle(Z), call_pos, Heap::kOld)); |
| 8807 type ^= ClassFinalizer::FinalizeType( | 8816 type ^= ClassFinalizer::FinalizeType( |
| 8808 current_class(), type, ClassFinalizer::kCanonicalize); | 8817 current_class(), type, ClassFinalizer::kCanonicalize); |
| 8809 arguments->Add(new(I) LiteralNode(call_pos, type)); | 8818 arguments->Add(new(Z) LiteralNode(call_pos, type)); |
| 8810 } | 8819 } |
| 8811 // String memberName. | 8820 // String memberName. |
| 8812 arguments->Add(new(I) LiteralNode( | 8821 arguments->Add(new(Z) LiteralNode( |
| 8813 call_pos, String::ZoneHandle(I, Symbols::New(function_name)))); | 8822 call_pos, String::ZoneHandle(Z, Symbols::New(function_name)))); |
| 8814 // Smi invocation_type. | 8823 // Smi invocation_type. |
| 8815 if (cls.IsTopLevel()) { | 8824 if (cls.IsTopLevel()) { |
| 8816 ASSERT(im_call == InvocationMirror::kStatic || | 8825 ASSERT(im_call == InvocationMirror::kStatic || |
| 8817 im_call == InvocationMirror::kTopLevel); | 8826 im_call == InvocationMirror::kTopLevel); |
| 8818 im_call = InvocationMirror::kTopLevel; | 8827 im_call = InvocationMirror::kTopLevel; |
| 8819 } | 8828 } |
| 8820 arguments->Add(new(I) LiteralNode(call_pos, Smi::ZoneHandle(I, | 8829 arguments->Add(new(Z) LiteralNode(call_pos, Smi::ZoneHandle(Z, |
| 8821 Smi::New(InvocationMirror::EncodeType(im_call, im_type))))); | 8830 Smi::New(InvocationMirror::EncodeType(im_call, im_type))))); |
| 8822 // List arguments. | 8831 // List arguments. |
| 8823 if (function_arguments == NULL) { | 8832 if (function_arguments == NULL) { |
| 8824 arguments->Add(new(I) LiteralNode(call_pos, Array::ZoneHandle(I))); | 8833 arguments->Add(new(Z) LiteralNode(call_pos, Array::ZoneHandle(Z))); |
| 8825 } else { | 8834 } else { |
| 8826 ArrayNode* array = new(I) ArrayNode( | 8835 ArrayNode* array = new(Z) ArrayNode( |
| 8827 call_pos, | 8836 call_pos, |
| 8828 Type::ZoneHandle(I, Type::ArrayType()), | 8837 Type::ZoneHandle(Z, Type::ArrayType()), |
| 8829 function_arguments->nodes()); | 8838 function_arguments->nodes()); |
| 8830 arguments->Add(array); | 8839 arguments->Add(array); |
| 8831 } | 8840 } |
| 8832 // List argumentNames. | 8841 // List argumentNames. |
| 8833 if (function_arguments == NULL) { | 8842 if (function_arguments == NULL) { |
| 8834 arguments->Add(new(I) LiteralNode(call_pos, Array::ZoneHandle(I))); | 8843 arguments->Add(new(Z) LiteralNode(call_pos, Array::ZoneHandle(Z))); |
| 8835 } else { | 8844 } else { |
| 8836 arguments->Add(new(I) LiteralNode(call_pos, function_arguments->names())); | 8845 arguments->Add(new(Z) LiteralNode(call_pos, function_arguments->names())); |
| 8837 } | 8846 } |
| 8838 | 8847 |
| 8839 // List existingArgumentNames. | 8848 // List existingArgumentNames. |
| 8840 // Check if there exists a function with the same name unless caller | 8849 // Check if there exists a function with the same name unless caller |
| 8841 // has done the lookup already. If there is a function with the same | 8850 // has done the lookup already. If there is a function with the same |
| 8842 // name but incompatible parameters, inform the NoSuchMethodError what the | 8851 // name but incompatible parameters, inform the NoSuchMethodError what the |
| 8843 // expected parameters are. | 8852 // expected parameters are. |
| 8844 Function& function = Function::Handle(I); | 8853 Function& function = Function::Handle(Z); |
| 8845 if (func != NULL) { | 8854 if (func != NULL) { |
| 8846 function = func->raw(); | 8855 function = func->raw(); |
| 8847 } else { | 8856 } else { |
| 8848 function = cls.LookupStaticFunction(function_name); | 8857 function = cls.LookupStaticFunction(function_name); |
| 8849 } | 8858 } |
| 8850 Array& array = Array::ZoneHandle(I); | 8859 Array& array = Array::ZoneHandle(Z); |
| 8851 // An unpatched external function is treated as an unresolved function. | 8860 // An unpatched external function is treated as an unresolved function. |
| 8852 if (!function.IsNull() && !function.is_external()) { | 8861 if (!function.IsNull() && !function.is_external()) { |
| 8853 // The constructor for NoSuchMethodError takes a list of existing | 8862 // The constructor for NoSuchMethodError takes a list of existing |
| 8854 // parameter names to produce a descriptive error message explaining | 8863 // parameter names to produce a descriptive error message explaining |
| 8855 // the parameter mismatch. The problem is that the array of names | 8864 // the parameter mismatch. The problem is that the array of names |
| 8856 // does not describe which parameters are optional positional or | 8865 // does not describe which parameters are optional positional or |
| 8857 // named, which can lead to confusing error messages. | 8866 // named, which can lead to confusing error messages. |
| 8858 // Since the NoSuchMethodError class only uses the list to produce | 8867 // Since the NoSuchMethodError class only uses the list to produce |
| 8859 // a string describing the expected parameters, we construct a more | 8868 // a string describing the expected parameters, we construct a more |
| 8860 // descriptive string here and pass it as the only element of the | 8869 // descriptive string here and pass it as the only element of the |
| 8861 // "existingArgumentNames" array of the NoSuchMethodError constructor. | 8870 // "existingArgumentNames" array of the NoSuchMethodError constructor. |
| 8862 // TODO(13471): Separate the implementations of NoSuchMethodError | 8871 // TODO(13471): Separate the implementations of NoSuchMethodError |
| 8863 // between dart2js and VM. Update the constructor to accept a string | 8872 // between dart2js and VM. Update the constructor to accept a string |
| 8864 // describing the formal parameters of an incompatible call target. | 8873 // describing the formal parameters of an incompatible call target. |
| 8865 array = Array::New(1, Heap::kOld); | 8874 array = Array::New(1, Heap::kOld); |
| 8866 array.SetAt(0, String::Handle(I, function.UserVisibleFormalParameters())); | 8875 array.SetAt(0, String::Handle(Z, function.UserVisibleFormalParameters())); |
| 8867 } | 8876 } |
| 8868 arguments->Add(new(I) LiteralNode(call_pos, array)); | 8877 arguments->Add(new(Z) LiteralNode(call_pos, array)); |
| 8869 | 8878 |
| 8870 return MakeStaticCall(Symbols::NoSuchMethodError(), | 8879 return MakeStaticCall(Symbols::NoSuchMethodError(), |
| 8871 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 8880 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 8872 arguments); | 8881 arguments); |
| 8873 } | 8882 } |
| 8874 | 8883 |
| 8875 | 8884 |
| 8876 AstNode* Parser::ParseBinaryExpr(int min_preced) { | 8885 AstNode* Parser::ParseBinaryExpr(int min_preced) { |
| 8877 TRACE_PARSER("ParseBinaryExpr"); | 8886 TRACE_PARSER("ParseBinaryExpr"); |
| 8878 ASSERT(min_preced >= Token::Precedence(Token::kOR)); | 8887 ASSERT(min_preced >= Token::Precedence(Token::kOR)); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 8890 AstNode* right_operand = NULL; | 8899 AstNode* right_operand = NULL; |
| 8891 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { | 8900 if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) { |
| 8892 right_operand = ParseBinaryExpr(current_preced + 1); | 8901 right_operand = ParseBinaryExpr(current_preced + 1); |
| 8893 } else { | 8902 } else { |
| 8894 // For 'is' and 'as' we expect the right operand to be a type. | 8903 // For 'is' and 'as' we expect the right operand to be a type. |
| 8895 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { | 8904 if ((op_kind == Token::kIS) && (CurrentToken() == Token::kNOT)) { |
| 8896 ConsumeToken(); | 8905 ConsumeToken(); |
| 8897 op_kind = Token::kISNOT; | 8906 op_kind = Token::kISNOT; |
| 8898 } | 8907 } |
| 8899 const intptr_t type_pos = TokenPos(); | 8908 const intptr_t type_pos = TokenPos(); |
| 8900 const AbstractType& type = AbstractType::ZoneHandle(I, | 8909 const AbstractType& type = AbstractType::ZoneHandle(Z, |
| 8901 ParseType(ClassFinalizer::kCanonicalize)); | 8910 ParseType(ClassFinalizer::kCanonicalize)); |
| 8902 if (!type.IsInstantiated() && | 8911 if (!type.IsInstantiated() && |
| 8903 (current_block_->scope->function_level() > 0)) { | 8912 (current_block_->scope->function_level() > 0)) { |
| 8904 // Make sure that the instantiator is captured. | 8913 // Make sure that the instantiator is captured. |
| 8905 CaptureInstantiator(); | 8914 CaptureInstantiator(); |
| 8906 } | 8915 } |
| 8907 right_operand = new(I) TypeNode(type_pos, type); | 8916 right_operand = new(Z) TypeNode(type_pos, type); |
| 8908 // In production mode, the type may be malformed. | 8917 // In production mode, the type may be malformed. |
| 8909 // In checked mode, the type may be malformed or malbounded. | 8918 // In checked mode, the type may be malformed or malbounded. |
| 8910 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || | 8919 if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) || |
| 8911 (op_kind == Token::kAS)) && | 8920 (op_kind == Token::kAS)) && |
| 8912 type.IsMalformedOrMalbounded()) { | 8921 type.IsMalformedOrMalbounded()) { |
| 8913 // Note that a type error is thrown in a type test or in | 8922 // Note that a type error is thrown in a type test or in |
| 8914 // a type cast even if the tested value is null. | 8923 // a type cast even if the tested value is null. |
| 8915 // We need to evaluate the left operand for potential | 8924 // We need to evaluate the left operand for potential |
| 8916 // side effects. | 8925 // side effects. |
| 8917 LetNode* let = new(I) LetNode(left_operand->token_pos()); | 8926 LetNode* let = new(Z) LetNode(left_operand->token_pos()); |
| 8918 let->AddNode(left_operand); | 8927 let->AddNode(left_operand); |
| 8919 let->AddNode(ThrowTypeError(type_pos, type)); | 8928 let->AddNode(ThrowTypeError(type_pos, type)); |
| 8920 left_operand = let; | 8929 left_operand = let; |
| 8921 break; // Type checks and casts can't be chained. | 8930 break; // Type checks and casts can't be chained. |
| 8922 } | 8931 } |
| 8923 } | 8932 } |
| 8924 if (Token::IsRelationalOperator(op_kind) | 8933 if (Token::IsRelationalOperator(op_kind) |
| 8925 || Token::IsTypeTestOperator(op_kind) | 8934 || Token::IsTypeTestOperator(op_kind) |
| 8926 || Token::IsTypeCastOperator(op_kind) | 8935 || Token::IsTypeCastOperator(op_kind) |
| 8927 || Token::IsEqualityOperator(op_kind)) { | 8936 || Token::IsEqualityOperator(op_kind)) { |
| 8928 if (Token::IsTypeTestOperator(op_kind) || | 8937 if (Token::IsTypeTestOperator(op_kind) || |
| 8929 Token::IsTypeCastOperator(op_kind)) { | 8938 Token::IsTypeCastOperator(op_kind)) { |
| 8930 if (!right_operand->AsTypeNode()->type().IsInstantiated()) { | 8939 if (!right_operand->AsTypeNode()->type().IsInstantiated()) { |
| 8931 EnsureExpressionTemp(); | 8940 EnsureExpressionTemp(); |
| 8932 } | 8941 } |
| 8933 } | 8942 } |
| 8934 left_operand = new(I) ComparisonNode( | 8943 left_operand = new(Z) ComparisonNode( |
| 8935 op_pos, op_kind, left_operand, right_operand); | 8944 op_pos, op_kind, left_operand, right_operand); |
| 8936 break; // Equality and relational operators cannot be chained. | 8945 break; // Equality and relational operators cannot be chained. |
| 8937 } else { | 8946 } else { |
| 8938 left_operand = OptimizeBinaryOpNode( | 8947 left_operand = OptimizeBinaryOpNode( |
| 8939 op_pos, op_kind, left_operand, right_operand); | 8948 op_pos, op_kind, left_operand, right_operand); |
| 8940 } | 8949 } |
| 8941 } | 8950 } |
| 8942 current_preced--; | 8951 current_preced--; |
| 8943 } | 8952 } |
| 8944 return left_operand; | 8953 return left_operand; |
| 8945 } | 8954 } |
| 8946 | 8955 |
| 8947 | 8956 |
| 8948 AstNode* Parser::ParseAwaitableExprList() { | 8957 AstNode* Parser::ParseAwaitableExprList() { |
| 8949 TRACE_PARSER("ParseAwaitableExprList"); | 8958 TRACE_PARSER("ParseAwaitableExprList"); |
| 8950 SequenceNode* preamble = NULL; | 8959 SequenceNode* preamble = NULL; |
| 8951 AstNode* expressions = ParseAwaitableExpr( | 8960 AstNode* expressions = ParseAwaitableExpr( |
| 8952 kAllowConst, kConsumeCascades, &preamble); | 8961 kAllowConst, kConsumeCascades, &preamble); |
| 8953 if (preamble != NULL) { | 8962 if (preamble != NULL) { |
| 8954 preamble->Add(expressions); | 8963 preamble->Add(expressions); |
| 8955 expressions = preamble; | 8964 expressions = preamble; |
| 8956 } | 8965 } |
| 8957 if (CurrentToken() == Token::kCOMMA) { | 8966 if (CurrentToken() == Token::kCOMMA) { |
| 8958 // Collect comma-separated expressions in a non scope owning sequence node. | 8967 // Collect comma-separated expressions in a non scope owning sequence node. |
| 8959 SequenceNode* list = new(I) SequenceNode(TokenPos(), NULL); | 8968 SequenceNode* list = new(Z) SequenceNode(TokenPos(), NULL); |
| 8960 list->Add(expressions); | 8969 list->Add(expressions); |
| 8961 while (CurrentToken() == Token::kCOMMA) { | 8970 while (CurrentToken() == Token::kCOMMA) { |
| 8962 ConsumeToken(); | 8971 ConsumeToken(); |
| 8963 preamble = NULL; | 8972 preamble = NULL; |
| 8964 AstNode* expr = ParseAwaitableExpr( | 8973 AstNode* expr = ParseAwaitableExpr( |
| 8965 kAllowConst, kConsumeCascades, &preamble); | 8974 kAllowConst, kConsumeCascades, &preamble); |
| 8966 if (preamble != NULL) { | 8975 if (preamble != NULL) { |
| 8967 list->Add(preamble); | 8976 list->Add(preamble); |
| 8968 } | 8977 } |
| 8969 list->Add(expr); | 8978 list->Add(expr); |
| 8970 } | 8979 } |
| 8971 expressions = list; | 8980 expressions = list; |
| 8972 } | 8981 } |
| 8973 return expressions; | 8982 return expressions; |
| 8974 } | 8983 } |
| 8975 | 8984 |
| 8976 | 8985 |
| 8977 void Parser::EnsureExpressionTemp() { | 8986 void Parser::EnsureExpressionTemp() { |
| 8978 // Temporary used later by the flow_graph_builder. | 8987 // Temporary used later by the flow_graph_builder. |
| 8979 parsed_function()->EnsureExpressionTemp(); | 8988 parsed_function()->EnsureExpressionTemp(); |
| 8980 } | 8989 } |
| 8981 | 8990 |
| 8982 | 8991 |
| 8983 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, | 8992 LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos, |
| 8984 const char* s) { | 8993 const char* s) { |
| 8985 char name[64]; | 8994 char name[64]; |
| 8986 OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos); | 8995 OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos); |
| 8987 LocalVariable* temp = new(I) LocalVariable( | 8996 LocalVariable* temp = new(Z) LocalVariable( |
| 8988 token_pos, | 8997 token_pos, |
| 8989 String::ZoneHandle(I, Symbols::New(name)), | 8998 String::ZoneHandle(Z, Symbols::New(name)), |
| 8990 Type::ZoneHandle(I, Type::DynamicType())); | 8999 Type::ZoneHandle(Z, Type::DynamicType())); |
| 8991 temp->set_is_final(); | 9000 temp->set_is_final(); |
| 8992 current_block_->scope->AddVariable(temp); | 9001 current_block_->scope->AddVariable(temp); |
| 8993 return temp; | 9002 return temp; |
| 8994 } | 9003 } |
| 8995 | 9004 |
| 8996 | 9005 |
| 8997 // TODO(srdjan): Implement other optimizations. | 9006 // TODO(srdjan): Implement other optimizations. |
| 8998 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, | 9007 AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos, |
| 8999 Token::Kind binary_op, | 9008 Token::Kind binary_op, |
| 9000 AstNode* lhs, | 9009 AstNode* lhs, |
| 9001 AstNode* rhs) { | 9010 AstNode* rhs) { |
| 9002 LiteralNode* lhs_literal = lhs->AsLiteralNode(); | 9011 LiteralNode* lhs_literal = lhs->AsLiteralNode(); |
| 9003 LiteralNode* rhs_literal = rhs->AsLiteralNode(); | 9012 LiteralNode* rhs_literal = rhs->AsLiteralNode(); |
| 9004 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { | 9013 if ((lhs_literal != NULL) && (rhs_literal != NULL)) { |
| 9005 if (lhs_literal->literal().IsDouble() && | 9014 if (lhs_literal->literal().IsDouble() && |
| 9006 rhs_literal->literal().IsDouble()) { | 9015 rhs_literal->literal().IsDouble()) { |
| 9007 double left_double = Double::Cast(lhs_literal->literal()).value(); | 9016 double left_double = Double::Cast(lhs_literal->literal()).value(); |
| 9008 double right_double = Double::Cast(rhs_literal->literal()).value(); | 9017 double right_double = Double::Cast(rhs_literal->literal()).value(); |
| 9009 if (binary_op == Token::kDIV) { | 9018 if (binary_op == Token::kDIV) { |
| 9010 const Double& dbl_obj = Double::ZoneHandle(I, | 9019 const Double& dbl_obj = Double::ZoneHandle(Z, |
| 9011 Double::NewCanonical((left_double / right_double))); | 9020 Double::NewCanonical((left_double / right_double))); |
| 9012 return new(I) LiteralNode(op_pos, dbl_obj); | 9021 return new(Z) LiteralNode(op_pos, dbl_obj); |
| 9013 } | 9022 } |
| 9014 } | 9023 } |
| 9015 } | 9024 } |
| 9016 if ((binary_op == Token::kAND) || (binary_op == Token::kOR)) { | 9025 if ((binary_op == Token::kAND) || (binary_op == Token::kOR)) { |
| 9017 EnsureExpressionTemp(); | 9026 EnsureExpressionTemp(); |
| 9018 } | 9027 } |
| 9019 if (binary_op == Token::kBIT_AND) { | 9028 if (binary_op == Token::kBIT_AND) { |
| 9020 // Normalize so that rhs is a literal if any is. | 9029 // Normalize so that rhs is a literal if any is. |
| 9021 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { | 9030 if ((rhs_literal == NULL) && (lhs_literal != NULL)) { |
| 9022 // Swap. | 9031 // Swap. |
| 9023 LiteralNode* temp = rhs_literal; | 9032 LiteralNode* temp = rhs_literal; |
| 9024 rhs_literal = lhs_literal; | 9033 rhs_literal = lhs_literal; |
| 9025 lhs_literal = temp; | 9034 lhs_literal = temp; |
| 9026 } | 9035 } |
| 9027 if ((rhs_literal != NULL) && | 9036 if ((rhs_literal != NULL) && |
| 9028 (rhs_literal->literal().IsSmi() || rhs_literal->literal().IsMint())) { | 9037 (rhs_literal->literal().IsSmi() || rhs_literal->literal().IsMint())) { |
| 9029 const int64_t val = Integer::Cast(rhs_literal->literal()).AsInt64Value(); | 9038 const int64_t val = Integer::Cast(rhs_literal->literal()).AsInt64Value(); |
| 9030 if ((0 <= val) && (Utils::IsUint(32, val))) { | 9039 if ((0 <= val) && (Utils::IsUint(32, val))) { |
| 9031 if (lhs->IsBinaryOpNode() && | 9040 if (lhs->IsBinaryOpNode() && |
| 9032 (lhs->AsBinaryOpNode()->kind() == Token::kSHL)) { | 9041 (lhs->AsBinaryOpNode()->kind() == Token::kSHL)) { |
| 9033 // Merge SHL and BIT_AND into one "SHL with mask" node. | 9042 // Merge SHL and BIT_AND into one "SHL with mask" node. |
| 9034 BinaryOpNode* old = lhs->AsBinaryOpNode(); | 9043 BinaryOpNode* old = lhs->AsBinaryOpNode(); |
| 9035 BinaryOpWithMask32Node* binop = new(I) BinaryOpWithMask32Node( | 9044 BinaryOpWithMask32Node* binop = new(Z) BinaryOpWithMask32Node( |
| 9036 old->token_pos(), old->kind(), old->left(), old->right(), val); | 9045 old->token_pos(), old->kind(), old->left(), old->right(), val); |
| 9037 return binop; | 9046 return binop; |
| 9038 } | 9047 } |
| 9039 } | 9048 } |
| 9040 } | 9049 } |
| 9041 } | 9050 } |
| 9042 return new(I) BinaryOpNode(op_pos, binary_op, lhs, rhs); | 9051 return new(Z) BinaryOpNode(op_pos, binary_op, lhs, rhs); |
| 9043 } | 9052 } |
| 9044 | 9053 |
| 9045 | 9054 |
| 9046 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, | 9055 AstNode* Parser::ExpandAssignableOp(intptr_t op_pos, |
| 9047 Token::Kind assignment_op, | 9056 Token::Kind assignment_op, |
| 9048 AstNode* lhs, | 9057 AstNode* lhs, |
| 9049 AstNode* rhs) { | 9058 AstNode* rhs) { |
| 9050 TRACE_PARSER("ExpandAssignableOp"); | 9059 TRACE_PARSER("ExpandAssignableOp"); |
| 9051 switch (assignment_op) { | 9060 switch (assignment_op) { |
| 9052 case Token::kASSIGN: | 9061 case Token::kASSIGN: |
| 9053 return rhs; | 9062 return rhs; |
| 9054 case Token::kASSIGN_ADD: | 9063 case Token::kASSIGN_ADD: |
| 9055 return new(I) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); | 9064 return new(Z) BinaryOpNode(op_pos, Token::kADD, lhs, rhs); |
| 9056 case Token::kASSIGN_SUB: | 9065 case Token::kASSIGN_SUB: |
| 9057 return new(I) BinaryOpNode(op_pos, Token::kSUB, lhs, rhs); | 9066 return new(Z) BinaryOpNode(op_pos, Token::kSUB, lhs, rhs); |
| 9058 case Token::kASSIGN_MUL: | 9067 case Token::kASSIGN_MUL: |
| 9059 return new(I) BinaryOpNode(op_pos, Token::kMUL, lhs, rhs); | 9068 return new(Z) BinaryOpNode(op_pos, Token::kMUL, lhs, rhs); |
| 9060 case Token::kASSIGN_TRUNCDIV: | 9069 case Token::kASSIGN_TRUNCDIV: |
| 9061 return new(I) BinaryOpNode(op_pos, Token::kTRUNCDIV, lhs, rhs); | 9070 return new(Z) BinaryOpNode(op_pos, Token::kTRUNCDIV, lhs, rhs); |
| 9062 case Token::kASSIGN_DIV: | 9071 case Token::kASSIGN_DIV: |
| 9063 return new(I) BinaryOpNode(op_pos, Token::kDIV, lhs, rhs); | 9072 return new(Z) BinaryOpNode(op_pos, Token::kDIV, lhs, rhs); |
| 9064 case Token::kASSIGN_MOD: | 9073 case Token::kASSIGN_MOD: |
| 9065 return new(I) BinaryOpNode(op_pos, Token::kMOD, lhs, rhs); | 9074 return new(Z) BinaryOpNode(op_pos, Token::kMOD, lhs, rhs); |
| 9066 case Token::kASSIGN_SHR: | 9075 case Token::kASSIGN_SHR: |
| 9067 return new(I) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); | 9076 return new(Z) BinaryOpNode(op_pos, Token::kSHR, lhs, rhs); |
| 9068 case Token::kASSIGN_SHL: | 9077 case Token::kASSIGN_SHL: |
| 9069 return new(I) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); | 9078 return new(Z) BinaryOpNode(op_pos, Token::kSHL, lhs, rhs); |
| 9070 case Token::kASSIGN_OR: | 9079 case Token::kASSIGN_OR: |
| 9071 return new(I) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); | 9080 return new(Z) BinaryOpNode(op_pos, Token::kBIT_OR, lhs, rhs); |
| 9072 case Token::kASSIGN_AND: | 9081 case Token::kASSIGN_AND: |
| 9073 return new(I) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); | 9082 return new(Z) BinaryOpNode(op_pos, Token::kBIT_AND, lhs, rhs); |
| 9074 case Token::kASSIGN_XOR: | 9083 case Token::kASSIGN_XOR: |
| 9075 return new(I) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); | 9084 return new(Z) BinaryOpNode(op_pos, Token::kBIT_XOR, lhs, rhs); |
| 9076 default: | 9085 default: |
| 9077 ReportError(op_pos, | 9086 ReportError(op_pos, |
| 9078 "internal error: ExpandAssignableOp '%s' unimplemented", | 9087 "internal error: ExpandAssignableOp '%s' unimplemented", |
| 9079 Token::Name(assignment_op)); | 9088 Token::Name(assignment_op)); |
| 9080 UNIMPLEMENTED(); | 9089 UNIMPLEMENTED(); |
| 9081 return NULL; | 9090 return NULL; |
| 9082 } | 9091 } |
| 9083 } | 9092 } |
| 9084 | 9093 |
| 9085 | 9094 |
| 9086 // Evaluates the value of the compile time constant expression | 9095 // Evaluates the value of the compile time constant expression |
| 9087 // and returns a literal node for the value. | 9096 // and returns a literal node for the value. |
| 9088 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { | 9097 AstNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) { |
| 9089 if (expr->IsLiteralNode()) { | 9098 if (expr->IsLiteralNode()) { |
| 9090 return expr; | 9099 return expr; |
| 9091 } | 9100 } |
| 9092 if (expr->EvalConstExpr() == NULL) { | 9101 if (expr->EvalConstExpr() == NULL) { |
| 9093 ReportError(expr_pos, "expression is not a valid compile-time constant"); | 9102 ReportError(expr_pos, "expression is not a valid compile-time constant"); |
| 9094 } | 9103 } |
| 9095 return new(I) LiteralNode( | 9104 return new(Z) LiteralNode( |
| 9096 expr_pos, EvaluateConstExpr(expr_pos, expr)); | 9105 expr_pos, EvaluateConstExpr(expr_pos, expr)); |
| 9097 } | 9106 } |
| 9098 | 9107 |
| 9099 | 9108 |
| 9100 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { | 9109 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) { |
| 9101 AstNode* node = *expr; | 9110 AstNode* node = *expr; |
| 9102 intptr_t token_pos = node->token_pos(); | 9111 intptr_t token_pos = node->token_pos(); |
| 9103 LetNode* result = new(I) LetNode(token_pos); | 9112 LetNode* result = new(Z) LetNode(token_pos); |
| 9104 if (node->IsLoadIndexedNode()) { | 9113 if (node->IsLoadIndexedNode()) { |
| 9105 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); | 9114 LoadIndexedNode* load_indexed = node->AsLoadIndexedNode(); |
| 9106 AstNode* array = load_indexed->array(); | 9115 AstNode* array = load_indexed->array(); |
| 9107 AstNode* index = load_indexed->index_expr(); | 9116 AstNode* index = load_indexed->index_expr(); |
| 9108 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { | 9117 if (!IsSimpleLocalOrLiteralNode(load_indexed->array())) { |
| 9109 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); | 9118 LocalVariable* t0 = result->AddInitializer(load_indexed->array()); |
| 9110 array = new(I) LoadLocalNode(token_pos, t0); | 9119 array = new(Z) LoadLocalNode(token_pos, t0); |
| 9111 } | 9120 } |
| 9112 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { | 9121 if (!IsSimpleLocalOrLiteralNode(load_indexed->index_expr())) { |
| 9113 LocalVariable* t1 = result->AddInitializer( | 9122 LocalVariable* t1 = result->AddInitializer( |
| 9114 load_indexed->index_expr()); | 9123 load_indexed->index_expr()); |
| 9115 index = new(I) LoadLocalNode(token_pos, t1); | 9124 index = new(Z) LoadLocalNode(token_pos, t1); |
| 9116 } | 9125 } |
| 9117 *expr = new(I) LoadIndexedNode(token_pos, | 9126 *expr = new(Z) LoadIndexedNode(token_pos, |
| 9118 array, | 9127 array, |
| 9119 index, | 9128 index, |
| 9120 load_indexed->super_class()); | 9129 load_indexed->super_class()); |
| 9121 return result; | 9130 return result; |
| 9122 } | 9131 } |
| 9123 if (node->IsInstanceGetterNode()) { | 9132 if (node->IsInstanceGetterNode()) { |
| 9124 InstanceGetterNode* getter = node->AsInstanceGetterNode(); | 9133 InstanceGetterNode* getter = node->AsInstanceGetterNode(); |
| 9125 AstNode* receiver = getter->receiver(); | 9134 AstNode* receiver = getter->receiver(); |
| 9126 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { | 9135 if (!IsSimpleLocalOrLiteralNode(getter->receiver())) { |
| 9127 LocalVariable* t0 = result->AddInitializer(getter->receiver()); | 9136 LocalVariable* t0 = result->AddInitializer(getter->receiver()); |
| 9128 receiver = new(I) LoadLocalNode(token_pos, t0); | 9137 receiver = new(Z) LoadLocalNode(token_pos, t0); |
| 9129 } | 9138 } |
| 9130 *expr = new(I) InstanceGetterNode( | 9139 *expr = new(Z) InstanceGetterNode( |
| 9131 token_pos, receiver, getter->field_name()); | 9140 token_pos, receiver, getter->field_name()); |
| 9132 return result; | 9141 return result; |
| 9133 } | 9142 } |
| 9134 return result; | 9143 return result; |
| 9135 } | 9144 } |
| 9136 | 9145 |
| 9137 | 9146 |
| 9138 // Check whether the syntax of expression expr is a grammatically legal | 9147 // Check whether the syntax of expression expr is a grammatically legal |
| 9139 // assignable expression. This check is used to detect situations where | 9148 // assignable expression. This check is used to detect situations where |
| 9140 // the expression itself is assignable, but the source is grammatically | 9149 // the expression itself is assignable, but the source is grammatically |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 9156 return Token::IsIdentifier(token) || (token == Token::kRBRACK); | 9165 return Token::IsIdentifier(token) || (token == Token::kRBRACK); |
| 9157 } | 9166 } |
| 9158 | 9167 |
| 9159 | 9168 |
| 9160 AstNode* Parser::CreateAssignmentNode(AstNode* original, | 9169 AstNode* Parser::CreateAssignmentNode(AstNode* original, |
| 9161 AstNode* rhs, | 9170 AstNode* rhs, |
| 9162 const String* left_ident, | 9171 const String* left_ident, |
| 9163 intptr_t left_pos) { | 9172 intptr_t left_pos) { |
| 9164 AstNode* result = original->MakeAssignmentNode(rhs); | 9173 AstNode* result = original->MakeAssignmentNode(rhs); |
| 9165 if (result == NULL) { | 9174 if (result == NULL) { |
| 9166 String& name = String::ZoneHandle(I); | 9175 String& name = String::ZoneHandle(Z); |
| 9167 const Class* target_cls = ¤t_class(); | 9176 const Class* target_cls = ¤t_class(); |
| 9168 if (original->IsTypeNode()) { | 9177 if (original->IsTypeNode()) { |
| 9169 name = Symbols::New(original->AsTypeNode()->TypeName()); | 9178 name = Symbols::New(original->AsTypeNode()->TypeName()); |
| 9170 } else if (original->IsLoadStaticFieldNode()) { | 9179 } else if (original->IsLoadStaticFieldNode()) { |
| 9171 name = original->AsLoadStaticFieldNode()->field().name(); | 9180 name = original->AsLoadStaticFieldNode()->field().name(); |
| 9172 target_cls = &Class::Handle(I, | 9181 target_cls = &Class::Handle(Z, |
| 9173 original->AsLoadStaticFieldNode()->field().owner()); | 9182 original->AsLoadStaticFieldNode()->field().owner()); |
| 9174 } else if ((left_ident != NULL) && | 9183 } else if ((left_ident != NULL) && |
| 9175 (original->IsLiteralNode() || | 9184 (original->IsLiteralNode() || |
| 9176 original->IsLoadLocalNode())) { | 9185 original->IsLoadLocalNode())) { |
| 9177 name = left_ident->raw(); | 9186 name = left_ident->raw(); |
| 9178 } | 9187 } |
| 9179 if (name.IsNull()) { | 9188 if (name.IsNull()) { |
| 9180 ReportError(left_pos, "expression is not assignable"); | 9189 ReportError(left_pos, "expression is not assignable"); |
| 9181 } | 9190 } |
| 9182 result = ThrowNoSuchMethodError( | 9191 result = ThrowNoSuchMethodError( |
| 9183 original->token_pos(), | 9192 original->token_pos(), |
| 9184 *target_cls, | 9193 *target_cls, |
| 9185 String::Handle(I, Field::SetterName(name)), | 9194 String::Handle(Z, Field::SetterName(name)), |
| 9186 NULL, // No arguments. | 9195 NULL, // No arguments. |
| 9187 InvocationMirror::kStatic, | 9196 InvocationMirror::kStatic, |
| 9188 original->IsLoadLocalNode() ? | 9197 original->IsLoadLocalNode() ? |
| 9189 InvocationMirror::kLocalVar : InvocationMirror::kSetter, | 9198 InvocationMirror::kLocalVar : InvocationMirror::kSetter, |
| 9190 NULL); // No existing function. | 9199 NULL); // No existing function. |
| 9191 } else if (result->IsStoreIndexedNode() || | 9200 } else if (result->IsStoreIndexedNode() || |
| 9192 result->IsInstanceSetterNode() || | 9201 result->IsInstanceSetterNode() || |
| 9193 result->IsStaticSetterNode() || | 9202 result->IsStaticSetterNode() || |
| 9194 result->IsStoreStaticFieldNode() || | 9203 result->IsStoreStaticFieldNode() || |
| 9195 result->IsStoreLocalNode()) { | 9204 result->IsStoreLocalNode()) { |
| 9196 // Ensure that the expression temp is allocated for nodes that may need it. | 9205 // Ensure that the expression temp is allocated for nodes that may need it. |
| 9197 EnsureExpressionTemp(); | 9206 EnsureExpressionTemp(); |
| 9198 } | 9207 } |
| 9199 return result; | 9208 return result; |
| 9200 } | 9209 } |
| 9201 | 9210 |
| 9202 | 9211 |
| 9203 AstNode* Parser::ParseCascades(AstNode* expr) { | 9212 AstNode* Parser::ParseCascades(AstNode* expr) { |
| 9204 intptr_t cascade_pos = TokenPos(); | 9213 intptr_t cascade_pos = TokenPos(); |
| 9205 LetNode* cascade = new(I) LetNode(cascade_pos); | 9214 LetNode* cascade = new(Z) LetNode(cascade_pos); |
| 9206 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); | 9215 LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr); |
| 9207 while (CurrentToken() == Token::kCASCADE) { | 9216 while (CurrentToken() == Token::kCASCADE) { |
| 9208 cascade_pos = TokenPos(); | 9217 cascade_pos = TokenPos(); |
| 9209 LoadLocalNode* load_cascade_receiver = | 9218 LoadLocalNode* load_cascade_receiver = |
| 9210 new(I) LoadLocalNode(cascade_pos, cascade_receiver_var); | 9219 new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var); |
| 9211 if (Token::IsIdentifier(LookaheadToken(1))) { | 9220 if (Token::IsIdentifier(LookaheadToken(1))) { |
| 9212 // Replace .. with . for ParseSelectors(). | 9221 // Replace .. with . for ParseSelectors(). |
| 9213 token_kind_ = Token::kPERIOD; | 9222 token_kind_ = Token::kPERIOD; |
| 9214 } else if (LookaheadToken(1) == Token::kLBRACK) { | 9223 } else if (LookaheadToken(1) == Token::kLBRACK) { |
| 9215 ConsumeToken(); | 9224 ConsumeToken(); |
| 9216 } else { | 9225 } else { |
| 9217 ReportError("identifier or [ expected after .."); | 9226 ReportError("identifier or [ expected after .."); |
| 9218 } | 9227 } |
| 9219 String* expr_ident = | 9228 String* expr_ident = |
| 9220 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 9229 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 9245 AstNode* assign_expr = | 9254 AstNode* assign_expr = |
| 9246 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); | 9255 CreateAssignmentNode(expr, right_expr, expr_ident, expr_pos); |
| 9247 ASSERT(assign_expr != NULL); | 9256 ASSERT(assign_expr != NULL); |
| 9248 expr = assign_expr; | 9257 expr = assign_expr; |
| 9249 } | 9258 } |
| 9250 } | 9259 } |
| 9251 cascade->AddNode(expr); | 9260 cascade->AddNode(expr); |
| 9252 } | 9261 } |
| 9253 // The result is an expression with the (side effects of the) cascade | 9262 // The result is an expression with the (side effects of the) cascade |
| 9254 // sequence followed by the (value of the) receiver temp variable load. | 9263 // sequence followed by the (value of the) receiver temp variable load. |
| 9255 cascade->AddNode(new(I) LoadLocalNode(cascade_pos, cascade_receiver_var)); | 9264 cascade->AddNode(new(Z) LoadLocalNode(cascade_pos, cascade_receiver_var)); |
| 9256 return cascade; | 9265 return cascade; |
| 9257 } | 9266 } |
| 9258 | 9267 |
| 9259 | 9268 |
| 9260 // Convert loading of a static const field into a literal node. | 9269 // Convert loading of a static const field into a literal node. |
| 9261 static AstNode* LiteralIfStaticConst(Isolate* iso, AstNode* expr) { | 9270 static AstNode* LiteralIfStaticConst(Zone* zone, AstNode* expr) { |
| 9262 if (expr->IsLoadStaticFieldNode()) { | 9271 if (expr->IsLoadStaticFieldNode()) { |
| 9263 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 9272 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
| 9264 if (field.is_const()) { | 9273 if (field.is_const()) { |
| 9265 ASSERT(field.value() != Object::sentinel().raw()); | 9274 ASSERT(field.value() != Object::sentinel().raw()); |
| 9266 ASSERT(field.value() != Object::transition_sentinel().raw()); | 9275 ASSERT(field.value() != Object::transition_sentinel().raw()); |
| 9267 return new(iso) LiteralNode(expr->token_pos(), | 9276 return new(zone) LiteralNode(expr->token_pos(), |
| 9268 Instance::ZoneHandle(iso, field.value())); | 9277 Instance::ZoneHandle(zone, field.value())); |
| 9269 } | 9278 } |
| 9270 } | 9279 } |
| 9271 return expr; | 9280 return expr; |
| 9272 } | 9281 } |
| 9273 | 9282 |
| 9274 | 9283 |
| 9275 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, | 9284 AstNode* Parser::ParseAwaitableExpr(bool require_compiletime_const, |
| 9276 bool consume_cascades, | 9285 bool consume_cascades, |
| 9277 SequenceNode** await_preamble) { | 9286 SequenceNode** await_preamble) { |
| 9278 TRACE_PARSER("ParseAwaitableExpr"); | 9287 TRACE_PARSER("ParseAwaitableExpr"); |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 9309 | 9318 |
| 9310 if (CurrentToken() == Token::kTHROW) { | 9319 if (CurrentToken() == Token::kTHROW) { |
| 9311 if (require_compiletime_const) { | 9320 if (require_compiletime_const) { |
| 9312 ReportError("'throw expr' is not a valid compile-time constant"); | 9321 ReportError("'throw expr' is not a valid compile-time constant"); |
| 9313 } | 9322 } |
| 9314 ConsumeToken(); | 9323 ConsumeToken(); |
| 9315 if (CurrentToken() == Token::kSEMICOLON) { | 9324 if (CurrentToken() == Token::kSEMICOLON) { |
| 9316 ReportError("expression expected after throw"); | 9325 ReportError("expression expected after throw"); |
| 9317 } | 9326 } |
| 9318 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); | 9327 AstNode* expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 9319 return new(I) ThrowNode(expr_pos, expr, NULL); | 9328 return new(Z) ThrowNode(expr_pos, expr, NULL); |
| 9320 } | 9329 } |
| 9321 AstNode* expr = ParseConditionalExpr(); | 9330 AstNode* expr = ParseConditionalExpr(); |
| 9322 if (!Token::IsAssignmentOperator(CurrentToken())) { | 9331 if (!Token::IsAssignmentOperator(CurrentToken())) { |
| 9323 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { | 9332 if ((CurrentToken() == Token::kCASCADE) && consume_cascades) { |
| 9324 return ParseCascades(expr); | 9333 return ParseCascades(expr); |
| 9325 } | 9334 } |
| 9326 if (require_compiletime_const) { | 9335 if (require_compiletime_const) { |
| 9327 expr = FoldConstExpr(expr_pos, expr); | 9336 expr = FoldConstExpr(expr_pos, expr); |
| 9328 } else { | 9337 } else { |
| 9329 expr = LiteralIfStaticConst(I, expr); | 9338 expr = LiteralIfStaticConst(Z, expr); |
| 9330 } | 9339 } |
| 9331 return expr; | 9340 return expr; |
| 9332 } | 9341 } |
| 9333 // Assignment expressions. | 9342 // Assignment expressions. |
| 9334 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 9343 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 9335 ReportError(expr_pos, "expression is not assignable"); | 9344 ReportError(expr_pos, "expression is not assignable"); |
| 9336 } | 9345 } |
| 9337 const Token::Kind assignment_op = CurrentToken(); | 9346 const Token::Kind assignment_op = CurrentToken(); |
| 9338 const intptr_t assignment_pos = TokenPos(); | 9347 const intptr_t assignment_pos = TokenPos(); |
| 9339 ConsumeToken(); | 9348 ConsumeToken(); |
| 9340 const intptr_t right_expr_pos = TokenPos(); | 9349 const intptr_t right_expr_pos = TokenPos(); |
| 9341 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { | 9350 if (require_compiletime_const && (assignment_op != Token::kASSIGN)) { |
| 9342 ReportError(right_expr_pos, | 9351 ReportError(right_expr_pos, |
| 9343 "expression is not a valid compile-time constant"); | 9352 "expression is not a valid compile-time constant"); |
| 9344 } | 9353 } |
| 9345 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); | 9354 AstNode* right_expr = ParseExpr(require_compiletime_const, consume_cascades); |
| 9346 if (assignment_op != Token::kASSIGN) { | 9355 if (assignment_op != Token::kASSIGN) { |
| 9347 // Compound assignment: store inputs with side effects into temp. locals. | 9356 // Compound assignment: store inputs with side effects into temp. locals. |
| 9348 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 9357 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 9349 AstNode* assigned_value = | 9358 AstNode* assigned_value = |
| 9350 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); | 9359 ExpandAssignableOp(assignment_pos, assignment_op, expr, right_expr); |
| 9351 AstNode* assign_expr = | 9360 AstNode* assign_expr = |
| 9352 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 9361 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
| 9353 ASSERT(assign_expr != NULL); | 9362 ASSERT(assign_expr != NULL); |
| 9354 let_expr->AddNode(assign_expr); | 9363 let_expr->AddNode(assign_expr); |
| 9355 return let_expr; | 9364 return let_expr; |
| 9356 } else { | 9365 } else { |
| 9357 AstNode* assigned_value = LiteralIfStaticConst(I, right_expr); | 9366 AstNode* assigned_value = LiteralIfStaticConst(Z, right_expr); |
| 9358 AstNode* assign_expr = | 9367 AstNode* assign_expr = |
| 9359 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); | 9368 CreateAssignmentNode(expr, assigned_value, expr_ident, expr_pos); |
| 9360 ASSERT(assign_expr != NULL); | 9369 ASSERT(assign_expr != NULL); |
| 9361 return assign_expr; | 9370 return assign_expr; |
| 9362 } | 9371 } |
| 9363 } | 9372 } |
| 9364 | 9373 |
| 9365 | 9374 |
| 9366 LiteralNode* Parser::ParseConstExpr() { | 9375 LiteralNode* Parser::ParseConstExpr() { |
| 9367 TRACE_PARSER("ParseConstExpr"); | 9376 TRACE_PARSER("ParseConstExpr"); |
| 9368 intptr_t expr_pos = TokenPos(); | 9377 intptr_t expr_pos = TokenPos(); |
| 9369 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); | 9378 AstNode* expr = ParseExpr(kRequireConst, kNoCascades); |
| 9370 if (!expr->IsLiteralNode()) { | 9379 if (!expr->IsLiteralNode()) { |
| 9371 ReportError(expr_pos, "expression must be a compile-time constant"); | 9380 ReportError(expr_pos, "expression must be a compile-time constant"); |
| 9372 } | 9381 } |
| 9373 return expr->AsLiteralNode(); | 9382 return expr->AsLiteralNode(); |
| 9374 } | 9383 } |
| 9375 | 9384 |
| 9376 | 9385 |
| 9377 AstNode* Parser::ParseConditionalExpr() { | 9386 AstNode* Parser::ParseConditionalExpr() { |
| 9378 TRACE_PARSER("ParseConditionalExpr"); | 9387 TRACE_PARSER("ParseConditionalExpr"); |
| 9379 const intptr_t expr_pos = TokenPos(); | 9388 const intptr_t expr_pos = TokenPos(); |
| 9380 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); | 9389 AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kOR)); |
| 9381 if (CurrentToken() == Token::kCONDITIONAL) { | 9390 if (CurrentToken() == Token::kCONDITIONAL) { |
| 9382 EnsureExpressionTemp(); | 9391 EnsureExpressionTemp(); |
| 9383 ConsumeToken(); | 9392 ConsumeToken(); |
| 9384 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); | 9393 AstNode* expr1 = ParseExpr(kAllowConst, kNoCascades); |
| 9385 ExpectToken(Token::kCOLON); | 9394 ExpectToken(Token::kCOLON); |
| 9386 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); | 9395 AstNode* expr2 = ParseExpr(kAllowConst, kNoCascades); |
| 9387 expr = new(I) ConditionalExprNode(expr_pos, expr, expr1, expr2); | 9396 expr = new(Z) ConditionalExprNode(expr_pos, expr, expr1, expr2); |
| 9388 } | 9397 } |
| 9389 return expr; | 9398 return expr; |
| 9390 } | 9399 } |
| 9391 | 9400 |
| 9392 | 9401 |
| 9393 AstNode* Parser::ParseUnaryExpr() { | 9402 AstNode* Parser::ParseUnaryExpr() { |
| 9394 TRACE_PARSER("ParseUnaryExpr"); | 9403 TRACE_PARSER("ParseUnaryExpr"); |
| 9395 AstNode* expr = NULL; | 9404 AstNode* expr = NULL; |
| 9396 const intptr_t op_pos = TokenPos(); | 9405 const intptr_t op_pos = TokenPos(); |
| 9397 if (IsAwaitKeyword()) { | 9406 if (IsAwaitKeyword()) { |
| 9398 TRACE_PARSER("ParseAwaitExpr"); | 9407 TRACE_PARSER("ParseAwaitExpr"); |
| 9399 ConsumeToken(); | 9408 ConsumeToken(); |
| 9400 parsed_function()->record_await(); | 9409 parsed_function()->record_await(); |
| 9401 expr = new (I) AwaitNode(TokenPos(), ParseUnaryExpr()); | 9410 expr = new (Z) AwaitNode(TokenPos(), ParseUnaryExpr()); |
| 9402 } else if (IsPrefixOperator(CurrentToken())) { | 9411 } else if (IsPrefixOperator(CurrentToken())) { |
| 9403 Token::Kind unary_op = CurrentToken(); | 9412 Token::Kind unary_op = CurrentToken(); |
| 9404 if (unary_op == Token::kSUB) { | 9413 if (unary_op == Token::kSUB) { |
| 9405 unary_op = Token::kNEGATE; | 9414 unary_op = Token::kNEGATE; |
| 9406 } | 9415 } |
| 9407 ConsumeToken(); | 9416 ConsumeToken(); |
| 9408 expr = ParseUnaryExpr(); | 9417 expr = ParseUnaryExpr(); |
| 9409 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { | 9418 if (expr->IsPrimaryNode() && (expr->AsPrimaryNode()->IsSuper())) { |
| 9410 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); | 9419 expr = BuildUnarySuperOperator(unary_op, expr->AsPrimaryNode()); |
| 9411 } else { | 9420 } else { |
| 9412 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); | 9421 expr = UnaryOpNode::UnaryOpOrLiteral(op_pos, unary_op, expr); |
| 9413 } | 9422 } |
| 9414 } else if (IsIncrementOperator(CurrentToken())) { | 9423 } else if (IsIncrementOperator(CurrentToken())) { |
| 9415 Token::Kind incr_op = CurrentToken(); | 9424 Token::Kind incr_op = CurrentToken(); |
| 9416 ConsumeToken(); | 9425 ConsumeToken(); |
| 9417 String* expr_ident = | 9426 String* expr_ident = |
| 9418 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; | 9427 Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL; |
| 9419 const intptr_t expr_pos = TokenPos(); | 9428 const intptr_t expr_pos = TokenPos(); |
| 9420 expr = ParseUnaryExpr(); | 9429 expr = ParseUnaryExpr(); |
| 9421 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 9430 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 9422 ReportError(expr_pos, "expression is not assignable"); | 9431 ReportError(expr_pos, "expression is not assignable"); |
| 9423 } | 9432 } |
| 9424 // Is prefix. | 9433 // Is prefix. |
| 9425 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 9434 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 9426 Token::Kind binary_op = | 9435 Token::Kind binary_op = |
| 9427 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 9436 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 9428 BinaryOpNode* add = new(I) BinaryOpNode( | 9437 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 9429 op_pos, | 9438 op_pos, |
| 9430 binary_op, | 9439 binary_op, |
| 9431 expr, | 9440 expr, |
| 9432 new(I) LiteralNode(op_pos, Smi::ZoneHandle(I, Smi::New(1)))); | 9441 new(Z) LiteralNode(op_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
| 9433 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 9442 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); |
| 9434 ASSERT(store != NULL); | 9443 ASSERT(store != NULL); |
| 9435 let_expr->AddNode(store); | 9444 let_expr->AddNode(store); |
| 9436 expr = let_expr; | 9445 expr = let_expr; |
| 9437 } else { | 9446 } else { |
| 9438 expr = ParsePostfixExpr(); | 9447 expr = ParsePostfixExpr(); |
| 9439 } | 9448 } |
| 9440 return expr; | 9449 return expr; |
| 9441 } | 9450 } |
| 9442 | 9451 |
| 9443 | 9452 |
| 9444 ArgumentListNode* Parser::ParseActualParameters( | 9453 ArgumentListNode* Parser::ParseActualParameters( |
| 9445 ArgumentListNode* implicit_arguments, | 9454 ArgumentListNode* implicit_arguments, |
| 9446 bool require_const) { | 9455 bool require_const) { |
| 9447 TRACE_PARSER("ParseActualParameters"); | 9456 TRACE_PARSER("ParseActualParameters"); |
| 9448 ASSERT(CurrentToken() == Token::kLPAREN); | 9457 ASSERT(CurrentToken() == Token::kLPAREN); |
| 9449 const bool saved_mode = SetAllowFunctionLiterals(true); | 9458 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 9450 ArgumentListNode* arguments; | 9459 ArgumentListNode* arguments; |
| 9451 if (implicit_arguments == NULL) { | 9460 if (implicit_arguments == NULL) { |
| 9452 arguments = new(I) ArgumentListNode(TokenPos()); | 9461 arguments = new(Z) ArgumentListNode(TokenPos()); |
| 9453 } else { | 9462 } else { |
| 9454 arguments = implicit_arguments; | 9463 arguments = implicit_arguments; |
| 9455 } | 9464 } |
| 9456 const GrowableObjectArray& names = GrowableObjectArray::Handle(I, | 9465 const GrowableObjectArray& names = GrowableObjectArray::Handle(Z, |
| 9457 GrowableObjectArray::New(Heap::kOld)); | 9466 GrowableObjectArray::New(Heap::kOld)); |
| 9458 bool named_argument_seen = false; | 9467 bool named_argument_seen = false; |
| 9459 if (LookaheadToken(1) != Token::kRPAREN) { | 9468 if (LookaheadToken(1) != Token::kRPAREN) { |
| 9460 String& arg_name = String::Handle(I); | 9469 String& arg_name = String::Handle(Z); |
| 9461 do { | 9470 do { |
| 9462 ASSERT((CurrentToken() == Token::kLPAREN) || | 9471 ASSERT((CurrentToken() == Token::kLPAREN) || |
| 9463 (CurrentToken() == Token::kCOMMA)); | 9472 (CurrentToken() == Token::kCOMMA)); |
| 9464 ConsumeToken(); | 9473 ConsumeToken(); |
| 9465 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { | 9474 if (IsIdentifier() && (LookaheadToken(1) == Token::kCOLON)) { |
| 9466 named_argument_seen = true; | 9475 named_argument_seen = true; |
| 9467 // The canonicalization of the arguments descriptor array built in | 9476 // The canonicalization of the arguments descriptor array built in |
| 9468 // the code generator requires that the names are symbols, i.e. | 9477 // the code generator requires that the names are symbols, i.e. |
| 9469 // canonicalized strings. | 9478 // canonicalized strings. |
| 9470 ASSERT(CurrentLiteral()->IsSymbol()); | 9479 ASSERT(CurrentLiteral()->IsSymbol()); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 9481 ReportError("named argument expected"); | 9490 ReportError("named argument expected"); |
| 9482 } | 9491 } |
| 9483 arguments->Add(ParseExpr(require_const, kConsumeCascades)); | 9492 arguments->Add(ParseExpr(require_const, kConsumeCascades)); |
| 9484 } while (CurrentToken() == Token::kCOMMA); | 9493 } while (CurrentToken() == Token::kCOMMA); |
| 9485 } else { | 9494 } else { |
| 9486 ConsumeToken(); | 9495 ConsumeToken(); |
| 9487 } | 9496 } |
| 9488 ExpectToken(Token::kRPAREN); | 9497 ExpectToken(Token::kRPAREN); |
| 9489 SetAllowFunctionLiterals(saved_mode); | 9498 SetAllowFunctionLiterals(saved_mode); |
| 9490 if (named_argument_seen) { | 9499 if (named_argument_seen) { |
| 9491 arguments->set_names(Array::Handle(I, Array::MakeArray(names))); | 9500 arguments->set_names(Array::Handle(Z, Array::MakeArray(names))); |
| 9492 } | 9501 } |
| 9493 return arguments; | 9502 return arguments; |
| 9494 } | 9503 } |
| 9495 | 9504 |
| 9496 | 9505 |
| 9497 AstNode* Parser::ParseStaticCall(const Class& cls, | 9506 AstNode* Parser::ParseStaticCall(const Class& cls, |
| 9498 const String& func_name, | 9507 const String& func_name, |
| 9499 intptr_t ident_pos) { | 9508 intptr_t ident_pos) { |
| 9500 TRACE_PARSER("ParseStaticCall"); | 9509 TRACE_PARSER("ParseStaticCall"); |
| 9501 const intptr_t call_pos = TokenPos(); | 9510 const intptr_t call_pos = TokenPos(); |
| 9502 ASSERT(CurrentToken() == Token::kLPAREN); | 9511 ASSERT(CurrentToken() == Token::kLPAREN); |
| 9503 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 9512 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 9504 const int num_arguments = arguments->length(); | 9513 const int num_arguments = arguments->length(); |
| 9505 const Function& func = Function::ZoneHandle(I, | 9514 const Function& func = Function::ZoneHandle(Z, |
| 9506 Resolver::ResolveStatic(cls, | 9515 Resolver::ResolveStatic(cls, |
| 9507 func_name, | 9516 func_name, |
| 9508 num_arguments, | 9517 num_arguments, |
| 9509 arguments->names())); | 9518 arguments->names())); |
| 9510 if (func.IsNull()) { | 9519 if (func.IsNull()) { |
| 9511 // Check if there is a static field of the same name, it could be a closure | 9520 // Check if there is a static field of the same name, it could be a closure |
| 9512 // and so we try and invoke the closure. | 9521 // and so we try and invoke the closure. |
| 9513 AstNode* closure = NULL; | 9522 AstNode* closure = NULL; |
| 9514 const Field& field = Field::ZoneHandle(I, cls.LookupStaticField(func_name)); | 9523 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(func_name)); |
| 9515 Function& func = Function::ZoneHandle(I); | 9524 Function& func = Function::ZoneHandle(Z); |
| 9516 if (field.IsNull()) { | 9525 if (field.IsNull()) { |
| 9517 // No field, check if we have an explicit getter function. | 9526 // No field, check if we have an explicit getter function. |
| 9518 const String& getter_name = | 9527 const String& getter_name = |
| 9519 String::ZoneHandle(I, Field::GetterName(func_name)); | 9528 String::ZoneHandle(Z, Field::GetterName(func_name)); |
| 9520 const int kNumArguments = 0; // no arguments. | 9529 const int kNumArguments = 0; // no arguments. |
| 9521 func = Resolver::ResolveStatic(cls, | 9530 func = Resolver::ResolveStatic(cls, |
| 9522 getter_name, | 9531 getter_name, |
| 9523 kNumArguments, | 9532 kNumArguments, |
| 9524 Object::empty_array()); | 9533 Object::empty_array()); |
| 9525 if (!func.IsNull()) { | 9534 if (!func.IsNull()) { |
| 9526 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 9535 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 9527 closure = new(I) StaticGetterNode( | 9536 closure = new(Z) StaticGetterNode( |
| 9528 call_pos, | 9537 call_pos, |
| 9529 NULL, | 9538 NULL, |
| 9530 false, | 9539 false, |
| 9531 Class::ZoneHandle(I, cls.raw()), | 9540 Class::ZoneHandle(Z, cls.raw()), |
| 9532 func_name); | 9541 func_name); |
| 9533 return BuildClosureCall(call_pos, closure, arguments); | 9542 return BuildClosureCall(call_pos, closure, arguments); |
| 9534 } | 9543 } |
| 9535 } else { | 9544 } else { |
| 9536 closure = GenerateStaticFieldLookup(field, call_pos); | 9545 closure = GenerateStaticFieldLookup(field, call_pos); |
| 9537 return BuildClosureCall(call_pos, closure, arguments); | 9546 return BuildClosureCall(call_pos, closure, arguments); |
| 9538 } | 9547 } |
| 9539 // Could not resolve static method: throw a NoSuchMethodError. | 9548 // Could not resolve static method: throw a NoSuchMethodError. |
| 9540 return ThrowNoSuchMethodError(ident_pos, | 9549 return ThrowNoSuchMethodError(ident_pos, |
| 9541 cls, | 9550 cls, |
| 9542 func_name, | 9551 func_name, |
| 9543 arguments, | 9552 arguments, |
| 9544 InvocationMirror::kStatic, | 9553 InvocationMirror::kStatic, |
| 9545 InvocationMirror::kMethod, | 9554 InvocationMirror::kMethod, |
| 9546 NULL); // No existing function. | 9555 NULL); // No existing function. |
| 9547 } else if (cls.IsTopLevel() && | 9556 } else if (cls.IsTopLevel() && |
| 9548 (cls.library() == Library::CoreLibrary()) && | 9557 (cls.library() == Library::CoreLibrary()) && |
| 9549 (func.name() == Symbols::Identical().raw())) { | 9558 (func.name() == Symbols::Identical().raw())) { |
| 9550 // This is the predefined toplevel function identical(a,b). | 9559 // This is the predefined toplevel function identical(a,b). |
| 9551 // Create a comparison node instead of a static call to the function, unless | 9560 // Create a comparison node instead of a static call to the function, unless |
| 9552 // javascript warnings are desired and identical is not invoked from a patch | 9561 // javascript warnings are desired and identical is not invoked from a patch |
| 9553 // source. | 9562 // source. |
| 9554 if (!FLAG_warn_on_javascript_compatibility || is_patch_source()) { | 9563 if (!FLAG_warn_on_javascript_compatibility || is_patch_source()) { |
| 9555 ASSERT(num_arguments == 2); | 9564 ASSERT(num_arguments == 2); |
| 9556 return new(I) ComparisonNode(ident_pos, | 9565 return new(Z) ComparisonNode(ident_pos, |
| 9557 Token::kEQ_STRICT, | 9566 Token::kEQ_STRICT, |
| 9558 arguments->NodeAt(0), | 9567 arguments->NodeAt(0), |
| 9559 arguments->NodeAt(1)); | 9568 arguments->NodeAt(1)); |
| 9560 } | 9569 } |
| 9561 } | 9570 } |
| 9562 return new(I) StaticCallNode(call_pos, func, arguments); | 9571 return new(Z) StaticCallNode(call_pos, func, arguments); |
| 9563 } | 9572 } |
| 9564 | 9573 |
| 9565 | 9574 |
| 9566 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { | 9575 AstNode* Parser::ParseInstanceCall(AstNode* receiver, const String& func_name) { |
| 9567 TRACE_PARSER("ParseInstanceCall"); | 9576 TRACE_PARSER("ParseInstanceCall"); |
| 9568 const intptr_t call_pos = TokenPos(); | 9577 const intptr_t call_pos = TokenPos(); |
| 9569 CheckToken(Token::kLPAREN); | 9578 CheckToken(Token::kLPAREN); |
| 9570 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 9579 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 9571 return new(I) InstanceCallNode(call_pos, receiver, func_name, arguments); | 9580 return new(Z) InstanceCallNode(call_pos, receiver, func_name, arguments); |
| 9572 } | 9581 } |
| 9573 | 9582 |
| 9574 | 9583 |
| 9575 AstNode* Parser::ParseClosureCall(AstNode* closure) { | 9584 AstNode* Parser::ParseClosureCall(AstNode* closure) { |
| 9576 TRACE_PARSER("ParseClosureCall"); | 9585 TRACE_PARSER("ParseClosureCall"); |
| 9577 const intptr_t call_pos = TokenPos(); | 9586 const intptr_t call_pos = TokenPos(); |
| 9578 ASSERT(CurrentToken() == Token::kLPAREN); | 9587 ASSERT(CurrentToken() == Token::kLPAREN); |
| 9579 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); | 9588 ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst); |
| 9580 return BuildClosureCall(call_pos, closure, arguments); | 9589 return BuildClosureCall(call_pos, closure, arguments); |
| 9581 } | 9590 } |
| 9582 | 9591 |
| 9583 | 9592 |
| 9584 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, | 9593 AstNode* Parser::GenerateStaticFieldLookup(const Field& field, |
| 9585 intptr_t ident_pos) { | 9594 intptr_t ident_pos) { |
| 9586 // If the static field has an initializer, initialize the field at compile | 9595 // If the static field has an initializer, initialize the field at compile |
| 9587 // time, which is only possible if the field is const. | 9596 // time, which is only possible if the field is const. |
| 9588 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); | 9597 AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos); |
| 9589 if (initializing_getter != NULL) { | 9598 if (initializing_getter != NULL) { |
| 9590 // The field is not yet initialized and could not be initialized at compile | 9599 // The field is not yet initialized and could not be initialized at compile |
| 9591 // time. The getter will initialize the field. | 9600 // time. The getter will initialize the field. |
| 9592 return initializing_getter; | 9601 return initializing_getter; |
| 9593 } | 9602 } |
| 9594 // The field is initialized. | 9603 // The field is initialized. |
| 9595 ASSERT(field.is_static()); | 9604 ASSERT(field.is_static()); |
| 9596 const Class& field_owner = Class::ZoneHandle(I, field.owner()); | 9605 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); |
| 9597 const String& field_name = String::ZoneHandle(I, field.name()); | 9606 const String& field_name = String::ZoneHandle(Z, field.name()); |
| 9598 const String& getter_name = String::Handle(I, Field::GetterName(field_name)); | 9607 const String& getter_name = String::Handle(Z, Field::GetterName(field_name)); |
| 9599 const Function& getter = Function::Handle(I, | 9608 const Function& getter = Function::Handle(Z, |
| 9600 field_owner.LookupStaticFunction(getter_name)); | 9609 field_owner.LookupStaticFunction(getter_name)); |
| 9601 // Never load field directly if there is a getter (deterministic AST). | 9610 // Never load field directly if there is a getter (deterministic AST). |
| 9602 if (getter.IsNull() || field.is_const()) { | 9611 if (getter.IsNull() || field.is_const()) { |
| 9603 return new(I) LoadStaticFieldNode( | 9612 return new(Z) LoadStaticFieldNode( |
| 9604 ident_pos, Field::ZoneHandle(I, field.raw())); | 9613 ident_pos, Field::ZoneHandle(Z, field.raw())); |
| 9605 } else { | 9614 } else { |
| 9606 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); | 9615 ASSERT(getter.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 9607 return new(I) StaticGetterNode(ident_pos, | 9616 return new(Z) StaticGetterNode(ident_pos, |
| 9608 NULL, // Receiver. | 9617 NULL, // Receiver. |
| 9609 false, // is_super_getter. | 9618 false, // is_super_getter. |
| 9610 field_owner, | 9619 field_owner, |
| 9611 field_name); | 9620 field_name); |
| 9612 } | 9621 } |
| 9613 } | 9622 } |
| 9614 | 9623 |
| 9615 | 9624 |
| 9616 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, | 9625 AstNode* Parser::ParseStaticFieldAccess(const Class& cls, |
| 9617 const String& field_name, | 9626 const String& field_name, |
| 9618 intptr_t ident_pos, | 9627 intptr_t ident_pos, |
| 9619 bool consume_cascades) { | 9628 bool consume_cascades) { |
| 9620 TRACE_PARSER("ParseStaticFieldAccess"); | 9629 TRACE_PARSER("ParseStaticFieldAccess"); |
| 9621 AstNode* access = NULL; | 9630 AstNode* access = NULL; |
| 9622 const Field& field = Field::ZoneHandle(I, cls.LookupStaticField(field_name)); | 9631 const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name)); |
| 9623 Function& func = Function::ZoneHandle(I); | 9632 Function& func = Function::ZoneHandle(Z); |
| 9624 if (field.IsNull()) { | 9633 if (field.IsNull()) { |
| 9625 // No field, check if we have an explicit getter function. | 9634 // No field, check if we have an explicit getter function. |
| 9626 const String& getter_name = | 9635 const String& getter_name = |
| 9627 String::ZoneHandle(I, Field::GetterName(field_name)); | 9636 String::ZoneHandle(Z, Field::GetterName(field_name)); |
| 9628 const int kNumArguments = 0; // no arguments. | 9637 const int kNumArguments = 0; // no arguments. |
| 9629 func = Resolver::ResolveStatic(cls, | 9638 func = Resolver::ResolveStatic(cls, |
| 9630 getter_name, | 9639 getter_name, |
| 9631 kNumArguments, | 9640 kNumArguments, |
| 9632 Object::empty_array()); | 9641 Object::empty_array()); |
| 9633 if (func.IsNull()) { | 9642 if (func.IsNull()) { |
| 9634 // We might be referring to an implicit closure, check to see if | 9643 // We might be referring to an implicit closure, check to see if |
| 9635 // there is a function of the same name. | 9644 // there is a function of the same name. |
| 9636 func = cls.LookupStaticFunction(field_name); | 9645 func = cls.LookupStaticFunction(field_name); |
| 9637 if (!func.IsNull()) { | 9646 if (!func.IsNull()) { |
| 9638 access = CreateImplicitClosureNode(func, ident_pos, NULL); | 9647 access = CreateImplicitClosureNode(func, ident_pos, NULL); |
| 9639 } else { | 9648 } else { |
| 9640 // No function to closurize found found. | 9649 // No function to closurize found found. |
| 9641 // This field access may turn out to be a call to the setter. | 9650 // This field access may turn out to be a call to the setter. |
| 9642 // Create a getter call, which may later be turned into | 9651 // Create a getter call, which may later be turned into |
| 9643 // a setter call, or else the backend will generate | 9652 // a setter call, or else the backend will generate |
| 9644 // a throw NoSuchMethodError(). | 9653 // a throw NoSuchMethodError(). |
| 9645 access = new(I) StaticGetterNode(ident_pos, | 9654 access = new(Z) StaticGetterNode(ident_pos, |
| 9646 NULL, | 9655 NULL, |
| 9647 false, | 9656 false, |
| 9648 Class::ZoneHandle(I, cls.raw()), | 9657 Class::ZoneHandle(Z, cls.raw()), |
| 9649 field_name); | 9658 field_name); |
| 9650 } | 9659 } |
| 9651 } else { | 9660 } else { |
| 9652 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); | 9661 ASSERT(func.kind() != RawFunction::kImplicitStaticFinalGetter); |
| 9653 access = new(I) StaticGetterNode( | 9662 access = new(Z) StaticGetterNode( |
| 9654 ident_pos, NULL, false, Class::ZoneHandle(I, cls.raw()), field_name); | 9663 ident_pos, NULL, false, Class::ZoneHandle(Z, cls.raw()), field_name); |
| 9655 } | 9664 } |
| 9656 } else { | 9665 } else { |
| 9657 access = GenerateStaticFieldLookup(field, ident_pos); | 9666 access = GenerateStaticFieldLookup(field, ident_pos); |
| 9658 } | 9667 } |
| 9659 return access; | 9668 return access; |
| 9660 } | 9669 } |
| 9661 | 9670 |
| 9662 | 9671 |
| 9663 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { | 9672 AstNode* Parser::LoadFieldIfUnresolved(AstNode* node) { |
| 9664 if (!node->IsPrimaryNode()) { | 9673 if (!node->IsPrimaryNode()) { |
| 9665 return node; | 9674 return node; |
| 9666 } | 9675 } |
| 9667 PrimaryNode* primary = node->AsPrimaryNode(); | 9676 PrimaryNode* primary = node->AsPrimaryNode(); |
| 9668 if (primary->primary().IsString()) { | 9677 if (primary->primary().IsString()) { |
| 9669 if (primary->IsSuper()) { | 9678 if (primary->IsSuper()) { |
| 9670 return primary; | 9679 return primary; |
| 9671 } | 9680 } |
| 9672 // In a static method, evaluation of an unresolved identifier causes a | 9681 // In a static method, evaluation of an unresolved identifier causes a |
| 9673 // NoSuchMethodError to be thrown. | 9682 // NoSuchMethodError to be thrown. |
| 9674 // In an instance method, we convert this into a getter call | 9683 // In an instance method, we convert this into a getter call |
| 9675 // for a field (which may be defined in a subclass.) | 9684 // for a field (which may be defined in a subclass.) |
| 9676 String& name = String::CheckedZoneHandle(primary->primary().raw()); | 9685 String& name = String::CheckedZoneHandle(primary->primary().raw()); |
| 9677 if (current_function().is_static() || | 9686 if (current_function().is_static() || |
| 9678 current_function().IsInFactoryScope()) { | 9687 current_function().IsInFactoryScope()) { |
| 9679 StaticGetterNode* getter = new(I) StaticGetterNode( | 9688 StaticGetterNode* getter = new(Z) StaticGetterNode( |
| 9680 primary->token_pos(), | 9689 primary->token_pos(), |
| 9681 NULL, // No receiver. | 9690 NULL, // No receiver. |
| 9682 false, // Not a super getter. | 9691 false, // Not a super getter. |
| 9683 Class::ZoneHandle(I, current_class().raw()), | 9692 Class::ZoneHandle(Z, current_class().raw()), |
| 9684 name); | 9693 name); |
| 9685 getter->set_is_deferred(primary->is_deferred_reference()); | 9694 getter->set_is_deferred(primary->is_deferred_reference()); |
| 9686 return getter; | 9695 return getter; |
| 9687 } else { | 9696 } else { |
| 9688 AstNode* receiver = LoadReceiver(primary->token_pos()); | 9697 AstNode* receiver = LoadReceiver(primary->token_pos()); |
| 9689 return CallGetter(node->token_pos(), receiver, name); | 9698 return CallGetter(node->token_pos(), receiver, name); |
| 9690 } | 9699 } |
| 9691 } | 9700 } |
| 9692 return primary; | 9701 return primary; |
| 9693 } | 9702 } |
| 9694 | 9703 |
| 9695 | 9704 |
| 9696 AstNode* Parser::LoadClosure(PrimaryNode* primary) { | 9705 AstNode* Parser::LoadClosure(PrimaryNode* primary) { |
| 9697 ASSERT(primary->primary().IsFunction()); | 9706 ASSERT(primary->primary().IsFunction()); |
| 9698 const Function& func = | 9707 const Function& func = |
| 9699 Function::CheckedZoneHandle(primary->primary().raw()); | 9708 Function::CheckedZoneHandle(primary->primary().raw()); |
| 9700 const String& funcname = String::ZoneHandle(I, func.name()); | 9709 const String& funcname = String::ZoneHandle(Z, func.name()); |
| 9701 if (func.is_static()) { | 9710 if (func.is_static()) { |
| 9702 // Static function access. | 9711 // Static function access. |
| 9703 ClosureNode* closure = | 9712 ClosureNode* closure = |
| 9704 CreateImplicitClosureNode(func, primary->token_pos(), NULL); | 9713 CreateImplicitClosureNode(func, primary->token_pos(), NULL); |
| 9705 closure->set_is_deferred(primary->is_deferred_reference()); | 9714 closure->set_is_deferred(primary->is_deferred_reference()); |
| 9706 return closure; | 9715 return closure; |
| 9707 } else { | 9716 } else { |
| 9708 // Instance function access. | 9717 // Instance function access. |
| 9709 if (current_function().is_static() || | 9718 if (current_function().is_static() || |
| 9710 current_function().IsInFactoryScope()) { | 9719 current_function().IsInFactoryScope()) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 9726 AstNode* selector = NULL; | 9735 AstNode* selector = NULL; |
| 9727 if (CurrentToken() == Token::kPERIOD) { | 9736 if (CurrentToken() == Token::kPERIOD) { |
| 9728 ConsumeToken(); | 9737 ConsumeToken(); |
| 9729 if (left->IsPrimaryNode()) { | 9738 if (left->IsPrimaryNode()) { |
| 9730 PrimaryNode* primary_node = left->AsPrimaryNode(); | 9739 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 9731 const intptr_t primary_pos = primary_node->token_pos(); | 9740 const intptr_t primary_pos = primary_node->token_pos(); |
| 9732 if (primary_node->primary().IsFunction()) { | 9741 if (primary_node->primary().IsFunction()) { |
| 9733 left = LoadClosure(primary_node); | 9742 left = LoadClosure(primary_node); |
| 9734 } else if (primary_node->primary().IsTypeParameter()) { | 9743 } else if (primary_node->primary().IsTypeParameter()) { |
| 9735 if (current_function().is_static()) { | 9744 if (current_function().is_static()) { |
| 9736 const String& name = String::ZoneHandle(I, | 9745 const String& name = String::ZoneHandle(Z, |
| 9737 TypeParameter::Cast(primary_node->primary()).name()); | 9746 TypeParameter::Cast(primary_node->primary()).name()); |
| 9738 ReportError(primary_pos, | 9747 ReportError(primary_pos, |
| 9739 "cannot access type parameter '%s' " | 9748 "cannot access type parameter '%s' " |
| 9740 "from static function", | 9749 "from static function", |
| 9741 name.ToCString()); | 9750 name.ToCString()); |
| 9742 } | 9751 } |
| 9743 if (current_block_->scope->function_level() > 0) { | 9752 if (current_block_->scope->function_level() > 0) { |
| 9744 // Make sure that the instantiator is captured. | 9753 // Make sure that the instantiator is captured. |
| 9745 CaptureInstantiator(); | 9754 CaptureInstantiator(); |
| 9746 } | 9755 } |
| 9747 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 9756 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
| 9748 type_parameter ^= ClassFinalizer::FinalizeType( | 9757 type_parameter ^= ClassFinalizer::FinalizeType( |
| 9749 current_class(), | 9758 current_class(), |
| 9750 TypeParameter::Cast(primary_node->primary()), | 9759 TypeParameter::Cast(primary_node->primary()), |
| 9751 ClassFinalizer::kCanonicalize); | 9760 ClassFinalizer::kCanonicalize); |
| 9752 ASSERT(!type_parameter.IsMalformed()); | 9761 ASSERT(!type_parameter.IsMalformed()); |
| 9753 left = new(I) TypeNode(primary->token_pos(), type_parameter); | 9762 left = new(Z) TypeNode(primary->token_pos(), type_parameter); |
| 9754 } else { | 9763 } else { |
| 9755 // Super field access handled in ParseSuperFieldAccess(), | 9764 // Super field access handled in ParseSuperFieldAccess(), |
| 9756 // super calls handled in ParseSuperCall(). | 9765 // super calls handled in ParseSuperCall(). |
| 9757 ASSERT(!primary_node->IsSuper()); | 9766 ASSERT(!primary_node->IsSuper()); |
| 9758 left = LoadFieldIfUnresolved(left); | 9767 left = LoadFieldIfUnresolved(left); |
| 9759 } | 9768 } |
| 9760 } | 9769 } |
| 9761 const intptr_t ident_pos = TokenPos(); | 9770 const intptr_t ident_pos = TokenPos(); |
| 9762 String* ident = ExpectIdentifier("identifier expected"); | 9771 String* ident = ExpectIdentifier("identifier expected"); |
| 9763 if (CurrentToken() == Token::kLPAREN) { | 9772 if (CurrentToken() == Token::kLPAREN) { |
| 9764 // Identifier followed by a opening paren: method call. | 9773 // Identifier followed by a opening paren: method call. |
| 9765 if (left->IsPrimaryNode() && | 9774 if (left->IsPrimaryNode() && |
| 9766 left->AsPrimaryNode()->primary().IsClass()) { | 9775 left->AsPrimaryNode()->primary().IsClass()) { |
| 9767 // Static method call prefixed with class name. | 9776 // Static method call prefixed with class name. |
| 9768 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); | 9777 const Class& cls = Class::Cast(left->AsPrimaryNode()->primary()); |
| 9769 selector = ParseStaticCall(cls, *ident, ident_pos); | 9778 selector = ParseStaticCall(cls, *ident, ident_pos); |
| 9770 } else { | 9779 } else { |
| 9771 selector = ParseInstanceCall(left, *ident); | 9780 selector = ParseInstanceCall(left, *ident); |
| 9772 } | 9781 } |
| 9773 } else { | 9782 } else { |
| 9774 // Field access. | 9783 // Field access. |
| 9775 Class& cls = Class::Handle(I); | 9784 Class& cls = Class::Handle(Z); |
| 9776 if (left->IsPrimaryNode()) { | 9785 if (left->IsPrimaryNode()) { |
| 9777 PrimaryNode* primary_node = left->AsPrimaryNode(); | 9786 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 9778 if (primary_node->primary().IsClass()) { | 9787 if (primary_node->primary().IsClass()) { |
| 9779 // If the primary node referred to a class we are loading a | 9788 // If the primary node referred to a class we are loading a |
| 9780 // qualified static field. | 9789 // qualified static field. |
| 9781 cls ^= primary_node->primary().raw(); | 9790 cls ^= primary_node->primary().raw(); |
| 9782 } | 9791 } |
| 9783 } | 9792 } |
| 9784 if (cls.IsNull()) { | 9793 if (cls.IsNull()) { |
| 9785 // Instance field access. | 9794 // Instance field access. |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 9802 SetAllowFunctionLiterals(saved_mode); | 9811 SetAllowFunctionLiterals(saved_mode); |
| 9803 ExpectToken(Token::kRBRACK); | 9812 ExpectToken(Token::kRBRACK); |
| 9804 AstNode* array = left; | 9813 AstNode* array = left; |
| 9805 if (left->IsPrimaryNode()) { | 9814 if (left->IsPrimaryNode()) { |
| 9806 PrimaryNode* primary_node = left->AsPrimaryNode(); | 9815 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 9807 const intptr_t primary_pos = primary_node->token_pos(); | 9816 const intptr_t primary_pos = primary_node->token_pos(); |
| 9808 if (primary_node->primary().IsFunction()) { | 9817 if (primary_node->primary().IsFunction()) { |
| 9809 array = LoadClosure(primary_node); | 9818 array = LoadClosure(primary_node); |
| 9810 } else if (primary_node->primary().IsClass()) { | 9819 } else if (primary_node->primary().IsClass()) { |
| 9811 const Class& type_class = Class::Cast(primary_node->primary()); | 9820 const Class& type_class = Class::Cast(primary_node->primary()); |
| 9812 AbstractType& type = Type::ZoneHandle(I, | 9821 AbstractType& type = Type::ZoneHandle(Z, |
| 9813 Type::New(type_class, TypeArguments::Handle(I), | 9822 Type::New(type_class, TypeArguments::Handle(Z), |
| 9814 primary_pos, Heap::kOld)); | 9823 primary_pos, Heap::kOld)); |
| 9815 type ^= ClassFinalizer::FinalizeType( | 9824 type ^= ClassFinalizer::FinalizeType( |
| 9816 current_class(), type, ClassFinalizer::kCanonicalize); | 9825 current_class(), type, ClassFinalizer::kCanonicalize); |
| 9817 // Type may be malbounded, but not malformed. | 9826 // Type may be malbounded, but not malformed. |
| 9818 ASSERT(!type.IsMalformed()); | 9827 ASSERT(!type.IsMalformed()); |
| 9819 array = new(I) TypeNode(primary_pos, type); | 9828 array = new(Z) TypeNode(primary_pos, type); |
| 9820 } else if (primary_node->primary().IsTypeParameter()) { | 9829 } else if (primary_node->primary().IsTypeParameter()) { |
| 9821 if (current_function().is_static()) { | 9830 if (current_function().is_static()) { |
| 9822 const String& name = String::ZoneHandle(I, | 9831 const String& name = String::ZoneHandle(Z, |
| 9823 TypeParameter::Cast(primary_node->primary()).name()); | 9832 TypeParameter::Cast(primary_node->primary()).name()); |
| 9824 ReportError(primary_pos, | 9833 ReportError(primary_pos, |
| 9825 "cannot access type parameter '%s' " | 9834 "cannot access type parameter '%s' " |
| 9826 "from static function", | 9835 "from static function", |
| 9827 name.ToCString()); | 9836 name.ToCString()); |
| 9828 } | 9837 } |
| 9829 if (current_block_->scope->function_level() > 0) { | 9838 if (current_block_->scope->function_level() > 0) { |
| 9830 // Make sure that the instantiator is captured. | 9839 // Make sure that the instantiator is captured. |
| 9831 CaptureInstantiator(); | 9840 CaptureInstantiator(); |
| 9832 } | 9841 } |
| 9833 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 9842 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
| 9834 type_parameter ^= ClassFinalizer::FinalizeType( | 9843 type_parameter ^= ClassFinalizer::FinalizeType( |
| 9835 current_class(), | 9844 current_class(), |
| 9836 TypeParameter::Cast(primary_node->primary()), | 9845 TypeParameter::Cast(primary_node->primary()), |
| 9837 ClassFinalizer::kCanonicalize); | 9846 ClassFinalizer::kCanonicalize); |
| 9838 ASSERT(!type_parameter.IsMalformed()); | 9847 ASSERT(!type_parameter.IsMalformed()); |
| 9839 array = new(I) TypeNode(primary_pos, type_parameter); | 9848 array = new(Z) TypeNode(primary_pos, type_parameter); |
| 9840 } else { | 9849 } else { |
| 9841 UNREACHABLE(); // Internal parser error. | 9850 UNREACHABLE(); // Internal parser error. |
| 9842 } | 9851 } |
| 9843 } | 9852 } |
| 9844 selector = new(I) LoadIndexedNode( | 9853 selector = new(Z) LoadIndexedNode( |
| 9845 bracket_pos, array, index, Class::ZoneHandle(I)); | 9854 bracket_pos, array, index, Class::ZoneHandle(Z)); |
| 9846 } else if (CurrentToken() == Token::kLPAREN) { | 9855 } else if (CurrentToken() == Token::kLPAREN) { |
| 9847 if (left->IsPrimaryNode()) { | 9856 if (left->IsPrimaryNode()) { |
| 9848 PrimaryNode* primary_node = left->AsPrimaryNode(); | 9857 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 9849 const intptr_t primary_pos = primary_node->token_pos(); | 9858 const intptr_t primary_pos = primary_node->token_pos(); |
| 9850 if (primary_node->primary().IsFunction()) { | 9859 if (primary_node->primary().IsFunction()) { |
| 9851 const Function& func = Function::Cast(primary_node->primary()); | 9860 const Function& func = Function::Cast(primary_node->primary()); |
| 9852 const String& func_name = String::ZoneHandle(I, func.name()); | 9861 const String& func_name = String::ZoneHandle(Z, func.name()); |
| 9853 if (func.is_static()) { | 9862 if (func.is_static()) { |
| 9854 // Parse static function call. | 9863 // Parse static function call. |
| 9855 Class& cls = Class::Handle(I, func.Owner()); | 9864 Class& cls = Class::Handle(Z, func.Owner()); |
| 9856 selector = ParseStaticCall(cls, func_name, primary_pos); | 9865 selector = ParseStaticCall(cls, func_name, primary_pos); |
| 9857 } else { | 9866 } else { |
| 9858 // Dynamic function call on implicit "this" parameter. | 9867 // Dynamic function call on implicit "this" parameter. |
| 9859 if (current_function().is_static()) { | 9868 if (current_function().is_static()) { |
| 9860 ReportError(primary_pos, | 9869 ReportError(primary_pos, |
| 9861 "cannot access instance method '%s' " | 9870 "cannot access instance method '%s' " |
| 9862 "from static function", | 9871 "from static function", |
| 9863 func_name.ToCString()); | 9872 func_name.ToCString()); |
| 9864 } | 9873 } |
| 9865 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); | 9874 selector = ParseInstanceCall(LoadReceiver(primary_pos), func_name); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 9877 name, | 9886 name, |
| 9878 NULL, // No arguments. | 9887 NULL, // No arguments. |
| 9879 InvocationMirror::kStatic, | 9888 InvocationMirror::kStatic, |
| 9880 InvocationMirror::kMethod, | 9889 InvocationMirror::kMethod, |
| 9881 NULL); // No existing function. | 9890 NULL); // No existing function. |
| 9882 } else { | 9891 } else { |
| 9883 // Treat as call to unresolved (instance) method. | 9892 // Treat as call to unresolved (instance) method. |
| 9884 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); | 9893 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); |
| 9885 } | 9894 } |
| 9886 } else if (primary_node->primary().IsTypeParameter()) { | 9895 } else if (primary_node->primary().IsTypeParameter()) { |
| 9887 const String& name = String::ZoneHandle(I, | 9896 const String& name = String::ZoneHandle(Z, |
| 9888 TypeParameter::Cast(primary_node->primary()).name()); | 9897 TypeParameter::Cast(primary_node->primary()).name()); |
| 9889 if (current_function().is_static()) { | 9898 if (current_function().is_static()) { |
| 9890 // Treat as this.T(), because T is in scope. | 9899 // Treat as this.T(), because T is in scope. |
| 9891 ReportError(primary_pos, | 9900 ReportError(primary_pos, |
| 9892 "cannot access type parameter '%s' " | 9901 "cannot access type parameter '%s' " |
| 9893 "from static function", | 9902 "from static function", |
| 9894 name.ToCString()); | 9903 name.ToCString()); |
| 9895 } else { | 9904 } else { |
| 9896 // Treat as call to unresolved (instance) method. | 9905 // Treat as call to unresolved (instance) method. |
| 9897 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); | 9906 selector = ParseInstanceCall(LoadReceiver(primary_pos), name); |
| 9898 } | 9907 } |
| 9899 } else if (primary_node->primary().IsClass()) { | 9908 } else if (primary_node->primary().IsClass()) { |
| 9900 const Class& type_class = Class::Cast(primary_node->primary()); | 9909 const Class& type_class = Class::Cast(primary_node->primary()); |
| 9901 AbstractType& type = Type::ZoneHandle(I, Type::New( | 9910 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
| 9902 type_class, TypeArguments::Handle(I), primary_pos)); | 9911 type_class, TypeArguments::Handle(Z), primary_pos)); |
| 9903 type ^= ClassFinalizer::FinalizeType( | 9912 type ^= ClassFinalizer::FinalizeType( |
| 9904 current_class(), type, ClassFinalizer::kCanonicalize); | 9913 current_class(), type, ClassFinalizer::kCanonicalize); |
| 9905 // Type may be malbounded, but not malformed. | 9914 // Type may be malbounded, but not malformed. |
| 9906 ASSERT(!type.IsMalformed()); | 9915 ASSERT(!type.IsMalformed()); |
| 9907 selector = new(I) TypeNode(primary_pos, type); | 9916 selector = new(Z) TypeNode(primary_pos, type); |
| 9908 } else { | 9917 } else { |
| 9909 UNREACHABLE(); // Internal parser error. | 9918 UNREACHABLE(); // Internal parser error. |
| 9910 } | 9919 } |
| 9911 } else { | 9920 } else { |
| 9912 // Left is not a primary node; this must be a closure call. | 9921 // Left is not a primary node; this must be a closure call. |
| 9913 AstNode* closure = left; | 9922 AstNode* closure = left; |
| 9914 selector = ParseClosureCall(closure); | 9923 selector = ParseClosureCall(closure); |
| 9915 } | 9924 } |
| 9916 } else { | 9925 } else { |
| 9917 // No (more) selectors to parse. | 9926 // No (more) selectors to parse. |
| 9918 left = LoadFieldIfUnresolved(left); | 9927 left = LoadFieldIfUnresolved(left); |
| 9919 if (left->IsPrimaryNode()) { | 9928 if (left->IsPrimaryNode()) { |
| 9920 PrimaryNode* primary_node = left->AsPrimaryNode(); | 9929 PrimaryNode* primary_node = left->AsPrimaryNode(); |
| 9921 const intptr_t primary_pos = primary->token_pos(); | 9930 const intptr_t primary_pos = primary->token_pos(); |
| 9922 if (primary_node->primary().IsFunction()) { | 9931 if (primary_node->primary().IsFunction()) { |
| 9923 // Treat as implicit closure. | 9932 // Treat as implicit closure. |
| 9924 left = LoadClosure(primary_node); | 9933 left = LoadClosure(primary_node); |
| 9925 } else if (primary_node->primary().IsClass()) { | 9934 } else if (primary_node->primary().IsClass()) { |
| 9926 const Class& type_class = Class::Cast(primary_node->primary()); | 9935 const Class& type_class = Class::Cast(primary_node->primary()); |
| 9927 AbstractType& type = Type::ZoneHandle(I, Type::New( | 9936 AbstractType& type = Type::ZoneHandle(Z, Type::New( |
| 9928 type_class, TypeArguments::Handle(I), primary_pos)); | 9937 type_class, TypeArguments::Handle(Z), primary_pos)); |
| 9929 type = ClassFinalizer::FinalizeType( | 9938 type = ClassFinalizer::FinalizeType( |
| 9930 current_class(), type, ClassFinalizer::kCanonicalize); | 9939 current_class(), type, ClassFinalizer::kCanonicalize); |
| 9931 // Type may be malbounded, but not malformed. | 9940 // Type may be malbounded, but not malformed. |
| 9932 ASSERT(!type.IsMalformed()); | 9941 ASSERT(!type.IsMalformed()); |
| 9933 left = new(I) TypeNode(primary_pos, type); | 9942 left = new(Z) TypeNode(primary_pos, type); |
| 9934 } else if (primary_node->primary().IsTypeParameter()) { | 9943 } else if (primary_node->primary().IsTypeParameter()) { |
| 9935 if (current_function().is_static()) { | 9944 if (current_function().is_static()) { |
| 9936 const String& name = String::ZoneHandle(I, | 9945 const String& name = String::ZoneHandle(Z, |
| 9937 TypeParameter::Cast(primary_node->primary()).name()); | 9946 TypeParameter::Cast(primary_node->primary()).name()); |
| 9938 ReportError(primary_pos, | 9947 ReportError(primary_pos, |
| 9939 "cannot access type parameter '%s' " | 9948 "cannot access type parameter '%s' " |
| 9940 "from static function", | 9949 "from static function", |
| 9941 name.ToCString()); | 9950 name.ToCString()); |
| 9942 } | 9951 } |
| 9943 if (current_block_->scope->function_level() > 0) { | 9952 if (current_block_->scope->function_level() > 0) { |
| 9944 // Make sure that the instantiator is captured. | 9953 // Make sure that the instantiator is captured. |
| 9945 CaptureInstantiator(); | 9954 CaptureInstantiator(); |
| 9946 } | 9955 } |
| 9947 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I); | 9956 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z); |
| 9948 type_parameter ^= ClassFinalizer::FinalizeType( | 9957 type_parameter ^= ClassFinalizer::FinalizeType( |
| 9949 current_class(), | 9958 current_class(), |
| 9950 TypeParameter::Cast(primary_node->primary()), | 9959 TypeParameter::Cast(primary_node->primary()), |
| 9951 ClassFinalizer::kCanonicalize); | 9960 ClassFinalizer::kCanonicalize); |
| 9952 ASSERT(!type_parameter.IsMalformed()); | 9961 ASSERT(!type_parameter.IsMalformed()); |
| 9953 left = new(I) TypeNode(primary_pos, type_parameter); | 9962 left = new(Z) TypeNode(primary_pos, type_parameter); |
| 9954 } else if (primary_node->IsSuper()) { | 9963 } else if (primary_node->IsSuper()) { |
| 9955 // Return "super" to handle unary super operator calls, | 9964 // Return "super" to handle unary super operator calls, |
| 9956 // or to report illegal use of "super" otherwise. | 9965 // or to report illegal use of "super" otherwise. |
| 9957 left = primary_node; | 9966 left = primary_node; |
| 9958 } else { | 9967 } else { |
| 9959 UNREACHABLE(); // Internal parser error. | 9968 UNREACHABLE(); // Internal parser error. |
| 9960 } | 9969 } |
| 9961 } | 9970 } |
| 9962 // Done parsing selectors. | 9971 // Done parsing selectors. |
| 9963 return left; | 9972 return left; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 9980 if (!IsLegalAssignableSyntax(expr, TokenPos())) { | 9989 if (!IsLegalAssignableSyntax(expr, TokenPos())) { |
| 9981 ReportError(expr_pos, "expression is not assignable"); | 9990 ReportError(expr_pos, "expression is not assignable"); |
| 9982 } | 9991 } |
| 9983 Token::Kind incr_op = CurrentToken(); | 9992 Token::Kind incr_op = CurrentToken(); |
| 9984 ConsumeToken(); | 9993 ConsumeToken(); |
| 9985 // Not prefix. | 9994 // Not prefix. |
| 9986 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); | 9995 LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr); |
| 9987 LocalVariable* temp = let_expr->AddInitializer(expr); | 9996 LocalVariable* temp = let_expr->AddInitializer(expr); |
| 9988 Token::Kind binary_op = | 9997 Token::Kind binary_op = |
| 9989 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; | 9998 (incr_op == Token::kINCR) ? Token::kADD : Token::kSUB; |
| 9990 BinaryOpNode* add = new(I) BinaryOpNode( | 9999 BinaryOpNode* add = new(Z) BinaryOpNode( |
| 9991 expr_pos, | 10000 expr_pos, |
| 9992 binary_op, | 10001 binary_op, |
| 9993 new(I) LoadLocalNode(expr_pos, temp), | 10002 new(Z) LoadLocalNode(expr_pos, temp), |
| 9994 new(I) LiteralNode(expr_pos, Smi::ZoneHandle(I, Smi::New(1)))); | 10003 new(Z) LiteralNode(expr_pos, Smi::ZoneHandle(Z, Smi::New(1)))); |
| 9995 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); | 10004 AstNode* store = CreateAssignmentNode(expr, add, expr_ident, expr_pos); |
| 9996 ASSERT(store != NULL); | 10005 ASSERT(store != NULL); |
| 9997 // The result is a pair of the (side effects of the) store followed by | 10006 // The result is a pair of the (side effects of the) store followed by |
| 9998 // the (value of the) initial value temp variable load. | 10007 // the (value of the) initial value temp variable load. |
| 9999 let_expr->AddNode(store); | 10008 let_expr->AddNode(store); |
| 10000 let_expr->AddNode(new(I) LoadLocalNode(expr_pos, temp)); | 10009 let_expr->AddNode(new(Z) LoadLocalNode(expr_pos, temp)); |
| 10001 return let_expr; | 10010 return let_expr; |
| 10002 } | 10011 } |
| 10003 return expr; | 10012 return expr; |
| 10004 } | 10013 } |
| 10005 | 10014 |
| 10006 | 10015 |
| 10007 // Resolve the given type and its type arguments from the given scope class | 10016 // Resolve the given type and its type arguments from the given scope class |
| 10008 // according to the given type finalization mode. | 10017 // according to the given type finalization mode. |
| 10009 // If the given scope class is null, use the current library, but do not try to | 10018 // If the given scope class is null, use the current library, but do not try to |
| 10010 // resolve type parameters. | 10019 // resolve type parameters. |
| 10011 // Not all involved type classes may get resolved yet, but at least the type | 10020 // Not all involved type classes may get resolved yet, but at least the type |
| 10012 // parameters of the given class will get resolved, thereby relieving the class | 10021 // parameters of the given class will get resolved, thereby relieving the class |
| 10013 // finalizer from resolving type parameters out of context. | 10022 // finalizer from resolving type parameters out of context. |
| 10014 void Parser::ResolveTypeFromClass(const Class& scope_class, | 10023 void Parser::ResolveTypeFromClass(const Class& scope_class, |
| 10015 ClassFinalizer::FinalizationKind finalization, | 10024 ClassFinalizer::FinalizationKind finalization, |
| 10016 AbstractType* type) { | 10025 AbstractType* type) { |
| 10017 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); | 10026 ASSERT(finalization >= ClassFinalizer::kResolveTypeParameters); |
| 10018 ASSERT(type != NULL); | 10027 ASSERT(type != NULL); |
| 10019 if (type->IsResolved()) { | 10028 if (type->IsResolved()) { |
| 10020 return; | 10029 return; |
| 10021 } | 10030 } |
| 10022 // Resolve class. | 10031 // Resolve class. |
| 10023 if (!type->HasResolvedTypeClass()) { | 10032 if (!type->HasResolvedTypeClass()) { |
| 10024 const UnresolvedClass& unresolved_class = | 10033 const UnresolvedClass& unresolved_class = |
| 10025 UnresolvedClass::Handle(I, type->unresolved_class()); | 10034 UnresolvedClass::Handle(Z, type->unresolved_class()); |
| 10026 const String& unresolved_class_name = | 10035 const String& unresolved_class_name = |
| 10027 String::Handle(I, unresolved_class.ident()); | 10036 String::Handle(Z, unresolved_class.ident()); |
| 10028 Class& resolved_type_class = Class::Handle(I); | 10037 Class& resolved_type_class = Class::Handle(Z); |
| 10029 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { | 10038 if (unresolved_class.library_prefix() == LibraryPrefix::null()) { |
| 10030 if (!scope_class.IsNull()) { | 10039 if (!scope_class.IsNull()) { |
| 10031 // First check if the type is a type parameter of the given scope class. | 10040 // First check if the type is a type parameter of the given scope class. |
| 10032 const TypeParameter& type_parameter = TypeParameter::Handle(I, | 10041 const TypeParameter& type_parameter = TypeParameter::Handle(Z, |
| 10033 scope_class.LookupTypeParameter(unresolved_class_name)); | 10042 scope_class.LookupTypeParameter(unresolved_class_name)); |
| 10034 if (!type_parameter.IsNull()) { | 10043 if (!type_parameter.IsNull()) { |
| 10035 // A type parameter is considered to be a malformed type when | 10044 // A type parameter is considered to be a malformed type when |
| 10036 // referenced by a static member. | 10045 // referenced by a static member. |
| 10037 if (ParsingStaticMember()) { | 10046 if (ParsingStaticMember()) { |
| 10038 ASSERT(scope_class.raw() == current_class().raw()); | 10047 ASSERT(scope_class.raw() == current_class().raw()); |
| 10039 *type = ClassFinalizer::NewFinalizedMalformedType( | 10048 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 10040 Error::Handle(I), // No previous error. | 10049 Error::Handle(Z), // No previous error. |
| 10041 script_, | 10050 script_, |
| 10042 type->token_pos(), | 10051 type->token_pos(), |
| 10043 "type parameter '%s' cannot be referenced " | 10052 "type parameter '%s' cannot be referenced " |
| 10044 "from static member", | 10053 "from static member", |
| 10045 String::Handle(I, type_parameter.name()).ToCString()); | 10054 String::Handle(Z, type_parameter.name()).ToCString()); |
| 10046 return; | 10055 return; |
| 10047 } | 10056 } |
| 10048 // A type parameter cannot be parameterized, so make the type | 10057 // A type parameter cannot be parameterized, so make the type |
| 10049 // malformed if type arguments have previously been parsed. | 10058 // malformed if type arguments have previously been parsed. |
| 10050 if (!TypeArguments::Handle(I, type->arguments()).IsNull()) { | 10059 if (!TypeArguments::Handle(Z, type->arguments()).IsNull()) { |
| 10051 *type = ClassFinalizer::NewFinalizedMalformedType( | 10060 *type = ClassFinalizer::NewFinalizedMalformedType( |
| 10052 Error::Handle(I), // No previous error. | 10061 Error::Handle(Z), // No previous error. |
| 10053 script_, | 10062 script_, |
| 10054 type_parameter.token_pos(), | 10063 type_parameter.token_pos(), |
| 10055 "type parameter '%s' cannot be parameterized", | 10064 "type parameter '%s' cannot be parameterized", |
| 10056 String::Handle(I, type_parameter.name()).ToCString()); | 10065 String::Handle(Z, type_parameter.name()).ToCString()); |
| 10057 return; | 10066 return; |
| 10058 } | 10067 } |
| 10059 *type = type_parameter.raw(); | 10068 *type = type_parameter.raw(); |
| 10060 return; | 10069 return; |
| 10061 } | 10070 } |
| 10062 } | 10071 } |
| 10063 // The referenced class may not have been parsed yet. It would be wrong | 10072 // The referenced class may not have been parsed yet. It would be wrong |
| 10064 // to resolve it too early to an imported class of the same name. | 10073 // to resolve it too early to an imported class of the same name. |
| 10065 if (finalization > ClassFinalizer::kResolveTypeParameters) { | 10074 if (finalization > ClassFinalizer::kResolveTypeParameters) { |
| 10066 // Resolve classname in the scope of the current library. | 10075 // Resolve classname in the scope of the current library. |
| 10067 resolved_type_class = ResolveClassInCurrentLibraryScope( | 10076 resolved_type_class = ResolveClassInCurrentLibraryScope( |
| 10068 unresolved_class_name); | 10077 unresolved_class_name); |
| 10069 } | 10078 } |
| 10070 } else { | 10079 } else { |
| 10071 LibraryPrefix& lib_prefix = | 10080 LibraryPrefix& lib_prefix = |
| 10072 LibraryPrefix::Handle(I, unresolved_class.library_prefix()); | 10081 LibraryPrefix::Handle(Z, unresolved_class.library_prefix()); |
| 10073 // Resolve class name in the scope of the library prefix. | 10082 // Resolve class name in the scope of the library prefix. |
| 10074 resolved_type_class = | 10083 resolved_type_class = |
| 10075 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); | 10084 ResolveClassInPrefixScope(lib_prefix, unresolved_class_name); |
| 10076 } | 10085 } |
| 10077 // At this point, we can only have a parameterized_type. | 10086 // At this point, we can only have a parameterized_type. |
| 10078 const Type& parameterized_type = Type::Cast(*type); | 10087 const Type& parameterized_type = Type::Cast(*type); |
| 10079 if (!resolved_type_class.IsNull()) { | 10088 if (!resolved_type_class.IsNull()) { |
| 10080 // Replace unresolved class with resolved type class. | 10089 // Replace unresolved class with resolved type class. |
| 10081 parameterized_type.set_type_class(resolved_type_class); | 10090 parameterized_type.set_type_class(resolved_type_class); |
| 10082 } else if (finalization >= ClassFinalizer::kCanonicalize) { | 10091 } else if (finalization >= ClassFinalizer::kCanonicalize) { |
| 10083 ClassFinalizer::FinalizeMalformedType( | 10092 ClassFinalizer::FinalizeMalformedType( |
| 10084 Error::Handle(I), // No previous error. | 10093 Error::Handle(Z), // No previous error. |
| 10085 script_, | 10094 script_, |
| 10086 parameterized_type, | 10095 parameterized_type, |
| 10087 "type '%s' is not loaded", | 10096 "type '%s' is not loaded", |
| 10088 String::Handle(I, parameterized_type.UserVisibleName()).ToCString()); | 10097 String::Handle(Z, parameterized_type.UserVisibleName()).ToCString()); |
| 10089 return; | 10098 return; |
| 10090 } | 10099 } |
| 10091 } | 10100 } |
| 10092 // Resolve type arguments, if any. | 10101 // Resolve type arguments, if any. |
| 10093 const TypeArguments& arguments = TypeArguments::Handle(I, type->arguments()); | 10102 const TypeArguments& arguments = TypeArguments::Handle(Z, type->arguments()); |
| 10094 TypeArguments::Handle(I, type->arguments()); | 10103 TypeArguments::Handle(Z, type->arguments()); |
| 10095 if (!arguments.IsNull()) { | 10104 if (!arguments.IsNull()) { |
| 10096 const intptr_t num_arguments = arguments.Length(); | 10105 const intptr_t num_arguments = arguments.Length(); |
| 10097 for (intptr_t i = 0; i < num_arguments; i++) { | 10106 for (intptr_t i = 0; i < num_arguments; i++) { |
| 10098 AbstractType& type_argument = AbstractType::Handle(I, | 10107 AbstractType& type_argument = AbstractType::Handle(Z, |
| 10099 arguments.TypeAt(i)); | 10108 arguments.TypeAt(i)); |
| 10100 ResolveTypeFromClass(scope_class, finalization, &type_argument); | 10109 ResolveTypeFromClass(scope_class, finalization, &type_argument); |
| 10101 arguments.SetTypeAt(i, type_argument); | 10110 arguments.SetTypeAt(i, type_argument); |
| 10102 } | 10111 } |
| 10103 } | 10112 } |
| 10104 } | 10113 } |
| 10105 | 10114 |
| 10106 | 10115 |
| 10107 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 10116 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
| 10108 if (current_block_ == NULL) { | 10117 if (current_block_ == NULL) { |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 10133 } | 10142 } |
| 10134 ASSERT(!current_function().IsNull()); | 10143 ASSERT(!current_function().IsNull()); |
| 10135 return | 10144 return |
| 10136 current_function().is_static() && !current_function().IsInFactoryScope(); | 10145 current_function().is_static() && !current_function().IsInFactoryScope(); |
| 10137 } | 10146 } |
| 10138 | 10147 |
| 10139 | 10148 |
| 10140 const AbstractType* Parser::ReceiverType(const Class& cls) { | 10149 const AbstractType* Parser::ReceiverType(const Class& cls) { |
| 10141 ASSERT(!cls.IsNull()); | 10150 ASSERT(!cls.IsNull()); |
| 10142 const TypeArguments& type_arguments = TypeArguments::Handle( | 10151 const TypeArguments& type_arguments = TypeArguments::Handle( |
| 10143 I, | 10152 Z, |
| 10144 (cls.NumTypeParameters() > 0) ? | 10153 (cls.NumTypeParameters() > 0) ? |
| 10145 cls.type_parameters() : TypeArguments::null()); | 10154 cls.type_parameters() : TypeArguments::null()); |
| 10146 AbstractType& type = AbstractType::ZoneHandle( | 10155 AbstractType& type = AbstractType::ZoneHandle( |
| 10147 I, Type::New(cls, type_arguments, cls.token_pos())); | 10156 Z, Type::New(cls, type_arguments, cls.token_pos())); |
| 10148 if (cls.is_type_finalized()) { | 10157 if (cls.is_type_finalized()) { |
| 10149 type ^= ClassFinalizer::FinalizeType( | 10158 type ^= ClassFinalizer::FinalizeType( |
| 10150 cls, type, ClassFinalizer::kCanonicalizeWellFormed); | 10159 cls, type, ClassFinalizer::kCanonicalizeWellFormed); |
| 10151 // Note that the receiver type may now be a malbounded type. | 10160 // Note that the receiver type may now be a malbounded type. |
| 10152 } | 10161 } |
| 10153 return &type; | 10162 return &type; |
| 10154 } | 10163 } |
| 10155 | 10164 |
| 10156 | 10165 |
| 10157 bool Parser::IsInstantiatorRequired() const { | 10166 bool Parser::IsInstantiatorRequired() const { |
| 10158 ASSERT(!current_function().IsNull()); | 10167 ASSERT(!current_function().IsNull()); |
| 10159 if (current_function().is_static() && | 10168 if (current_function().is_static() && |
| 10160 !current_function().IsInFactoryScope()) { | 10169 !current_function().IsInFactoryScope()) { |
| 10161 return false; | 10170 return false; |
| 10162 } | 10171 } |
| 10163 return current_class().NumTypeParameters() > 0; | 10172 return current_class().NumTypeParameters() > 0; |
| 10164 } | 10173 } |
| 10165 | 10174 |
| 10166 | 10175 |
| 10167 RawInstance* Parser::TryCanonicalize(const Instance& instance, | 10176 RawInstance* Parser::TryCanonicalize(const Instance& instance, |
| 10168 intptr_t token_pos) { | 10177 intptr_t token_pos) { |
| 10169 if (instance.IsNull()) { | 10178 if (instance.IsNull()) { |
| 10170 return instance.raw(); | 10179 return instance.raw(); |
| 10171 } | 10180 } |
| 10172 const char* error_str = NULL; | 10181 const char* error_str = NULL; |
| 10173 Instance& result = | 10182 Instance& result = |
| 10174 Instance::Handle(I, instance.CheckAndCanonicalize(&error_str)); | 10183 Instance::Handle(Z, instance.CheckAndCanonicalize(&error_str)); |
| 10175 if (result.IsNull()) { | 10184 if (result.IsNull()) { |
| 10176 ReportError(token_pos, "Invalid const object %s", error_str); | 10185 ReportError(token_pos, "Invalid const object %s", error_str); |
| 10177 } | 10186 } |
| 10178 return result.raw(); | 10187 return result.raw(); |
| 10179 } | 10188 } |
| 10180 | 10189 |
| 10181 | 10190 |
| 10182 // If the field is already initialized, return no ast (NULL). | 10191 // If the field is already initialized, return no ast (NULL). |
| 10183 // Otherwise, if the field is constant, initialize the field and return no ast. | 10192 // Otherwise, if the field is constant, initialize the field and return no ast. |
| 10184 // If the field is not initialized and not const, return the ast for the getter. | 10193 // If the field is not initialized and not const, return the ast for the getter. |
| 10185 AstNode* Parser::RunStaticFieldInitializer(const Field& field, | 10194 AstNode* Parser::RunStaticFieldInitializer(const Field& field, |
| 10186 intptr_t field_ref_pos) { | 10195 intptr_t field_ref_pos) { |
| 10187 ASSERT(field.is_static()); | 10196 ASSERT(field.is_static()); |
| 10188 const Class& field_owner = Class::ZoneHandle(I, field.owner()); | 10197 const Class& field_owner = Class::ZoneHandle(Z, field.owner()); |
| 10189 const String& field_name = String::ZoneHandle(I, field.name()); | 10198 const String& field_name = String::ZoneHandle(Z, field.name()); |
| 10190 const String& getter_name = String::Handle(I, Field::GetterName(field_name)); | 10199 const String& getter_name = String::Handle(Z, Field::GetterName(field_name)); |
| 10191 const Function& getter = Function::Handle(I, | 10200 const Function& getter = Function::Handle(Z, |
| 10192 field_owner.LookupStaticFunction(getter_name)); | 10201 field_owner.LookupStaticFunction(getter_name)); |
| 10193 const Instance& value = Instance::Handle(I, field.value()); | 10202 const Instance& value = Instance::Handle(Z, field.value()); |
| 10194 if (value.raw() == Object::transition_sentinel().raw()) { | 10203 if (value.raw() == Object::transition_sentinel().raw()) { |
| 10195 if (field.is_const()) { | 10204 if (field.is_const()) { |
| 10196 ReportError("circular dependency while initializing static field '%s'", | 10205 ReportError("circular dependency while initializing static field '%s'", |
| 10197 field_name.ToCString()); | 10206 field_name.ToCString()); |
| 10198 } else { | 10207 } else { |
| 10199 // The implicit static getter will throw the exception if necessary. | 10208 // The implicit static getter will throw the exception if necessary. |
| 10200 return new(I) StaticGetterNode( | 10209 return new(Z) StaticGetterNode( |
| 10201 field_ref_pos, NULL, false, field_owner, field_name); | 10210 field_ref_pos, NULL, false, field_owner, field_name); |
| 10202 } | 10211 } |
| 10203 } else if (value.raw() == Object::sentinel().raw()) { | 10212 } else if (value.raw() == Object::sentinel().raw()) { |
| 10204 // This field has not been referenced yet and thus the value has | 10213 // This field has not been referenced yet and thus the value has |
| 10205 // not been evaluated. If the field is const, call the static getter method | 10214 // not been evaluated. If the field is const, call the static getter method |
| 10206 // to evaluate the expression and canonicalize the value. | 10215 // to evaluate the expression and canonicalize the value. |
| 10207 if (field.is_const()) { | 10216 if (field.is_const()) { |
| 10208 field.set_value(Object::transition_sentinel()); | 10217 field.set_value(Object::transition_sentinel()); |
| 10209 const int kNumArguments = 0; // no arguments. | 10218 const int kNumArguments = 0; // no arguments. |
| 10210 const Function& func = Function::Handle(I, | 10219 const Function& func = Function::Handle(Z, |
| 10211 Resolver::ResolveStatic(field_owner, | 10220 Resolver::ResolveStatic(field_owner, |
| 10212 getter_name, | 10221 getter_name, |
| 10213 kNumArguments, | 10222 kNumArguments, |
| 10214 Object::empty_array())); | 10223 Object::empty_array())); |
| 10215 ASSERT(!func.IsNull()); | 10224 ASSERT(!func.IsNull()); |
| 10216 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); | 10225 ASSERT(func.kind() == RawFunction::kImplicitStaticFinalGetter); |
| 10217 Object& const_value = Object::Handle(I); | 10226 Object& const_value = Object::Handle(Z); |
| 10218 { | 10227 { |
| 10219 PAUSETIMERSCOPE(I, time_compilation); | 10228 PAUSETIMERSCOPE(I, time_compilation); |
| 10220 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); | 10229 const_value = DartEntry::InvokeFunction(func, Object::empty_array()); |
| 10221 } | 10230 } |
| 10222 if (const_value.IsError()) { | 10231 if (const_value.IsError()) { |
| 10223 const Error& error = Error::Cast(const_value); | 10232 const Error& error = Error::Cast(const_value); |
| 10224 if (error.IsUnhandledException()) { | 10233 if (error.IsUnhandledException()) { |
| 10225 // An exception may not occur in every parse attempt, i.e., the | 10234 // An exception may not occur in every parse attempt, i.e., the |
| 10226 // generated AST is not deterministic. Therefore mark the function as | 10235 // generated AST is not deterministic. Therefore mark the function as |
| 10227 // not optimizable. | 10236 // not optimizable. |
| 10228 current_function().SetIsOptimizable(false); | 10237 current_function().SetIsOptimizable(false); |
| 10229 field.set_value(Object::null_instance()); | 10238 field.set_value(Object::null_instance()); |
| 10230 // It is a compile-time error if evaluation of a compile-time constant | 10239 // It is a compile-time error if evaluation of a compile-time constant |
| 10231 // would raise an exception. | 10240 // would raise an exception. |
| 10232 const String& field_name = String::Handle(I, field.name()); | 10241 const String& field_name = String::Handle(Z, field.name()); |
| 10233 ReportErrors(error, | 10242 ReportErrors(error, |
| 10234 script_, field_ref_pos, | 10243 script_, field_ref_pos, |
| 10235 "error initializing const field '%s'", | 10244 "error initializing const field '%s'", |
| 10236 field_name.ToCString()); | 10245 field_name.ToCString()); |
| 10237 } else { | 10246 } else { |
| 10238 ReportError(error); | 10247 ReportError(error); |
| 10239 } | 10248 } |
| 10240 UNREACHABLE(); | 10249 UNREACHABLE(); |
| 10241 } | 10250 } |
| 10242 ASSERT(const_value.IsNull() || const_value.IsInstance()); | 10251 ASSERT(const_value.IsNull() || const_value.IsInstance()); |
| 10243 Instance& instance = Instance::Handle(I); | 10252 Instance& instance = Instance::Handle(Z); |
| 10244 instance ^= const_value.raw(); | 10253 instance ^= const_value.raw(); |
| 10245 instance = TryCanonicalize(instance, field_ref_pos); | 10254 instance = TryCanonicalize(instance, field_ref_pos); |
| 10246 field.set_value(instance); | 10255 field.set_value(instance); |
| 10247 return NULL; // Constant | 10256 return NULL; // Constant |
| 10248 } else { | 10257 } else { |
| 10249 return new(I) StaticGetterNode( | 10258 return new(Z) StaticGetterNode( |
| 10250 field_ref_pos, NULL, false, field_owner, field_name); | 10259 field_ref_pos, NULL, false, field_owner, field_name); |
| 10251 } | 10260 } |
| 10252 } | 10261 } |
| 10253 if (getter.IsNull() || | 10262 if (getter.IsNull() || |
| 10254 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { | 10263 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)) { |
| 10255 return NULL; | 10264 return NULL; |
| 10256 } | 10265 } |
| 10257 ASSERT(getter.kind() == RawFunction::kImplicitGetter); | 10266 ASSERT(getter.kind() == RawFunction::kImplicitGetter); |
| 10258 return new(I) StaticGetterNode( | 10267 return new(Z) StaticGetterNode( |
| 10259 field_ref_pos, NULL, false, field_owner, field_name); | 10268 field_ref_pos, NULL, false, field_owner, field_name); |
| 10260 } | 10269 } |
| 10261 | 10270 |
| 10262 | 10271 |
| 10263 RawObject* Parser::EvaluateConstConstructorCall( | 10272 RawObject* Parser::EvaluateConstConstructorCall( |
| 10264 const Class& type_class, | 10273 const Class& type_class, |
| 10265 const TypeArguments& type_arguments, | 10274 const TypeArguments& type_arguments, |
| 10266 const Function& constructor, | 10275 const Function& constructor, |
| 10267 ArgumentListNode* arguments) { | 10276 ArgumentListNode* arguments) { |
| 10268 // Factories have one extra argument: the type arguments. | 10277 // Factories have one extra argument: the type arguments. |
| 10269 // Constructors have 2 extra arguments: rcvr and construction phase. | 10278 // Constructors have 2 extra arguments: rcvr and construction phase. |
| 10270 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; | 10279 const int kNumExtraArgs = constructor.IsFactory() ? 1 : 2; |
| 10271 const int num_arguments = arguments->length() + kNumExtraArgs; | 10280 const int num_arguments = arguments->length() + kNumExtraArgs; |
| 10272 const Array& arg_values = Array::Handle(I, Array::New(num_arguments)); | 10281 const Array& arg_values = Array::Handle(Z, Array::New(num_arguments)); |
| 10273 Instance& instance = Instance::Handle(I); | 10282 Instance& instance = Instance::Handle(Z); |
| 10274 if (!constructor.IsFactory()) { | 10283 if (!constructor.IsFactory()) { |
| 10275 instance = Instance::New(type_class, Heap::kOld); | 10284 instance = Instance::New(type_class, Heap::kOld); |
| 10276 if (!type_arguments.IsNull()) { | 10285 if (!type_arguments.IsNull()) { |
| 10277 if (!type_arguments.IsInstantiated()) { | 10286 if (!type_arguments.IsInstantiated()) { |
| 10278 ReportError("type must be constant in const constructor"); | 10287 ReportError("type must be constant in const constructor"); |
| 10279 } | 10288 } |
| 10280 instance.SetTypeArguments( | 10289 instance.SetTypeArguments( |
| 10281 TypeArguments::Handle(I, type_arguments.Canonicalize())); | 10290 TypeArguments::Handle(Z, type_arguments.Canonicalize())); |
| 10282 } | 10291 } |
| 10283 arg_values.SetAt(0, instance); | 10292 arg_values.SetAt(0, instance); |
| 10284 arg_values.SetAt(1, Smi::Handle(I, Smi::New(Function::kCtorPhaseAll))); | 10293 arg_values.SetAt(1, Smi::Handle(Z, Smi::New(Function::kCtorPhaseAll))); |
| 10285 } else { | 10294 } else { |
| 10286 // Prepend type_arguments to list of arguments to factory. | 10295 // Prepend type_arguments to list of arguments to factory. |
| 10287 ASSERT(type_arguments.IsZoneHandle()); | 10296 ASSERT(type_arguments.IsZoneHandle()); |
| 10288 arg_values.SetAt(0, type_arguments); | 10297 arg_values.SetAt(0, type_arguments); |
| 10289 } | 10298 } |
| 10290 for (int i = 0; i < arguments->length(); i++) { | 10299 for (int i = 0; i < arguments->length(); i++) { |
| 10291 AstNode* arg = arguments->NodeAt(i); | 10300 AstNode* arg = arguments->NodeAt(i); |
| 10292 // Arguments have been evaluated to a literal value already. | 10301 // Arguments have been evaluated to a literal value already. |
| 10293 ASSERT(arg->IsLiteralNode()); | 10302 ASSERT(arg->IsLiteralNode()); |
| 10294 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); | 10303 arg_values.SetAt((i + kNumExtraArgs), arg->AsLiteralNode()->literal()); |
| 10295 } | 10304 } |
| 10296 const Array& args_descriptor = Array::Handle(I, | 10305 const Array& args_descriptor = Array::Handle(Z, |
| 10297 ArgumentsDescriptor::New(num_arguments, arguments->names())); | 10306 ArgumentsDescriptor::New(num_arguments, arguments->names())); |
| 10298 Object& result = Object::Handle(I); | 10307 Object& result = Object::Handle(Z); |
| 10299 { | 10308 { |
| 10300 PAUSETIMERSCOPE(I, time_compilation); | 10309 PAUSETIMERSCOPE(I, time_compilation); |
| 10301 result = DartEntry::InvokeFunction( | 10310 result = DartEntry::InvokeFunction( |
| 10302 constructor, arg_values, args_descriptor); | 10311 constructor, arg_values, args_descriptor); |
| 10303 } | 10312 } |
| 10304 if (result.IsError()) { | 10313 if (result.IsError()) { |
| 10305 // An exception may not occur in every parse attempt, i.e., the | 10314 // An exception may not occur in every parse attempt, i.e., the |
| 10306 // generated AST is not deterministic. Therefore mark the function as | 10315 // generated AST is not deterministic. Therefore mark the function as |
| 10307 // not optimizable. | 10316 // not optimizable. |
| 10308 current_function().SetIsOptimizable(false); | 10317 current_function().SetIsOptimizable(false); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 10330 const String &ident, | 10339 const String &ident, |
| 10331 AstNode** node) { | 10340 AstNode** node) { |
| 10332 TRACE_PARSER("ResolveIdentInLocalScope"); | 10341 TRACE_PARSER("ResolveIdentInLocalScope"); |
| 10333 // First try to find the identifier in the nested local scopes. | 10342 // First try to find the identifier in the nested local scopes. |
| 10334 LocalVariable* local = LookupLocalScope(ident); | 10343 LocalVariable* local = LookupLocalScope(ident); |
| 10335 if (current_block_ != NULL) { | 10344 if (current_block_ != NULL) { |
| 10336 current_block_->scope->AddReferencedName(ident_pos, ident); | 10345 current_block_->scope->AddReferencedName(ident_pos, ident); |
| 10337 } | 10346 } |
| 10338 if (local != NULL) { | 10347 if (local != NULL) { |
| 10339 if (node != NULL) { | 10348 if (node != NULL) { |
| 10340 *node = new(I) LoadLocalNode(ident_pos, local); | 10349 *node = new(Z) LoadLocalNode(ident_pos, local); |
| 10341 } | 10350 } |
| 10342 return true; | 10351 return true; |
| 10343 } | 10352 } |
| 10344 | 10353 |
| 10345 // Try to find the identifier in the class scope of the current class. | 10354 // Try to find the identifier in the class scope of the current class. |
| 10346 // If the current class is the result of a mixin application, we must | 10355 // If the current class is the result of a mixin application, we must |
| 10347 // use the class scope of the class from which the function originates. | 10356 // use the class scope of the class from which the function originates. |
| 10348 Class& cls = Class::Handle(I); | 10357 Class& cls = Class::Handle(Z); |
| 10349 if (!current_class().IsMixinApplication()) { | 10358 if (!current_class().IsMixinApplication()) { |
| 10350 cls = current_class().raw(); | 10359 cls = current_class().raw(); |
| 10351 } else { | 10360 } else { |
| 10352 cls = parsed_function()->function().origin(); | 10361 cls = parsed_function()->function().origin(); |
| 10353 } | 10362 } |
| 10354 Function& func = Function::Handle(I, Function::null()); | 10363 Function& func = Function::Handle(Z, Function::null()); |
| 10355 Field& field = Field::Handle(I, Field::null()); | 10364 Field& field = Field::Handle(Z, Field::null()); |
| 10356 | 10365 |
| 10357 // First check if a field exists. | 10366 // First check if a field exists. |
| 10358 field = cls.LookupField(ident); | 10367 field = cls.LookupField(ident); |
| 10359 if (!field.IsNull()) { | 10368 if (!field.IsNull()) { |
| 10360 if (node != NULL) { | 10369 if (node != NULL) { |
| 10361 if (!field.is_static()) { | 10370 if (!field.is_static()) { |
| 10362 CheckInstanceFieldAccess(ident_pos, ident); | 10371 CheckInstanceFieldAccess(ident_pos, ident); |
| 10363 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 10372 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 10364 } else { | 10373 } else { |
| 10365 *node = GenerateStaticFieldLookup(field, ident_pos); | 10374 *node = GenerateStaticFieldLookup(field, ident_pos); |
| 10366 } | 10375 } |
| 10367 } | 10376 } |
| 10368 return true; | 10377 return true; |
| 10369 } | 10378 } |
| 10370 | 10379 |
| 10371 // Check if an instance/static function exists. | 10380 // Check if an instance/static function exists. |
| 10372 func = cls.LookupFunction(ident); | 10381 func = cls.LookupFunction(ident); |
| 10373 if (!func.IsNull() && | 10382 if (!func.IsNull() && |
| 10374 (func.IsDynamicFunction() || | 10383 (func.IsDynamicFunction() || |
| 10375 func.IsStaticFunction() || | 10384 func.IsStaticFunction() || |
| 10376 func.is_abstract())) { | 10385 func.is_abstract())) { |
| 10377 if (node != NULL) { | 10386 if (node != NULL) { |
| 10378 *node = new(I) PrimaryNode( | 10387 *node = new(Z) PrimaryNode( |
| 10379 ident_pos, Function::ZoneHandle(I, func.raw())); | 10388 ident_pos, Function::ZoneHandle(Z, func.raw())); |
| 10380 } | 10389 } |
| 10381 return true; | 10390 return true; |
| 10382 } | 10391 } |
| 10383 | 10392 |
| 10384 // Now check if a getter/setter method exists for it in which case | 10393 // Now check if a getter/setter method exists for it in which case |
| 10385 // it is still a field. | 10394 // it is still a field. |
| 10386 func = cls.LookupGetterFunction(ident); | 10395 func = cls.LookupGetterFunction(ident); |
| 10387 if (!func.IsNull()) { | 10396 if (!func.IsNull()) { |
| 10388 if (func.IsDynamicFunction() || func.is_abstract()) { | 10397 if (func.IsDynamicFunction() || func.is_abstract()) { |
| 10389 if (node != NULL) { | 10398 if (node != NULL) { |
| 10390 CheckInstanceFieldAccess(ident_pos, ident); | 10399 CheckInstanceFieldAccess(ident_pos, ident); |
| 10391 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 10400 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 10392 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 10401 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 10393 } | 10402 } |
| 10394 return true; | 10403 return true; |
| 10395 } else if (func.IsStaticFunction()) { | 10404 } else if (func.IsStaticFunction()) { |
| 10396 if (node != NULL) { | 10405 if (node != NULL) { |
| 10397 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 10406 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 10398 // The static getter may later be changed into a dynamically | 10407 // The static getter may later be changed into a dynamically |
| 10399 // resolved instance setter if no static setter can | 10408 // resolved instance setter if no static setter can |
| 10400 // be found. | 10409 // be found. |
| 10401 AstNode* receiver = NULL; | 10410 AstNode* receiver = NULL; |
| 10402 const bool kTestOnly = true; | 10411 const bool kTestOnly = true; |
| 10403 if (!current_function().is_static() && | 10412 if (!current_function().is_static() && |
| 10404 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { | 10413 (LookupReceiver(current_block_->scope, kTestOnly) != NULL)) { |
| 10405 receiver = LoadReceiver(ident_pos); | 10414 receiver = LoadReceiver(ident_pos); |
| 10406 } | 10415 } |
| 10407 *node = new(I) StaticGetterNode(ident_pos, | 10416 *node = new(Z) StaticGetterNode(ident_pos, |
| 10408 receiver, | 10417 receiver, |
| 10409 false, | 10418 false, |
| 10410 Class::ZoneHandle(I, cls.raw()), | 10419 Class::ZoneHandle(Z, cls.raw()), |
| 10411 ident); | 10420 ident); |
| 10412 } | 10421 } |
| 10413 return true; | 10422 return true; |
| 10414 } | 10423 } |
| 10415 } | 10424 } |
| 10416 func = cls.LookupSetterFunction(ident); | 10425 func = cls.LookupSetterFunction(ident); |
| 10417 if (!func.IsNull()) { | 10426 if (!func.IsNull()) { |
| 10418 if (func.IsDynamicFunction() || func.is_abstract()) { | 10427 if (func.IsDynamicFunction() || func.is_abstract()) { |
| 10419 if (node != NULL) { | 10428 if (node != NULL) { |
| 10420 // We create a getter node even though a getter doesn't exist as | 10429 // We create a getter node even though a getter doesn't exist as |
| 10421 // it could be followed by an assignment which will convert it to | 10430 // it could be followed by an assignment which will convert it to |
| 10422 // a setter node. If there is no assignment we will get an error | 10431 // a setter node. If there is no assignment we will get an error |
| 10423 // when we try to invoke the getter. | 10432 // when we try to invoke the getter. |
| 10424 CheckInstanceFieldAccess(ident_pos, ident); | 10433 CheckInstanceFieldAccess(ident_pos, ident); |
| 10425 ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved()); | 10434 ASSERT(AbstractType::Handle(Z, func.result_type()).IsResolved()); |
| 10426 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 10435 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 10427 } | 10436 } |
| 10428 return true; | 10437 return true; |
| 10429 } else if (func.IsStaticFunction()) { | 10438 } else if (func.IsStaticFunction()) { |
| 10430 if (node != NULL) { | 10439 if (node != NULL) { |
| 10431 // We create a getter node even though a getter doesn't exist as | 10440 // We create a getter node even though a getter doesn't exist as |
| 10432 // it could be followed by an assignment which will convert it to | 10441 // it could be followed by an assignment which will convert it to |
| 10433 // a setter node. If there is no assignment we will get an error | 10442 // a setter node. If there is no assignment we will get an error |
| 10434 // when we try to invoke the getter. | 10443 // when we try to invoke the getter. |
| 10435 *node = new(I) StaticGetterNode( | 10444 *node = new(Z) StaticGetterNode( |
| 10436 ident_pos, | 10445 ident_pos, |
| 10437 NULL, | 10446 NULL, |
| 10438 false, | 10447 false, |
| 10439 Class::ZoneHandle(I, cls.raw()), | 10448 Class::ZoneHandle(Z, cls.raw()), |
| 10440 ident); | 10449 ident); |
| 10441 } | 10450 } |
| 10442 return true; | 10451 return true; |
| 10443 } | 10452 } |
| 10444 } | 10453 } |
| 10445 | 10454 |
| 10446 // Nothing found in scope of current class. | 10455 // Nothing found in scope of current class. |
| 10447 if (node != NULL) { | 10456 if (node != NULL) { |
| 10448 *node = NULL; | 10457 *node = NULL; |
| 10449 } | 10458 } |
| 10450 return false; // Not an unqualified identifier. | 10459 return false; // Not an unqualified identifier. |
| 10451 } | 10460 } |
| 10452 | 10461 |
| 10453 | 10462 |
| 10454 RawClass* Parser::ResolveClassInCurrentLibraryScope(const String& name) { | 10463 RawClass* Parser::ResolveClassInCurrentLibraryScope(const String& name) { |
| 10455 HANDLESCOPE(I); | 10464 HANDLESCOPE(I); |
| 10456 const Object& obj = Object::Handle(I, library_.ResolveName(name)); | 10465 const Object& obj = Object::Handle(Z, library_.ResolveName(name)); |
| 10457 if (obj.IsClass()) { | 10466 if (obj.IsClass()) { |
| 10458 return Class::Cast(obj).raw(); | 10467 return Class::Cast(obj).raw(); |
| 10459 } | 10468 } |
| 10460 return Class::null(); | 10469 return Class::null(); |
| 10461 } | 10470 } |
| 10462 | 10471 |
| 10463 | 10472 |
| 10464 // Resolve an identifier by checking the global scope of the current | 10473 // Resolve an identifier by checking the global scope of the current |
| 10465 // library. If not found in the current library, then look in the scopes | 10474 // library. If not found in the current library, then look in the scopes |
| 10466 // of all libraries that are imported without a library prefix. | 10475 // of all libraries that are imported without a library prefix. |
| 10467 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 10476 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, |
| 10468 const String& ident) { | 10477 const String& ident) { |
| 10469 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 10478 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
| 10470 HANDLESCOPE(I); | 10479 HANDLESCOPE(I); |
| 10471 const Object& obj = Object::Handle(I, library_.ResolveName(ident)); | 10480 const Object& obj = Object::Handle(Z, library_.ResolveName(ident)); |
| 10472 if (obj.IsClass()) { | 10481 if (obj.IsClass()) { |
| 10473 const Class& cls = Class::Cast(obj); | 10482 const Class& cls = Class::Cast(obj); |
| 10474 return new(I) PrimaryNode(ident_pos, Class::ZoneHandle(I, cls.raw())); | 10483 return new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
| 10475 } else if (obj.IsField()) { | 10484 } else if (obj.IsField()) { |
| 10476 const Field& field = Field::Cast(obj); | 10485 const Field& field = Field::Cast(obj); |
| 10477 ASSERT(field.is_static()); | 10486 ASSERT(field.is_static()); |
| 10478 return GenerateStaticFieldLookup(field, ident_pos); | 10487 return GenerateStaticFieldLookup(field, ident_pos); |
| 10479 } else if (obj.IsFunction()) { | 10488 } else if (obj.IsFunction()) { |
| 10480 const Function& func = Function::Cast(obj); | 10489 const Function& func = Function::Cast(obj); |
| 10481 ASSERT(func.is_static()); | 10490 ASSERT(func.is_static()); |
| 10482 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 10491 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
| 10483 return new(I) StaticGetterNode(ident_pos, | 10492 return new(Z) StaticGetterNode(ident_pos, |
| 10484 /* receiver */ NULL, | 10493 /* receiver */ NULL, |
| 10485 /* is_super_getter */ false, | 10494 /* is_super_getter */ false, |
| 10486 Class::ZoneHandle(I, func.Owner()), | 10495 Class::ZoneHandle(Z, func.Owner()), |
| 10487 ident); | 10496 ident); |
| 10488 | 10497 |
| 10489 } else { | 10498 } else { |
| 10490 return new(I) PrimaryNode(ident_pos, Function::ZoneHandle(I, func.raw())); | 10499 return new(Z) PrimaryNode(ident_pos, Function::ZoneHandle(Z, func.raw())); |
| 10491 } | 10500 } |
| 10492 } else { | 10501 } else { |
| 10493 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); | 10502 ASSERT(obj.IsNull() || obj.IsLibraryPrefix()); |
| 10494 } | 10503 } |
| 10495 // Lexically unresolved primary identifiers are referenced by their name. | 10504 // Lexically unresolved primary identifiers are referenced by their name. |
| 10496 return new(I) PrimaryNode(ident_pos, ident); | 10505 return new(Z) PrimaryNode(ident_pos, ident); |
| 10497 } | 10506 } |
| 10498 | 10507 |
| 10499 | 10508 |
| 10500 RawClass* Parser::ResolveClassInPrefixScope(const LibraryPrefix& prefix, | 10509 RawClass* Parser::ResolveClassInPrefixScope(const LibraryPrefix& prefix, |
| 10501 const String& name) { | 10510 const String& name) { |
| 10502 HANDLESCOPE(I); | 10511 HANDLESCOPE(I); |
| 10503 const Object& obj = Object::Handle(I, prefix.LookupObject(name)); | 10512 const Object& obj = Object::Handle(Z, prefix.LookupObject(name)); |
| 10504 if (obj.IsClass()) { | 10513 if (obj.IsClass()) { |
| 10505 return Class::Cast(obj).raw(); | 10514 return Class::Cast(obj).raw(); |
| 10506 } | 10515 } |
| 10507 return Class::null(); | 10516 return Class::null(); |
| 10508 } | 10517 } |
| 10509 | 10518 |
| 10510 | 10519 |
| 10511 // Do a lookup for the identifier in the scope of the specified | 10520 // Do a lookup for the identifier in the scope of the specified |
| 10512 // library prefix. This means trying to resolve it locally in all of the | 10521 // library prefix. This means trying to resolve it locally in all of the |
| 10513 // libraries present in the library prefix. | 10522 // libraries present in the library prefix. |
| 10514 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 10523 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, |
| 10515 const LibraryPrefix& prefix, | 10524 const LibraryPrefix& prefix, |
| 10516 const String& ident) { | 10525 const String& ident) { |
| 10517 TRACE_PARSER("ResolveIdentInPrefixScope"); | 10526 TRACE_PARSER("ResolveIdentInPrefixScope"); |
| 10518 HANDLESCOPE(I); | 10527 HANDLESCOPE(I); |
| 10519 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { | 10528 if (ident.CharAt(0) == Library::kPrivateIdentifierStart) { |
| 10520 // Private names are not exported by libraries. The name mangling | 10529 // Private names are not exported by libraries. The name mangling |
| 10521 // of private names with a library-specific suffix usually ensures | 10530 // of private names with a library-specific suffix usually ensures |
| 10522 // that _x in library A is not found when looked up from library B. | 10531 // that _x in library A is not found when looked up from library B. |
| 10523 // In the pathological case where a library includes itself with | 10532 // In the pathological case where a library includes itself with |
| 10524 // a prefix, the name mangling would not help in hiding the private | 10533 // a prefix, the name mangling would not help in hiding the private |
| 10525 // name, so we need to explicitly reject private names here. | 10534 // name, so we need to explicitly reject private names here. |
| 10526 return NULL; | 10535 return NULL; |
| 10527 } | 10536 } |
| 10528 Object& obj = Object::Handle(I); | 10537 Object& obj = Object::Handle(Z); |
| 10529 if (prefix.is_loaded()) { | 10538 if (prefix.is_loaded()) { |
| 10530 obj = prefix.LookupObject(ident); | 10539 obj = prefix.LookupObject(ident); |
| 10531 } else { | 10540 } else { |
| 10532 // Remember that this function depends on an import prefix of an | 10541 // Remember that this function depends on an import prefix of an |
| 10533 // unloaded deferred library. Note that parsed_function() can be | 10542 // unloaded deferred library. Note that parsed_function() can be |
| 10534 // NULL when parsing expressions outside the scope of a function. | 10543 // NULL when parsing expressions outside the scope of a function. |
| 10535 if (parsed_function() != NULL) { | 10544 if (parsed_function() != NULL) { |
| 10536 parsed_function()->AddDeferredPrefix(prefix); | 10545 parsed_function()->AddDeferredPrefix(prefix); |
| 10537 } | 10546 } |
| 10538 } | 10547 } |
| 10539 const bool is_deferred = prefix.is_deferred_load(); | 10548 const bool is_deferred = prefix.is_deferred_load(); |
| 10540 if (obj.IsNull()) { | 10549 if (obj.IsNull()) { |
| 10541 // Unresolved prefixed primary identifier. | 10550 // Unresolved prefixed primary identifier. |
| 10542 return NULL; | 10551 return NULL; |
| 10543 } else if (obj.IsClass()) { | 10552 } else if (obj.IsClass()) { |
| 10544 const Class& cls = Class::Cast(obj); | 10553 const Class& cls = Class::Cast(obj); |
| 10545 PrimaryNode* primary = | 10554 PrimaryNode* primary = |
| 10546 new(I) PrimaryNode(ident_pos, Class::ZoneHandle(I, cls.raw())); | 10555 new(Z) PrimaryNode(ident_pos, Class::ZoneHandle(Z, cls.raw())); |
| 10547 primary->set_is_deferred(is_deferred); | 10556 primary->set_is_deferred(is_deferred); |
| 10548 return primary; | 10557 return primary; |
| 10549 } else if (obj.IsField()) { | 10558 } else if (obj.IsField()) { |
| 10550 const Field& field = Field::Cast(obj); | 10559 const Field& field = Field::Cast(obj); |
| 10551 ASSERT(field.is_static()); | 10560 ASSERT(field.is_static()); |
| 10552 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); | 10561 AstNode* get_field = GenerateStaticFieldLookup(field, ident_pos); |
| 10553 ASSERT(get_field != NULL); | 10562 ASSERT(get_field != NULL); |
| 10554 ASSERT(get_field->IsLoadStaticFieldNode() || | 10563 ASSERT(get_field->IsLoadStaticFieldNode() || |
| 10555 get_field->IsStaticGetterNode()); | 10564 get_field->IsStaticGetterNode()); |
| 10556 if (get_field->IsLoadStaticFieldNode()) { | 10565 if (get_field->IsLoadStaticFieldNode()) { |
| 10557 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); | 10566 get_field->AsLoadStaticFieldNode()->set_is_deferred(is_deferred); |
| 10558 } else if (get_field->IsStaticGetterNode()) { | 10567 } else if (get_field->IsStaticGetterNode()) { |
| 10559 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); | 10568 get_field->AsStaticGetterNode()->set_is_deferred(is_deferred); |
| 10560 } | 10569 } |
| 10561 return get_field; | 10570 return get_field; |
| 10562 } else if (obj.IsFunction()) { | 10571 } else if (obj.IsFunction()) { |
| 10563 const Function& func = Function::Cast(obj); | 10572 const Function& func = Function::Cast(obj); |
| 10564 ASSERT(func.is_static()); | 10573 ASSERT(func.is_static()); |
| 10565 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 10574 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
| 10566 StaticGetterNode* getter = new(I) StaticGetterNode( | 10575 StaticGetterNode* getter = new(Z) StaticGetterNode( |
| 10567 ident_pos, | 10576 ident_pos, |
| 10568 /* receiver */ NULL, | 10577 /* receiver */ NULL, |
| 10569 /* is_super_getter */ false, | 10578 /* is_super_getter */ false, |
| 10570 Class::ZoneHandle(I, func.Owner()), | 10579 Class::ZoneHandle(Z, func.Owner()), |
| 10571 ident); | 10580 ident); |
| 10572 getter->set_is_deferred(is_deferred); | 10581 getter->set_is_deferred(is_deferred); |
| 10573 return getter; | 10582 return getter; |
| 10574 } else { | 10583 } else { |
| 10575 PrimaryNode* primary = new(I) PrimaryNode( | 10584 PrimaryNode* primary = new(Z) PrimaryNode( |
| 10576 ident_pos, Function::ZoneHandle(I, func.raw())); | 10585 ident_pos, Function::ZoneHandle(Z, func.raw())); |
| 10577 primary->set_is_deferred(is_deferred); | 10586 primary->set_is_deferred(is_deferred); |
| 10578 return primary; | 10587 return primary; |
| 10579 } | 10588 } |
| 10580 } | 10589 } |
| 10581 // All possible object types are handled above. | 10590 // All possible object types are handled above. |
| 10582 UNREACHABLE(); | 10591 UNREACHABLE(); |
| 10583 return NULL; | 10592 return NULL; |
| 10584 } | 10593 } |
| 10585 | 10594 |
| 10586 | 10595 |
| 10587 // Resolve identifier. Issue an error message if | 10596 // Resolve identifier. Issue an error message if |
| 10588 // the ident refers to a method and allow_closure_names is false. | 10597 // the ident refers to a method and allow_closure_names is false. |
| 10589 // If the name cannot be resolved, turn it into an instance field access | 10598 // If the name cannot be resolved, turn it into an instance field access |
| 10590 // if we're compiling an instance method, or generate | 10599 // if we're compiling an instance method, or generate |
| 10591 // throw NoSuchMethodError if we're compiling a static method. | 10600 // throw NoSuchMethodError if we're compiling a static method. |
| 10592 AstNode* Parser::ResolveIdent(intptr_t ident_pos, | 10601 AstNode* Parser::ResolveIdent(intptr_t ident_pos, |
| 10593 const String& ident, | 10602 const String& ident, |
| 10594 bool allow_closure_names) { | 10603 bool allow_closure_names) { |
| 10595 TRACE_PARSER("ResolveIdent"); | 10604 TRACE_PARSER("ResolveIdent"); |
| 10596 // First try to find the variable in the local scope (block scope or | 10605 // First try to find the variable in the local scope (block scope or |
| 10597 // class scope). | 10606 // class scope). |
| 10598 AstNode* resolved = NULL; | 10607 AstNode* resolved = NULL; |
| 10599 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 10608 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
| 10600 if (resolved == NULL) { | 10609 if (resolved == NULL) { |
| 10601 // Check whether the identifier is a type parameter. | 10610 // Check whether the identifier is a type parameter. |
| 10602 if (!current_class().IsNull()) { | 10611 if (!current_class().IsNull()) { |
| 10603 TypeParameter& type_parameter = TypeParameter::ZoneHandle(I, | 10612 TypeParameter& type_parameter = TypeParameter::ZoneHandle(Z, |
| 10604 current_class().LookupTypeParameter(ident)); | 10613 current_class().LookupTypeParameter(ident)); |
| 10605 if (!type_parameter.IsNull()) { | 10614 if (!type_parameter.IsNull()) { |
| 10606 if (current_block_->scope->function_level() > 0) { | 10615 if (current_block_->scope->function_level() > 0) { |
| 10607 // Make sure that the instantiator is captured. | 10616 // Make sure that the instantiator is captured. |
| 10608 CaptureInstantiator(); | 10617 CaptureInstantiator(); |
| 10609 } | 10618 } |
| 10610 type_parameter ^= ClassFinalizer::FinalizeType( | 10619 type_parameter ^= ClassFinalizer::FinalizeType( |
| 10611 current_class(), type_parameter, ClassFinalizer::kCanonicalize); | 10620 current_class(), type_parameter, ClassFinalizer::kCanonicalize); |
| 10612 ASSERT(!type_parameter.IsMalformed()); | 10621 ASSERT(!type_parameter.IsMalformed()); |
| 10613 return new(I) TypeNode(ident_pos, type_parameter); | 10622 return new(Z) TypeNode(ident_pos, type_parameter); |
| 10614 } | 10623 } |
| 10615 } | 10624 } |
| 10616 // Not found in the local scope, and the name is not a type parameter. | 10625 // Not found in the local scope, and the name is not a type parameter. |
| 10617 // Try finding the variable in the library scope (current library | 10626 // Try finding the variable in the library scope (current library |
| 10618 // and all libraries imported by it without a library prefix). | 10627 // and all libraries imported by it without a library prefix). |
| 10619 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); | 10628 resolved = ResolveIdentInCurrentLibraryScope(ident_pos, ident); |
| 10620 } | 10629 } |
| 10621 if (resolved->IsPrimaryNode()) { | 10630 if (resolved->IsPrimaryNode()) { |
| 10622 PrimaryNode* primary = resolved->AsPrimaryNode(); | 10631 PrimaryNode* primary = resolved->AsPrimaryNode(); |
| 10623 const intptr_t primary_pos = primary->token_pos(); | 10632 const intptr_t primary_pos = primary->token_pos(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 10641 } | 10650 } |
| 10642 } else if (primary->primary().IsFunction()) { | 10651 } else if (primary->primary().IsFunction()) { |
| 10643 if (allow_closure_names) { | 10652 if (allow_closure_names) { |
| 10644 resolved = LoadClosure(primary); | 10653 resolved = LoadClosure(primary); |
| 10645 } else { | 10654 } else { |
| 10646 ReportError(ident_pos, "illegal reference to method '%s'", | 10655 ReportError(ident_pos, "illegal reference to method '%s'", |
| 10647 ident.ToCString()); | 10656 ident.ToCString()); |
| 10648 } | 10657 } |
| 10649 } else if (primary->primary().IsClass()) { | 10658 } else if (primary->primary().IsClass()) { |
| 10650 const Class& type_class = Class::Cast(primary->primary()); | 10659 const Class& type_class = Class::Cast(primary->primary()); |
| 10651 AbstractType& type = Type::ZoneHandle(I, | 10660 AbstractType& type = Type::ZoneHandle(Z, |
| 10652 Type::New(type_class, TypeArguments::Handle(I), primary_pos)); | 10661 Type::New(type_class, TypeArguments::Handle(Z), primary_pos)); |
| 10653 type ^= ClassFinalizer::FinalizeType( | 10662 type ^= ClassFinalizer::FinalizeType( |
| 10654 current_class(), type, ClassFinalizer::kCanonicalize); | 10663 current_class(), type, ClassFinalizer::kCanonicalize); |
| 10655 // Type may be malbounded, but not malformed. | 10664 // Type may be malbounded, but not malformed. |
| 10656 ASSERT(!type.IsMalformed()); | 10665 ASSERT(!type.IsMalformed()); |
| 10657 resolved = new(I) TypeNode(primary_pos, type); | 10666 resolved = new(Z) TypeNode(primary_pos, type); |
| 10658 } | 10667 } |
| 10659 } | 10668 } |
| 10660 return resolved; | 10669 return resolved; |
| 10661 } | 10670 } |
| 10662 | 10671 |
| 10663 | 10672 |
| 10664 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 10673 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
| 10665 // finalize it according to the given type finalization mode. | 10674 // finalize it according to the given type finalization mode. |
| 10666 RawAbstractType* Parser::ParseType( | 10675 RawAbstractType* Parser::ParseType( |
| 10667 ClassFinalizer::FinalizationKind finalization, | 10676 ClassFinalizer::FinalizationKind finalization, |
| 10668 bool allow_deferred_type, | 10677 bool allow_deferred_type, |
| 10669 bool consume_unresolved_prefix) { | 10678 bool consume_unresolved_prefix) { |
| 10670 TRACE_PARSER("ParseType"); | 10679 TRACE_PARSER("ParseType"); |
| 10671 CheckToken(Token::kIDENT, "type name expected"); | 10680 CheckToken(Token::kIDENT, "type name expected"); |
| 10672 intptr_t ident_pos = TokenPos(); | 10681 intptr_t ident_pos = TokenPos(); |
| 10673 LibraryPrefix& prefix = LibraryPrefix::Handle(I); | 10682 LibraryPrefix& prefix = LibraryPrefix::Handle(Z); |
| 10674 String& type_name = String::Handle(I);; | 10683 String& type_name = String::Handle(Z);; |
| 10675 | 10684 |
| 10676 if (finalization == ClassFinalizer::kIgnore) { | 10685 if (finalization == ClassFinalizer::kIgnore) { |
| 10677 if (!is_top_level_ && (current_block_ != NULL)) { | 10686 if (!is_top_level_ && (current_block_ != NULL)) { |
| 10678 // Add the library prefix or type class name to the list of referenced | 10687 // Add the library prefix or type class name to the list of referenced |
| 10679 // names of this scope, even if the type is ignored. | 10688 // names of this scope, even if the type is ignored. |
| 10680 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); | 10689 current_block_->scope->AddReferencedName(TokenPos(), *CurrentLiteral()); |
| 10681 } | 10690 } |
| 10682 SkipQualIdent(); | 10691 SkipQualIdent(); |
| 10683 } else { | 10692 } else { |
| 10684 prefix = ParsePrefix(); | 10693 prefix = ParsePrefix(); |
| 10685 type_name = CurrentLiteral()->raw(); | 10694 type_name = CurrentLiteral()->raw(); |
| 10686 ConsumeToken(); | 10695 ConsumeToken(); |
| 10687 | 10696 |
| 10688 // Check whether we have a malformed qualified type name if the caller | 10697 // Check whether we have a malformed qualified type name if the caller |
| 10689 // requests to consume unresolved prefix names: | 10698 // requests to consume unresolved prefix names: |
| 10690 // If we didn't see a valid prefix but the identifier is followed by | 10699 // If we didn't see a valid prefix but the identifier is followed by |
| 10691 // a period and another identifier, consume the qualified identifier | 10700 // a period and another identifier, consume the qualified identifier |
| 10692 // and create a malformed type. | 10701 // and create a malformed type. |
| 10693 if (consume_unresolved_prefix && | 10702 if (consume_unresolved_prefix && |
| 10694 prefix.IsNull() && | 10703 prefix.IsNull() && |
| 10695 (CurrentToken() == Token::kPERIOD) && | 10704 (CurrentToken() == Token::kPERIOD) && |
| 10696 (Token::IsIdentifier(LookaheadToken(1)))) { | 10705 (Token::IsIdentifier(LookaheadToken(1)))) { |
| 10697 if (!is_top_level_ && (current_block_ != NULL)) { | 10706 if (!is_top_level_ && (current_block_ != NULL)) { |
| 10698 // Add the unresolved prefix name to the list of referenced | 10707 // Add the unresolved prefix name to the list of referenced |
| 10699 // names of this scope. | 10708 // names of this scope. |
| 10700 current_block_->scope->AddReferencedName(TokenPos(), type_name); | 10709 current_block_->scope->AddReferencedName(TokenPos(), type_name); |
| 10701 } | 10710 } |
| 10702 ConsumeToken(); // Period token. | 10711 ConsumeToken(); // Period token. |
| 10703 ASSERT(IsIdentifier()); | 10712 ASSERT(IsIdentifier()); |
| 10704 String& qualified_name = String::Handle(I, type_name.raw()); | 10713 String& qualified_name = String::Handle(Z, type_name.raw()); |
| 10705 qualified_name = String::Concat(qualified_name, Symbols::Dot()); | 10714 qualified_name = String::Concat(qualified_name, Symbols::Dot()); |
| 10706 qualified_name = String::Concat(qualified_name, *CurrentLiteral()); | 10715 qualified_name = String::Concat(qualified_name, *CurrentLiteral()); |
| 10707 ConsumeToken(); | 10716 ConsumeToken(); |
| 10708 // The type is malformed. Skip over its type arguments. | 10717 // The type is malformed. Skip over its type arguments. |
| 10709 ParseTypeArguments(ClassFinalizer::kIgnore); | 10718 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 10710 return ClassFinalizer::NewFinalizedMalformedType( | 10719 return ClassFinalizer::NewFinalizedMalformedType( |
| 10711 Error::Handle(I), // No previous error. | 10720 Error::Handle(Z), // No previous error. |
| 10712 script_, | 10721 script_, |
| 10713 ident_pos, | 10722 ident_pos, |
| 10714 "qualified name '%s' does not refer to a type", | 10723 "qualified name '%s' does not refer to a type", |
| 10715 qualified_name.ToCString()); | 10724 qualified_name.ToCString()); |
| 10716 } | 10725 } |
| 10717 | 10726 |
| 10718 // If parsing inside a local scope, check whether the type name | 10727 // If parsing inside a local scope, check whether the type name |
| 10719 // is shadowed by a local declaration. | 10728 // is shadowed by a local declaration. |
| 10720 if (!is_top_level_ && | 10729 if (!is_top_level_ && |
| 10721 (prefix.IsNull()) && | 10730 (prefix.IsNull()) && |
| 10722 ResolveIdentInLocalScope(ident_pos, type_name, NULL)) { | 10731 ResolveIdentInLocalScope(ident_pos, type_name, NULL)) { |
| 10723 // The type is malformed. Skip over its type arguments. | 10732 // The type is malformed. Skip over its type arguments. |
| 10724 ParseTypeArguments(ClassFinalizer::kIgnore); | 10733 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 10725 return ClassFinalizer::NewFinalizedMalformedType( | 10734 return ClassFinalizer::NewFinalizedMalformedType( |
| 10726 Error::Handle(I), // No previous error. | 10735 Error::Handle(Z), // No previous error. |
| 10727 script_, | 10736 script_, |
| 10728 ident_pos, | 10737 ident_pos, |
| 10729 "using '%s' in this context is invalid", | 10738 "using '%s' in this context is invalid", |
| 10730 type_name.ToCString()); | 10739 type_name.ToCString()); |
| 10731 } | 10740 } |
| 10732 if (!prefix.IsNull() && prefix.is_deferred_load() && !allow_deferred_type) { | 10741 if (!prefix.IsNull() && prefix.is_deferred_load() && !allow_deferred_type) { |
| 10733 ParseTypeArguments(ClassFinalizer::kIgnore); | 10742 ParseTypeArguments(ClassFinalizer::kIgnore); |
| 10734 return ClassFinalizer::NewFinalizedMalformedType( | 10743 return ClassFinalizer::NewFinalizedMalformedType( |
| 10735 Error::Handle(I), // No previous error. | 10744 Error::Handle(Z), // No previous error. |
| 10736 script_, | 10745 script_, |
| 10737 ident_pos, | 10746 ident_pos, |
| 10738 "using deferred type '%s.%s' is invalid", | 10747 "using deferred type '%s.%s' is invalid", |
| 10739 String::Handle(I, prefix.name()).ToCString(), | 10748 String::Handle(Z, prefix.name()).ToCString(), |
| 10740 type_name.ToCString()); | 10749 type_name.ToCString()); |
| 10741 } | 10750 } |
| 10742 } | 10751 } |
| 10743 Object& type_class = Object::Handle(I); | 10752 Object& type_class = Object::Handle(Z); |
| 10744 // Leave type_class as null if type finalization mode is kIgnore. | 10753 // Leave type_class as null if type finalization mode is kIgnore. |
| 10745 if (finalization != ClassFinalizer::kIgnore) { | 10754 if (finalization != ClassFinalizer::kIgnore) { |
| 10746 type_class = UnresolvedClass::New(prefix, type_name, ident_pos); | 10755 type_class = UnresolvedClass::New(prefix, type_name, ident_pos); |
| 10747 } | 10756 } |
| 10748 TypeArguments& type_arguments = TypeArguments::Handle( | 10757 TypeArguments& type_arguments = TypeArguments::Handle( |
| 10749 I, ParseTypeArguments(finalization)); | 10758 Z, ParseTypeArguments(finalization)); |
| 10750 if (finalization == ClassFinalizer::kIgnore) { | 10759 if (finalization == ClassFinalizer::kIgnore) { |
| 10751 return Type::DynamicType(); | 10760 return Type::DynamicType(); |
| 10752 } | 10761 } |
| 10753 AbstractType& type = AbstractType::Handle( | 10762 AbstractType& type = AbstractType::Handle( |
| 10754 I, Type::New(type_class, type_arguments, ident_pos)); | 10763 Z, Type::New(type_class, type_arguments, ident_pos)); |
| 10755 if (finalization >= ClassFinalizer::kResolveTypeParameters) { | 10764 if (finalization >= ClassFinalizer::kResolveTypeParameters) { |
| 10756 ResolveTypeFromClass(current_class(), finalization, &type); | 10765 ResolveTypeFromClass(current_class(), finalization, &type); |
| 10757 if (finalization >= ClassFinalizer::kCanonicalize) { | 10766 if (finalization >= ClassFinalizer::kCanonicalize) { |
| 10758 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); | 10767 type ^= ClassFinalizer::FinalizeType(current_class(), type, finalization); |
| 10759 } | 10768 } |
| 10760 } | 10769 } |
| 10761 return type.raw(); | 10770 return type.raw(); |
| 10762 } | 10771 } |
| 10763 | 10772 |
| 10764 | 10773 |
| 10765 void Parser::CheckConstructorCallTypeArguments( | 10774 void Parser::CheckConstructorCallTypeArguments( |
| 10766 intptr_t pos, const Function& constructor, | 10775 intptr_t pos, const Function& constructor, |
| 10767 const TypeArguments& type_arguments) { | 10776 const TypeArguments& type_arguments) { |
| 10768 if (!type_arguments.IsNull()) { | 10777 if (!type_arguments.IsNull()) { |
| 10769 const Class& constructor_class = Class::Handle(I, constructor.Owner()); | 10778 const Class& constructor_class = Class::Handle(Z, constructor.Owner()); |
| 10770 ASSERT(!constructor_class.IsNull()); | 10779 ASSERT(!constructor_class.IsNull()); |
| 10771 ASSERT(constructor_class.is_finalized()); | 10780 ASSERT(constructor_class.is_finalized()); |
| 10772 ASSERT(type_arguments.IsCanonical()); | 10781 ASSERT(type_arguments.IsCanonical()); |
| 10773 // Do not report the expected vs. actual number of type arguments, because | 10782 // Do not report the expected vs. actual number of type arguments, because |
| 10774 // the type argument vector is flattened and raw types are allowed. | 10783 // the type argument vector is flattened and raw types are allowed. |
| 10775 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { | 10784 if (type_arguments.Length() != constructor_class.NumTypeArguments()) { |
| 10776 ReportError(pos, "wrong number of type arguments passed to constructor"); | 10785 ReportError(pos, "wrong number of type arguments passed to constructor"); |
| 10777 } | 10786 } |
| 10778 } | 10787 } |
| 10779 } | 10788 } |
| 10780 | 10789 |
| 10781 | 10790 |
| 10782 // Parse "[" [ expr { "," expr } ["," ] "]". | 10791 // Parse "[" [ expr { "," expr } ["," ] "]". |
| 10783 // Note: if the list literal is empty and the brackets have no whitespace | 10792 // Note: if the list literal is empty and the brackets have no whitespace |
| 10784 // between them, the scanner recognizes the opening and closing bracket | 10793 // between them, the scanner recognizes the opening and closing bracket |
| 10785 // as one token of type Token::kINDEX. | 10794 // as one token of type Token::kINDEX. |
| 10786 AstNode* Parser::ParseListLiteral(intptr_t type_pos, | 10795 AstNode* Parser::ParseListLiteral(intptr_t type_pos, |
| 10787 bool is_const, | 10796 bool is_const, |
| 10788 const TypeArguments& type_arguments) { | 10797 const TypeArguments& type_arguments) { |
| 10789 TRACE_PARSER("ParseListLiteral"); | 10798 TRACE_PARSER("ParseListLiteral"); |
| 10790 ASSERT(type_pos >= 0); | 10799 ASSERT(type_pos >= 0); |
| 10791 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); | 10800 ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX); |
| 10792 const intptr_t literal_pos = TokenPos(); | 10801 const intptr_t literal_pos = TokenPos(); |
| 10793 bool is_empty_literal = CurrentToken() == Token::kINDEX; | 10802 bool is_empty_literal = CurrentToken() == Token::kINDEX; |
| 10794 ConsumeToken(); | 10803 ConsumeToken(); |
| 10795 | 10804 |
| 10796 AbstractType& element_type = Type::ZoneHandle(I, Type::DynamicType()); | 10805 AbstractType& element_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 10797 TypeArguments& list_type_arguments = | 10806 TypeArguments& list_type_arguments = |
| 10798 TypeArguments::ZoneHandle(I, type_arguments.raw()); | 10807 TypeArguments::ZoneHandle(Z, type_arguments.raw()); |
| 10799 // If no type argument vector is provided, leave it as null, which is | 10808 // If no type argument vector is provided, leave it as null, which is |
| 10800 // equivalent to using dynamic as the type argument for the element type. | 10809 // equivalent to using dynamic as the type argument for the element type. |
| 10801 if (!list_type_arguments.IsNull()) { | 10810 if (!list_type_arguments.IsNull()) { |
| 10802 ASSERT(list_type_arguments.Length() > 0); | 10811 ASSERT(list_type_arguments.Length() > 0); |
| 10803 // List literals take a single type argument. | 10812 // List literals take a single type argument. |
| 10804 if (list_type_arguments.Length() == 1) { | 10813 if (list_type_arguments.Length() == 1) { |
| 10805 element_type = list_type_arguments.TypeAt(0); | 10814 element_type = list_type_arguments.TypeAt(0); |
| 10806 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. | 10815 ASSERT(!element_type.IsMalformed()); // Would be mapped to dynamic. |
| 10807 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. | 10816 ASSERT(!element_type.IsMalbounded()); // No declared bound in List. |
| 10808 if (element_type.IsDynamicType()) { | 10817 if (element_type.IsDynamicType()) { |
| 10809 list_type_arguments = TypeArguments::null(); | 10818 list_type_arguments = TypeArguments::null(); |
| 10810 } else if (is_const && !element_type.IsInstantiated()) { | 10819 } else if (is_const && !element_type.IsInstantiated()) { |
| 10811 ReportError(type_pos, | 10820 ReportError(type_pos, |
| 10812 "the type argument of a constant list literal cannot " | 10821 "the type argument of a constant list literal cannot " |
| 10813 "include a type variable"); | 10822 "include a type variable"); |
| 10814 } | 10823 } |
| 10815 } else { | 10824 } else { |
| 10816 if (FLAG_error_on_bad_type) { | 10825 if (FLAG_error_on_bad_type) { |
| 10817 ReportError(type_pos, | 10826 ReportError(type_pos, |
| 10818 "a list literal takes one type argument specifying " | 10827 "a list literal takes one type argument specifying " |
| 10819 "the element type"); | 10828 "the element type"); |
| 10820 } | 10829 } |
| 10821 // Ignore type arguments. | 10830 // Ignore type arguments. |
| 10822 list_type_arguments = TypeArguments::null(); | 10831 list_type_arguments = TypeArguments::null(); |
| 10823 } | 10832 } |
| 10824 } | 10833 } |
| 10825 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); | 10834 ASSERT(list_type_arguments.IsNull() || (list_type_arguments.Length() == 1)); |
| 10826 const Class& array_class = Class::Handle(I, I->object_store()->array_class()); | 10835 const Class& array_class = Class::Handle(Z, I->object_store()->array_class()); |
| 10827 Type& type = Type::ZoneHandle(I, | 10836 Type& type = Type::ZoneHandle(Z, |
| 10828 Type::New(array_class, list_type_arguments, type_pos)); | 10837 Type::New(array_class, list_type_arguments, type_pos)); |
| 10829 type ^= ClassFinalizer::FinalizeType( | 10838 type ^= ClassFinalizer::FinalizeType( |
| 10830 current_class(), type, ClassFinalizer::kCanonicalize); | 10839 current_class(), type, ClassFinalizer::kCanonicalize); |
| 10831 GrowableArray<AstNode*> element_list; | 10840 GrowableArray<AstNode*> element_list; |
| 10832 // Parse the list elements. Note: there may be an optional extra | 10841 // Parse the list elements. Note: there may be an optional extra |
| 10833 // comma after the last element. | 10842 // comma after the last element. |
| 10834 if (!is_empty_literal) { | 10843 if (!is_empty_literal) { |
| 10835 const bool saved_mode = SetAllowFunctionLiterals(true); | 10844 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 10836 while (CurrentToken() != Token::kRBRACK) { | 10845 while (CurrentToken() != Token::kRBRACK) { |
| 10837 const intptr_t element_pos = TokenPos(); | 10846 const intptr_t element_pos = TokenPos(); |
| 10838 AstNode* element = ParseExpr(is_const, kConsumeCascades); | 10847 AstNode* element = ParseExpr(is_const, kConsumeCascades); |
| 10839 if (FLAG_enable_type_checks && | 10848 if (FLAG_enable_type_checks && |
| 10840 !is_const && | 10849 !is_const && |
| 10841 !element_type.IsDynamicType()) { | 10850 !element_type.IsDynamicType()) { |
| 10842 element = new(I) AssignableNode(element_pos, | 10851 element = new(Z) AssignableNode(element_pos, |
| 10843 element, | 10852 element, |
| 10844 element_type, | 10853 element_type, |
| 10845 Symbols::ListLiteralElement()); | 10854 Symbols::ListLiteralElement()); |
| 10846 } | 10855 } |
| 10847 element_list.Add(element); | 10856 element_list.Add(element); |
| 10848 if (CurrentToken() == Token::kCOMMA) { | 10857 if (CurrentToken() == Token::kCOMMA) { |
| 10849 ConsumeToken(); | 10858 ConsumeToken(); |
| 10850 } else if (CurrentToken() != Token::kRBRACK) { | 10859 } else if (CurrentToken() != Token::kRBRACK) { |
| 10851 ReportError("comma or ']' expected"); | 10860 ReportError("comma or ']' expected"); |
| 10852 } | 10861 } |
| 10853 } | 10862 } |
| 10854 ExpectToken(Token::kRBRACK); | 10863 ExpectToken(Token::kRBRACK); |
| 10855 SetAllowFunctionLiterals(saved_mode); | 10864 SetAllowFunctionLiterals(saved_mode); |
| 10856 } | 10865 } |
| 10857 | 10866 |
| 10858 if (is_const) { | 10867 if (is_const) { |
| 10859 // Allocate and initialize the const list at compile time. | 10868 // Allocate and initialize the const list at compile time. |
| 10860 Array& const_list = | 10869 Array& const_list = |
| 10861 Array::ZoneHandle(I, Array::New(element_list.length(), Heap::kOld)); | 10870 Array::ZoneHandle(Z, Array::New(element_list.length(), Heap::kOld)); |
| 10862 const_list.SetTypeArguments( | 10871 const_list.SetTypeArguments( |
| 10863 TypeArguments::Handle(I, list_type_arguments.Canonicalize())); | 10872 TypeArguments::Handle(Z, list_type_arguments.Canonicalize())); |
| 10864 Error& malformed_error = Error::Handle(I); | 10873 Error& malformed_error = Error::Handle(Z); |
| 10865 for (int i = 0; i < element_list.length(); i++) { | 10874 for (int i = 0; i < element_list.length(); i++) { |
| 10866 AstNode* elem = element_list[i]; | 10875 AstNode* elem = element_list[i]; |
| 10867 // Arguments have been evaluated to a literal value already. | 10876 // Arguments have been evaluated to a literal value already. |
| 10868 ASSERT(elem->IsLiteralNode()); | 10877 ASSERT(elem->IsLiteralNode()); |
| 10869 ASSERT(!is_top_level_); // We cannot check unresolved types. | 10878 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 10870 if (FLAG_enable_type_checks && | 10879 if (FLAG_enable_type_checks && |
| 10871 !element_type.IsDynamicType() && | 10880 !element_type.IsDynamicType() && |
| 10872 (!elem->AsLiteralNode()->literal().IsNull() && | 10881 (!elem->AsLiteralNode()->literal().IsNull() && |
| 10873 !elem->AsLiteralNode()->literal().IsInstanceOf( | 10882 !elem->AsLiteralNode()->literal().IsInstanceOf( |
| 10874 element_type, | 10883 element_type, |
| 10875 TypeArguments::Handle(I), | 10884 TypeArguments::Handle(Z), |
| 10876 &malformed_error))) { | 10885 &malformed_error))) { |
| 10877 // If the failure is due to a malformed type error, display it instead. | 10886 // If the failure is due to a malformed type error, display it instead. |
| 10878 if (!malformed_error.IsNull()) { | 10887 if (!malformed_error.IsNull()) { |
| 10879 ReportError(malformed_error); | 10888 ReportError(malformed_error); |
| 10880 } else { | 10889 } else { |
| 10881 ReportError(elem->AsLiteralNode()->token_pos(), | 10890 ReportError(elem->AsLiteralNode()->token_pos(), |
| 10882 "list literal element at index %d must be " | 10891 "list literal element at index %d must be " |
| 10883 "a constant of type '%s'", | 10892 "a constant of type '%s'", |
| 10884 i, | 10893 i, |
| 10885 String::Handle(I, | 10894 String::Handle(Z, |
| 10886 element_type.UserVisibleName()).ToCString()); | 10895 element_type.UserVisibleName()).ToCString()); |
| 10887 } | 10896 } |
| 10888 } | 10897 } |
| 10889 const_list.SetAt(i, elem->AsLiteralNode()->literal()); | 10898 const_list.SetAt(i, elem->AsLiteralNode()->literal()); |
| 10890 } | 10899 } |
| 10891 const_list.MakeImmutable(); | 10900 const_list.MakeImmutable(); |
| 10892 const_list ^= TryCanonicalize(const_list, literal_pos); | 10901 const_list ^= TryCanonicalize(const_list, literal_pos); |
| 10893 return new(I) LiteralNode(literal_pos, const_list); | 10902 return new(Z) LiteralNode(literal_pos, const_list); |
| 10894 } else { | 10903 } else { |
| 10895 // Factory call at runtime. | 10904 // Factory call at runtime. |
| 10896 const Class& factory_class = | 10905 const Class& factory_class = |
| 10897 Class::Handle(I, Library::LookupCoreClass(Symbols::List())); | 10906 Class::Handle(Z, Library::LookupCoreClass(Symbols::List())); |
| 10898 ASSERT(!factory_class.IsNull()); | 10907 ASSERT(!factory_class.IsNull()); |
| 10899 const Function& factory_method = Function::ZoneHandle(I, | 10908 const Function& factory_method = Function::ZoneHandle(Z, |
| 10900 factory_class.LookupFactory( | 10909 factory_class.LookupFactory( |
| 10901 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); | 10910 Library::PrivateCoreLibName(Symbols::ListLiteralFactory()))); |
| 10902 ASSERT(!factory_method.IsNull()); | 10911 ASSERT(!factory_method.IsNull()); |
| 10903 if (!list_type_arguments.IsNull() && | 10912 if (!list_type_arguments.IsNull() && |
| 10904 !list_type_arguments.IsInstantiated() && | 10913 !list_type_arguments.IsInstantiated() && |
| 10905 (current_block_->scope->function_level() > 0)) { | 10914 (current_block_->scope->function_level() > 0)) { |
| 10906 // Make sure that the instantiator is captured. | 10915 // Make sure that the instantiator is captured. |
| 10907 CaptureInstantiator(); | 10916 CaptureInstantiator(); |
| 10908 } | 10917 } |
| 10909 TypeArguments& factory_type_args = | 10918 TypeArguments& factory_type_args = |
| 10910 TypeArguments::ZoneHandle(I, list_type_arguments.raw()); | 10919 TypeArguments::ZoneHandle(Z, list_type_arguments.raw()); |
| 10911 // If the factory class extends other parameterized classes, adjust the | 10920 // If the factory class extends other parameterized classes, adjust the |
| 10912 // type argument vector. | 10921 // type argument vector. |
| 10913 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { | 10922 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 1)) { |
| 10914 ASSERT(factory_type_args.Length() == 1); | 10923 ASSERT(factory_type_args.Length() == 1); |
| 10915 Type& factory_type = Type::Handle(I, Type::New( | 10924 Type& factory_type = Type::Handle(Z, Type::New( |
| 10916 factory_class, factory_type_args, type_pos, Heap::kNew)); | 10925 factory_class, factory_type_args, type_pos, Heap::kNew)); |
| 10917 factory_type ^= ClassFinalizer::FinalizeType( | 10926 factory_type ^= ClassFinalizer::FinalizeType( |
| 10918 current_class(), factory_type, ClassFinalizer::kFinalize); | 10927 current_class(), factory_type, ClassFinalizer::kFinalize); |
| 10919 factory_type_args = factory_type.arguments(); | 10928 factory_type_args = factory_type.arguments(); |
| 10920 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 10929 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
| 10921 } | 10930 } |
| 10922 factory_type_args = factory_type_args.Canonicalize(); | 10931 factory_type_args = factory_type_args.Canonicalize(); |
| 10923 ArgumentListNode* factory_param = new(I) ArgumentListNode( | 10932 ArgumentListNode* factory_param = new(Z) ArgumentListNode( |
| 10924 literal_pos); | 10933 literal_pos); |
| 10925 if (element_list.length() == 0) { | 10934 if (element_list.length() == 0) { |
| 10926 LiteralNode* empty_array_literal = | 10935 LiteralNode* empty_array_literal = |
| 10927 new(I) LiteralNode(TokenPos(), Object::empty_array()); | 10936 new(Z) LiteralNode(TokenPos(), Object::empty_array()); |
| 10928 factory_param->Add(empty_array_literal); | 10937 factory_param->Add(empty_array_literal); |
| 10929 } else { | 10938 } else { |
| 10930 ArrayNode* list = new(I) ArrayNode(TokenPos(), type, element_list); | 10939 ArrayNode* list = new(Z) ArrayNode(TokenPos(), type, element_list); |
| 10931 factory_param->Add(list); | 10940 factory_param->Add(list); |
| 10932 } | 10941 } |
| 10933 return CreateConstructorCallNode(literal_pos, | 10942 return CreateConstructorCallNode(literal_pos, |
| 10934 factory_type_args, | 10943 factory_type_args, |
| 10935 factory_method, | 10944 factory_method, |
| 10936 factory_param); | 10945 factory_param); |
| 10937 } | 10946 } |
| 10938 } | 10947 } |
| 10939 | 10948 |
| 10940 | 10949 |
| 10941 ConstructorCallNode* Parser::CreateConstructorCallNode( | 10950 ConstructorCallNode* Parser::CreateConstructorCallNode( |
| 10942 intptr_t token_pos, | 10951 intptr_t token_pos, |
| 10943 const TypeArguments& type_arguments, | 10952 const TypeArguments& type_arguments, |
| 10944 const Function& constructor, | 10953 const Function& constructor, |
| 10945 ArgumentListNode* arguments) { | 10954 ArgumentListNode* arguments) { |
| 10946 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { | 10955 if (!type_arguments.IsNull() && !type_arguments.IsInstantiated()) { |
| 10947 EnsureExpressionTemp(); | 10956 EnsureExpressionTemp(); |
| 10948 } | 10957 } |
| 10949 return new(I) ConstructorCallNode( | 10958 return new(Z) ConstructorCallNode( |
| 10950 token_pos, type_arguments, constructor, arguments); | 10959 token_pos, type_arguments, constructor, arguments); |
| 10951 } | 10960 } |
| 10952 | 10961 |
| 10953 | 10962 |
| 10954 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, | 10963 static void AddKeyValuePair(GrowableArray<AstNode*>* pairs, |
| 10955 bool is_const, | 10964 bool is_const, |
| 10956 AstNode* key, | 10965 AstNode* key, |
| 10957 AstNode* value) { | 10966 AstNode* value) { |
| 10958 if (is_const) { | 10967 if (is_const) { |
| 10959 ASSERT(key->IsLiteralNode()); | 10968 ASSERT(key->IsLiteralNode()); |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 10978 | 10987 |
| 10979 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, | 10988 AstNode* Parser::ParseMapLiteral(intptr_t type_pos, |
| 10980 bool is_const, | 10989 bool is_const, |
| 10981 const TypeArguments& type_arguments) { | 10990 const TypeArguments& type_arguments) { |
| 10982 TRACE_PARSER("ParseMapLiteral"); | 10991 TRACE_PARSER("ParseMapLiteral"); |
| 10983 ASSERT(type_pos >= 0); | 10992 ASSERT(type_pos >= 0); |
| 10984 ASSERT(CurrentToken() == Token::kLBRACE); | 10993 ASSERT(CurrentToken() == Token::kLBRACE); |
| 10985 const intptr_t literal_pos = TokenPos(); | 10994 const intptr_t literal_pos = TokenPos(); |
| 10986 ConsumeToken(); | 10995 ConsumeToken(); |
| 10987 | 10996 |
| 10988 AbstractType& key_type = Type::ZoneHandle(I, Type::DynamicType()); | 10997 AbstractType& key_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 10989 AbstractType& value_type = Type::ZoneHandle(I, Type::DynamicType()); | 10998 AbstractType& value_type = Type::ZoneHandle(Z, Type::DynamicType()); |
| 10990 TypeArguments& map_type_arguments = | 10999 TypeArguments& map_type_arguments = |
| 10991 TypeArguments::ZoneHandle(I, type_arguments.raw()); | 11000 TypeArguments::ZoneHandle(Z, type_arguments.raw()); |
| 10992 // If no type argument vector is provided, leave it as null, which is | 11001 // If no type argument vector is provided, leave it as null, which is |
| 10993 // equivalent to using dynamic as the type argument for the both key and value | 11002 // equivalent to using dynamic as the type argument for the both key and value |
| 10994 // types. | 11003 // types. |
| 10995 if (!map_type_arguments.IsNull()) { | 11004 if (!map_type_arguments.IsNull()) { |
| 10996 ASSERT(map_type_arguments.Length() > 0); | 11005 ASSERT(map_type_arguments.Length() > 0); |
| 10997 // Map literals take two type arguments. | 11006 // Map literals take two type arguments. |
| 10998 if (map_type_arguments.Length() == 2) { | 11007 if (map_type_arguments.Length() == 2) { |
| 10999 key_type = map_type_arguments.TypeAt(0); | 11008 key_type = map_type_arguments.TypeAt(0); |
| 11000 value_type = map_type_arguments.TypeAt(1); | 11009 value_type = map_type_arguments.TypeAt(1); |
| 11001 // Malformed type arguments are mapped to dynamic. | 11010 // Malformed type arguments are mapped to dynamic. |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 11025 GrowableArray<AstNode*> kv_pairs_list; | 11034 GrowableArray<AstNode*> kv_pairs_list; |
| 11026 // Parse the map entries. Note: there may be an optional extra | 11035 // Parse the map entries. Note: there may be an optional extra |
| 11027 // comma after the last entry. | 11036 // comma after the last entry. |
| 11028 while (CurrentToken() != Token::kRBRACE) { | 11037 while (CurrentToken() != Token::kRBRACE) { |
| 11029 const bool saved_mode = SetAllowFunctionLiterals(true); | 11038 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 11030 const intptr_t key_pos = TokenPos(); | 11039 const intptr_t key_pos = TokenPos(); |
| 11031 AstNode* key = ParseExpr(is_const, kConsumeCascades); | 11040 AstNode* key = ParseExpr(is_const, kConsumeCascades); |
| 11032 if (FLAG_enable_type_checks && | 11041 if (FLAG_enable_type_checks && |
| 11033 !is_const && | 11042 !is_const && |
| 11034 !key_type.IsDynamicType()) { | 11043 !key_type.IsDynamicType()) { |
| 11035 key = new(I) AssignableNode( | 11044 key = new(Z) AssignableNode( |
| 11036 key_pos, key, key_type, Symbols::ListLiteralElement()); | 11045 key_pos, key, key_type, Symbols::ListLiteralElement()); |
| 11037 } | 11046 } |
| 11038 if (is_const) { | 11047 if (is_const) { |
| 11039 ASSERT(key->IsLiteralNode()); | 11048 ASSERT(key->IsLiteralNode()); |
| 11040 const Instance& key_value = key->AsLiteralNode()->literal(); | 11049 const Instance& key_value = key->AsLiteralNode()->literal(); |
| 11041 if (key_value.IsDouble()) { | 11050 if (key_value.IsDouble()) { |
| 11042 ReportError(key_pos, "key value must not be of type double"); | 11051 ReportError(key_pos, "key value must not be of type double"); |
| 11043 } | 11052 } |
| 11044 if (!key_value.IsInteger() && | 11053 if (!key_value.IsInteger() && |
| 11045 !key_value.IsString() && | 11054 !key_value.IsString() && |
| 11046 (key_value.clazz() != I->object_store()->symbol_class()) && | 11055 (key_value.clazz() != I->object_store()->symbol_class()) && |
| 11047 ImplementsEqualOperator(key_value)) { | 11056 ImplementsEqualOperator(key_value)) { |
| 11048 ReportError(key_pos, "key value must not implement operator =="); | 11057 ReportError(key_pos, "key value must not implement operator =="); |
| 11049 } | 11058 } |
| 11050 } | 11059 } |
| 11051 ExpectToken(Token::kCOLON); | 11060 ExpectToken(Token::kCOLON); |
| 11052 const intptr_t value_pos = TokenPos(); | 11061 const intptr_t value_pos = TokenPos(); |
| 11053 AstNode* value = ParseExpr(is_const, kConsumeCascades); | 11062 AstNode* value = ParseExpr(is_const, kConsumeCascades); |
| 11054 SetAllowFunctionLiterals(saved_mode); | 11063 SetAllowFunctionLiterals(saved_mode); |
| 11055 if (FLAG_enable_type_checks && | 11064 if (FLAG_enable_type_checks && |
| 11056 !is_const && | 11065 !is_const && |
| 11057 !value_type.IsDynamicType()) { | 11066 !value_type.IsDynamicType()) { |
| 11058 value = new(I) AssignableNode( | 11067 value = new(Z) AssignableNode( |
| 11059 value_pos, value, value_type, Symbols::ListLiteralElement()); | 11068 value_pos, value, value_type, Symbols::ListLiteralElement()); |
| 11060 } | 11069 } |
| 11061 AddKeyValuePair(&kv_pairs_list, is_const, key, value); | 11070 AddKeyValuePair(&kv_pairs_list, is_const, key, value); |
| 11062 | 11071 |
| 11063 if (CurrentToken() == Token::kCOMMA) { | 11072 if (CurrentToken() == Token::kCOMMA) { |
| 11064 ConsumeToken(); | 11073 ConsumeToken(); |
| 11065 } else if (CurrentToken() != Token::kRBRACE) { | 11074 } else if (CurrentToken() != Token::kRBRACE) { |
| 11066 ReportError("comma or '}' expected"); | 11075 ReportError("comma or '}' expected"); |
| 11067 } | 11076 } |
| 11068 } | 11077 } |
| 11069 ASSERT(kv_pairs_list.length() % 2 == 0); | 11078 ASSERT(kv_pairs_list.length() % 2 == 0); |
| 11070 ExpectToken(Token::kRBRACE); | 11079 ExpectToken(Token::kRBRACE); |
| 11071 | 11080 |
| 11072 if (is_const) { | 11081 if (is_const) { |
| 11073 // Create the key-value pair array, canonicalize it and then create | 11082 // Create the key-value pair array, canonicalize it and then create |
| 11074 // the immutable map object with it. This all happens at compile time. | 11083 // the immutable map object with it. This all happens at compile time. |
| 11075 // The resulting immutable map object is returned as a literal. | 11084 // The resulting immutable map object is returned as a literal. |
| 11076 | 11085 |
| 11077 // First, create the canonicalized key-value pair array. | 11086 // First, create the canonicalized key-value pair array. |
| 11078 Array& key_value_array = | 11087 Array& key_value_array = |
| 11079 Array::ZoneHandle(I, Array::New(kv_pairs_list.length(), Heap::kOld)); | 11088 Array::ZoneHandle(Z, Array::New(kv_pairs_list.length(), Heap::kOld)); |
| 11080 AbstractType& arg_type = Type::Handle(I); | 11089 AbstractType& arg_type = Type::Handle(Z); |
| 11081 Error& malformed_error = Error::Handle(I); | 11090 Error& malformed_error = Error::Handle(Z); |
| 11082 for (int i = 0; i < kv_pairs_list.length(); i++) { | 11091 for (int i = 0; i < kv_pairs_list.length(); i++) { |
| 11083 AstNode* arg = kv_pairs_list[i]; | 11092 AstNode* arg = kv_pairs_list[i]; |
| 11084 // Arguments have been evaluated to a literal value already. | 11093 // Arguments have been evaluated to a literal value already. |
| 11085 ASSERT(arg->IsLiteralNode()); | 11094 ASSERT(arg->IsLiteralNode()); |
| 11086 ASSERT(!is_top_level_); // We cannot check unresolved types. | 11095 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 11087 if (FLAG_enable_type_checks) { | 11096 if (FLAG_enable_type_checks) { |
| 11088 if ((i % 2) == 0) { | 11097 if ((i % 2) == 0) { |
| 11089 // Check key type. | 11098 // Check key type. |
| 11090 arg_type = key_type.raw(); | 11099 arg_type = key_type.raw(); |
| 11091 } else { | 11100 } else { |
| 11092 // Check value type. | 11101 // Check value type. |
| 11093 arg_type = value_type.raw(); | 11102 arg_type = value_type.raw(); |
| 11094 } | 11103 } |
| 11095 if (!arg_type.IsDynamicType() && | 11104 if (!arg_type.IsDynamicType() && |
| 11096 (!arg->AsLiteralNode()->literal().IsNull() && | 11105 (!arg->AsLiteralNode()->literal().IsNull() && |
| 11097 !arg->AsLiteralNode()->literal().IsInstanceOf( | 11106 !arg->AsLiteralNode()->literal().IsInstanceOf( |
| 11098 arg_type, | 11107 arg_type, |
| 11099 Object::null_type_arguments(), | 11108 Object::null_type_arguments(), |
| 11100 &malformed_error))) { | 11109 &malformed_error))) { |
| 11101 // If the failure is due to a malformed type error, display it. | 11110 // If the failure is due to a malformed type error, display it. |
| 11102 if (!malformed_error.IsNull()) { | 11111 if (!malformed_error.IsNull()) { |
| 11103 ReportError(malformed_error); | 11112 ReportError(malformed_error); |
| 11104 } else { | 11113 } else { |
| 11105 ReportError(arg->AsLiteralNode()->token_pos(), | 11114 ReportError(arg->AsLiteralNode()->token_pos(), |
| 11106 "map literal %s at index %d must be " | 11115 "map literal %s at index %d must be " |
| 11107 "a constant of type '%s'", | 11116 "a constant of type '%s'", |
| 11108 ((i % 2) == 0) ? "key" : "value", | 11117 ((i % 2) == 0) ? "key" : "value", |
| 11109 i >> 1, | 11118 i >> 1, |
| 11110 String::Handle(I, | 11119 String::Handle(Z, |
| 11111 arg_type.UserVisibleName()).ToCString()); | 11120 arg_type.UserVisibleName()).ToCString()); |
| 11112 } | 11121 } |
| 11113 } | 11122 } |
| 11114 } | 11123 } |
| 11115 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); | 11124 key_value_array.SetAt(i, arg->AsLiteralNode()->literal()); |
| 11116 } | 11125 } |
| 11117 key_value_array.MakeImmutable(); | 11126 key_value_array.MakeImmutable(); |
| 11118 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); | 11127 key_value_array ^= TryCanonicalize(key_value_array, TokenPos()); |
| 11119 | 11128 |
| 11120 // Construct the map object. | 11129 // Construct the map object. |
| 11121 const Class& immutable_map_class = Class::Handle(I, | 11130 const Class& immutable_map_class = Class::Handle(Z, |
| 11122 Library::LookupCoreClass(Symbols::ImmutableMap())); | 11131 Library::LookupCoreClass(Symbols::ImmutableMap())); |
| 11123 ASSERT(!immutable_map_class.IsNull()); | 11132 ASSERT(!immutable_map_class.IsNull()); |
| 11124 // If the immutable map class extends other parameterized classes, we need | 11133 // If the immutable map class extends other parameterized classes, we need |
| 11125 // to adjust the type argument vector. This is currently not the case. | 11134 // to adjust the type argument vector. This is currently not the case. |
| 11126 ASSERT(immutable_map_class.NumTypeArguments() == 2); | 11135 ASSERT(immutable_map_class.NumTypeArguments() == 2); |
| 11127 ArgumentListNode* constr_args = new(I) ArgumentListNode(TokenPos()); | 11136 ArgumentListNode* constr_args = new(Z) ArgumentListNode(TokenPos()); |
| 11128 constr_args->Add(new(I) LiteralNode(literal_pos, key_value_array)); | 11137 constr_args->Add(new(Z) LiteralNode(literal_pos, key_value_array)); |
| 11129 const Function& map_constr = | 11138 const Function& map_constr = |
| 11130 Function::ZoneHandle(I, immutable_map_class.LookupConstructor( | 11139 Function::ZoneHandle(Z, immutable_map_class.LookupConstructor( |
| 11131 Library::PrivateCoreLibName(Symbols::ImmutableMapConstructor()))); | 11140 Library::PrivateCoreLibName(Symbols::ImmutableMapConstructor()))); |
| 11132 ASSERT(!map_constr.IsNull()); | 11141 ASSERT(!map_constr.IsNull()); |
| 11133 const Object& constructor_result = Object::Handle(I, | 11142 const Object& constructor_result = Object::Handle(Z, |
| 11134 EvaluateConstConstructorCall(immutable_map_class, | 11143 EvaluateConstConstructorCall(immutable_map_class, |
| 11135 map_type_arguments, | 11144 map_type_arguments, |
| 11136 map_constr, | 11145 map_constr, |
| 11137 constr_args)); | 11146 constr_args)); |
| 11138 if (constructor_result.IsUnhandledException()) { | 11147 if (constructor_result.IsUnhandledException()) { |
| 11139 ReportErrors(Error::Cast(constructor_result), | 11148 ReportErrors(Error::Cast(constructor_result), |
| 11140 script_, literal_pos, | 11149 script_, literal_pos, |
| 11141 "error executing const Map constructor"); | 11150 "error executing const Map constructor"); |
| 11142 } else { | 11151 } else { |
| 11143 const Instance& const_instance = Instance::Cast(constructor_result); | 11152 const Instance& const_instance = Instance::Cast(constructor_result); |
| 11144 return new(I) LiteralNode( | 11153 return new(Z) LiteralNode( |
| 11145 literal_pos, Instance::ZoneHandle(I, const_instance.raw())); | 11154 literal_pos, Instance::ZoneHandle(Z, const_instance.raw())); |
| 11146 } | 11155 } |
| 11147 } else { | 11156 } else { |
| 11148 // Factory call at runtime. | 11157 // Factory call at runtime. |
| 11149 const Class& factory_class = | 11158 const Class& factory_class = |
| 11150 Class::Handle(I, Library::LookupCoreClass(Symbols::Map())); | 11159 Class::Handle(Z, Library::LookupCoreClass(Symbols::Map())); |
| 11151 ASSERT(!factory_class.IsNull()); | 11160 ASSERT(!factory_class.IsNull()); |
| 11152 const Function& factory_method = Function::ZoneHandle(I, | 11161 const Function& factory_method = Function::ZoneHandle(Z, |
| 11153 factory_class.LookupFactory( | 11162 factory_class.LookupFactory( |
| 11154 Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); | 11163 Library::PrivateCoreLibName(Symbols::MapLiteralFactory()))); |
| 11155 ASSERT(!factory_method.IsNull()); | 11164 ASSERT(!factory_method.IsNull()); |
| 11156 if (!map_type_arguments.IsNull() && | 11165 if (!map_type_arguments.IsNull() && |
| 11157 !map_type_arguments.IsInstantiated() && | 11166 !map_type_arguments.IsInstantiated() && |
| 11158 (current_block_->scope->function_level() > 0)) { | 11167 (current_block_->scope->function_level() > 0)) { |
| 11159 // Make sure that the instantiator is captured. | 11168 // Make sure that the instantiator is captured. |
| 11160 CaptureInstantiator(); | 11169 CaptureInstantiator(); |
| 11161 } | 11170 } |
| 11162 TypeArguments& factory_type_args = | 11171 TypeArguments& factory_type_args = |
| 11163 TypeArguments::ZoneHandle(I, map_type_arguments.raw()); | 11172 TypeArguments::ZoneHandle(Z, map_type_arguments.raw()); |
| 11164 // If the factory class extends other parameterized classes, adjust the | 11173 // If the factory class extends other parameterized classes, adjust the |
| 11165 // type argument vector. | 11174 // type argument vector. |
| 11166 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) { | 11175 if (!factory_type_args.IsNull() && (factory_class.NumTypeArguments() > 2)) { |
| 11167 ASSERT(factory_type_args.Length() == 2); | 11176 ASSERT(factory_type_args.Length() == 2); |
| 11168 Type& factory_type = Type::Handle(I, Type::New( | 11177 Type& factory_type = Type::Handle(Z, Type::New( |
| 11169 factory_class, factory_type_args, type_pos, Heap::kNew)); | 11178 factory_class, factory_type_args, type_pos, Heap::kNew)); |
| 11170 factory_type ^= ClassFinalizer::FinalizeType( | 11179 factory_type ^= ClassFinalizer::FinalizeType( |
| 11171 current_class(), factory_type, ClassFinalizer::kFinalize); | 11180 current_class(), factory_type, ClassFinalizer::kFinalize); |
| 11172 factory_type_args = factory_type.arguments(); | 11181 factory_type_args = factory_type.arguments(); |
| 11173 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); | 11182 ASSERT(factory_type_args.Length() == factory_class.NumTypeArguments()); |
| 11174 } | 11183 } |
| 11175 factory_type_args = factory_type_args.Canonicalize(); | 11184 factory_type_args = factory_type_args.Canonicalize(); |
| 11176 ArgumentListNode* factory_param = new(I) ArgumentListNode(literal_pos); | 11185 ArgumentListNode* factory_param = new(Z) ArgumentListNode(literal_pos); |
| 11177 // The kv_pair array is temporary and of element type dynamic. It is passed | 11186 // The kv_pair array is temporary and of element type dynamic. It is passed |
| 11178 // to the factory to initialize a properly typed map. | 11187 // to the factory to initialize a properly typed map. |
| 11179 ArrayNode* kv_pairs = new(I) ArrayNode( | 11188 ArrayNode* kv_pairs = new(Z) ArrayNode( |
| 11180 TokenPos(), | 11189 TokenPos(), |
| 11181 Type::ZoneHandle(I, Type::ArrayType()), | 11190 Type::ZoneHandle(Z, Type::ArrayType()), |
| 11182 kv_pairs_list); | 11191 kv_pairs_list); |
| 11183 factory_param->Add(kv_pairs); | 11192 factory_param->Add(kv_pairs); |
| 11184 return CreateConstructorCallNode(literal_pos, | 11193 return CreateConstructorCallNode(literal_pos, |
| 11185 factory_type_args, | 11194 factory_type_args, |
| 11186 factory_method, | 11195 factory_method, |
| 11187 factory_param); | 11196 factory_param); |
| 11188 } | 11197 } |
| 11189 UNREACHABLE(); | 11198 UNREACHABLE(); |
| 11190 return NULL; | 11199 return NULL; |
| 11191 } | 11200 } |
| 11192 | 11201 |
| 11193 | 11202 |
| 11194 AstNode* Parser::ParseCompoundLiteral() { | 11203 AstNode* Parser::ParseCompoundLiteral() { |
| 11195 TRACE_PARSER("ParseCompoundLiteral"); | 11204 TRACE_PARSER("ParseCompoundLiteral"); |
| 11196 bool is_const = false; | 11205 bool is_const = false; |
| 11197 if (CurrentToken() == Token::kCONST) { | 11206 if (CurrentToken() == Token::kCONST) { |
| 11198 is_const = true; | 11207 is_const = true; |
| 11199 ConsumeToken(); | 11208 ConsumeToken(); |
| 11200 } | 11209 } |
| 11201 const intptr_t type_pos = TokenPos(); | 11210 const intptr_t type_pos = TokenPos(); |
| 11202 TypeArguments& type_arguments = TypeArguments::Handle(I, | 11211 TypeArguments& type_arguments = TypeArguments::Handle(Z, |
| 11203 ParseTypeArguments(ClassFinalizer::kCanonicalize)); | 11212 ParseTypeArguments(ClassFinalizer::kCanonicalize)); |
| 11204 // Malformed type arguments are mapped to dynamic, so we will not encounter | 11213 // Malformed type arguments are mapped to dynamic, so we will not encounter |
| 11205 // them here. | 11214 // them here. |
| 11206 // Map and List interfaces do not declare bounds on their type parameters, so | 11215 // Map and List interfaces do not declare bounds on their type parameters, so |
| 11207 // we will not see malbounded type arguments here. | 11216 // we will not see malbounded type arguments here. |
| 11208 AstNode* primary = NULL; | 11217 AstNode* primary = NULL; |
| 11209 if ((CurrentToken() == Token::kLBRACK) || | 11218 if ((CurrentToken() == Token::kLBRACK) || |
| 11210 (CurrentToken() == Token::kINDEX)) { | 11219 (CurrentToken() == Token::kINDEX)) { |
| 11211 primary = ParseListLiteral(type_pos, is_const, type_arguments); | 11220 primary = ParseListLiteral(type_pos, is_const, type_arguments); |
| 11212 } else if (CurrentToken() == Token::kLBRACE) { | 11221 } else if (CurrentToken() == Token::kLBRACE) { |
| 11213 primary = ParseMapLiteral(type_pos, is_const, type_arguments); | 11222 primary = ParseMapLiteral(type_pos, is_const, type_arguments); |
| 11214 } else { | 11223 } else { |
| 11215 ReportError("unexpected token %s", Token::Str(CurrentToken())); | 11224 ReportError("unexpected token %s", Token::Str(CurrentToken())); |
| 11216 } | 11225 } |
| 11217 return primary; | 11226 return primary; |
| 11218 } | 11227 } |
| 11219 | 11228 |
| 11220 | 11229 |
| 11221 AstNode* Parser::ParseSymbolLiteral() { | 11230 AstNode* Parser::ParseSymbolLiteral() { |
| 11222 ASSERT(CurrentToken() == Token::kHASH); | 11231 ASSERT(CurrentToken() == Token::kHASH); |
| 11223 ConsumeToken(); | 11232 ConsumeToken(); |
| 11224 intptr_t symbol_pos = TokenPos(); | 11233 intptr_t symbol_pos = TokenPos(); |
| 11225 String& symbol = String::Handle(I); | 11234 String& symbol = String::Handle(Z); |
| 11226 if (IsIdentifier()) { | 11235 if (IsIdentifier()) { |
| 11227 symbol = CurrentLiteral()->raw(); | 11236 symbol = CurrentLiteral()->raw(); |
| 11228 ConsumeToken(); | 11237 ConsumeToken(); |
| 11229 while (CurrentToken() == Token::kPERIOD) { | 11238 while (CurrentToken() == Token::kPERIOD) { |
| 11230 symbol = String::Concat(symbol, Symbols::Dot()); | 11239 symbol = String::Concat(symbol, Symbols::Dot()); |
| 11231 ConsumeToken(); | 11240 ConsumeToken(); |
| 11232 symbol = String::Concat(symbol, | 11241 symbol = String::Concat(symbol, |
| 11233 *ExpectIdentifier("identifier expected")); | 11242 *ExpectIdentifier("identifier expected")); |
| 11234 } | 11243 } |
| 11235 } else if (Token::CanBeOverloaded(CurrentToken())) { | 11244 } else if (Token::CanBeOverloaded(CurrentToken())) { |
| 11236 symbol = String::New(Token::Str(CurrentToken())); | 11245 symbol = String::New(Token::Str(CurrentToken())); |
| 11237 ConsumeToken(); | 11246 ConsumeToken(); |
| 11238 } else { | 11247 } else { |
| 11239 ReportError("illegal symbol literal"); | 11248 ReportError("illegal symbol literal"); |
| 11240 } | 11249 } |
| 11241 | 11250 |
| 11242 // Call Symbol class constructor to create a symbol instance. | 11251 // Call Symbol class constructor to create a symbol instance. |
| 11243 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class()); | 11252 const Class& symbol_class = Class::Handle(I->object_store()->symbol_class()); |
| 11244 ASSERT(!symbol_class.IsNull()); | 11253 ASSERT(!symbol_class.IsNull()); |
| 11245 ArgumentListNode* constr_args = new(I) ArgumentListNode(symbol_pos); | 11254 ArgumentListNode* constr_args = new(Z) ArgumentListNode(symbol_pos); |
| 11246 constr_args->Add(new(I) LiteralNode( | 11255 constr_args->Add(new(Z) LiteralNode( |
| 11247 symbol_pos, String::ZoneHandle(I, Symbols::New(symbol)))); | 11256 symbol_pos, String::ZoneHandle(Z, Symbols::New(symbol)))); |
| 11248 const Function& constr = Function::ZoneHandle(I, | 11257 const Function& constr = Function::ZoneHandle(Z, |
| 11249 symbol_class.LookupConstructor(Symbols::SymbolCtor())); | 11258 symbol_class.LookupConstructor(Symbols::SymbolCtor())); |
| 11250 ASSERT(!constr.IsNull()); | 11259 ASSERT(!constr.IsNull()); |
| 11251 const Object& result = Object::Handle(I, | 11260 const Object& result = Object::Handle(Z, |
| 11252 EvaluateConstConstructorCall(symbol_class, | 11261 EvaluateConstConstructorCall(symbol_class, |
| 11253 TypeArguments::Handle(I), | 11262 TypeArguments::Handle(Z), |
| 11254 constr, | 11263 constr, |
| 11255 constr_args)); | 11264 constr_args)); |
| 11256 if (result.IsUnhandledException()) { | 11265 if (result.IsUnhandledException()) { |
| 11257 ReportErrors(Error::Cast(result), | 11266 ReportErrors(Error::Cast(result), |
| 11258 script_, symbol_pos, | 11267 script_, symbol_pos, |
| 11259 "error executing const Symbol constructor"); | 11268 "error executing const Symbol constructor"); |
| 11260 } | 11269 } |
| 11261 const Instance& instance = Instance::Cast(result); | 11270 const Instance& instance = Instance::Cast(result); |
| 11262 return new(I) LiteralNode(symbol_pos, | 11271 return new(Z) LiteralNode(symbol_pos, |
| 11263 Instance::ZoneHandle(I, instance.raw())); | 11272 Instance::ZoneHandle(Z, instance.raw())); |
| 11264 } | 11273 } |
| 11265 | 11274 |
| 11266 | 11275 |
| 11267 static String& BuildConstructorName(const String& type_class_name, | 11276 static String& BuildConstructorName(const String& type_class_name, |
| 11268 const String* named_constructor) { | 11277 const String* named_constructor) { |
| 11269 // By convention, the static function implementing a named constructor 'C' | 11278 // By convention, the static function implementing a named constructor 'C' |
| 11270 // for class 'A' is labeled 'A.C', and the static function implementing the | 11279 // for class 'A' is labeled 'A.C', and the static function implementing the |
| 11271 // unnamed constructor for class 'A' is labeled 'A.'. | 11280 // unnamed constructor for class 'A' is labeled 'A.'. |
| 11272 // This convention prevents users from explicitly calling constructors. | 11281 // This convention prevents users from explicitly calling constructors. |
| 11273 String& constructor_name = | 11282 String& constructor_name = |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 11285 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); | 11294 ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST)); |
| 11286 bool is_const = (op_kind == Token::kCONST); | 11295 bool is_const = (op_kind == Token::kCONST); |
| 11287 if (!IsIdentifier()) { | 11296 if (!IsIdentifier()) { |
| 11288 ReportError("type name expected"); | 11297 ReportError("type name expected"); |
| 11289 } | 11298 } |
| 11290 intptr_t type_pos = TokenPos(); | 11299 intptr_t type_pos = TokenPos(); |
| 11291 // Can't allocate const objects of a deferred type. | 11300 // Can't allocate const objects of a deferred type. |
| 11292 const bool allow_deferred_type = !is_const; | 11301 const bool allow_deferred_type = !is_const; |
| 11293 const bool consume_unresolved_prefix = (LookaheadToken(3) == Token::kLT) || | 11302 const bool consume_unresolved_prefix = (LookaheadToken(3) == Token::kLT) || |
| 11294 (LookaheadToken(3) == Token::kPERIOD); | 11303 (LookaheadToken(3) == Token::kPERIOD); |
| 11295 AbstractType& type = AbstractType::Handle(I, | 11304 AbstractType& type = AbstractType::Handle(Z, |
| 11296 ParseType(ClassFinalizer::kCanonicalizeWellFormed, | 11305 ParseType(ClassFinalizer::kCanonicalizeWellFormed, |
| 11297 allow_deferred_type, | 11306 allow_deferred_type, |
| 11298 consume_unresolved_prefix)); | 11307 consume_unresolved_prefix)); |
| 11299 // In case the type is malformed, throw a dynamic type error after finishing | 11308 // In case the type is malformed, throw a dynamic type error after finishing |
| 11300 // parsing the instance creation expression. | 11309 // parsing the instance creation expression. |
| 11301 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { | 11310 if (!type.IsMalformed() && (type.IsTypeParameter() || type.IsDynamicType())) { |
| 11302 // Replace the type with a malformed type. | 11311 // Replace the type with a malformed type. |
| 11303 type = ClassFinalizer::NewFinalizedMalformedType( | 11312 type = ClassFinalizer::NewFinalizedMalformedType( |
| 11304 Error::Handle(I), // No previous error. | 11313 Error::Handle(Z), // No previous error. |
| 11305 script_, | 11314 script_, |
| 11306 type_pos, | 11315 type_pos, |
| 11307 "%s'%s' cannot be instantiated", | 11316 "%s'%s' cannot be instantiated", |
| 11308 type.IsTypeParameter() ? "type parameter " : "", | 11317 type.IsTypeParameter() ? "type parameter " : "", |
| 11309 type.IsTypeParameter() ? | 11318 type.IsTypeParameter() ? |
| 11310 String::Handle(I, type.UserVisibleName()).ToCString() : | 11319 String::Handle(Z, type.UserVisibleName()).ToCString() : |
| 11311 "dynamic"); | 11320 "dynamic"); |
| 11312 } | 11321 } |
| 11313 // Attempting to instantiate an enum type is a compile-time error. | 11322 // Attempting to instantiate an enum type is a compile-time error. |
| 11314 Class& type_class = Class::Handle(I, type.type_class()); | 11323 Class& type_class = Class::Handle(Z, type.type_class()); |
| 11315 if (type_class.is_enum_class()) { | 11324 if (type_class.is_enum_class()) { |
| 11316 ReportError(new_pos, "enum type '%s' can not be instantiated", | 11325 ReportError(new_pos, "enum type '%s' can not be instantiated", |
| 11317 String::Handle(I, type_class.Name()).ToCString()); | 11326 String::Handle(Z, type_class.Name()).ToCString()); |
| 11318 } | 11327 } |
| 11319 | 11328 |
| 11320 // The grammar allows for an optional ('.' identifier)? after the type, which | 11329 // The grammar allows for an optional ('.' identifier)? after the type, which |
| 11321 // is a named constructor. Note that we tell ParseType() above not to | 11330 // is a named constructor. Note that we tell ParseType() above not to |
| 11322 // consume it as part of a misinterpreted qualified identifier. Only a | 11331 // consume it as part of a misinterpreted qualified identifier. Only a |
| 11323 // valid library prefix is accepted as qualifier. | 11332 // valid library prefix is accepted as qualifier. |
| 11324 String* named_constructor = NULL; | 11333 String* named_constructor = NULL; |
| 11325 if (CurrentToken() == Token::kPERIOD) { | 11334 if (CurrentToken() == Token::kPERIOD) { |
| 11326 ConsumeToken(); | 11335 ConsumeToken(); |
| 11327 named_constructor = ExpectIdentifier("name of constructor expected"); | 11336 named_constructor = ExpectIdentifier("name of constructor expected"); |
| 11328 } | 11337 } |
| 11329 | 11338 |
| 11330 // Parse constructor parameters. | 11339 // Parse constructor parameters. |
| 11331 CheckToken(Token::kLPAREN); | 11340 CheckToken(Token::kLPAREN); |
| 11332 intptr_t call_pos = TokenPos(); | 11341 intptr_t call_pos = TokenPos(); |
| 11333 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); | 11342 ArgumentListNode* arguments = ParseActualParameters(NULL, is_const); |
| 11334 | 11343 |
| 11335 // Parsing is complete, so we can return a throw in case of a malformed or | 11344 // Parsing is complete, so we can return a throw in case of a malformed or |
| 11336 // malbounded type or report a compile-time error if the constructor is const. | 11345 // malbounded type or report a compile-time error if the constructor is const. |
| 11337 if (type.IsMalformedOrMalbounded()) { | 11346 if (type.IsMalformedOrMalbounded()) { |
| 11338 if (is_const) { | 11347 if (is_const) { |
| 11339 const Error& error = Error::Handle(I, type.error()); | 11348 const Error& error = Error::Handle(Z, type.error()); |
| 11340 ReportError(error); | 11349 ReportError(error); |
| 11341 } | 11350 } |
| 11342 return ThrowTypeError(type_pos, type); | 11351 return ThrowTypeError(type_pos, type); |
| 11343 } | 11352 } |
| 11344 | 11353 |
| 11345 // Resolve the type and optional identifier to a constructor or factory. | 11354 // Resolve the type and optional identifier to a constructor or factory. |
| 11346 String& type_class_name = String::Handle(I, type_class.Name()); | 11355 String& type_class_name = String::Handle(Z, type_class.Name()); |
| 11347 TypeArguments& type_arguments = | 11356 TypeArguments& type_arguments = |
| 11348 TypeArguments::ZoneHandle(I, type.arguments()); | 11357 TypeArguments::ZoneHandle(Z, type.arguments()); |
| 11349 | 11358 |
| 11350 // A constructor has an implicit 'this' parameter (instance to construct) | 11359 // A constructor has an implicit 'this' parameter (instance to construct) |
| 11351 // and a factory has an implicit 'this' parameter (type_arguments). | 11360 // and a factory has an implicit 'this' parameter (type_arguments). |
| 11352 // A constructor has a second implicit 'phase' parameter. | 11361 // A constructor has a second implicit 'phase' parameter. |
| 11353 intptr_t arguments_length = arguments->length() + 2; | 11362 intptr_t arguments_length = arguments->length() + 2; |
| 11354 | 11363 |
| 11355 // An additional type check of the result of a redirecting factory may be | 11364 // An additional type check of the result of a redirecting factory may be |
| 11356 // required. | 11365 // required. |
| 11357 AbstractType& type_bound = AbstractType::ZoneHandle(I); | 11366 AbstractType& type_bound = AbstractType::ZoneHandle(Z); |
| 11358 | 11367 |
| 11359 // Make sure that an appropriate constructor exists. | 11368 // Make sure that an appropriate constructor exists. |
| 11360 String& constructor_name = | 11369 String& constructor_name = |
| 11361 BuildConstructorName(type_class_name, named_constructor); | 11370 BuildConstructorName(type_class_name, named_constructor); |
| 11362 Function& constructor = Function::ZoneHandle(I, | 11371 Function& constructor = Function::ZoneHandle(Z, |
| 11363 type_class.LookupConstructor(constructor_name)); | 11372 type_class.LookupConstructor(constructor_name)); |
| 11364 if (constructor.IsNull()) { | 11373 if (constructor.IsNull()) { |
| 11365 constructor = type_class.LookupFactory(constructor_name); | 11374 constructor = type_class.LookupFactory(constructor_name); |
| 11366 if (constructor.IsNull()) { | 11375 if (constructor.IsNull()) { |
| 11367 const String& external_constructor_name = | 11376 const String& external_constructor_name = |
| 11368 (named_constructor ? constructor_name : type_class_name); | 11377 (named_constructor ? constructor_name : type_class_name); |
| 11369 // Replace the type with a malformed type and compile a throw or report a | 11378 // Replace the type with a malformed type and compile a throw or report a |
| 11370 // compile-time error if the constructor is const. | 11379 // compile-time error if the constructor is const. |
| 11371 if (is_const) { | 11380 if (is_const) { |
| 11372 type = ClassFinalizer::NewFinalizedMalformedType( | 11381 type = ClassFinalizer::NewFinalizedMalformedType( |
| 11373 Error::Handle(I), // No previous error. | 11382 Error::Handle(Z), // No previous error. |
| 11374 script_, | 11383 script_, |
| 11375 call_pos, | 11384 call_pos, |
| 11376 "class '%s' has no constructor or factory named '%s'", | 11385 "class '%s' has no constructor or factory named '%s'", |
| 11377 String::Handle(I, type_class.Name()).ToCString(), | 11386 String::Handle(Z, type_class.Name()).ToCString(), |
| 11378 external_constructor_name.ToCString()); | 11387 external_constructor_name.ToCString()); |
| 11379 ReportError(Error::Handle(I, type.error())); | 11388 ReportError(Error::Handle(Z, type.error())); |
| 11380 } | 11389 } |
| 11381 return ThrowNoSuchMethodError(call_pos, | 11390 return ThrowNoSuchMethodError(call_pos, |
| 11382 type_class, | 11391 type_class, |
| 11383 external_constructor_name, | 11392 external_constructor_name, |
| 11384 arguments, | 11393 arguments, |
| 11385 InvocationMirror::kConstructor, | 11394 InvocationMirror::kConstructor, |
| 11386 InvocationMirror::kMethod, | 11395 InvocationMirror::kMethod, |
| 11387 NULL); // No existing function. | 11396 NULL); // No existing function. |
| 11388 } else if (constructor.IsRedirectingFactory()) { | 11397 } else if (constructor.IsRedirectingFactory()) { |
| 11389 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); | 11398 ClassFinalizer::ResolveRedirectingFactory(type_class, constructor); |
| 11390 Type& redirect_type = Type::Handle(I, constructor.RedirectionType()); | 11399 Type& redirect_type = Type::Handle(Z, constructor.RedirectionType()); |
| 11391 if (!redirect_type.IsMalformedOrMalbounded() && | 11400 if (!redirect_type.IsMalformedOrMalbounded() && |
| 11392 !redirect_type.IsInstantiated()) { | 11401 !redirect_type.IsInstantiated()) { |
| 11393 // The type arguments of the redirection type are instantiated from the | 11402 // The type arguments of the redirection type are instantiated from the |
| 11394 // type arguments of the parsed type of the 'new' or 'const' expression. | 11403 // type arguments of the parsed type of the 'new' or 'const' expression. |
| 11395 Error& error = Error::Handle(I); | 11404 Error& error = Error::Handle(Z); |
| 11396 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); | 11405 redirect_type ^= redirect_type.InstantiateFrom(type_arguments, &error); |
| 11397 if (!error.IsNull()) { | 11406 if (!error.IsNull()) { |
| 11398 redirect_type = ClassFinalizer::NewFinalizedMalformedType( | 11407 redirect_type = ClassFinalizer::NewFinalizedMalformedType( |
| 11399 error, | 11408 error, |
| 11400 script_, | 11409 script_, |
| 11401 call_pos, | 11410 call_pos, |
| 11402 "redirecting factory type '%s' cannot be instantiated", | 11411 "redirecting factory type '%s' cannot be instantiated", |
| 11403 String::Handle(I, redirect_type.UserVisibleName()).ToCString()); | 11412 String::Handle(Z, redirect_type.UserVisibleName()).ToCString()); |
| 11404 } | 11413 } |
| 11405 } | 11414 } |
| 11406 if (redirect_type.IsMalformedOrMalbounded()) { | 11415 if (redirect_type.IsMalformedOrMalbounded()) { |
| 11407 if (is_const) { | 11416 if (is_const) { |
| 11408 ReportError(Error::Handle(I, redirect_type.error())); | 11417 ReportError(Error::Handle(Z, redirect_type.error())); |
| 11409 } | 11418 } |
| 11410 return ThrowTypeError(redirect_type.token_pos(), redirect_type); | 11419 return ThrowTypeError(redirect_type.token_pos(), redirect_type); |
| 11411 } | 11420 } |
| 11412 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { | 11421 if (FLAG_enable_type_checks && !redirect_type.IsSubtypeOf(type, NULL)) { |
| 11413 // Additional type checking of the result is necessary. | 11422 // Additional type checking of the result is necessary. |
| 11414 type_bound = type.raw(); | 11423 type_bound = type.raw(); |
| 11415 } | 11424 } |
| 11416 type = redirect_type.raw(); | 11425 type = redirect_type.raw(); |
| 11417 type_class = type.type_class(); | 11426 type_class = type.type_class(); |
| 11418 type_class_name = type_class.Name(); | 11427 type_class_name = type_class.Name(); |
| 11419 type_arguments = type.arguments(); | 11428 type_arguments = type.arguments(); |
| 11420 constructor = constructor.RedirectionTarget(); | 11429 constructor = constructor.RedirectionTarget(); |
| 11421 constructor_name = constructor.name(); | 11430 constructor_name = constructor.name(); |
| 11422 ASSERT(!constructor.IsNull()); | 11431 ASSERT(!constructor.IsNull()); |
| 11423 } | 11432 } |
| 11424 if (constructor.IsFactory()) { | 11433 if (constructor.IsFactory()) { |
| 11425 // A factory does not have the implicit 'phase' parameter. | 11434 // A factory does not have the implicit 'phase' parameter. |
| 11426 arguments_length -= 1; | 11435 arguments_length -= 1; |
| 11427 } | 11436 } |
| 11428 } | 11437 } |
| 11429 | 11438 |
| 11430 // It is ok to call a factory method of an abstract class, but it is | 11439 // It is ok to call a factory method of an abstract class, but it is |
| 11431 // a dynamic error to instantiate an abstract class. | 11440 // a dynamic error to instantiate an abstract class. |
| 11432 ASSERT(!constructor.IsNull()); | 11441 ASSERT(!constructor.IsNull()); |
| 11433 if (type_class.is_abstract() && !constructor.IsFactory()) { | 11442 if (type_class.is_abstract() && !constructor.IsFactory()) { |
| 11434 // Evaluate arguments before throwing. | 11443 // Evaluate arguments before throwing. |
| 11435 LetNode* result = new(I) LetNode(call_pos); | 11444 LetNode* result = new(Z) LetNode(call_pos); |
| 11436 for (intptr_t i = 0; i < arguments->length(); ++i) { | 11445 for (intptr_t i = 0; i < arguments->length(); ++i) { |
| 11437 result->AddNode(arguments->NodeAt(i)); | 11446 result->AddNode(arguments->NodeAt(i)); |
| 11438 } | 11447 } |
| 11439 ArgumentListNode* error_arguments = new(I) ArgumentListNode(type_pos); | 11448 ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos); |
| 11440 error_arguments->Add(new(I) LiteralNode( | 11449 error_arguments->Add(new(Z) LiteralNode( |
| 11441 TokenPos(), Integer::ZoneHandle(I, Integer::New(type_pos)))); | 11450 TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos)))); |
| 11442 error_arguments->Add(new(I) LiteralNode( | 11451 error_arguments->Add(new(Z) LiteralNode( |
| 11443 TokenPos(), String::ZoneHandle(I, type_class_name.raw()))); | 11452 TokenPos(), String::ZoneHandle(Z, type_class_name.raw()))); |
| 11444 result->AddNode( | 11453 result->AddNode( |
| 11445 MakeStaticCall(Symbols::AbstractClassInstantiationError(), | 11454 MakeStaticCall(Symbols::AbstractClassInstantiationError(), |
| 11446 Library::PrivateCoreLibName(Symbols::ThrowNew()), | 11455 Library::PrivateCoreLibName(Symbols::ThrowNew()), |
| 11447 error_arguments)); | 11456 error_arguments)); |
| 11448 return result; | 11457 return result; |
| 11449 } | 11458 } |
| 11450 String& error_message = String::Handle(I); | 11459 String& error_message = String::Handle(Z); |
| 11451 if (!constructor.AreValidArguments(arguments_length, | 11460 if (!constructor.AreValidArguments(arguments_length, |
| 11452 arguments->names(), | 11461 arguments->names(), |
| 11453 &error_message)) { | 11462 &error_message)) { |
| 11454 const String& external_constructor_name = | 11463 const String& external_constructor_name = |
| 11455 (named_constructor ? constructor_name : type_class_name); | 11464 (named_constructor ? constructor_name : type_class_name); |
| 11456 if (is_const) { | 11465 if (is_const) { |
| 11457 ReportError(call_pos, | 11466 ReportError(call_pos, |
| 11458 "invalid arguments passed to constructor '%s' " | 11467 "invalid arguments passed to constructor '%s' " |
| 11459 "for class '%s': %s", | 11468 "for class '%s': %s", |
| 11460 external_constructor_name.ToCString(), | 11469 external_constructor_name.ToCString(), |
| 11461 String::Handle(I, type_class.Name()).ToCString(), | 11470 String::Handle(Z, type_class.Name()).ToCString(), |
| 11462 error_message.ToCString()); | 11471 error_message.ToCString()); |
| 11463 } | 11472 } |
| 11464 return ThrowNoSuchMethodError(call_pos, | 11473 return ThrowNoSuchMethodError(call_pos, |
| 11465 type_class, | 11474 type_class, |
| 11466 external_constructor_name, | 11475 external_constructor_name, |
| 11467 arguments, | 11476 arguments, |
| 11468 InvocationMirror::kConstructor, | 11477 InvocationMirror::kConstructor, |
| 11469 InvocationMirror::kMethod, | 11478 InvocationMirror::kMethod, |
| 11470 &constructor); | 11479 &constructor); |
| 11471 } | 11480 } |
| 11472 | 11481 |
| 11473 // Return a throw in case of a malformed or malbounded type or report a | 11482 // Return a throw in case of a malformed or malbounded type or report a |
| 11474 // compile-time error if the constructor is const. | 11483 // compile-time error if the constructor is const. |
| 11475 if (type.IsMalformedOrMalbounded()) { | 11484 if (type.IsMalformedOrMalbounded()) { |
| 11476 if (is_const) { | 11485 if (is_const) { |
| 11477 ReportError(Error::Handle(I, type.error())); | 11486 ReportError(Error::Handle(Z, type.error())); |
| 11478 } | 11487 } |
| 11479 return ThrowTypeError(type_pos, type); | 11488 return ThrowTypeError(type_pos, type); |
| 11480 } | 11489 } |
| 11481 type_arguments ^= type_arguments.Canonicalize(); | 11490 type_arguments ^= type_arguments.Canonicalize(); |
| 11482 // Make the constructor call. | 11491 // Make the constructor call. |
| 11483 AstNode* new_object = NULL; | 11492 AstNode* new_object = NULL; |
| 11484 if (is_const) { | 11493 if (is_const) { |
| 11485 if (!constructor.is_const()) { | 11494 if (!constructor.is_const()) { |
| 11486 const String& external_constructor_name = | 11495 const String& external_constructor_name = |
| 11487 (named_constructor ? constructor_name : type_class_name); | 11496 (named_constructor ? constructor_name : type_class_name); |
| 11488 ReportError("non-const constructor '%s' cannot be used in " | 11497 ReportError("non-const constructor '%s' cannot be used in " |
| 11489 "const object creation", | 11498 "const object creation", |
| 11490 external_constructor_name.ToCString()); | 11499 external_constructor_name.ToCString()); |
| 11491 } | 11500 } |
| 11492 const Object& constructor_result = Object::Handle(I, | 11501 const Object& constructor_result = Object::Handle(Z, |
| 11493 EvaluateConstConstructorCall(type_class, | 11502 EvaluateConstConstructorCall(type_class, |
| 11494 type_arguments, | 11503 type_arguments, |
| 11495 constructor, | 11504 constructor, |
| 11496 arguments)); | 11505 arguments)); |
| 11497 if (constructor_result.IsUnhandledException()) { | 11506 if (constructor_result.IsUnhandledException()) { |
| 11498 // It's a compile-time error if invocation of a const constructor | 11507 // It's a compile-time error if invocation of a const constructor |
| 11499 // call fails. | 11508 // call fails. |
| 11500 ReportErrors(Error::Cast(constructor_result), | 11509 ReportErrors(Error::Cast(constructor_result), |
| 11501 script_, new_pos, | 11510 script_, new_pos, |
| 11502 "error while evaluating const constructor"); | 11511 "error while evaluating const constructor"); |
| 11503 } else { | 11512 } else { |
| 11504 // Const constructors can return null in the case where a const native | 11513 // Const constructors can return null in the case where a const native |
| 11505 // factory returns a null value. Thus we cannot use a Instance::Cast here. | 11514 // factory returns a null value. Thus we cannot use a Instance::Cast here. |
| 11506 Instance& const_instance = Instance::Handle(I); | 11515 Instance& const_instance = Instance::Handle(Z); |
| 11507 const_instance ^= constructor_result.raw(); | 11516 const_instance ^= constructor_result.raw(); |
| 11508 new_object = new(I) LiteralNode( | 11517 new_object = new(Z) LiteralNode( |
| 11509 new_pos, Instance::ZoneHandle(I, const_instance.raw())); | 11518 new_pos, Instance::ZoneHandle(Z, const_instance.raw())); |
| 11510 if (!type_bound.IsNull()) { | 11519 if (!type_bound.IsNull()) { |
| 11511 ASSERT(!type_bound.IsMalformed()); | 11520 ASSERT(!type_bound.IsMalformed()); |
| 11512 Error& malformed_error = Error::Handle(I); | 11521 Error& malformed_error = Error::Handle(Z); |
| 11513 ASSERT(!is_top_level_); // We cannot check unresolved types. | 11522 ASSERT(!is_top_level_); // We cannot check unresolved types. |
| 11514 if (!const_instance.IsInstanceOf(type_bound, | 11523 if (!const_instance.IsInstanceOf(type_bound, |
| 11515 TypeArguments::Handle(I), | 11524 TypeArguments::Handle(Z), |
| 11516 &malformed_error)) { | 11525 &malformed_error)) { |
| 11517 type_bound = ClassFinalizer::NewFinalizedMalformedType( | 11526 type_bound = ClassFinalizer::NewFinalizedMalformedType( |
| 11518 malformed_error, | 11527 malformed_error, |
| 11519 script_, | 11528 script_, |
| 11520 new_pos, | 11529 new_pos, |
| 11521 "const factory result is not an instance of '%s'", | 11530 "const factory result is not an instance of '%s'", |
| 11522 String::Handle(I, type_bound.UserVisibleName()).ToCString()); | 11531 String::Handle(Z, type_bound.UserVisibleName()).ToCString()); |
| 11523 new_object = ThrowTypeError(new_pos, type_bound); | 11532 new_object = ThrowTypeError(new_pos, type_bound); |
| 11524 } | 11533 } |
| 11525 type_bound = AbstractType::null(); | 11534 type_bound = AbstractType::null(); |
| 11526 } | 11535 } |
| 11527 } | 11536 } |
| 11528 } else { | 11537 } else { |
| 11529 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); | 11538 CheckConstructorCallTypeArguments(new_pos, constructor, type_arguments); |
| 11530 if (!type_arguments.IsNull() && | 11539 if (!type_arguments.IsNull() && |
| 11531 !type_arguments.IsInstantiated() && | 11540 !type_arguments.IsInstantiated() && |
| 11532 (current_block_->scope->function_level() > 0)) { | 11541 (current_block_->scope->function_level() > 0)) { |
| 11533 // Make sure that the instantiator is captured. | 11542 // Make sure that the instantiator is captured. |
| 11534 CaptureInstantiator(); | 11543 CaptureInstantiator(); |
| 11535 } | 11544 } |
| 11536 // If the type argument vector is not instantiated, we verify in checked | 11545 // If the type argument vector is not instantiated, we verify in checked |
| 11537 // mode at runtime that it is within its declared bounds. | 11546 // mode at runtime that it is within its declared bounds. |
| 11538 new_object = CreateConstructorCallNode( | 11547 new_object = CreateConstructorCallNode( |
| 11539 new_pos, type_arguments, constructor, arguments); | 11548 new_pos, type_arguments, constructor, arguments); |
| 11540 } | 11549 } |
| 11541 if (!type_bound.IsNull()) { | 11550 if (!type_bound.IsNull()) { |
| 11542 new_object = new(I) AssignableNode( | 11551 new_object = new(Z) AssignableNode( |
| 11543 new_pos, new_object, type_bound, Symbols::FactoryResult()); | 11552 new_pos, new_object, type_bound, Symbols::FactoryResult()); |
| 11544 } | 11553 } |
| 11545 return new_object; | 11554 return new_object; |
| 11546 } | 11555 } |
| 11547 | 11556 |
| 11548 | 11557 |
| 11549 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { | 11558 String& Parser::Interpolate(const GrowableArray<AstNode*>& values) { |
| 11550 const Class& cls = Class::Handle( | 11559 const Class& cls = Class::Handle( |
| 11551 I, Library::LookupCoreClass(Symbols::StringBase())); | 11560 Z, Library::LookupCoreClass(Symbols::StringBase())); |
| 11552 ASSERT(!cls.IsNull()); | 11561 ASSERT(!cls.IsNull()); |
| 11553 const Function& func = Function::Handle(I, cls.LookupStaticFunction( | 11562 const Function& func = Function::Handle(Z, cls.LookupStaticFunction( |
| 11554 Library::PrivateCoreLibName(Symbols::Interpolate()))); | 11563 Library::PrivateCoreLibName(Symbols::Interpolate()))); |
| 11555 ASSERT(!func.IsNull()); | 11564 ASSERT(!func.IsNull()); |
| 11556 | 11565 |
| 11557 // Build the array of literal values to interpolate. | 11566 // Build the array of literal values to interpolate. |
| 11558 const Array& value_arr = Array::Handle(I, Array::New(values.length())); | 11567 const Array& value_arr = Array::Handle(Z, Array::New(values.length())); |
| 11559 for (int i = 0; i < values.length(); i++) { | 11568 for (int i = 0; i < values.length(); i++) { |
| 11560 ASSERT(values[i]->IsLiteralNode()); | 11569 ASSERT(values[i]->IsLiteralNode()); |
| 11561 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); | 11570 value_arr.SetAt(i, values[i]->AsLiteralNode()->literal()); |
| 11562 } | 11571 } |
| 11563 | 11572 |
| 11564 // Build argument array to pass to the interpolation function. | 11573 // Build argument array to pass to the interpolation function. |
| 11565 const Array& interpolate_arg = Array::Handle(I, Array::New(1)); | 11574 const Array& interpolate_arg = Array::Handle(Z, Array::New(1)); |
| 11566 interpolate_arg.SetAt(0, value_arr); | 11575 interpolate_arg.SetAt(0, value_arr); |
| 11567 | 11576 |
| 11568 // Call interpolation function. | 11577 // Call interpolation function. |
| 11569 Object& result = Object::Handle(I); | 11578 Object& result = Object::Handle(Z); |
| 11570 { | 11579 { |
| 11571 PAUSETIMERSCOPE(I, time_compilation); | 11580 PAUSETIMERSCOPE(I, time_compilation); |
| 11572 result = DartEntry::InvokeFunction(func, interpolate_arg); | 11581 result = DartEntry::InvokeFunction(func, interpolate_arg); |
| 11573 } | 11582 } |
| 11574 if (result.IsUnhandledException()) { | 11583 if (result.IsUnhandledException()) { |
| 11575 ReportError("%s", Error::Cast(result).ToErrorCString()); | 11584 ReportError("%s", Error::Cast(result).ToErrorCString()); |
| 11576 } | 11585 } |
| 11577 String& concatenated = String::ZoneHandle(I); | 11586 String& concatenated = String::ZoneHandle(Z); |
| 11578 concatenated ^= result.raw(); | 11587 concatenated ^= result.raw(); |
| 11579 concatenated = Symbols::New(concatenated); | 11588 concatenated = Symbols::New(concatenated); |
| 11580 return concatenated; | 11589 return concatenated; |
| 11581 } | 11590 } |
| 11582 | 11591 |
| 11583 | 11592 |
| 11584 // A string literal consists of the concatenation of the next n tokens | 11593 // A string literal consists of the concatenation of the next n tokens |
| 11585 // that satisfy the EBNF grammar: | 11594 // that satisfy the EBNF grammar: |
| 11586 // literal = kSTRING {{ interpol } kSTRING } | 11595 // literal = kSTRING {{ interpol } kSTRING } |
| 11587 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) | 11596 // interpol = kINTERPOL_VAR | (kINTERPOL_START expression kINTERPOL_END) |
| 11588 // In other words, the scanner breaks down interpolated strings so that | 11597 // In other words, the scanner breaks down interpolated strings so that |
| 11589 // a string literal always begins and ends with a kSTRING token. | 11598 // a string literal always begins and ends with a kSTRING token. |
| 11590 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { | 11599 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) { |
| 11591 TRACE_PARSER("ParseStringLiteral"); | 11600 TRACE_PARSER("ParseStringLiteral"); |
| 11592 AstNode* primary = NULL; | 11601 AstNode* primary = NULL; |
| 11593 const intptr_t literal_start = TokenPos(); | 11602 const intptr_t literal_start = TokenPos(); |
| 11594 ASSERT(CurrentToken() == Token::kSTRING); | 11603 ASSERT(CurrentToken() == Token::kSTRING); |
| 11595 Token::Kind l1_token = LookaheadToken(1); | 11604 Token::Kind l1_token = LookaheadToken(1); |
| 11596 if ((l1_token != Token::kSTRING) && | 11605 if ((l1_token != Token::kSTRING) && |
| 11597 (l1_token != Token::kINTERPOL_VAR) && | 11606 (l1_token != Token::kINTERPOL_VAR) && |
| 11598 (l1_token != Token::kINTERPOL_START)) { | 11607 (l1_token != Token::kINTERPOL_START)) { |
| 11599 // Common case: no interpolation. | 11608 // Common case: no interpolation. |
| 11600 primary = new(I) LiteralNode(literal_start, *CurrentLiteral()); | 11609 primary = new(Z) LiteralNode(literal_start, *CurrentLiteral()); |
| 11601 ConsumeToken(); | 11610 ConsumeToken(); |
| 11602 return primary; | 11611 return primary; |
| 11603 } | 11612 } |
| 11604 // String interpolation needed. | 11613 // String interpolation needed. |
| 11605 bool is_compiletime_const = true; | 11614 bool is_compiletime_const = true; |
| 11606 bool has_interpolation = false; | 11615 bool has_interpolation = false; |
| 11607 GrowableArray<AstNode*> values_list; | 11616 GrowableArray<AstNode*> values_list; |
| 11608 while (CurrentToken() == Token::kSTRING) { | 11617 while (CurrentToken() == Token::kSTRING) { |
| 11609 if (CurrentLiteral()->Length() > 0) { | 11618 if (CurrentLiteral()->Length() > 0) { |
| 11610 // Only add non-empty string sections to the values list | 11619 // Only add non-empty string sections to the values list |
| 11611 // that will be concatenated. | 11620 // that will be concatenated. |
| 11612 values_list.Add(new(I) LiteralNode(TokenPos(), *CurrentLiteral())); | 11621 values_list.Add(new(Z) LiteralNode(TokenPos(), *CurrentLiteral())); |
| 11613 } | 11622 } |
| 11614 ConsumeToken(); | 11623 ConsumeToken(); |
| 11615 while ((CurrentToken() == Token::kINTERPOL_VAR) || | 11624 while ((CurrentToken() == Token::kINTERPOL_VAR) || |
| 11616 (CurrentToken() == Token::kINTERPOL_START)) { | 11625 (CurrentToken() == Token::kINTERPOL_START)) { |
| 11617 if (!allow_interpolation) { | 11626 if (!allow_interpolation) { |
| 11618 ReportError("string interpolation not allowed in this context"); | 11627 ReportError("string interpolation not allowed in this context"); |
| 11619 } | 11628 } |
| 11620 has_interpolation = true; | 11629 has_interpolation = true; |
| 11621 AstNode* expr = NULL; | 11630 AstNode* expr = NULL; |
| 11622 const intptr_t expr_pos = TokenPos(); | 11631 const intptr_t expr_pos = TokenPos(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 11636 // a constant or not. Only strings, numbers, booleans and null values | 11645 // a constant or not. Only strings, numbers, booleans and null values |
| 11637 // are allowed in compile time const interpolations. | 11646 // are allowed in compile time const interpolations. |
| 11638 if (is_compiletime_const) { | 11647 if (is_compiletime_const) { |
| 11639 const Object* const_expr = expr->EvalConstExpr(); | 11648 const Object* const_expr = expr->EvalConstExpr(); |
| 11640 if ((const_expr != NULL) && | 11649 if ((const_expr != NULL) && |
| 11641 (const_expr->IsNumber() || | 11650 (const_expr->IsNumber() || |
| 11642 const_expr->IsString() || | 11651 const_expr->IsString() || |
| 11643 const_expr->IsBool() || | 11652 const_expr->IsBool() || |
| 11644 const_expr->IsNull())) { | 11653 const_expr->IsNull())) { |
| 11645 // Change expr into a literal. | 11654 // Change expr into a literal. |
| 11646 expr = new(I) LiteralNode(expr_pos, | 11655 expr = new(Z) LiteralNode(expr_pos, |
| 11647 EvaluateConstExpr(expr_pos, expr)); | 11656 EvaluateConstExpr(expr_pos, expr)); |
| 11648 } else { | 11657 } else { |
| 11649 is_compiletime_const = false; | 11658 is_compiletime_const = false; |
| 11650 } | 11659 } |
| 11651 } | 11660 } |
| 11652 values_list.Add(expr); | 11661 values_list.Add(expr); |
| 11653 } | 11662 } |
| 11654 } | 11663 } |
| 11655 if (is_compiletime_const) { | 11664 if (is_compiletime_const) { |
| 11656 if (has_interpolation) { | 11665 if (has_interpolation) { |
| 11657 primary = new(I) LiteralNode(literal_start, Interpolate(values_list)); | 11666 primary = new(Z) LiteralNode(literal_start, Interpolate(values_list)); |
| 11658 } else { | 11667 } else { |
| 11659 const Array& strings = Array::Handle(I, Array::New(values_list.length())); | 11668 const Array& strings = Array::Handle(Z, Array::New(values_list.length())); |
| 11660 for (int i = 0; i < values_list.length(); i++) { | 11669 for (int i = 0; i < values_list.length(); i++) { |
| 11661 const Instance& part = values_list[i]->AsLiteralNode()->literal(); | 11670 const Instance& part = values_list[i]->AsLiteralNode()->literal(); |
| 11662 ASSERT(part.IsString()); | 11671 ASSERT(part.IsString()); |
| 11663 strings.SetAt(i, String::Cast(part)); | 11672 strings.SetAt(i, String::Cast(part)); |
| 11664 } | 11673 } |
| 11665 String& lit = String::ZoneHandle(I, | 11674 String& lit = String::ZoneHandle(Z, |
| 11666 String::ConcatAll(strings, Heap::kOld)); | 11675 String::ConcatAll(strings, Heap::kOld)); |
| 11667 lit = Symbols::New(lit); | 11676 lit = Symbols::New(lit); |
| 11668 primary = new(I) LiteralNode(literal_start, lit); | 11677 primary = new(Z) LiteralNode(literal_start, lit); |
| 11669 } | 11678 } |
| 11670 } else { | 11679 } else { |
| 11671 ArrayNode* values = new(I) ArrayNode( | 11680 ArrayNode* values = new(Z) ArrayNode( |
| 11672 TokenPos(), | 11681 TokenPos(), |
| 11673 Type::ZoneHandle(I, Type::ArrayType()), | 11682 Type::ZoneHandle(Z, Type::ArrayType()), |
| 11674 values_list); | 11683 values_list); |
| 11675 primary = new(I) StringInterpolateNode(TokenPos(), values); | 11684 primary = new(Z) StringInterpolateNode(TokenPos(), values); |
| 11676 } | 11685 } |
| 11677 return primary; | 11686 return primary; |
| 11678 } | 11687 } |
| 11679 | 11688 |
| 11680 | 11689 |
| 11681 AstNode* Parser::ParsePrimary() { | 11690 AstNode* Parser::ParsePrimary() { |
| 11682 TRACE_PARSER("ParsePrimary"); | 11691 TRACE_PARSER("ParsePrimary"); |
| 11683 ASSERT(!is_top_level_); | 11692 ASSERT(!is_top_level_); |
| 11684 AstNode* primary = NULL; | 11693 AstNode* primary = NULL; |
| 11685 const Token::Kind token = CurrentToken(); | 11694 const Token::Kind token = CurrentToken(); |
| 11686 if (IsFunctionLiteral()) { | 11695 if (IsFunctionLiteral()) { |
| 11687 // The name of a literal function is visible from inside the function, but | 11696 // The name of a literal function is visible from inside the function, but |
| 11688 // must not collide with names in the scope declaring the literal. | 11697 // must not collide with names in the scope declaring the literal. |
| 11689 OpenBlock(); | 11698 OpenBlock(); |
| 11690 primary = ParseFunctionStatement(true); | 11699 primary = ParseFunctionStatement(true); |
| 11691 CloseBlock(); | 11700 CloseBlock(); |
| 11692 } else if (IsIdentifier()) { | 11701 } else if (IsIdentifier()) { |
| 11693 intptr_t qual_ident_pos = TokenPos(); | 11702 intptr_t qual_ident_pos = TokenPos(); |
| 11694 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(I, ParsePrefix()); | 11703 const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix()); |
| 11695 String& ident = *CurrentLiteral(); | 11704 String& ident = *CurrentLiteral(); |
| 11696 ConsumeToken(); | 11705 ConsumeToken(); |
| 11697 if (prefix.IsNull()) { | 11706 if (prefix.IsNull()) { |
| 11698 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { | 11707 if (!ResolveIdentInLocalScope(qual_ident_pos, ident, &primary)) { |
| 11699 // Check whether the identifier is a type parameter. | 11708 // Check whether the identifier is a type parameter. |
| 11700 if (!current_class().IsNull()) { | 11709 if (!current_class().IsNull()) { |
| 11701 TypeParameter& type_param = TypeParameter::ZoneHandle(I, | 11710 TypeParameter& type_param = TypeParameter::ZoneHandle(Z, |
| 11702 current_class().LookupTypeParameter(ident)); | 11711 current_class().LookupTypeParameter(ident)); |
| 11703 if (!type_param.IsNull()) { | 11712 if (!type_param.IsNull()) { |
| 11704 return new(I) PrimaryNode(qual_ident_pos, type_param); | 11713 return new(Z) PrimaryNode(qual_ident_pos, type_param); |
| 11705 } | 11714 } |
| 11706 } | 11715 } |
| 11707 // This is a non-local unqualified identifier so resolve the | 11716 // This is a non-local unqualified identifier so resolve the |
| 11708 // identifier locally in the main app library and all libraries | 11717 // identifier locally in the main app library and all libraries |
| 11709 // imported by it. | 11718 // imported by it. |
| 11710 primary = ResolveIdentInCurrentLibraryScope(qual_ident_pos, ident); | 11719 primary = ResolveIdentInCurrentLibraryScope(qual_ident_pos, ident); |
| 11711 } | 11720 } |
| 11712 } else { | 11721 } else { |
| 11713 // This is a qualified identifier with a library prefix so resolve | 11722 // This is a qualified identifier with a library prefix so resolve |
| 11714 // the identifier locally in that library (we do not include the | 11723 // the identifier locally in that library (we do not include the |
| 11715 // libraries imported by that library). | 11724 // libraries imported by that library). |
| 11716 primary = ResolveIdentInPrefixScope(qual_ident_pos, prefix, ident); | 11725 primary = ResolveIdentInPrefixScope(qual_ident_pos, prefix, ident); |
| 11717 | 11726 |
| 11718 // If the identifier could not be resolved, throw a NoSuchMethodError. | 11727 // If the identifier could not be resolved, throw a NoSuchMethodError. |
| 11719 // Note: unlike in the case of an unqualified identifier, do not | 11728 // Note: unlike in the case of an unqualified identifier, do not |
| 11720 // interpret the unresolved identifier as an instance method or | 11729 // interpret the unresolved identifier as an instance method or |
| 11721 // instance getter call when compiling an instance method. | 11730 // instance getter call when compiling an instance method. |
| 11722 if (primary == NULL) { | 11731 if (primary == NULL) { |
| 11723 if (prefix.is_deferred_load() && | 11732 if (prefix.is_deferred_load() && |
| 11724 ident.Equals(Symbols::LoadLibrary())) { | 11733 ident.Equals(Symbols::LoadLibrary())) { |
| 11725 // Hack Alert: recognize special 'loadLibrary' call on the | 11734 // Hack Alert: recognize special 'loadLibrary' call on the |
| 11726 // prefix object. The prefix is the primary. Rewind parser and | 11735 // prefix object. The prefix is the primary. Rewind parser and |
| 11727 // let ParseSelectors() handle the loadLibrary call. | 11736 // let ParseSelectors() handle the loadLibrary call. |
| 11728 SetPosition(qual_ident_pos); | 11737 SetPosition(qual_ident_pos); |
| 11729 ConsumeToken(); // Prefix name. | 11738 ConsumeToken(); // Prefix name. |
| 11730 primary = new(I) LiteralNode(qual_ident_pos, prefix); | 11739 primary = new(Z) LiteralNode(qual_ident_pos, prefix); |
| 11731 } else { | 11740 } else { |
| 11732 // TODO(hausner): Ideally we should generate the NoSuchMethodError | 11741 // TODO(hausner): Ideally we should generate the NoSuchMethodError |
| 11733 // later, when we know more about how the unresolved name is used. | 11742 // later, when we know more about how the unresolved name is used. |
| 11734 // For example, we don't know yet whether the unresolved name | 11743 // For example, we don't know yet whether the unresolved name |
| 11735 // refers to a getter or a setter. However, it is more awkward | 11744 // refers to a getter or a setter. However, it is more awkward |
| 11736 // to distinuish four NoSuchMethodError cases all over the place | 11745 // to distinuish four NoSuchMethodError cases all over the place |
| 11737 // in the parser. The four cases are: prefixed vs non-prefixed | 11746 // in the parser. The four cases are: prefixed vs non-prefixed |
| 11738 // name, static vs dynamic context in which the unresolved name | 11747 // name, static vs dynamic context in which the unresolved name |
| 11739 // is used. We cheat a little here by looking at the next token | 11748 // is used. We cheat a little here by looking at the next token |
| 11740 // to determine whether we have an unresolved method call or | 11749 // to determine whether we have an unresolved method call or |
| 11741 // field access. | 11750 // field access. |
| 11742 String& qualified_name = String::ZoneHandle(I, prefix.name()); | 11751 String& qualified_name = String::ZoneHandle(Z, prefix.name()); |
| 11743 qualified_name = String::Concat(qualified_name, Symbols::Dot()); | 11752 qualified_name = String::Concat(qualified_name, Symbols::Dot()); |
| 11744 qualified_name = String::Concat(qualified_name, ident); | 11753 qualified_name = String::Concat(qualified_name, ident); |
| 11745 qualified_name = Symbols::New(qualified_name); | 11754 qualified_name = Symbols::New(qualified_name); |
| 11746 InvocationMirror::Type call_type = | 11755 InvocationMirror::Type call_type = |
| 11747 CurrentToken() == Token::kLPAREN ? | 11756 CurrentToken() == Token::kLPAREN ? |
| 11748 InvocationMirror::kMethod : InvocationMirror::kGetter; | 11757 InvocationMirror::kMethod : InvocationMirror::kGetter; |
| 11749 primary = ThrowNoSuchMethodError(qual_ident_pos, | 11758 primary = ThrowNoSuchMethodError(qual_ident_pos, |
| 11750 current_class(), | 11759 current_class(), |
| 11751 qualified_name, | 11760 qualified_name, |
| 11752 NULL, // No arguments. | 11761 NULL, // No arguments. |
| 11753 InvocationMirror::kTopLevel, | 11762 InvocationMirror::kTopLevel, |
| 11754 call_type, | 11763 call_type, |
| 11755 NULL); // No existing function. | 11764 NULL); // No existing function. |
| 11756 } | 11765 } |
| 11757 } | 11766 } |
| 11758 } | 11767 } |
| 11759 ASSERT(primary != NULL); | 11768 ASSERT(primary != NULL); |
| 11760 } else if (token == Token::kTHIS) { | 11769 } else if (token == Token::kTHIS) { |
| 11761 LocalVariable* local = LookupLocalScope(Symbols::This()); | 11770 LocalVariable* local = LookupLocalScope(Symbols::This()); |
| 11762 if (local == NULL) { | 11771 if (local == NULL) { |
| 11763 ReportError("receiver 'this' is not in scope"); | 11772 ReportError("receiver 'this' is not in scope"); |
| 11764 } | 11773 } |
| 11765 primary = new(I) LoadLocalNode(TokenPos(), local); | 11774 primary = new(Z) LoadLocalNode(TokenPos(), local); |
| 11766 ConsumeToken(); | 11775 ConsumeToken(); |
| 11767 } else if (token == Token::kINTEGER) { | 11776 } else if (token == Token::kINTEGER) { |
| 11768 const Integer& literal = Integer::ZoneHandle(I, CurrentIntegerLiteral()); | 11777 const Integer& literal = Integer::ZoneHandle(Z, CurrentIntegerLiteral()); |
| 11769 primary = new(I) LiteralNode(TokenPos(), literal); | 11778 primary = new(Z) LiteralNode(TokenPos(), literal); |
| 11770 ConsumeToken(); | 11779 ConsumeToken(); |
| 11771 } else if (token == Token::kTRUE) { | 11780 } else if (token == Token::kTRUE) { |
| 11772 primary = new(I) LiteralNode(TokenPos(), Bool::True()); | 11781 primary = new(Z) LiteralNode(TokenPos(), Bool::True()); |
| 11773 ConsumeToken(); | 11782 ConsumeToken(); |
| 11774 } else if (token == Token::kFALSE) { | 11783 } else if (token == Token::kFALSE) { |
| 11775 primary = new(I) LiteralNode(TokenPos(), Bool::False()); | 11784 primary = new(Z) LiteralNode(TokenPos(), Bool::False()); |
| 11776 ConsumeToken(); | 11785 ConsumeToken(); |
| 11777 } else if (token == Token::kNULL) { | 11786 } else if (token == Token::kNULL) { |
| 11778 primary = new(I) LiteralNode(TokenPos(), Instance::ZoneHandle(I)); | 11787 primary = new(Z) LiteralNode(TokenPos(), Instance::ZoneHandle(Z)); |
| 11779 ConsumeToken(); | 11788 ConsumeToken(); |
| 11780 } else if (token == Token::kLPAREN) { | 11789 } else if (token == Token::kLPAREN) { |
| 11781 ConsumeToken(); | 11790 ConsumeToken(); |
| 11782 const bool saved_mode = SetAllowFunctionLiterals(true); | 11791 const bool saved_mode = SetAllowFunctionLiterals(true); |
| 11783 primary = ParseExpr(kAllowConst, kConsumeCascades); | 11792 primary = ParseExpr(kAllowConst, kConsumeCascades); |
| 11784 SetAllowFunctionLiterals(saved_mode); | 11793 SetAllowFunctionLiterals(saved_mode); |
| 11785 ExpectToken(Token::kRPAREN); | 11794 ExpectToken(Token::kRPAREN); |
| 11786 } else if (token == Token::kDOUBLE) { | 11795 } else if (token == Token::kDOUBLE) { |
| 11787 Double& double_value = Double::ZoneHandle(I, CurrentDoubleLiteral()); | 11796 Double& double_value = Double::ZoneHandle(Z, CurrentDoubleLiteral()); |
| 11788 if (double_value.IsNull()) { | 11797 if (double_value.IsNull()) { |
| 11789 ReportError("invalid double literal"); | 11798 ReportError("invalid double literal"); |
| 11790 } | 11799 } |
| 11791 primary = new(I) LiteralNode(TokenPos(), double_value); | 11800 primary = new(Z) LiteralNode(TokenPos(), double_value); |
| 11792 ConsumeToken(); | 11801 ConsumeToken(); |
| 11793 } else if (token == Token::kSTRING) { | 11802 } else if (token == Token::kSTRING) { |
| 11794 primary = ParseStringLiteral(true); | 11803 primary = ParseStringLiteral(true); |
| 11795 } else if (token == Token::kNEW) { | 11804 } else if (token == Token::kNEW) { |
| 11796 ConsumeToken(); | 11805 ConsumeToken(); |
| 11797 primary = ParseNewOperator(Token::kNEW); | 11806 primary = ParseNewOperator(Token::kNEW); |
| 11798 } else if (token == Token::kCONST) { | 11807 } else if (token == Token::kCONST) { |
| 11799 if ((LookaheadToken(1) == Token::kLT) || | 11808 if ((LookaheadToken(1) == Token::kLT) || |
| 11800 (LookaheadToken(1) == Token::kLBRACK) || | 11809 (LookaheadToken(1) == Token::kLBRACK) || |
| 11801 (LookaheadToken(1) == Token::kINDEX) || | 11810 (LookaheadToken(1) == Token::kINDEX) || |
| 11802 (LookaheadToken(1) == Token::kLBRACE)) { | 11811 (LookaheadToken(1) == Token::kLBRACE)) { |
| 11803 primary = ParseCompoundLiteral(); | 11812 primary = ParseCompoundLiteral(); |
| 11804 } else { | 11813 } else { |
| 11805 ConsumeToken(); | 11814 ConsumeToken(); |
| 11806 primary = ParseNewOperator(Token::kCONST); | 11815 primary = ParseNewOperator(Token::kCONST); |
| 11807 } | 11816 } |
| 11808 } else if (token == Token::kLT || | 11817 } else if (token == Token::kLT || |
| 11809 token == Token::kLBRACK || | 11818 token == Token::kLBRACK || |
| 11810 token == Token::kINDEX || | 11819 token == Token::kINDEX || |
| 11811 token == Token::kLBRACE) { | 11820 token == Token::kLBRACE) { |
| 11812 primary = ParseCompoundLiteral(); | 11821 primary = ParseCompoundLiteral(); |
| 11813 } else if (token == Token::kHASH) { | 11822 } else if (token == Token::kHASH) { |
| 11814 primary = ParseSymbolLiteral(); | 11823 primary = ParseSymbolLiteral(); |
| 11815 } else if (token == Token::kSUPER) { | 11824 } else if (token == Token::kSUPER) { |
| 11816 if (current_function().is_static()) { | 11825 if (current_function().is_static()) { |
| 11817 ReportError("cannot access superclass from static method"); | 11826 ReportError("cannot access superclass from static method"); |
| 11818 } | 11827 } |
| 11819 if (current_class().SuperClass() == Class::null()) { | 11828 if (current_class().SuperClass() == Class::null()) { |
| 11820 ReportError("class '%s' does not have a superclass", | 11829 ReportError("class '%s' does not have a superclass", |
| 11821 String::Handle(I, current_class().Name()).ToCString()); | 11830 String::Handle(Z, current_class().Name()).ToCString()); |
| 11822 } | 11831 } |
| 11823 if (current_class().IsMixinApplication()) { | 11832 if (current_class().IsMixinApplication()) { |
| 11824 const Type& mixin_type = Type::Handle(I, current_class().mixin()); | 11833 const Type& mixin_type = Type::Handle(Z, current_class().mixin()); |
| 11825 if (mixin_type.type_class() == current_function().origin()) { | 11834 if (mixin_type.type_class() == current_function().origin()) { |
| 11826 ReportError("method of mixin class '%s' may not refer to 'super'", | 11835 ReportError("method of mixin class '%s' may not refer to 'super'", |
| 11827 String::Handle(I, Class::Handle(I, | 11836 String::Handle(Z, Class::Handle(Z, |
| 11828 current_function().origin()).Name()).ToCString()); | 11837 current_function().origin()).Name()).ToCString()); |
| 11829 } | 11838 } |
| 11830 } | 11839 } |
| 11831 const intptr_t super_pos = TokenPos(); | 11840 const intptr_t super_pos = TokenPos(); |
| 11832 ConsumeToken(); | 11841 ConsumeToken(); |
| 11833 if (CurrentToken() == Token::kPERIOD) { | 11842 if (CurrentToken() == Token::kPERIOD) { |
| 11834 ConsumeToken(); | 11843 ConsumeToken(); |
| 11835 const intptr_t ident_pos = TokenPos(); | 11844 const intptr_t ident_pos = TokenPos(); |
| 11836 const String& ident = *ExpectIdentifier("identifier expected"); | 11845 const String& ident = *ExpectIdentifier("identifier expected"); |
| 11837 if (CurrentToken() == Token::kLPAREN) { | 11846 if (CurrentToken() == Token::kLPAREN) { |
| 11838 primary = ParseSuperCall(ident); | 11847 primary = ParseSuperCall(ident); |
| 11839 } else { | 11848 } else { |
| 11840 primary = ParseSuperFieldAccess(ident, ident_pos); | 11849 primary = ParseSuperFieldAccess(ident, ident_pos); |
| 11841 } | 11850 } |
| 11842 } else if ((CurrentToken() == Token::kLBRACK) || | 11851 } else if ((CurrentToken() == Token::kLBRACK) || |
| 11843 Token::CanBeOverloaded(CurrentToken()) || | 11852 Token::CanBeOverloaded(CurrentToken()) || |
| 11844 (CurrentToken() == Token::kNE)) { | 11853 (CurrentToken() == Token::kNE)) { |
| 11845 primary = ParseSuperOperator(); | 11854 primary = ParseSuperOperator(); |
| 11846 } else { | 11855 } else { |
| 11847 primary = new(I) PrimaryNode(super_pos, Symbols::Super()); | 11856 primary = new(Z) PrimaryNode(super_pos, Symbols::Super()); |
| 11848 } | 11857 } |
| 11849 } else { | 11858 } else { |
| 11850 UnexpectedToken(); | 11859 UnexpectedToken(); |
| 11851 } | 11860 } |
| 11852 return primary; | 11861 return primary; |
| 11853 } | 11862 } |
| 11854 | 11863 |
| 11855 | 11864 |
| 11856 // Evaluate expression in expr and return the value. The expression must | 11865 // Evaluate expression in expr and return the value. The expression must |
| 11857 // be a compile time constant. | 11866 // be a compile time constant. |
| 11858 const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) { | 11867 const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) { |
| 11859 if (expr->IsLiteralNode()) { | 11868 if (expr->IsLiteralNode()) { |
| 11860 return expr->AsLiteralNode()->literal(); | 11869 return expr->AsLiteralNode()->literal(); |
| 11861 } else if (expr->IsLoadLocalNode() && | 11870 } else if (expr->IsLoadLocalNode() && |
| 11862 expr->AsLoadLocalNode()->local().IsConst()) { | 11871 expr->AsLoadLocalNode()->local().IsConst()) { |
| 11863 return *expr->AsLoadLocalNode()->local().ConstValue(); | 11872 return *expr->AsLoadLocalNode()->local().ConstValue(); |
| 11864 } else if (expr->IsLoadStaticFieldNode()) { | 11873 } else if (expr->IsLoadStaticFieldNode()) { |
| 11865 const Field& field = expr->AsLoadStaticFieldNode()->field(); | 11874 const Field& field = expr->AsLoadStaticFieldNode()->field(); |
| 11866 // We already checked that this field is const and has been | 11875 // We already checked that this field is const and has been |
| 11867 // initialized. | 11876 // initialized. |
| 11868 ASSERT(field.is_const()); | 11877 ASSERT(field.is_const()); |
| 11869 ASSERT(field.value() != Object::sentinel().raw()); | 11878 ASSERT(field.value() != Object::sentinel().raw()); |
| 11870 ASSERT(field.value() != Object::transition_sentinel().raw()); | 11879 ASSERT(field.value() != Object::transition_sentinel().raw()); |
| 11871 return Instance::ZoneHandle(I, field.value()); | 11880 return Instance::ZoneHandle(Z, field.value()); |
| 11872 } else { | 11881 } else { |
| 11873 ASSERT(expr->EvalConstExpr() != NULL); | 11882 ASSERT(expr->EvalConstExpr() != NULL); |
| 11874 ReturnNode* ret = new(I) ReturnNode(expr->token_pos(), expr); | 11883 ReturnNode* ret = new(Z) ReturnNode(expr->token_pos(), expr); |
| 11875 // Compile time constant expressions cannot reference anything from a | 11884 // Compile time constant expressions cannot reference anything from a |
| 11876 // local scope. | 11885 // local scope. |
| 11877 LocalScope* empty_scope = new(I) LocalScope(NULL, 0, 0); | 11886 LocalScope* empty_scope = new(Z) LocalScope(NULL, 0, 0); |
| 11878 SequenceNode* seq = new(I) SequenceNode(expr->token_pos(), empty_scope); | 11887 SequenceNode* seq = new(Z) SequenceNode(expr->token_pos(), empty_scope); |
| 11879 seq->Add(ret); | 11888 seq->Add(ret); |
| 11880 | 11889 |
| 11881 Object& result = Object::Handle(I, Compiler::ExecuteOnce(seq)); | 11890 Object& result = Object::Handle(Z, Compiler::ExecuteOnce(seq)); |
| 11882 if (result.IsError()) { | 11891 if (result.IsError()) { |
| 11883 ReportErrors(Error::Cast(result), | 11892 ReportErrors(Error::Cast(result), |
| 11884 script_, expr_pos, | 11893 script_, expr_pos, |
| 11885 "error evaluating constant expression"); | 11894 "error evaluating constant expression"); |
| 11886 } | 11895 } |
| 11887 ASSERT(result.IsInstance()); | 11896 ASSERT(result.IsInstance()); |
| 11888 Instance& value = Instance::ZoneHandle(I); | 11897 Instance& value = Instance::ZoneHandle(Z); |
| 11889 value ^= result.raw(); | 11898 value ^= result.raw(); |
| 11890 value = TryCanonicalize(value, TokenPos()); | 11899 value = TryCanonicalize(value, TokenPos()); |
| 11891 return value; | 11900 return value; |
| 11892 } | 11901 } |
| 11893 } | 11902 } |
| 11894 | 11903 |
| 11895 | 11904 |
| 11896 void Parser::SkipFunctionLiteral() { | 11905 void Parser::SkipFunctionLiteral() { |
| 11897 if (IsIdentifier()) { | 11906 if (IsIdentifier()) { |
| 11898 if (LookaheadToken(1) != Token::kLPAREN) { | 11907 if (LookaheadToken(1) != Token::kLPAREN) { |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12224 void Parser::SkipQualIdent() { | 12233 void Parser::SkipQualIdent() { |
| 12225 ASSERT(IsIdentifier()); | 12234 ASSERT(IsIdentifier()); |
| 12226 ConsumeToken(); | 12235 ConsumeToken(); |
| 12227 if (CurrentToken() == Token::kPERIOD) { | 12236 if (CurrentToken() == Token::kPERIOD) { |
| 12228 ConsumeToken(); // Consume the kPERIOD token. | 12237 ConsumeToken(); // Consume the kPERIOD token. |
| 12229 ExpectIdentifier("identifier expected after '.'"); | 12238 ExpectIdentifier("identifier expected after '.'"); |
| 12230 } | 12239 } |
| 12231 } | 12240 } |
| 12232 | 12241 |
| 12233 } // namespace dart | 12242 } // namespace dart |
| OLD | NEW |