KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > reflect > impl > asm > AsmMethodInfo


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.aspectwerkz.reflect.impl.asm;
5
6 import com.tc.backport175.bytecode.AnnotationElement;
7 import com.tc.asm.Type;
8
9 import com.tc.aspectwerkz.exception.DefinitionException;
10 import com.tc.aspectwerkz.transform.inlining.AsmHelper;
11 import com.tc.aspectwerkz.reflect.MethodInfo;
12 import com.tc.aspectwerkz.reflect.ClassInfo;
13
14 import java.lang.reflect.Modifier JavaDoc;
15
16 /**
17  * ASM implementation of the MethodInfo interface.
18  *
19  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
20  */

21 public class AsmMethodInfo extends AsmMemberInfo implements MethodInfo {
22
23   /**
24    * The return type name.
25    */

26   private String JavaDoc m_returnTypeName = null;
27
28   /**
29    * A list with the parameter names as they appear in the source code.
30    * This information may not be available.
31    */

32   protected String JavaDoc[] m_parameterNames = null;
33
34   /**
35    * A list with the parameter type names.
36    */

37   private String JavaDoc[] m_parameterTypeNames = null;
38
39   /**
40    * A list with the exception type names.
41    */

42   private String JavaDoc[] m_exceptionTypeNames = null;
43
44   /**
45    * The return type.
46    */

47   private ClassInfo m_returnType = null;
48
49   /**
50    * A list with the parameter types.
51    */

52   private ClassInfo[] m_parameterTypes = null;
53
54   /**
55    * A list with the exception types.
56    */

57   private ClassInfo[] m_exceptionTypes = null;
58
59   /**
60    * Creates a new method info instance.
61    *
62    * @param method
63    * @param declaringType
64    * @param loader
65    */

66   AsmMethodInfo(final MethodStruct method, final String JavaDoc declaringType, final ClassLoader JavaDoc loader) {
67     super(method, declaringType, loader);
68
69     m_returnTypeName = Type.getReturnType(method.desc).getClassName();
70     Type[] argTypes = Type.getArgumentTypes(method.desc);
71     m_parameterTypeNames = new String JavaDoc[argTypes.length];
72     for (int i = 0; i < argTypes.length; i++) {
73       m_parameterTypeNames[i] = argTypes[i].getClassName();
74     }
75     // TODO how to do exceptions?
76
m_exceptionTypeNames = new String JavaDoc[]{};
77   }
78
79   /**
80    * Returns the method info for the method specified.
81    *
82    * @param methodName
83    * @param methodDesc
84    * @param bytecode
85    * @param loader
86    * @return the method info
87    */

88   public static MethodInfo getMethodInfo(final String JavaDoc methodName,
89                                          final String JavaDoc methodDesc,
90                                          final byte[] bytecode,
91                                          final ClassLoader JavaDoc loader) {
92     String JavaDoc className = AsmClassInfo.retrieveClassNameFromBytecode(bytecode);
93     AsmClassInfoRepository repository = AsmClassInfoRepository.getRepository(loader);
94     ClassInfo classInfo = repository.getClassInfo(className);
95     if (classInfo == null) {
96       classInfo = AsmClassInfo.getClassInfo(bytecode, loader);
97     }
98     return classInfo.getMethod(AsmHelper.calculateMethodHash(methodName, methodDesc));
99   }
100
101   /**
102    * Returns the signature for the element.
103    *
104    * @return the signature for the element
105    */

106   public String JavaDoc getSignature() {
107     return AsmHelper.getMethodDescriptor(this);
108   }
109   
110   public String JavaDoc getGenericsSignature() {
111     return m_member.signature;
112   }
113
114   /**
115    * Returns the return type.
116    *
117    * @return the return type
118    */

119   public ClassInfo getReturnType() {
120     if (m_returnType == null) {
121       m_returnType = AsmClassInfo.getClassInfo(m_returnTypeName, (ClassLoader JavaDoc) m_loaderRef.get());
122     }
123     return m_returnType;
124   }
125
126   /**
127    * Returns the parameter types.
128    *
129    * @return the parameter types
130    */

131   public synchronized ClassInfo[] getParameterTypes() {
132     if (m_parameterTypes == null) {
133       m_parameterTypes = new ClassInfo[m_parameterTypeNames.length];
134       for (int i = 0; i < m_parameterTypeNames.length; i++) {
135         m_parameterTypes[i] = AsmClassInfo.getClassInfo(
136                 m_parameterTypeNames[i],
137                 (ClassLoader JavaDoc) m_loaderRef.get()
138         );
139       }
140     }
141     return m_parameterTypes;
142   }
143
144   /**
145    * Returns the parameter names as they appear in the source code.
146    * This information is available only when class are compiled with javac -g (debug info), but is required
147    * for Aspect that are using args() and target()/this() bindings.
148    * <p/>
149    * It returns null if not available.
150    *
151    * @return
152    */

153   public String JavaDoc[] getParameterNames() {
154     return m_parameterNames;
155   }
156
157   /**
158    * Returns the exception types.
159    *
160    * @return the exception types
161    */

162   public synchronized ClassInfo[] getExceptionTypes() {
163     if (m_exceptionTypes == null) {
164       m_exceptionTypes = new ClassInfo[m_exceptionTypeNames.length];
165       for (int i = 0; i < m_exceptionTypeNames.length; i++) {
166         m_exceptionTypes[i] = AsmClassInfo.getClassInfo(
167                 m_exceptionTypeNames[i],
168                 (ClassLoader JavaDoc) m_loaderRef.get()
169         );
170       }
171     }
172     return m_exceptionTypes;
173   }
174
175   /**
176    * Returns the annotations.
177    *
178    * @return the annotations
179    */

180   public AnnotationElement.Annotation[] getAnnotations() {
181     return getDeclaringType().getAnnotationReader().getMethodAnnotationElements(m_member.name, m_member.desc);
182   }
183
184   public boolean equals(Object JavaDoc o) {
185     if (this == o) {
186       return true;
187     }
188     if (!(o instanceof MethodInfo)) {
189       return false;
190     }
191     MethodInfo methodInfo = (MethodInfo) o;
192     if (!m_declaringTypeName.equals(methodInfo.getDeclaringType().getName())) {
193       return false;
194     }
195     if (!m_member.name.equals(methodInfo.getName())) {
196       return false;
197     }
198     ClassInfo[] parameterTypes = methodInfo.getParameterTypes();
199     if (m_parameterTypeNames.length != parameterTypes.length) {//check on names length for lazyness optim
200
return false;
201     }
202     for (int i = 0; i < m_parameterTypeNames.length; i++) {
203       if (!m_parameterTypeNames[i].equals(parameterTypes[i].getName())) {
204         return false;
205       }
206     }
207     return true;
208   }
209
210   public int hashCode() {
211     int result = 29;
212     result = (29 * result) + m_declaringTypeName.hashCode();
213     result = (29 * result) + m_member.name.hashCode();
214     for (int i = 0; i < m_parameterTypeNames.length; i++) {
215       result = (29 * result) + m_parameterTypeNames[i].hashCode();
216     }
217     return result;
218   }
219
220   public String JavaDoc toString() {
221     StringBuffer JavaDoc sb = new StringBuffer JavaDoc(m_declaringTypeName);
222     sb.append('.').append(m_member.name);
223     sb.append(m_member.desc);
224     return sb.toString();
225   }
226
227   /**
228    * Update the parameter name given the parameter information
229    * the index is the one from the register ie a long or double will needs 2 register
230    *
231    * @param registerIndex
232    * @param parameterName
233    */

234   public void pushParameterNameFromRegister(int registerIndex, String JavaDoc parameterName) {
235     int registerStart = 1;
236     if (Modifier.isStatic(m_member.modifiers)) {
237       registerStart = 0;
238     }
239     // assume we have a stack starting at the first parameter
240
int registerIndexFrom0 = registerIndex - registerStart;
241     Type[] parameters = Type.getArgumentTypes(m_member.desc);
242     int typeIndex = AsmHelper.getTypeIndexOf(parameters, registerIndexFrom0);
243     if (typeIndex >= 0 && typeIndex < m_parameterNames.length) {
244       m_parameterNames[typeIndex] = parameterName;
245     } else {
246       throw new DefinitionException(
247               "Could not register parameter named " + parameterName
248                       + " from register " + registerIndex + " for " + m_member.name + "." + m_member.desc
249       );
250     }
251   }
252 }
Popular Tags