    001    /* Copyright 2000, 2001, Compaq Computer Corporation */
    002
    003    package javafe.tc;
    004
    005    import java.util.Hashtable;
    006
    007    import javafe.ast.*;
    008    import javafe.util.*;
    009
    010    /**
    011     *
    012     */
    013
    014    public class TypeSig extends Type
    015    {
    016        /***************************************************
    017         *                                                 *
    018         * Basic TypeSig instance variables:               *
    019         *                                                 *
    020         **************************************************/
    021
    022        /**
    023         * The name of the package we belong to.  Always non-null.
    024         */
    025        //@ invariant \nonnullelements(packageName);
    026        public /*public readonly non_null */ String[] packageName;
    027
    028        /**
    029         * Our enclosing type or null iff we are a package-member type.
    030         */
    031        public /*public readonly*/ TypeSig enclosingType;
    032
    033        /**
    034         * Our simple name or null if we are an anonymous type.
    035         */
    036        public /*public readonly*/ String simpleName;
    037
    038        /**
    039         * Are we a direct member of a package or a type? <p>
    040         *
    041         * (Otherwise, we are a block-level type or an anonymous type.) <p>
    042         */
    043        public /*public readonly*/ boolean member;
    044
    045
    046        /**
    047         * Our enclosing Env; may be null for member types because of
    048         * laziness.  Use TypeSig.getEnclosingEnv() to obtain an always
    049         * non-null version of this.
    050         */
    051        protected /*subclass-only*/ Env enclosingEnv;
    052
    053        /**
    054         * Our TypeDecl; may be null only for package-member type
    055         * because of laziness.  Use getTypeDecl() to obtain an always
    056         * non-null version of this. <p>
    057         *
    058         * This variable should be set only using setDecl. <p>
    059         */
    060        //@ invariant state>=PARSED ==> myTypeDecl != null;
    061        //@ invariant state<PARSED ==> myTypeDecl==null;
    062        /*@spec_public*/ protected TypeDecl myTypeDecl;
    063
    064        /**
    065         * The CompilationUnit we belong to; null iff myTypeDecl is null
    066         * because of laziness.  Use getCompilationUnit() to obtain an
    067         * always non-null version of this.
    068         */
    069        //@ invariant (myTypeDecl==null) == (CU==null);
    070        protected CompilationUnit CU;
    071
    072
    073
    074        /*
    075         * Enforce the various invariants about what kind of type we represent
    076         * and the nullness of our basic instance variables.
    077         *
    078         *
    079         * You can tell what kind of type we are as follows:
    080         *
    081         *   package-member type               if enclosingType==null
    082         *   type-member type                 if enclosingType != null && member
    083         *   block level type                  if simpleName != null && !member
    084         *   anonymous type                    if simpleName==null
    085         */
    086        //@ invariant (enclosingType==null) ==> member;   // package-member
    087        //@ invariant (simpleName==null) ==> !member;      // anonymous
    088        //@ invariant !member ==> enclosingEnv != null;
    089        //@ invariant (enclosingType != null) ==> myTypeDecl != null;
    090
    091
    092        /***************************************************
    093         *                                                 *
    094         * Associating TypeSigs and TypeDecls:             *
    095         *                                                 *
    096         **************************************************/
    097
    098        /**
    099         * Decorates <code>TypeDecl</code> nodes to point to
    100         * <code>TypeSig</code> objects.
    101         */
    102        //@ invariant sigDecoration.decorationType == \type(TypeSig);
    103        public static final ASTDecoration sigDecoration
    104            = new ASTDecoration("sigDecoration");
    105
    106
    107        /**
    108         * The myTypeDecl field maps TypeSigs to TypeDecls.  The
    109         * getSig(TypeDecl) function provides the reverse mapping. <p>
    110         *
    111         * Precondition: d has already been associated with a TypeSig. <p>
    112         */
    113        //@ ensures \result != null;
    114        public static TypeSig getSig(/*@ non_null @*/ TypeDecl d) {
    115            TypeSig r = (TypeSig)sigDecoration.get(d);
    116            if (r == null) Assert.notNull(r,      //@ nowarn Pre;
    117                   "getSig called on a TypeDecl (" + d.id + ") not associated with a TypeSig");
    118            return r;
    119        }
    120
    121
    122        /**
    123         * Protected routine used to associate a TypeSig with a TypeDecl. <p>
    124         *
    125         * It automatically creates TypeSigs for any (indirect) members
    126         * of decl and associates them properly. <p>
    127         *
    128         * CU must be the CompilationUnit that decl belongs to.<p>
    129         */
    130        //@ ensures this.myTypeDecl != null;
    131        protected void setDecl(/*@ non_null @*/ TypeDecl decl,
    132                             /*@ non_null @*/ CompilationUnit CU) {
    133            this.myTypeDecl = decl;
    134            this.CU = CU;
    135            state = PARSED;
    136            sigDecoration.set(decl, this);
    137
    138            // Create TypeSigs for any TypeDecl members of us:
    139            for (int i = 0; i < decl.elems.size(); i++) {
    140                TypeDeclElem member = decl.elems.elementAt(i);
    141                if (!(member instanceof TypeDecl))
    142                    continue;
    143
    144                TypeDecl subDecl = (TypeDecl)member;
    145                TypeSig subSig = Types.makeTypeSig(
    146                                            packageName, subDecl.id.toString(),
    147                                             this, subDecl, CU);
    148                // (The TypeSig constructor will call subSig.setDecl(subDecl, CU))
    149            }
    150        }
    151
    152        /***************************************************
    153         *                                                 *
    154         * Creation:                                       *
    155         *                                                 *
    156         **************************************************/
    157
    158        /**
    159         * Create a TypeSig that represents a non-member type. <p>
    160         *
    161         * We represent a block-level type if simpleName is non-null,
    162         * and an anonymous type otherwise. <p>
    163         */
    164        //@ requires !(enclosingEnv instanceof EnvForCU);
    165        protected TypeSig(String simpleName,
    166                          /*@ non_null @*/ Env enclosingEnv,
    167                          /*@ non_null @*/ TypeDecl decl) {
    168            super();   //@ nowarn Pre; // can't do set before super()
    169
    170            member = false;
    171
    172            this.simpleName = simpleName;
    173            this.enclosingEnv = enclosingEnv;
    174
    175            this.enclosingType = enclosingEnv.getEnclosingClass();
    176            //@ assume this.enclosingType != this;
    177            Assert.notNull(this.enclosingType);
    178
    179            // We inherit our packageName and CompilationUnit from our
    180            // enclosing type:
    181            this.packageName = this.enclosingType.packageName;
    182            this.CU = this.enclosingType.getCompilationUnit();
    183
    184            setDecl(decl, this.CU);    //@ nowarn Invariant; // helper function
    185        }
    186
    187
    188        /**
    189         * Create a TypeSig that represents a member type. <p>
    190         *
    191         * This constructor is designed to be private to TypeSig;
    192         * It is protected to support the Types inst pattern, but
    193         * clients should use
    194         * OutsideEnv.lookup[Deffered] and getSig to get TypeSig's
    195         * representing member types. <p>
    196         *
    197         * We represent a package-member type if enclosingType is
    198         * non-null, and a type-member type otherwise. <p>
    199         *
    200         * Note: packageName should never be modified by the caller after
    201         * this call.<p>
    202         *
    203         * CU must be the CompilationUnit that decl belongs to.<p>
    204         */
    205        //@ requires \nonnullelements(packageName);
    206        //@ requires (enclosingType != null) ==> (decl != null);
    207        //@ requires (decl==null) == (CU==null);
    208        protected TypeSig(/*@non_null*/ String[] packageName,
    209                        /*@ non_null @*/ String simpleName,
    210                        TypeSig enclosingType,
    211                        TypeDecl decl, CompilationUnit CU) {
    212            super();                //@ nowarn Pre; // can't do set before super
    213
    214            member = true;
    215
    216            this.packageName = packageName;
    217            this.simpleName = simpleName;
    218            this.enclosingType = enclosingType;
    219
    220            this.enclosingEnv = null;      // be lazy...
    221            if (decl != null)
    222                setDecl(decl, CU);    //@ nowarn Invariant; // helper function
    223        }
    224
    225
    226        /**
    227         * Create a TypeSig that represents an internal-use-only
    228         * package-member type.  Such types do not have external names
    229         * and should be avoided if at all possible since they are
    230         * kludges. <p>
    231         *
    232         * This constructor should only be used by
    233         * PrepTypeDeclaration.getRootInterface().<p>
    234         *
    235         * Note: packageName should never be modified by the caller after
    236         * this call.<p>
    237         *
    238         * CU must be the CompilationUnit that decl belongs to.<p>
    239         */
    240        //@ requires \nonnullelements(packageName);
    241        protected TypeSig(/*@non_null*/ String[] packageName,
    242                        /*@ non_null @*/ String simpleName,
    243                        /*@ non_null @*/ TypeDecl decl,
    244                        /*@ non_null @*/ CompilationUnit CU) {
    245            this(packageName, simpleName, null, decl, CU);
    246        }
    247
    248
    249
    250    //    //@ requires \nonnullelements(packageName);
    251    //    //@ requires (enclosingType != null) ==> (decl != null);
    252    //    //@ requires (decl==null) == (CU==null);
    253    //    //@ ensures \result != null;
    254    // UNUSED
    255    //    private static TypeSig make(String[] packageName,
    256    //                              /*@ non_null @*/ String simpleName,
    257    //                              TypeSig enclosingType,
    258    //                              TypeDecl decl,
    259    //                              CompilationUnit CU) {
    260    //      TypeSig t = Types.makeTypeSig(packageName,
    261    //                                  simpleName,
    262    //                                  enclosingType,
    263    //                                  decl,
    264    //                                  CU);
    265    //      return t;
    266    //    }
    267
    268        /***************************************************
    269         *                                                 *
    270         * Interning by External Name for package-members: *
    271         *                                                 *
    272         **************************************************/
    273
    274        /*
    275         * We maintain a mapping from fully-qualified names to
    276         * package-member types so that OutsideEnv never creates 2
    277         * TypeSigs with the same external name.
    278         *
    279         * This map is complete in the sense that all created
    280         * package-member types are in its range.
    281         *
    282         * These functions are intended for use *only* by OutsideEnv!
    283         */
    284
    285
    286        /**
    287         * The map from fully-qualified external names of package-member
    288         * types to the TypeSigs representing them. <p>
    289         *
    290         * Invariant: map's range includes all existing package-member
    291         * TypeSigs; map sends getKey(P,T) to the unique package-member
    292         * TypeSig with external name P.T.<p>
    293         *
    294         * The domain type of map is String and its range type is (non-null)
    295         * TypeSigs.<p>
    296         */
    297        //  Old specs from original full JML spec files.  Must be
    298        //  rewritten for current java.util.Hashtable specs.
    299        //- invariant map.keyType == \type(String);
    300        //- invariant map.elementType == \type(TypeSig);
    301        //@ spec_public
    302        private static final Hashtable map = new Hashtable(101);
    303
    304        public static final void clear() {
    305            map.clear();
    306        }
    307
    308        /**
    309         * Compute the key for map for fully-qualified type P.T.
    310         */
    311        //@ requires \nonnullelements(P);
    312        //@ ensures \result != null;
    313        private static String getKey(/*@non_null*/ String[] P, /*@ non_null @*/ String T) {
    314            String key = "";
    315
    316            for (int i=0; i<P.length; i++)
    317                key += "."+P[i];
    318            key += "."+T;
    319
    320            return key;
    321        }
    322
    323
    324        /**
    325         * If a TypeSig representing the package-member type named P.T
    326         * has been created, return it; otherwise, return null. <p>
    327         *
    328         * This function should only be called by OutsideEnv. <p>
    329         */
    330        //@ requires \nonnullelements(P);
    331        static public TypeSig lookup(/*@non_null*/ String[] P, /*@ non_null @*/ String T) {
    332            return (TypeSig)map.get(getKey(P,T));
    333        }
    334
    335            // FIXME - the type lookup ends up parsing a qualified name into
    336            // pieces and then reassembling them through getKey into a
    337            // qualified name.  This could be improved by providing a
    338            // direct lookup from a fully qualified name
    339
    340        /**
    341         * If a TypeSig representing the package-member type named P.T
    342         * has been created, return it; otherwise, create such a TypeSig
    343         * then return it. <p>
    344         *
    345         * This function should only be called by OutsideEnv. <p>
    346         */
    347        //@ requires \nonnullelements(P);
    348        //@ ensures \result != null;
    349        static /*package*/ TypeSig get(/*@non_null*/ String[] P, /*@ non_null @*/ String T) {
    350            String key = getKey(P,T);
    351            TypeSig result = (TypeSig)map.get(key);
    352            if (result != null)
    353                return result;
    354
    355            result = Types.makeTypeSig(P, T, (TypeSig)null, (TypeDecl)null,
    356                                      (CompilationUnit)null);
    357            map.put(key, result);
    358            return result;
    359        }
    360
    361        /***************************************************
    362         *                                                 *
    363         * Lazy loading of TypeDecls:                      *
    364         *                                                 *
    365         **************************************************/
    366
    367        /**
    368         * Get the non-null TypeDecl we are associated with. <p>
    369         *
    370         * (Under the covers, for package-member types, this method may
    371         * cause <code>OutsideEnv</code> to parse the
    372         * <code>TypeDecl</code> in question, but this should be
    373         * transparent to most clients.) <p>
    374         */
    375        //@ ensures \result != null;
    376        //@ ensures state>=PARSED;
    377        public TypeDecl getTypeDecl() {
    378            if (myTypeDecl==null)
    379                 preload();
    380
    381            return myTypeDecl;
    382        }
    383
    384        /**
    385         * Get the non-null CompilationUnit we are associated with. <p>
    386         *
    387         * (Under the covers, for package-member types, this method may
    388         * cause <code>OutsideEnv</code> to parse the type in question,
    389         * but this should be transparent to most clients.) <p>
    390         */
    391        //@ ensures \result != null;
    392        public CompilationUnit getCompilationUnit() {
    393            if (myTypeDecl==null)
    394                 preload();
    395
    396            return CU;
    397        }
    398
    399
    400        /**
    401         * Ensure that we have loaded our TypeDecl, invoking OutsideEnv
    402         * if needed to load a TypeDecl into us via load below.  We abort
    403         * via an assertion failure if OutsideEnv fails to load us.
    404         */
    405        //@ ensures myTypeDecl != null;
    406        private void preload() {
    407            if (myTypeDecl != null)
    408                return;
    409
    410            /*
    411             * This call should always call our load method (below) with a
    412             * TypeDecl.
    413             */
    414            OutsideEnv.load(this);
    415            Assert.notNull(myTypeDecl);
    416        }
    417
    418
    419        /*
    420         * The below functions are provided for use by OutsideEnv in
    421         * loading us.
    422         */
    423
    424
    425        /**
    426         * Is our TypeDecl already loaded?
    427         */
    428        //@ ensures !member ==> \result;
    429        //@ ensures \result == (myTypeDecl != null);
    430        public boolean isPreloaded() {
    431            return myTypeDecl != null;
    432        }
    433
    434
    435        /**
    436         * Load the non-null TypeDecl decl as our TypeDecl.
    437         * This method is used by OutsideEnv to install a TypeDecl in us once
    438         * it has been loaded.<p>
    439         *
    440         * If we have already been loaded with a different TypeDecl, then
    441         * an appropriate fatal error results. <p>
    442         *
    443         * Note: This method should *only* be called by OutsideEnv.load.<p>
    444         *
    445         * CU must be the CompilationUnit that decl belongs to.<p>
    446         */
    447        //@ ensures myTypeDecl != null;
    448        /*package*/ void load(/*@ non_null @*/ TypeDecl decl,
    449                              /*@ non_null @*/ CompilationUnit CU) {
    450            // If no (potential) duplication, just install decl and return:
    451            if (myTypeDecl==null) {
    452                setDecl(decl, CU);
    453                return;
    454            }
    455
    456            if (myTypeDecl==decl && this.CU==CU)
    457                return;
    458
    459            ErrorSet.fatal(decl.loc, "type " + this.getExternalName()
    460                    + " already defined at "
    461                    + Location.toString(myTypeDecl.loc));
    462        }
    463
    464        /***************************************************
    465         *                                                 *
    466         * Name accessor functions:                        *
    467         *                                                 *
    468         **************************************************/
    469
    470        /**
    471         * Return our package name as a human-readable string
    472         * suitable for display.  If we are in the unnamed package,
    473         * the constant THE_UNNAMED_PACKAGE is returned.
    474         */
    475        //@ ensures \result != null;
    476        public String getPackageName() {
    477          if (packageName.length == 0)
    478            return THE_UNNAMED_PACKAGE;
    479
    480          StringBuffer P = new StringBuffer(5*packageName.length);
    481          for (int i = 0; i < packageName.length; i++) {
    482            if (i != 0)
    483              P.append('.');
    484            P.append(packageName[i]);
    485          }
    486
    487          return P.toString();
    488        }
    489
    490        public final static String THE_UNNAMED_PACKAGE = "<the unnamed package>";
    491
    492
    493        /**
    494         * Return our exact type name, omitting the package name, as a
    495         * human-readable string suitable for display.
    496         */
    497        //@ ensures \result != null;
    498        public String getTypeName() {
    499            if (enclosingType==null) {
    500                // package-member type:
    501                return simpleName;
    502            }
    503
    504            String parent = enclosingType.getTypeName();
    505            if (member)
    506                return parent+"$"+simpleName;
    507            if (simpleName != null)
    508                return parent+"$"
    509                    +Location.toLineNumber(getTypeDecl().getStartLoc())+"$"
    510                    +simpleName;
    511            else
    512                return parent+"$"
    513                    +Location.toLineNumber(getTypeDecl().getStartLoc())+"$"
    514                    +"<anonymous>";
    515        }
    516
    517
    518        /**
    519         * Return our exact fully-qualified external name as a
    520         * human-readable string suitable for display.  The package name is
    521         * omitted if it is the unnamed package.
    522         */
    523        //@ ensures \result != null;
    524         public String getExternalName() {
    525             String P = getPackageName();
    526             if (P==THE_UNNAMED_PACKAGE)
    527                 return getTypeName();
    528             else
    529                 return P+"."+getTypeName();
    530         }
    531
    532
    533        /**
    534         * Returns a String that represents the value of this Object.
    535         */
    536        public String toString() {
    537            return getExternalName();
    538        }
    539
    540        /***************************************************
    541         *                                                 *
    542         * ASTNode functions:                              *
    543         *                                                 *
    544         **************************************************/
    545
    546        public int childCount() {
    547            return 0;
    548        }
    549
    550        public Object childAt(int i) {
    551            throw new IndexOutOfBoundsException();
    552        }   //@ nowarn Exception;
    553
    554        public int getTag() {
    555            return TagConstants.TYPESIG;
    556        }
    557
    558        public void accept(Visitor v) {
    559            // v does not have a special visitor method for TypeSig
    560            // so just use the one for Type
    561            v.visitType( this );
    562        }
    563
    564
    565        public Object accept(VisitorArgResult v, Object o) {
    566            return v.visitType( this,o );
    567        }
    568
    569    /*
    570        // We don't promise any meaningful locations...
    571        //@ invariant !syntax;
    572        {
    573            // Deal with can't handle non-injective fields & invariants problem:
    574            //@ assume (\forall MethodDecl m; m.returnType != this);
    575            //@ assume (\forall GenericVarDecl g; g.type != this);
    576            //@ set syntax = false;
    577        }
    578    */
    579
    580        public int getStartLoc() {
    581            return getTypeDecl().getStartLoc();
    582        }
    583
    584        public int getEndLoc() {
    585            return getTypeDecl().getEndLoc();
    586        }
    587
    588        /***************************************************
    589         *                                                 *
    590         * Looking up type members:                        *
    591         *                                                 *
    592         **************************************************/
    593
    594        /**
    595         * Do we have a type member named id (including inherited type
    596         * members)? <p>
    597         *
    598         * If we have exactly one such type member, then return it.  If
    599         * we have no such type member, return null.  If we have more
    600         * than one such type member, then if loc != Location.NULL then a
    601         * fatal error is reported at that location via ErrorSet else one
    602         * of the relevant type members is returned.<p>
    603         *
    604         * If caller is null, this routine does not check that the
    605         * resulting type (if any) is accessible.  If caller is not
    606         * null, then the resulting type is checked to be accessible
    607         * from the caller. <p>
    608         */
    609        public TypeSig lookupType(TypeSig caller,
    610                                    /*@ non_null @*/ Identifier id, int loc) {
    611            // Look locally first:
    612            TypeSig result = lookupLocalType(caller,id);
    613            if (result != null)
    614                return result;
    615
    616            /*
    617             * Then try our superclass (if any):
    618             */
    619            resolveSupertypeLinks();
    620            TypeSig s = superClass();
    621            if (s != null) {
    622                result = s.lookupType(caller,id,loc);
    623            }
    624
    625            /*
    626             * and our superinterfaces, checking for duplicates:
    627             */
    628            TypeDecl decl = getTypeDecl();
    629            for (int i=0; i<decl.superInterfaces.size(); i++ ) {
    630                TypeName superInterfaceName = decl.superInterfaces.elementAt(i);
    631                TypeSig newResult = getSig(superInterfaceName).lookupType(caller,id, loc);
    632                if (newResult==null)
    633                    continue;
    634
    635                if (result==null || result==newResult)
    636                    result = newResult;
    637                else {
    638                    if (loc != Location.NULL)
    639                        ErrorSet.fatal(loc, "Reference to type member `"
    640                                       + id.toString()
    641                                       + "' of type " + toString()
    642                                       + " is ambiguous; it may refer to type "
    643                                       + result.toString()
    644                                       + " or to type "
    645                                       + newResult.toString()
    646                                       + ".");
    647                    else
    648                        return result;
    649                }
    650            }
    651
    652            return result;
    653        }
    654
    655
    656        /**
    657         * Do we have a type member named id (*not* including inherited
    658         * type members)?  If so, return it; otherwise, return null. <p>
    659         *
    660         * If caller is null, then this routine does not check that the
    661         * resulting type (if any) is actually accessable. If caller is
    662         * non_null, then the resulting type is checked that it is
    663         * accessible from the caller.<p>
    664         */
    665
    666         public TypeSig lookupLocalType(TypeSig caller, Identifier id) {
    667            TypeDeclElemVec elems = getTypeDecl().elems;
    668            for (int i=0; i<elems.size(); i++) {
    669                TypeDeclElem e = elems.elementAt(i);
    670                if (e instanceof TypeDecl && ((TypeDecl)e).id==id) {
    671                    TypeDecl td = (TypeDecl)e;
    672                    TypeSig t = getSig(td);
    673                    if (caller == null) return t;
    674                    TypeSig c = caller;
    675                    do {
    676                        if (TypeCheck.inst.canAccess(c, this, td.modifiers,
    677                                                        td.pmodifiers) ) {
    678                            return t;
    679                        }
    680                        c = c.enclosingType;
    681                    } while (c != null);
    682                }
    683            }
    684            return null;
    685        }
    686
    687        /***************************************************
    688         *                                                 *
    689         * Environments:                                   *
    690         *                                                 *
    691         **************************************************/
    692
    693        /**
    694         * Return our enclosing environment.
    695         */
    696        //@ ensures \result != null;
    697        public Env getEnclosingEnv() {
    698            if (enclosingEnv != null)
    699                return enclosingEnv;
    700
    701            if (enclosingType==null)
    702                enclosingEnv = new EnvForCU(getCompilationUnit());
    703            else
    704                enclosingEnv = enclosingType.getEnv(isStatic());
    705
    706            return enclosingEnv;
    707        }
    708
    709
    710        /**
    711         * Return an environment for use in checking code inside us. <p>
    712         *
    713         * Our instance members are considered accessible iff
    714         * staticContext is false.
    715         */
    716        //@ ensures \result != null;
    717        public EnvForTypeSig getEnv(boolean staticContext) {
    718            return new EnvForTypeSig(getEnclosingEnv(), this, staticContext);
    719        }
    720
    721        /***************************************************
    722         *                                                 *
    723         * Misc:                                           *
    724         *                                                 *
    725         **************************************************/
    726
    727        /**
    728         * Are we (possibly implicitly) static? <p>
    729         *
    730         * This differs from using Modifiers.isStatic because it does not
    731         * rely on Prep'ing having added the static modifier where
    732         * implicit so we can be used by Prep itself.
    733         */
    734        public boolean isStatic() {
    735            if (Modifiers.isStatic(getTypeDecl().modifiers))
    736                return true;
    737
    738            // interfaces are implicitly static:
    739            if (getTypeDecl() instanceof InterfaceDecl)
    740                return true;
    741
    742            // interface members are implicitly static:
    743            if (enclosingType != null &&
    744                enclosingType.getTypeDecl() instanceof InterfaceDecl)
    745                return true;
    746
    747            return false;
    748        }
    749
    750
    751        /**
    752         * Are we a top-level type? <p>
    753         *
    754         * True iff either we are a package-level type or a static member
    755         * of a top-level type. <p>
    756         *
    757         * Note: This may be called during any state; it may bump
    758         * TypeSigs to the Parsed state. <p>
    759         */
    760        //@ ensures enclosingType==null ==> \result;
    761        public boolean isTopLevelType() {
    762            if (enclosingType==null)
    763                return true;
    764
    765            if (!isStatic())
    766                return false;
    767
    768            return enclosingType.isTopLevelType();
    769        }
    770
    771        //************************************************************
    772        //************************************************************
    773        //************************************************************
    774        //************************************************************
    775        //************************************************************
    776
    777        /***************************************************
    778         *                                                 *
    779         * TypeSig states and transition functions:        *
    780         *                                                 *
    781         **************************************************/
    782
    783        /*
    784         * The states that a TypeSig can be in.  The variable state (below)
    785         * holds our current state, which must be one of the following
    786         * values:
    787         */
    788        public final static int CREATED             = 1;
    789        public final static int PARSED              = 2;
    790        public final static int RESOLVINGLINKS      = 3;  // used by SLResolution
    791        public final static int LINKSRESOLVED       = 4;
    792        public final static int PREPPED             = 5;
    793        public final static int CHECKED             = 6;
    794
    795        /**
    796         * The current state of <code>this</code>.  Must be one of
    797         * <code>CREATED</code>, <code>PARSED</code>,
    798         * <code>LINKSRESOLVED</code>, <code>PREPPED</code>, or
    799         * <code>CHECKED</code>.  In most circumstances, this field
    800         * should not be written to; rather, methods of
    801         * <code>TypeSig</code> should be called to effect changes to it.
    802         * This field must never be decreased after creation time.
    803         */
    804        public int state = CREATED;
    805
    806
    807        /*
    808         * Note: The transition to PARSED from CREATED is performed
    809         * automatically by setDecl.
    810         */
    811
    812        /**
    813         * Transition <code>this</code> to the supertype links resolved
    814         * state. <p>
    815         *
    816         * See the TypeSig type comments for details of what this involves.<p>
    817         *
    818         * A fatal error may be reported if we cannot resolve a supertype
    819         * name, or detect a cycle in the type hierarchy.<p>
    820         */
    821        //@ modifies state;
    822        //@ ensures state>=TypeSig.LINKSRESOLVED;
    823        public void resolveSupertypeLinks() {
    824            if (state<LINKSRESOLVED)
    825                SLResolution.transition(this);
    826        }
    827
    828        /**
    829         * Transition <code>this</code> to the "prepped" state. <p>
    830         *
    831         * A prepped declaration has all of the <code>TypeName</code>
    832         * nodes defining the types of its members resolved.  For a field
    833         * declaration, this means resolving the <code>type</code> field;
    834         * For a routine declaration, this means resolving
    835         * <code>TypeName</code>s that occur in the <code>args</code>,
    836         * <code>raises</code>, and <code>returnType</code> fields.<p>
    837         *
    838         * See the TypeSig type comments for more details of what this
    839         * involves.<p>
    840         */
    841        //@ modifies state;
    842        //@ ensures state >= PREPPED;
    843        public void prep() {
    844            if (state >= TypeSig.PREPPED)
    845                return;
    846
    847            if (Info.on) Info.out("[prepping-slinks " + this + "]");
    848            resolveSupertypeLinks();
    849            if (Info.on) Info.out("[prepping " + this + "]");
    850            PrepTypeDeclaration.inst.prepTypeSignature(this);
    851            if (Info.on) Info.out("[prepping-complete " + this + "]");
    852
    853            state = TypeSig.PREPPED;
    854        }
    855
    856        /**
    857         * Transition <code>this</code> to the "checked" state. <p>
    858         *
    859         * See the TypeSig type comments for details of what this involves.<p>
    860         *
    861         * A fatal error may be reported if we cannot resolve a supertype
    862         * name, or detect a cycle in the type hierarchy.<p>
    863         */
    864        //@ modifies state;
    865        //@ ensures state >= CHECKED;
    866        public void typecheck() {
    867            if (this.state >= TypeSig.CHECKED)
    868                return;
    869            if (this.state < TypeSig.PREPPED)
    870                prep();
    871
    872            typecheckSuperTypes();
    873            long start = 0;
    874            if (Info.on) start = javafe.Tool.currentTime();
    875            if (Info.on) Info.out("[typechecking " + this + "]");
    876            TypeCheck.inst.makeFlowInsensitiveChecks().checkTypeDeclaration(this);
    877            if (Info.on) Info.out("[typechecking-end " + this + " " + javafe.Tool.timeUsed(start) + "]");
    878            // @review kiniry 31 Aug - Why is this commented out?
    879            // FlowSensitiveChecks.checkTypeDeclaration(this);
    880            this.state = TypeSig.CHECKED;
    881        }
    882
    883      /**
    884       * Typecheck the superclass of the current classtype being typecheck and
    885       * typecheck all interfaces that the current classtype implements.
    886       */
    887        public void typecheckSuperTypes() {
    888            TypeSig t = superClass();
    889            // If we are typechecking an inner class whose parent is the enclosing
    890            // environment, then do not try to typecheck the parent as that is what we
    891            // are doing at this moment!
    892            if ((t != null) && getEnclosingEnv().getEnclosingClass() != enclosingType)
    893              t.typecheck();
    894            TypeDecl decl = getTypeDecl();
    895            for (int i=0; i<decl.superInterfaces.size(); i++ ) {
    896                TypeName superInterfaceName = decl.superInterfaces.elementAt(i);
    897                TypeSig ts = getSig(superInterfaceName);
    898                ts.typecheck();
    899            }
    900        }
    901
    902        /***************************************************
    903         *                                                 *
    904         * Looking up fields, methods, and constructors:   *
    905         *                                                 *
    906         **************************************************/
    907
    908        //// Fields and methods associated with preparation of a TypeSig
    909
    910        /** After preparation, this field contains all field members of
    911        the <code>TypeDecl</code> associated with <code>this</code>,
    912        including inherited ones. */
    913
    914        // "invariant" fields.<each element>.hasParent
    915        //@ invariant state>=PREPPED ==> fields != null;
    916        //@ spec_public
    917        protected FieldDeclVec fields;
    918
    919        // Note: 'fields' contains all visible fields
    920        // 'hiddenfields' contains all the others (e.g. hidden or not accessible)
    921        //@ invariant state>=PREPPED ==> hiddenfields != null;
    922        protected FieldDeclVec hiddenfields;
    923
    924        /** After preparation, this field contains all method members of
    925        the <code>TypeDecl</code> associated with <code>this</code>,
    926        including inherited ones. */
    927
    928        // "invariant" methods.<each element>.hasParent
    929        //@ invariant state>=PREPPED ==> methods != null;
    930        //@ spec_public
    931        protected MethodDeclVec methods;
    932
    933        /** Returns all fields of the type declaration associated with
    934        <code>this</code>, including inherited ones.  (If
    935        <code>this</code> has not been prepped yet, this method will prep
    936        it (possibly triggering parsing and/or processing of other
    937        types).) If allFields is true, then all declared fields, including
    938        hidden and inaccessible fields, are returned; if allFields is false,
    939        then only visible fields are returned.  */
    940
    941        // "ensures" <result elements>.hasParent
    942        //@ ensures \result != null;
    943        public FieldDeclVec getFields(boolean allFields) {
    944            prep();
    945            Assert.notNull( fields );
    946            if (!allFields) return fields;
    947            FieldDeclVec v = fields.copy();
    948            v.append(hiddenfields);
    949            return v;
    950        }
    951
    952        public FieldDeclVec getFieldsRaw() { return fields; }
    953
    954        public FieldDeclVec getHiddenFields() { return hiddenfields; }
    955
    956        /** Similar to <code>getFields</code>, except for methods. */
    957
    958        // "ensures" <result elements>.hasParent
    959        //@ ensures \result != null;
    960        public MethodDeclVec getMethods() {
    961            prep();
    962            Assert.notNull( methods );
    963            return methods;
    964        }
    965
    966
    967        /** TBW */
    968
    969        //@ requires \nonnullelements(args) && caller != null;
    970        //@ ensures \result != null;
    971        public ConstructorDecl lookupConstructor(Type[] args, TypeSig caller)
    972                throws LookupException
    973        {
    974            prep();
    975
    976            // Holds the most specific, applicable, accessible constructor found so far
    977            ConstructorDecl mostSpecific = null;
    978            boolean somethingFound = false;
    979            TypeDecl decl = getTypeDecl();
    980
    981            search:
    982            for(int i = 0; i < decl.elems.size(); i++) {
    983                TypeDeclElem elem = decl.elems.elementAt(i);
    984                if (elem instanceof ConstructorDecl) {
    985                    ConstructorDecl md = (ConstructorDecl)elem;
    986                    if (md.args.size() == args.length
    987                        && TypeCheck.inst.canAccess(caller, this, md.modifiers,
    988                                                    md.pmodifiers) ) {
    989                        // accessible, same name and number of args
    990
    991                        somethingFound = true;
    992                        for(int j = 0; j < args.length; j++)
    993                            if (! Types.isInvocationConvertable(args[j],
    994                                                                md.args.elementAt(j).type))
    995                                continue search;
    996                        // accessible and applicable
    997
    998                        if (mostSpecific == null ||
    999                            Types.routineMoreSpecific(md, mostSpecific))
    1000                            mostSpecific = md;
    1001                        else if (! Types.routineMoreSpecific(mostSpecific, md))
    1002                            throw new LookupException( LookupException.AMBIGUOUS );
    1003                    }
    1004                }
    1005            }
    1006
    1007            if (mostSpecific != null)
    1008                return mostSpecific;
    1009            else if (somethingFound)
    1010                throw new LookupException( LookupException.BADTYPECOMBO );
    1011            else
    1012                throw new LookupException( LookupException.NOTFOUND );
    1013        }
    1014
    1015        /** TBW */
    1016
    1017        //@ ensures \result != null;
    1018        //@ ensures \result.id == id;
    1019        public FieldDecl lookupField(Identifier id, /*@ non_null */ TypeSig caller)
    1020                throws LookupException
    1021        {
    1022            FieldDeclVec fields = getFields(false);
    1023            FieldDecl r = null;
    1024            for(int i=0; i<fields.size(); i++ ) {
    1025                FieldDecl fd = fields.elementAt(i);
    1026                if (fd.id == id)
    1027                    if (r == null) r = fd;
    1028                    else throw new LookupException( LookupException.AMBIGUOUS );
    1029            }
    1030
    1031            if (r == null)
    1032                throw new LookupException( LookupException.NOTFOUND );
    1033            else if (! TypeCheck.inst.canAccess(caller, this, r.modifiers,
    1034                                                r.pmodifiers))
    1035                throw new LookupException( LookupException.NOTACCESSIBLE );
    1036            else return r;
    1037        }
    1038
    1039
    1040        /** TBW */
    1041
    1042        public boolean hasField(Identifier id) {
    1043            FieldDeclVec fields = getFields(false);
    1044            for(int i=0; i<fields.size(); i++)
    1045                if (fields.elementAt(i).id == id) return true;
    1046            return false;
    1047        }
    1048
    1049        public MethodDecl hasMethod(Identifier id, Type[] args) {
    1050            try {
    1051                return lookupMethod(id,args,this);
    1052            } catch (LookupException e) {
    1053                return null;
    1054            }
    1055        }
    1056
    1057        /** TBW */
    1058
    1059        //@ requires \nonnullelements(args) && caller != null;
    1060        //@ ensures \result != null;
    1061        //@ ensures \result.id == id;
    1062        public MethodDecl lookupMethod(Identifier id, Type[] args, TypeSig caller)
    1063                throws LookupException
    1064        {
    1065            MethodDeclVec methods = getMethods();
    1066
    1067            // Holds the most specific, applicable, accessible method found so far
    1068            MethodDecl mostSpecific = null;
    1069            boolean somethingFound = false;
    1070
    1071            search:
    1072            for(int i = 0; i < methods.size(); i++) {
    1073                MethodDecl md = methods.elementAt(i);
    1074                if (md.id == id
    1075                    && md.args.size() == args.length
    1076                    && TypeCheck.inst.canAccess(caller, this, md.modifiers,
    1077                                                md.pmodifiers)) {
    1078                    // accessible, same name and number of args
    1079
    1080                    somethingFound = true;
    1081                    for(int j=0; j<args.length; j++) {
    1082                        // FIXME - the argument (particularly the second) might be just a
    1083                        // Typename - ought to resolve it once and for all, instead of doing so
    1084                        // each time the following method is called.
    1085                        if(! Types.isInvocationConvertable(args[j],
    1086                                                           md.args.elementAt(j).type)) {
    1087                            continue search;
    1088                        }
    1089                    }
    1090                    // accessible and applicable
    1091
    1092                    if (mostSpecific == null
    1093                        || Types.routineMoreSpecific(md, mostSpecific))
    1094                        mostSpecific = md;
    1095                    else if (! Types.routineMoreSpecific(mostSpecific, md))
    1096                        throw new LookupException( LookupException.AMBIGUOUS );
    1097                }
    1098            }
    1099
    1100            if (mostSpecific != null)
    1101                return mostSpecific;
    1102            else if (somethingFound)
    1103                throw new LookupException( LookupException.BADTYPECOMBO );
    1104            else
    1105                throw new LookupException( LookupException.NOTFOUND );
    1106        }
    1107
    1108        //************************************************************
    1109        //************************************************************
    1110        //************************************************************
    1111        //************************************************************
    1112        //************************************************************
    1113
    1114    /**
    1115
    1116      A <code>TypeSig</code> is a proxy and adaptor for <a
    1117      href="javafe.ast.TypeDecl.html"><code>TypeDecl</code></a>.<p>
    1118
    1119      They are proxies because, during name resolution, <a
    1120      href="javafe.ast.TypeName.html"><code>TypeName</code></a> objects are
    1121      resolved to point to <code>TypeSig</code> objects rather than directly
    1122      to <code>TypeDecl</code> objects. This gives us the flexibility of
    1123      deferring parsing of a type declaration until we know we need detailed
    1124      information about it.<p>
    1125
    1126      They are adaptors because they provide extra functionality not provided
    1127      by <code>TypeDecl</code> objects.  In particular, they provide lookup
    1128      methods that allow clients to find particular members of a type
    1129      declaration (including inherited members), and resolve methods that
    1130      perform name resolution inside the implementation of a type
    1131      declaration.<p>
    1132
    1133      <i>What about the fact that we are a subtype of <code>Type</code>?</i>
    1134
    1135
    1136      <h3> Interning </h3>
    1137
    1138      <code>TypeSig</code> objects are meant to be "interned"; that is, for
    1139      each <i>canonical</i> <code>TypeDecl</code>, we want there to be exactly
    1140      one associated <code>TypeSig</code> object.  The first
    1141      <code>TypeDecl</code> loaded by the system for a given typename is
    1142      considered to be the canonical <code>TypeDecl</code> for that typename;
    1143      all other <code>TypeDecl</code>s for that typename are considered
    1144      non-canonical.<p>
    1145
    1146      To achieve this interning, clients of the <code>javafe.tc</code> package
    1147      should not directly create <code>TypeSig</code> objects; rather, they
    1148      should rely on <code>javafe.tc</code> to create <code>TypeSig</code>
    1149      objects for them.  Similarly, clients of the <code>javafe.tc</code>
    1150      package should rely on <code>javafe.tc</code> to do the parsing
    1151      necessary to create instances of <code>TypeDecl</code>.  Not only will
    1152      the <code>javafe.tc</code> package intern <code>TypeSig</code> objects,
    1153      it will also ensure that, for <code>TypeSig s</code> and <code>TypeDecl
    1154      d,</code><ul>
    1155
    1156      <li> <code>s.getTypeDecl()</code> is always a canonical <code>TypeDecl</code>
    1157
    1158      <li> <code>s.getTypeDecl().sig == s</code>
    1159
    1160      <li> if <code>d</code> is canonical then <code>d.sig.getTypeDecl()==d</code>
    1161
    1162      <li> if <code>d</code> is not canonical then <code>d.sig</code> is the
    1163      <code>TypeSig</code> associated with <code>d</code>'s typename.</ul>
    1164
    1165      <i>What is the interface for clients within the <code>javafe.tc</code>
    1166      package?</i><p>
    1167
    1168
    1169
    1170      <h3> Staging the processing of type declarations </h3><p>
    1171
    1172      Resolving the names in a type declaration and checking its static
    1173      semantics usually involves looking at other declarations to which it
    1174      refers.  Finding, reading, and processing referred-to types makes
    1175      resolution and checking fairly complicated.  As a result, we have
    1176      decomposed it into smaller steps.  Type declarations move through a
    1177      number of states as the resolution and checking process proceeds.  In
    1178      addition to making the overall processing of type declarations
    1179      conceptually more manageable, this decomposition has two other
    1180      benefits:<ul>
    1181
    1182
    1183      <li> <i>Handling cycles</i>. As mentioned above, processing one type may
    1184      involve processing types to which it refers.  However, two types may
    1185      refer to each other, making it impossible to process any one of them
    1186      "first."  Decomposing the processing into stages helps us handle such
    1187      cycles.
    1188
    1189      <li> <i>Improving performance</i>. Processing one type declaration does
    1190      not require fully processing the declarations to which it refers.  How
    1191      much processing is required of a referred-to type depends on the manner
    1192      in which it is referred (e.g., the superclass of a class requires more
    1193      processing than a type referred to by another type referred to by the
    1194      class).  Decomposing processing into stages allows us to be lazy in
    1195      processing referred-to types; that is, it allows us to process them only
    1196      to the extent that is necessary and no further.</ul>
    1197
    1198
    1199      The rest of this section details the states through which a
    1200      <code>TypeSig</code> object moves during its lifetime.  Most clients of
    1201      the <code>javafe.tc</code> package do not need to know about these
    1202      details.  However, clients interested in extending the processing done
    1203      by the <code>javafe.tc</code> package may need to add other states as
    1204      well.  Also, this documentation gives an overview of the
    1205      <code>javafe.tc</code> package for those interested in understanding its
    1206      implementation.<p>
    1207
    1208      <code>TypeSig</code>s start in the <i><code>TypeSig</code> created</i>
    1209      state then move sequentially through the following four states:
    1210      <i>parsed</i>, <i>supertype links resolved</i>, <i>prepped</i>, and
    1211      <i>checked</i>.  Each following state represents additional processing
    1212      completed on top of the processing required for the previous state.  A
    1213      description of these states in reverse order follows.  Included are the
    1214      properties that hold in each state; these properties are "additive":
    1215      properties of states later in the list are also properties of states
    1216      earlier in the list.<ul>
    1217
    1218      <li> <i>Checked.</i> Type declarations in this state have been fully
    1219      disambiguated, resolved and checked (see <a
    1220      href="javafe.tc.TypeCheck.html"> <code>TypeCheck</code> </a> for the
    1221      definitions of disambiguation, resolution, and checking).
    1222      Transitioning to this state can trigger parsing and/or preparation of
    1223      types referenced (<i>where?</i>) either explicitly or implicitly.
    1224      Implicitly referenced types are types used but not explicitly
    1225      mentioned in a <code>TypeName</code> node (<i>huh?</i>); for example,
    1226      the type of the result of <code>foo</code> in the expression
    1227      "<code>bar(x.foo())</code>" is implicitly referenced by this
    1228      expression.<p>
    1229
    1230
    1231      <li> <i>Prepped.</i> When checking a type declaration, we need to look
    1232      up members of other type declarations it uses.  Before looking up
    1233      members of these referred-to declarations, it is useful to do some work
    1234      on them first, such as building internal tables.  <code>TypeSig</code>s
    1235      in the prepped state have had such work done on their declarations,
    1236      preparing them for having their members queried.  As a convenience, the
    1237      methods of <code>TypeSig</code> that lookup the members of a type
    1238      declaration, such as <A href="#lookupField(javafe.ast.Identifier,
    1239      javafe.tc.TypeSig)"> <code>lookupField</code></A> and <A
    1240      href="#lookupMethod(javafe.ast.Identifier, javafe.ast.Type[],
    1241      javafe.tc.TypeSig)"> <code>lookupMethod</code></a>, automatically
    1242      transition the declaration (<i><code>TypeSig</code></i>?) to the prepped
    1243      state if it isn't there already.<p>
    1244
    1245      When preparing the declaration associated with a <code>TypeSig</code>,
    1246      it is also useful to report certain errors in it, such as two fields
    1247      with the same name.  This way, when checking a class, the user will also
    1248      see a report of errors in the interfaces (but not the implementations)
    1249      of the classes used by the class being checked.<p>
    1250
    1251      The prepped state is <i>supertype transitive</i>: a state <i>X</i> is
    1252      supertype transitive if a <code>TypeSig</code> can only be in state
    1253      <i>X</i> if all its supertypes are at least in state <i>X</i>.  Note
    1254      that there is no requirement that <i>X</i>'s type members be in any
    1255      particular state.<p>
    1256
    1257
    1258      <li> <i>Supertype links resolved.</i> When preparing or checking a type
    1259      declaration, we may need to ask if one type referred to by the
    1260      declaration is a supertype of another.  To perform this query, we need
    1261      to resolve supertype links.  After parsing, the supertypes of a type
    1262      declaration are represented as <code>TypeName</code>s, which are
    1263      symbolic references.  Resolution of a <code>TypeName</code> object
    1264      involves pointing its <code>sig</code> field to the <code>TypeSig</code>
    1265      object for the type declaration to which the <code>TypeName</code>
    1266      symbolically refers.  Resolving the supertype links of type declarations
    1267      separately from preparing them allows us to perform supertype checks
    1268      during the preparation process.<p>
    1269
    1270      As a convenience, the <code>isSubtypeOf</code> method of
    1271      <code>TypeSig</code>, which performs the supertype test, automatically
    1272      resolves supertype links if they have not been resolved already.<p>
    1273
    1274      Like the prepped state, the "supertype links resolved" state is
    1275      supertype transitive.<p>
    1276
    1277
    1278      <li> <i>Parsed</i>.  Although many <code>TypeSig</code>s come into
    1279      existence when their type declarations are parsed, some of them can be
    1280      created earlier.  Thus, we can distinguish <code>TypeSig</code>s that
    1281      have been parsed from those that have not.  However, it is difficult for
    1282      a client outside <code>javafe.tc</code> to know whether or not a
    1283      <code>TypeSig</code> has been parsed.  This is because, if a client
    1284      calls <a href="#getTypeDecl()"> <code>getTypeDecl</code></a> on a
    1285      <code>TypeSig</code> that has not been parsed, it will be parsed
    1286      automatically.<p>
    1287
    1288
    1289      <li> <i><code>TypeSig</code> created</i>.  This is the initial state
    1290      of <code>TypeSig</code> objects that come into existence before their
    1291      corresponding declarations have been parsed.  Again, it is it is
    1292      difficult for a client outside <code>javafe.tc</code> to to distinguish
    1293      between this state and the parsed state.</ul>
    1294
    1295
    1296
    1297
    1298      <h3> More internal details </h3>
    1299
    1300      <p> This section contains a few more details about the implementation
    1301      for those who wish to understand it.
    1302
    1303      <p> Inside the <code>javafe.tc</code> package, creation of
    1304      <code>TypeSig</code> and <code>TypeDecl</code> objects is managed by
    1305      the <a href="javafe.tc.OutsideEnv.html"> <code>OutsideEnv</code>
    1306      </a> class.  Methods of this class take the fully-qualified name of
    1307      an "package-member type" -- that is, a type declaration not nested
    1308      inside another declaration -- and return the <code>TypeSig</code>
    1309      instance associated with the type declaration denoted by that name.
    1310      <code>OutsideEnv</code> also coordinates the parsing of type
    1311      declarations, ensuring that only one <code>TypeDecl</code> is
    1312      created for a type declaration, and ensuring that
    1313      <code>TypeSig</code> objects point to the appropriate
    1314      <code>TypeDecl</code> objects.
    1315
    1316      <p> The <code>OutsideEnv</code> uses direct instances of
    1317      <code>TypeSig</CODE> for nested types only.  It uses a special subclass
    1318      of <code>TypeSig</code>, <code>TopTypeSig</code>, for externally
    1319      nameable types (what the Java spec calls "top-level types").  This
    1320      subclass has fields giving the types external name.  A further subclass
    1321      of <code>TopTypeSig</code>, <code>OutsideTypeSig</code>, handles outside
    1322      types.  Alone among <code>TypeSigs</code>, <code>OutsideTypeSig</code>s
    1323      have the the ability to load their <code>TypeDecl</code> objects lazily.
    1324      All other <code>TypeSig</code> classes must have their
    1325      <code>TypeDecl</code> provided at creation time.  However, this is an
    1326      implementation issue only: clients outside of <code>javafe.tc</code>
    1327      should not assume the existence of these subclasses.
    1328
    1329      <p> Transitioning a <code>TypeSig</code> from one state to another may
    1330      require parsing and processing of other types such as supertypes or the
    1331      types found in method signatures.  For example, checking that the
    1332      <code>throws</code> clause of a method override is legal may involve
    1333      checking a subtype relationship, which requires that types involved be
    1334      supertype-link resolved.  We call transitions that arise in the process
    1335      of another transitions "secondary transitions."  The code that
    1336      implements transitions does not have to explicitly invoke secondary
    1337      transitions; rather, they are performed by calling methods like
    1338      <code>lookupField</code> or <code>isSubtypeOf</code>, whose
    1339      implementations <em>do</em> invoke transitions if they are needed.  For
    1340      example, the method that implements the preparation transition does not
    1341      directly call the method that implements supertype link resolution, but
    1342      it <em>does</code> call <code>isSubtypeOf</code>, which in turn does
    1343      directly call the supertype link resolution method.  Thus, secondary
    1344      transitions are largely transparent to the code implementing each
    1345      transition, with one exception.  The code implementing the transition to
    1346      one state can<em>not</em> invoke methods that automatically transition
    1347      types to a higher state.  For example, the code implementing supertype
    1348      link resolution cannot call <code>lookupField</code>.  This discipline
    1349      helps us avoid looping.
    1350
    1351
    1352    @see OutsideEnv
    1353    @see TypeCheck
    1354    @see TypeDecl
    1355    @see TypeName
    1356
    1357      */
    1358
    1359        /**
    1360         * Gets the TypeSig recorded by <code>setSig</code>, or null.
    1361         */
    1362        public static TypeSig getRawSig(/*@ non_null @*/ TypeName n) {
    1363            TypeSig r = (TypeSig)sigDecoration.get(n);
    1364            return r;
    1365        }
    1366
    1367        /**
    1368         * Gets the TypeSig recorded by <code>setSig</code>.
    1369         *
    1370         * Precondition: n has been resolved.
    1371         */
    1372        //@ ensures \result != null;
    1373        public static TypeSig getSig(/*@ non_null @*/ TypeName n) {
    1374            TypeSig r = (TypeSig)sigDecoration.get(n);
    1375            if (r==null) {
    1376                ErrorSet.error(n.getStartLoc(),
    1377                               "Internal error: getSig called on a TypeName ("
    1378                               + n + ") that has not been resolved!");
    1379                System.out.flush();
    1380                Assert.precondition( //@ nowarn Pre; // punt on catching this
    1381                                    "See previous error message");
    1382            }
    1383
    1384            return r;
    1385        }
    1386
    1387        public static void setSig(/*@ non_null @*/ TypeName n,
    1388                                  /*@ non_null @*/ TypeSig sig) {
    1389            sigDecoration.set(n, sig);
    1390        }
    1391
    1392        public final boolean isSubtypeOf(TypeSig s2) {
    1393            if (state < TypeSig.LINKSRESOLVED)
    1394                resolveSupertypeLinks();
    1395
    1396            TypeSig jlo = Types.javaLangObject();
    1397
    1398            if (this == s2 || s2 == jlo)
    1399                return true;
    1400            if (this == jlo)
    1401                return false;
    1402
    1403            TypeDecl d = getTypeDecl();
    1404            if (d.getTag() == TagConstants.CLASSDECL &&
    1405                ((ClassDecl)d).superClass != null) {
    1406                TypeSig s1 = getSig(((ClassDecl)d).superClass);
    1407                if (s1 == s2)
    1408                    return true;
    1409                if (s1.isSubtypeOf(s2))
    1410                    return true;
    1411            }
    1412
    1413            for(int i = 0; i < d.superInterfaces.size(); i++) {
    1414                TypeSig s1 = getSig(d.superInterfaces.elementAt(i));
    1415                if (s1 == s2)
    1416                    return true;
    1417                if (s1.isSubtypeOf(s2))
    1418                    return true;
    1419            }
    1420
    1421            return false;
    1422        }
    1423
    1424        //// Helper functions
    1425
    1426        //@ requires s != null;
    1427        public final boolean inSamePackageAs(TypeSig s) {
    1428            String[] p1 = this.packageName;
    1429            String[] p2 = s.packageName;
    1430            if (p1.length != p2.length) return false;
    1431            for(int i = 0; i < p1.length; i++)
    1432                if (! p1[i].equals(p2[i])) return false;
    1433            return true;
    1434        }
    1435
    1436        /** Check invariants of a TypeSig, raising an exception if
    1437         they don't hold. */
    1438
    1439        public void check() {
    1440            Assert.notFalse(state != RESOLVINGLINKS);                   //@ nowarn Pre;
    1441
    1442            if (state >= CREATED) {
    1443                if (state == CREATED)
    1444                    Assert.notFalse(myTypeDecl == null);
    1445            }
    1446
    1447            if (state >= PARSED) {
    1448                Assert.notNull(myTypeDecl);
    1449                Assert.notFalse(this == getSig(myTypeDecl));            //@ nowarn Pre;
    1450            }
    1451        }
    1452
    1453        /** Check invariants of a TypeSig, raising an exception if
    1454         they don't hold. */
    1455
    1456        public void deepCheck() {
    1457            Info.out("[checking deep invariants on " + this + "]");
    1458            check();
    1459            if (state >= PARSED) {
    1460                myTypeDecl.check();
    1461                CheckInvariants.checkTypeDeclOfSig(this);
    1462            }
    1463        }
    1464
    1465        private TypeSig superClass = null;
    1466
    1467        // Probably should use this only after super types have been resolved.
    1468        public TypeSig superClass() {
    1469            if (superClass != null) return superClass;
    1470            TypeDecl decl = getTypeDecl();
    1471            if (decl instanceof ClassDecl) {
    1472                TypeName n = ((ClassDecl)decl).superClass;
    1473                if (n != null) {
    1474                    superClass = getSig(n);
    1475                }
    1476            }
    1477            return superClass;
    1478        }
    1479
    1480        /* This class returns a Collection containing all of the super interfaces
    1481            of the receiver TypeSig.  No interface is repeated.
    1482        */
    1483        public java.util.Collection superInterfaces() {
    1484            TypeSig t = this;
    1485            java.util.ArrayList result = new java.util.ArrayList();
    1486            int j = 0;
    1487            while (true) {
    1488                TypeNameVec tv = t.getTypeDecl().superInterfaces;
    1489                for (int i = 0; i<tv.size(); ++i) {
    1490                    TypeName tt = tv.elementAt(i);
    1491                    TypeSig tts = getSig(tt);
    1492                    if (!result.contains(tts)) result.add(tts);
    1493                }
    1494                if (j >= result.size()) break;
    1495                t = (TypeSig)result.get(j++);
    1496            }
    1497            return result;
    1498        }
    1499
    1500    } // end of class TypeSig
    1501
    1502    /*
    1503     * Local Variables:
    1504     * Mode: Java
    1505     * fill-column: 85
    1506     * End:
    1507     */