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 "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 254 DISALLOW_COPY_AND_ASSIGN(TryBlocks); | 254 DISALLOW_COPY_AND_ASSIGN(TryBlocks); |
| 255 }; | 255 }; |
| 256 | 256 |
| 257 | 257 |
| 258 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { | 258 void Parser::TryBlocks::AddNodeForFinallyInlining(AstNode* node) { |
| 259 inlined_finally_nodes_.Add(node); | 259 inlined_finally_nodes_.Add(node); |
| 260 } | 260 } |
| 261 | 261 |
| 262 | 262 |
| 263 // For parsing a compilation unit. | 263 // For parsing a compilation unit. |
| 264 Parser::Parser(const Script& script, const Library& library) | 264 Parser::Parser(const Script& script, const Library& library, intptr_t token_pos) |
| 265 : script_(Script::Handle(script.raw())), | 265 : script_(Script::Handle(script.raw())), |
| 266 tokens_iterator_(TokenStream::Handle(script.tokens()), 0), | 266 tokens_iterator_(TokenStream::Handle(script.tokens()), token_pos), |
| 267 token_kind_(Token::kILLEGAL), | 267 token_kind_(Token::kILLEGAL), |
| 268 current_block_(NULL), | 268 current_block_(NULL), |
| 269 is_top_level_(false), | 269 is_top_level_(false), |
| 270 current_member_(NULL), | 270 current_member_(NULL), |
| 271 allow_function_literals_(true), | 271 allow_function_literals_(true), |
| 272 parsed_function_(NULL), | 272 parsed_function_(NULL), |
| 273 innermost_function_(Function::Handle()), | 273 innermost_function_(Function::Handle()), |
| 274 current_class_(Class::Handle()), | 274 current_class_(Class::Handle()), |
| 275 library_(Library::Handle(library.raw())), | 275 library_(Library::Handle(library.raw())), |
| 276 try_blocks_list_(NULL) { | 276 try_blocks_list_(NULL) { |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 345 } | 345 } |
| 346 tokens_iterator_.SetCurrentPosition(position); | 346 tokens_iterator_.SetCurrentPosition(position); |
| 347 token_kind_ = Token::kILLEGAL; | 347 token_kind_ = Token::kILLEGAL; |
| 348 } | 348 } |
| 349 | 349 |
| 350 | 350 |
| 351 void Parser::ParseCompilationUnit(const Library& library, | 351 void Parser::ParseCompilationUnit(const Library& library, |
| 352 const Script& script) { | 352 const Script& script) { |
| 353 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); | 353 ASSERT(Isolate::Current()->long_jump_base()->IsSafeToJump()); |
| 354 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 354 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 355 Parser parser(script, library); | 355 Parser parser(script, library, 0); |
| 356 parser.ParseTopLevel(); | 356 parser.ParseTopLevel(); |
| 357 } | 357 } |
| 358 | 358 |
| 359 | 359 |
| 360 Token::Kind Parser::CurrentToken() { | 360 Token::Kind Parser::CurrentToken() { |
| 361 if (token_kind_ == Token::kILLEGAL) { | 361 if (token_kind_ == Token::kILLEGAL) { |
| 362 token_kind_ = tokens_iterator_.CurrentTokenKind(); | 362 token_kind_ = tokens_iterator_.CurrentTokenKind(); |
| 363 if (token_kind_ == Token::kERROR) { | 363 if (token_kind_ == Token::kERROR) { |
| 364 ErrorMsg(TokenPos(), "%s", CurrentLiteral()->ToCString()); | 364 ErrorMsg(TokenPos(), "%s", CurrentLiteral()->ToCString()); |
| 365 } | 365 } |
| (...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 return false; | 730 return false; |
| 731 } else if ((seq->length()) == 1 && | 731 } else if ((seq->length()) == 1 && |
| 732 (seq->NodeAt(seq->length() - 1)->IsSequenceNode())) { | 732 (seq->NodeAt(seq->length() - 1)->IsSequenceNode())) { |
| 733 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); | 733 return HasReturnNode(seq->NodeAt(seq->length() - 1)->AsSequenceNode()); |
| 734 } else { | 734 } else { |
| 735 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); | 735 return seq->NodeAt(seq->length() - 1)->IsReturnNode(); |
| 736 } | 736 } |
| 737 } | 737 } |
| 738 | 738 |
| 739 | 739 |
| 740 void Parser::ParseClass(const Class& cls) { | |
| 741 if (!cls.is_synthesized_class()) { | |
| 742 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | |
| 743 Isolate* isolate = Isolate::Current(); | |
| 744 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | |
| 745 const Script& script = Script::Handle(isolate, cls.script()); | |
| 746 const Library& lib = Library::Handle(isolate, cls.library()); | |
| 747 Parser parser(script, lib, cls.token_pos()); | |
| 748 parser.ParseClassDefinition(cls); | |
| 749 } | |
| 750 } | |
| 751 | |
| 752 | |
| 740 void Parser::ParseFunction(ParsedFunction* parsed_function) { | 753 void Parser::ParseFunction(ParsedFunction* parsed_function) { |
| 741 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); | 754 TimerScope timer(FLAG_compiler_stats, &CompilerStats::parser_timer); |
| 742 Isolate* isolate = Isolate::Current(); | 755 Isolate* isolate = Isolate::Current(); |
| 743 ASSERT(isolate->long_jump_base()->IsSafeToJump()); | 756 ASSERT(isolate->long_jump_base()->IsSafeToJump()); |
| 744 ASSERT(parsed_function != NULL); | 757 ASSERT(parsed_function != NULL); |
| 745 const Function& func = parsed_function->function(); | 758 const Function& func = parsed_function->function(); |
| 746 const Script& script = Script::Handle(isolate, func.script()); | 759 const Script& script = Script::Handle(isolate, func.script()); |
| 747 Parser parser(script, parsed_function, func.token_pos()); | 760 Parser parser(script, parsed_function, func.token_pos()); |
| 748 SequenceNode* node_sequence = NULL; | 761 SequenceNode* node_sequence = NULL; |
| 749 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); | 762 Array& default_parameter_values = Array::ZoneHandle(isolate, Array::null()); |
| (...skipping 1724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2474 if (CurrentToken() == Token::kLPAREN) { | 2487 if (CurrentToken() == Token::kLPAREN) { |
| 2475 level++; | 2488 level++; |
| 2476 } else if (CurrentToken() == Token::kRPAREN) { | 2489 } else if (CurrentToken() == Token::kRPAREN) { |
| 2477 level--; | 2490 level--; |
| 2478 } | 2491 } |
| 2479 ConsumeToken(); | 2492 ConsumeToken(); |
| 2480 } while ((level > 0) && (CurrentToken() != Token::kEOS)); | 2493 } while ((level > 0) && (CurrentToken() != Token::kEOS)); |
| 2481 } | 2494 } |
| 2482 | 2495 |
| 2483 | 2496 |
| 2497 // Skips tokens up to matching closing braces. | |
| 2498 void Parser::SkipToMatchingBraces() { | |
|
hausner
2013/05/21 20:07:30
Parser::SkipBlock() does the same thing and additi
siva
2013/05/23 00:54:31
Thanks for pointing that out, used SkipBlock).
On
| |
| 2499 ASSERT(CurrentToken() == Token::kLBRACE); | |
| 2500 int level = 0; | |
| 2501 do { | |
| 2502 if (CurrentToken() == Token::kLBRACE) { | |
| 2503 level++; | |
| 2504 } else if (CurrentToken() == Token::kRBRACE) { | |
| 2505 level--; | |
| 2506 } | |
| 2507 ConsumeToken(); | |
| 2508 } while ((level > 0) && (CurrentToken() != Token::kEOS)); | |
| 2509 } | |
| 2510 | |
| 2511 | |
| 2484 void Parser::SkipInitializers() { | 2512 void Parser::SkipInitializers() { |
| 2485 ASSERT(CurrentToken() == Token::kCOLON); | 2513 ASSERT(CurrentToken() == Token::kCOLON); |
| 2486 do { | 2514 do { |
| 2487 ConsumeToken(); // Colon or comma. | 2515 ConsumeToken(); // Colon or comma. |
| 2488 if (CurrentToken() == Token::kSUPER) { | 2516 if (CurrentToken() == Token::kSUPER) { |
| 2489 ConsumeToken(); | 2517 ConsumeToken(); |
| 2490 if (CurrentToken() == Token::kPERIOD) { | 2518 if (CurrentToken() == Token::kPERIOD) { |
| 2491 ConsumeToken(); | 2519 ConsumeToken(); |
| 2492 ExpectIdentifier("identifier expected"); | 2520 ExpectIdentifier("identifier expected"); |
| 2493 } | 2521 } |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3194 } | 3222 } |
| 3195 ParseFieldDefinition(members, &member); | 3223 ParseFieldDefinition(members, &member); |
| 3196 } else { | 3224 } else { |
| 3197 UnexpectedToken(); | 3225 UnexpectedToken(); |
| 3198 } | 3226 } |
| 3199 current_member_ = NULL; | 3227 current_member_ = NULL; |
| 3200 members->AddMember(member); | 3228 members->AddMember(member); |
| 3201 } | 3229 } |
| 3202 | 3230 |
| 3203 | 3231 |
| 3204 void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) { | 3232 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes) { |
| 3205 TRACE_PARSER("ParseClassDefinition"); | 3233 TRACE_PARSER("ParseClassDeclaration"); |
| 3206 bool is_patch = false; | 3234 bool is_patch = false; |
| 3207 bool is_abstract = false; | 3235 bool is_abstract = false; |
| 3208 if (is_patch_source() && | 3236 if (is_patch_source() && |
| 3209 (CurrentToken() == Token::kIDENT) && | 3237 (CurrentToken() == Token::kIDENT) && |
| 3210 CurrentLiteral()->Equals("patch")) { | 3238 CurrentLiteral()->Equals("patch")) { |
| 3211 ConsumeToken(); | 3239 ConsumeToken(); |
| 3212 is_patch = true; | 3240 is_patch = true; |
| 3213 } else if (CurrentToken() == Token::kABSTRACT) { | 3241 } else if (CurrentToken() == Token::kABSTRACT) { |
| 3214 is_abstract = true; | 3242 is_abstract = true; |
| 3215 ConsumeToken(); | 3243 ConsumeToken(); |
| 3216 } | 3244 } |
| 3217 const intptr_t class_pos = TokenPos(); | |
| 3218 ExpectToken(Token::kCLASS); | 3245 ExpectToken(Token::kCLASS); |
| 3219 const intptr_t classname_pos = TokenPos(); | 3246 const intptr_t classname_pos = TokenPos(); |
| 3220 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); | 3247 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected"); |
| 3221 if (FLAG_trace_parser) { | 3248 if (FLAG_trace_parser) { |
| 3222 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); | 3249 OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString()); |
| 3223 } | 3250 } |
| 3224 Class& cls = Class::Handle(); | 3251 Class& cls = Class::Handle(); |
| 3225 TypeArguments& orig_type_parameters = TypeArguments::Handle(); | 3252 TypeArguments& orig_type_parameters = TypeArguments::Handle(); |
| 3226 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | 3253 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
| 3227 if (obj.IsNull()) { | 3254 if (obj.IsNull()) { |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 3250 } else { | 3277 } else { |
| 3251 // Not patching a class, but it has been found. This must be one of the | 3278 // Not patching a class, but it has been found. This must be one of the |
| 3252 // pre-registered classes from object.cc or a duplicate definition. | 3279 // pre-registered classes from object.cc or a duplicate definition. |
| 3253 if (!(cls.is_prefinalized() || | 3280 if (!(cls.is_prefinalized() || |
| 3254 RawObject::IsTypedDataViewClassId(cls.id()))) { | 3281 RawObject::IsTypedDataViewClassId(cls.id()))) { |
| 3255 ErrorMsg(classname_pos, "class '%s' is already defined", | 3282 ErrorMsg(classname_pos, "class '%s' is already defined", |
| 3256 class_name.ToCString()); | 3283 class_name.ToCString()); |
| 3257 } | 3284 } |
| 3258 // Pre-registered classes need their scripts connected at this time. | 3285 // Pre-registered classes need their scripts connected at this time. |
| 3259 cls.set_script(script_); | 3286 cls.set_script(script_); |
| 3287 cls.set_token_pos(classname_pos); | |
| 3260 } | 3288 } |
| 3261 } | 3289 } |
| 3262 ASSERT(!cls.IsNull()); | 3290 ASSERT(!cls.IsNull()); |
| 3263 ASSERT(cls.functions() == Object::empty_array().raw()); | 3291 ASSERT(cls.functions() == Object::empty_array().raw()); |
| 3264 set_current_class(cls); | 3292 set_current_class(cls); |
| 3265 ParseTypeParameters(cls); | 3293 ParseTypeParameters(cls); |
| 3266 if (is_patch) { | 3294 if (is_patch) { |
| 3267 // Check that the new type parameters are identical to the original ones. | 3295 // Check that the new type parameters are identical to the original ones. |
| 3268 const TypeArguments& new_type_parameters = | 3296 const TypeArguments& new_type_parameters = |
| 3269 TypeArguments::Handle(cls.type_parameters()); | 3297 TypeArguments::Handle(cls.type_parameters()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3321 // No extends clause: implicitly extend Object. | 3349 // No extends clause: implicitly extend Object. |
| 3322 super_type = Type::ObjectType(); | 3350 super_type = Type::ObjectType(); |
| 3323 } | 3351 } |
| 3324 ASSERT(!super_type.IsNull()); | 3352 ASSERT(!super_type.IsNull()); |
| 3325 cls.set_super_type(super_type); | 3353 cls.set_super_type(super_type); |
| 3326 | 3354 |
| 3327 if (CurrentToken() == Token::kIMPLEMENTS) { | 3355 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3328 ParseInterfaceList(cls); | 3356 ParseInterfaceList(cls); |
| 3329 } | 3357 } |
| 3330 | 3358 |
| 3359 if (is_abstract) { | |
| 3360 cls.set_is_abstract(); | |
| 3361 } | |
| 3362 if (is_patch) { | |
| 3363 // Apply the changes to the patched class looked up above. | |
| 3364 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); | |
| 3365 // The patched class must not be finalized yet. | |
| 3366 const Class& orig_class = Class::Cast(obj); | |
| 3367 ASSERT(!orig_class.is_finalized()); | |
| 3368 orig_class.add_patch_class(cls); | |
| 3369 cls.set_is_patch(); | |
| 3370 } | |
| 3371 pending_classes.Add(cls, Heap::kOld); | |
| 3372 | |
| 3373 if (CurrentToken() != Token::kLBRACE) { | |
| 3374 ErrorMsg("'%s' expected", Token::Str(Token::kLBRACE)); | |
|
hausner
2013/05/21 20:07:30
Is it Rube Goldberg's birthday? ;-)
I think it's g
siva
2013/05/23 00:54:31
Done.
(was just guarding for the time when we dec
| |
| 3375 } | |
| 3376 SkipToMatchingBraces(); | |
|
hausner
2013/05/21 20:07:30
Use SkipBlock instead (and maybe rename the functi
siva
2013/05/23 00:54:31
Done.
| |
| 3377 } | |
| 3378 | |
| 3379 | |
| 3380 void Parser::ParseClassDefinition(const Class& cls) { | |
| 3381 TRACE_PARSER("ParseClassDefinition"); | |
| 3382 set_current_class(cls); | |
| 3383 is_top_level_ = true; | |
| 3384 String& class_name = String::Handle(cls.Name()); | |
| 3385 const intptr_t class_pos = TokenPos(); | |
| 3386 ClassDesc members(cls, class_name, false, class_pos); | |
| 3387 while (CurrentToken() != Token::kLBRACE) { | |
| 3388 ConsumeToken(); | |
| 3389 } | |
| 3331 ExpectToken(Token::kLBRACE); | 3390 ExpectToken(Token::kLBRACE); |
| 3332 ClassDesc members(cls, class_name, false, class_pos); | |
| 3333 while (CurrentToken() != Token::kRBRACE) { | 3391 while (CurrentToken() != Token::kRBRACE) { |
| 3334 SkipMetadata(); | 3392 SkipMetadata(); |
| 3335 ParseClassMemberDefinition(&members); | 3393 ParseClassMemberDefinition(&members); |
| 3336 } | 3394 } |
| 3337 ExpectToken(Token::kRBRACE); | 3395 ExpectToken(Token::kRBRACE); |
| 3338 | 3396 |
| 3339 if (is_abstract) { | |
| 3340 cls.set_is_abstract(); | |
| 3341 } | |
| 3342 | |
| 3343 CheckConstructors(&members); | 3397 CheckConstructors(&members); |
| 3344 | 3398 |
| 3345 // Need to compute this here since MakeArray() will clear the | 3399 // Need to compute this here since MakeArray() will clear the |
| 3346 // functions array in members. | 3400 // functions array in members. |
| 3347 const bool need_implicit_constructor = | 3401 const bool need_implicit_constructor = |
| 3348 !members.has_constructor() && !is_patch; | 3402 !members.has_constructor() && !cls.is_patch(); |
| 3349 | 3403 |
| 3350 Array& array = Array::Handle(); | 3404 Array& array = Array::Handle(); |
| 3351 array = Array::MakeArray(members.fields()); | 3405 array = Array::MakeArray(members.fields()); |
| 3352 cls.SetFields(array); | 3406 cls.SetFields(array); |
| 3353 | 3407 |
| 3354 // Creating a new array for functions marks the class as parsed. | 3408 // Creating a new array for functions marks the class as parsed. |
| 3355 array = Array::MakeArray(members.functions()); | 3409 array = Array::MakeArray(members.functions()); |
| 3356 cls.SetFunctions(array); | 3410 cls.SetFunctions(array); |
| 3357 | 3411 |
| 3358 // Add an implicit constructor if no explicit constructor is present. | 3412 // Add an implicit constructor if no explicit constructor is present. |
| 3359 // No implicit constructors are needed for patch classes. | 3413 // No implicit constructors are needed for patch classes. |
| 3360 if (need_implicit_constructor) { | 3414 if (need_implicit_constructor) { |
| 3361 AddImplicitConstructor(cls); | 3415 AddImplicitConstructor(cls); |
| 3362 } | 3416 } |
| 3363 | 3417 |
| 3364 if (!is_patch) { | 3418 if (cls.is_patch()) { |
| 3365 pending_classes.Add(cls, Heap::kOld); | |
| 3366 } else { | |
| 3367 // Apply the changes to the patched class looked up above. | 3419 // Apply the changes to the patched class looked up above. |
| 3368 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); | 3420 Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
| 3369 // The patched class must not be finalized yet. | 3421 // The patched class must not be finalized yet. |
| 3370 ASSERT(!Class::Cast(obj).is_finalized()); | 3422 const Class& orig_class = Class::Cast(obj); |
| 3371 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); | 3423 ASSERT(!orig_class.is_finalized()); |
| 3424 const char* err_msg = orig_class.ApplyPatch(cls); | |
| 3372 if (err_msg != NULL) { | 3425 if (err_msg != NULL) { |
| 3373 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); | 3426 ErrorMsg(class_pos, "applying patch failed with '%s'", err_msg); |
| 3374 } | 3427 } |
| 3375 } | 3428 } |
| 3376 } | 3429 } |
| 3377 | 3430 |
| 3378 | 3431 |
| 3379 // Add an implicit constructor to the given class. | 3432 // Add an implicit constructor to the given class. |
| 3380 void Parser::AddImplicitConstructor(const Class& cls) { | 3433 void Parser::AddImplicitConstructor(const Class& cls) { |
| 3381 // The implicit constructor is unnamed, has no explicit parameter. | 3434 // The implicit constructor is unnamed, has no explicit parameter. |
| 3382 String& ctor_name = String::ZoneHandle(cls.Name()); | 3435 String& ctor_name = String::ZoneHandle(cls.Name()); |
| 3383 ctor_name = String::Concat(ctor_name, Symbols::Dot()); | 3436 ctor_name = String::Concat(ctor_name, Symbols::Dot()); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3488 } | 3541 } |
| 3489 | 3542 |
| 3490 if (CurrentToken() != Token::kWITH) { | 3543 if (CurrentToken() != Token::kWITH) { |
| 3491 ErrorMsg("mixin application 'with Type' expected"); | 3544 ErrorMsg("mixin application 'with Type' expected"); |
| 3492 } | 3545 } |
| 3493 type = ParseMixins(type); | 3546 type = ParseMixins(type); |
| 3494 | 3547 |
| 3495 // TODO(hausner): treat the mixin application as an alias, not as a base | 3548 // TODO(hausner): treat the mixin application as an alias, not as a base |
| 3496 // class whose super class is the mixin application! | 3549 // class whose super class is the mixin application! |
| 3497 mixin_application.set_super_type(type); | 3550 mixin_application.set_super_type(type); |
| 3551 mixin_application.set_is_synthesized_class(); | |
| 3498 | 3552 |
| 3499 AddImplicitConstructor(mixin_application); | 3553 AddImplicitConstructor(mixin_application); |
| 3500 if (CurrentToken() == Token::kIMPLEMENTS) { | 3554 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3501 ParseInterfaceList(mixin_application); | 3555 ParseInterfaceList(mixin_application); |
| 3502 } | 3556 } |
| 3503 ExpectSemicolon(); | 3557 ExpectSemicolon(); |
| 3504 pending_classes.Add(mixin_application, Heap::kOld); | 3558 pending_classes.Add(mixin_application, Heap::kOld); |
| 3505 } | 3559 } |
| 3506 | 3560 |
| 3507 | 3561 |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3896 mixin_app_name = mixin_super_type.ClassName(); | 3950 mixin_app_name = mixin_super_type.ClassName(); |
| 3897 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand()); | 3951 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand()); |
| 3898 mixin_app_name = String::Concat(mixin_app_name, | 3952 mixin_app_name = String::Concat(mixin_app_name, |
| 3899 String::Handle(mixin_type.ClassName())); | 3953 String::Handle(mixin_type.ClassName())); |
| 3900 mixin_app_name = Symbols::New(mixin_app_name); | 3954 mixin_app_name = Symbols::New(mixin_app_name); |
| 3901 | 3955 |
| 3902 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); | 3956 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); |
| 3903 mixin_application.set_super_type(mixin_super_type); | 3957 mixin_application.set_super_type(mixin_super_type); |
| 3904 mixin_application.set_mixin(Type::Cast(mixin_type)); | 3958 mixin_application.set_mixin(Type::Cast(mixin_type)); |
| 3905 mixin_application.set_library(library_); | 3959 mixin_application.set_library(library_); |
| 3960 mixin_application.set_is_synthesized_class(); | |
| 3906 AddImplicitConstructor(mixin_application); | 3961 AddImplicitConstructor(mixin_application); |
| 3907 // Add the mixin type to the interfaces that the mixin application | 3962 // Add the mixin type to the interfaces that the mixin application |
| 3908 // class implements. This is necessary so that type tests work. | 3963 // class implements. This is necessary so that type tests work. |
| 3909 mixin_application_interfaces = Array::New(1); | 3964 mixin_application_interfaces = Array::New(1); |
| 3910 mixin_application_interfaces.SetAt(0, mixin_type); | 3965 mixin_application_interfaces.SetAt(0, mixin_type); |
| 3911 mixin_application.set_interfaces(mixin_application_interfaces); | 3966 mixin_application.set_interfaces(mixin_application_interfaces); |
| 3912 | 3967 |
| 3913 // For the type arguments of the mixin application type, we need | 3968 // For the type arguments of the mixin application type, we need |
| 3914 // a copy of the type arguments to the mixin type. The simplest way | 3969 // a copy of the type arguments to the mixin type. The simplest way |
| 3915 // to get the copy is to rewind the parser, parse the mixin type | 3970 // to get the copy is to rewind the parser, parse the mixin type |
| (...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4480 if (is_library_source() || is_patch_source()) { | 4535 if (is_library_source() || is_patch_source()) { |
| 4481 ParseLibraryDefinition(); | 4536 ParseLibraryDefinition(); |
| 4482 } else if (is_part_source()) { | 4537 } else if (is_part_source()) { |
| 4483 ParsePartHeader(); | 4538 ParsePartHeader(); |
| 4484 } | 4539 } |
| 4485 | 4540 |
| 4486 while (true) { | 4541 while (true) { |
| 4487 set_current_class(Class::Handle()); // No current class. | 4542 set_current_class(Class::Handle()); // No current class. |
| 4488 SkipMetadata(); | 4543 SkipMetadata(); |
| 4489 if (CurrentToken() == Token::kCLASS) { | 4544 if (CurrentToken() == Token::kCLASS) { |
| 4490 ParseClassDefinition(pending_classes); | 4545 ParseClassDeclaration(pending_classes); |
| 4491 } else if ((CurrentToken() == Token::kTYPEDEF) && | 4546 } else if ((CurrentToken() == Token::kTYPEDEF) && |
| 4492 (LookaheadToken(1) != Token::kLPAREN)) { | 4547 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4493 set_current_class(toplevel_class); | 4548 set_current_class(toplevel_class); |
| 4494 ParseTypedef(pending_classes); | 4549 ParseTypedef(pending_classes); |
| 4495 } else if ((CurrentToken() == Token::kABSTRACT) && | 4550 } else if ((CurrentToken() == Token::kABSTRACT) && |
| 4496 (LookaheadToken(1) == Token::kCLASS)) { | 4551 (LookaheadToken(1) == Token::kCLASS)) { |
| 4497 ParseClassDefinition(pending_classes); | 4552 ParseClassDeclaration(pending_classes); |
| 4498 } else if (is_patch_source() && IsLiteral("patch") && | 4553 } else if (is_patch_source() && IsLiteral("patch") && |
| 4499 (LookaheadToken(1) == Token::kCLASS)) { | 4554 (LookaheadToken(1) == Token::kCLASS)) { |
| 4500 ParseClassDefinition(pending_classes); | 4555 ParseClassDeclaration(pending_classes); |
| 4501 } else { | 4556 } else { |
| 4502 set_current_class(toplevel_class); | 4557 set_current_class(toplevel_class); |
| 4503 if (IsVariableDeclaration()) { | 4558 if (IsVariableDeclaration()) { |
| 4504 ParseTopLevelVariable(&top_level); | 4559 ParseTopLevelVariable(&top_level); |
| 4505 } else if (IsFunctionDeclaration()) { | 4560 } else if (IsFunctionDeclaration()) { |
| 4506 ParseTopLevelFunction(&top_level); | 4561 ParseTopLevelFunction(&top_level); |
| 4507 } else if (IsTopLevelAccessor()) { | 4562 } else if (IsTopLevelAccessor()) { |
| 4508 ParseTopLevelAccessor(&top_level); | 4563 ParseTopLevelAccessor(&top_level); |
| 4509 } else if (CurrentToken() == Token::kEOS) { | 4564 } else if (CurrentToken() == Token::kEOS) { |
| 4510 break; | 4565 break; |
| 4511 } else { | 4566 } else { |
| 4512 UnexpectedToken(); | 4567 UnexpectedToken(); |
| 4513 } | 4568 } |
| 4514 } | 4569 } |
| 4515 } | 4570 } |
| 4571 toplevel_class.set_is_parsed(); | |
| 4516 if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) { | 4572 if ((top_level.fields.Length() > 0) || (top_level.functions.Length() > 0)) { |
| 4517 Array& array = Array::Handle(); | 4573 Array& array = Array::Handle(); |
| 4518 | 4574 |
| 4519 array = Array::MakeArray(top_level.fields); | 4575 array = Array::MakeArray(top_level.fields); |
| 4520 toplevel_class.SetFields(array); | 4576 toplevel_class.SetFields(array); |
| 4521 | 4577 |
| 4522 array = Array::MakeArray(top_level.functions); | 4578 array = Array::MakeArray(top_level.functions); |
| 4523 toplevel_class.SetFunctions(array); | 4579 toplevel_class.SetFunctions(array); |
| 4524 | 4580 |
| 4525 library_.AddAnonymousClass(toplevel_class); | 4581 library_.AddAnonymousClass(toplevel_class); |
| (...skipping 3490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8016 | 8072 |
| 8017 | 8073 |
| 8018 const Type* Parser::ReceiverType(intptr_t type_pos) const { | 8074 const Type* Parser::ReceiverType(intptr_t type_pos) const { |
| 8019 ASSERT(!current_class().IsNull()); | 8075 ASSERT(!current_class().IsNull()); |
| 8020 TypeArguments& type_arguments = TypeArguments::Handle(); | 8076 TypeArguments& type_arguments = TypeArguments::Handle(); |
| 8021 if (current_class().NumTypeParameters() > 0) { | 8077 if (current_class().NumTypeParameters() > 0) { |
| 8022 type_arguments = current_class().type_parameters(); | 8078 type_arguments = current_class().type_parameters(); |
| 8023 } | 8079 } |
| 8024 Type& type = Type::ZoneHandle( | 8080 Type& type = Type::ZoneHandle( |
| 8025 Type::New(current_class(), type_arguments, type_pos)); | 8081 Type::New(current_class(), type_arguments, type_pos)); |
| 8026 if (!is_top_level_) { | 8082 if (!is_top_level_ || current_class().is_type_finalized()) { |
| 8027 type ^= ClassFinalizer::FinalizeType( | 8083 type ^= ClassFinalizer::FinalizeType( |
| 8028 current_class(), type, ClassFinalizer::kCanonicalizeWellFormed); | 8084 current_class(), type, ClassFinalizer::kCanonicalizeWellFormed); |
| 8029 } | 8085 } |
| 8030 return &type; | 8086 return &type; |
| 8031 } | 8087 } |
| 8032 | 8088 |
| 8033 | 8089 |
| 8034 bool Parser::IsInstantiatorRequired() const { | 8090 bool Parser::IsInstantiatorRequired() const { |
| 8035 ASSERT(!current_function().IsNull()); | 8091 ASSERT(!current_function().IsNull()); |
| 8036 if (current_function().is_static() && | 8092 if (current_function().is_static() && |
| (...skipping 1918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9955 void Parser::SkipQualIdent() { | 10011 void Parser::SkipQualIdent() { |
| 9956 ASSERT(IsIdentifier()); | 10012 ASSERT(IsIdentifier()); |
| 9957 ConsumeToken(); | 10013 ConsumeToken(); |
| 9958 if (CurrentToken() == Token::kPERIOD) { | 10014 if (CurrentToken() == Token::kPERIOD) { |
| 9959 ConsumeToken(); // Consume the kPERIOD token. | 10015 ConsumeToken(); // Consume the kPERIOD token. |
| 9960 ExpectIdentifier("identifier expected after '.'"); | 10016 ExpectIdentifier("identifier expected after '.'"); |
| 9961 } | 10017 } |
| 9962 } | 10018 } |
| 9963 | 10019 |
| 9964 } // namespace dart | 10020 } // namespace dart |
| OLD | NEW |