| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 20082)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -3244,19 +3244,17 @@
|
| }
|
| cls.set_type_parameters(orig_type_parameters);
|
| }
|
| - Type& super_type = Type::Handle();
|
| + AbstractType& super_type = Type::Handle();
|
| if (CurrentToken() == Token::kEXTENDS) {
|
| ConsumeToken();
|
| const intptr_t type_pos = TokenPos();
|
| - const AbstractType& type = AbstractType::Handle(
|
| - ParseType(ClassFinalizer::kTryResolve));
|
| - if (type.IsTypeParameter()) {
|
| + super_type = ParseType(ClassFinalizer::kTryResolve);
|
| + if (super_type.IsTypeParameter()) {
|
| ErrorMsg(type_pos,
|
| "class '%s' may not extend type parameter '%s'",
|
| class_name.ToCString(),
|
| - String::Handle(type.UserVisibleName()).ToCString());
|
| + String::Handle(super_type.UserVisibleName()).ToCString());
|
| }
|
| - super_type ^= type.raw();
|
| if (CurrentToken() == Token::kWITH) {
|
| super_type = ParseMixins(super_type);
|
| }
|
| @@ -3416,12 +3414,6 @@
|
| set_current_class(mixin_application);
|
| ParseTypeParameters(mixin_application);
|
|
|
| - // TODO(hausner): Handle mixin application aliases with generics.
|
| - if (mixin_application.NumTypeParameters() > 0) {
|
| - ErrorMsg(classname_pos,
|
| - "type parameters on mixin applications not yet supported");
|
| - }
|
| -
|
| ExpectToken(Token::kASSIGN);
|
|
|
| if (CurrentToken() == Token::kABSTRACT) {
|
| @@ -3429,56 +3421,34 @@
|
| ConsumeToken();
|
| }
|
|
|
| - const intptr_t supertype_pos = TokenPos();
|
| - const AbstractType& type =
|
| + const intptr_t type_pos = TokenPos();
|
| + AbstractType& type =
|
| AbstractType::Handle(ParseType(ClassFinalizer::kTryResolve));
|
| if (type.IsTypeParameter()) {
|
| - ErrorMsg(supertype_pos,
|
| + ErrorMsg(type_pos,
|
| "class '%s' may not extend type parameter '%s'",
|
| class_name.ToCString(),
|
| String::Handle(type.UserVisibleName()).ToCString());
|
| }
|
| - Type& mixin_super_type = Type::Handle();
|
| - mixin_super_type ^= type.raw();
|
|
|
| if (CurrentToken() != Token::kWITH) {
|
| ErrorMsg("mixin application 'with Type' expected");
|
| }
|
| + type = ParseMixins(type);
|
|
|
| - const Type& mixin_application_type =
|
| - Type::Handle(ParseMixins(mixin_super_type));
|
| - // TODO(hausner): Implement generic mixin support.
|
| - if (mixin_application_type.arguments() != AbstractTypeArguments::null()) {
|
| - ErrorMsg(mixin_application_type.token_pos(),
|
| - "mixin class with type arguments not yet supported");
|
| - }
|
| + // TODO(hausner): treat the mixin application as an alias, not as a base
|
| + // class whose super class is the mixin application!
|
| + mixin_application.set_super_type(type);
|
|
|
| - // The result of ParseMixins() is a chain of super types that is the
|
| - // result of the mixin composition 'S with M1, M2, ...'. The mixin
|
| - // application classes are anonymous (i.e. not registered in the current
|
| - // library). We steal the super type and mixin type from the bottom of
|
| - // the chain and add it to the named mixin application class. The bottom
|
| - // anonymous class in the chain is thrown away.
|
| - const Class& anon_mixin_app_class =
|
| - Class::Handle(mixin_application_type.type_class());
|
| - mixin_application.set_super_type(
|
| - AbstractType::Handle(anon_mixin_app_class.super_type()));
|
| - mixin_application.set_mixin(Type::Handle(anon_mixin_app_class.mixin()));
|
| - const Array& interfaces = Array::Handle(anon_mixin_app_class.interfaces());
|
| - mixin_application.set_interfaces(interfaces);
|
| AddImplicitConstructor(mixin_application);
|
| -
|
| if (CurrentToken() == Token::kIMPLEMENTS) {
|
| Array& interfaces = Array::Handle();
|
| const intptr_t interfaces_pos = TokenPos();
|
| - Type& super_type = Type::Handle();
|
| - super_type ^= mixin_application.super_type();
|
| - interfaces = ParseInterfaceList(super_type);
|
| + interfaces = ParseInterfaceList(type);
|
| AddInterfaces(interfaces_pos, mixin_application, interfaces);
|
| }
|
| -
|
| - pending_classes.Add(mixin_application, Heap::kOld);
|
| ExpectSemicolon();
|
| + pending_classes.Add(mixin_application, Heap::kOld);
|
| }
|
|
|
|
|
| @@ -3810,7 +3780,7 @@
|
|
|
|
|
| // Parse and return an array of interface types.
|
| -RawArray* Parser::ParseInterfaceList(const Type& super_type) {
|
| +RawArray* Parser::ParseInterfaceList(const AbstractType& super_type) {
|
| TRACE_PARSER("ParseInterfaceList");
|
| ASSERT(CurrentToken() == Token::kIMPLEMENTS);
|
| const GrowableObjectArray& interfaces =
|
| @@ -3846,22 +3816,20 @@
|
| }
|
|
|
|
|
| -RawType* Parser::ParseMixins(const Type& super_type) {
|
| +RawAbstractType* Parser::ParseMixins(const AbstractType& super_type) {
|
| TRACE_PARSER("ParseMixins");
|
| ASSERT(CurrentToken() == Token::kWITH);
|
|
|
| - // TODO(hausner): Remove this restriction.
|
| - if (super_type.arguments() != AbstractTypeArguments::null()) {
|
| - ErrorMsg(super_type.token_pos(),
|
| - "super class in mixin application may not have type arguments");
|
| - }
|
| -
|
| + const GrowableObjectArray& mixin_apps =
|
| + GrowableObjectArray::Handle(GrowableObjectArray::New());
|
| AbstractType& mixin_type = AbstractType::Handle();
|
| AbstractTypeArguments& mixin_type_arguments =
|
| AbstractTypeArguments::Handle();
|
| Class& mixin_application = Class::Handle();
|
| Type& mixin_application_type = Type::Handle();
|
| - Type& mixin_super_type = Type::Handle(super_type.raw());
|
| + Type& mixin_super_type = Type::Handle();
|
| + ASSERT(super_type.IsType());
|
| + mixin_super_type ^= super_type.raw();
|
| Array& mixin_application_interfaces = Array::Handle();
|
| do {
|
| ConsumeToken();
|
| @@ -3905,8 +3873,10 @@
|
| mixin_type_arguments,
|
| mixin_pos);
|
| mixin_super_type = mixin_application_type.raw();
|
| + mixin_apps.Add(mixin_application_type);
|
| } while (CurrentToken() == Token::kCOMMA);
|
| - return mixin_application_type.raw();
|
| + return MixinAppType::New(super_type,
|
| + Array::Handle(Array::MakeArray(mixin_apps)));
|
| }
|
|
|
|
|
|
|