import edu.rice.cs.mint.runtime.*;

public class SeparableSample {
    // public separable int i = 1; // not allowed
    // public separable static interface I { // not allowed
    public static interface I {
        public separable void m();
    }
    public static class C implements I {
        // check that implementing and overriding methods also have separable
        // public void m() { } // error
        public separable void m() { }
    }
    public static class Super {
        protected Super() { }
        protected separable Super(int i) {
            // this(); // error
        }
        public separable void m() { }
        public void n() { }
    }
    public static class Sub extends Super {
        public separable Sub() {
            super(5); // error: super();
        }
        // check that implementing and overriding methods also have separable
        // public void m() { } // error
        public separable void m() { }
        public separable void n() { } // allowed to add separable
    }
    public SeparableSample() {
        // implicit Object ctor call, allowed
        // separable int i = 1; // not allowed
    }
    public separable SeparableSample(int i) {
        // this(); // error
    }
    // error: public static Code<Integer> method() {
    public static separable SafeCode<Integer> method(int i) {
        return <| 1 |>;
    }
    public static separable Integer method2() {
        return 1;
    }
    public separable Foo foo() {
        return new Foo();
    }
    public static separable Foo staticFoo() {
        // error: notSeparableFoo();
        return new Foo();
    }
    public static Foo notSeparableFoo() {
        return new Foo();
    }
    static {
        // error: System.out.println("initializer!");
    }
    {
        // error: System.out.println("initializer!");
    }
    public static class Foo {
        public separable Bar bar() { return new Bar(); }
    }
    public static class Bar {
        public static separable void staticCall() { }
    }
    public void run() {
        foo().bar();
    }
    public static void main (String [] args) {
        SafeCode<Integer> c2 = <| 2 |>;
        Code<Integer> c = <| `(method(1)) + `c2 |>;
        System.out.println (c.run ());
        Code<Integer> cc = <| `( <| method2() |> ) + `c2 |>;
        System.out.println (cc.run ());
        // error:
        // Code<Integer> ccc = <| `(new Code<Integer>() {
        //     public Integer run() { return 2; }
        // }) + `c2 |>;
        staticFoo().bar();
        notSeparableFoo().bar().hashCode();
        new SeparableSample() {
            public void run() {
                super.run();
            }
        }.run();
        Bar.staticCall();
    }
}
