home *** CD-ROM | disk | FTP | other *** search
/ Tutto per Internet / Internet.iso / soft95 / Java / espints / espinst.exe / classes / espresso / ClassDef.class (.txt) < prev    next >
Encoding:
Java Class File  |  1996-02-28  |  11.4 KB  |  350 lines

  1. package espresso;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.util.Enumeration;
  7. import java.util.Hashtable;
  8.  
  9. class ClassDef extends Def {
  10.    private static final Name periodS = Name.fromString(".");
  11.    private static final Name emptyS = Name.fromString("");
  12.    ASTS closures;
  13.    Scope funscope;
  14.    FunObj clinit;
  15.    Env clinitEnv;
  16.    Code clinitcode;
  17.    Code initcode;
  18.    Block body;
  19.    AST[] implementing;
  20.    AST extending;
  21.  
  22.    void print(int var1) {
  23.       if ((super.mods & 512) != 0) {
  24.          System.out.print(Obj.modNames(super.mods ^ 512));
  25.          System.out.print(String.valueOf("interface ").concat(String.valueOf(super.name)));
  26.          if (this.implementing.length > 0) {
  27.             System.out.print(" extends ");
  28.             AST.printSeq(this.implementing);
  29.          }
  30.       } else {
  31.          System.out.print(Obj.modNames(super.mods));
  32.          System.out.print(String.valueOf("class ").concat(String.valueOf(super.name)));
  33.          if (this.extending != null) {
  34.             System.out.print(" extends ");
  35.             this.extending.print();
  36.          }
  37.  
  38.          if (this.implementing.length > 0) {
  39.             System.out.print(" implements ");
  40.             AST.printSeq(this.implementing);
  41.          }
  42.       }
  43.  
  44.       System.out.print(" ");
  45.       this.body.print();
  46.    }
  47.  
  48.    Name fullName() {
  49.       return ((ClassObj)super.obj).fullname;
  50.    }
  51.  
  52.    void output() {
  53.       if (Report.nerrors == 0) {
  54.          ClassObj var1 = (ClassObj)super.obj;
  55.  
  56.          try {
  57.             File var2 = ClassFile.openOutput(var1);
  58.             FileOutputStream var3 = new FileOutputStream(var2);
  59.             ClassFile.writeClass(var3, var1);
  60.             var3.close();
  61.             if (Switches.verbose) {
  62.                System.out.println(String.valueOf(String.valueOf("[wrote ").concat(String.valueOf(var2.getPath()))).concat(String.valueOf("]")));
  63.             }
  64.          } catch (IOException var5) {
  65.             Report.error(super.pos, String.valueOf(String.valueOf(String.valueOf("error writing ").concat(String.valueOf(var1.name))).concat(String.valueOf(".class: "))).concat(String.valueOf(var5)));
  66.          }
  67.       }
  68.  
  69.    }
  70.  
  71.    Item gen() {
  72.       this.genTry(false);
  73.       return Item.voidItem;
  74.    }
  75.  
  76.    private void genTry(boolean var1) {
  77.       ClassObj var2 = (ClassObj)super.obj;
  78.       var2.pool = Gen.newPool();
  79.       this.initcode = Gen.newCode(var2, false, var1);
  80.       this.clinitcode = Gen.newCode(var2, true, var1);
  81.  
  82.       for(int var3 = 0; var3 < this.body.stats.length; ++var3) {
  83.          if (this.body.stats[var3].tag != 65) {
  84.             this.body.stats[var3].genDrop();
  85.          }
  86.       }
  87.  
  88.       for(int var4 = 0; var4 < this.body.stats.length; ++var4) {
  89.          if (this.body.stats[var4].tag == 65) {
  90.             this.body.stats[var4].genDrop();
  91.          }
  92.       }
  93.  
  94.       if (this.clinitcode.cp != 0) {
  95.          Gen.useCode(this.clinitcode);
  96.          Gen.entryPoint(0);
  97.          Gen.emitop(177);
  98.          this.clinit.code = this.clinitcode;
  99.          super.localEnv.scope.enter(this.clinit);
  100.       }
  101.  
  102.       if (!var1 && (this.initcode.fatCode || this.clinitcode.fatCode)) {
  103.          boolean var5 = Report.silent;
  104.          Report.silent = true;
  105.          this.genTry(true);
  106.          Report.silent = var5;
  107.       }
  108.  
  109.    }
  110.  
  111.    AST simplify() {
  112.       this.body.markCaptured(new Bits());
  113.       this.body.markCaptured(new Bits());
  114.       if (this.extending != null) {
  115.          this.extending = this.extending.simplify();
  116.       }
  117.  
  118.       for(int var1 = 0; var1 < this.implementing.length; ++var1) {
  119.          this.implementing[var1] = this.implementing[var1].simplify();
  120.       }
  121.  
  122.       int var2 = this.body.pos;
  123.       this.closures = new ASTS();
  124.       this.body = (Block)this.body.simplify();
  125.       ClassObj var3 = (ClassObj)super.obj;
  126.       if (this.closures.length != 0) {
  127.          super.localEnv.toplevel.newClasses.append(this.makeClosureClass());
  128.          ASTS var4 = new ASTS(this.body.stats);
  129.  
  130.          for(int var5 = 0; var5 < this.closures.length; ++var5) {
  131.             ((FunDef)this.closures.elems[var5]).obj = null;
  132.             var4.append(this.closures.elems[var5]);
  133.          }
  134.  
  135.          this.body = new Block(var2, var4);
  136.       }
  137.  
  138.       return this;
  139.    }
  140.  
  141.    private AST makeClosureClass() {
  142.       int var1 = this.body.pos;
  143.       AST[] var2 = new AST[]{new VarDef(var1, Simplify.fvarsS, 2, Simplify.objectArray(var1), (AST)null), new VarDef(var1, Simplify.receiverS, 2, new Ident(var1, super.name), (AST)null), new VarDef(var1, Simplify.tagS, 2, Simplify.toAST(var1, Typ.intTyp), (AST)null), this.makeClosureConstructor(), this.makeClosureApply()};
  144.       return new ClassDef(var1, super.name.append(Simplify.closureS), 0, Simplify.toAST(var1, Simplify.ClosureS), new ASTS(), new Block(var1, new ASTS(var2)));
  145.    }
  146.  
  147.    private AST makeClosureConstructor() {
  148.       int var1 = this.body.pos;
  149.       return new FunDef(var1, 65, Predef.initS, 0, (AST)null, new ASTS(new VarDef(var1, Simplify.fvarsS, 0, Simplify.objectArray(var1), (AST)null), new VarDef(var1, Simplify.receiverS, 0, new Ident(var1, super.name), (AST)null), new VarDef(var1, Simplify.tagS, 0, Simplify.toAST(var1, Typ.intTyp), (AST)null)), new ASTS(), new Block(var1, new ASTS(new Exec(var1, new Assignop(var1, 49, Simplify.selectThis(var1, Simplify.fvarsS), new Ident(var1, Simplify.fvarsS))), new Exec(var1, new Assignop(var1, 49, Simplify.selectThis(var1, Simplify.receiverS), new Ident(var1, Simplify.receiverS))), new Exec(var1, new Assignop(var1, 49, Simplify.selectThis(var1, Simplify.tagS), new Ident(var1, Simplify.tagS))))));
  150.    }
  151.  
  152.    private AST makeClosureApply() {
  153.       int var1 = this.body.pos;
  154.       ASTS var2 = new ASTS();
  155.       ClassObj var3 = (ClassObj)super.obj;
  156.       int var4 = Simplify.totalClosures(var3.superclass);
  157.  
  158.       for(int var5 = 0; var5 < this.closures.length; ++var5) {
  159.          var2.append(this.makeClosureCall((FunDef)this.closures.elems[var5], var5 + var4));
  160.       }
  161.  
  162.       AST[] var6 = new AST[]{new VarDef(var1, Simplify.allargsS, 0, Simplify.objectArray(var1), new Apply(var1, new Select(var1, Simplify.toAST(var1, Simplify.ClosureS), Simplify.combineS), new ASTS(new Ident(var1, Simplify.fvarsS), new Ident(var1, Simplify.argsS)))), new Switch(var1, new Ident(var1, Simplify.tagS), var2), new Throw(var1, new New(var1, new Apply(var1, Simplify.toAST(var1, Simplify.MessageNotUnderstoodS), new ASTS(new Ident(var1, Simplify.tagS)))))};
  163.       return new FunDef(var1, 65, Simplify.applyS, 1, Simplify.objectTyp(var1), new ASTS(new VarDef(var1, Simplify.argsS, 0, Simplify.objectArray(var1), (AST)null)), new ASTS(), new Block(var1, new ASTS(var6)));
  164.    }
  165.  
  166.    private AST makeClosureCall(FunDef var1, int var2) {
  167.       int var3 = this.body.pos;
  168.       FunTyp var4 = (FunTyp)var1.typ;
  169.       ASTS var5 = new ASTS();
  170.       Hashtable var6 = ((FunObj)var1.obj).freevars;
  171.       Enumeration var7 = var6.elements();
  172.       int var8 = var6.size();
  173.  
  174.       for(int var9 = 0; var9 < var1.params.length; ++var9) {
  175.          Object var10;
  176.          if (var9 < var8) {
  177.             VarObj var11 = (VarObj)var7.nextElement();
  178.             var10 = var11.typ;
  179.             if (var11.passByRef) {
  180.                var10 = new ArrayTyp((Typ)var10);
  181.             }
  182.          } else {
  183.             var10 = var4.argtyps[var9 - var8];
  184.          }
  185.  
  186.          var5.append(Simplify.unbox(new Subscript(var3, new Ident(var3, Simplify.allargsS), new Literal(var3, 90, new Integer(var9))), (Typ)var10));
  187.       }
  188.  
  189.       Name var12 = (var1.mods & 8) != 0 ? super.name : Simplify.receiverS;
  190.       Apply var13 = new Apply(var3, Simplify.toAST(var3, var12.append(periodS).append(var1.name)), var5);
  191.       ASTS var14 = var4.restyp.tag == 12 ? new ASTS(new Exec(var3, var13), new Return(var3, new Ident(var3, Simplify.nullS))) : new ASTS(new Return(var3, Simplify.box(var13)));
  192.       return new Case(var3, new Literal(var3, 90, new Integer(var2)), var14);
  193.    }
  194.  
  195.    Typ attr(Env var1, int var2, Typ var3) {
  196.       ClassObj var4 = (ClassObj)super.obj;
  197.       if (!this.fatallyFlawed(var4)) {
  198.          Attr.fixupScope(super.pos, var4);
  199.          this.funscope.baseOn(var4.scope);
  200.          this.clinit = new FunObj(8, Predef.clinitS, new FunTyp(new Typ[0], Typ.voidTyp, (TypSet)null));
  201.          this.clinitEnv = new Env(super.localEnv, this, new Scope(super.localEnv.scope, this.clinit));
  202.          this.clinitEnv.isStatic = true;
  203.          if ((var4.modifiers & 1536) == 0) {
  204.             var4.modifiers ^= 1024;
  205.             Obj var5 = firstUndef(var4, var4);
  206.             if (var5 != null) {
  207.                Report.error(super.pos, String.valueOf(String.valueOf(String.valueOf(String.valueOf(var4).concat(String.valueOf(" should be declared abstract; "))).concat(String.valueOf("it does not define "))).concat(String.valueOf(var5))).concat(String.valueOf(Attr.location(var5))));
  208.             }
  209.  
  210.             var4.modifiers ^= 1024;
  211.          }
  212.  
  213.          this.body.typ = Typ.voidTyp;
  214.  
  215.          for(int var6 = 0; var6 < this.body.stats.length; ++var6) {
  216.             this.body.stats[var6].attr(super.localEnv, 12, Typ.voidTyp);
  217.          }
  218.       }
  219.  
  220.       super.typ = var3;
  221.       return super.typ;
  222.    }
  223.  
  224.    void enterFields(Env var1) {
  225.       ClassObj var2 = (ClassObj)super.obj;
  226.       var2.scope = new Scope((Scope)null, var2);
  227.       if (this.extending == null) {
  228.          if (var2.isRoot()) {
  229.             var2.superclass = null;
  230.          } else {
  231.             var2.superclass = Predef.objectClass;
  232.          }
  233.       } else {
  234.          var2.superclass = this.classRef(var1, this.extending, true);
  235.       }
  236.  
  237.       var2.interfaces = new ClassObj[this.implementing.length];
  238.  
  239.       for(int var3 = 0; var3 < var2.interfaces.length; ++var3) {
  240.          var2.interfaces[var3] = this.classRef(var1, this.implementing[var3], false);
  241.       }
  242.  
  243.       this.funscope = new Scope(var2.scope, (Obj)null);
  244.       super.localEnv = new Env(var1, this, var2.scope);
  245.       super.localEnv.enclClass = this;
  246.       this.ensureConstructor();
  247.       if (!this.fatallyFlawed(var2)) {
  248.          for(int var4 = 0; var4 < this.body.stats.length; ++var4) {
  249.             this.body.stats[var4].enter(super.localEnv);
  250.          }
  251.       }
  252.  
  253.    }
  254.  
  255.    private boolean fatallyFlawed(ClassObj var1) {
  256.       if (var1.superclass != null && var1.superclass.typ.tag == 0) {
  257.          return true;
  258.       } else {
  259.          for(int var2 = 0; var2 < var1.interfaces.length; ++var2) {
  260.             if (var1.interfaces[var2].typ.tag == 0) {
  261.                return true;
  262.             }
  263.          }
  264.  
  265.          return false;
  266.       }
  267.    }
  268.  
  269.    private void ensureConstructor() {
  270.       if ((super.mods & 512) == 0 && !this.body.hasConstructors()) {
  271.          this.body.pushStat(new FunDef(super.pos, 65, Predef.initS, 1, (AST)null, new ASTS(), new ASTS(), new Block(super.pos, new ASTS())));
  272.       }
  273.  
  274.    }
  275.  
  276.    private ClassObj classRef(Env var1, AST var2, boolean var3) {
  277.       ClassObj var4 = Attr.checkObjectTyp(var2.pos, var2.attr(var1, 2, Typ.anyTyp)).obj;
  278.       if (var4.typ.tag == 11) {
  279.          if (var3 && (var4.modifiers & 512) != 0) {
  280.             Report.error(var2.pos, "no interface allowed here");
  281.          } else if (!var3 && (var4.modifiers & 512) == 0) {
  282.             Report.error(var2.pos, "not an interface");
  283.          } else if ((var4.modifiers & 16) != 0) {
  284.             Report.error(var2.pos, String.valueOf("can't inherit from final ").concat(String.valueOf(var4)));
  285.          }
  286.       }
  287.  
  288.       return var4;
  289.    }
  290.  
  291.    void enter(Env var1) {
  292.       ClassObj var2 = new ClassObj();
  293.       var2.name = super.name;
  294.       var2.modifiers = Attr.checkMods(super.pos, super.mods, 1553);
  295.       var2.typ = new Typ(11, var2);
  296.       var2.fullname = var1.packageName.append(super.name);
  297.       var2.packagename = var1.packageName;
  298.       var2.sourcefile = Name.fromString(var1.toplevel.sourcefile);
  299.       super.obj = var2;
  300.       if (var1.scope.lookup(super.name).scope == var1.scope) {
  301.          Report.error(super.pos, String.valueOf("duplicate definition of class ").concat(String.valueOf(var2.fullname)));
  302.       } else {
  303.          var1.scope.enter(var2);
  304.          ClassFile.loaded.put(var2.fullname, var2);
  305.       }
  306.  
  307.    }
  308.  
  309.    private static Obj firstUndef(ClassObj var0, ClassObj var1) {
  310.       Obj var2 = null;
  311.       if ((var1.modifiers & 1536) != 0) {
  312.          var2 = firstUndef(var0, var1.scope);
  313.          if (var2 == null && var1.superclass != null) {
  314.             var2 = firstUndef(var0, var1.superclass);
  315.          }
  316.  
  317.          if (var2 == null && var1.interfaces.length > 0) {
  318.             var2 = firstUndef(var0, var1.scope.next);
  319.          }
  320.       }
  321.  
  322.       return var2;
  323.    }
  324.  
  325.    private static Obj firstUndef(ClassObj var0, Scope var1) {
  326.       Object var2 = null;
  327.  
  328.       for(ScopeEntry var3 = var1.elements(); var3 != null; var3 = var3.sibling) {
  329.          if (var3.obj instanceof FunObj && (var3.obj.modifiers & 1024) != 0) {
  330.             ScopeEntry var4;
  331.             for(var4 = var0.scope.lookup(var3.obj.name); var4.scope != null && (!(var4.obj instanceof FunObj) || (var4.obj.modifiers & 1024) != 0 || !((FunObj)var4.obj).overrides(var3.obj)); var4 = var4.next()) {
  332.             }
  333.  
  334.             if (var4.scope == null) {
  335.                return var3.obj;
  336.             }
  337.          }
  338.       }
  339.  
  340.       return null;
  341.    }
  342.  
  343.    ClassDef(int var1, Name var2, int var3, AST var4, ASTS var5, Block var6) {
  344.       super(var1, 16, var2, var3);
  345.       this.extending = var4;
  346.       this.implementing = var5.shrink();
  347.       this.body = var6;
  348.    }
  349. }
  350.