| 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 3248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3259 super_type = ParseMixins(super_type); | 3259 super_type = ParseMixins(super_type); |
| 3260 } | 3260 } |
| 3261 } else { | 3261 } else { |
| 3262 // No extends clause: implicitly extend Object. | 3262 // No extends clause: implicitly extend Object. |
| 3263 super_type = Type::ObjectType(); | 3263 super_type = Type::ObjectType(); |
| 3264 } | 3264 } |
| 3265 ASSERT(!super_type.IsNull()); | 3265 ASSERT(!super_type.IsNull()); |
| 3266 cls.set_super_type(super_type); | 3266 cls.set_super_type(super_type); |
| 3267 | 3267 |
| 3268 if (CurrentToken() == Token::kIMPLEMENTS) { | 3268 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3269 Array& interfaces = Array::Handle(); | 3269 ParseInterfaceList(cls); |
| 3270 const intptr_t interfaces_pos = TokenPos(); | |
| 3271 interfaces = ParseInterfaceList(super_type); | |
| 3272 AddInterfaces(interfaces_pos, cls, interfaces); | |
| 3273 } | 3270 } |
| 3274 | 3271 |
| 3275 ExpectToken(Token::kLBRACE); | 3272 ExpectToken(Token::kLBRACE); |
| 3276 ClassDesc members(cls, class_name, false, class_pos); | 3273 ClassDesc members(cls, class_name, false, class_pos); |
| 3277 while (CurrentToken() != Token::kRBRACE) { | 3274 while (CurrentToken() != Token::kRBRACE) { |
| 3278 SkipMetadata(); | 3275 SkipMetadata(); |
| 3279 ParseClassMemberDefinition(&members); | 3276 ParseClassMemberDefinition(&members); |
| 3280 } | 3277 } |
| 3281 ExpectToken(Token::kRBRACE); | 3278 ExpectToken(Token::kRBRACE); |
| 3282 | 3279 |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3435 ErrorMsg("mixin application 'with Type' expected"); | 3432 ErrorMsg("mixin application 'with Type' expected"); |
| 3436 } | 3433 } |
| 3437 type = ParseMixins(type); | 3434 type = ParseMixins(type); |
| 3438 | 3435 |
| 3439 // TODO(hausner): treat the mixin application as an alias, not as a base | 3436 // TODO(hausner): treat the mixin application as an alias, not as a base |
| 3440 // class whose super class is the mixin application! | 3437 // class whose super class is the mixin application! |
| 3441 mixin_application.set_super_type(type); | 3438 mixin_application.set_super_type(type); |
| 3442 | 3439 |
| 3443 AddImplicitConstructor(mixin_application); | 3440 AddImplicitConstructor(mixin_application); |
| 3444 if (CurrentToken() == Token::kIMPLEMENTS) { | 3441 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3445 Array& interfaces = Array::Handle(); | 3442 ParseInterfaceList(mixin_application); |
| 3446 const intptr_t interfaces_pos = TokenPos(); | |
| 3447 interfaces = ParseInterfaceList(type); | |
| 3448 AddInterfaces(interfaces_pos, mixin_application, interfaces); | |
| 3449 } | 3443 } |
| 3450 ExpectSemicolon(); | 3444 ExpectSemicolon(); |
| 3451 pending_classes.Add(mixin_application, Heap::kOld); | 3445 pending_classes.Add(mixin_application, Heap::kOld); |
| 3452 } | 3446 } |
| 3453 | 3447 |
| 3454 | 3448 |
| 3455 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 3449 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 3456 // We need this lookahead to distinguish between the optional return type | 3450 // We need this lookahead to distinguish between the optional return type |
| 3457 // and the alias name of a function type alias. | 3451 // and the alias name of a function type alias. |
| 3458 // Token position remains unchanged. | 3452 // Token position remains unchanged. |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3772 ErrorMsg("right angle bracket expected"); | 3766 ErrorMsg("right angle bracket expected"); |
| 3773 } | 3767 } |
| 3774 if (finalization != ClassFinalizer::kIgnore) { | 3768 if (finalization != ClassFinalizer::kIgnore) { |
| 3775 return NewTypeArguments(types); | 3769 return NewTypeArguments(types); |
| 3776 } | 3770 } |
| 3777 } | 3771 } |
| 3778 return TypeArguments::null(); | 3772 return TypeArguments::null(); |
| 3779 } | 3773 } |
| 3780 | 3774 |
| 3781 | 3775 |
| 3782 // Parse and return an array of interface types. | 3776 // Parse interface list and add to class cls. |
| 3783 RawArray* Parser::ParseInterfaceList(const AbstractType& super_type) { | 3777 void Parser::ParseInterfaceList(const Class& cls) { |
| 3784 TRACE_PARSER("ParseInterfaceList"); | 3778 TRACE_PARSER("ParseInterfaceList"); |
| 3785 ASSERT(CurrentToken() == Token::kIMPLEMENTS); | 3779 ASSERT(CurrentToken() == Token::kIMPLEMENTS); |
| 3786 const GrowableObjectArray& interfaces = | 3780 const GrowableObjectArray& all_interfaces = |
| 3787 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3781 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3788 String& interface_name = String::Handle(); | |
| 3789 AbstractType& interface = AbstractType::Handle(); | 3782 AbstractType& interface = AbstractType::Handle(); |
| 3790 String& other_name = String::Handle(); | 3783 // First get all the interfaces already implemented by class. |
| 3791 AbstractType& other_interface = AbstractType::Handle(); | 3784 Array& cls_interfaces = Array::Handle(cls.interfaces()); |
| 3792 const String& super_type_name = String::Handle(super_type.Name()); | 3785 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { |
| 3786 interface ^= cls_interfaces.At(i); |
| 3787 all_interfaces.Add(interface); |
| 3788 } |
| 3789 // Now parse and add the new interfaces. |
| 3793 do { | 3790 do { |
| 3794 ConsumeToken(); | 3791 ConsumeToken(); |
| 3795 intptr_t interface_pos = TokenPos(); | 3792 intptr_t interface_pos = TokenPos(); |
| 3796 interface = ParseType(ClassFinalizer::kTryResolve); | 3793 interface = ParseType(ClassFinalizer::kTryResolve); |
| 3797 interface_name = interface.UserVisibleName(); | 3794 if (interface.IsTypeParameter()) { |
| 3798 if (interface_name.Equals(super_type_name)) { | 3795 ErrorMsg(interface_pos, |
| 3799 // TODO(hausner): I think this check is not necessary. There is | 3796 "type parameter '%s' may not be used in interface list", |
| 3800 // no such restriction. If the check is removed, the 'super_type' | 3797 String::Handle(interface.UserVisibleName()).ToCString()); |
| 3801 // parameter to this function can be eliminated. | |
| 3802 ErrorMsg(interface_pos, "class may not extend and implement '%s'", | |
| 3803 interface_name.ToCString()); | |
| 3804 } | 3798 } |
| 3805 for (int i = 0; i < interfaces.Length(); i++) { | 3799 all_interfaces.Add(interface); |
| 3806 other_interface ^= interfaces.At(i); | |
| 3807 other_name = other_interface.Name(); | |
| 3808 if (interface_name.Equals(other_name)) { | |
| 3809 ErrorMsg(interface_pos, "duplicate interface '%s'", | |
| 3810 interface_name.ToCString()); | |
| 3811 } | |
| 3812 } | |
| 3813 interfaces.Add(interface); | |
| 3814 } while (CurrentToken() == Token::kCOMMA); | 3800 } while (CurrentToken() == Token::kCOMMA); |
| 3815 return Array::MakeArray(interfaces); | 3801 cls_interfaces = Array::MakeArray(all_interfaces); |
| 3802 cls.set_interfaces(cls_interfaces); |
| 3816 } | 3803 } |
| 3817 | 3804 |
| 3818 | 3805 |
| 3819 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 3806 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
| 3820 TRACE_PARSER("ParseMixins"); | 3807 TRACE_PARSER("ParseMixins"); |
| 3821 ASSERT(CurrentToken() == Token::kWITH); | 3808 ASSERT(CurrentToken() == Token::kWITH); |
| 3822 | 3809 |
| 3823 const GrowableObjectArray& mixin_apps = | 3810 const GrowableObjectArray& mixin_apps = |
| 3824 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 3811 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 3825 AbstractType& mixin_type = AbstractType::Handle(); | 3812 AbstractType& mixin_type = AbstractType::Handle(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3873 mixin_type_arguments, | 3860 mixin_type_arguments, |
| 3874 mixin_pos); | 3861 mixin_pos); |
| 3875 mixin_super_type = mixin_application_type.raw(); | 3862 mixin_super_type = mixin_application_type.raw(); |
| 3876 mixin_apps.Add(mixin_application_type); | 3863 mixin_apps.Add(mixin_application_type); |
| 3877 } while (CurrentToken() == Token::kCOMMA); | 3864 } while (CurrentToken() == Token::kCOMMA); |
| 3878 return MixinAppType::New(super_type, | 3865 return MixinAppType::New(super_type, |
| 3879 Array::Handle(Array::MakeArray(mixin_apps))); | 3866 Array::Handle(Array::MakeArray(mixin_apps))); |
| 3880 } | 3867 } |
| 3881 | 3868 |
| 3882 | 3869 |
| 3883 // Add 'interface' to 'interface_list' if it is not already in the list. | |
| 3884 // An error is reported if the interface conflicts with an interface already in | |
| 3885 // the list with the same class and same type arguments. | |
| 3886 void Parser::AddInterfaceIfUnique(intptr_t interfaces_pos, | |
| 3887 const GrowableObjectArray& interface_list, | |
| 3888 const AbstractType& interface) { | |
| 3889 String& interface_name = String::Handle(interface.Name()); | |
| 3890 String& existing_interface_name = String::Handle(); | |
| 3891 AbstractType& other_interface = AbstractType::Handle(); | |
| 3892 for (intptr_t i = 0; i < interface_list.Length(); i++) { | |
| 3893 other_interface ^= interface_list.At(i); | |
| 3894 existing_interface_name = other_interface.Name(); | |
| 3895 if (interface_name.Equals(existing_interface_name)) { | |
| 3896 return; | |
| 3897 } | |
| 3898 } | |
| 3899 interface_list.Add(interface); | |
| 3900 } | |
| 3901 | |
| 3902 | |
| 3903 void Parser::AddInterfaces(intptr_t interfaces_pos, | |
| 3904 const Class& cls, | |
| 3905 const Array& interfaces) { | |
| 3906 const GrowableObjectArray& all_interfaces = | |
| 3907 GrowableObjectArray::Handle(GrowableObjectArray::New()); | |
| 3908 AbstractType& interface = AbstractType::Handle(); | |
| 3909 // First get all the interfaces already implemented by class. | |
| 3910 Array& cls_interfaces = Array::Handle(cls.interfaces()); | |
| 3911 for (intptr_t i = 0; i < cls_interfaces.Length(); i++) { | |
| 3912 interface ^= cls_interfaces.At(i); | |
| 3913 all_interfaces.Add(interface); | |
| 3914 } | |
| 3915 // Now add the new interfaces. | |
| 3916 for (intptr_t i = 0; i < interfaces.Length(); i++) { | |
| 3917 AbstractType& interface = AbstractType::ZoneHandle(); | |
| 3918 interface ^= interfaces.At(i); | |
| 3919 if (interface.IsTypeParameter()) { | |
| 3920 ErrorMsg(interfaces_pos, | |
| 3921 "class '%s' may not implement type parameter '%s'", | |
| 3922 String::Handle(cls.Name()).ToCString(), | |
| 3923 String::Handle(interface.UserVisibleName()).ToCString()); | |
| 3924 } | |
| 3925 AddInterfaceIfUnique(interfaces_pos, all_interfaces, interface); | |
| 3926 } | |
| 3927 cls_interfaces = Array::MakeArray(all_interfaces); | |
| 3928 cls.set_interfaces(cls_interfaces); | |
| 3929 } | |
| 3930 | |
| 3931 | |
| 3932 void Parser::ParseTopLevelVariable(TopLevel* top_level) { | 3870 void Parser::ParseTopLevelVariable(TopLevel* top_level) { |
| 3933 TRACE_PARSER("ParseTopLevelVariable"); | 3871 TRACE_PARSER("ParseTopLevelVariable"); |
| 3934 const bool is_const = (CurrentToken() == Token::kCONST); | 3872 const bool is_const = (CurrentToken() == Token::kCONST); |
| 3935 // Const fields are implicitly final. | 3873 // Const fields are implicitly final. |
| 3936 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 3874 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 3937 const bool is_static = true; | 3875 const bool is_static = true; |
| 3938 const AbstractType& type = | 3876 const AbstractType& type = |
| 3939 AbstractType::ZoneHandle(ParseConstFinalVarOrType( | 3877 AbstractType::ZoneHandle(ParseConstFinalVarOrType( |
| 3940 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : | 3878 FLAG_enable_type_checks ? ClassFinalizer::kTryResolve : |
| 3941 ClassFinalizer::kIgnore)); | 3879 ClassFinalizer::kIgnore)); |
| (...skipping 6097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10039 void Parser::SkipQualIdent() { | 9977 void Parser::SkipQualIdent() { |
| 10040 ASSERT(IsIdentifier()); | 9978 ASSERT(IsIdentifier()); |
| 10041 ConsumeToken(); | 9979 ConsumeToken(); |
| 10042 if (CurrentToken() == Token::kPERIOD) { | 9980 if (CurrentToken() == Token::kPERIOD) { |
| 10043 ConsumeToken(); // Consume the kPERIOD token. | 9981 ConsumeToken(); // Consume the kPERIOD token. |
| 10044 ExpectIdentifier("identifier expected after '.'"); | 9982 ExpectIdentifier("identifier expected after '.'"); |
| 10045 } | 9983 } |
| 10046 } | 9984 } |
| 10047 | 9985 |
| 10048 } // namespace dart | 9986 } // namespace dart |
| OLD | NEW |