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