library #lib;
import self as self;
import "dart:core" as core;

abstract class A extends core::Object {
  synthetic constructor •() → self::A*
    : super core::Object::•()
    ;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasNonThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  abstract method foo() → core::int*;
}
class B extends self::A {
  synthetic constructor •() → self::B*
    : super self::A::•()
    ;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method foo() → core::int*
    return 1;
}
class C extends core::Object implements self::A {
  synthetic constructor •() → self::C*
    : super core::Object::•()
    ;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method foo() → core::int*
    return 2;
}
class D extends self::C {
  synthetic constructor •() → self::D*
    : super self::C::•()
    ;
}
class E extends core::Object {
  synthetic constructor •() → self::E*
    : super core::Object::•()
    ;
[@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:3,getterSelectorId:4]  method toString() → core::String*
    return "D";
}
[@vm.inferred-type.metadata=#lib::D?]static field self::A* dd;
[@vm.inferred-type.metadata=#lib::E?]static field self::E* ee = new self::E::•();
static method callerA1([@vm.inferred-type.metadata=!] self::A* aa) → void {
  [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
static method callerA2([@vm.inferred-type.metadata=#lib::B] self::A* aa) → void {
  [@vm.direct-call.metadata=B::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
static method callerA3([@vm.inferred-type.metadata=#lib::C] self::A* aa) → void {
  [@vm.direct-call.metadata=C::foo] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
static method callerA4([@vm.inferred-type.metadata=#lib::D?] self::A* aa) → void {
  [@vm.direct-call.metadata=C::foo??] [@vm.inferred-type.metadata=!? (skip check)] aa.{self::A::foo}();
}
static method callerE1([@vm.inferred-type.metadata=dart.core::_OneByteString (value: abc)] dynamic x) → void {
  [@vm.direct-call.metadata=_StringBase::toString] [@vm.inferred-type.metadata=!? (skip check) (receiver not int)] x.{core::Object::toString}();
}
static method callerE2([@vm.inferred-type.metadata=#lib::E?] dynamic x) → void {
  [@vm.inferred-type.metadata=!? (receiver not int)] x.{core::Object::toString}();
}
static method main(core::List<core::String*>* args) → dynamic {
  self::callerA1(new self::B::•());
  self::callerA1(new self::C::•());
  self::callerA2(new self::B::•());
  let self::C* #arg1 = new self::C::•() in self::callerA3(#arg1);
  self::callerA4([@vm.inferred-type.metadata=#lib::D?] self::dd);
  self::dd = new self::D::•();
  self::callerE1("abc");
  self::callerE2([@vm.inferred-type.metadata=#lib::E?] self::ee);
}
