001 package edu.rice.cs.cunit.classFile.attributes; 002 003 import edu.rice.cs.cunit.classFile.attributes.visitors.IAttributeVisitor; 004 import edu.rice.cs.cunit.classFile.code.instructions.LineNumberTable; 005 import edu.rice.cs.cunit.classFile.constantPool.AUTFPoolInfo; 006 import edu.rice.cs.cunit.classFile.constantPool.ConstantPool; 007 import edu.rice.cs.cunit.classFile.constantPool.ClassPoolInfo; 008 import edu.rice.cs.cunit.classFile.constantPool.NameAndTypePoolInfo; 009 import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckClassVisitor; 010 import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckNameAndTypeVisitor; 011 import edu.rice.cs.cunit.util.Types; 012 013 /** 014 * Represents the EnclosingMethod attribute in a class file. 015 * 016 * @author Mathias Ricken 017 */ 018 public class EnclosingMethodAttributeInfo extends AAttributeInfo { 019 /** 020 * Constructor. 021 * 022 * @param name attribute name 023 * @param data attribute data 024 * @param cp constant pool 025 * 026 * @throws ClassFormatError 027 */ 028 public EnclosingMethodAttributeInfo(AUTFPoolInfo name, byte[] data, ConstantPool cp) throws ClassFormatError { 029 super(name, data, cp); 030 } 031 032 /** 033 * Return the enclosing class information. 034 * 035 * @return class information 036 * 037 * @throws ClassFormatError 038 */ 039 public ClassPoolInfo getEnclosingClass() throws ClassFormatError { 040 return _constantPool.get(Types.ushortFromBytes(_data, 0)).execute(CheckClassVisitor.singleton(), null); 041 } 042 043 /** 044 * Set the enclosing class information. 045 * 046 * @param newClass enclosing class 047 */ 048 public void setSourceFileName(ClassPoolInfo newClass) { 049 Types.bytesFromShort(_constantPool.indexOf(newClass), _data, 0); 050 } 051 052 /** 053 * Return the enclosing method information. 054 * 055 * @return method information 056 * 057 * @throws ClassFormatError 058 */ 059 public NameAndTypePoolInfo getEnclosingMethod() throws ClassFormatError { 060 return _constantPool.get(Types.ushortFromBytes(_data, 2)).execute(CheckNameAndTypeVisitor.singleton(), null); 061 } 062 063 /** 064 * Set the enclosing method information. 065 * 066 * @param newMethod enclosing method 067 */ 068 public void setEnclosinMethod(ClassPoolInfo newMethod) { 069 Types.bytesFromShort(_constantPool.indexOf(newMethod), _data, 2); 070 } 071 072 /** 073 * Execute a visitor on this attribute. 074 * 075 * @param visitor visitor 076 * @param param visitor-specific parameter 077 * 078 * @return visitor-specific return value 079 */ 080 public <R, D> R execute(IAttributeVisitor<R, D> visitor, D param) { 081 return visitor.enclosingMethodCase(this, param); 082 } 083 084 /** 085 * Adjust program counter values contained in this attribute, starting at startPC, by adding deltaPC to them. 086 * 087 * @param startPC program counter to start at 088 * @param deltaPC change in program counter values 089 */ 090 public void adjustPC(int startPC, int deltaPC) { 091 // nothing to do 092 } 093 094 /** 095 * Translate the program counter values contained in this attribute from an old line number table to a new one. 096 * 097 * @param index critical point (insertion or deletion point) 098 * @param deltaIndex delta value to add to all old line numbers greater than the critical point 099 * @param oldLnt old line number table 100 * @param newLnt new line number table 101 */ 102 public void translatePC(int index, int deltaIndex, LineNumberTable oldLnt, LineNumberTable newLnt) { 103 // nothing to do 104 } 105 106 /** 107 * Creates and returns a copy of this object. 108 */ 109 public Object clone() throws CloneNotSupportedException { 110 return super.clone(); 111 } 112 113 /** 114 * Return a human-readable version of this attribute. 115 * 116 * @return string 117 */ 118 public String toString() { 119 try { 120 return "EnclosingMethod <Class = "+getEnclosingClass().toString()+", Method = "+getEnclosingMethod().toStringVerbose()+" >"; 121 } 122 catch(ClassFormatError cfe) { 123 if ((cfe.getMessage().startsWith("Info is of type ") && cfe.getMessage().endsWith(", needs to be NameAndType"))) { 124 return "EnclosingMethod: <unknown; encountered EmptyPoolInfo>"; 125 } 126 throw cfe; 127 } 128 } 129 130 /** 131 * Returns the name of the attribute as it appears in the class file. 132 * 133 * @return name of the attribute. 134 */ 135 public static String getAttributeName() { 136 return "EnclosingMethod"; 137 } 138 }