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

class A extends core::Object {
  synthetic constructor •() → self::A*
    : super core::Object::•()
    ;
  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
  abstract member-signature method toString() → core::String*; -> core::Object::toString
  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
class B extends self::A {
  synthetic constructor •() → self::B*
    : super self::A::•()
    ;
  operator +(self::C* v) → self::B*
    return null;
  operator -(core::int* i) → self::B*
    return null;
  operator *(self::B* v) → self::B*
    return null;
  operator &(self::A* v) → self::C*
    return null;
}
class C extends self::B {
  synthetic constructor •() → self::C*
    : super self::B::•()
    ;
}
class Test extends core::Object {
  field self::B* member;
  constructor •(self::B* member) → self::Test*
    : self::Test::member = member, super core::Object::•()
    ;
  static method test(self::Test* t) → void {
    let final self::Test* #t1 = t in #t1 == null ?{self::B*} null : #t1.{self::Test::member} = self::f<self::B*>();
    let final self::Test* #t2 = t in #t2 == null ?{self::B*} null : #t2.{self::Test::member}{self::B*} == null ?{self::B*} #t2.{self::Test::member} = self::f<self::B*>() : null;
    let final self::Test* #t3 = t in #t3 == null ?{self::B*} null : #t3.{self::Test::member} = #t3.{self::Test::member}{self::B*}.{self::B::+}(self::f<self::C*>()){(self::C*) →* self::B*};
    let final self::Test* #t4 = t in #t4 == null ?{self::B*} null : #t4.{self::Test::member} = #t4.{self::Test::member}{self::B*}.{self::B::*}(self::f<self::B*>()){(self::B*) →* self::B*};
    let final self::Test* #t5 = t in #t5 == null ?{self::C*} null : #t5.{self::Test::member} = #t5.{self::Test::member}{self::B*}.{self::B::&}(self::f<self::A*>()){(self::A*) →* self::C*};
    let final self::Test* #t6 = t in #t6 == null ?{self::B*} null : let final self::B* #t7 = #t6.{self::Test::member}{self::B*}.{self::B::-}(1){(core::int*) →* self::B*} in let final void #t8 = #t6.{self::Test::member} = #t7 in #t7;
    let final self::Test* #t9 = t in #t9 == null ?{self::B*} null : #t9.{self::Test::member} = #t9.{self::Test::member}{self::B*}.{self::B::-}(1){(core::int*) →* self::B*};
    self::B* v1 = let final self::Test* #t10 = t in #t10 == null ?{self::B*} null : #t10.{self::Test::member} = self::f<self::B*>();
    self::B* v2 = let final self::Test* #t11 = t in #t11 == null ?{self::B*} null : let final self::B* #t12 = #t11.{self::Test::member}{self::B*} in #t12 == null ?{self::B*} #t11.{self::Test::member} = self::f<self::B*>() : #t12;
    self::B* v3 = let final self::Test* #t13 = t in #t13 == null ?{self::B*} null : let final self::B* #t14 = #t13.{self::Test::member}{self::B*}.{self::B::+}(self::f<self::C*>()){(self::C*) →* self::B*} in let final void #t15 = #t13.{self::Test::member} = #t14 in #t14;
    self::B* v4 = let final self::Test* #t16 = t in #t16 == null ?{self::B*} null : let final self::B* #t17 = #t16.{self::Test::member}{self::B*}.{self::B::*}(self::f<self::B*>()){(self::B*) →* self::B*} in let final void #t18 = #t16.{self::Test::member} = #t17 in #t17;
    self::C* v5 = let final self::Test* #t19 = t in #t19 == null ?{self::C*} null : let final self::C* #t20 = #t19.{self::Test::member}{self::B*}.{self::B::&}(self::f<self::A*>()){(self::A*) →* self::C*} in let final void #t21 = #t19.{self::Test::member} = #t20 in #t20;
    self::B* v6 = let final self::Test* #t22 = t in #t22 == null ?{self::B*} null : let final self::B* #t23 = #t22.{self::Test::member}{self::B*}.{self::B::-}(1){(core::int*) →* self::B*} in let final void #t24 = #t22.{self::Test::member} = #t23 in #t23;
    self::B* v7 = let final self::Test* #t25 = t in #t25 == null ?{self::B*} null : let final self::B* #t26 = #t25.{self::Test::member}{self::B*} in let final self::B* #t27 = #t25.{self::Test::member} = #t26.{self::B::-}(1){(core::int*) →* self::B*} in #t26;
  }
  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
  abstract member-signature method toString() → core::String*; -> core::Object::toString
  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
static method f<T extends core::Object* = dynamic>() → self::f::T*
  return null;
static method main() → dynamic {}
