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 class _C&Super&Mixin<V extends core::Object = dynamic> extends self::Super<self::_C&Super&Mixin::V> implements mix::Mixin<self::_C&Super&Mixin::V> {
  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
  generic-covariant-impl field self::_C&Super&Mixin::V t = null /* from org-dartlang-testcase:///mixin_library.dart */;
  synthetic constructor •() → self::_C&Super&Mixin<self::_C&Super&Mixin::V>
    : super self::Super::•()
    ;
  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
    return super.foo().+(mix::f());
  method /* from org-dartlang-testcase:///mixin_library.dart */ g(generic-covariant-impl self::_C&Super&Mixin::V a) → self::_C&Super&Mixin::V
    return null;
  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
    return mix::V();
  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
    return mix::_private();
  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
    return 49;
  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
    return this.{mix::Mixin::_privateMethod}();
}
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 extends self::Super<dynamic> implements mix::Mixin<dynamic> {
  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
  generic-covariant-impl field dynamic t = null /* from org-dartlang-testcase:///mixin_library.dart */;
  synthetic constructor •() → self::_D&Super&Mixin
    : super self::Super::•()
    ;
  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
    return super.foo().+(mix::f());
  method /* from org-dartlang-testcase:///mixin_library.dart */ g(generic-covariant-impl dynamic a) → dynamic
    return null;
  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
    return mix::V();
  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
    return mix::_private();
  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
    return 49;
  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
    return this.{mix::Mixin::_privateMethod}();
}
class D extends self::_D&Super&Mixin {
  synthetic constructor •() → self::D
    : super self::_D&Super&Mixin::•()
    ;
}
class C2<V extends core::Object = dynamic> extends self::Super<self::C2::V> implements mix::Mixin<self::C2::V> {
  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
  generic-covariant-impl field self::C2::V t = null /* from org-dartlang-testcase:///mixin_library.dart */;
  synthetic constructor •() → self::C2<self::C2::V>
    : super self::Super::•()
    ;
  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
    return super.foo().+(mix::f());
  method /* from org-dartlang-testcase:///mixin_library.dart */ g(generic-covariant-impl self::C2::V a) → self::C2::V
    return null;
  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
    return mix::V();
  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
    return mix::_private();
  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
    return 49;
  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
    return this.{mix::Mixin::_privateMethod}();
}
class D2 extends self::Super<dynamic> implements mix::Mixin<dynamic> {
  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
  generic-covariant-impl field dynamic t = null /* from org-dartlang-testcase:///mixin_library.dart */;
  synthetic constructor •() → self::D2
    : super self::Super::•()
    ;
  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
    return super.foo().+(mix::f());
  method /* from org-dartlang-testcase:///mixin_library.dart */ g(generic-covariant-impl dynamic a) → dynamic
    return null;
  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
    return mix::V();
  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
    return mix::_private();
  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
    return 49;
  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
    return this.{mix::Mixin::_privateMethod}();
}
static method main() → dynamic {
  core::print(new self::C::•<dynamic>().foo());
  core::print(new self::C2::•<dynamic>().foo());
}

library test.mixin_library;
//
// Problems in library:
//
// pkg/front_end/testcases/rasta/mixin_library.dart:16:18: Warning: 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}();
}
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();
