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

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*; -> 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 get runtimeType() → core::Type*; -> core::Object::runtimeType
  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>(core::_GrowableList::_literal1<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>(core::_GrowableList::_literal1<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>(core::_GrowableList::_literal1<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() → void {
  self::MyFuture<core::int*>* f;
  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* /* originally async */ {
    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
    core::bool* :is_sync = false;
    FutureOr<core::int*>* :return_value;
    (dynamic) →* dynamic :async_op_then;
    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
    core::int* :await_jump_var = 0;
    dynamic :await_ctx_var;
    dynamic :saved_try_context_var0;
    core::int* :async_temporary_0;
    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
      try {
        #L1:
        {
          final core::int* #t1 = x;
          if(#t1 == null) {
            [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int*>(3), :async_op_then, :async_op_error, :async_op) in null;
            :async_temporary_0 = _in::unsafeCast<core::int*>(:result);
          }
          else {
            :async_temporary_0 = #t1;
          }
          :return_value = _in::unsafeCast<core::int*>(:async_temporary_0);
          break #L1;
        }
        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
        return;
      }
      on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
      }
    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
    :async_op(){() →* dynamic};
    :is_sync = true;
    return :async_future;
  }){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* /* originally async */ {
    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
    core::bool* :is_sync = false;
    FutureOr<core::int*>* :return_value;
    (dynamic) →* dynamic :async_op_then;
    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
    core::int* :await_jump_var = 0;
    dynamic :await_ctx_var;
    dynamic :saved_try_context_var0;
    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
      try {
        #L2:
        {
          [yield] let dynamic #t3 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
          :return_value = (let final core::int* #t4 = _in::unsafeCast<core::int*>(:result) in #t4 == null ?{core::Object*} asy::Future::value<core::int*>(3) : #t4) as{TypeError} FutureOr<core::int*>*;
          break #L2;
        }
        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
        return;
      }
      on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
      }
    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
    :async_op(){() →* dynamic};
    :is_sync = true;
    return :async_future;
  }){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
  asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* => (let final core::int* #t5 = x in #t5 == null ?{core::Object*} asy::Future::value<core::int*>(3) : #t5) as{TypeError} FutureOr<core::int*>*){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
  asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* {
    return (let final core::int* #t6 = x in #t6 == null ?{core::Object*} asy::Future::value<core::int*>(3) : #t6) as{TypeError} FutureOr<core::int*>*;
  }){((core::int*) →* 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
}
