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;
  FutureOr<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::_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.call();
  :is_sync = true;
  return :async_future;
}
static method expect(dynamic expected, dynamic actual) → dynamic {
  if(!expected.{core::Object::==}(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);
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);
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: 93, effectively constant: 3
