| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 3397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3408 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); | 3408 const Object& obj = Object::Handle(library_.LookupLocalObject(class_name)); |
| 3409 if (!obj.IsNull()) { | 3409 if (!obj.IsNull()) { |
| 3410 ErrorMsg(classname_pos, "'%s' is already defined", | 3410 ErrorMsg(classname_pos, "'%s' is already defined", |
| 3411 class_name.ToCString()); | 3411 class_name.ToCString()); |
| 3412 } | 3412 } |
| 3413 const Class& mixin_application = | 3413 const Class& mixin_application = |
| 3414 Class::Handle(Class::New(class_name, script_, classname_pos)); | 3414 Class::Handle(Class::New(class_name, script_, classname_pos)); |
| 3415 library_.AddClass(mixin_application); | 3415 library_.AddClass(mixin_application); |
| 3416 set_current_class(mixin_application); | 3416 set_current_class(mixin_application); |
| 3417 ParseTypeParameters(mixin_application); | 3417 ParseTypeParameters(mixin_application); |
| 3418 |
| 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 |
| 3418 ExpectToken(Token::kASSIGN); | 3425 ExpectToken(Token::kASSIGN); |
| 3419 | 3426 |
| 3420 if (CurrentToken() == Token::kABSTRACT) { | 3427 if (CurrentToken() == Token::kABSTRACT) { |
| 3421 mixin_application.set_is_abstract(); | 3428 mixin_application.set_is_abstract(); |
| 3422 ConsumeToken(); | 3429 ConsumeToken(); |
| 3423 } | 3430 } |
| 3424 | 3431 |
| 3425 const intptr_t supertype_pos = TokenPos(); | 3432 const intptr_t supertype_pos = TokenPos(); |
| 3426 const AbstractType& type = | 3433 const AbstractType& type = |
| 3427 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve)); | 3434 AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve)); |
| 3428 if (type.IsTypeParameter()) { | 3435 if (type.IsTypeParameter()) { |
| 3429 ErrorMsg(supertype_pos, | 3436 ErrorMsg(supertype_pos, |
| 3430 "class '%s' may not extend type parameter '%s'", | 3437 "class '%s' may not extend type parameter '%s'", |
| 3431 class_name.ToCString(), | 3438 class_name.ToCString(), |
| 3432 String::Handle(type.UserVisibleName()).ToCString()); | 3439 String::Handle(type.UserVisibleName()).ToCString()); |
| 3433 } | 3440 } |
| 3434 Type& mixin_super_type = Type::Handle(); | 3441 Type& mixin_super_type = Type::Handle(); |
| 3435 mixin_super_type ^= type.raw(); | 3442 mixin_super_type ^= type.raw(); |
| 3436 | 3443 |
| 3437 if (CurrentToken() != Token::kWITH) { | 3444 if (CurrentToken() != Token::kWITH) { |
| 3438 ErrorMsg("mixin application 'with Type' expected"); | 3445 ErrorMsg("mixin application 'with Type' expected"); |
| 3439 } | 3446 } |
| 3440 | 3447 |
| 3441 Type& mixin_application_type = Type::Handle(ParseMixins(mixin_super_type)); | 3448 const Type& mixin_application_type = |
| 3442 // The result of ParseMixins() is a chain of super classes that is the | 3449 Type::Handle(ParseMixins(mixin_super_type)); |
| 3450 // TODO(hausner): Implement generic mixin support. |
| 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 |
| 3456 // The result of ParseMixins() is a chain of super types that is the |
| 3443 // result of the mixin composition 'S with M1, M2, ...'. The mixin | 3457 // result of the mixin composition 'S with M1, M2, ...'. The mixin |
| 3444 // application classes are anonymous (i.e. not registered in the current | 3458 // application classes are anonymous (i.e. not registered in the current |
| 3445 // library). We steal the super type and mixin type from the bottom of | 3459 // library). We steal the super type and mixin type from the bottom of |
| 3446 // the chain and add it to the named mixin application class. The bottom | 3460 // the chain and add it to the named mixin application class. The bottom |
| 3447 // anonymous class in the chain is thrown away. | 3461 // anonymous class in the chain is thrown away. |
| 3448 const Class& anon_mixin_app_class = | 3462 const Class& anon_mixin_app_class = |
| 3449 Class::Handle(mixin_application_type.type_class()); | 3463 Class::Handle(mixin_application_type.type_class()); |
| 3450 mixin_application.set_super_type( | 3464 mixin_application.set_super_type( |
| 3451 Type::Handle(anon_mixin_app_class.super_type())); | 3465 Type::Handle(anon_mixin_app_class.super_type())); |
| 3452 mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin())); | 3466 mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin())); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3841 "super class of mixin may not have type arguments"); | 3855 "super class of mixin may not have type arguments"); |
| 3842 } | 3856 } |
| 3843 | 3857 |
| 3844 AbstractType& mixin_type = AbstractType::Handle(); | 3858 AbstractType& mixin_type = AbstractType::Handle(); |
| 3845 AbstractTypeArguments& mixin_type_arguments = | 3859 AbstractTypeArguments& mixin_type_arguments = |
| 3846 AbstractTypeArguments::Handle(); | 3860 AbstractTypeArguments::Handle(); |
| 3847 Class& mixin_application = Class::Handle(); | 3861 Class& mixin_application = Class::Handle(); |
| 3848 Type& mixin_application_type = Type::Handle(); | 3862 Type& mixin_application_type = Type::Handle(); |
| 3849 Type& mixin_super_type = Type::Handle(super_type.raw()); | 3863 Type& mixin_super_type = Type::Handle(super_type.raw()); |
| 3850 Array& mixin_application_interfaces = Array::Handle(); | 3864 Array& mixin_application_interfaces = Array::Handle(); |
| 3851 const TypeArguments& no_type_arguments = TypeArguments::Handle(); | |
| 3852 do { | 3865 do { |
| 3853 ConsumeToken(); | 3866 ConsumeToken(); |
| 3854 const intptr_t mixin_pos = TokenPos(); | 3867 const intptr_t mixin_pos = TokenPos(); |
| 3855 mixin_type = ParseType(ClassFinalizer::kTryResolve); | 3868 mixin_type = ParseType(ClassFinalizer::kTryResolve); |
| 3856 if (mixin_type.IsTypeParameter()) { | 3869 if (mixin_type.IsTypeParameter()) { |
| 3857 ErrorMsg(mixin_pos, | 3870 ErrorMsg(mixin_pos, |
| 3858 "mixin type '%s' may not be a type parameter", | 3871 "mixin type '%s' may not be a type parameter", |
| 3859 String::Handle(mixin_type.UserVisibleName()).ToCString()); | 3872 String::Handle(mixin_type.UserVisibleName()).ToCString()); |
| 3860 } | 3873 } |
| 3861 // TODO(hausner): Remove this check once we handle mixins with type | |
| 3862 // arguments. | |
| 3863 mixin_type_arguments = mixin_type.arguments(); | |
| 3864 if (!mixin_type_arguments.IsNull()) { | |
| 3865 ErrorMsg(mixin_pos, | |
| 3866 "mixin type '%s' may not have type arguments", | |
| 3867 String::Handle(mixin_type.UserVisibleName()).ToCString()); | |
| 3868 } | |
| 3869 | 3874 |
| 3870 // The name of the mixin application class is a combination of | 3875 // The name of the mixin application class is a combination of |
| 3871 // the superclass and mixin class. | 3876 // the superclass and mixin class. |
| 3872 String& mixin_app_name = String::Handle(); | 3877 String& mixin_app_name = String::Handle(); |
| 3873 mixin_app_name = mixin_super_type.Name(); | 3878 mixin_app_name = mixin_super_type.Name(); |
| 3874 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand()); | 3879 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand()); |
| 3875 mixin_app_name = String::Concat(mixin_app_name, | 3880 mixin_app_name = String::Concat(mixin_app_name, |
| 3876 String::Handle(mixin_type.Name())); | 3881 String::Handle(mixin_type.Name())); |
| 3877 mixin_app_name = Symbols::New(mixin_app_name); | 3882 mixin_app_name = Symbols::New(mixin_app_name); |
| 3878 | 3883 |
| 3879 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); | 3884 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); |
| 3880 mixin_application.set_super_type(mixin_super_type); | 3885 mixin_application.set_super_type(mixin_super_type); |
| 3881 mixin_application.set_mixin(Type::Cast(mixin_type)); | 3886 mixin_application.set_mixin(Type::Cast(mixin_type)); |
| 3882 mixin_application.set_library(library_); | 3887 mixin_application.set_library(library_); |
| 3883 AddImplicitConstructor(mixin_application); | 3888 AddImplicitConstructor(mixin_application); |
| 3884 // Add the mixin type to the interfaces that the mixin application | 3889 // Add the mixin type to the interfaces that the mixin application |
| 3885 // class implements. This is necessary so that type tests work. | 3890 // class implements. This is necessary so that type tests work. |
| 3886 mixin_application_interfaces = Array::New(1); | 3891 mixin_application_interfaces = Array::New(1); |
| 3887 mixin_application_interfaces.SetAt(0, mixin_type); | 3892 mixin_application_interfaces.SetAt(0, mixin_type); |
| 3888 mixin_application.set_interfaces(mixin_application_interfaces); | 3893 mixin_application.set_interfaces(mixin_application_interfaces); |
| 3889 | 3894 |
| 3890 // TODO(hausner): Need to support type arguments. | 3895 // For the type arguments of the mixin application type, we need |
| 3896 // a copy of the type arguments to the mixin type. The simplest way |
| 3897 // to get the copy is to rewind the parser, parse the mixin type |
| 3898 // again and steal its type arguments. |
| 3899 SetPosition(mixin_pos); |
| 3900 mixin_type = ParseType(ClassFinalizer::kTryResolve); |
| 3901 mixin_type_arguments = mixin_type.arguments(); |
| 3902 |
| 3891 mixin_application_type = Type::New(mixin_application, | 3903 mixin_application_type = Type::New(mixin_application, |
| 3892 no_type_arguments, | 3904 mixin_type_arguments, |
| 3893 Scanner::kDummyTokenIndex); | 3905 mixin_pos); |
| 3894 mixin_super_type = mixin_application_type.raw(); | 3906 mixin_super_type = mixin_application_type.raw(); |
| 3895 } while (CurrentToken() == Token::kCOMMA); | 3907 } while (CurrentToken() == Token::kCOMMA); |
| 3896 return mixin_application_type.raw(); | 3908 return mixin_application_type.raw(); |
| 3897 } | 3909 } |
| 3898 | 3910 |
| 3899 | 3911 |
| 3900 // Add 'interface' to 'interface_list' if it is not already in the list. | 3912 // Add 'interface' to 'interface_list' if it is not already in the list. |
| 3901 // An error is reported if the interface conflicts with an interface already in | 3913 // An error is reported if the interface conflicts with an interface already in |
| 3902 // the list with the same class and same type arguments. | 3914 // the list with the same class and same type arguments. |
| 3903 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, | 3915 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, |
| (...skipping 6149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10053 void Parser::SkipQualIdent() { | 10065 void Parser::SkipQualIdent() { |
| 10054 ASSERT(IsIdentifier()); | 10066 ASSERT(IsIdentifier()); |
| 10055 ConsumeToken(); | 10067 ConsumeToken(); |
| 10056 if (CurrentToken() == Token::kPERIOD) { | 10068 if (CurrentToken() == Token::kPERIOD) { |
| 10057 ConsumeToken(); // Consume the kPERIOD token. | 10069 ConsumeToken(); // Consume the kPERIOD token. |
| 10058 ExpectIdentifier("identifier expected after '.'"); | 10070 ExpectIdentifier("identifier expected after '.'"); |
| 10059 } | 10071 } |
| 10060 } | 10072 } |
| 10061 | 10073 |
| 10062 } // namespace dart | 10074 } // namespace dart |
| OLD | NEW |