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) → 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*) →* asy::FutureOr<self::MyFuture::then::S*>* f, {core::Function* onError = #C1}) → self::MyFuture<self::MyFuture::then::S*>*
    return null;
  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ 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} asy::Future<self::MyFuture::T*>*;
  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() →* asy::FutureOr<dynamic>* 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} asy::Future<self::MyFuture::T*>*;
  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration* timeLimit, {generic-covariant-impl () →* asy::FutureOr<self::MyFuture::T*>* onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C8, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C9: onTimeout}))) as{TypeError} asy::Future<self::MyFuture::T*>*;
  no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T*>*
    return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C10, 0, #C3, #C6, core::Map::unmodifiable<core::Symbol*, dynamic>(#C7))) as{TypeError} asy::Stream<self::MyFuture::T*>*;
}
static method g1(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
  asy::FutureOr<core::int*>* :return_value;
  dynamic :async_stack_trace;
  dynamic :async_op_then;
  dynamic :async_op_error;
  dynamic :await_jump_var = 0;
  dynamic :await_ctx_var;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L1:
      {
        :return_value = (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} asy::FutureOr<core::int*>*;
        break #L1;
      }
      asy::_completeOnAsyncReturn(:async_completer, :return_value);
      return;
    }
    on dynamic catch(dynamic :exception, dynamic :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.start(:async_op);
  return :async_completer.{asy::Completer::future};
}
static method g2(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
  asy::FutureOr<core::int*>* :return_value;
  dynamic :async_stack_trace;
  dynamic :async_op_then;
  dynamic :async_op_error;
  dynamic :await_jump_var = 0;
  dynamic :await_ctx_var;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L2:
      {
        :return_value = (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} asy::FutureOr<core::int*>*;
        break #L2;
      }
      asy::_completeOnAsyncReturn(:async_completer, :return_value);
      return;
    }
    on dynamic catch(dynamic :exception, dynamic :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.start(:async_op);
  return :async_completer.{asy::Completer::future};
}
static method g3(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
  asy::FutureOr<core::int*>* :return_value;
  dynamic :async_stack_trace;
  dynamic :async_op_then;
  dynamic :async_op_error;
  dynamic :await_jump_var = 0;
  dynamic :await_ctx_var;
  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
    try {
      #L3:
      {
        core::Object* y = x ?{core::Object*} 42 : new self::MyFuture::value<dynamic>(42);
        :return_value = y as{TypeError} asy::FutureOr<core::int*>*;
        break #L3;
      }
      asy::_completeOnAsyncReturn(:async_completer, :return_value);
      return;
    }
    on dynamic catch(dynamic :exception, dynamic :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.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 = #timeout
  #C9 = #onTimeout
  #C10 = #asStream
}
