library;
import self as self;
import "dart:core" as core;
import "forwarder_propagation_lib.dart" as for;

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

abstract class A extends core::Object {
  synthetic constructor •() → self::A*
    ;
  abstract set foo(core::int* value) → void;
  abstract get bar() → core::int*;
  abstract method baz(core::int* x, {core::String* y, core::double* z}) → void;
  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
  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 get runtimeType() → core::Type*;
}
class B extends core::Object implements self::A {
  synthetic constructor •() → self::B*
    ;
  method noSuchMethod(core::Invocation* _) → dynamic
    ;
  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 get runtimeType() → core::Type*;
  no-such-method-forwarder get bar() → core::int*
    return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#bar, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic} core::int*;
  no-such-method-forwarder method baz(core::int* x, {core::String* y, core::double* z}) → void
    return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#baz, 0, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[x]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#y: y, #z: z})));
  no-such-method-forwarder set foo(core::int* value) → void
    return this.{self::B::noSuchMethod}(new core::_InvocationMirror::_withType(#foo=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
}
class C extends self::B {
  synthetic constructor •() → self::C*
    ;
}
class E extends core::Object implements for::D {
  synthetic constructor •() → self::E*
    ;
  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*;
  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateGetter() → core::int*
    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateGetter, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic} core::int*;
  no-such-method-forwarder get /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField() → core::int*
    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateField, 1, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{}))) as{TypeError,ForDynamic} core::int*;
  no-such-method-forwarder method /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateMethod() → void
    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateMethod, 0, const <core::Type*>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateSetter(core::int* value) → void
    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateSetter=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
  no-such-method-forwarder set /* from org-dartlang-testcase:///forwarder_propagation_lib.dart */ _privateField(core::int* value) → void
    return this.{self::E::noSuchMethod}(new core::_InvocationMirror::_withType(#_privateField=, 2, const <core::Type*>[], core::List::unmodifiable<dynamic>(<dynamic>[value]), core::Map::unmodifiable<core::Symbol*, dynamic>(const <core::Symbol*, dynamic>{})));
}
class F extends self::E {
  synthetic constructor •() → self::F*
    ;
}
static method main() → dynamic
  ;

library;
import self as for;
import "dart:core" as core;

abstract class D extends core::Object {
  field core::int* _privateField;
  synthetic constructor •() → for::D*
    ;
  abstract get _privateGetter() → core::int*;
  abstract set _privateSetter(core::int* value) → void;
  abstract method _privateMethod() → void;
  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*;
}
