1 16 17 package org.cojen.classfile; 18 19 import java.util.ArrayList ; 20 import java.util.List ; 21 import java.io.DataInput ; 22 import java.io.DataOutput ; 23 import java.io.IOException ; 24 import java.lang.reflect.Modifier ; 25 import org.cojen.classfile.attribute.Annotation; 26 import org.cojen.classfile.attribute.AnnotationsAttr; 27 import org.cojen.classfile.attribute.CodeAttr; 28 import org.cojen.classfile.attribute.DeprecatedAttr; 29 import org.cojen.classfile.attribute.EnclosingMethodAttr; 30 import org.cojen.classfile.attribute.ExceptionsAttr; 31 import org.cojen.classfile.attribute.RuntimeInvisibleAnnotationsAttr; 32 import org.cojen.classfile.attribute.RuntimeVisibleAnnotationsAttr; 33 import org.cojen.classfile.attribute.SignatureAttr; 34 import org.cojen.classfile.attribute.SourceFileAttr; 35 import org.cojen.classfile.attribute.SyntheticAttr; 36 import org.cojen.classfile.constant.ConstantClassInfo; 37 import org.cojen.classfile.constant.ConstantUTFInfo; 38 39 49 public class MethodInfo { 50 private ClassFile mParent; 51 private ConstantPool mCp; 52 53 private String mName; 54 private MethodDesc mDesc; 55 56 private Modifiers mModifiers; 57 58 private ConstantUTFInfo mNameConstant; 59 private ConstantUTFInfo mDescriptorConstant; 60 61 private List mAttributes = new ArrayList (2); 62 63 private CodeAttr mCode; 64 private ExceptionsAttr mExceptions; 65 66 private int mAnonymousInnerClassCount = 0; 67 68 MethodInfo(ClassFile parent, 69 Modifiers modifiers, 70 String name, 71 MethodDesc desc) { 72 73 mParent = parent; 74 mCp = parent.getConstantPool(); 75 mName = name; 76 mDesc = desc; 77 78 mModifiers = modifiers; 79 mNameConstant = mCp.addConstantUTF(name); 80 mDescriptorConstant = mCp.addConstantUTF(desc.getDescriptor()); 81 82 if (!modifiers.isAbstract() && !modifiers.isNative()) { 83 addAttribute(new CodeAttr(mCp)); 84 } 85 } 86 87 private MethodInfo(ClassFile parent, 88 int modifier, 89 ConstantUTFInfo nameConstant, 90 ConstantUTFInfo descConstant) { 91 92 mParent = parent; 93 mCp = parent.getConstantPool(); 94 mName = nameConstant.getValue(); 95 mDesc = MethodDesc.forDescriptor(descConstant.getValue()); 96 97 mModifiers = Modifiers.getInstance(modifier); 98 mNameConstant = nameConstant; 99 mDescriptorConstant = descConstant; 100 } 101 102 105 public ClassFile getClassFile() { 106 return mParent; 107 } 108 109 112 public String getName() { 113 return mName; 114 } 115 116 120 public MethodDesc getMethodDescriptor() { 121 return mDesc; 122 } 123 124 127 public Modifiers getModifiers() { 128 return mModifiers; 129 } 130 131 public void setModifiers(Modifiers modifiers) { 132 mModifiers = modifiers; 133 } 134 135 138 public ConstantUTFInfo getNameConstant() { 139 return mNameConstant; 140 } 141 142 147 public ConstantUTFInfo getDescriptorConstant() { 148 return mDescriptorConstant; 149 } 150 151 154 public TypeDesc[] getExceptions() { 155 if (mExceptions == null) { 156 return new TypeDesc[0]; 157 } 158 159 ConstantClassInfo[] classes = mExceptions.getExceptions(); 160 TypeDesc[] types = new TypeDesc[classes.length]; 161 for (int i=0; i<types.length; i++) { 162 types[i] = classes[i].getType(); 163 } 164 165 return types; 166 } 167 168 172 public CodeAttr getCodeAttr() { 173 return mCode; 174 } 175 176 public boolean isSynthetic() { 177 for (int i = mAttributes.size(); --i >= 0; ) { 178 Object obj = mAttributes.get(i); 179 if (obj instanceof SyntheticAttr) { 180 return true; 181 } 182 } 183 return false; 184 } 185 186 public boolean isDeprecated() { 187 for (int i = mAttributes.size(); --i >= 0; ) { 188 Object obj = mAttributes.get(i); 189 if (obj instanceof DeprecatedAttr) { 190 return true; 191 } 192 } 193 return false; 194 } 195 196 200 public Annotation[] getRuntimeInvisibleAnnotations() { 201 for (int i = mAttributes.size(); --i >= 0; ) { 202 Object obj = mAttributes.get(i); 203 if (obj instanceof RuntimeInvisibleAnnotationsAttr) { 204 return ((AnnotationsAttr) obj).getAnnotations(); 205 } 206 } 207 return new Annotation[0]; 208 } 209 210 214 public Annotation[] getRuntimeVisibleAnnotations() { 215 for (int i = mAttributes.size(); --i >= 0; ) { 216 Object obj = mAttributes.get(i); 217 if (obj instanceof RuntimeVisibleAnnotationsAttr) { 218 return ((AnnotationsAttr) obj).getAnnotations(); 219 } 220 } 221 return new Annotation[0]; 222 } 223 224 227 public Annotation addRuntimeInvisibleAnnotation(TypeDesc type) { 228 AnnotationsAttr attr = null; 229 for (int i = mAttributes.size(); --i >= 0; ) { 230 Object obj = mAttributes.get(i); 231 if (obj instanceof RuntimeInvisibleAnnotationsAttr) { 232 attr = (AnnotationsAttr) obj; 233 } 234 } 235 if (attr == null) { 236 attr = new RuntimeInvisibleAnnotationsAttr(mCp); 237 addAttribute(attr); 238 } 239 Annotation ann = new Annotation(mCp); 240 ann.setType(type); 241 attr.addAnnotation(ann); 242 return ann; 243 } 244 245 248 public Annotation addRuntimeVisibleAnnotation(TypeDesc type) { 249 AnnotationsAttr attr = null; 250 for (int i = mAttributes.size(); --i >= 0; ) { 251 Object obj = mAttributes.get(i); 252 if (obj instanceof RuntimeVisibleAnnotationsAttr) { 253 attr = (AnnotationsAttr) obj; 254 } 255 } 256 if (attr == null) { 257 attr = new RuntimeVisibleAnnotationsAttr(mCp); 258 addAttribute(attr); 259 } 260 Annotation ann = new Annotation(mCp); 261 ann.setType(type); 262 attr.addAnnotation(ann); 263 return ann; 264 } 265 266 270 public SignatureAttr getSignatureAttr() { 272 for (int i = mAttributes.size(); --i >= 0; ) { 273 Object obj = mAttributes.get(i); 274 if (obj instanceof SignatureAttr) { 275 return (SignatureAttr) obj; 276 } 277 } 278 return null; 279 } 280 281 284 public void addException(TypeDesc type) { 285 if (mExceptions == null) { 286 addAttribute(new ExceptionsAttr(mCp)); 287 } 288 ConstantClassInfo cci = mCp.addConstantClass(type); 290 mExceptions.addException(cci); 291 } 292 293 298 public ClassFile addInnerClass(String innerClassName) { 299 return addInnerClass(innerClassName, (String )null); 300 } 301 302 308 public ClassFile addInnerClass(String innerClassName, Class superClass) { 309 return addInnerClass(innerClassName, superClass.getName()); 310 } 311 312 318 public ClassFile addInnerClass(String innerClassName, String superClassName) { 319 ClassFile inner; 320 if (innerClassName == null) { 321 inner = mParent.addInnerClass(null, null, superClassName); 322 } else { 323 String fullInnerClassName = mParent.getClassName() + '$' + 324 (++mAnonymousInnerClassCount) + innerClassName; 325 inner = mParent.addInnerClass(fullInnerClassName, innerClassName, superClassName); 326 } 327 328 if (mParent.getMajorVersion() >= 49) { 329 inner.addAttribute(new EnclosingMethodAttr 330 (mCp, mCp.addConstantClass(mParent.getClassName()), 331 mCp.addConstantNameAndType(mNameConstant, mDescriptorConstant))); 332 } 333 334 return inner; 335 } 336 337 340 public void markSynthetic() { 341 addAttribute(new SyntheticAttr(mCp)); 342 } 343 344 347 public void markDeprecated() { 348 addAttribute(new DeprecatedAttr(mCp)); 349 } 350 351 public void addAttribute(Attribute attr) { 352 if (attr instanceof CodeAttr) { 353 if (mCode != null) { 354 mAttributes.remove(mCode); 355 } 356 mCode = (CodeAttr)attr; 357 } else if (attr instanceof ExceptionsAttr) { 358 if (mExceptions != null) { 359 mAttributes.remove(mExceptions); 360 } 361 mExceptions = (ExceptionsAttr)attr; 362 } 363 364 mAttributes.add(attr); 365 } 366 367 public Attribute[] getAttributes() { 368 Attribute[] attrs = new Attribute[mAttributes.size()]; 369 return (Attribute[])mAttributes.toArray(attrs); 370 } 371 372 375 public int getLength() { 376 int length = 8; 377 378 int size = mAttributes.size(); 379 for (int i=0; i<size; i++) { 380 length += ((Attribute)mAttributes.get(i)).getLength(); 381 } 382 383 return length; 384 } 385 386 public void writeTo(DataOutput dout) throws IOException { 387 dout.writeShort(mModifiers.getBitmask()); 388 dout.writeShort(mNameConstant.getIndex()); 389 dout.writeShort(mDescriptorConstant.getIndex()); 390 391 int size = mAttributes.size(); 392 dout.writeShort(size); 393 for (int i=0; i<size; i++) { 394 Attribute attr = (Attribute)mAttributes.get(i); 395 try { 396 attr.writeTo(dout); 397 } catch (IllegalStateException e) { 398 IllegalStateException e2 = 399 new IllegalStateException (e.getMessage() + ": " + toString()); 400 try { 401 e2.initCause(e); 402 } catch (NoSuchMethodError e3) { 403 } 404 throw e2; 405 } 406 } 407 } 408 409 public String toString() { 410 String str = mDesc.toMethodSignature(getName(), mModifiers.isVarArgs()); 411 String modStr = mModifiers.toString(); 412 if (modStr.length() > 0) { 413 str = modStr + ' ' + str; 414 } 415 return str; 416 } 417 418 static MethodInfo readFrom(ClassFile parent, 419 DataInput din, 420 AttributeFactory attrFactory) 421 throws IOException 422 { 423 ConstantPool cp = parent.getConstantPool(); 424 425 int modifier = din.readUnsignedShort(); 426 int index = din.readUnsignedShort(); 427 ConstantUTFInfo nameConstant = (ConstantUTFInfo)cp.getConstant(index); 428 index = din.readUnsignedShort(); 429 ConstantUTFInfo descConstant = (ConstantUTFInfo)cp.getConstant(index); 430 431 MethodInfo info = new MethodInfo(parent, modifier, 432 nameConstant, descConstant); 433 434 int size = din.readUnsignedShort(); 436 for (int i=0; i<size; i++) { 437 info.addAttribute(Attribute.readFrom(cp, din, attrFactory)); 438 } 439 440 return info; 441 } 442 } 443 | Popular Tags |