library;
import self as self;
import "dart:core" as core;
import "mixin_library.dart" as mix;

import "org-dartlang-testcase:///mixin_library.dart";

class Super<S extends core::Object* = dynamic> extends core::Object {
  synthetic constructor •() → self::Super<self::Super::S*>*
    : super core::Object::•()
    ;
  method foo() → dynamic
    return 40;
  method f() → dynamic
    return 3;
  abstract member-signature get _identityHashCode() → core::int*;
  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
  abstract member-signature operator ==(dynamic other) → core::bool*;
  abstract member-signature get hashCode() → core::int*;
  abstract member-signature method toString() → core::String*;
  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
  abstract member-signature get runtimeType() → core::Type*;
}
abstract class _C&Super&Mixin<V extends core::Object* = dynamic> = self::Super<self::_C&Super&Mixin::V*> with mix::Mixin<self::_C&Super&Mixin::V*> /*isAnonymousMixin*/  {
  synthetic constructor •() → self::_C&Super&Mixin<self::_C&Super&Mixin::V*>*
    : super self::Super::•()
    ;
}
class C<V extends core::Object* = dynamic> extends self::_C&Super&Mixin<self::C::V*> {
  synthetic constructor •() → self::C<self::C::V*>*
    : super self::_C&Super&Mixin::•()
    ;
}
abstract class _D&Super&Mixin = self::Super<dynamic> with mix::Mixin<dynamic> /*isAnonymousMixin*/  {
  synthetic constructor •() → self::_D&Super&Mixin*
    : super self::Super::•()
    ;
}
class D extends self::_D&Super&Mixin {
  synthetic constructor •() → self::D*
    : super self::_D&Super&Mixin::•()
    ;
}
class C2<V extends core::Object* = dynamic> = self::Super<self::C2::V*> with mix::Mixin<self::C2::V*> {
  synthetic constructor •() → self::C2<self::C2::V*>*
    : super self::Super::•()
    ;
}
class D2 = self::Super<dynamic> with mix::Mixin<dynamic> {
  synthetic constructor •() → self::D2*
    : super self::Super::•()
    ;
}
static method main() → dynamic {
  core::print(new self::C::•<dynamic>().{mix::Mixin::foo}());
  core::print(new self::C2::•<dynamic>().{mix::Mixin::foo}());
}

library test.mixin_library;
//
// Problems in library:
//
// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Error: Superclass has no method named 'foo'.
//   foo() => super.foo() + f();
//                  ^^^
//
import self as mix;
import "dart:core" as core;

class Mixin<T extends core::Object* = dynamic> extends core::Object {
  field dynamic x = mix::f();
  field dynamic y = null;
  field dynamic z = null;
  generic-covariant-impl field mix::Mixin::T* t = null;
  synthetic constructor •() → mix::Mixin<mix::Mixin::T*>*
    : super core::Object::•()
    ;
  method foo() → dynamic
    return super.foo().+(mix::f());
  method g(generic-covariant-impl mix::Mixin::T* a) → mix::Mixin::T*
    return null;
  method h() → dynamic
    return mix::V();
  method l() → dynamic
    return mix::_private();
  method _privateMethod() → dynamic
    return 49;
  method publicMethod() → dynamic
    return this.{mix::Mixin::_privateMethod}();
  abstract member-signature get _identityHashCode() → core::int*;
  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
  abstract member-signature operator ==(dynamic other) → core::bool*;
  abstract member-signature get hashCode() → core::int*;
  abstract member-signature method toString() → core::String*;
  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
  abstract member-signature get runtimeType() → core::Type*;
}
static method f() → dynamic
  return 2;
static method V() → dynamic
  return 87;
static method _private() → dynamic
  return 117;
static method foo(dynamic m) → dynamic
  return m._privateMethod();
