| 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 |