The module contains procedures to gain necessary imports to compile a type.
MODULE\subsection{Producing import lists} The proceuderes; IMPORT Atom, AtomRefTbl, Type; ImportList 
Import... maintain
   a list modules necessary to represent a type.  This list is a
   AtomRefTbl.T which is only used in a set like fashion.  There are no
   entries in the table (NIL is inserted together with the interface).
   The main module called from outside is FromType().
REVEAL T = AtomRefTbl.Default BRANDED OBJECT END; PROCEDURENew (): T = BEGIN RETURN NEW(T).init(); END New; PROCEDUREFromType (type: Type.Object; methods: MethodList): T = VAR obj : Type.Reference := type; importTbl: T := NEW(T).init(); BEGIN IF type.name # NIL AND type.name.intf # nullAtm THEN EVAL importTbl.put(type.name.intf, NIL); END; ImportRevelations(type, importTbl); FOR i := 0 TO LAST(methods^) DO WITH sig = methods[i].sig DO ImportFromSig(sig, importTbl); ImportRefsFromSig(sig, importTbl);
Hmm. StableData.m3 will not actually handle the exceptions. FOR j := 0 TO LAST(sig.raises^) DO ImportFromType(sig.raises[j].arg, importTbl); END;
      END                        (*WITH*)
    END;                         (*FOR*)
    WHILE obj # NIL AND ISTYPE(obj, Type.Object) DO
      IF obj.revIntf # NIL THEN EVAL importTbl.put(obj.revIntf, NIL); END;
      obj := NARROW(obj, Type.Object).super;
    END;
    RETURN importTbl;
  END FromType;
PROCEDURE ImportRevelations  (t: Type.Reference; importTbl: T) =
  (* Add to the table "importTbl" the names of interfaces that provide
     revelations of "t" or one of its supertypes. *)
  BEGIN
    IF t.revIntf # NIL THEN EVAL importTbl.put(t.revIntf, NIL); END;
    TYPECASE t OF
    | Type.Object (obj) =>
        VAR o := obj;
        BEGIN
          WHILE TRUE DO
            TYPECASE o.super OF
            | Type.Opaque => EXIT
            | Type.Object =>
                IF o.revIntf # NIL THEN
                  EVAL importTbl.put(o.revIntf, NIL);
                END;
                o := o.super;
            ELSE
              <*ASSERT FALSE*>
            END;
          END;
        END;
    ELSE
    END;
  END ImportRevelations;
PROCEDURE ImportFromType  (t: Type.T; importTbl: T; byName: BOOLEAN := TRUE) =
  BEGIN
    IF t = NIL THEN RETURN END;
    IF t.name # NIL AND t.name.intf # nullAtm THEN
      EVAL importTbl.put(t.name.intf, NIL);
    END;
    TYPECASE t OF
    | Type.Reference (ref) => ImportRevelations(ref, importTbl);
    ELSE
    END;
    IF byName AND t.name # NIL THEN RETURN; END;
    TYPECASE t OF
    | Type.Enumeration, Type.UserDefined, Type.Real, Type.LongReal,
        Type.Extended =>
    | Type.Subrange (sr) => ImportFromType(sr.base, importTbl);
    | Type.Object (ob) =>
        ImportFromFields(ob.fields, importTbl);
        FOR i := 0 TO LAST(ob.methods^) DO
          ImportFromSig(ob.methods[i].sig, importTbl);
        END;
        IF ob.revIntf # NIL THEN EVAL importTbl.put(ob.revIntf, NIL); END;
    | Type.Ref (r) => ImportFromType(r.target, importTbl);
    | Type.Opaque (op) => ImportFromType(op.revealedSuperType, importTbl);
    | Type.Array (a) =>
        ImportFromType(a.index, importTbl);
        ImportFromType(a.element, importTbl);
    | Type.Packed (p) => ImportFromType(p.base, importTbl);
    | Type.Record (rec) => ImportFromFields(rec.fields, importTbl);
    | Type.Set (s) => ImportFromType(s.range, importTbl);
    | Type.Procedure (p) => ImportFromSig(p.sig, importTbl);
    ELSE
      <*ASSERT FALSE*>
    END;
  END ImportFromType;
PROCEDURE ImportFromFields  (fields: REF ARRAY OF Type.Field; importTbl: T) =
  BEGIN
    IF fields = NIL THEN RETURN END;
    FOR i := 0 TO LAST(fields^) DO
      ImportFromType(fields[i].type, importTbl);
    END;
  END ImportFromFields;
PROCEDURE ImportFromSig  (sig: Type.Signature; importTbl: T) =
  BEGIN
    FOR i := 0 TO LAST(sig.formals^) DO
      ImportFromType(sig.formals[i].type, importTbl);
    END;
    ImportFromType(sig.result, importTbl);
    IF sig.raises # NIL THEN
      FOR i := 0 TO LAST(sig.raises^) DO
        EVAL importTbl.put(sig.raises[i].qid.intf, NIL);
      END;
    END;
  END ImportFromSig;
PROCEDURE ImportRefsFromSig  (sig: Type.Signature; importTbl: T) =
  BEGIN
    FOR i := 0 TO LAST(sig.formals^) DO
      ImportRefsFromType(sig.formals[i].type, importTbl);
    END;
    ImportRefsFromType(sig.result, importTbl);
  END ImportRefsFromSig;
PROCEDURE ImportRefsFromType  (t: Type.T; importTbl: T) =
  BEGIN
    IF t = NIL THEN RETURN END;
    TYPECASE t OF
    | Type.Enumeration, Type.UserDefined, Type.Real, Type.LongReal,
        Type.Extended, Type.Subrange, Type.Set, Type.Procedure =>
    | Type.Reference =>
        IF NOT Type.MayBeRefAny(t) AND Type.NamedType(t) THEN
          ImportFromType(t, importTbl)
        END;
    | Type.Array (a) =>
        ImportFromType(a.index, importTbl);
        ImportRefsFromType(a.element, importTbl);
    | Type.Packed (p) => ImportRefsFromType(p.base, importTbl);
    | Type.Record (rec) =>
        IF rec.fields = NIL THEN RETURN END;
        FOR i := 0 TO LAST(rec.fields^) DO
          ImportRefsFromType(rec.fields[i].type, importTbl);
        END;
    ELSE
      <*ASSERT FALSE*>
    END;
  END ImportRefsFromType;
 \subsection{Procedure Add} Add an element intf to a import list. 
PROCEDURE\subsection{Procedure ToText} Generate a comma separated list of interface names out ofAdd (importList: T; intf: Atom.T) = BEGIN EVAL importList.put(intf, NIL) END Add;
imports.  The output is suitable for an
   IMPORT statement.
   Iterate over the table imports and append to result.
PROCEDUREToText (imports: T): TEXT = VAR intf : Atom.T; dummy : REFANY; iter := imports.iterate(); result := ""; BEGIN IF iter.next(intf, dummy) THEN result := Atom.ToText(intf); WHILE iter.next(intf, dummy) DO result := result & ", " & Atom.ToText(intf); END; END; RETURN result; END ToText; VAR nullAtm := Atom.FromText(""); BEGIN END ImportList.