refactored tons of functionality into Class.Body and HasAttributes
authoradam <adam@megacz.com>
Sun, 3 Jul 2005 03:56:03 +0000 (03:56 +0000)
committeradam <adam@megacz.com>
Sun, 3 Jul 2005 03:56:03 +0000 (03:56 +0000)
darcs-hash:20050703035603-5007d-105acbefa98a045457c54980622c0c2831aaa88c.gz

src/org/ibex/classgen/ClassFile.java
src/org/ibex/classgen/FieldGen.java
src/org/ibex/classgen/HasAttributes.java [new file with mode: 0644]
src/org/ibex/classgen/HasFlags.java
src/org/ibex/classgen/MethodGen.java
src/org/ibex/classgen/Type.java

index 32bda60..70c447b 100644 (file)
@@ -10,13 +10,10 @@ public class ClassFile extends Type.Class.Body {
     private final Type.Class[] interfaces;
     private final short minor;
     private final short major;
     private final Type.Class[] interfaces;
     private final short minor;
     private final short major;
-    final int flags;
     
     private final Vector fields = new Vector();
     public final Vector methods = new Vector();
     
     
     private final Vector fields = new Vector();
     public final Vector methods = new Vector();
     
-    private final AttrGen attributes;
-
     static String flagsToString(int flags, boolean isClass) {
         StringBuffer sb = new StringBuffer(32);
         if ((flags & PUBLIC) != 0)       sb.append("public ");
     static String flagsToString(int flags, boolean isClass) {
         StringBuffer sb = new StringBuffer(32);
         if ((flags & PUBLIC) != 0)       sb.append("public ");
@@ -46,7 +43,7 @@ public class ClassFile extends Type.Class.Body {
         for(int i=0; i<interfaces.length; i++) sb.append((i==0?" ":", ")+interfaces[i].debugToString());
         sb.append(" {");
         sb.append(" // v"+major+"."+minor);
         for(int i=0; i<interfaces.length; i++) sb.append((i==0?" ":", ")+interfaces[i].debugToString());
         sb.append(" {");
         sb.append(" // v"+major+"."+minor);
-        ConstantPool.Utf8Key sourceFile = (ConstantPool.Utf8Key) attributes.get("SourceFile");
+        ConstantPool.Utf8Key sourceFile = (ConstantPool.Utf8Key) attrs.get("SourceFile");
         if (sourceFile != null) sb.append(" from " + sourceFile.s);
         sb.append("\n");
         for(int i=0; i<fields.size(); i++) {
         if (sourceFile != null) sb.append(" from " + sourceFile.s);
         sb.append("\n");
         for(int i=0; i<fields.size(); i++) {
@@ -64,16 +61,12 @@ public class ClassFile extends Type.Class.Body {
 
     public ClassFile(Type.Class thisType, Type.Class superType, int flags) { this(thisType, superType, flags, null); }
     public ClassFile(Type.Class thisType, Type.Class superType, int flags, Type.Class[] interfaces) {
 
     public ClassFile(Type.Class thisType, Type.Class superType, int flags) { this(thisType, superType, flags, null); }
     public ClassFile(Type.Class thisType, Type.Class superType, int flags, Type.Class[] interfaces) {
-        thisType.super();
+        thisType.super(flags, new AttrGen());
         this.thisType = thisType;
         this.thisType = thisType;
-        if((flags & ~(PUBLIC|FINAL|SUPER|INTERFACE|ABSTRACT)) != 0)
-            throw new IllegalArgumentException("invalid flags");
         this.superType = superType;
         this.interfaces = interfaces;
         this.superType = superType;
         this.interfaces = interfaces;
-        this.flags = flags;
         this.minor = 3;
         this.major = 45;        
         this.minor = 3;
         this.major = 45;        
-        this.attributes = new AttrGen();
     }
     
     /** Adds a new method to this class 
     }
     
     /** Adds a new method to this class 
@@ -112,7 +105,7 @@ public class ClassFile extends Type.Class.Body {
     /** Sets the source value of the SourceFile attribute of this class 
         @param sourceFile The string to be uses as the SourceFile of this class
     */
     /** Sets the source value of the SourceFile attribute of this class 
         @param sourceFile The string to be uses as the SourceFile of this class
     */
-    public void setSourceFile(String sourceFile) { attributes.put("SourceFile", new ConstantPool.Utf8Key(sourceFile)); }
+    public void setSourceFile(String sourceFile) { attrs.put("SourceFile", new ConstantPool.Utf8Key(sourceFile)); }
     
     /** Writes the classfile data to the file specifed
         @see ClassFile#dump(OutputStream)
     
     /** Writes the classfile data to the file specifed
         @see ClassFile#dump(OutputStream)
@@ -157,7 +150,7 @@ public class ClassFile extends Type.Class.Body {
         if(interfaces != null) for(int i=0;i<interfaces.length;i++) cp.add(interfaces[i]);
         for(int i=0;i<methods.size();i++) ((MethodGen)methods.elementAt(i)).finish(cp);
         for(int i=0;i<fields.size();i++) ((FieldGen)fields.elementAt(i)).finish(cp);
         if(interfaces != null) for(int i=0;i<interfaces.length;i++) cp.add(interfaces[i]);
         for(int i=0;i<methods.size();i++) ((MethodGen)methods.elementAt(i)).finish(cp);
         for(int i=0;i<fields.size();i++) ((FieldGen)fields.elementAt(i)).finish(cp);
-        attributes.finish(cp);
+        attrs.finish(cp);
         
         cp.optimize();
         cp.seal();
         
         cp.optimize();
         cp.seal();
@@ -181,7 +174,7 @@ public class ClassFile extends Type.Class.Body {
         o.writeShort(methods.size()); // methods_count
         for(int i=0;i<methods.size();i++) ((MethodGen)methods.elementAt(i)).dump(o,cp); // methods
         
         o.writeShort(methods.size()); // methods_count
         for(int i=0;i<methods.size();i++) ((MethodGen)methods.elementAt(i)).dump(o,cp); // methods
         
-        attributes.dump(o,cp); // attributes        
+        attrs.dump(o,cp); // attributes        
     }
     
     public static ClassFile read(String s) throws IOException { return read(new File(s)); }
     }
     
     public static ClassFile read(String s) throws IOException { return read(new File(s)); }
@@ -211,29 +204,26 @@ public class ClassFile extends Type.Class.Body {
     }
     private ClassFile(int magic, short minor, short major, ConstantPool cp, short flags,
                       Type.Class thisType, DataInput i, boolean ssa) throws IOException {
     }
     private ClassFile(int magic, short minor, short major, ConstantPool cp, short flags,
                       Type.Class thisType, DataInput i, boolean ssa) throws IOException {
-        thisType.super();
+        thisType.super(flags, null);
         if (magic != 0xcafebabe) throw new ClassReadExn("invalid magic: " + Long.toString(0xffffffffL & magic, 16));
         this.minor = minor;
         this.major = major;
         if (magic != 0xcafebabe) throw new ClassReadExn("invalid magic: " + Long.toString(0xffffffffL & magic, 16));
         this.minor = minor;
         this.major = major;
-        this.flags = flags;
-        if((flags & ~(PUBLIC|FINAL|SUPER|INTERFACE|ABSTRACT)) != 0)
-            throw new ClassReadExn("invalid flags: " + Integer.toString(flags,16));
         this.thisType = thisType;
         superType = (Type.Class) cp.getKeyByIndex(i.readShort());
         interfaces = new Type.Class[i.readShort()];
         for(int j=0; j<interfaces.length; j++) interfaces[j] = (Type.Class) cp.getKeyByIndex(i.readShort());
         int numFields = i.readShort();
         this.thisType = thisType;
         superType = (Type.Class) cp.getKeyByIndex(i.readShort());
         interfaces = new Type.Class[i.readShort()];
         for(int j=0; j<interfaces.length; j++) interfaces[j] = (Type.Class) cp.getKeyByIndex(i.readShort());
         int numFields = i.readShort();
-        for(int j=0; j<numFields; j++) fields.addElement(new FieldGen(this, i, cp));
+        for(int j=0; j<numFields; j++) fields.addElement(new FieldGen(this.getType(), i, cp));
         int numMethods = i.readShort();
         for(int j=0; j<numMethods; j++) methods.addElement(ssa 
                                                            ? new JSSA(this.getType(), i, cp) 
                                                            : new MethodGen(this.getType(), i, cp));
         int numMethods = i.readShort();
         for(int j=0; j<numMethods; j++) methods.addElement(ssa 
                                                            ? new JSSA(this.getType(), i, cp) 
                                                            : new MethodGen(this.getType(), i, cp));
-        attributes = new AttrGen(i, cp);
+        readAttributes(i, cp);
         
         // FEATURE: Support these
         // NOTE: Until we can support them properly we HAVE to delete them,
         //       they'll be incorrect after we rewrite the constant pool, etc
         
         // FEATURE: Support these
         // NOTE: Until we can support them properly we HAVE to delete them,
         //       they'll be incorrect after we rewrite the constant pool, etc
-        attributes.remove("InnerClasses");
+        attrs.remove("InnerClasses");
     }
     
     /** Thrown when class generation fails for a reason not under the control of the user
     }
     
     /** Thrown when class generation fails for a reason not under the control of the user
index 7f5242c..3640834 100644 (file)
@@ -5,31 +5,27 @@ import java.io.*;
 /** Class representing a field in a generated classfile
     @see ClassFile#addField */
 public class FieldGen extends Type.Class.Field.Body {
 /** Class representing a field in a generated classfile
     @see ClassFile#addField */
 public class FieldGen extends Type.Class.Field.Body {
-    private final ClassFile.AttrGen attrs;
 
     StringBuffer debugToString(StringBuffer sb) {
         sb.append(ClassFile.flagsToString(flags, false));
         sb.append(getField().getType().debugToString());
         sb.append(" ");
         sb.append(getField().getName());
 
     StringBuffer debugToString(StringBuffer sb) {
         sb.append(ClassFile.flagsToString(flags, false));
         sb.append(getField().getType().debugToString());
         sb.append(" ");
         sb.append(getField().getName());
-        if(attrs.contains("ConstantValue"))
-            sb.append(" = \"").append(attrs.get("ConstantValue")).append("\"");
+        if (attrs.contains("ConstantValue")) sb.append(" = \"").append(attrs.get("ConstantValue")).append("\"");
         sb.append(";");
         return sb;
     }
     
         sb.append(";");
         return sb;
     }
     
-    FieldGen(ClassFile cf, DataInput in, ConstantPool cp) throws IOException {
+    FieldGen(Type.Class c, DataInput in, ConstantPool cp) throws IOException {
         this(in.readShort(),
         this(in.readShort(),
-             cf.getType().field(cp.getUtf8KeyByIndex(in.readShort()),
-                                Type.fromDescriptor(cp.getUtf8KeyByIndex(in.readShort()))));
+             c.field(cp.getUtf8KeyByIndex(in.readShort()),
+                     Type.fromDescriptor(cp.getUtf8KeyByIndex(in.readShort()))),
+             new ClassFile.AttrGen(in, cp));
     }
 
     }
 
-    private FieldGen(int flags, Type.Class.Field field) { this(field, flags); }
+    private FieldGen(int flags, Type.Class.Field field, ClassFile.AttrGen attrs) { this(field, flags, attrs); }
     FieldGen(Type.Class.Field field, int flags) { this(field, flags, new ClassFile.AttrGen()); }
     FieldGen(Type.Class.Field field, int flags) { this(field, flags, new ClassFile.AttrGen()); }
-    FieldGen(Type.Class.Field field, int flags, ClassFile.AttrGen attrs) {
-        field.super(flags);
-        this.attrs = attrs;
-   }
+    FieldGen(Type.Class.Field field, int flags, ClassFile.AttrGen attrs) { field.super(flags, attrs); }
     
     /** Sets the ContantValue attribute for this field. 
         @param val The value to set this field to. Must be an Integer, Long, Float, Double, or String */
     
     /** Sets the ContantValue attribute for this field. 
         @param val The value to set this field to. Must be an Integer, Long, Float, Double, or String */
diff --git a/src/org/ibex/classgen/HasAttributes.java b/src/org/ibex/classgen/HasAttributes.java
new file mode 100644 (file)
index 0000000..259a0cd
--- /dev/null
@@ -0,0 +1,8 @@
+package org.ibex.classgen;
+import java.io.*;
+
+public abstract class HasAttributes extends HasFlags {
+    public ClassFile.AttrGen attrs;
+    public HasAttributes(int flags, ClassFile.AttrGen attrs) { super(flags); this.attrs = attrs; }
+    public void readAttributes(DataInput i, ConstantPool cp) throws IOException { attrs = new ClassFile.AttrGen(i, cp); }
+}
index 20aa90d..313c422 100644 (file)
@@ -1,17 +1,22 @@
 package org.ibex.classgen;
 
 public abstract class HasFlags implements CGConst {
 package org.ibex.classgen;
 
 public abstract class HasFlags implements CGConst {
-    public abstract int getFlags();
+
+    public HasFlags(int flags) { this.flags = flags; }
+
+    public final int flags;
+    public int getFlags() { return flags; }
 
     public boolean isPublic() { return (getFlags() & PUBLIC) != 0; }
     public boolean isPrivate() { return (getFlags() & PRIVATE) != 0; }
     public boolean isProtected() { return (getFlags() & PROTECTED) != 0; }
     public boolean isStatic() { return (getFlags() & STATIC) != 0; }
     public boolean isFinal() { return (getFlags() & FINAL) != 0; }
 
     public boolean isPublic() { return (getFlags() & PUBLIC) != 0; }
     public boolean isPrivate() { return (getFlags() & PRIVATE) != 0; }
     public boolean isProtected() { return (getFlags() & PROTECTED) != 0; }
     public boolean isStatic() { return (getFlags() & STATIC) != 0; }
     public boolean isFinal() { return (getFlags() & FINAL) != 0; }
+    public boolean isInterface() { return (getFlags() & INTERFACE) != 0; }
 
     public boolean isAbstract() { return (getFlags() & ABSTRACT) != 0; }
     public boolean isNative() { return (getFlags() & NATIVE) != 0; }
 
     public boolean isAbstract() { return (getFlags() & ABSTRACT) != 0; }
     public boolean isNative() { return (getFlags() & NATIVE) != 0; }
-    public boolean isConcrete() { return !isAbstract() && !isNative(); }
+    public boolean isConcrete() { return !isAbstract() && !isNative() && !isInterface(); }
 
     public boolean isVolatile() { return (getFlags() & VOLATILE) != 0; }
     public boolean isTransient() { return (getFlags() & TRANSIENT) != 0; }
 
     public boolean isVolatile() { return (getFlags() & VOLATILE) != 0; }
     public boolean isTransient() { return (getFlags() & TRANSIENT) != 0; }
index 492cd76..bc80d75 100644 (file)
@@ -5,14 +5,12 @@ import java.util.*;
 
 /** A class representing a method in a generated classfile
     @see ClassFile#addMethod */
 
 /** A class representing a method in a generated classfile
     @see ClassFile#addMethod */
-public class MethodGen extends Type.Class.Method.Body implements CGConst {
+public class MethodGen extends Type.Class.Method.Body {
     private final static boolean EMIT_NOPS = false;
     
     private static final int NO_CODE = -1;
 
     public final Type.Class.Method method;
     private final static boolean EMIT_NOPS = false;
     
     private static final int NO_CODE = -1;
 
     public final Type.Class.Method method;
-    private final int flags;
-    private final ClassFile.AttrGen attrs;
     private final ClassFile.AttrGen codeAttrs;
     private final Vector exnTable = new Vector();
     private final Hashtable thrownExceptions = new Hashtable();
     private final ClassFile.AttrGen codeAttrs;
     private final Vector exnTable = new Vector();
     private final Hashtable thrownExceptions = new Hashtable();
@@ -30,16 +28,10 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
     // Constructors //////////////////////////////////////////////////////////////////////////////
 
     MethodGen(Type.Class.Method method, int flags) {
     // Constructors //////////////////////////////////////////////////////////////////////////////
 
     MethodGen(Type.Class.Method method, int flags) {
-        method.super();
-        if ((flags & ~VALID_METHOD_FLAGS) != 0) throw new IllegalArgumentException("invalid flags");
+        method.super(flags, new ClassFile.AttrGen());
         this.method = method;
         this.method = method;
-        this.flags = flags;
-        
-        attrs = new ClassFile.AttrGen();
         codeAttrs = new ClassFile.AttrGen();
         codeAttrs = new ClassFile.AttrGen();
-        
-        if (((flags & INTERFACE) != 0) || (flags & (ABSTRACT|NATIVE)) != 0) size = capacity = -1;
-        
+        if (!isConcrete()) size = capacity = -1;
         maxLocals = Math.max(method.getNumArgs() + (flags&STATIC)==0 ? 1 : 0, 4);
     }
 
         maxLocals = Math.max(method.getNumArgs() + (flags&STATIC)==0 ? 1 : 0, 4);
     }
 
@@ -50,13 +42,10 @@ public class MethodGen extends Type.Class.Method.Body implements CGConst {
         this(flags, name, c.method(name+cp.getUtf8KeyByIndex(in.readShort())), c, in, cp); }
     private MethodGen(short flags, String name, Type.Class.Method m,
                       Type.Class c, DataInput in, ConstantPool cp) throws IOException {
         this(flags, name, c.method(name+cp.getUtf8KeyByIndex(in.readShort())), c, in, cp); }
     private MethodGen(short flags, String name, Type.Class.Method m,
                       Type.Class c, DataInput in, ConstantPool cp) throws IOException {
-        m.super();
-        this.flags = flags;
-        if ((flags & ~VALID_METHOD_FLAGS) != 0) throw new ClassFile.ClassReadExn("invalid flags");
+        m.super(flags, new ClassFile.AttrGen(in,cp));
         this.method = m;
         this.method = m;
-        this.attrs = new ClassFile.AttrGen(in,cp);
         
         
-        if ((flags & (NATIVE|ABSTRACT))==0)  {
+        if (isConcrete())  {
             byte[] codeAttr = (byte[]) attrs.get("Code");
             if (codeAttr == null) throw new ClassFile.ClassReadExn("code attr expected");
             DataInputStream ci = new DataInputStream(new ByteArrayInputStream(codeAttr));
             byte[] codeAttr = (byte[]) attrs.get("Code");
             if (codeAttr == null) throw new ClassFile.ClassReadExn("code attr expected");
             DataInputStream ci = new DataInputStream(new ByteArrayInputStream(codeAttr));
index 08c346f..6e20f67 100644 (file)
@@ -115,10 +115,16 @@ public abstract class Type implements CGConst {
             return a;
         }
 
             return a;
         }
 
-        public Field field(String name, Type type) { return new Field(name, type); }
-        public abstract class Body extends HasFlags {
+        public abstract class Body extends HasAttributes {
+            public Body(int flags, ClassFile.AttrGen attrs) {
+                super(flags, attrs);
+                if ((flags & ~(PUBLIC|FINAL|SUPER|INTERFACE|ABSTRACT)) != 0)
+                    throw new IllegalArgumentException("invalid flags: " + Integer.toString(flags,16));
+            }
         }
 
         }
 
+        public Field field(String name, Type type) { return new Field(name, type); }
+
         public Method method(String name, Type returnType, Type[] argTypes) { return new Method(name, returnType, argTypes); }
         public Method method(String leftCrap, String rightCrap) { return method(leftCrap+rightCrap); }
 
         public Method method(String name, Type returnType, Type[] argTypes) { return new Method(name, returnType, argTypes); }
         public Method method(String leftCrap, String rightCrap) { return method(leftCrap+rightCrap); }
 
@@ -164,14 +170,12 @@ public abstract class Type implements CGConst {
             public String getTypeDescriptor() { return type.getDescriptor(); }
             public Type getType() { return type; }
             public String debugToString() { return getDeclaringClass().debugToString()+"."+name+"["+type.debugToString()+"]"; }
             public String getTypeDescriptor() { return type.getDescriptor(); }
             public Type getType() { return type; }
             public String debugToString() { return getDeclaringClass().debugToString()+"."+name+"["+type.debugToString()+"]"; }
-            public class Body extends HasFlags {
-                public final int flags;
-                public Body(int flags) {
+            public class Body extends HasAttributes {
+                public Field getField() { return Field.this; }
+                public Body(int flags, ClassFile.AttrGen attrs) {
+                    super(flags, attrs);
                     if ((flags & ~VALID_FIELD_FLAGS) != 0) throw new IllegalArgumentException("invalid flags");
                     if ((flags & ~VALID_FIELD_FLAGS) != 0) throw new IllegalArgumentException("invalid flags");
-                    this.flags = flags;
                 }
                 }
-                public int getFlags() { return flags; }
-                public Field getField() { return Field.this; }
             }
         }
 
             }
         }
 
@@ -217,9 +221,13 @@ public abstract class Type implements CGConst {
                 sb.append(returnType.getDescriptor());
                 return sb.toString();
             }
                 sb.append(returnType.getDescriptor());
                 return sb.toString();
             }
-            public abstract class Body extends HasFlags {
+            public abstract class Body extends HasAttributes {
                 public abstract java.util.Hashtable getThrownExceptions();
                 public abstract void debugBodyToString(StringBuffer sb);
                 public abstract java.util.Hashtable getThrownExceptions();
                 public abstract void debugBodyToString(StringBuffer sb);
+                public Body(int flags, ClassFile.AttrGen attrs) {
+                    super(flags, attrs);
+                    if ((flags & ~VALID_METHOD_FLAGS) != 0) throw new IllegalArgumentException("invalid flags");
+                }
                 public void debugToString(StringBuffer sb, String constructorName) {
                     int flags = getFlags();
                     sb.append("  ").append(ClassFile.flagsToString(flags,false));
                 public void debugToString(StringBuffer sb, String constructorName) {
                     int flags = getFlags();
                     sb.append("  ").append(ClassFile.flagsToString(flags,false));