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

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
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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 : script_(script), 279 : script_(script),
280 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position), 280 tokens_iterator_(TokenStream::Handle(script.tokens()), token_position),
281 token_kind_(Token::kILLEGAL), 281 token_kind_(Token::kILLEGAL),
282 current_block_(NULL), 282 current_block_(NULL),
283 is_top_level_(false), 283 is_top_level_(false),
284 current_member_(NULL), 284 current_member_(NULL),
285 allow_function_literals_(true), 285 allow_function_literals_(true),
286 current_function_(function), 286 current_function_(function),
287 innermost_function_(Function::Handle(function.raw())), 287 innermost_function_(Function::Handle(function.raw())),
288 current_class_(Class::Handle(current_function_.Owner())), 288 current_class_(Class::Handle(current_function_.Owner())),
289 library_(Library::Handle(current_class_.library())), 289 library_(Library::Handle(Class::Handle(function.origin()).library())),
290 try_blocks_list_(NULL), 290 try_blocks_list_(NULL),
291 expression_temp_(NULL), 291 expression_temp_(NULL),
292 saved_current_context_(NULL) { 292 saved_current_context_(NULL) {
293 ASSERT(tokens_iterator_.IsValid()); 293 ASSERT(tokens_iterator_.IsValid());
294 ASSERT(!function.IsNull()); 294 ASSERT(!function.IsNull());
295 if (FLAG_enable_type_checks) { 295 if (FLAG_enable_type_checks) {
296 EnsureExpressionTemp(); 296 EnsureExpressionTemp();
297 } 297 }
298 } 298 }
299 299
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 if (!f.is_static() && f.has_initializer()) { 1818 if (!f.is_static() && f.has_initializer()) {
1819 Field& field = Field::ZoneHandle(); 1819 Field& field = Field::ZoneHandle();
1820 field ^= fields.At(i); 1820 field ^= fields.At(i);
1821 if (field.is_final()) { 1821 if (field.is_final()) {
1822 // Final fields with initializer expression may not be initialized 1822 // Final fields with initializer expression may not be initialized
1823 // again by constructors. Remember that this field is already 1823 // again by constructors. Remember that this field is already
1824 // initialized. 1824 // initialized.
1825 initialized_fields->Add(&field); 1825 initialized_fields->Add(&field);
1826 } 1826 }
1827 intptr_t field_pos = field.token_pos(); 1827 intptr_t field_pos = field.token_pos();
1828 if (current_class().raw() != field.origin()) {
1829 const Class& origin_class = Class::Handle(field.origin());
1830 if (origin_class.library() != library_.raw()) {
1831 ErrorMsg("Cannot handle initialized mixin field '%s'"
1832 "from imported library\n", field.ToCString());
1833 }
1834 }
1828 SetPosition(field_pos); 1835 SetPosition(field_pos);
1829 ASSERT(IsIdentifier()); 1836 ASSERT(IsIdentifier());
1830 ConsumeToken(); 1837 ConsumeToken();
1831 ExpectToken(Token::kASSIGN); 1838 ExpectToken(Token::kASSIGN);
1832 1839
1833 AstNode* init_expr = NULL; 1840 AstNode* init_expr = NULL;
1834 if (field.is_const()) { 1841 if (field.is_const()) {
1835 init_expr = ParseConstExpr(); 1842 init_expr = ParseConstExpr();
1836 } else { 1843 } else {
1837 init_expr = ParseExpr(kAllowConst, kConsumeCascades); 1844 init_expr = ParseExpr(kAllowConst, kConsumeCascades);
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2010 SequenceNode* Parser::ParseConstructor(const Function& func, 2017 SequenceNode* Parser::ParseConstructor(const Function& func,
2011 Array& default_parameter_values) { 2018 Array& default_parameter_values) {
2012 TRACE_PARSER("ParseConstructor"); 2019 TRACE_PARSER("ParseConstructor");
2013 ASSERT(func.IsConstructor()); 2020 ASSERT(func.IsConstructor());
2014 ASSERT(!func.IsFactory()); 2021 ASSERT(!func.IsFactory());
2015 ASSERT(!func.is_static()); 2022 ASSERT(!func.is_static());
2016 ASSERT(!func.IsLocalFunction()); 2023 ASSERT(!func.IsLocalFunction());
2017 const Class& cls = Class::Handle(func.Owner()); 2024 const Class& cls = Class::Handle(func.Owner());
2018 ASSERT(!cls.IsNull()); 2025 ASSERT(!cls.IsNull());
2019 2026
2020 if (CurrentToken() == Token::kCLASS) { 2027 if (func.IsImplicitConstructor()) {
2021 // Special case: implicit constructor. 2028 // Special case: implicit constructor.
2022 // The parser adds an implicit default constructor when a class 2029 // The parser adds an implicit default constructor when a class
2023 // does not have any explicit constructor or factory (see 2030 // does not have any explicit constructor or factory (see
2024 // Parser::AddImplicitConstructor). The token position of this implicit 2031 // Parser::AddImplicitConstructor).
2025 // constructor points to the 'class' keyword, which is followed
2026 // by the name of the class (which is also the constructor name).
2027 // There is no source text to parse. We just build the 2032 // There is no source text to parse. We just build the
2028 // sequence node by hand. 2033 // sequence node by hand.
2029 return MakeImplicitConstructor(func); 2034 return MakeImplicitConstructor(func);
2030 } 2035 }
2031 2036
2032 OpenFunctionBlock(func); 2037 OpenFunctionBlock(func);
2033 ParamList params; 2038 ParamList params;
2034 const bool allow_explicit_default_values = true; 2039 const bool allow_explicit_default_values = true;
2035 ASSERT(CurrentToken() == Token::kLPAREN); 2040 ASSERT(CurrentToken() == Token::kLPAREN);
2036 2041
(...skipping 1184 matching lines...) Expand 10 before | Expand all | Expand 10 after
3221 const intptr_t type_pos = TokenPos(); 3226 const intptr_t type_pos = TokenPos();
3222 const AbstractType& type = AbstractType::Handle( 3227 const AbstractType& type = AbstractType::Handle(
3223 ParseType(ClassFinalizer::kTryResolve)); 3228 ParseType(ClassFinalizer::kTryResolve));
3224 if (type.IsTypeParameter()) { 3229 if (type.IsTypeParameter()) {
3225 ErrorMsg(type_pos, 3230 ErrorMsg(type_pos,
3226 "class '%s' may not extend type parameter '%s'", 3231 "class '%s' may not extend type parameter '%s'",
3227 class_name.ToCString(), 3232 class_name.ToCString(),
3228 String::Handle(type.UserVisibleName()).ToCString()); 3233 String::Handle(type.UserVisibleName()).ToCString());
3229 } 3234 }
3230 super_type ^= type.raw(); 3235 super_type ^= type.raw();
3236 if (CurrentToken() == Token::kWITH) {
3237 super_type = ParseMixins(super_type);
3238 }
3231 } else { 3239 } else {
3232 // No extends clause: Implicitly extend Object. 3240 // No extends clause: implicitly extend Object.
3233 super_type = Type::ObjectType(); 3241 super_type = Type::ObjectType();
3234 } 3242 }
3235 ASSERT(!super_type.IsNull()); 3243 ASSERT(!super_type.IsNull());
3236 cls.set_super_type(super_type); 3244 cls.set_super_type(super_type);
3237 3245
3238 if (CurrentToken() == Token::kIMPLEMENTS) { 3246 if (CurrentToken() == Token::kIMPLEMENTS) {
3239 Array& interfaces = Array::Handle(); 3247 Array& interfaces = Array::Handle();
3240 const intptr_t interfaces_pos = TokenPos(); 3248 const intptr_t interfaces_pos = TokenPos();
3241 interfaces = ParseInterfaceList(super_type); 3249 interfaces = ParseInterfaceList(super_type);
3242 AddInterfaces(interfaces_pos, cls, interfaces); 3250 AddInterfaces(interfaces_pos, cls, interfaces);
3243 } 3251 }
3244 3252
3245 ExpectToken(Token::kLBRACE); 3253 ExpectToken(Token::kLBRACE);
3246 ClassDesc members(cls, class_name, false, class_pos); 3254 ClassDesc members(cls, class_name, false, class_pos);
3247 while (CurrentToken() != Token::kRBRACE) { 3255 while (CurrentToken() != Token::kRBRACE) {
3248 SkipMetadata(); 3256 SkipMetadata();
3249 ParseClassMemberDefinition(&members); 3257 ParseClassMemberDefinition(&members);
3250 } 3258 }
3251 ExpectToken(Token::kRBRACE); 3259 ExpectToken(Token::kRBRACE);
3252 3260
3253 if (is_abstract) { 3261 if (is_abstract) {
3254 cls.set_is_abstract(); 3262 cls.set_is_abstract();
3255 } 3263 }
3256 3264
3257 // Add an implicit constructor if no explicit constructor is present. No
3258 // implicit constructors are needed for patch classes.
3259 if (!members.has_constructor() && !is_patch) {
3260 AddImplicitConstructor(&members);
3261 }
3262 CheckConstructors(&members); 3265 CheckConstructors(&members);
3263 3266
3267 // Need to compute this here since MakeArray() will clear the
3268 // functions array in members.
3269 const bool need_implicit_constructor =
3270 !members.has_constructor() && !is_patch;
3271
3264 Array& array = Array::Handle(); 3272 Array& array = Array::Handle();
3265 array = Array::MakeArray(members.fields()); 3273 array = Array::MakeArray(members.fields());
3266 cls.SetFields(array); 3274 cls.SetFields(array);
3267 3275
3268 // Creating a new array for functions marks the class as parsed. 3276 // Creating a new array for functions marks the class as parsed.
3269 array = Array::MakeArray(members.functions()); 3277 array = Array::MakeArray(members.functions());
3270 cls.SetFunctions(array); 3278 cls.SetFunctions(array);
3271 3279
3280 // Add an implicit constructor if no explicit constructor is present.
3281 // No implicit constructors are needed for patch classes.
3282 if (need_implicit_constructor) {
3283 AddImplicitConstructor(cls);
3284 }
3285
3272 if (!is_patch) { 3286 if (!is_patch) {
3273 pending_classes.Add(cls, Heap::kOld); 3287 pending_classes.Add(cls, Heap::kOld);
3274 } else { 3288 } else {
3275 // Apply the changes to the patched class looked up above. 3289 // Apply the changes to the patched class looked up above.
3276 ASSERT(obj.raw() == library_.LookupLocalObject(class_name)); 3290 ASSERT(obj.raw() == library_.LookupLocalObject(class_name));
3277 // The patched class must not be finalized yet. 3291 // The patched class must not be finalized yet.
3278 ASSERT(!Class::Cast(obj).is_finalized()); 3292 ASSERT(!Class::Cast(obj).is_finalized());
3279 const char* err_msg = Class::Cast(obj).ApplyPatch(cls); 3293 const char* err_msg = Class::Cast(obj).ApplyPatch(cls);
3280 if (err_msg != NULL) { 3294 if (err_msg != NULL) {
3281 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg); 3295 ErrorMsg(classname_pos, "applying patch failed with '%s'", err_msg);
3282 } 3296 }
3283 } 3297 }
3284 } 3298 }
3285 3299
3286 3300
3287 // Add an implicit constructor if no explicit constructor is present. 3301 // Add an implicit constructor to the given class.
3288 void Parser::AddImplicitConstructor(ClassDesc* class_desc) { 3302 void Parser::AddImplicitConstructor(const Class& cls) {
3289 // The implicit constructor is unnamed, has no explicit parameter, 3303 // The implicit constructor is unnamed, has no explicit parameter.
3290 // and contains a supercall in the initializer list. 3304 String& ctor_name = String::ZoneHandle(cls.Name());
3291 String& ctor_name = String::ZoneHandle( 3305 ctor_name = String::Concat(ctor_name, Symbols::Dot());
3292 String::Concat(class_desc->class_name(), Symbols::Dot()));
3293 ctor_name = Symbols::New(ctor_name); 3306 ctor_name = Symbols::New(ctor_name);
3294 // The token position for the implicit constructor is the 'class' 3307 // To indicate that this is an implicit constructor, we set the
3295 // keyword of the constructor's class. 3308 // token position is the same as the token position of the class.
3296 Function& ctor = Function::Handle( 3309 Function& ctor = Function::Handle(
3297 Function::New(ctor_name, 3310 Function::New(ctor_name,
3298 RawFunction::kConstructor, 3311 RawFunction::kConstructor,
3299 /* is_static = */ false, 3312 /* is_static = */ false,
3300 /* is_const = */ false, 3313 /* is_const = */ false,
3301 /* is_abstract = */ false, 3314 /* is_abstract = */ false,
3302 /* is_external = */ false, 3315 /* is_external = */ false,
3303 current_class(), 3316 cls,
3304 class_desc->token_pos())); 3317 cls.token_pos()));
3305 ParamList params; 3318 ParamList params;
3306 // Add implicit 'this' parameter. 3319 // Add implicit 'this' parameter. We don't care about the specific type
3307 ASSERT(current_class().raw() == ctor.Owner()); 3320 // and just specify dynamic.
3308 params.AddReceiver(ReceiverType(TokenPos())); 3321 const Type& receiver_type = Type::Handle(Type::DynamicType());
3322 params.AddReceiver(&receiver_type);
3309 // Add implicit parameter for construction phase. 3323 // Add implicit parameter for construction phase.
3310 params.AddFinalParameter(TokenPos(), 3324 params.AddFinalParameter(cls.token_pos(),
3311 &Symbols::PhaseParameter(), 3325 &Symbols::PhaseParameter(),
3312 &Type::ZoneHandle(Type::SmiType())); 3326 &Type::ZoneHandle(Type::SmiType()));
3313 3327
3314 AddFormalParamsToFunction(&params, ctor); 3328 AddFormalParamsToFunction(&params, ctor);
3315 // The body of the constructor cannot modify the type of the constructed 3329 // The body of the constructor cannot modify the type of the constructed
3316 // instance, which is passed in as the receiver. 3330 // instance, which is passed in as the receiver.
3317 ctor.set_result_type(*((*params.parameters)[0].type)); 3331 ctor.set_result_type(receiver_type);
3318 class_desc->AddFunction(ctor); 3332 cls.AddFunction(ctor);
3319 } 3333 }
3320 3334
3321 3335
3322 // Check for cycles in constructor redirection. Also check whether a 3336 // Check for cycles in constructor redirection. Also check whether a
3323 // named constructor collides with the name of another class member. 3337 // named constructor collides with the name of another class member.
3324 void Parser::CheckConstructors(ClassDesc* class_desc) { 3338 void Parser::CheckConstructors(ClassDesc* class_desc) {
3325 // Check for cycles in constructor redirection. 3339 // Check for cycles in constructor redirection.
3326 const GrowableArray<MemberDesc>& members = class_desc->members(); 3340 const GrowableArray<MemberDesc>& members = class_desc->members();
3327 for (int i = 0; i < members.length(); i++) { 3341 for (int i = 0; i < members.length(); i++) {
3328 MemberDesc* member = &members[i]; 3342 MemberDesc* member = &members[i];
(...skipping 24 matching lines...) Expand all
3353 // which the current one redirects, we ignore the unresolved 3367 // which the current one redirects, we ignore the unresolved
3354 // reference. We'll catch it later when the constructor gets 3368 // reference. We'll catch it later when the constructor gets
3355 // compiled. 3369 // compiled.
3356 ctors.Add(member); 3370 ctors.Add(member);
3357 member = class_desc->LookupMember(*member->redirect_name); 3371 member = class_desc->LookupMember(*member->redirect_name);
3358 } 3372 }
3359 } 3373 }
3360 } 3374 }
3361 3375
3362 3376
3377 void Parser::ParseMixinTypedef(const GrowableObjectArray& pending_classes) {
3378 TRACE_PARSER("ParseMixinTypedef");
3379 const intptr_t classname_pos = TokenPos();
3380 String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected");
3381 if (FLAG_trace_parser) {
3382 OS::Print("toplevel parsing typedef class '%s'\n", class_name.ToCString());
3383 }
3384 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name));
3385 if (!obj.IsNull()) {
3386 ErrorMsg(classname_pos, "'%s' is already defined",
3387 class_name.ToCString());
3388 }
3389 const Class& mixin_application =
3390 Class::Handle(Class::New(class_name, script_, classname_pos));
3391 library_.AddClass(mixin_application);
3392 set_current_class(mixin_application);
3393 ParseTypeParameters(mixin_application);
3394 ExpectToken(Token::kASSIGN);
3395
3396 if (CurrentToken() == Token::kABSTRACT) {
3397 mixin_application.set_is_abstract();
3398 ConsumeToken();
3399 }
3400
3401 const intptr_t supertype_pos = TokenPos();
3402 const AbstractType& type =
3403 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve));
3404 if (type.IsTypeParameter()) {
3405 ErrorMsg(supertype_pos,
3406 "class '%s' may not extend type parameter '%s'",
3407 class_name.ToCString(),
3408 String::Handle(type.UserVisibleName()).ToCString());
3409 }
3410 Type& mixin_super_type = Type::Handle();
3411 mixin_super_type ^= type.raw();
3412
3413 if (CurrentToken() != Token::kWITH) {
3414 ErrorMsg("mixin application 'with Type' expected");
3415 }
3416
3417 Type& mixin_application_type = Type::Handle(ParseMixins(mixin_super_type));
3418 // The result of ParseMixins() is a chain of super classes that is the
3419 // result of the mixin composition 'S with M1, M2, ...'. The mixin
3420 // application classes are anonymous (i.e. not registered in the current
3421 // library). We steal the super type and mixin type from the bottom of
3422 // the chain and add it to the named mixin application class. The bottom
3423 // anonymous class in the chain is thrown away.
3424 const Class& anon_mixin_app_class =
3425 Class::Handle(mixin_application_type.type_class());
3426 mixin_application.set_super_type(
3427 Type::Handle(anon_mixin_app_class.super_type()));
3428 mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin()));
3429 const Array& interfaces = Array::Handle(anon_mixin_app_class.interfaces());
3430 mixin_application.set_interfaces(interfaces);
3431 AddImplicitConstructor(mixin_application);
3432
3433 if (CurrentToken() == Token::kIMPLEMENTS) {
3434 Array& interfaces = Array::Handle();
3435 const intptr_t interfaces_pos = TokenPos();
3436 const Type& super_type = Type::Handle(mixin_application.super_type());
3437 interfaces = ParseInterfaceList(super_type);
3438 AddInterfaces(interfaces_pos, mixin_application, interfaces);
3439 }
3440
3441 pending_classes.Add(mixin_application, Heap::kOld);
3442 ExpectSemicolon();
3443 }
3444
3445
3363 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". 3446 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(".
3364 // We need this lookahead to distinguish between the optional return type 3447 // We need this lookahead to distinguish between the optional return type
3365 // and the alias name of a function type alias. 3448 // and the alias name of a function type alias.
3366 // Token position remains unchanged. 3449 // Token position remains unchanged.
3367 bool Parser::IsFunctionTypeAliasName() { 3450 bool Parser::IsFunctionTypeAliasName() {
3368 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { 3451 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
3369 return true; 3452 return true;
3370 } 3453 }
3371 const intptr_t saved_pos = TokenPos(); 3454 const intptr_t saved_pos = TokenPos();
3372 bool is_alias_name = false; 3455 bool is_alias_name = false;
3373 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { 3456 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
3374 ConsumeToken(); 3457 ConsumeToken();
3375 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { 3458 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) {
3376 is_alias_name = true; 3459 is_alias_name = true;
3377 } 3460 }
3378 } 3461 }
3379 SetPosition(saved_pos); 3462 SetPosition(saved_pos);
3380 return is_alias_name; 3463 return is_alias_name;
3381 } 3464 }
3382 3465
3383 3466
3384 void Parser::ParseFunctionTypeAlias( 3467 // Look ahead to detect if we are seeing ident [ TypeParameters ] "=".
3385 const GrowableObjectArray& pending_classes) { 3468 // Token position remains unchanged.
3386 TRACE_PARSER("ParseFunctionTypeAlias"); 3469 bool Parser::IsMixinTypedef() {
3470 if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) {
3471 return true;
3472 }
3473 const intptr_t saved_pos = TokenPos();
3474 bool is_mixin_def = false;
3475 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
3476 ConsumeToken();
3477 if (TryParseTypeParameter() && (CurrentToken() == Token::kASSIGN)) {
3478 is_mixin_def = true;
3479 }
3480 }
3481 SetPosition(saved_pos);
3482 return is_mixin_def;
3483 }
3484
3485
3486 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes) {
3487 TRACE_PARSER("ParseTypedef");
3387 ExpectToken(Token::kTYPEDEF); 3488 ExpectToken(Token::kTYPEDEF);
3388 3489
3490 if (IsMixinTypedef()) {
3491 ParseMixinTypedef(pending_classes);
3492 return;
3493 }
3494
3389 // Parse the result type of the function type. 3495 // Parse the result type of the function type.
3390 AbstractType& result_type = Type::Handle(Type::DynamicType()); 3496 AbstractType& result_type = Type::Handle(Type::DynamicType());
3391 if (CurrentToken() == Token::kVOID) { 3497 if (CurrentToken() == Token::kVOID) {
3392 ConsumeToken(); 3498 ConsumeToken();
3393 result_type = Type::VoidType(); 3499 result_type = Type::VoidType();
3394 } else if (!IsFunctionTypeAliasName()) { 3500 } else if (!IsFunctionTypeAliasName()) {
3395 // Type annotations in typedef are never ignored, even in unchecked mode. 3501 // Type annotations in typedef are never ignored, even in unchecked mode.
3396 // Wait until we have an owner class before resolving the result type. 3502 // Wait until we have an owner class before resolving the result type.
3397 result_type = ParseType(ClassFinalizer::kDoNotResolve); 3503 result_type = ParseType(ClassFinalizer::kDoNotResolve);
3398 } 3504 }
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
3660 return NewTypeArguments(types); 3766 return NewTypeArguments(types);
3661 } 3767 }
3662 } 3768 }
3663 return TypeArguments::null(); 3769 return TypeArguments::null();
3664 } 3770 }
3665 3771
3666 3772
3667 // Parse and return an array of interface types. 3773 // Parse and return an array of interface types.
3668 RawArray* Parser::ParseInterfaceList(const Type& super_type) { 3774 RawArray* Parser::ParseInterfaceList(const Type& super_type) {
3669 TRACE_PARSER("ParseInterfaceList"); 3775 TRACE_PARSER("ParseInterfaceList");
3670 ASSERT((CurrentToken() == Token::kIMPLEMENTS) || 3776 ASSERT(CurrentToken() == Token::kIMPLEMENTS);
3671 (CurrentToken() == Token::kEXTENDS));
3672 const GrowableObjectArray& interfaces = 3777 const GrowableObjectArray& interfaces =
3673 GrowableObjectArray::Handle(GrowableObjectArray::New()); 3778 GrowableObjectArray::Handle(GrowableObjectArray::New());
3674 String& interface_name = String::Handle(); 3779 String& interface_name = String::Handle();
3675 AbstractType& interface = AbstractType::Handle(); 3780 AbstractType& interface = AbstractType::Handle();
3676 String& other_name = String::Handle(); 3781 String& other_name = String::Handle();
3677 AbstractType& other_interface = AbstractType::Handle(); 3782 AbstractType& other_interface = AbstractType::Handle();
3678 const String& super_type_name = String::Handle(super_type.Name()); 3783 const String& super_type_name = String::Handle(super_type.Name());
3679 do { 3784 do {
3680 ConsumeToken(); 3785 ConsumeToken();
3681 intptr_t interface_pos = TokenPos(); 3786 intptr_t interface_pos = TokenPos();
3682 interface = ParseType(ClassFinalizer::kTryResolve); 3787 interface = ParseType(ClassFinalizer::kTryResolve);
3683 interface_name = interface.UserVisibleName(); 3788 interface_name = interface.UserVisibleName();
3684 if (interface_name.Equals(super_type_name)) { 3789 if (interface_name.Equals(super_type_name)) {
3790 // TODO(hausner): I think this check is not necessary. There is
3791 // no such restriction. If the check is removed, the 'super_type'
3792 // parameter to this function can be eliminated.
3685 ErrorMsg(interface_pos, "class may not extend and implement '%s'", 3793 ErrorMsg(interface_pos, "class may not extend and implement '%s'",
3686 interface_name.ToCString()); 3794 interface_name.ToCString());
3687 } 3795 }
3688 for (int i = 0; i < interfaces.Length(); i++) { 3796 for (int i = 0; i < interfaces.Length(); i++) {
3689 other_interface ^= interfaces.At(i); 3797 other_interface ^= interfaces.At(i);
3690 other_name = other_interface.Name(); 3798 other_name = other_interface.Name();
3691 if (interface_name.Equals(other_name)) { 3799 if (interface_name.Equals(other_name)) {
3692 ErrorMsg(interface_pos, "duplicate interface '%s'", 3800 ErrorMsg(interface_pos, "duplicate interface '%s'",
3693 interface_name.ToCString()); 3801 interface_name.ToCString());
3694 } 3802 }
3695 } 3803 }
3696 interfaces.Add(interface); 3804 interfaces.Add(interface);
3697 } while (CurrentToken() == Token::kCOMMA); 3805 } while (CurrentToken() == Token::kCOMMA);
3698 return Array::MakeArray(interfaces); 3806 return Array::MakeArray(interfaces);
3699 } 3807 }
3700 3808
3701 3809
3810 RawType* Parser::ParseMixins(const Type& super_type) {
3811 TRACE_PARSER("ParseMixins");
3812 ASSERT(CurrentToken() == Token::kWITH);
3813
3814 // TODO(hausner): Remove this restriction.
3815 if (super_type.arguments() != AbstractTypeArguments::null()) {
3816 ErrorMsg(super_type.token_pos(),
3817 "super class of mixin may not have type arguments");
3818 }
3819
3820 AbstractType& mixin_type = AbstractType::Handle();
3821 AbstractTypeArguments& mixin_type_arguments =
3822 AbstractTypeArguments::Handle();
3823 Class& mixin_application = Class::Handle();
3824 Type& mixin_application_type = Type::Handle();
3825 Type& mixin_super_type = Type::Handle(super_type.raw());
3826 Array& mixin_application_interfaces = Array::Handle();
3827 const TypeArguments& no_type_arguments = TypeArguments::Handle();
3828 do {
3829 ConsumeToken();
3830 const intptr_t mixin_pos = TokenPos();
3831 mixin_type = ParseType(ClassFinalizer::kTryResolve);
3832 if (mixin_type.IsTypeParameter()) {
3833 ErrorMsg(mixin_pos,
3834 "mixin type '%s' may not be a type parameter",
3835 String::Handle(mixin_type.UserVisibleName()).ToCString());
3836 }
3837 // TODO(hausner): Remove this check once we handle mixins with type
3838 // arguments.
3839 mixin_type_arguments = mixin_type.arguments();
3840 if (!mixin_type_arguments.IsNull()) {
3841 ErrorMsg(mixin_pos,
3842 "mixin type '%s' may not have type arguments",
3843 String::Handle(mixin_type.UserVisibleName()).ToCString());
3844 }
siva 2013/02/13 01:34:37 How do you handle 'S with M,N,M' or 'S with M,M' i
hausner 2013/02/13 19:58:14 I discussed that with Gilad. He says it's perfectl
3845
3846 // The name of the mixin application class is a combination of
3847 // the superclass and mixin class.
3848 String& mixin_app_name = String::Handle();
3849 mixin_app_name = mixin_super_type.Name();
3850 mixin_app_name = String::Concat(mixin_app_name,
3851 String::Handle(String::New("&")));
siva 2013/02/13 01:34:37 Maybe add a Symbols::Ampersand() method similar to
hausner 2013/02/13 19:58:14 I thought about this and didn't think this is used
3852 mixin_app_name = String::Concat(mixin_app_name,
3853 String::Handle(mixin_type.Name()));
3854 mixin_app_name = Symbols::New(mixin_app_name);
3855
3856 mixin_application = Class::New(mixin_app_name, script_, mixin_pos);
3857 mixin_application.set_super_type(mixin_super_type);
3858 mixin_application.set_mixin(Type::Cast(mixin_type));
3859 mixin_application.set_library(library_);
3860 AddImplicitConstructor(mixin_application);
3861 // Add the mixin type to the interfaces that the mixin application
3862 // class implements. This is necessary so that type tests work.
3863 mixin_application_interfaces = Array::New(1);
3864 mixin_application_interfaces.SetAt(0, mixin_type);
3865 mixin_application.set_interfaces(mixin_application_interfaces);
3866
3867 // TODO(hausner): Need to support type arguments.
3868 mixin_application_type = Type::New(mixin_application,
3869 no_type_arguments,
3870 Scanner::kDummyTokenIndex);
3871 mixin_super_type = mixin_application_type.raw();
3872 } while (CurrentToken() == Token::kCOMMA);
3873 return mixin_application_type.raw();
3874 }
3875
3876
3702 // Add 'interface' to 'interface_list' if it is not already in the list. 3877 // Add 'interface' to 'interface_list' if it is not already in the list.
3703 // An error is reported if the interface conflicts with an interface already in 3878 // An error is reported if the interface conflicts with an interface already in
3704 // the list with the same class and same type arguments. 3879 // the list with the same class and same type arguments.
3705 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, 3880 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos,
3706 const GrowableObjectArray& interface_list, 3881 const GrowableObjectArray& interface_list,
3707 const AbstractType& interface) { 3882 const AbstractType& interface) {
3708 String& interface_name = String::Handle(interface.Name()); 3883 String& interface_name = String::Handle(interface.Name());
3709 String& existing_interface_name = String::Handle(); 3884 String& existing_interface_name = String::Handle();
3710 AbstractType& other_interface = AbstractType::Handle(); 3885 AbstractType& other_interface = AbstractType::Handle();
3711 for (intptr_t i = 0; i < interface_list.Length(); i++) { 3886 for (intptr_t i = 0; i < interface_list.Length(); i++) {
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
4426 } 4601 }
4427 4602
4428 while (true) { 4603 while (true) {
4429 set_current_class(Class::Handle()); // No current class. 4604 set_current_class(Class::Handle()); // No current class.
4430 SkipMetadata(); 4605 SkipMetadata();
4431 if (CurrentToken() == Token::kCLASS) { 4606 if (CurrentToken() == Token::kCLASS) {
4432 ParseClassDefinition(pending_classes); 4607 ParseClassDefinition(pending_classes);
4433 } else if ((CurrentToken() == Token::kTYPEDEF) && 4608 } else if ((CurrentToken() == Token::kTYPEDEF) &&
4434 (LookaheadToken(1) != Token::kLPAREN)) { 4609 (LookaheadToken(1) != Token::kLPAREN)) {
4435 set_current_class(toplevel_class); 4610 set_current_class(toplevel_class);
4436 ParseFunctionTypeAlias(pending_classes); 4611 ParseTypedef(pending_classes);
4437 } else if ((CurrentToken() == Token::kABSTRACT) && 4612 } else if ((CurrentToken() == Token::kABSTRACT) &&
4438 (LookaheadToken(1) == Token::kCLASS)) { 4613 (LookaheadToken(1) == Token::kCLASS)) {
4439 ParseClassDefinition(pending_classes); 4614 ParseClassDefinition(pending_classes);
4440 } else if (is_patch_source() && IsLiteral("patch") && 4615 } else if (is_patch_source() && IsLiteral("patch") &&
4441 (LookaheadToken(1) == Token::kCLASS)) { 4616 (LookaheadToken(1) == Token::kCLASS)) {
4442 ParseClassDefinition(pending_classes); 4617 ParseClassDefinition(pending_classes);
4443 } else { 4618 } else {
4444 set_current_class(toplevel_class); 4619 set_current_class(toplevel_class);
4445 if (IsVariableDeclaration()) { 4620 if (IsVariableDeclaration()) {
4446 ParseTopLevelVariable(&top_level); 4621 ParseTopLevelVariable(&top_level);
(...skipping 4996 matching lines...) Expand 10 before | Expand all | Expand 10 after
9443 CurrentToken() == Token::kLBRACE) { 9618 CurrentToken() == Token::kLBRACE) {
9444 primary = ParseCompoundLiteral(); 9619 primary = ParseCompoundLiteral();
9445 } else if (CurrentToken() == Token::kSUPER) { 9620 } else if (CurrentToken() == Token::kSUPER) {
9446 if (current_function().is_static()) { 9621 if (current_function().is_static()) {
9447 ErrorMsg("cannot access superclass from static method"); 9622 ErrorMsg("cannot access superclass from static method");
9448 } 9623 }
9449 if (current_class().SuperClass() == Class::null()) { 9624 if (current_class().SuperClass() == Class::null()) {
9450 ErrorMsg("class '%s' does not have a superclass", 9625 ErrorMsg("class '%s' does not have a superclass",
9451 String::Handle(current_class().Name()).ToCString()); 9626 String::Handle(current_class().Name()).ToCString());
9452 } 9627 }
9628 if (current_class().mixin() != Type::null()) {
9629 const Type& mixin_type = Type::Handle(current_class().mixin());
9630 if (mixin_type.type_class() == current_function().origin()) {
9631 ErrorMsg("class '%s' may not use super "
9632 "because it is used as mixin class",
9633 String::Handle(current_class().Name()).ToCString());
9634 }
9635 }
9453 ConsumeToken(); 9636 ConsumeToken();
9454 if (CurrentToken() == Token::kPERIOD) { 9637 if (CurrentToken() == Token::kPERIOD) {
9455 ConsumeToken(); 9638 ConsumeToken();
9456 const String& ident = *ExpectIdentifier("identifier expected"); 9639 const String& ident = *ExpectIdentifier("identifier expected");
9457 if (CurrentToken() == Token::kLPAREN) { 9640 if (CurrentToken() == Token::kLPAREN) {
9458 primary = ParseSuperCall(ident); 9641 primary = ParseSuperCall(ident);
9459 } else { 9642 } else {
9460 primary = ParseSuperFieldAccess(ident); 9643 primary = ParseSuperFieldAccess(ident);
9461 } 9644 }
9462 } else if ((CurrentToken() == Token::kLBRACK) || 9645 } else if ((CurrentToken() == Token::kLBRACK) ||
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
9784 void Parser::SkipQualIdent() { 9967 void Parser::SkipQualIdent() {
9785 ASSERT(IsIdentifier()); 9968 ASSERT(IsIdentifier());
9786 ConsumeToken(); 9969 ConsumeToken();
9787 if (CurrentToken() == Token::kPERIOD) { 9970 if (CurrentToken() == Token::kPERIOD) {
9788 ConsumeToken(); // Consume the kPERIOD token. 9971 ConsumeToken(); // Consume the kPERIOD token.
9789 ExpectIdentifier("identifier expected after '.'"); 9972 ExpectIdentifier("identifier expected after '.'");
9790 } 9973 }
9791 } 9974 }
9792 9975
9793 } // namespace dart 9976 } // namespace dart
OLDNEW
« runtime/vm/object.h ('K') | « 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