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     */