library;
//
// Problems in library:
//
// pkg/front_end/testcases/extensions/deferred_explicit_access.dart:5:1: Error: Extension 'Extension' cannot be imported through a deferred import.
// Try adding the `hide Extension` to the import.
// import 'deferred_explicit_access_lib.dart' deferred as prefix;
// ^
//
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
import "deferred_explicit_access_lib.dart" as def;

import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;

static method main() → dynamic /* originally async */ {
  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
  core::bool* :is_sync = false;
  dynamic :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 {
      #L1:
      {
        [yield] let dynamic #t1 = asy::_awaitHelper(LoadLibrary(prefix), :async_op_then, :async_op_error, :async_op) in null;
        :result;
        self::expect(0, let final core::Object* #t2 = CheckLibraryIsLoaded(prefix) in def::Extension|staticField);
        self::expect(0, let final core::Object* #t3 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(0));
        self::expect(42, let final core::Object* #t4 = CheckLibraryIsLoaded(prefix) in let final core::int* #t5 = 0 in let final core::int* #t6 = 42 in let final void #t7 = def::Extension|set#property(#t5, #t6) in #t6);
        self::expect(84, let final core::Object* #t8 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(42));
        self::expect(85, let final core::Object* #t9 = CheckLibraryIsLoaded(prefix) in def::Extension|method(43));
        self::expect(42, let final core::Object* #t10 = CheckLibraryIsLoaded(prefix) in def::Extension|staticProperty);
        self::expect(87, let final core::Object* #t11 = CheckLibraryIsLoaded(prefix) in def::Extension|staticProperty = 87);
        self::expect(87, let final core::Object* #t12 = CheckLibraryIsLoaded(prefix) in def::Extension|staticMethod());
      }
      asy::_completeWithNoFutureOnAsyncReturn(: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;
}
static method expect(dynamic expected, dynamic actual) → dynamic {
  if(!(expected =={core::Object::==}{(core::Object*) →* core::bool*} actual))
    throw "Expected ${expected}, actual ${actual}";
}

library;
import self as def;
import "dart:core" as core;

extension Extension on core::int* {
  static field staticField = def::Extension|staticField;
  static get staticProperty = get def::Extension|staticProperty;
  static method staticMethod = def::Extension|staticMethod;
  get property = def::Extension|get#property;
  method method = def::Extension|method;
  tearoff method = def::Extension|get#method;
  static set staticProperty = set def::Extension|staticProperty;
  set property = def::Extension|set#property;
}
static field core::int* Extension|staticField = 0;
static field core::int* topLevelField = def::Extension|staticField;
static get Extension|staticProperty() → core::int*
  return def::Extension|staticField;
static set Extension|staticProperty(core::int* value) → void {
  def::Extension|staticField = value;
}
static method Extension|staticMethod() → core::int*
  return def::Extension|staticField;
static method Extension|get#property(lowered final core::int* #this) → core::int*
  return #this.{core::num::+}(def::Extension|staticField){(core::num*) →* core::int*};
static method Extension|set#property(lowered final core::int* #this, core::int* value) → void {
  def::Extension|staticField = value;
}
static method Extension|method(lowered final core::int* #this) → core::int*
  return #this.{core::num::+}(def::Extension|staticField){(core::num*) →* core::int*};
static method Extension|get#method(lowered final core::int* #this) → () →* core::int*
  return () → core::int* => def::Extension|method(#this);
static get topLevelProperty() → core::int*
  return def::Extension|staticField;
static set topLevelProperty(core::int* value) → void {
  def::Extension|staticField = value;
}
static method topLevelMethod() → dynamic
  return def::Extension|staticField;


Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:31 -> IntConstant(0)
Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:45 -> IntConstant(42)
Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:45 -> IntConstant(42)
Extra constant evaluation: evaluated: 92, effectively constant: 3
