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 3226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |