| 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 3735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3746 "class '%s' may not extend a malformed type", | 3746 "class '%s' may not extend a malformed type", |
| 3747 class_name.ToCString()); | 3747 class_name.ToCString()); |
| 3748 } | 3748 } |
| 3749 if (super_type.IsTypeParameter()) { | 3749 if (super_type.IsTypeParameter()) { |
| 3750 ErrorMsg(type_pos, | 3750 ErrorMsg(type_pos, |
| 3751 "class '%s' may not extend type parameter '%s'", | 3751 "class '%s' may not extend type parameter '%s'", |
| 3752 class_name.ToCString(), | 3752 class_name.ToCString(), |
| 3753 String::Handle(super_type.UserVisibleName()).ToCString()); | 3753 String::Handle(super_type.UserVisibleName()).ToCString()); |
| 3754 } | 3754 } |
| 3755 if (CurrentToken() == Token::kWITH) { | 3755 if (CurrentToken() == Token::kWITH) { |
| 3756 super_type = ParseMixins(pending_classes, super_type); | 3756 super_type = ParseMixins(super_type); |
| 3757 } | 3757 } |
| 3758 if (is_mixin_declaration) { | 3758 if (is_mixin_declaration) { |
| 3759 cls.set_is_mixin_typedef(); | 3759 cls.set_is_mixin_typedef(); |
| 3760 cls.set_is_synthesized_class(); | 3760 cls.set_is_synthesized_class(); |
| 3761 } | 3761 } |
| 3762 } else { | 3762 } else { |
| 3763 // No extends clause: implicitly extend Object, unless Object itself. | 3763 // No extends clause: implicitly extend Object, unless Object itself. |
| 3764 if (!cls.IsObjectClass()) { | 3764 if (!cls.IsObjectClass()) { |
| 3765 super_type = Type::ObjectType(); | 3765 super_type = Type::ObjectType(); |
| 3766 } | 3766 } |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3948 if (type.IsTypeParameter()) { | 3948 if (type.IsTypeParameter()) { |
| 3949 ErrorMsg(type_pos, | 3949 ErrorMsg(type_pos, |
| 3950 "class '%s' may not extend type parameter '%s'", | 3950 "class '%s' may not extend type parameter '%s'", |
| 3951 class_name.ToCString(), | 3951 class_name.ToCString(), |
| 3952 String::Handle(type.UserVisibleName()).ToCString()); | 3952 String::Handle(type.UserVisibleName()).ToCString()); |
| 3953 } | 3953 } |
| 3954 | 3954 |
| 3955 if (CurrentToken() != Token::kWITH) { | 3955 if (CurrentToken() != Token::kWITH) { |
| 3956 ErrorMsg("mixin application 'with Type' expected"); | 3956 ErrorMsg("mixin application 'with Type' expected"); |
| 3957 } | 3957 } |
| 3958 type = ParseMixins(pending_classes, type); | 3958 type = ParseMixins(type); |
| 3959 | 3959 |
| 3960 mixin_application.set_super_type(type); | 3960 mixin_application.set_super_type(type); |
| 3961 mixin_application.set_is_synthesized_class(); | 3961 mixin_application.set_is_synthesized_class(); |
| 3962 | 3962 |
| 3963 // This mixin application typedef needs an implicit constructor, but it is | 3963 // This mixin application typedef needs an implicit constructor, but it is |
| 3964 // too early to call 'AddImplicitConstructor(mixin_application)' here, | 3964 // too early to call 'AddImplicitConstructor(mixin_application)' here, |
| 3965 // because this class should be lazily compiled. | 3965 // because this class should be lazily compiled. |
| 3966 if (CurrentToken() == Token::kIMPLEMENTS) { | 3966 if (CurrentToken() == Token::kIMPLEMENTS) { |
| 3967 ParseInterfaceList(mixin_application); | 3967 ParseInterfaceList(mixin_application); |
| 3968 } | 3968 } |
| (...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4331 "type parameter '%s' may not be used in interface list", | 4331 "type parameter '%s' may not be used in interface list", |
| 4332 String::Handle(interface.UserVisibleName()).ToCString()); | 4332 String::Handle(interface.UserVisibleName()).ToCString()); |
| 4333 } | 4333 } |
| 4334 all_interfaces.Add(interface); | 4334 all_interfaces.Add(interface); |
| 4335 } while (CurrentToken() == Token::kCOMMA); | 4335 } while (CurrentToken() == Token::kCOMMA); |
| 4336 cls_interfaces = Array::MakeArray(all_interfaces); | 4336 cls_interfaces = Array::MakeArray(all_interfaces); |
| 4337 cls.set_interfaces(cls_interfaces); | 4337 cls.set_interfaces(cls_interfaces); |
| 4338 } | 4338 } |
| 4339 | 4339 |
| 4340 | 4340 |
| 4341 RawAbstractType* Parser::ParseMixins(const GrowableObjectArray& pending_classes, | 4341 RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) { |
| 4342 const AbstractType& super_type) { | |
| 4343 TRACE_PARSER("ParseMixins"); | 4342 TRACE_PARSER("ParseMixins"); |
| 4344 ASSERT(CurrentToken() == Token::kWITH); | 4343 ASSERT(CurrentToken() == Token::kWITH); |
| 4345 ASSERT(super_type.IsType()); // TODO(regis): Could be a BoundedType. | 4344 ASSERT(super_type.IsType()); // TODO(regis): Could be a BoundedType. |
| 4346 AbstractType& mixin_super_type = AbstractType::Handle(super_type.raw()); | 4345 const GrowableObjectArray& mixin_types = |
| 4347 | |
| 4348 const GrowableObjectArray& mixin_apps = | |
| 4349 GrowableObjectArray::Handle(GrowableObjectArray::New()); | 4346 GrowableObjectArray::Handle(GrowableObjectArray::New()); |
| 4350 AbstractType& mixin_type = AbstractType::Handle(); | 4347 AbstractType& mixin_type = AbstractType::Handle(); |
| 4351 Class& mixin_app_class = Class::Handle(); | |
| 4352 String& mixin_app_class_name = String::Handle(); | |
| 4353 String& mixin_type_class_name = String::Handle(); | |
| 4354 do { | 4348 do { |
| 4355 ConsumeToken(); | 4349 ConsumeToken(); |
| 4356 const intptr_t mixin_pos = TokenPos(); | |
| 4357 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); | 4350 mixin_type = ParseType(ClassFinalizer::kResolveTypeParameters); |
| 4351 if (mixin_type.IsDynamicType()) { |
| 4352 // The string 'dynamic' is not resolved yet at this point, but a malformed |
| 4353 // type mapped to dynamic can be encountered here. |
| 4354 ErrorMsg(mixin_type.token_pos(), "illegal mixin of a malformed type"); |
| 4355 } |
| 4358 if (mixin_type.IsTypeParameter()) { | 4356 if (mixin_type.IsTypeParameter()) { |
| 4359 ErrorMsg(mixin_pos, | 4357 ErrorMsg(mixin_type.token_pos(), |
| 4360 "mixin type '%s' may not be a type parameter", | 4358 "mixin type '%s' may not be a type parameter", |
| 4361 String::Handle(mixin_type.UserVisibleName()).ToCString()); | 4359 String::Handle(mixin_type.UserVisibleName()).ToCString()); |
| 4362 } | 4360 } |
| 4363 | 4361 mixin_types.Add(mixin_type); |
| 4364 // The name of the mixin application class is a combination of | |
| 4365 // the super class name and mixin class name. | |
| 4366 mixin_app_class_name = mixin_super_type.ClassName(); | |
| 4367 mixin_app_class_name = String::Concat(mixin_app_class_name, | |
| 4368 Symbols::Ampersand()); | |
| 4369 mixin_type_class_name = mixin_type.ClassName(); | |
| 4370 mixin_app_class_name = String::Concat(mixin_app_class_name, | |
| 4371 mixin_type_class_name); | |
| 4372 mixin_app_class_name = Symbols::New(mixin_app_class_name); | |
| 4373 | |
| 4374 mixin_app_class = Class::New(mixin_app_class_name, script_, mixin_pos); | |
| 4375 mixin_app_class.set_super_type(mixin_super_type); | |
| 4376 mixin_app_class.set_mixin(Type::Cast(mixin_type)); | |
| 4377 mixin_app_class.set_library(library_); | |
| 4378 mixin_app_class.set_is_synthesized_class(); | |
| 4379 pending_classes.Add(mixin_app_class, Heap::kOld); | |
| 4380 | |
| 4381 // The class finalizer will add the mixin type to the interfaces that the | |
| 4382 // mixin application class implements. This is necessary so that type tests | |
| 4383 // work. The mixin class may not be resolved yet, so it is not possible to | |
| 4384 // add the interface with the correct type arguments here. | |
| 4385 | |
| 4386 // Add the synthesized class to the list of mixin apps. | |
| 4387 mixin_apps.Add(mixin_app_class); | |
| 4388 | |
| 4389 // This mixin application class becomes the type class of the super type of | |
| 4390 // the next mixin application class. It is however too early to provide the | |
| 4391 // correct super type arguments. We use the raw type for now. | |
| 4392 mixin_super_type = Type::New(mixin_app_class, | |
| 4393 Object::null_abstract_type_arguments(), | |
| 4394 mixin_pos); | |
| 4395 } while (CurrentToken() == Token::kCOMMA); | 4362 } while (CurrentToken() == Token::kCOMMA); |
| 4396 return MixinAppType::New(Array::Handle(Array::MakeArray(mixin_apps))); | 4363 return MixinAppType::New(super_type, |
| 4364 Array::Handle(Array::MakeArray(mixin_types))); |
| 4397 } | 4365 } |
| 4398 | 4366 |
| 4399 | 4367 |
| 4400 void Parser::ParseTopLevelVariable(TopLevel* top_level, | 4368 void Parser::ParseTopLevelVariable(TopLevel* top_level, |
| 4401 intptr_t metadata_pos) { | 4369 intptr_t metadata_pos) { |
| 4402 TRACE_PARSER("ParseTopLevelVariable"); | 4370 TRACE_PARSER("ParseTopLevelVariable"); |
| 4403 const bool is_const = (CurrentToken() == Token::kCONST); | 4371 const bool is_const = (CurrentToken() == Token::kCONST); |
| 4404 // Const fields are implicitly final. | 4372 // Const fields are implicitly final. |
| 4405 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); | 4373 const bool is_final = is_const || (CurrentToken() == Token::kFINAL); |
| 4406 const bool is_static = true; | 4374 const bool is_static = true; |
| (...skipping 6204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10611 void Parser::SkipQualIdent() { | 10579 void Parser::SkipQualIdent() { |
| 10612 ASSERT(IsIdentifier()); | 10580 ASSERT(IsIdentifier()); |
| 10613 ConsumeToken(); | 10581 ConsumeToken(); |
| 10614 if (CurrentToken() == Token::kPERIOD) { | 10582 if (CurrentToken() == Token::kPERIOD) { |
| 10615 ConsumeToken(); // Consume the kPERIOD token. | 10583 ConsumeToken(); // Consume the kPERIOD token. |
| 10616 ExpectIdentifier("identifier expected after '.'"); | 10584 ExpectIdentifier("identifier expected after '.'"); |
| 10617 } | 10585 } |
| 10618 } | 10586 } |
| 10619 | 10587 |
| 10620 } // namespace dart | 10588 } // namespace dart |
| OLD | NEW |