Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(595)

Side by Side Diff: runtime/vm/parser.cc

Issue 14820028: Delay Class parsing until the class is actually used. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698