Chromium Code Reviews| 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/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 3570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3581 ConsumeToken(); | 3581 ConsumeToken(); |
| 3582 const intptr_t type_pos = TokenPos(); | 3582 const intptr_t type_pos = TokenPos(); |
| 3583 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 3583 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 3584 if (super_type.IsTypeParameter()) { | 3584 if (super_type.IsTypeParameter()) { |
| 3585 ErrorMsg(type_pos, | 3585 ErrorMsg(type_pos, |
| 3586 "class '%s' may not extend type parameter '%s'", | 3586 "class '%s' may not extend type parameter '%s'", |
| 3587 class_name.ToCString(), | 3587 class_name.ToCString(), |
| 3588 String::Handle(super_type.UserVisibleName()).ToCString()); | 3588 String::Handle(super_type.UserVisibleName()).ToCString()); |
| 3589 } | 3589 } |
| 3590 if (CurrentToken() == Token::kWITH) { | 3590 if (CurrentToken() == Token::kWITH) { |
| 3591 super_type = ParseMixins(super_type); | 3591 super_type = ParseMixins(super_type, Class::Handle()); |
| 3592 } | 3592 } |
| 3593 } else { | 3593 } else { |
| 3594 // No extends clause: implicitly extend Object, unless Object itself. | 3594 // No extends clause: implicitly extend Object, unless Object itself. |
| 3595 if (!cls.IsObjectClass()) { | 3595 if (!cls.IsObjectClass()) { |
| 3596 super_type = Type::ObjectType(); | 3596 super_type = Type::ObjectType(); |
| 3597 } | 3597 } |
| 3598 } | 3598 } |
| 3599 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); | 3599 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); |
| 3600 cls.set_super_type(super_type); | 3600 cls.set_super_type(super_type); |
| 3601 | 3601 |
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3788 if (type.IsTypeParameter()) { | 3788 if (type.IsTypeParameter()) { |
| 3789 ErrorMsg(type_pos, | 3789 ErrorMsg(type_pos, |
| 3790 "class '%s' may not extend type parameter '%s'", | 3790 "class '%s' may not extend type parameter '%s'", |
| 3791 class_name.ToCString(), | 3791 class_name.ToCString(), |
| 3792 String::Handle(type.UserVisibleName()).ToCString()); | 3792 String::Handle(type.UserVisibleName()).ToCString()); |
| 3793 } | 3793 } |
| 3794 | 3794 |
| 3795 if (CurrentToken() != Token::kWITH) { | 3795 if (CurrentToken() != Token::kWITH) { |
| 3796 ErrorMsg("mixin application 'with Type' expected"); | 3796 ErrorMsg("mixin application 'with Type' expected"); |
| 3797 } | 3797 } |
| 3798 type = ParseMixins(type); | 3798 type = ParseMixins(type, mixin_application); |
| 3799 | |
| 3800 // TODO(hausner): treat the mixin application as an alias, not as a base | |
| 3801 // class whose super class is the mixin application! | |
| 3802 mixin_application.set_super_type(type); | |
| 3803 mixin_application.set_is_synthesized_class(); | |
| 3804 | 3799 |
| 3805 // This mixin application typedef needs an implicit constructor, but it is | 3800 // This mixin application typedef needs an implicit constructor, but it is |
| 3806 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 3801 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| 3807 // because this class should be lazily compiled. | 3802 // because this class should be lazily compiled. |
| 3808 if (CurrentToken() == Token::kIMPLEMENTS) { | 3803 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3809 ParseInterfaceList(mixin_application); | 3804 ParseInterfaceList(mixin_application); |
|
regis
2013/08/20 18:56:37
At this point, the mixin_application alias already
| |
| 3810 } | 3805 } |
| 3811 ExpectSemicolon(); | 3806 ExpectSemicolon(); |
| 3812 pending_classes.Add(mixin_application, Heap::kOld); | 3807 pending_classes.Add(mixin_application, Heap::kOld); |
| 3813 } | 3808 } |
| 3814 | 3809 |
| 3815 | 3810 |
| 3816 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". | 3811 // Look ahead to detect if we are seeing ident [ TypeParameters ] "(". |
| 3817 // We need this lookahead to distinguish between the optional return type | 3812 // We need this lookahead to distinguish between the optional return type |
| 3818 // and the alias name of a function type alias. | 3813 // and the alias name of a function type alias. |
| 3819 // Token position remains unchanged. | 3814 // Token position remains unchanged. |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4160 "type parameter '%s' may not be used in interface list", | 4155 "type parameter '%s' may not be used in interface list", |
| 4161 String::Handle(interface.UserVisibleName()).ToCString()); | 4156 String::Handle(interface.UserVisibleName()).ToCString()); |
| 4162 } | 4157 } |
| 4163 all_interfaces.Add(interface); | 4158 all_interfaces.Add(interface); |
| 4164 } while (CurrentToken() == Token::kCOMMA); | 4159 } while (CurrentToken() == Token::kCOMMA); |
| 4165 cls_interfaces = Array::MakeArray(all_interfaces); | 4160 cls_interfaces = Array::MakeArray(all_interfaces); |
| 4166 cls.set_interfaces(cls_interfaces); | 4161 cls.set_interfaces(cls_interfaces); |
| 4167 } | 4162 } |
| 4168 | 4163 |
| 4169 | 4164 |
| 4170 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 4165 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type, |
| 4166 const Class& final_mixin_application) { | |
| 4171 TRACE_PARSER("ParseMixins"); | 4167 TRACE_PARSER("ParseMixins"); |
| 4172 ASSERT(CurrentToken() == Token::kWITH); | 4168 ASSERT(CurrentToken() == Token::kWITH); |
| 4173 | 4169 |
| 4174 const GrowableObjectArray& mixin_apps = | 4170 const GrowableObjectArray& mixin_apps = |
| 4175 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4171 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 4176 AbstractType& mixin_type = AbstractType::Handle(); | 4172 AbstractType& mixin_type = AbstractType::Handle(); |
| 4177 AbstractTypeArguments& mixin_type_arguments = | 4173 AbstractTypeArguments& mixin_type_arguments = |
| 4178 AbstractTypeArguments::Handle(); | 4174 AbstractTypeArguments::Handle(); |
| 4179 Class& mixin_application = Class::Handle(); | 4175 Class& mixin_application = Class::Handle(); |
| 4180 Type& mixin_application_type = Type::Handle(); | 4176 Type& mixin_application_type = Type::Handle(); |
| 4181 Type& mixin_super_type = Type::Handle(); | 4177 Type& mixin_super_type = Type::Handle(); |
| 4182 ASSERT(super_type.IsType()); | 4178 ASSERT(super_type.IsType()); |
| 4183 mixin_super_type ^= super_type.raw(); | 4179 mixin_super_type ^= super_type.raw(); |
| 4184 Array& mixin_application_interfaces = Array::Handle(); | 4180 Array& mixin_application_interfaces = Array::Handle(); |
| 4185 do { | 4181 do { |
| 4186 ConsumeToken(); | 4182 ConsumeToken(); |
| 4187 const intptr_t mixin_pos = TokenPos(); | 4183 const intptr_t mixin_pos = TokenPos(); |
| 4188 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4184 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4189 if (mixin_type.IsTypeParameter()) { | 4185 if (mixin_type.IsTypeParameter()) { |
| 4190 ErrorMsg(mixin_pos, | 4186 ErrorMsg(mixin_pos, |
| 4191 "mixin type '%s' may not be a type parameter", | 4187 "mixin type '%s' may not be a type parameter", |
| 4192 String::Handle(mixin_type.UserVisibleName()).ToCString()); | 4188 String::Handle(mixin_type.UserVisibleName()).ToCString()); |
| 4193 } | 4189 } |
| 4194 | 4190 |
| 4195 // The name of the mixin application class is a combination of | 4191 // The name of the mixin application class is a combination of |
| 4196 // the superclass and mixin class. | 4192 // the superclass and mixin class. |
| 4197 String& mixin_app_name = String::Handle(); | 4193 if (CurrentToken() != Token::kCOMMA && !final_mixin_application.IsNull()) { |
| 4198 mixin_app_name = mixin_super_type.ClassName(); | 4194 mixin_application = final_mixin_application.raw(); |
| 4199 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand()); | 4195 } else { |
| 4200 mixin_app_name = String::Concat(mixin_app_name, | 4196 String& mixin_app_name = String::Handle(); |
| 4197 mixin_app_name = mixin_super_type.ClassName(); | |
| 4198 mixin_app_name = String::Concat(mixin_app_name, Symbols::Ampersand()); | |
| 4199 mixin_app_name = String::Concat(mixin_app_name, | |
| 4201 String::Handle(mixin_type.ClassName())); | 4200 String::Handle(mixin_type.ClassName())); |
| 4202 mixin_app_name = Symbols::New(mixin_app_name); | 4201 mixin_app_name = Symbols::New(mixin_app_name); |
| 4203 | 4202 |
| 4204 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); | 4203 mixin_application = Class::New(mixin_app_name, script_, mixin_pos); |
| 4204 mixin_application.set_library(library_); | |
| 4205 } | |
| 4205 mixin_application.set_super_type(mixin_super_type); | 4206 mixin_application.set_super_type(mixin_super_type); |
| 4206 mixin_application.set_mixin(Type::Cast(mixin_type)); | 4207 mixin_application.set_mixin(Type::Cast(mixin_type)); |
| 4207 mixin_application.set_library(library_); | |
| 4208 mixin_application.set_is_synthesized_class(); | 4208 mixin_application.set_is_synthesized_class(); |
| 4209 | 4209 |
| 4210 // Add the mixin type to the interfaces that the mixin application | 4210 // Add the mixin type to the interfaces that the mixin application |
| 4211 // class implements. This is necessary so that type tests work. | 4211 // class implements. This is necessary so that type tests work. |
| 4212 mixin_application_interfaces = Array::New(1); | 4212 mixin_application_interfaces = Array::New(1); |
| 4213 mixin_application_interfaces.SetAt(0, mixin_type); | 4213 mixin_application_interfaces.SetAt(0, mixin_type); |
| 4214 mixin_application.set_interfaces(mixin_application_interfaces); | 4214 mixin_application.set_interfaces(mixin_application_interfaces); |
| 4215 | 4215 |
| 4216 // For the type arguments of the mixin application type, we need | 4216 // For the type arguments of the mixin application type, we need |
| 4217 // a copy of the type arguments to the mixin type. The simplest way | 4217 // a copy of the type arguments to the mixin type. The simplest way |
| (...skipping 6109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10327 void Parser::SkipQualIdent() { | 10327 void Parser::SkipQualIdent() { |
| 10328 ASSERT(IsIdentifier()); | 10328 ASSERT(IsIdentifier()); |
| 10329 ConsumeToken(); | 10329 ConsumeToken(); |
| 10330 if (CurrentToken() == Token::kPERIOD) { | 10330 if (CurrentToken() == Token::kPERIOD) { |
| 10331 ConsumeToken(); // Consume the kPERIOD token. | 10331 ConsumeToken(); // Consume the kPERIOD token. |
| 10332 ExpectIdentifier("identifier expected after '.'"); | 10332 ExpectIdentifier("identifier expected after '.'"); |
| 10333 } | 10333 } |
| 10334 } | 10334 } |
| 10335 | 10335 |
| 10336 } // namespace dart | 10336 } // namespace dart |
| OLD | NEW |