pulled {Method,Member,Field}Ref into Type.Class; made them inner classes; much cleaner
authoradam <adam@megacz.com>
Fri, 3 Jun 2005 05:57:51 +0000 (05:57 +0000)
committeradam <adam@megacz.com>
Fri, 3 Jun 2005 05:57:51 +0000 (05:57 +0000)
darcs-hash:20050603055751-5007d-0475599d53090e3875c0dd4d54a2a2d34e033a08.gz

src/org/ibex/classgen/CPGen.java
src/org/ibex/classgen/ClassFile.java
src/org/ibex/classgen/FieldRef.java [deleted file]
src/org/ibex/classgen/MemberRef.java [deleted file]
src/org/ibex/classgen/MethodGen.java
src/org/ibex/classgen/MethodRef.java [deleted file]
src/org/ibex/classgen/Type.java

index 92f7643..edc4d9c 100644 (file)
@@ -89,12 +89,12 @@ class CPGen {
                     NameAndTypeKey nt = (NameAndTypeKey) e2.key();
                     Type t = Type.instance(nt.type);
                     if(t == null) throw new ClassFile.ClassReadExn("invalid type descriptor");
                     NameAndTypeKey nt = (NameAndTypeKey) e2.key();
                     Type t = Type.instance(nt.type);
                     if(t == null) throw new ClassFile.ClassReadExn("invalid type descriptor");
-                    return new FieldRef((Type.Class)e1.key(), nt.name, t);
+                    return ((Type.Class)e1.key()).field(nt.name, t);
                 }
                 case 10: case 11: {
                     NameAndTypeKey nt = (NameAndTypeKey) e2.key();
                     if (e1.key() == null) throw new Error(e1.tag + " => " + e1.key());
                 }
                 case 10: case 11: {
                     NameAndTypeKey nt = (NameAndTypeKey) e2.key();
                     if (e1.key() == null) throw new Error(e1.tag + " => " + e1.key());
-                    return new MethodRef((Type.Class)e1.key(), "methodname", Type.VOID, new Type[0]); // FIXME FIXME
+                    return ((Type.Class)e1.key()).method("methodname", Type.VOID, new Type[0]); // FIXME FIXME
                 }
                 case 12: {
                     return new NameAndTypeKey(((Utf8Ent)e1).s, ((Utf8Ent)e2).s); 
                 }
                 case 12: {
                     return new NameAndTypeKey(((Utf8Ent)e1).s, ((Utf8Ent)e2).s); 
@@ -215,12 +215,12 @@ class CPGen {
             ce.e1 = addUtf8(key.name);
             ce.e2 = addUtf8(key.type);
             ent = ce;
             ce.e1 = addUtf8(key.name);
             ce.e2 = addUtf8(key.type);
             ent = ce;
-        } else if(o instanceof MemberRef) {
-            MemberRef key = (MemberRef) o;
-            int tag = invokeInterface ? 11 : o instanceof FieldRef ? 9 : o instanceof MethodRef ? 10 : 0;
+        } else if(o instanceof Type.Class.Member) {
+            Type.Class.Member key = (Type.Class.Member) o;
+            int tag = invokeInterface ? 11 : o instanceof Type.Class.Field ? 9 : o instanceof Type.Class.Method ? 10 : 0;
             if(tag == 0) throw new Error("should never happen");
             CPRefEnt ce = new CPRefEnt(tag);
             if(tag == 0) throw new Error("should never happen");
             CPRefEnt ce = new CPRefEnt(tag);
-            ce.e1 = add(key.klass);
+            ce.e1 = add(key.getDeclaringClass());
             ce.e2 = addNameAndType(key.name, key.getDescriptor());
             ent = ce;
         } else {
             ce.e2 = addNameAndType(key.name, key.getDescriptor());
             ent = ce;
         } else {
@@ -326,8 +326,8 @@ class CPGen {
             switch(tag) {
                 case 7: // Object Type
                 case 8: // String
             switch(tag) {
                 case 7: // Object Type
                 case 8: // String
-                case 9: // FieldRef
-                case 10: // MethodRef
+                case 9: // Type.Class.Field
+                case 10: // Type.Class.Method
                 case 11: // Instance Method Ref
                 case 12: // NameAndType
                 {
                 case 11: // Instance Method Ref
                 case 12: // NameAndType
                 {
index 6be6bfa..29b8d7f 100644 (file)
@@ -34,7 +34,8 @@ public class ClassFile implements CGConst {
         if ((flags & ACC_TRANSIENT) != 0)    ret += "transient ";
         return ret;
     }
         if ((flags & ACC_TRANSIENT) != 0)    ret += "transient ";
         return ret;
     }
-  
+
+    public Type.Class getType() { return thisType; }
     public String toString() { StringBuffer sb = new StringBuffer(); toString(sb); return sb.toString(); }
     public void   toString(StringBuffer sb) {
         sb.append(flagsToString(flags));
     public String toString() { StringBuffer sb = new StringBuffer(); toString(sb); return sb.toString(); }
     public void   toString(StringBuffer sb) {
         sb.append(flagsToString(flags));
@@ -227,7 +228,7 @@ public class ClassFile implements CGConst {
         int numFields = i.readShort();
         for(int j=0; j<numFields; j++) fields.add(new FieldGen(cp, i));
         int numMethods = i.readShort();
         int numFields = i.readShort();
         for(int j=0; j<numFields; j++) fields.add(new FieldGen(cp, i));
         int numMethods = i.readShort();
-        for(int j=0; j<numMethods; j++) methods.add(new MethodGen(cp, i));
+        for(int j=0; j<numMethods; j++) methods.add(new MethodGen(cp, i, this));
         attributes = new AttrGen(cp, i);
         sourceFile = (String)attributes.get("SourceFile");
     }
         attributes = new AttrGen(cp, i);
         sourceFile = (String)attributes.get("SourceFile");
     }
diff --git a/src/org/ibex/classgen/FieldRef.java b/src/org/ibex/classgen/FieldRef.java
deleted file mode 100644 (file)
index b13fd4d..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-package org.ibex.classgen;
-
-/** This class represents Field references. It is used as an argument to the 
-GETFIELD, PUTFIELD, GETSTATIC, and PUTSTATCI bytecodes 
-@see CGConst#GETFIELD
-@see CGConst#PUTFIELD
-@see CGConst#GETSTATIC
-@see CGConst#PUTSTATIC
-*/
-public class FieldRef extends MemberRef {
-    /** Create a reference to field <i>name</i> of class <i>c</i> with the type <i>t</i>  */    
-    public final Type type;
-    public FieldRef(Type.Class c, String name, Type t) { super(c, name); this.type = t; }
-    public String getDescriptor() { return name; }
-}
-
diff --git a/src/org/ibex/classgen/MemberRef.java b/src/org/ibex/classgen/MemberRef.java
deleted file mode 100644 (file)
index ca39c93..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-package org.ibex.classgen;
-
-import java.util.*;
-import java.io.*;
-
-/** A class representing a field or method reference. This is used as an argument to the INVOKE*, GET*, and PUT* bytecodes
-    @see MethodRef
-    @see FieldRef
-    @see MethodRef.I
-    @see FieldRef
-*/
-public abstract class MemberRef {
-    public final Type.Class klass;
-    public final String name;
-        
-    MemberRef(Type.Class klass, String name) {
-        this.klass = klass;
-        this.name = name;
-    }
-    public abstract String getDescriptor();
-    public boolean equals(Object o_) {
-        if(!(o_ instanceof MemberRef)) return false;
-        MemberRef o = (MemberRef) o_;
-        return o.klass.equals(klass) && o.name.equals(name) && o.getDescriptor().equals(getDescriptor());
-    }
-    public int hashCode() { return klass.hashCode() ^ name.hashCode() ^ getDescriptor().hashCode(); }
-}
-    
index 31d1229..ba055bf 100644 (file)
@@ -10,7 +10,8 @@ public class MethodGen implements CGConst {
     
     private static final int NO_CODE = -1;
     private static final int FINISHED = -2;
     
     private static final int NO_CODE = -1;
     private static final int FINISHED = -2;
-    
+
+    private final ClassFile owner;
     private final CPGen cp;
     private final String name;
     private final Type ret;
     private final CPGen cp;
     private final String name;
     private final Type ret;
@@ -49,8 +50,9 @@ public class MethodGen implements CGConst {
         // FIXME: attrs, body
     }
 
         // FIXME: attrs, body
     }
 
-    MethodGen(CPGen cp, DataInput in) throws IOException {
+    MethodGen(CPGen cp, DataInput in, ClassFile owner) throws IOException {
         this.cp = cp;
         this.cp = cp;
+        this.owner = owner;
         flags = in.readShort();
         name = cp.getUtf8ByIndex(in.readShort());
         String descriptor = cp.getUtf8ByIndex(in.readShort());
         flags = in.readShort();
         name = cp.getUtf8ByIndex(in.readShort());
         String descriptor = cp.getUtf8ByIndex(in.readShort());
@@ -70,21 +72,19 @@ public class MethodGen implements CGConst {
         this.ret = ret;
         this.args = args;
         this.flags = flags;
         this.ret = ret;
         this.args = args;
         this.flags = flags;
+        this.owner = owner;
         
         attrs = new ClassFile.AttrGen(cp);
         codeAttrs = new ClassFile.AttrGen(cp);
         
         cp.addUtf8(name);
         
         attrs = new ClassFile.AttrGen(cp);
         codeAttrs = new ClassFile.AttrGen(cp);
         
         cp.addUtf8(name);
-        cp.addUtf8(getDescriptor());
+        cp.addUtf8(owner.getType().method(name, ret, args).getDescriptor());
         
         if((owner.flags & ACC_INTERFACE) != 0 || (flags & (ACC_ABSTRACT|ACC_NATIVE)) != 0) size = capacity = -1;
         
         maxLocals = Math.max(args.length + (flags&ACC_STATIC)==0 ? 1 : 0, 4);
     }
     
         
         if((owner.flags & ACC_INTERFACE) != 0 || (flags & (ACC_ABSTRACT|ACC_NATIVE)) != 0) size = capacity = -1;
         
         maxLocals = Math.max(args.length + (flags&ACC_STATIC)==0 ? 1 : 0, 4);
     }
     
-    /** Returns the descriptor string for this method */
-    public String getDescriptor() { return new MethodRef(null, name, ret, args).getDescriptor(); }
-    
     private class ExnTableEnt {
         public int start;
         public int end;
     private class ExnTableEnt {
         public int start;
         public int end;
@@ -629,7 +629,7 @@ public class MethodGen implements CGConst {
     void dump(DataOutput o) throws IOException {
         o.writeShort(flags);
         o.writeShort(cp.getUtf8Index(name));
     void dump(DataOutput o) throws IOException {
         o.writeShort(flags);
         o.writeShort(cp.getUtf8Index(name));
-        o.writeShort(cp.getUtf8Index(getDescriptor()));
+        o.writeShort(cp.getUtf8Index(owner.getType().method(name, ret, args).getDescriptor()));
         o.writeShort(attrs.size());
         attrs.dump(o);
     }
         o.writeShort(attrs.size());
         attrs.dump(o);
     }
diff --git a/src/org/ibex/classgen/MethodRef.java b/src/org/ibex/classgen/MethodRef.java
deleted file mode 100644 (file)
index 6dbb46f..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.ibex.classgen;
-
-/** This class represents Method references. It is used as an argument to the 
-    INVOKESTATIC, INVOKEVIRTUAL, INVOKESPEICAL, and INVOKEINTERFACE bytecodes 
-    @see CGConst#INVOKESTATIC
-    @see CGConst#INVOKEVIRTUAL
-    @see CGConst#INVOKESPECIAL
-    @see CGConst#INVOKEINTERFACE
-*/
-public class MethodRef extends MemberRef {
-    
-    final Type[] argTypes;
-    final Type   returnType;
-
-    /** Create a reference to method <i>name</i> of class <i>c</i> with the return type <i>ret</i> and the
-        arguments <i>args</i> */
-    public MethodRef(Type.Class c, String name, Type returnType, Type[] argTypes) {
-        super(c, name);
-        this.argTypes = argTypes;
-        this.returnType = returnType;
-    }
-    
-    public String getDescriptor() {
-        StringBuffer sb = new StringBuffer(argTypes.length*4);
-        sb.append("(");
-        for(int i=0;i<argTypes.length;i++) sb.append(argTypes[i].getDescriptor());
-        sb.append(")");
-        sb.append(returnType.getDescriptor());
-        return sb.toString();
-    }
-}
index 84c9343..491cc12 100644 (file)
@@ -89,6 +89,50 @@ public class Type {
             for(int i=0;st.hasMoreTokens();i++) a[i] = st.nextToken();
             return a;
         }
             for(int i=0;st.hasMoreTokens();i++) a[i] = st.nextToken();
             return a;
         }
+
+        public Method method(String name, Type returnType, Type[] argTypes) { return new Method(name, returnType, argTypes); }
+        public Field  field(String name, Type type) { return new Field(name, type); }
+
+        public abstract class Member {
+            public final String name;
+            private Member(String name) { this.name = name; }
+            public Type.Class getDeclaringClass() { return Type.Class.this; }
+            public abstract String getDescriptor();
+            public boolean equals(Object o_) {
+                if(!(o_ instanceof Member)) return false;
+                Member o = (Member) o_;
+                return o.getDeclaringClass().equals(getDeclaringClass()) &&
+                    o.name.equals(name) &&
+                    o.getDescriptor().equals(getDescriptor());
+            }
+            public int hashCode() { return getDeclaringClass().hashCode() ^ name.hashCode() ^ getDescriptor().hashCode(); }
+        }
+    
+        public class Field extends Member {
+            /** Create a reference to field <i>name</i> of class <i>c</i> with the type <i>t</i>  */    
+            public final Type type;
+            private Field(String name, Type t) { super(name); this.type = t; }
+            public String getDescriptor() { return name; }
+        }
+
+        public class Method extends Member {
+            final Type[] argTypes;
+            final Type   returnType;
+            private Method(String name, Type returnType, Type[] argTypes) {
+                super(name);
+                this.argTypes = argTypes;
+                this.returnType = returnType;
+            }
+            public String getDescriptor() {
+                StringBuffer sb = new StringBuffer(argTypes.length*4);
+                sb.append("(");
+                for(int i=0;i<argTypes.length;i++) sb.append(argTypes[i].getDescriptor());
+                sb.append(")");
+                sb.append(returnType.getDescriptor());
+                return sb.toString();
+            }
+        }
+
     }    
 
     public static class Array extends Type.Ref {
     }    
 
     public static class Array extends Type.Ref {