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

import "dart:async";

class MyFuture<T extends core::Object* = dynamic> extends core::Object implements asy::Future<self::MyFuture::T*> {
  constructor •() → self::MyFuture<self::MyFuture::T*>*
    : super core::Object::•() {}
  constructor value(self::MyFuture::T* x) → self::MyFuture<self::MyFuture::T*>*
    : super core::Object::•() {}
  method noSuchMethod(core::Invocation* invocation) → dynamic
    return null;
  method then<S extends core::Object* = dynamic>((self::MyFuture::T*) →* FutureOr<self::MyFuture::then::S*>* f, {core::Function* onError = #C1}) → self::MyFuture<self::MyFuture::then::S*>*
    return null;
  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 method catchError(core::Function* onError, {(core::Object*) →* core::bool* test = #C1}) → asy::Future<self::MyFuture::T*>*
    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[onError]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))) as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
  no-such-method-forwarder method whenComplete(() →* FutureOr<void>* action) → asy::Future<self::MyFuture::T*>*
    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[action]), core::Map::unmodifiable<core::Symbol*, dynamic>(#C7))) as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
  no-such-method-forwarder method asStream() → asy::Stream<self::MyFuture::T*>*
    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C8, 0, #C3, #C6, core::Map::unmodifiable<core::Symbol*, dynamic>(#C7))) as{TypeError,ForDynamic} asy::Stream<self::MyFuture::T*>*;
  no-such-method-forwarder method timeout(core::Duration* timeLimit, {generic-covariant-impl () →* FutureOr<self::MyFuture::T*>onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onTimeout}))) as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
}
static method test() → void {
  asy::Future<dynamic>* f;
  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await asy::Future::value<core::int*>(3));
  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
    return await asy::Future::value<core::int*>(3);
  });
  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3);
  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
    return 3;
  });
  asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3));
  asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
    return asy::Future::value<core::int*>(3);
  });
  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => asy::Future::value<core::int*>(3));
  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
    return asy::Future::value<core::int*>(3);
  });
}
static method main() → dynamic {}

constants  {
  #C1 = null
  #C2 = #catchError
  #C3 = <core::Type*>[]
  #C4 = #test
  #C5 = #whenComplete
  #C6 = <dynamic>[]
  #C7 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C6}
  #C8 = #asStream
  #C9 = #timeout
  #C10 = #onTimeout
}
