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

public final class CspSample2 {
    public int field = 123;
    public static int sfield = 123;
    public <T> T getNumber(T n) { return n; }
    public static final class Helper {
        public Object objField;
    }
    public static final class HelperCode {
        public Code<Integer> codeField;
    }
    public static class HelperSuper {
        public Object objField;
    }
    public static final class HelperSub extends HelperSuper {
    }
    public void m() { System.out.println("m()"); }
    public static void sm() { System.out.println("sm()"); }
    public void run() {    
        // int x = 1; // error: must be final
        final int x = 1;
        final int[] y = new int[] {2};
        final CspSample2 cthis = this;
        
        final Object o = new Object();
        final Object[] oarr = new Object[] {null};
        final Helper h = new Helper();
        final HelperCode hc = new HelperCode();
        final HelperSub hs = new HelperSub();
        
        Code<Void> c = <| {
            // x = 5; // error: can't assign to final
            // field = 456; // error: cannot access enclosing class fields
            // this.field = 456; // error: cannot access enclosing class fields
            // System.out.println(this); // error: cannot access enclosing
            sfield = 456;
            // CspSample2.this.field = 456; // error: cannot access enclosing
            CspSample2.sfield = 456;
            // cthis.field = 456; // error: CSP variable not primitive
            y[0] = 3;
            // Object temp = o;
            // temp = oarr[0];
            // Helper temph = h; // error: CSP variable not primitive
            // HelperCode temphc = hc; // error: CSP variable not primitive
            // HelperSub temphs = hs; // error: CSP variable not primitive
            System.out.println("in <| |>: x="+x+" sfield="+sfield+" y[0]="+y[0]);
            // m(); // error: cannot access enclosing class methods
            // this.m(); // error: cannot access enclosing class methods
            // CspSample2.this.m(); // error: cannot access enclosing class methods
            sm();
            // this.sm(); // error: cannot access enclosing class methods
            CspSample2.sm();
        } |>;
        c.run ();
        System.out.println("after run: x="+x+" sfield="+sfield+" y[0]="+y[0]);
    }
    
    public static <T> java.util.List<T> listOfCode(T t) {
        java.util.ArrayList<T> l = new java.util.ArrayList<T>();
        l.add(t);
        return l;
    }
    
    public static void main (String [] args) {
        Object o = <| 1 |>;
        //Code<Integer> c = (Code<Integer>)o; // error: cast to Code
        new CspSample2().run();
        //java.util.List<Code> l; // error: instantiated to Code
        //java.util.List<Code<Integer>> l2; // error
        //Code<java.util.List<Code>> clc; // error
        //java.util.List<Code<Integer>> l3 = listOfCode(c); // error
    }
}
