You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

BcelMethod.java 6.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.bcel;
  13. import java.lang.reflect.Modifier;
  14. import java.util.Iterator;
  15. import java.util.List;
  16. import org.aspectj.apache.bcel.classfile.ExceptionTable;
  17. import org.aspectj.apache.bcel.classfile.LocalVariable;
  18. import org.aspectj.apache.bcel.classfile.LocalVariableTable;
  19. import org.aspectj.apache.bcel.classfile.Method;
  20. import org.aspectj.apache.bcel.classfile.annotation.Annotation;
  21. import org.aspectj.bridge.ISourceLocation;
  22. import org.aspectj.bridge.SourceLocation;
  23. import org.aspectj.weaver.AjAttribute;
  24. import org.aspectj.weaver.BCException;
  25. import org.aspectj.weaver.ISourceContext;
  26. import org.aspectj.weaver.ResolvedMember;
  27. import org.aspectj.weaver.ResolvedTypeX;
  28. import org.aspectj.weaver.ShadowMunger;
  29. import org.aspectj.weaver.TypeX;
  30. import org.aspectj.weaver.World;
  31. final class BcelMethod extends ResolvedMember {
  32. private Method method;
  33. private boolean isAjSynthetic;
  34. private ShadowMunger associatedShadowMunger;
  35. private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
  36. private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
  37. private ResolvedTypeX[] resolvedAnnotations;
  38. private World world;
  39. BcelMethod(BcelObjectType declaringType, Method method) {
  40. super(
  41. method.getName().equals("<init>") ? CONSTRUCTOR :
  42. (method.getName().equals("<clinit>") ? STATIC_INITIALIZATION : METHOD),
  43. declaringType.getResolvedTypeX(),
  44. declaringType.isInterface()
  45. ? method.getAccessFlags() | Modifier.INTERFACE
  46. : method.getAccessFlags(),
  47. method.getName(),
  48. method.getSignature());
  49. this.method = method;
  50. this.sourceContext = declaringType.getResolvedTypeX().getSourceContext();
  51. this.world = declaringType.getResolvedTypeX().getWorld();
  52. unpackAjAttributes(world);
  53. unpackJavaAttributes();
  54. }
  55. // ----
  56. private void unpackJavaAttributes() {
  57. ExceptionTable exnTable = method.getExceptionTable();
  58. checkedExceptions = (exnTable == null)
  59. ? TypeX.NONE
  60. : TypeX.forNames(exnTable.getExceptionNames());
  61. LocalVariableTable varTable = method.getLocalVariableTable();
  62. int len = getArity();
  63. if (varTable == null) {
  64. this.parameterNames = Utility.makeArgNames(len);
  65. } else {
  66. TypeX[] paramTypes = getParameterTypes();
  67. String[] paramNames = new String[len];
  68. int index = isStatic() ? 0 : 1;
  69. for (int i = 0; i < len; i++) {
  70. LocalVariable lv = varTable.getLocalVariable(index);
  71. if (lv == null) {
  72. paramNames[i] = "arg" + i;
  73. } else {
  74. paramNames[i] = lv.getName();
  75. }
  76. index += paramTypes[i].getSize();
  77. }
  78. this.parameterNames = paramNames;
  79. }
  80. }
  81. private void unpackAjAttributes(World world) {
  82. List as = BcelAttributes.readAjAttributes(getDeclaringType().getClassName(),method.getAttributes(), getSourceContext(world),world.getMessageHandler());
  83. //System.out.println("unpack: " + this + ", " + as);
  84. for (Iterator iter = as.iterator(); iter.hasNext();) {
  85. AjAttribute a = (AjAttribute) iter.next();
  86. if (a instanceof AjAttribute.MethodDeclarationLineNumberAttribute) {
  87. declarationLineNumber = (AjAttribute.MethodDeclarationLineNumberAttribute)a;
  88. } else if (a instanceof AjAttribute.AdviceAttribute) {
  89. associatedShadowMunger = ((AjAttribute.AdviceAttribute)a).reify(this, world);
  90. return;
  91. } else if (a instanceof AjAttribute.AjSynthetic) {
  92. isAjSynthetic = true;
  93. } else if (a instanceof AjAttribute.EffectiveSignatureAttribute) {
  94. //System.out.println("found effective: " + this);
  95. effectiveSignature = (AjAttribute.EffectiveSignatureAttribute)a;
  96. } else {
  97. throw new BCException("weird method attribute " + a);
  98. }
  99. }
  100. associatedShadowMunger = null;
  101. }
  102. public boolean isAjSynthetic() {
  103. return isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX);
  104. }
  105. //FIXME needs an isSynthetic method
  106. public ShadowMunger getAssociatedShadowMunger() {
  107. return associatedShadowMunger;
  108. }
  109. public AjAttribute.EffectiveSignatureAttribute getEffectiveSignature() {
  110. return effectiveSignature;
  111. }
  112. public boolean hasDeclarationLineNumberInfo() {
  113. return declarationLineNumber != null;
  114. }
  115. public int getDeclarationLineNumber() {
  116. if (declarationLineNumber != null) {
  117. return declarationLineNumber.getLineNumber();
  118. } else {
  119. return -1;
  120. }
  121. }
  122. public ISourceLocation getSourceLocation() {
  123. ISourceLocation ret = super.getSourceLocation();
  124. if ((ret == null || ret.getLine()==0) && hasDeclarationLineNumberInfo()) {
  125. // lets see if we can do better
  126. ISourceContext isc = getSourceContext();
  127. if (isc !=null) ret = isc.makeSourceLocation(getDeclarationLineNumber());
  128. else ret = new SourceLocation(null,getDeclarationLineNumber());
  129. }
  130. return ret;
  131. }
  132. public Kind getKind() {
  133. if (associatedShadowMunger != null) {
  134. return ADVICE;
  135. } else {
  136. return super.getKind();
  137. }
  138. }
  139. public boolean hasAnnotation(TypeX ofType) {
  140. Annotation[] anns = method.getAnnotations();
  141. for (int i = 0; i < anns.length; i++) {
  142. Annotation annotation = anns[i];
  143. if (annotation.getTypeName().equals(ofType.getName())) return true;
  144. }
  145. return false;
  146. }
  147. public ResolvedTypeX[] getAnnotationTypes() {
  148. if (resolvedAnnotations == null) {
  149. Annotation[] annotations = method.getAnnotations();
  150. resolvedAnnotations = new ResolvedTypeX[annotations.length];
  151. for (int i = 0; i < annotations.length; i++) {
  152. Annotation annotation = annotations[i];
  153. ResolvedTypeX rtx = world.resolve(TypeX.forName(annotation.getTypeName()));
  154. resolvedAnnotations[i] = rtx;
  155. }
  156. }
  157. return resolvedAnnotations;
  158. }
  159. }