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([dynamic x = #C1]) → 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*;
  member-signature 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*>*;
  member-signature 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*>*;
  member-signature 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*>*;
  member-signature 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 field self::MyFuture<dynamic>* f;
static field asy::Future<core::int*>* t1 = self::f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>("hi"));
static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]);
static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
  FutureOr<core::List<core::int*>*>* :return_value;
  dynamic :async_stack_trace;
  (dynamic) →* dynamic :async_op_then;
  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
  core::int* :await_jump_var = 0;
  dynamic :await_ctx_var;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L1:
      {
        :return_value = <core::int*>[3];
        break #L1;
      }
      asy::_completeOnAsyncReturn(:async_completer, :return_value);
      return;
    }
    on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
    }
  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
  return :async_completer.{asy::Completer::future};
}
static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
  FutureOr<core::List<core::int*>*>* :return_value;
  dynamic :async_stack_trace;
  (dynamic) →* dynamic :async_op_then;
  (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
  core::int* :await_jump_var = 0;
  dynamic :await_ctx_var;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L2:
      {
        :return_value = new self::MyFuture::value<core::List<core::int*>*>(<core::int*>[3]);
        break #L2;
      }
      asy::_completeOnAsyncReturn(:async_completer, :return_value);
      return;
    }
    on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
    }
  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
  return :async_completer.{asy::Completer::future};
}
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
}
