/*
 * This example illustrates why a class' methods must have code-free
 * argument and return types in order for the whole class to be
 * code-free.
 */
import edu.rice.cs.mint.runtime.*;

// Some dummy classes.
class A {}
class B {}
class D {
    Code<A> f;
}

public final class ClassInsideAIC {
    public static void main (String args[]) {
        <| let final A x = null; // dynamic binding
        `(new B () {
                // C is almost code-free but has an
                // ill-formed method.
                final class C {
                    Code<A> getX () {
                        return <|x|>; // returns open term
                    }}
                // problematic uses of class C
                separable Code<Code <A>> gen () {
                    final C c = new C ();
                    return <|c.getX ()|>;
                }}.gen ()) // close the escape
        |>.run ().run ();   // runtime error
        System.out.println ("run succeeds");

        // The following version does the same using an AIC in place
        // of `let', but the compiler rejects it for some reason,
        // saying:
        // ClassInsideAIC.java:19: no enclosing instance of type <anonymous ClassInsideAIC$1> is in scope
        //            return `(new B () {
        /*        <|new Object () { 
                Code<A> extract (final A x) { // dynamic binding
                    return `(new B () {
                            // C is almost code-free but has an
                            // ill-formed method.
                            final class C {
                                Code<A> getX () {
                                    return <|x|>; // returns open term
                                }}
                            // problematic uses of class C
                            public separable Code<Code <A>> gen () {
                                final C c = new C ();
                                return <|c.getX ()|>;
                            }}.gen ()); // close the escape
                }}|>.run ().extract (null).run (); // err
        */
    }
}