| 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 3775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3786 ConsumeToken(); | 3786 ConsumeToken(); |
| 3787 const intptr_t type_pos = TokenPos(); | 3787 const intptr_t type_pos = TokenPos(); |
| 3788 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 3788 super_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 3789 if (super_type.IsTypeParameter()) { | 3789 if (super_type.IsTypeParameter()) { |
| 3790 ErrorMsg(type_pos, | 3790 ErrorMsg(type_pos, |
| 3791 "class '%s' may not extend type parameter '%s'", | 3791 "class '%s' may not extend type parameter '%s'", |
| 3792 class_name.ToCString(), | 3792 class_name.ToCString(), |
| 3793 String::Handle(super_type.UserVisibleName()).ToCString()); | 3793 String::Handle(super_type.UserVisibleName()).ToCString()); |
| 3794 } | 3794 } |
| 3795 if (CurrentToken() == Token::kWITH) { | 3795 if (CurrentToken() == Token::kWITH) { |
| 3796 super_type = ParseMixins(super_type); | 3796 super_type = ParseMixins(pending_classes, super_type); |
| 3797 } | 3797 } |
| 3798 } else { | 3798 } else { |
| 3799 // No extends clause: implicitly extend Object, unless Object itself. | 3799 // No extends clause: implicitly extend Object, unless Object itself. |
| 3800 if (!cls.IsObjectClass()) { | 3800 if (!cls.IsObjectClass()) { |
| 3801 super_type = Type::ObjectType(); | 3801 super_type = Type::ObjectType(); |
| 3802 } | 3802 } |
| 3803 } | 3803 } |
| 3804 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); | 3804 ASSERT(!super_type.IsNull() || cls.IsObjectClass()); |
| 3805 cls.set_super_type(super_type); | 3805 cls.set_super_type(super_type); |
| 3806 | 3806 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3996 if (type.IsTypeParameter()) { | 3996 if (type.IsTypeParameter()) { |
| 3997 ErrorMsg(type_pos, | 3997 ErrorMsg(type_pos, |
| 3998 "class '%s' may not extend type parameter '%s'", | 3998 "class '%s' may not extend type parameter '%s'", |
| 3999 class_name.ToCString(), | 3999 class_name.ToCString(), |
| 4000 String::Handle(type.UserVisibleName()).ToCString()); | 4000 String::Handle(type.UserVisibleName()).ToCString()); |
| 4001 } | 4001 } |
| 4002 | 4002 |
| 4003 if (CurrentToken() != Token::kWITH) { | 4003 if (CurrentToken() != Token::kWITH) { |
| 4004 ErrorMsg("mixin application 'with Type' expected"); | 4004 ErrorMsg("mixin application 'with Type' expected"); |
| 4005 } | 4005 } |
| 4006 type = ParseMixins(type); | 4006 type = ParseMixins(pending_classes, type); |
| 4007 | 4007 |
| 4008 // TODO(12773): Treat the mixin application as an alias, not as a base | 4008 // TODO(12773): Treat the mixin application as an alias, not as a base |
| 4009 // class whose super class is the mixin application! This is difficult because | 4009 // class whose super class is the mixin application! This is difficult because |
| 4010 // of issues involving subsitution of type parameters | 4010 // of issues involving subsitution of type parameters |
| 4011 mixin_application.set_super_type(type); | 4011 mixin_application.set_super_type(type); |
| 4012 mixin_application.set_is_synthesized_class(); | 4012 mixin_application.set_is_synthesized_class(); |
| 4013 | 4013 |
| 4014 // This mixin application typedef needs an implicit constructor, but it is | 4014 // This mixin application typedef needs an implicit constructor, but it is |
| 4015 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 4015 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| 4016 // because this class should be lazily compiled. | 4016 // because this class should be lazily compiled. |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4382 "type parameter '%s' may not be used in interface list", | 4382 "type parameter '%s' may not be used in interface list", |
| 4383 String::Handle(interface.UserVisibleName()).ToCString()); | 4383 String::Handle(interface.UserVisibleName()).ToCString()); |
| 4384 } | 4384 } |
| 4385 all_interfaces.Add(interface); | 4385 all_interfaces.Add(interface); |
| 4386 } while (CurrentToken() == Token::kCOMMA); | 4386 } while (CurrentToken() == Token::kCOMMA); |
| 4387 cls_interfaces = Array::MakeArray(all_interfaces); | 4387 cls_interfaces = Array::MakeArray(all_interfaces); |
| 4388 cls.set_interfaces(cls_interfaces); | 4388 cls.set_interfaces(cls_interfaces); |
| 4389 } | 4389 } |
| 4390 | 4390 |
| 4391 | 4391 |
| 4392 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { | 4392 RawAbstractType* Parser::ParseMixins(const GrowableObjectArray& pending_classes, |
| 4393 const AbstractType& super_type) { |
| 4393 TRACE_PARSER("ParseMixins"); | 4394 TRACE_PARSER("ParseMixins"); |
| 4394 ASSERT(CurrentToken() == Token::kWITH); | 4395 ASSERT(CurrentToken() == Token::kWITH); |
| 4395 ASSERT(super_type.IsType()); // TODO(regis): Could be a BoundedType. | 4396 ASSERT(super_type.IsType()); // TODO(regis): Could be a BoundedType. |
| 4396 AbstractType& mixin_super_type = AbstractType::Handle(super_type.raw()); | 4397 AbstractType& mixin_super_type = AbstractType::Handle(super_type.raw()); |
| 4397 | 4398 |
| 4398 const GrowableObjectArray& mixin_apps = | 4399 const GrowableObjectArray& mixin_apps = |
| 4399 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4400 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 4400 AbstractType& mixin_type = AbstractType::Handle(); | 4401 AbstractType& mixin_type = AbstractType::Handle(); |
| 4401 Class& mixin_app_class = Class::Handle(); | 4402 Class& mixin_app_class = Class::Handle(); |
| 4402 Array& mixin_app_interfaces = Array::Handle(); | |
| 4403 String& mixin_app_class_name = String::Handle(); | 4403 String& mixin_app_class_name = String::Handle(); |
| 4404 String& mixin_type_class_name = String::Handle(); | 4404 String& mixin_type_class_name = String::Handle(); |
| 4405 do { | 4405 do { |
| 4406 ConsumeToken(); | 4406 ConsumeToken(); |
| 4407 const intptr_t mixin_pos = TokenPos(); | 4407 const intptr_t mixin_pos = TokenPos(); |
| 4408 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4408 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4409 if (mixin_type.IsTypeParameter()) { | 4409 if (mixin_type.IsTypeParameter()) { |
| 4410 ErrorMsg(mixin_pos, | 4410 ErrorMsg(mixin_pos, |
| 4411 "mixin type '%s' may not be a type parameter", | 4411 "mixin type '%s' may not be a type parameter", |
| 4412 String::Handle(mixin_type.UserVisibleName()).ToCString()); | 4412 String::Handle(mixin_type.UserVisibleName()).ToCString()); |
| 4413 } | 4413 } |
| 4414 | 4414 |
| 4415 // The name of the mixin application class is a combination of | 4415 // The name of the mixin application class is a combination of |
| 4416 // the super class name and mixin class name. | 4416 // the super class name and mixin class name. |
| 4417 mixin_app_class_name = mixin_super_type.ClassName(); | 4417 mixin_app_class_name = mixin_super_type.ClassName(); |
| 4418 mixin_app_class_name = String::Concat(mixin_app_class_name, | 4418 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| 4419 Symbols::Ampersand()); | 4419 Symbols::Ampersand()); |
| 4420 mixin_type_class_name = mixin_type.ClassName(); | 4420 mixin_type_class_name = mixin_type.ClassName(); |
| 4421 mixin_app_class_name = String::Concat(mixin_app_class_name, | 4421 mixin_app_class_name = String::Concat(mixin_app_class_name, |
| 4422 mixin_type_class_name); | 4422 mixin_type_class_name); |
| 4423 mixin_app_class_name = Symbols::New(mixin_app_class_name); | 4423 mixin_app_class_name = Symbols::New(mixin_app_class_name); |
| 4424 | 4424 |
| 4425 mixin_app_class = Class::New(mixin_app_class_name, script_, mixin_pos); | 4425 mixin_app_class = Class::New(mixin_app_class_name, script_, mixin_pos); |
| 4426 mixin_app_class.set_super_type(mixin_super_type); | 4426 mixin_app_class.set_super_type(mixin_super_type); |
| 4427 mixin_app_class.set_mixin(Type::Cast(mixin_type)); | 4427 mixin_app_class.set_mixin(Type::Cast(mixin_type)); |
| 4428 mixin_app_class.set_library(library_); | 4428 mixin_app_class.set_library(library_); |
| 4429 mixin_app_class.set_is_synthesized_class(); | 4429 mixin_app_class.set_is_synthesized_class(); |
| 4430 pending_classes.Add(mixin_app_class, Heap::kOld); |
| 4430 | 4431 |
| 4431 // Add the mixin type to the interfaces that the mixin application | 4432 // The class finalizer will add the mixin type to the interfaces that the |
| 4432 // class implements. This is necessary so that type tests work. | 4433 // mixin application class implements. This is necessary so that type tests |
| 4433 mixin_app_interfaces = Array::New(1); | 4434 // work. The mixin class may not be resolved yet, so it is not possible to |
| 4434 mixin_app_interfaces.SetAt(0, mixin_type); | 4435 // add the interface with the correct type arguments here. |
| 4435 mixin_app_class.set_interfaces(mixin_app_interfaces); | |
| 4436 | 4436 |
| 4437 // Add the synthesized class to the list of mixin apps. | 4437 // Add the synthesized class to the list of mixin apps. |
| 4438 mixin_apps.Add(mixin_app_class); | 4438 mixin_apps.Add(mixin_app_class); |
| 4439 | 4439 |
| 4440 // This mixin application class becomes the type class of the super type of | 4440 // This mixin application class becomes the type class of the super type of |
| 4441 // the next mixin application class. It is however too early to provide the | 4441 // the next mixin application class. It is however too early to provide the |
| 4442 // correct super type arguments. We use the raw type for now. | 4442 // correct super type arguments. We use the raw type for now. |
| 4443 mixin_super_type = Type::New(mixin_app_class, | 4443 mixin_super_type = Type::New(mixin_app_class, |
| 4444 Object::null_abstract_type_arguments(), | 4444 Object::null_abstract_type_arguments(), |
| 4445 mixin_pos); | 4445 mixin_pos); |
| (...skipping 6071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10517 void Parser::SkipQualIdent() { | 10517 void Parser::SkipQualIdent() { |
| 10518 ASSERT(IsIdentifier()); | 10518 ASSERT(IsIdentifier()); |
| 10519 ConsumeToken(); | 10519 ConsumeToken(); |
| 10520 if (CurrentToken() == Token::kPERIOD) { | 10520 if (CurrentToken() == Token::kPERIOD) { |
| 10521 ConsumeToken(); // Consume the kPERIOD token. | 10521 ConsumeToken(); // Consume the kPERIOD token. |
| 10522 ExpectIdentifier("identifier expected after '.'"); | 10522 ExpectIdentifier("identifier expected after '.'"); |
| 10523 } | 10523 } |
| 10524 } | 10524 } |
| 10525 | 10525 |
| 10526 } // namespace dart | 10526 } // namespace dart |
| OLD | NEW |