library;
import self as self;
import "dart:core" as core;
import "dart:_late_helper" as _la;
import "dart:_internal" as _in;

class C extends core::Object {
  field core::int _#C#a#A = _in::createSentinel<core::int>();
  field core::int _#C#b#F = _in::createSentinel<core::int>();
  field core::int _#C#c#AI = _in::createSentinel<core::int>();
  field core::int _#C#d#FI = _in::createSentinel<core::int>();
  synthetic constructor •() → self::C
    : super core::Object::•()
    ;
  static synthetic method _#new#tearOff() → self::C
    return new self::C::•();
  get a() → core::int
    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#a#A}{core::int}, "a");
  set a(synthesized core::int value) → void
    this.{self::C::_#C#a#A} = value;
  get b() → core::int
    return _la::_lateReadCheck<core::int>(this.{self::C::_#C#b#F}{core::int}, "b");
  set b(synthesized core::int value) → void {
    _la::_lateWriteOnceCheck(this.{self::C::_#C#b#F}{core::int}, "b");
    this.{self::C::_#C#b#F} = value;
  }
  get c() → core::int {
    synthesized core::int value = this.{self::C::_#C#c#AI}{core::int};
    if(_in::isSentinel(value))
      value = this.{self::C::_#C#c#AI} = 1.{core::int::unary-}(){() → core::int};
    return value;
  }
  set c(synthesized core::int value) → void
    this.{self::C::_#C#c#AI} = value;
  @#C3
  get d() → core::int {
    synthesized core::int value = this.{self::C::_#C#d#FI}{core::int};
    if(_in::isSentinel(value)) {
      final synthesized core::int result = 1.{core::int::unary-}(){() → core::int};
      _la::_lateInitializeOnceCheck(this.{self::C::_#C#d#FI}{core::int}, "d");
      value = this.{self::C::_#C#d#FI} = result;
    }
    return value;
  }
}
static field self::C c = new self::C::•();
static method main() → void {
  self::testUninitializedNonFinalInstanceField();
  self::testUninitializedFinalInstanceField();
  self::testInitializedNonFinalInstanceField();
  self::testInitializedFinalInstanceField();
}
static method testUninitializedNonFinalInstanceField() → void {
  core::print(self::c.{self::C::a}{core::int});
  self::c.{self::C::a} = 42;
  core::print(self::c.{self::C::a}{core::int});
}
static method testUninitializedFinalInstanceField() → void {
  core::print(self::c.{self::C::b}{core::int});
  self::c.{self::C::b} = 42;
  core::print(self::c.{self::C::b}{core::int});
}
static method testInitializedNonFinalInstanceField() → void {
  core::print(self::c.{self::C::c}{core::int});
  self::c.{self::C::c} = 42;
  core::print(self::c.{self::C::c}{core::int});
}
static method testInitializedFinalInstanceField() → void {
  core::print(self::c.{self::C::d}{core::int});
}

constants  {
  #C1 = "dart2js:allow-cse"
  #C2 = null
  #C3 = core::pragma {name:#C1, options:#C2}
}

Extra constant evaluation status:
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_fields.dart:15:16 -> DoubleConstant(-1.0)
Evaluated: InstanceInvocation @ org-dartlang-testcase:///late_fields.dart:16:22 -> DoubleConstant(-1.0)
Extra constant evaluation: evaluated: 77, effectively constant: 2
