1 cananian 1.6.2.2 // HMethodSyn.java, created Fri Oct 16 2:21:03 1998 by cananian 2 cananian 1.1 // Copyright (C) 1998 C. Scott Ananian <cananian@alumni.princeton.edu> 3 cananian 1.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 cananian 1.1 package harpoon.ClassFile; 5 cananian 1.1 6 cananian 1.6.2.6 import harpoon.Util.Util; 7 cananian 1.6.2.6 8 cananian 1.1 import java.lang.reflect.Modifier; 9 cananian 1.6 import java.util.Enumeration; 10 cananian 1.1 import java.util.Hashtable; 11 cananian 1.1 import java.util.Vector; 12 cananian 1.1 /** 13 cananian 1.1 * An <code>HMethodSyn</code> provides information about, and access to, a 14 cananian 1.1 * single method on a class or interface. The reflected method 15 cananian 1.1 * may be a class method or an instance method (including an abstract 16 cananian 1.1 * method). 17 cananian 1.1 * 18 cananian 1.1 * @author C. Scott Ananian <cananian@alumni.princeton.edu> 19 cananian 1.9 * @version $Id: HMethodSyn.java,v 1.9 2002/04/10 03:04:15 cananian Exp $ 20 cananian 1.1 * @see HMember 21 cananian 1.1 * @see HClass 22 cananian 1.1 */ 23 cananian 1.6.2.6 class HMethodSyn extends HMethodImpl implements HMethodMutator { 24 cananian 1.1 25 cananian 1.6.2.6 /** Create a new method like the <code>template</code>, but named 26 cananian 1.6.2.6 * <code>name</code>. 27 cananian 1.6 * The new method will be added to class <code>parent</code>. */ 28 cananian 1.6.2.6 HMethodSyn(HClassSyn parent, String name, HMethod template) { 29 cananian 1.6.2.11 this ((HClass)parent, name, template); 30 cananian 1.6.2.11 } 31 cananian 1.6.2.11 HMethodSyn(HClassArraySyn parent, String name, HMethod template) { 32 cananian 1.6.2.11 this ((HClass)parent, name, template); 33 cananian 1.6 } 34 cananian 1.6.2.11 // private, not-as-type-safe implementation. 35 cananian 1.6.2.11 private HMethodSyn(HClass parent, String name, HMethod template) { 36 cananian 1.6 this.parent = parent; 37 cananian 1.6.2.6 this.name = name; 38 cananian 1.1 this.modifiers = template.getModifiers(); 39 cananian 1.1 this.returnType = template.getReturnType(); 40 cananian 1.1 this.parameterTypes = template.getParameterTypes(); 41 cananian 1.1 this.parameterNames = template.getParameterNames(); 42 cananian 1.1 this.exceptionTypes = template.getExceptionTypes(); 43 cananian 1.1 this.isSynthetic = template.isSynthetic(); 44 cananian 1.6.2.8 // ensure linker information is consistent. 45 cananian 1.8.2.1 assert checkLinker((HClass)this.returnType); 46 cananian 1.6.2.8 for(int i=0; i<this.parameterTypes.length; i++) 47 cananian 1.8.2.1 assert checkLinker((HClass)this.parameterTypes[i]); 48 cananian 1.6.2.8 for(int i=0; i<this.exceptionTypes.length; i++) 49 cananian 1.8.2.1 assert checkLinker((HClass)this.exceptionTypes[i]); 50 nkushman 1.4 } 51 nkushman 1.4 52 cananian 1.6.2.6 /** Create a new empty method in the specified class 53 nkushman 1.4 * with the specified parameter and return types 54 nkushman 1.4 * that throws no checked exceptions. 55 nkushman 1.4 */ 56 cananian 1.6.2.6 HMethodSyn(HClassSyn parent, String name, 57 cananian 1.6 HClass[] paramTypes, HClass returnType) { 58 nkushman 1.4 this(parent, name, makeDescriptor (paramTypes, returnType)); 59 nkushman 1.4 } 60 cananian 1.6.2.11 HMethodSyn(HClassArraySyn parent, String name, 61 cananian 1.6 HClass[] paramTypes, HClass returnType) { 62 nkushman 1.4 this(parent, name, makeDescriptor (paramTypes, returnType)); 63 nkushman 1.4 } 64 nkushman 1.4 65 cananian 1.6.2.6 /** Create a new empty method in the specified class 66 cananian 1.2 * with the specified descriptor 67 cananian 1.2 * that throws no checked exceptions. 68 cananian 1.1 */ 69 cananian 1.6.2.6 HMethodSyn(HClassSyn parent, String name, String descriptor) { 70 cananian 1.6.2.11 this((HClass)parent, name, descriptor); 71 cananian 1.6.2.11 } 72 cananian 1.6.2.11 HMethodSyn(HClassArraySyn parent, String name, String descriptor) { 73 cananian 1.6.2.11 this((HClass)parent, name, descriptor); 74 cananian 1.6.2.11 } 75 cananian 1.6.2.11 // private, not-as-type-safe implementation. 76 cananian 1.6.2.11 private HMethodSyn(HClass parent, String name, String descriptor) { 77 cananian 1.1 this.parent = parent; 78 cananian 1.6.2.6 this.name = name; 79 cananian 1.6.2.6 this.modifiers = 0; 80 cananian 1.2 { // parse descriptor for return type. 81 cananian 1.2 String desc = descriptor.substring(descriptor.lastIndexOf(')')+1); 82 cananian 1.6.2.12 this.returnType = new ClassPointer(parent.getLinker(), desc); 83 cananian 1.2 } 84 cananian 1.2 { // parse descriptor for parameter types. 85 cananian 1.2 String desc = descriptor.substring(1, descriptor.lastIndexOf(')')); 86 cananian 1.2 Vector v = new Vector(); 87 cananian 1.2 for (int i=0; i<desc.length(); i++) { 88 cananian 1.6.2.12 int first = i; 89 cananian 1.2 while (desc.charAt(i)=='[') i++; 90 cananian 1.2 if (desc.charAt(i)=='L') i=desc.indexOf(';', i); 91 cananian 1.6.2.12 v.addElement(new ClassPointer(parent.getLinker(), 92 cananian 1.6.2.12 desc.substring(first, i+1))); 93 cananian 1.2 } 94 cananian 1.6.2.12 this.parameterTypes = new HPointer[v.size()]; 95 cananian 1.2 v.copyInto(this.parameterTypes); 96 cananian 1.2 } 97 cananian 1.2 this.parameterNames = new String[this.parameterTypes.length]; 98 cananian 1.1 this.exceptionTypes = new HClass[0]; 99 cananian 1.1 this.isSynthetic = false; 100 cananian 1.1 } 101 cananian 1.1 102 cananian 1.6.2.6 public HMethodMutator getMutator() { return this; } 103 cananian 1.1 104 cananian 1.6.2.6 public void addModifiers(int m) { setModifiers(getModifiers()|m); } 105 cananian 1.6.2.6 public void removeModifiers(int m) { setModifiers(getModifiers()&(~m)); } 106 cananian 1.6.2.6 public void setModifiers(int m) { 107 cananian 1.6.2.6 if (this.modifiers != m) parent.hasBeenModified = true; 108 cananian 1.6.2.6 this.modifiers = m; 109 cananian 1.6.2.6 } 110 cananian 1.1 111 cananian 1.6.2.6 public void setReturnType(HClass returnType) { 112 cananian 1.8.2.1 assert checkLinker(returnType); 113 cananian 1.6.2.6 if (this.returnType != returnType) parent.hasBeenModified = true; 114 cananian 1.6.2.6 this.returnType = returnType; 115 cananian 1.6.2.6 } 116 cananian 1.1 117 cananian 1.2 /** Warning: use can cause method name conflicts in class. */ 118 cananian 1.1 public void setParameterTypes(HClass[] parameterTypes) { 119 cananian 1.6.2.8 for (int i=0; i<parameterTypes.length; i++) 120 cananian 1.8.2.1 assert checkLinker(parameterTypes[i]); 121 cananian 1.6.2.6 if (this.parameterTypes.length != parameterTypes.length) 122 cananian 1.6.2.6 parent.hasBeenModified = true; 123 cananian 1.6.2.6 else for (int i=0; 124 cananian 1.6.2.6 i<this.parameterTypes.length && i<parameterTypes.length; i++) 125 cananian 1.6.2.6 if (this.parameterTypes[i] != parameterTypes[i]) 126 cananian 1.6.2.6 parent.hasBeenModified = true; 127 cananian 1.1 this.parameterTypes = parameterTypes; 128 cananian 1.1 } 129 cananian 1.2 /** Warning: use can cause method name conflicts in class. */ 130 cananian 1.1 public void setParameterType(int which, HClass type) { 131 cananian 1.8.2.1 assert checkLinker(type); 132 cananian 1.6.2.6 if (this.parameterTypes[which] != type) 133 cananian 1.6.2.6 parent.hasBeenModified = true; 134 cananian 1.1 this.parameterTypes[which] = type; 135 cananian 1.1 } 136 cananian 1.1 137 cananian 1.1 public void setParameterNames(String[] parameterNames) { 138 cananian 1.1 this.parameterNames = parameterNames; 139 cananian 1.1 } 140 cananian 1.1 public void setParameterName(int which, String name) { 141 cananian 1.1 this.parameterNames[which] = name; 142 cananian 1.1 } 143 cananian 1.1 144 cananian 1.6.2.6 public void addExceptionType(HClass exceptionType) { 145 cananian 1.8.2.1 assert checkLinker(exceptionType); 146 cananian 1.6.2.6 for (int i=0; i<exceptionTypes.length; i++) 147 cananian 1.6.2.6 if (exceptionTypes[i]==exceptionType) 148 cananian 1.6.2.6 return; 149 cananian 1.6.2.6 this.exceptionTypes = (HPointer[]) Util.grow(HPointer.arrayFactory, 150 cananian 1.6.2.6 exceptionTypes, exceptionType, 151 cananian 1.6.2.6 exceptionTypes.length); 152 cananian 1.6.2.6 parent.hasBeenModified = true; 153 cananian 1.6.2.6 } 154 cananian 1.1 public void setExceptionTypes(HClass[] exceptionTypes) { 155 cananian 1.6.2.8 for (int i=0; i<exceptionTypes.length; i++) 156 cananian 1.8.2.1 assert checkLinker(exceptionTypes[i]); 157 cananian 1.6.2.6 if (this.exceptionTypes.length != exceptionTypes.length) 158 cananian 1.6.2.6 parent.hasBeenModified = true; 159 cananian 1.6.2.6 else for (int i=0; 160 cananian 1.6.2.6 i<this.exceptionTypes.length && i<exceptionTypes.length; i++) 161 cananian 1.6.2.6 if (this.exceptionTypes[i] != exceptionTypes[i]) 162 cananian 1.6.2.6 parent.hasBeenModified = true; 163 cananian 1.1 this.exceptionTypes = exceptionTypes; 164 cananian 1.1 } 165 cananian 1.6.2.6 public void removeExceptionType(HClass exceptionType) { 166 cananian 1.8.2.1 assert checkLinker(exceptionType); 167 cananian 1.6.2.6 for (int i=0; i<exceptionTypes.length; i++) 168 cananian 1.6.2.6 if (exceptionTypes[i].actual().equals(exceptionType)) { 169 cananian 1.6.2.6 exceptionTypes = (HPointer[]) Util.shrink(HPointer.arrayFactory, 170 cananian 1.6.2.6 exceptionTypes, i); 171 cananian 1.6.2.6 parent.hasBeenModified = true; 172 cananian 1.6.2.6 return; 173 cananian 1.6.2.6 } 174 cananian 1.1 } 175 cananian 1.1 176 cananian 1.1 public void setSynthetic(boolean isSynthetic) { 177 cananian 1.6.2.6 if (this.isSynthetic != isSynthetic) parent.hasBeenModified = true; 178 cananian 1.1 this.isSynthetic = isSynthetic; 179 cananian 1.3 } 180 cananian 1.3 181 cananian 1.6 //---------------------------------------------------------- 182 cananian 1.6 183 cananian 1.6.2.6 /** Make a method descriptor string given parameter and return value types. 184 cananian 1.6 * A helper function. */ 185 cananian 1.6.2.4 static String makeDescriptor(HClass[] paramTypes, HClass returnType){ 186 cananian 1.6 StringBuffer sb = new StringBuffer(); 187 cananian 1.6 sb.append ('('); 188 cananian 1.6 for (int i = 0; i < paramTypes.length; i++){ 189 cananian 1.6 sb.append (paramTypes[i].getDescriptor()); 190 cananian 1.6 } 191 cananian 1.6 sb.append (')'); 192 cananian 1.6 sb.append (returnType.getDescriptor()); 193 cananian 1.6 return sb.toString(); 194 cananian 1.1 } 195 cananian 1.6.2.3 196 cananian 1.6.2.9 //---------------------------------------------------------- 197 cananian 1.6.2.9 // assertion helper. 198 cananian 1.6.2.9 private boolean checkLinker(HClass hc) { 199 cananian 1.6.2.9 return hc.isPrimitive() || hc.getLinker()==parent.getLinker(); 200 cananian 1.6.2.9 } 201 cananian 1.6.2.3 //---------------------------------------------------------- 202 cananian 1.1 } 203 cananian 1.1 204 cananian 1.1 // set emacs indentation style. 205 cananian 1.1 // Local Variables: 206 cananian 1.1 // c-basic-offset:2 207 cananian 1.1 // End: