1 cananian 1.1.2.1 // HClassArraySyn.java, created Fri Oct 20 17:34:37 2000 by cananian 2 cananian 1.1.2.1 // Copyright (C) 2000 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1.2.1 package harpoon.ClassFile; 5 cananian 1.1.2.1 6 cananian 1.1.2.1 import harpoon.Util.Util; 7 cananian 1.1.2.1 8 cananian 1.1.2.1 import java.util.ArrayList; 9 cananian 1.1.2.5 import java.util.Iterator; 10 cananian 1.1.2.1 import java.util.List; 11 cananian 1.1.2.1 /** 12 cananian 1.1.2.1 * <code>HClassArraySyn</code> is a simple subclass of 13 cananian 1.1.2.1 * <code>HClassArray</code> which allows you to add methods 14 cananian 1.1.2.1 * (not fields, class initializers, or constructors) to 15 cananian 1.1.2.1 * an array type. 16 cananian 1.1.2.1 * 17 cananian 1.1.2.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 18 cananian 1.5 * @version $Id: HClassArraySyn.java,v 1.5 2004/02/08 03:21:10 cananian Exp $ 19 cananian 1.1.2.1 */ 20 cananian 1.1.2.1 class HClassArraySyn extends HClassArray implements HClassMutator { 21 cananian 1.1.2.4 final List declaredMethods = new ArrayList(4); 22 cananian 1.1.2.1 23 cananian 1.1.2.1 /** Creates a <code>HClassArraySyn</code>. */ 24 cananian 1.1.2.1 HClassArraySyn(Linker linker, HClass baseType, int dims) { 25 cananian 1.1.2.6 this(linker, baseType, dims, true/*init w/ clone method*/); 26 cananian 1.1.2.6 } 27 cananian 1.1.2.6 private HClassArraySyn(Linker linker, HClass baseType, int dims, 28 cananian 1.1.2.6 boolean init) { 29 cananian 1.1.2.1 super(linker, baseType, dims); 30 cananian 1.1.2.6 if (init) // we skip this step when restoring from serialized form. 31 cananian 1.1.2.6 declaredMethods.add // even clone method is mutable. 32 cananian 1.1.2.6 (new HMethodSyn(this, cloneMethod.getName(), cloneMethod)); 33 cananian 1.1.2.1 } 34 cananian 1.1.2.1 /** Allow mutation. */ 35 cananian 1.1.2.1 public HClassMutator getMutator() { return this; } 36 cananian 1.1.2.3 public HMethod[] getDeclaredMethods() { 37 cananian 1.1.2.3 return (HMethod[]) 38 cananian 1.1.2.3 declaredMethods.toArray(new HMethod[declaredMethods.size()]); 39 cananian 1.1.2.3 } 40 cananian 1.1.2.1 41 cananian 1.1.2.1 // Allowed mutations. ----------------------------------------- 42 cananian 1.1.2.1 public HMethod addDeclaredMethod(String name, String descriptor) { 43 cananian 1.3.2.1 assert !name.equals("<init>") && !name.equals("<clinit>"); 44 cananian 1.1.2.1 return addDeclaredMethod0(new HMethodSyn(this, name, descriptor)); 45 cananian 1.1.2.1 } 46 cananian 1.1.2.1 public HMethod addDeclaredMethod(String name, HClass[] paramTypes, 47 cananian 1.1.2.1 HClass returnType) { 48 cananian 1.3.2.1 assert !name.equals("<init>") && !name.equals("<clinit>"); 49 cananian 1.3.2.1 assert checkLinker(returnType); 50 cananian 1.1.2.1 for (int i=0; i<paramTypes.length; i++) 51 cananian 1.3.2.1 assert checkLinker(paramTypes[i]); 52 cananian 1.1.2.1 return addDeclaredMethod0(new HMethodSyn(this, name, paramTypes, 53 cananian 1.1.2.1 returnType)); 54 cananian 1.1.2.1 } 55 cananian 1.1.2.1 public HMethod addDeclaredMethod(String name, HMethod template) { 56 cananian 1.3.2.1 assert !name.equals("<init>") && !name.equals("<clinit>"); 57 cananian 1.1.2.1 return addDeclaredMethod0(new HMethodSyn(this, name, template)); 58 cananian 1.1.2.1 } 59 cananian 1.1.2.1 /** single implementation. */ 60 cananian 1.1.2.1 private HMethod addDeclaredMethod0(HMethodSyn hm) { 61 cananian 1.3.2.1 assert hm.getDeclaringClass()==this; 62 cananian 1.1.2.1 if (declaredMethods.contains(hm)) 63 cananian 1.1.2.1 throw new DuplicateMemberException("Method "+hm+" in "+this); 64 cananian 1.1.2.1 declaredMethods.add(hm); 65 cananian 1.1.2.1 hasBeenModified=true; // flag the modification 66 cananian 1.1.2.1 return hm; 67 cananian 1.1.2.1 } 68 cananian 1.1.2.1 public void removeDeclaredMethod(HMethod m) throws NoSuchMethodError { 69 cananian 1.1.2.1 if (declaredMethods.remove(m)) { 70 cananian 1.1.2.1 hasBeenModified=true; // flag the modification 71 cananian 1.1.2.1 return; 72 cananian 1.1.2.1 } 73 cananian 1.1.2.1 throw new NoSuchMemberException("Method "+m+" in "+this); 74 cananian 1.1.2.1 } 75 cananian 1.1.2.1 76 cananian 1.1.2.1 // Unallowed mutations. --------------------------------------- 77 cananian 1.1.2.1 public HField addDeclaredField(String name, HClass type) 78 cananian 1.1.2.1 throws DuplicateMemberException { 79 cananian 1.1.2.1 throw new Error("Adding fields to arrays is not allowed."); 80 cananian 1.1.2.1 } 81 cananian 1.1.2.1 public HField addDeclaredField(String name, String descriptor) 82 cananian 1.1.2.1 throws DuplicateMemberException { 83 cananian 1.1.2.1 throw new Error("Adding fields to arrays is not allowed."); 84 cananian 1.1.2.1 } 85 cananian 1.1.2.1 public HField addDeclaredField(String name, HField template) 86 cananian 1.1.2.1 throws DuplicateMemberException { 87 cananian 1.1.2.1 throw new Error("Adding fields to arrays is not allowed."); 88 cananian 1.1.2.1 } 89 cananian 1.1.2.1 public void removeDeclaredField(HField f) throws NoSuchMemberException { 90 cananian 1.1.2.1 if (f==lengthField) 91 cananian 1.1.2.1 throw new Error("Removing the length fields from an array is not "+ 92 cananian 1.1.2.1 "allowed."); 93 cananian 1.1.2.1 else throw new NoSuchMemberException(f.toString()); 94 cananian 1.1.2.1 } 95 cananian 1.1.2.1 public HInitializer addClassInitializer() throws DuplicateMemberException { 96 cananian 1.1.2.1 throw new Error("Adding a class initializer to an array is not "+ 97 cananian 1.1.2.1 "allowed."); 98 cananian 1.1.2.1 } 99 cananian 1.1.2.1 public void removeClassInitializer(HInitializer m) 100 cananian 1.1.2.1 throws NoSuchMemberException { 101 cananian 1.1.2.1 throw new NoSuchMemberException(m.toString()); 102 cananian 1.1.2.1 } 103 cananian 1.1.2.1 public HConstructor addConstructor(String descriptor) 104 cananian 1.1.2.1 throws DuplicateMemberException { 105 cananian 1.1.2.1 throw new Error("Adding a constructor to an array is not allowed."); 106 cananian 1.1.2.1 } 107 cananian 1.1.2.1 public HConstructor addConstructor(HClass[] paramTypes) 108 cananian 1.1.2.1 throws DuplicateMemberException { 109 cananian 1.1.2.1 throw new Error("Adding a constructor to an array is not allowed."); 110 cananian 1.1.2.1 } 111 cananian 1.1.2.1 public HConstructor addConstructor(HConstructor template) 112 cananian 1.1.2.1 throws DuplicateMemberException { 113 cananian 1.1.2.1 throw new Error("Adding a constructor to an array is not allowed."); 114 cananian 1.1.2.1 } 115 cananian 1.1.2.1 public void removeConstructor(HConstructor c) 116 cananian 1.1.2.1 throws NoSuchMemberException { 117 cananian 1.1.2.1 throw new NoSuchMemberException(c.toString()); 118 cananian 1.1.2.1 } 119 cananian 1.1.2.1 public void addInterface(HClass in) { 120 cananian 1.1.2.1 throw new Error("Not allowed to add interfaces to an array."); 121 cananian 1.1.2.1 } 122 cananian 1.1.2.1 public void removeInterface(HClass in) 123 cananian 1.1.2.1 throws NoSuchClassException { 124 cananian 1.1.2.1 throw new Error("Not allowed to remove interfaces from an array."); 125 cananian 1.1.2.1 } 126 cananian 1.1.2.1 public void removeAllInterfaces() { 127 cananian 1.1.2.1 throw new Error("Not allowed to remove interfaces from an array."); 128 cananian 1.1.2.1 } 129 cananian 1.1.2.1 public void addModifiers(int m) { 130 cananian 1.1.2.1 throw new Error("Not allowed to change the modifiers of an array."); 131 cananian 1.1.2.1 } 132 cananian 1.1.2.1 public void setModifiers(int m) { 133 cananian 1.1.2.1 throw new Error("Not allowed to change the modifiers of an array."); 134 cananian 1.1.2.1 } 135 cananian 1.1.2.1 public void removeModifiers(int m) { 136 cananian 1.1.2.1 throw new Error("Not allowed to change the modifiers of an array."); 137 cananian 1.1.2.1 } 138 cananian 1.1.2.1 public void setSuperclass(HClass sc) { 139 cananian 1.1.2.1 throw new Error("Not allowed to change the superclass of an array."); 140 cananian 1.1.2.1 } 141 cananian 1.1.2.1 public void setSourceFile(String sourcefilename) { 142 cananian 1.1.2.1 throw new Error("Not allowed to reset the source file of an array."); 143 cananian 1.1.2.1 } 144 cananian 1.1.2.1 145 cananian 1.1.2.1 //---------------------------------------------------------- 146 cananian 1.1.2.1 // assertion helper. 147 cananian 1.1.2.1 private boolean checkLinker(HClass hc) { 148 cananian 1.1.2.1 return hc.isPrimitive() || hc.getLinker()==getLinker(); 149 cananian 1.1.2.1 } 150 cananian 1.1.2.1 //---------------------------------------------------------- 151 cananian 1.1.2.4 152 cananian 1.1.2.4 /** Serializable interface. */ 153 cananian 1.1.2.4 public Object writeReplace() { 154 cananian 1.1.2.5 return new Stub(this); 155 cananian 1.1.2.4 } 156 cananian 1.1.2.4 private static final class Stub implements java.io.Serializable { 157 cananian 1.1.2.4 private final Linker linker; 158 cananian 1.1.2.4 private final HClass baseType; 159 cananian 1.1.2.4 private final int dims; 160 cananian 1.1.2.4 private final List declaredMethods; 161 cananian 1.1.2.4 private final boolean modified; 162 cananian 1.1.2.4 Stub(HClassArraySyn c) { // store salient information. 163 cananian 1.1.2.4 this.linker = c.getLinker(); 164 cananian 1.1.2.4 this.baseType = c.baseType; 165 cananian 1.1.2.4 this.dims = c.dims; 166 cananian 1.1.2.4 this.modified = c.hasBeenModified; 167 cananian 1.1.2.6 this.declaredMethods = new ArrayList(c.declaredMethods.size()); 168 cananian 1.5 for (Object hmO : c.declaredMethods) { 169 cananian 1.5 HMethod hm = (HMethod) hmO; 170 cananian 1.1.2.5 this.declaredMethods.add(new HClassSyn.MethodStub(hm)); 171 cananian 1.1.2.5 } 172 cananian 1.1.2.4 } 173 cananian 1.1.2.4 public Object readResolve() { 174 cananian 1.1.2.6 HClassArraySyn c=new HClassArraySyn(linker, baseType, dims, false); 175 cananian 1.1.2.5 for (Iterator it=declaredMethods.iterator(); it.hasNext(); ) { 176 cananian 1.1.2.5 HMethod hm = ((HClassSyn.MethodStub)it.next()).reconstruct(c); 177 cananian 1.1.2.5 c.declaredMethods.add(hm); 178 cananian 1.1.2.5 } 179 cananian 1.1.2.4 c.hasBeenModified = this.modified; 180 cananian 1.1.2.4 return c; 181 cananian 1.1.2.4 } 182 cananian 1.1.2.4 } 183 cananian 1.2 }