// @skip-test

// To reproduce the problem, run:
//   javac -processor nullness Issue556b.java
//   java Issue556b
// and observe that the javac execution issues no warnings but the java execution suffers a null
// pointer exception.

// Before the constructor is invoked, static initializers and static blocks are executed.  This
// suggests that the Initialization Checker can assume that static fields are initialized in the
// constructor.
//
// However, if any user-defined code -- including callbacks such as executions of equals() and
// hashCode() -- appears in a static initializer or static block, then static fields cannot be
// assumed to be initialized within the constructor.

public class Issue556b {
  static class Parent {
    private final Object o;

    public Parent(final Object o) {
      this.o = o;
    }

    @Override
    public String toString() {
      return o.toString();
    }
  }

  static class Child extends Parent {
    public static final Child CHILD = new Child();
    private static final Object OBJ = new Object();

    private Child() {
      // This call should not be legal, because at the time that the call occurs, the static
      // initializers of Child have not yet finished executing and therefore CHILD and OBJ are not
      // necessarily initialized and are not necessarily non-null.
      // :: error: (method.invocation)
      super(OBJ);
    }
  }

  static class Child2 extends Parent {
    public static final Child2 CHILD;
    private static final Object OBJ;

    static {
      CHILD = new Child2();
      OBJ = new Object();
    }

    private Child2() {
      // This call should not be legal, because at the time that the call occurs, the static
      // initializers of Child have not yet finished executing and therefore CHILD and OBJ are not
      // necessarily initialized and are not necessarily non-null.
      // :: error: (method.invocation)
      super(OBJ);
    }
  }

  // Changing the order of the OBJ and CHILD fields prevents a null pointer exception.
  static class ChildOk1 extends Parent {
    private static final Object OBJ = new Object();
    public static final Child CHILD = new Child();

    private ChildOk1() {
      // This call is legal, because OBJ is non-null at the time of the
      // call.  That's because OBJ is initialized before CHILD and
      // therefore before the call to "new Child()".
      super(OBJ);
    }
  }

  // Changing the order of the OBJ and CHILD field assignments prevents a null pointer exception.
  static class ChildOk2 extends Parent {
    public static final ChildOk2 CHILD;
    private static final Object OBJ;

    static {
      OBJ = new Object();
      CHILD = new ChildOk2();
    }

    private ChildOk2() {
      // This call is legal, because OBJ is non-null at the time of the
      // call.  That's because OBJ is initialized before CHILD and
      // therefore before the call to "new Child()".
      super(OBJ);
    }
  }

  public static void main(final String[] args) {
    System.out.println(Child.CHILD);
  }
}
