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

typedef F<contravariant T extends core::Object* = dynamic> = (T*) →* void;
class C<T extends core::Object* = dynamic> extends core::Object {
  synthetic constructor •() → self::C<self::C::T*>*
    : super core::Object::•()
    ;
  method f1() → (self::C::T*) →* void {}
  method f2() → core::List<(self::C::T*) →* void>* {
    return <(self::C::T*) →* void>[this.{self::C::f1}()];
  }
  abstract member-signature get /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ _identityHashCode() → core::int*; -> core::Object::_identityHashCode
  abstract member-signature method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
  abstract member-signature method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
  abstract member-signature method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
  abstract member-signature method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
  abstract member-signature operator /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ ==(dynamic other) → core::bool*; -> core::Object::==
  abstract member-signature get /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ hashCode() → core::int*; -> core::Object::hashCode
  abstract member-signature method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ toString() → core::String*; -> core::Object::toString
  abstract member-signature method /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
  abstract member-signature get /* from org-dartlang-sdk:///sdk/lib/_internal/vm/lib/object_patch.dart */ runtimeType() → core::Type*; -> core::Object::runtimeType
}
static method g1(self::C<core::num*>* c) → void {
  (core::num*) →* void x = let final self::C<core::num*>* #t1 = c in #t1.{self::C::==}(null) ?{(core::num*) →* void} null : #t1.{self::C::f1}() as{TypeError,CovarianceCheck} (core::num*) →* void;
  core::print("hello");
  x.call(1.5);
}
static method g2(self::C<core::num*>* c) → void {
  (core::int*) →* void x = let final self::C<core::num*>* #t2 = c in #t2.{self::C::==}(null) ?{(core::num*) →* void} null : #t2.{self::C::f1}() as{TypeError,CovarianceCheck} (core::num*) →* void;
  x.call(1);
}
static method g3(self::C<core::num*>* c) → void {
  core::List<(core::num*) →* void>* x = let final self::C<core::num*>* #t3 = c in #t3.{self::C::==}(null) ?{core::List<(core::num*) →* void>*} null : #t3.{self::C::f2}() as{TypeError,CovarianceCheck} core::List<(core::num*) →* void>*;
}
static method main() → void {}
