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

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

Issue 12779008: Mixins with Generics (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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 "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 3226 matching lines...) Expand 10 before | Expand all | Expand 10 after
3237 "original type parameter '%s'", 3237 "original type parameter '%s'",
3238 new_name.ToCString(), 3238 new_name.ToCString(),
3239 class_name.ToCString(), 3239 class_name.ToCString(),
3240 orig_name.ToCString()); 3240 orig_name.ToCString());
3241 } 3241 }
3242 // We do not check that the bounds are repeated. We use the original ones. 3242 // We do not check that the bounds are repeated. We use the original ones.
3243 // TODO(regis): Should we check? 3243 // TODO(regis): Should we check?
3244 } 3244 }
3245 cls.set_type_parameters(orig_type_parameters); 3245 cls.set_type_parameters(orig_type_parameters);
3246 } 3246 }
3247 Type& super_type = Type::Handle(); 3247 AbstractType& super_type = Type::Handle();
3248 if (CurrentToken() == Token::kEXTENDS) { 3248 if (CurrentToken() == Token::kEXTENDS) {
3249 ConsumeToken(); 3249 ConsumeToken();
3250 const intptr_t type_pos = TokenPos(); 3250 const intptr_t type_pos = TokenPos();
3251 const AbstractType& type = AbstractType::Handle( 3251 super_type = ParseType(ClassFinalizer::kTryResolve);
3252 ParseType(ClassFinalizer::kTryResolve)); 3252 if (super_type.IsTypeParameter()) {
3253 if (type.IsTypeParameter()) {
3254 ErrorMsg(type_pos, 3253 ErrorMsg(type_pos,
3255 "class '%s' may not extend type parameter '%s'", 3254 "class '%s' may not extend type parameter '%s'",
3256 class_name.ToCString(), 3255 class_name.ToCString(),
3257 String::Handle(type.UserVisibleName()).ToCString()); 3256 String::Handle(super_type.UserVisibleName()).ToCString());
3258 } 3257 }
3259 super_type ^= type.raw();
3260 if (CurrentToken() == Token::kWITH) { 3258 if (CurrentToken() == Token::kWITH) {
3261 super_type = ParseMixins(super_type); 3259 super_type = ParseMixins(super_type);
3262 } 3260 }
3263 } else { 3261 } else {
3264 // No extends clause: implicitly extend Object. 3262 // No extends clause: implicitly extend Object.
3265 super_type = Type::ObjectType(); 3263 super_type = Type::ObjectType();
3266 } 3264 }
3267 ASSERT(!super_type.IsNull()); 3265 ASSERT(!super_type.IsNull());
3268 cls.set_super_type(super_type); 3266 cls.set_super_type(super_type);
3269 3267
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
3409 if (!obj.IsNull()) { 3407 if (!obj.IsNull()) {
3410 ErrorMsg(classname_pos, "'%s' is already defined", 3408 ErrorMsg(classname_pos, "'%s' is already defined",
3411 class_name.ToCString()); 3409 class_name.ToCString());
3412 } 3410 }
3413 const Class& mixin_application = 3411 const Class& mixin_application =
3414 Class::Handle(Class::New(class_name, script_, classname_pos)); 3412 Class::Handle(Class::New(class_name, script_, classname_pos));
3415 library_.AddClass(mixin_application); 3413 library_.AddClass(mixin_application);
3416 set_current_class(mixin_application); 3414 set_current_class(mixin_application);
3417 ParseTypeParameters(mixin_application); 3415 ParseTypeParameters(mixin_application);
3418 3416
3419 // TODO(hausner): Handle mixin application aliases with generics.
3420 if (mixin_application.NumTypeParameters() > 0) {
3421 ErrorMsg(classname_pos,
3422 "type parameters on mixin applications not yet supported");
3423 }
3424
3425 ExpectToken(Token::kASSIGN); 3417 ExpectToken(Token::kASSIGN);
3426 3418
3427 if (CurrentToken() == Token::kABSTRACT) { 3419 if (CurrentToken() == Token::kABSTRACT) {
3428 mixin_application.set_is_abstract(); 3420 mixin_application.set_is_abstract();
3429 ConsumeToken(); 3421 ConsumeToken();
3430 } 3422 }
3431 3423
3432 const intptr_t supertype_pos = TokenPos(); 3424 const intptr_t type_pos = TokenPos();
3433 const AbstractType& type = 3425 AbstractType& type =
3434 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve)); 3426 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve));
3435 if (type.IsTypeParameter()) { 3427 if (type.IsTypeParameter()) {
3436 ErrorMsg(supertype_pos, 3428 ErrorMsg(type_pos,
3437 "class '%s' may not extend type parameter '%s'", 3429 "class '%s' may not extend type parameter '%s'",
3438 class_name.ToCString(), 3430 class_name.ToCString(),
3439 String::Handle(type.UserVisibleName()).ToCString()); 3431 String::Handle(type.UserVisibleName()).ToCString());
3440 } 3432 }
3441 Type& mixin_super_type = Type::Handle();
3442 mixin_super_type ^= type.raw();
3443 3433
3444 if (CurrentToken() != Token::kWITH) { 3434 if (CurrentToken() != Token::kWITH) {
3445 ErrorMsg("mixin application 'with Type' expected"); 3435 ErrorMsg("mixin application 'with Type' expected");
3446 } 3436 }
3437 type = ParseMixins(type);
3447 3438
3448 const Type& mixin_application_type = 3439 // TODO(hausner): treat the mixin application as an alias, not as a base
3449 Type::Handle(ParseMixins(mixin_super_type)); 3440 // class whose super class is the mixin application!
3450 // TODO(hausner): Implement generic mixin support. 3441 mixin_application.set_super_type(type);
3451 if (mixin_application_type.arguments() != AbstractTypeArguments::null()) {
3452 ErrorMsg(mixin_application_type.token_pos(),
3453 "mixin class with type arguments not yet supported");
3454 }
3455 3442
3456 // The result of ParseMixins() is a chain of super types that is the
3457 // result of the mixin composition 'S with M1, M2, ...'. The mixin
3458 // application classes are anonymous (i.e. not registered in the current
3459 // library). We steal the super type and mixin type from the bottom of
3460 // the chain and add it to the named mixin application class. The bottom
3461 // anonymous class in the chain is thrown away.
3462 const Class& anon_mixin_app_class =
3463 Class::Handle(mixin_application_type.type_class());
3464 mixin_application.set_super_type(
3465 AbstractType::Handle(anon_mixin_app_class.super_type()));
3466 mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin()));
3467 const Array& interfaces = Array::Handle(anon_mixin_app_class.interfaces());
3468 mixin_application.set_interfaces(interfaces);
3469 AddImplicitConstructor(mixin_application); 3443 AddImplicitConstructor(mixin_application);
3470
3471 if (CurrentToken() == Token::kIMPLEMENTS) { 3444 if (CurrentToken() == Token::kIMPLEMENTS) {
3472 Array& interfaces = Array::Handle(); 3445 Array& interfaces = Array::Handle();
3473 const intptr_t interfaces_pos = TokenPos(); 3446 const intptr_t interfaces_pos = TokenPos();
3474 Type& super_type = Type::Handle(); 3447 interfaces = ParseInterfaceList(type);
3475 super_type ^= mixin_application.super_type();
3476 interfaces = ParseInterfaceList(super_type);
3477 AddInterfaces(interfaces_pos, mixin_application, interfaces); 3448 AddInterfaces(interfaces_pos, mixin_application, interfaces);
3478 } 3449 }
3479 3450 ExpectSemicolon();
3480 pending_classes.Add(mixin_application, Heap::kOld); 3451 pending_classes.Add(mixin_application, Heap::kOld);
3481 ExpectSemicolon();
3482 } 3452 }
3483 3453
3484 3454
3485 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". 3455 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(".
3486 // We need this lookahead to distinguish between the optional return type 3456 // We need this lookahead to distinguish between the optional return type
3487 // and the alias name of a function type alias. 3457 // and the alias name of a function type alias.
3488 // Token position remains unchanged. 3458 // Token position remains unchanged.
3489 bool Parser::IsFunctionTypeAliasName() { 3459 bool Parser::IsFunctionTypeAliasName() {
3490 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { 3460 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
3491 return true; 3461 return true;
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
3803 } 3773 }
3804 if (finalization != ClassFinalizer::kIgnore) { 3774 if (finalization != ClassFinalizer::kIgnore) {
3805 return NewTypeArguments(types); 3775 return NewTypeArguments(types);
3806 } 3776 }
3807 } 3777 }
3808 return TypeArguments::null(); 3778 return TypeArguments::null();
3809 } 3779 }
3810 3780
3811 3781
3812 // Parse and return an array of interface types. 3782 // Parse and return an array of interface types.
3813 RawArray* Parser::ParseInterfaceList(const Type& super_type) { 3783 RawArray* Parser::ParseInterfaceList(const AbstractType& super_type) {
3814 TRACE_PARSER("ParseInterfaceList"); 3784 TRACE_PARSER("ParseInterfaceList");
3815 ASSERT(CurrentToken() == Token::kIMPLEMENTS); 3785 ASSERT(CurrentToken() == Token::kIMPLEMENTS);
3816 const GrowableObjectArray& interfaces = 3786 const GrowableObjectArray& interfaces =
3817 GrowableObjectArray::Handle(GrowableObjectArray::New()); 3787 GrowableObjectArray::Handle(GrowableObjectArray::New());
3818 String& interface_name = String::Handle(); 3788 String& interface_name = String::Handle();
3819 AbstractType& interface = AbstractType::Handle(); 3789 AbstractType& interface = AbstractType::Handle();
3820 String& other_name = String::Handle(); 3790 String& other_name = String::Handle();
3821 AbstractType& other_interface = AbstractType::Handle(); 3791 AbstractType& other_interface = AbstractType::Handle();
3822 const String& super_type_name = String::Handle(super_type.Name()); 3792 const String& super_type_name = String::Handle(super_type.Name());
3823 do { 3793 do {
(...skipping 15 matching lines...) Expand all
3839 ErrorMsg(interface_pos, "duplicate interface '%s'", 3809 ErrorMsg(interface_pos, "duplicate interface '%s'",
3840 interface_name.ToCString()); 3810 interface_name.ToCString());
3841 } 3811 }
3842 } 3812 }
3843 interfaces.Add(interface); 3813 interfaces.Add(interface);
3844 } while (CurrentToken() == Token::kCOMMA); 3814 } while (CurrentToken() == Token::kCOMMA);
3845 return Array::MakeArray(interfaces); 3815 return Array::MakeArray(interfaces);
3846 } 3816 }
3847 3817
3848 3818
3849 RawType* Parser::ParseMixins(const Type& super_type) { 3819 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
3850 TRACE_PARSER("ParseMixins"); 3820 TRACE_PARSER("ParseMixins");
3851 ASSERT(CurrentToken() == Token::kWITH); 3821 ASSERT(CurrentToken() == Token::kWITH);
3852 3822
3853 // TODO(hausner): Remove this restriction. 3823 const GrowableObjectArray& mixin_apps =
3854 if (super_type.arguments() != AbstractTypeArguments::null()) { 3824 GrowableObjectArray::Handle(GrowableObjectArray::New());
3855 ErrorMsg(super_type.token_pos(),
3856 "super class in mixin application may not have type arguments");
3857 }
3858
3859 AbstractType& mixin_type = AbstractType::Handle(); 3825 AbstractType& mixin_type = AbstractType::Handle();
3860 AbstractTypeArguments& mixin_type_arguments = 3826 AbstractTypeArguments& mixin_type_arguments =
3861 AbstractTypeArguments::Handle(); 3827 AbstractTypeArguments::Handle();
3862 Class& mixin_application = Class::Handle(); 3828 Class& mixin_application = Class::Handle();
3863 Type& mixin_application_type = Type::Handle(); 3829 Type& mixin_application_type = Type::Handle();
3864 Type& mixin_super_type = Type::Handle(super_type.raw()); 3830 Type& mixin_super_type = Type::Handle();
3831 ASSERT(super_type.IsType());
3832 mixin_super_type ^= super_type.raw();
3865 Array& mixin_application_interfaces = Array::Handle(); 3833 Array& mixin_application_interfaces = Array::Handle();
3866 do { 3834 do {
3867 ConsumeToken(); 3835 ConsumeToken();
3868 const intptr_t mixin_pos = TokenPos(); 3836 const intptr_t mixin_pos = TokenPos();
3869 mixin_type = ParseType(ClassFinalizer::kTryResolve); 3837 mixin_type = ParseType(ClassFinalizer::kTryResolve);
3870 if (mixin_type.IsTypeParameter()) { 3838 if (mixin_type.IsTypeParameter()) {
3871 ErrorMsg(mixin_pos, 3839 ErrorMsg(mixin_pos,
3872 "mixin type '%s' may not be a type parameter", 3840 "mixin type '%s' may not be a type parameter",
3873 String::Handle(mixin_type.UserVisibleName()).ToCString()); 3841 String::Handle(mixin_type.UserVisibleName()).ToCString());
3874 } 3842 }
(...skipping 23 matching lines...) Expand all
3898 // to get the copy is to rewind the parser, parse the mixin type 3866 // to get the copy is to rewind the parser, parse the mixin type
3899 // again and steal its type arguments. 3867 // again and steal its type arguments.
3900 SetPosition(mixin_pos); 3868 SetPosition(mixin_pos);
3901 mixin_type = ParseType(ClassFinalizer::kTryResolve); 3869 mixin_type = ParseType(ClassFinalizer::kTryResolve);
3902 mixin_type_arguments = mixin_type.arguments(); 3870 mixin_type_arguments = mixin_type.arguments();
3903 3871
3904 mixin_application_type = Type::New(mixin_application, 3872 mixin_application_type = Type::New(mixin_application,
3905 mixin_type_arguments, 3873 mixin_type_arguments,
3906 mixin_pos); 3874 mixin_pos);
3907 mixin_super_type = mixin_application_type.raw(); 3875 mixin_super_type = mixin_application_type.raw();
3876 mixin_apps.Add(mixin_application_type);
3908 } while (CurrentToken() == Token::kCOMMA); 3877 } while (CurrentToken() == Token::kCOMMA);
3909 return mixin_application_type.raw(); 3878 return MixinAppType::New(super_type,
3879 Array::Handle(Array::MakeArray(mixin_apps)));
3910 } 3880 }
3911 3881
3912 3882
3913 // Add 'interface' to 'interface_list' if it is not already in the list. 3883 // Add 'interface' to 'interface_list' if it is not already in the list.
3914 // An error is reported if the interface conflicts with an interface already in 3884 // An error is reported if the interface conflicts with an interface already in
3915 // the list with the same class and same type arguments. 3885 // the list with the same class and same type arguments.
3916 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, 3886 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos,
3917 const GrowableObjectArray& interface_list, 3887 const GrowableObjectArray& interface_list,
3918 const AbstractType& interface) { 3888 const AbstractType& interface) {
3919 String& interface_name = String::Handle(interface.Name()); 3889 String& interface_name = String::Handle(interface.Name());
(...skipping 6149 matching lines...) Expand 10 before | Expand all | Expand 10 after
10069 void Parser::SkipQualIdent() { 10039 void Parser::SkipQualIdent() {
10070 ASSERT(IsIdentifier()); 10040 ASSERT(IsIdentifier());
10071 ConsumeToken(); 10041 ConsumeToken();
10072 if (CurrentToken() == Token::kPERIOD) { 10042 if (CurrentToken() == Token::kPERIOD) {
10073 ConsumeToken(); // Consume the kPERIOD token. 10043 ConsumeToken(); // Consume the kPERIOD token.
10074 ExpectIdentifier("identifier expected after '.'"); 10044 ExpectIdentifier("identifier expected after '.'");
10075 } 10045 }
10076 } 10046 }
10077 10047
10078 } // namespace dart 10048 } // 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