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 throw "";
  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}))){(core::Invocation) → dynamic} 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>(#C6))){(core::Invocation) → dynamic} 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(#C7, 0, #C3, #C8, core::Map::unmodifiable<core::Symbol, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic} asy::Stream<self::MyFuture::T%>;
  no-such-method-forwarder method timeout(core::Duration timeLimit, {covariant-by-class () →? 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}))){(core::Invocation) → dynamic} as{TypeError,ForDynamic} asy::Future<self::MyFuture::T%>;
}
static method test(self::MyFuture<dynamic> f) → void {
  self::MyFuture<core::int> t1 = f.{self::MyFuture::then}<core::int>((dynamic _#wc0#formal) → asy::Future<core::int> async /* emittedValueType= core::int */ => await new self::MyFuture::value<core::int>(3)){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
  self::MyFuture<core::int> t2 = f.{self::MyFuture::then}<core::int>((dynamic _#wc1#formal) → asy::Future<core::int> async /* emittedValueType= core::int */ {
    return await new self::MyFuture::value<core::int>(3);
  }){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
  self::MyFuture<core::int> t3 = f.{self::MyFuture::then}<core::int>((dynamic _#wc2#formal) → asy::Future<core::int> async /* emittedValueType= core::int */ => 3){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
  self::MyFuture<core::int> t4 = f.{self::MyFuture::then}<core::int>((dynamic _#wc3#formal) → asy::Future<core::int> async /* emittedValueType= core::int */ {
    return 3;
  }){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
  self::MyFuture<core::int> t5 = f.{self::MyFuture::then}<core::int>((dynamic _#wc4#formal) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>(3)){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
  self::MyFuture<core::int> t6 = f.{self::MyFuture::then}<core::int>((dynamic _#wc5#formal) → self::MyFuture<core::int> {
    return new self::MyFuture::value<core::int>(3);
  }){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
  self::MyFuture<core::int> t7 = f.{self::MyFuture::then}<core::int>((dynamic _#wc6#formal) → asy::Future<core::int> async /* emittedValueType= core::int */ => new self::MyFuture::value<core::int>(3)){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
  self::MyFuture<core::int> t8 = f.{self::MyFuture::then}<core::int>((dynamic _#wc7#formal) → asy::Future<core::int> async /* emittedValueType= core::int */ {
    return new self::MyFuture::value<core::int>(3);
  }){((dynamic) → FutureOr<core::int>, {onError: core::Function?}) → self::MyFuture<core::int>};
}
static method main() → dynamic {}

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