    001    /* Copyright 2000, 2001, Compaq Computer Corporation */
    002
    003    package javafe.tc;
    004
    005    import javafe.ast.*;
    006    import javafe.util.*;
    007
    008
    009    /**
    010     * EnvForLocals are used to extend an existing Env with one new local
    011     * type binding.
    012     */
    013
    014    public class EnvForEnclosedScope extends Env implements/*privately*/ Cloneable {
    015
    016        /***************************************************
    017         *                                                 *
    018         * Creation:                                       *
    019         *                                                 *
    020         **************************************************/
    021
    022        /**
    023         * Our parent environment
    024         */
    025        //@ invariant !(parent instanceof EnvForCU);
    026        protected /*@ non_null @*/ Env parent;
    027
    028        /**
    029         * Create a environment from an existing one by adding a new
    030         * local type binding. <p>
    031         *
    032         * We report an error to ErrorSet if the new local type binding
    033         * is a redefinition of a local type binding not hidden by a type
    034         * member.<p>
    035         */
    036        //@ requires !(parent instanceof EnvForCU);
    037        public EnvForEnclosedScope(/*@ non_null @*/ Env parent) {
    038            this.parent = parent;
    039        }
    040
    041
    042
    043        /***************************************************
    044         *                                                 *
    045         * Current/enclosing instances I:                  *
    046         *                                                 *
    047         **************************************************/
    048
    049        /**
    050         * Is there a current instance in scope? <p>
    051         *
    052         * E.g., is "this" (or "<enclosing class>.this") legal here? <p>
    053         *
    054         * This is also refered to as "are we in a static context?".  The
    055         * legality of super also depends on this result. <p>
    056         *
    057         * The legality of C.this, C != <enclosing class> is different; see
    058         * canAccessInstance(-).
    059         */
    060        public boolean isStaticContext() { return parent.isStaticContext(); }
    061
    062
    063        /**
    064         * Return the intermost class enclosing the code that is checked
    065         * in this environment. <p>
    066         *
    067         * May return null if there is no enclosing class (aka, for
    068         * environments for CompilationUnits). <p>
    069         *
    070         * If isStaticContext() returns true, then this is the type of "this".
    071         */
    072        public TypeSig getEnclosingClass() {
    073            return parent.getEnclosingClass();
    074        }
    075
    076
    077        /**
    078         * If there is an enclosing instance in scope, then return the
    079         * (exact) type of the innermost such instance. <p>
    080         *
    081         * Note: this is considered a current instance, not an enclosing
    082         * instance, even inside its methods.
    083         */
    084        public TypeSig getEnclosingInstance() {
    085            return parent.getEnclosingInstance();
    086        }
    087
    088
    089        /**
    090         * Returns a new Env that acts the same as us, except that its
    091         * current instance (if any) is not accessible. <p>
    092         *
    093         * Note: this routine is somewhat inefficient and should be
    094         * avoided unless an unknown environment needs to be coerced in
    095         * this way. <p>
    096         */
    097        public Env asStaticContext() {
    098            EnvForEnclosedScope n;
    099            try {
    100                n = (EnvForEnclosedScope)this.clone();
    101            } catch (CloneNotSupportedException e) {
    102                Assert.fail("clone did not obey its spec!");
    103                return null;  // keep compiler happy
    104            }
    105            n.parent = parent.asStaticContext();
    106            return n;
    107        }
    108
    109
    110        /***************************************************
    111         *                                                 *
    112         * Simple names:                                   *
    113         *                                                 *
    114         **************************************************/
    115
    116        /**
    117         * Attempt to lookup a simple TypeName in this environment to get
    118         * the TypeSig it denotes.  Returns null if no such type
    119         * exists.<p>
    120         *
    121         * This routine does not check that the resulting type (if any)
    122         * is actually accessable. <p>
    123         *
    124         * If id is ambiguous, then if loc != Location.NULL then a fatal
    125         * error is reported at that location via ErrorSet else one of
    126         * its possible meanings is returned.<p>
    127         */
    128        public TypeSig lookupSimpleTypeName(TypeSig caller, Identifier id, int loc) {
    129                return parent.lookupSimpleTypeName(caller, id, loc);
    130        }
    131
    132
    133        /**
    134         * Locate the lexically innermost field or local variable
    135         * declaration. <p>
    136         *
    137         * Let d be the lexically innermost field or local variable
    138         * declaration (including formals) of id (if any such declaration
    139         * exists).  Then this routine returns: <p>
    140         *
    141         *    d (a LocalVarDecl or FormalParaDecl) if d is a local
    142         *                                            variable declaration
    143         *
    144         *    the class C that lexically encloses us and contains the
    145         *    (inherited) field d if d is a field declaration
    146         *
    147         *    null if d does not exist
    148         *
    149         * Note: inherited fields are considered to lexically enclose the
    150         * code of their subclasses.  We give the class containing the
    151         * field instead of the field itself to postpone dealing with
    152         * multiple fields named id visible in the same class.<p>
    153         *
    154         * In the field case, id disambiguates to C[.this].id.<p>
    155         */
    156        public ASTNode locateFieldOrLocal(Identifier id) {
    157            // we bind no fields or local variables/formals ourselves:
    158            return parent.locateFieldOrLocal(id);
    159        }
    160
    161        public boolean isDuplicate(Identifier id) {
    162            return false;
    163        }
    164
    165        /**
    166         * Locate the lexically innermost method named id. <p>
    167         *
    168         * Returns the TypeSig for the innermost lexically enclosing type
    169         * that has a method named id or null if no such type exists.<p>
    170         *
    171         * Note: inherited methods are considered to lexically enclose
    172         * the code of their subclasses.<p>
    173         *
    174         * id disambiguates to C[.this].id.<p>
    175         */
    176        public TypeSig locateMethod(Identifier id) {
    177            // we bind no methods ourselves:
    178            return parent.locateMethod(id);
    179        }
    180
    181
    182        /***************************************************
    183         *                                                 *
    184         * Debugging functions:                            *
    185         *                                                 *
    186         **************************************************/
    187
    188        /**
    189         * Display information about us to System.out.  This function is
    190         * intended only for debugging use.
    191         */
    192        public void display() {
    193            parent.display();
    194            System.out.println("[[ extended with enclosed scope marker ]] ");
    195        }
    196    }