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

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

Issue 12210127: First stab at mixins in VM compiler (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 10 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
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/class_finalizer.h" 8 #include "vm/class_finalizer.h"
9 #include "vm/compiler.h" 9 #include "vm/compiler.h"
10 #include "vm/compiler_stats.h" 10 #include "vm/compiler_stats.h"
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 : script_(script), 284 : script_(script),
285 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), 285 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position),
286 token_kind_(Token::kILLEGAL), 286 token_kind_(Token::kILLEGAL),
287 current_block_(NULL), 287 current_block_(NULL),
288 is_top_level_(false), 288 is_top_level_(false),
289 current_member_(NULL), 289 current_member_(NULL),
290 allow_function_literals_(true), 290 allow_function_literals_(true),
291 parsed_function_(parsed_function), 291 parsed_function_(parsed_function),
292 innermost_function_(Function::Handle(parsed_function->function().raw())), 292 innermost_function_(Function::Handle(parsed_function->function().raw())),
293 current_class_(Class::Handle(parsed_function->function().Owner())), 293 current_class_(Class::Handle(parsed_function->function().Owner())),
294 library_(Library::Handle(current_class_.library())), 294 library_(Library::Handle(Class::Handle(
295 parsed_function->function().origin()).library())),
295 try_blocks_list_(NULL) { 296 try_blocks_list_(NULL) {
296 ASSERT(tokens_iterator_.IsValid()); 297 ASSERT(tokens_iterator_.IsValid());
297 ASSERT(!current_function().IsNull()); 298 ASSERT(!current_function().IsNull());
298 if (FLAG_enable_type_checks) { 299 if (FLAG_enable_type_checks) {
299 EnsureExpressionTemp(); 300 EnsureExpressionTemp();
300 } 301 }
301 } 302 }
302 303
303 304
304 bool Parser::SetAllowFunctionLiterals(bool value) { 305 bool Parser::SetAllowFunctionLiterals(bool value) {
(...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after
1834 if (!f.is_static() && f.has_initializer()) { 1835 if (!f.is_static() && f.has_initializer()) {
1835 Field& field = Field::ZoneHandle(); 1836 Field& field = Field::ZoneHandle();
1836 field ^= fields.At(i); 1837 field ^= fields.At(i);
1837 if (field.is_final()) { 1838 if (field.is_final()) {
1838 // Final fields with initializer expression may not be initialized 1839 // Final fields with initializer expression may not be initialized
1839 // again by constructors. Remember that this field is already 1840 // again by constructors. Remember that this field is already
1840 // initialized. 1841 // initialized.
1841 initialized_fields->Add(&field); 1842 initialized_fields->Add(&field);
1842 } 1843 }
1843 intptr_t field_pos = field.token_pos(); 1844 intptr_t field_pos = field.token_pos();
1845 if (current_class().raw() != field.origin()) {
1846 const Class& origin_class = Class::Handle(field.origin());
1847 if (origin_class.library() != library_.raw()) {
1848 ErrorMsg("Cannot handle initialized mixin field '%s'"
1849 "from imported library\n", field.ToCString());
1850 }
1851 }
1844 SetPosition(field_pos); 1852 SetPosition(field_pos);
1845 ASSERT(IsIdentifier()); 1853 ASSERT(IsIdentifier());
1846 ConsumeToken(); 1854 ConsumeToken();
1847 ExpectToken(Token::kASSIGN); 1855 ExpectToken(Token::kASSIGN);
1848 1856
1849 AstNode* init_expr = NULL; 1857 AstNode* init_expr = NULL;
1850 if (field.is_const()) { 1858 if (field.is_const()) {
1851 init_expr = ParseConstExpr(); 1859 init_expr = ParseConstExpr();
1852 } else { 1860 } else {
1853 init_expr = ParseExpr(kAllowConst, kConsumeCascades); 1861 init_expr = ParseExpr(kAllowConst, kConsumeCascades);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2026 SequenceNode* Parser::ParseConstructor(const Function& func, 2034 SequenceNode* Parser::ParseConstructor(const Function& func,
2027 Array& default_parameter_values) { 2035 Array& default_parameter_values) {
2028 TRACE_PARSER("ParseConstructor"); 2036 TRACE_PARSER("ParseConstructor");
2029 ASSERT(func.IsConstructor()); 2037 ASSERT(func.IsConstructor());
2030 ASSERT(!func.IsFactory()); 2038 ASSERT(!func.IsFactory());
2031 ASSERT(!func.is_static()); 2039 ASSERT(!func.is_static());
2032 ASSERT(!func.IsLocalFunction()); 2040 ASSERT(!func.IsLocalFunction());
2033 const Class& cls = Class::Handle(func.Owner()); 2041 const Class& cls = Class::Handle(func.Owner());
2034 ASSERT(!cls.IsNull()); 2042 ASSERT(!cls.IsNull());
2035 2043
2036 if (CurrentToken() == Token::kCLASS) { 2044 if (func.IsImplicitConstructor()) {
2037 // Special case: implicit constructor. 2045 // Special case: implicit constructor.
2038 // The parser adds an implicit default constructor when a class 2046 // The parser adds an implicit default constructor when a class
2039 // does not have any explicit constructor or factory (see 2047 // does not have any explicit constructor or factory (see
2040 // Parser::AddImplicitConstructor). The token position of this implicit 2048 // Parser::AddImplicitConstructor).
2041 // constructor points to the 'class' keyword, which is followed
2042 // by the name of the class (which is also the constructor name).
2043 // There is no source text to parse. We just build the 2049 // There is no source text to parse. We just build the
2044 // sequence node by hand. 2050 // sequence node by hand.
2045 return MakeImplicitConstructor(func); 2051 return MakeImplicitConstructor(func);
2046 } 2052 }
2047 2053
2048 OpenFunctionBlock(func); 2054 OpenFunctionBlock(func);
2049 ParamList params; 2055 ParamList params;
2050 const bool allow_explicit_default_values = true; 2056 const bool allow_explicit_default_values = true;
2051 ASSERT(CurrentToken() == Token::kLPAREN); 2057 ASSERT(CurrentToken() == Token::kLPAREN);
2052 2058
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after
3237 const intptr_t type_pos = TokenPos(); 3243 const intptr_t type_pos = TokenPos();
3238 const AbstractType& type = AbstractType::Handle( 3244 const AbstractType& type = AbstractType::Handle(
3239 ParseType(ClassFinalizer::kTryResolve)); 3245 ParseType(ClassFinalizer::kTryResolve));
3240 if (type.IsTypeParameter()) { 3246 if (type.IsTypeParameter()) {
3241 ErrorMsg(type_pos, 3247 ErrorMsg(type_pos,
3242 "class '%s' may not extend type parameter '%s'", 3248 "class '%s' may not extend type parameter '%s'",
3243 class_name.ToCString(), 3249 class_name.ToCString(),
3244 String::Handle(type.UserVisibleName()).ToCString()); 3250 String::Handle(type.UserVisibleName()).ToCString());
3245 } 3251 }
3246 super_type ^= type.raw(); 3252 super_type ^= type.raw();
3253 if (CurrentToken() == Token::kWITH) {
3254 super_type = ParseMixins(super_type);
3255 }
3247 } else { 3256 } else {
3248 // No extends clause: Implicitly extend Object. 3257 // No extends clause: implicitly extend Object.
3249 super_type = Type::ObjectType(); 3258 super_type = Type::ObjectType();
3250 } 3259 }
3251 ASSERT(!super_type.IsNull()); 3260 ASSERT(!super_type.IsNull());
3252 cls.set_super_type(super_type); 3261 cls.set_super_type(super_type);
3253 3262
3254 if (CurrentToken() == Token::kIMPLEMENTS) { 3263 if (CurrentToken() == Token::kIMPLEMENTS) {
3255 Array& interfaces = Array::Handle(); 3264 Array& interfaces = Array::Handle();
3256 const intptr_t interfaces_pos = TokenPos(); 3265 const intptr_t interfaces_pos = TokenPos();
3257 interfaces = ParseInterfaceList(super_type); 3266 interfaces = ParseInterfaceList(super_type);
3258 AddInterfaces(interfaces_pos, cls, interfaces); 3267 AddInterfaces(interfaces_pos, cls, interfaces);
3259 } 3268 }
3260 3269
3261 ExpectToken(Token::kLBRACE); 3270 ExpectToken(Token::kLBRACE);
3262 ClassDesc members(cls, class_name, false, class_pos); 3271 ClassDesc members(cls, class_name, false, class_pos);
3263 while (CurrentToken() != Token::kRBRACE) { 3272 while (CurrentToken() != Token::kRBRACE) {
3264 SkipMetadata(); 3273 SkipMetadata();
3265 ParseClassMemberDefinition(&members); 3274 ParseClassMemberDefinition(&members);
3266 } 3275 }
3267 ExpectToken(Token::kRBRACE); 3276 ExpectToken(Token::kRBRACE);
3268 3277
3269 if (is_abstract) { 3278 if (is_abstract) {
3270 cls.set_is_abstract(); 3279 cls.set_is_abstract();
3271 } 3280 }
3272 3281
3273 // Add an implicit constructor if no explicit constructor is present. No
3274 // implicit constructors are needed for patch classes.
3275 if (!members.has_constructor() && !is_patch) {
3276 AddImplicitConstructor(&members);
3277 }
3278 CheckConstructors(&members); 3282 CheckConstructors(&members);
3279 3283
3284 // Need to compute this here since MakeArray() will clear the
3285 // functions array in members.
3286 const bool need_implicit_constructor =
3287 !members.has_constructor() && !is_patch;
3288
3280 Array& array = Array::Handle(); 3289 Array& array = Array::Handle();
3281 array = Array::MakeArray(members.fields()); 3290 array = Array::MakeArray(members.fields());
3282 cls.SetFields(array); 3291 cls.SetFields(array);
3283 3292
3284 // Creating a new array for functions marks the class as parsed. 3293 // Creating a new array for functions marks the class as parsed.
3285 array = Array::MakeArray(members.functions()); 3294 array = Array::MakeArray(members.functions());
3286 cls.SetFunctions(array); 3295 cls.SetFunctions(array);
3287 3296
3297 // Add an implicit constructor if no explicit constructor is present.
3298 // No implicit constructors are needed for patch classes.
3299 if (need_implicit_constructor) {
3300 AddImplicitConstructor(cls);
3301 }
3302
3288 if (!is_patch) { 3303 if (!is_patch) {
3289 pending_classes.Add(cls, Heap::kOld); 3304 pending_classes.Add(cls, Heap::kOld);
3290 } else { 3305 } else {
3291 // Apply the changes to the patched class looked up above. 3306 // Apply the changes to the patched class looked up above.
3292 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); 3307 ASSERT(obj.raw() == library_.LookupLocalObject(class_name));
3293 // The patched class must not be finalized yet. 3308 // The patched class must not be finalized yet.
3294 ASSERT(!Class::Cast(obj).is_finalized()); 3309 ASSERT(!Class::Cast(obj).is_finalized());
3295 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); 3310 const char* err_msg = Class::Cast(obj).ApplyPatch(cls);
3296 if (err_msg != NULL) { 3311 if (err_msg != NULL) {
3297 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); 3312 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg);
3298 } 3313 }
3299 } 3314 }
3300 } 3315 }
3301 3316
3302 3317
3303 // Add an implicit constructor if no explicit constructor is present. 3318 // Add an implicit constructor to the given class.
3304 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { 3319 void Parser::AddImplicitConstructor(const Class& cls) {
3305 // The implicit constructor is unnamed, has no explicit parameter, 3320 // The implicit constructor is unnamed, has no explicit parameter.
3306 // and contains a supercall in the initializer list. 3321 String& ctor_name = String::ZoneHandle(cls.Name());
3307 String& ctor_name = String::ZoneHandle( 3322 ctor_name = String::Concat(ctor_name, Symbols::Dot());
3308 String::Concat(class_desc->class_name(), Symbols::Dot()));
3309 ctor_name = Symbols::New(ctor_name); 3323 ctor_name = Symbols::New(ctor_name);
3310 // The token position for the implicit constructor is the 'class' 3324 // To indicate that this is an implicit constructor, we set the
3311 // keyword of the constructor's class. 3325 // token position is the same as the token position of the class.
3312 Function& ctor = Function::Handle( 3326 Function& ctor = Function::Handle(
3313 Function::New(ctor_name, 3327 Function::New(ctor_name,
3314 RawFunction::kConstructor, 3328 RawFunction::kConstructor,
3315 /* is_static = */ false, 3329 /* is_static = */ false,
3316 /* is_const = */ false, 3330 /* is_const = */ false,
3317 /* is_abstract = */ false, 3331 /* is_abstract = */ false,
3318 /* is_external = */ false, 3332 /* is_external = */ false,
3319 current_class(), 3333 cls,
3320 class_desc->token_pos())); 3334 cls.token_pos()));
3321 ParamList params; 3335 ParamList params;
3322 // Add implicit 'this' parameter. 3336 // Add implicit 'this' parameter. We don't care about the specific type
3323 ASSERT(current_class().raw() == ctor.Owner()); 3337 // and just specify dynamic.
3324 params.AddReceiver(ReceiverType(TokenPos())); 3338 const Type& receiver_type = Type::Handle(Type::DynamicType());
3339 params.AddReceiver(&receiver_type);
3325 // Add implicit parameter for construction phase. 3340 // Add implicit parameter for construction phase.
3326 params.AddFinalParameter(TokenPos(), 3341 params.AddFinalParameter(cls.token_pos(),
3327 &Symbols::PhaseParameter(), 3342 &Symbols::PhaseParameter(),
3328 &Type::ZoneHandle(Type::SmiType())); 3343 &Type::ZoneHandle(Type::SmiType()));
3329 3344
3330 AddFormalParamsToFunction(&params, ctor); 3345 AddFormalParamsToFunction(&params, ctor);
3331 // The body of the constructor cannot modify the type of the constructed 3346 // The body of the constructor cannot modify the type of the constructed
3332 // instance, which is passed in as the receiver. 3347 // instance, which is passed in as the receiver.
3333 ctor.set_result_type(*((*params.parameters)[0].type)); 3348 ctor.set_result_type(receiver_type);
3334 class_desc->AddFunction(ctor); 3349 cls.AddFunction(ctor);
3335 } 3350 }
3336 3351
3337 3352
3338 // Check for cycles in constructor redirection. Also check whether a 3353 // Check for cycles in constructor redirection. Also check whether a
3339 // named constructor collides with the name of another class member. 3354 // named constructor collides with the name of another class member.
3340 void Parser::CheckConstructors(ClassDesc* class_desc) { 3355 void Parser::CheckConstructors(ClassDesc* class_desc) {
3341 // Check for cycles in constructor redirection. 3356 // Check for cycles in constructor redirection.
3342 const GrowableArray<MemberDesc>& members = class_desc->members(); 3357 const GrowableArray<MemberDesc>& members = class_desc->members();
3343 for (int i = 0; i < members.length(); i++) { 3358 for (int i = 0; i < members.length(); i++) {
3344 MemberDesc* member = &members[i]; 3359 MemberDesc* member = &members[i];
(...skipping 24 matching lines...) Expand all
3369 // which the current one redirects, we ignore the unresolved 3384 // which the current one redirects, we ignore the unresolved
3370 // reference. We'll catch it later when the constructor gets 3385 // reference. We'll catch it later when the constructor gets
3371 // compiled. 3386 // compiled.
3372 ctors.Add(member); 3387 ctors.Add(member);
3373 member = class_desc->LookupMember(*member->redirect_name); 3388 member = class_desc->LookupMember(*member->redirect_name);
3374 } 3389 }
3375 } 3390 }
3376 } 3391 }
3377 3392
3378 3393
3394 void Parser::ParseMixinTypedef(const GrowableObjectArray& pending_classes) {
3395 TRACE_PARSER("ParseMixinTypedef");
3396 const intptr_t classname_pos = TokenPos();
3397 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected");
3398 if (FLAG_trace_parser) {
3399 OS::Print("toplevel parsing typedef class '%s'\n", class_name.ToCString());
3400 }
3401 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name));
3402 if (!obj.IsNull()) {
3403 ErrorMsg(classname_pos, "'%s' is already defined",
3404 class_name.ToCString());
3405 }
3406 const Class& mixin_application =
3407 Class::Handle(Class::New(class_name, script_, classname_pos));
3408 library_.AddClass(mixin_application);
3409 set_current_class(mixin_application);
3410 ParseTypeParameters(mixin_application);
3411 ExpectToken(Token::kASSIGN);
3412
3413 if (CurrentToken() == Token::kABSTRACT) {
3414 mixin_application.set_is_abstract();
3415 ConsumeToken();
3416 }
3417
3418 const intptr_t supertype_pos = TokenPos();
3419 const AbstractType& type =
3420 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve));
3421 if (type.IsTypeParameter()) {
3422 ErrorMsg(supertype_pos,
3423 "class '%s' may not extend type parameter '%s'",
3424 class_name.ToCString(),
3425 String::Handle(type.UserVisibleName()).ToCString());
3426 }
3427 Type& mixin_super_type = Type::Handle();
3428 mixin_super_type ^= type.raw();
3429
3430 if (CurrentToken() != Token::kWITH) {
3431 ErrorMsg("mixin application 'with Type' expected");
3432 }
3433
3434 Type& mixin_application_type = Type::Handle(ParseMixins(mixin_super_type));
3435 // The result of ParseMixins() is a chain of super classes that is the
3436 // result of the mixin composition 'S with M1, M2, ...'. The mixin
3437 // application classes are anonymous (i.e. not registered in the current
3438 // library). We steal the super type and mixin type from the bottom of
3439 // the chain and add it to the named mixin application class. The bottom
3440 // anonymous class in the chain is thrown away.
3441 const Class& anon_mixin_app_class =
3442 Class::Handle(mixin_application_type.type_class());
3443 mixin_application.set_super_type(
3444 Type::Handle(anon_mixin_app_class.super_type()));
3445 mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin()));
3446 const Array& interfaces = Array::Handle(anon_mixin_app_class.interfaces());
3447 mixin_application.set_interfaces(interfaces);
3448 AddImplicitConstructor(mixin_application);
3449
3450 if (CurrentToken() == Token::kIMPLEMENTS) {
3451 Array& interfaces = Array::Handle();
3452 const intptr_t interfaces_pos = TokenPos();
3453 const Type& super_type = Type::Handle(mixin_application.super_type());
3454 interfaces = ParseInterfaceList(super_type);
3455 AddInterfaces(interfaces_pos, mixin_application, interfaces);
3456 }
3457
3458 pending_classes.Add(mixin_application, Heap::kOld);
3459 ExpectSemicolon();
3460 }
3461
3462
3379 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". 3463 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(".
3380 // We need this lookahead to distinguish between the optional return type 3464 // We need this lookahead to distinguish between the optional return type
3381 // and the alias name of a function type alias. 3465 // and the alias name of a function type alias.
3382 // Token position remains unchanged. 3466 // Token position remains unchanged.
3383 bool Parser::IsFunctionTypeAliasName() { 3467 bool Parser::IsFunctionTypeAliasName() {
3384 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { 3468 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
3385 return true; 3469 return true;
3386 } 3470 }
3387 const intptr_t saved_pos = TokenPos(); 3471 const intptr_t saved_pos = TokenPos();
3388 bool is_alias_name = false; 3472 bool is_alias_name = false;
3389 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { 3473 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
3390 ConsumeToken(); 3474 ConsumeToken();
3391 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { 3475 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) {
3392 is_alias_name = true; 3476 is_alias_name = true;
3393 } 3477 }
3394 } 3478 }
3395 SetPosition(saved_pos); 3479 SetPosition(saved_pos);
3396 return is_alias_name; 3480 return is_alias_name;
3397 } 3481 }
3398 3482
3399 3483
3400 void Parser::ParseFunctionTypeAlias( 3484 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=".
3401 const GrowableObjectArray& pending_classes) { 3485 // Token position remains unchanged.
3402 TRACE_PARSER("ParseFunctionTypeAlias"); 3486 bool Parser::IsMixinTypedef() {
3487 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) {
3488 return true;
3489 }
3490 const intptr_t saved_pos = TokenPos();
3491 bool is_mixin_def = false;
3492 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
3493 ConsumeToken();
3494 if (TryParseTypeParameter() && (CurrentToken() == Token::kASSIGN)) {
3495 is_mixin_def = true;
3496 }
3497 }
3498 SetPosition(saved_pos);
3499 return is_mixin_def;
3500 }
3501
3502
3503 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes) {
3504 TRACE_PARSER("ParseTypedef");
3403 ExpectToken(Token::kTYPEDEF); 3505 ExpectToken(Token::kTYPEDEF);
3404 3506
3507 if (IsMixinTypedef()) {
3508 ParseMixinTypedef(pending_classes);
3509 return;
3510 }
3511
3405 // Parse the result type of the function type. 3512 // Parse the result type of the function type.
3406 AbstractType& result_type = Type::Handle(Type::DynamicType()); 3513 AbstractType& result_type = Type::Handle(Type::DynamicType());
3407 if (CurrentToken() == Token::kVOID) { 3514 if (CurrentToken() == Token::kVOID) {
3408 ConsumeToken(); 3515 ConsumeToken();
3409 result_type = Type::VoidType(); 3516 result_type = Type::VoidType();
3410 } else if (!IsFunctionTypeAliasName()) { 3517 } else if (!IsFunctionTypeAliasName()) {
3411 // Type annotations in typedef are never ignored, even in unchecked mode. 3518 // Type annotations in typedef are never ignored, even in unchecked mode.
3412 // Wait until we have an owner class before resolving the result type. 3519 // Wait until we have an owner class before resolving the result type.
3413 result_type = ParseType(ClassFinalizer::kDoNotResolve); 3520 result_type = ParseType(ClassFinalizer::kDoNotResolve);
3414 } 3521 }
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
3676 return NewTypeArguments(types); 3783 return NewTypeArguments(types);
3677 } 3784 }
3678 } 3785 }
3679 return TypeArguments::null(); 3786 return TypeArguments::null();
3680 } 3787 }
3681 3788
3682 3789
3683 // Parse and return an array of interface types. 3790 // Parse and return an array of interface types.
3684 RawArray* Parser::ParseInterfaceList(const Type& super_type) { 3791 RawArray* Parser::ParseInterfaceList(const Type& super_type) {
3685 TRACE_PARSER("ParseInterfaceList"); 3792 TRACE_PARSER("ParseInterfaceList");
3686 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || 3793 ASSERT(CurrentToken() == Token::kIMPLEMENTS);
3687 (CurrentToken() == Token::kEXTENDS));
3688 const GrowableObjectArray& interfaces = 3794 const GrowableObjectArray& interfaces =
3689 GrowableObjectArray::Handle(GrowableObjectArray::New()); 3795 GrowableObjectArray::Handle(GrowableObjectArray::New());
3690 String& interface_name = String::Handle(); 3796 String& interface_name = String::Handle();
3691 AbstractType& interface = AbstractType::Handle(); 3797 AbstractType& interface = AbstractType::Handle();
3692 String& other_name = String::Handle(); 3798 String& other_name = String::Handle();
3693 AbstractType& other_interface = AbstractType::Handle(); 3799 AbstractType& other_interface = AbstractType::Handle();
3694 const String& super_type_name = String::Handle(super_type.Name()); 3800 const String& super_type_name = String::Handle(super_type.Name());
3695 do { 3801 do {
3696 ConsumeToken(); 3802 ConsumeToken();
3697 intptr_t interface_pos = TokenPos(); 3803 intptr_t interface_pos = TokenPos();
3698 interface = ParseType(ClassFinalizer::kTryResolve); 3804 interface = ParseType(ClassFinalizer::kTryResolve);
3699 interface_name = interface.UserVisibleName(); 3805 interface_name = interface.UserVisibleName();
3700 if (interface_name.Equals(super_type_name)) { 3806 if (interface_name.Equals(super_type_name)) {
3807 // TODO(hausner): I think this check is not necessary. There is
3808 // no such restriction. If the check is removed, the 'super_type'
3809 // parameter to this function can be eliminated.
3701 ErrorMsg(interface_pos, "class may not extend and implement '%s'", 3810 ErrorMsg(interface_pos, "class may not extend and implement '%s'",
3702 interface_name.ToCString()); 3811 interface_name.ToCString());
3703 } 3812 }
3704 for (int i = 0; i < interfaces.Length(); i++) { 3813 for (int i = 0; i < interfaces.Length(); i++) {
3705 other_interface ^= interfaces.At(i); 3814 other_interface ^= interfaces.At(i);
3706 other_name = other_interface.Name(); 3815 other_name = other_interface.Name();
3707 if (interface_name.Equals(other_name)) { 3816 if (interface_name.Equals(other_name)) {
3708 ErrorMsg(interface_pos, "duplicate interface '%s'", 3817 ErrorMsg(interface_pos, "duplicate interface '%s'",
3709 interface_name.ToCString()); 3818 interface_name.ToCString());
3710 } 3819 }
3711 } 3820 }
3712 interfaces.Add(interface); 3821 interfaces.Add(interface);
3713 } while (CurrentToken() == Token::kCOMMA); 3822 } while (CurrentToken() == Token::kCOMMA);
3714 return Array::MakeArray(interfaces); 3823 return Array::MakeArray(interfaces);
3715 } 3824 }
3716 3825
3717 3826
3827 RawType* Parser::ParseMixins(const Type& super_type) {
3828 TRACE_PARSER("ParseMixins");
3829 ASSERT(CurrentToken() == Token::kWITH);
3830
3831 // TODO(hausner): Remove this restriction.
3832 if (super_type.arguments() != AbstractTypeArguments::null()) {
3833 ErrorMsg(super_type.token_pos(),
3834 "super class of mixin may not have type arguments");
3835 }
3836
3837 AbstractType& mixin_type = AbstractType::Handle();
3838 AbstractTypeArguments& mixin_type_arguments =
3839 AbstractTypeArguments::Handle();
3840 Class& mixin_application = Class::Handle();
3841 Type& mixin_application_type = Type::Handle();
3842 Type& mixin_super_type = Type::Handle(super_type.raw());
3843 Array& mixin_application_interfaces = Array::Handle();
3844 const TypeArguments& no_type_arguments = TypeArguments::Handle();
3845 do {
3846 ConsumeToken();
3847 const intptr_t mixin_pos = TokenPos();
3848 mixin_type = ParseType(ClassFinalizer::kTryResolve);
3849 if (mixin_type.IsTypeParameter()) {
3850 ErrorMsg(mixin_pos,
3851 "mixin type '%s' may not be a type parameter",
3852 String::Handle(mixin_type.UserVisibleName()).ToCString());
3853 }
3854 // TODO(hausner): Remove this check once we handle mixins with type
3855 // arguments.
3856 mixin_type_arguments = mixin_type.arguments();
3857 if (!mixin_type_arguments.IsNull()) {
3858 ErrorMsg(mixin_pos,
3859 "mixin type '%s' may not have type arguments",
3860 String::Handle(mixin_type.UserVisibleName()).ToCString());
3861 }
3862
3863 // The name of the mixin application class is a combination of
3864 // the superclass and mixin class.
3865 String& mixin_app_name = String::Handle();
3866 mixin_app_name = mixin_super_type.Name();
3867 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand());
3868 mixin_app_name = String::Concat(mixin_app_name,
3869 String::Handle(mixin_type.Name()));
3870 mixin_app_name = Symbols::New(mixin_app_name);
3871
3872 mixin_application = Class::New(mixin_app_name, script_, mixin_pos);
3873 mixin_application.set_super_type(mixin_super_type);
3874 mixin_application.set_mixin(Type::Cast(mixin_type));
3875 mixin_application.set_library(library_);
3876 AddImplicitConstructor(mixin_application);
3877 // Add the mixin type to the interfaces that the mixin application
3878 // class implements. This is necessary so that type tests work.
3879 mixin_application_interfaces = Array::New(1);
3880 mixin_application_interfaces.SetAt(0, mixin_type);
3881 mixin_application.set_interfaces(mixin_application_interfaces);
3882
3883 // TODO(hausner): Need to support type arguments.
3884 mixin_application_type = Type::New(mixin_application,
3885 no_type_arguments,
3886 Scanner::kDummyTokenIndex);
3887 mixin_super_type = mixin_application_type.raw();
3888 } while (CurrentToken() == Token::kCOMMA);
3889 return mixin_application_type.raw();
3890 }
3891
3892
3718 // Add 'interface' to 'interface_list' if it is not already in the list. 3893 // Add 'interface' to 'interface_list' if it is not already in the list.
3719 // An error is reported if the interface conflicts with an interface already in 3894 // An error is reported if the interface conflicts with an interface already in
3720 // the list with the same class and same type arguments. 3895 // the list with the same class and same type arguments.
3721 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, 3896 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos,
3722 const GrowableObjectArray& interface_list, 3897 const GrowableObjectArray& interface_list,
3723 const AbstractType& interface) { 3898 const AbstractType& interface) {
3724 String& interface_name = String::Handle(interface.Name()); 3899 String& interface_name = String::Handle(interface.Name());
3725 String& existing_interface_name = String::Handle(); 3900 String& existing_interface_name = String::Handle();
3726 AbstractType& other_interface = AbstractType::Handle(); 3901 AbstractType& other_interface = AbstractType::Handle();
3727 for (intptr_t i = 0; i < interface_list.Length(); i++) { 3902 for (intptr_t i = 0; i < interface_list.Length(); i++) {
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
4442 } 4617 }
4443 4618
4444 while (true) { 4619 while (true) {
4445 set_current_class(Class::Handle()); // No current class. 4620 set_current_class(Class::Handle()); // No current class.
4446 SkipMetadata(); 4621 SkipMetadata();
4447 if (CurrentToken() == Token::kCLASS) { 4622 if (CurrentToken() == Token::kCLASS) {
4448 ParseClassDefinition(pending_classes); 4623 ParseClassDefinition(pending_classes);
4449 } else if ((CurrentToken() == Token::kTYPEDEF) && 4624 } else if ((CurrentToken() == Token::kTYPEDEF) &&
4450 (LookaheadToken(1) != Token::kLPAREN)) { 4625 (LookaheadToken(1) != Token::kLPAREN)) {
4451 set_current_class(toplevel_class); 4626 set_current_class(toplevel_class);
4452 ParseFunctionTypeAlias(pending_classes); 4627 ParseTypedef(pending_classes);
4453 } else if ((CurrentToken() == Token::kABSTRACT) && 4628 } else if ((CurrentToken() == Token::kABSTRACT) &&
4454 (LookaheadToken(1) == Token::kCLASS)) { 4629 (LookaheadToken(1) == Token::kCLASS)) {
4455 ParseClassDefinition(pending_classes); 4630 ParseClassDefinition(pending_classes);
4456 } else if (is_patch_source() && IsLiteral("patch") && 4631 } else if (is_patch_source() && IsLiteral("patch") &&
4457 (LookaheadToken(1) == Token::kCLASS)) { 4632 (LookaheadToken(1) == Token::kCLASS)) {
4458 ParseClassDefinition(pending_classes); 4633 ParseClassDefinition(pending_classes);
4459 } else { 4634 } else {
4460 set_current_class(toplevel_class); 4635 set_current_class(toplevel_class);
4461 if (IsVariableDeclaration()) { 4636 if (IsVariableDeclaration()) {
4462 ParseTopLevelVariable(&top_level); 4637 ParseTopLevelVariable(&top_level);
(...skipping 5005 matching lines...) Expand 10 before | Expand all | Expand 10 after
9468 CurrentToken() == Token::kLBRACE) { 9643 CurrentToken() == Token::kLBRACE) {
9469 primary = ParseCompoundLiteral(); 9644 primary = ParseCompoundLiteral();
9470 } else if (CurrentToken() == Token::kSUPER) { 9645 } else if (CurrentToken() == Token::kSUPER) {
9471 if (current_function().is_static()) { 9646 if (current_function().is_static()) {
9472 ErrorMsg("cannot access superclass from static method"); 9647 ErrorMsg("cannot access superclass from static method");
9473 } 9648 }
9474 if (current_class().SuperClass() == Class::null()) { 9649 if (current_class().SuperClass() == Class::null()) {
9475 ErrorMsg("class '%s' does not have a superclass", 9650 ErrorMsg("class '%s' does not have a superclass",
9476 String::Handle(current_class().Name()).ToCString()); 9651 String::Handle(current_class().Name()).ToCString());
9477 } 9652 }
9653 if (current_class().mixin() != Type::null()) {
9654 const Type& mixin_type = Type::Handle(current_class().mixin());
9655 if (mixin_type.type_class() == current_function().origin()) {
9656 ErrorMsg("class '%s' may not use super "
9657 "because it is used as mixin class",
9658 String::Handle(current_class().Name()).ToCString());
9659 }
9660 }
9478 ConsumeToken(); 9661 ConsumeToken();
9479 if (CurrentToken() == Token::kPERIOD) { 9662 if (CurrentToken() == Token::kPERIOD) {
9480 ConsumeToken(); 9663 ConsumeToken();
9481 const String& ident = *ExpectIdentifier("identifier expected"); 9664 const String& ident = *ExpectIdentifier("identifier expected");
9482 if (CurrentToken() == Token::kLPAREN) { 9665 if (CurrentToken() == Token::kLPAREN) {
9483 primary = ParseSuperCall(ident); 9666 primary = ParseSuperCall(ident);
9484 } else { 9667 } else {
9485 primary = ParseSuperFieldAccess(ident); 9668 primary = ParseSuperFieldAccess(ident);
9486 } 9669 }
9487 } else if ((CurrentToken() == Token::kLBRACK) || 9670 } else if ((CurrentToken() == Token::kLBRACK) ||
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
9809 void Parser::SkipQualIdent() { 9992 void Parser::SkipQualIdent() {
9810 ASSERT(IsIdentifier()); 9993 ASSERT(IsIdentifier());
9811 ConsumeToken(); 9994 ConsumeToken();
9812 if (CurrentToken() == Token::kPERIOD) { 9995 if (CurrentToken() == Token::kPERIOD) {
9813 ConsumeToken(); // Consume the kPERIOD token. 9996 ConsumeToken(); // Consume the kPERIOD token.
9814 ExpectIdentifier("identifier expected after '.'"); 9997 ExpectIdentifier("identifier expected after '.'");
9815 } 9998 }
9816 } 9999 }
9817 10000
9818 } // namespace dart 10001 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698