123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714 |
- /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
- package org.aspectj.weaver.bcel;
-
- import java.lang.reflect.Modifier;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.StringTokenizer;
-
- import org.aspectj.apache.bcel.classfile.AnnotationDefault;
- import org.aspectj.apache.bcel.classfile.Attribute;
- import org.aspectj.apache.bcel.classfile.ExceptionTable;
- import org.aspectj.apache.bcel.classfile.JavaClass;
- import org.aspectj.apache.bcel.classfile.LineNumber;
- import org.aspectj.apache.bcel.classfile.LineNumberTable;
- import org.aspectj.apache.bcel.classfile.LocalVariable;
- import org.aspectj.apache.bcel.classfile.LocalVariableTable;
- import org.aspectj.apache.bcel.classfile.Method;
- import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
- import org.aspectj.apache.bcel.classfile.annotation.NameValuePair;
- import org.aspectj.bridge.ISourceLocation;
- import org.aspectj.bridge.SourceLocation;
- import org.aspectj.util.GenericSignature;
- import org.aspectj.util.GenericSignature.TypeVariableSignature;
- import org.aspectj.util.GenericSignatureParser;
- import org.aspectj.weaver.AjAttribute;
- import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
- import org.aspectj.weaver.AnnotationAJ;
- import org.aspectj.weaver.BCException;
- import org.aspectj.weaver.ISourceContext;
- import org.aspectj.weaver.MemberKind;
- import org.aspectj.weaver.ResolvedMemberImpl;
- import org.aspectj.weaver.ResolvedPointcutDefinition;
- import org.aspectj.weaver.ResolvedType;
- import org.aspectj.weaver.ShadowMunger;
- import org.aspectj.weaver.TypeVariable;
- import org.aspectj.weaver.UnresolvedType;
- import org.aspectj.weaver.World;
- import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
-
- //public final
- class BcelMethod extends ResolvedMemberImpl {
-
- private final static String ASPECTJ_ANNOTATION_PACKAGE = "org.aspectj.lang.annotation";
- private final static char PACKAGE_INITIAL_CHAR = ASPECTJ_ANNOTATION_PACKAGE.charAt(0);
-
- private Method method;
-
- // these fields are not set for many BcelMethods...
- private ShadowMunger associatedShadowMunger;
- private ResolvedPointcutDefinition preResolvedPointcut; // used when ajc has pre-resolved the pointcut of some @Advice
- private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
-
- private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
- private final BcelObjectType bcelObjectType;
-
- private int bitflags;
- private static final int KNOW_IF_SYNTHETIC = 0x0001;
- private static final int PARAMETER_NAMES_INITIALIZED = 0x0002;
- private static final int CAN_BE_PARAMETERIZED = 0x0004;
- private static final int UNPACKED_GENERIC_SIGNATURE = 0x0008;
- private static final int IS_AJ_SYNTHETIC = 0x0040;
- private static final int IS_SYNTHETIC = 0x0080;
- private static final int IS_SYNTHETIC_INVERSE = 0x7f7f; // all bits but
- // IS_SYNTHETIC (and
- // topmost bit)
- private static final int HAS_ANNOTATIONS = 0x0400;
- private static final int HAVE_DETERMINED_ANNOTATIONS = 0x0800;
-
- // genericized version of return and parameter types
- private UnresolvedType genericReturnType = null;
- private UnresolvedType[] genericParameterTypes = null;
-
- BcelMethod(BcelObjectType declaringType, Method method) {
- super(method.getName().equals("<init>") ? CONSTRUCTOR : (method.getName().equals("<clinit>") ? STATIC_INITIALIZATION
- : METHOD), declaringType.getResolvedTypeX(), method.getModifiers(), method.getName(), method.getSignature());
- this.method = method;
- sourceContext = declaringType.getResolvedTypeX().getSourceContext();
- bcelObjectType = declaringType;
- unpackJavaAttributes();
- unpackAjAttributes(bcelObjectType.getWorld());
- }
-
- /**
- * This constructor expects to be passed the attributes, rather than deserializing them.
- */
- BcelMethod(BcelObjectType declaringType, Method method, List<AjAttribute> attributes) {
- super(method.getName().equals("<init>") ? CONSTRUCTOR : (method.getName().equals("<clinit>") ? STATIC_INITIALIZATION
- : METHOD), declaringType.getResolvedTypeX(), method.getModifiers(), method.getName(), method.getSignature());
- this.method = method;
- sourceContext = declaringType.getResolvedTypeX().getSourceContext();
- bcelObjectType = declaringType;
- unpackJavaAttributes();
- processAttributes(bcelObjectType.getWorld(), attributes);
- }
-
- // ----
-
- private void unpackJavaAttributes() {
- ExceptionTable exnTable = method.getExceptionTable();
- checkedExceptions = (exnTable == null) ? UnresolvedType.NONE : UnresolvedType.forNames(exnTable.getExceptionNames());
- }
-
- @Override
- public String[] getParameterNames() {
- determineParameterNames();
- return super.getParameterNames();
- }
-
- public int getLineNumberOfFirstInstruction() {
- LineNumberTable lnt = method.getLineNumberTable();
- if (lnt == null) {
- return -1;
- }
- LineNumber[] lns = lnt.getLineNumberTable();
- if (lns == null || lns.length == 0) {
- return -1;
- }
- return lns[0].getLineNumber();
- }
-
- public void determineParameterNames() {
- if ((bitflags & PARAMETER_NAMES_INITIALIZED) != 0) {
- return;
- }
- bitflags |= PARAMETER_NAMES_INITIALIZED;
- LocalVariableTable varTable = method.getLocalVariableTable();
- int len = getArity();
- if (varTable == null) {
- // do we have an annotation with the argNames value specified...
- AnnotationAJ[] annos = getAnnotations();
- if (annos != null && annos.length != 0) {
- AnnotationAJ[] axs = getAnnotations();
- for (int i = 0; i < axs.length; i++) {
- AnnotationAJ annotationX = axs[i];
- String typename = annotationX.getTypeName();
- if (typename.charAt(0) == PACKAGE_INITIAL_CHAR) {
- if (typename.equals("org.aspectj.lang.annotation.Pointcut")
- || typename.equals("org.aspectj.lang.annotation.Before")
- || typename.equals("org.aspectj.lang.annotation.Around")
- || typename.startsWith("org.aspectj.lang.annotation.After")) {
- AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation();
- if (a != null) {
- List<NameValuePair> values = a.getValues();
- for (NameValuePair nvPair : values) {
- if (nvPair.getNameString().equals("argNames")) {
- String argNames = nvPair.getValue().stringifyValue();
- StringTokenizer argNameTokenizer = new StringTokenizer(argNames, " ,");
- List<String> argsList = new ArrayList<String>();
- while (argNameTokenizer.hasMoreTokens()) {
- argsList.add(argNameTokenizer.nextToken());
- }
- int requiredCount = getParameterTypes().length;
- while (argsList.size() < requiredCount) {
- argsList.add("arg" + argsList.size());
- }
- setParameterNames(argsList.toArray(new String[] {}));
- return;
- }
- }
- }
- }
- }
- }
- }
- setParameterNames(Utility.makeArgNames(len));
- } else {
- UnresolvedType[] paramTypes = getParameterTypes();
- String[] paramNames = new String[len];
- int index = Modifier.isStatic(modifiers) ? 0 : 1;
- for (int i = 0; i < len; i++) {
- LocalVariable lv = varTable.getLocalVariable(index);
- if (lv == null) {
- paramNames[i] = "arg" + i;
- } else {
- paramNames[i] = lv.getName();
- }
- index += paramTypes[i].getSize();
- }
- setParameterNames(paramNames);
- }
- }
-
- private void unpackAjAttributes(World world) {
- associatedShadowMunger = null;
- ResolvedType resolvedDeclaringType = getDeclaringType().resolve(world);
- WeaverVersionInfo wvinfo = bcelObjectType.getWeaverVersionAttribute();
- List<AjAttribute> as = Utility.readAjAttributes(resolvedDeclaringType.getClassName(), method.getAttributes(),
- resolvedDeclaringType.getSourceContext(), world, wvinfo, new BcelConstantPoolReader(method.getConstantPool()));
- processAttributes(world, as);
- as = AtAjAttributes.readAj5MethodAttributes(method, this, resolvedDeclaringType, preResolvedPointcut,
- resolvedDeclaringType.getSourceContext(), world.getMessageHandler());
- processAttributes(world, as);
- }
-
- private void processAttributes(World world, List<AjAttribute> as) {
- for (AjAttribute attr : as) {
- if (attr instanceof AjAttribute.MethodDeclarationLineNumberAttribute) {
- declarationLineNumber = (AjAttribute.MethodDeclarationLineNumberAttribute) attr;
- } else if (attr instanceof AjAttribute.AdviceAttribute) {
- associatedShadowMunger = ((AjAttribute.AdviceAttribute) attr).reify(this, world, (ResolvedType) getDeclaringType());
- } else if (attr instanceof AjAttribute.AjSynthetic) {
- bitflags |= IS_AJ_SYNTHETIC;
- } else if (attr instanceof AjAttribute.EffectiveSignatureAttribute) {
- effectiveSignature = (AjAttribute.EffectiveSignatureAttribute) attr;
- } else if (attr instanceof AjAttribute.PointcutDeclarationAttribute) {
- // this is an @AspectJ annotated advice method, with pointcut pre-resolved by ajc
- preResolvedPointcut = ((AjAttribute.PointcutDeclarationAttribute) attr).reify();
- } else {
- throw new BCException("weird method attribute " + attr);
- }
- }
- }
-
- //
- // // for testing - if we have this attribute, return it - will return null
- // if
- // // it doesnt know anything
- // public AjAttribute[] getAttributes(String name) {
- // List results = new ArrayList();
- // List l = Utility.readAjAttributes(getDeclaringType().getClassName(),
- // method.getAttributes(),
- // getSourceContext(bcelObjectType.getWorld()), bcelObjectType.getWorld(),
- // bcelObjectType.getWeaverVersionAttribute());
- // for (Iterator iter = l.iterator(); iter.hasNext();) {
- // AjAttribute element = (AjAttribute) iter.next();
- // if (element.getNameString().equals(name))
- // results.add(element);
- // }
- // if (results.size() > 0) {
- // return (AjAttribute[]) results.toArray(new AjAttribute[] {});
- // }
- // return null;
- // }
-
- @Override
- public String getAnnotationDefaultValue() {
- Attribute[] attrs = method.getAttributes();
- for (int i = 0; i < attrs.length; i++) {
- Attribute attribute = attrs[i];
- if (attribute.getName().equals("AnnotationDefault")) {
- AnnotationDefault def = (AnnotationDefault) attribute;
- return def.getElementValue().stringifyValue();
- }
- }
- return null;
- }
-
- // for testing - use with the method above
- public String[] getAttributeNames(boolean onlyIncludeAjOnes) {
- Attribute[] as = method.getAttributes();
- List<String> names = new ArrayList<String>();
- // String[] strs = new String[as.length];
- for (int j = 0; j < as.length; j++) {
- if (!onlyIncludeAjOnes || as[j].getName().startsWith(AjAttribute.AttributePrefix)) {
- names.add(as[j].getName());
- }
- }
- return names.toArray(new String[] {});
- }
-
- @Override
- public boolean isAjSynthetic() {
- return (bitflags & IS_AJ_SYNTHETIC) != 0;
- }
-
- @Override
- public ShadowMunger getAssociatedShadowMunger() {
- return associatedShadowMunger;
- }
-
- @Override
- public AjAttribute.EffectiveSignatureAttribute getEffectiveSignature() {
- return effectiveSignature;
- }
-
- public boolean hasDeclarationLineNumberInfo() {
- return declarationLineNumber != null;
- }
-
- public int getDeclarationLineNumber() {
- if (declarationLineNumber != null) {
- return declarationLineNumber.getLineNumber();
- } else {
- return -1;
- }
- }
-
- public int getDeclarationOffset() {
- if (declarationLineNumber != null) {
- return declarationLineNumber.getOffset();
- } else {
- return -1;
- }
- }
-
- @Override
- public ISourceLocation getSourceLocation() {
- ISourceLocation ret = super.getSourceLocation();
- if ((ret == null || ret.getLine() == 0) && hasDeclarationLineNumberInfo()) {
- // lets see if we can do better
- ISourceContext isc = getSourceContext();
- if (isc != null) {
- ret = isc.makeSourceLocation(getDeclarationLineNumber(), getDeclarationOffset());
- } else {
- ret = new SourceLocation(null, getDeclarationLineNumber());
- }
- }
- return ret;
- }
-
- @Override
- public MemberKind getKind() {
- if (associatedShadowMunger != null) {
- return ADVICE;
- } else {
- return super.getKind();
- }
- }
-
- @Override
- public boolean hasAnnotation(UnresolvedType ofType) {
- ensureAnnotationsRetrieved();
- for (ResolvedType aType : annotationTypes) {
- if (aType.equals(ofType)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public AnnotationAJ[] getAnnotations() {
- ensureAnnotationsRetrieved();
- if ((bitflags & HAS_ANNOTATIONS) != 0) {
- return annotations;
- } else {
- return AnnotationAJ.EMPTY_ARRAY;
- }
- }
-
- @Override
- public ResolvedType[] getAnnotationTypes() {
- ensureAnnotationsRetrieved();
- return annotationTypes;
- }
-
- @Override
- public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) {
- ensureAnnotationsRetrieved();
- if ((bitflags & HAS_ANNOTATIONS) == 0) {
- return null;
- }
- for (int i = 0; i < annotations.length; i++) {
- if (annotations[i].getTypeName().equals(ofType.getName())) {
- return annotations[i];
- }
- }
- return null;
- }
-
- @Override
- public void addAnnotation(AnnotationAJ annotation) {
- ensureAnnotationsRetrieved();
- if ((bitflags & HAS_ANNOTATIONS) == 0) {
- annotations = new AnnotationAJ[1];
- annotations[0] = annotation;
- annotationTypes = new ResolvedType[1];
- annotationTypes[0] = annotation.getType();
- } else {
- // Add it to the set of annotations
- int len = annotations.length;
- AnnotationAJ[] ret = new AnnotationAJ[len + 1];
- System.arraycopy(annotations, 0, ret, 0, len);
- ret[len] = annotation;
- annotations = ret;
- ResolvedType[] newAnnotationTypes = new ResolvedType[len + 1];
- System.arraycopy(annotationTypes, 0, newAnnotationTypes, 0, len);
- newAnnotationTypes[len] = annotation.getType();
- annotationTypes = newAnnotationTypes;
- }
- bitflags |= HAS_ANNOTATIONS;
- }
-
- public void removeAnnotation(ResolvedType annotationType) {
- ensureAnnotationsRetrieved();
- if ((bitflags & HAS_ANNOTATIONS) == 0) {
- // nothing to do, why did we get called?
- } else {
- int len = annotations.length;
- if (len == 1) {
- bitflags &= ~HAS_ANNOTATIONS;
- annotations = null;
- annotationTypes = null;
- return;
- }
- AnnotationAJ[] ret = new AnnotationAJ[len - 1];
- int p = 0;
- for (AnnotationAJ annotation : annotations) {
- if (!annotation.getType().equals(annotationType)) {
- ret[p++] = annotation;
- }
- }
- annotations = ret;
-
- ResolvedType[] newAnnotationTypes = new ResolvedType[len - 1];
- p = 0;
- for (AnnotationAJ annotation : annotations) {
- if (!annotation.getType().equals(annotationType)) {
- newAnnotationTypes[p++] = annotationType;
- }
- }
- annotationTypes = newAnnotationTypes;
- }
- bitflags |= HAS_ANNOTATIONS;
- }
-
- public static final AnnotationAJ[] NO_PARAMETER_ANNOTATIONS = new AnnotationAJ[] {};
-
- public void addParameterAnnotation(int param, AnnotationAJ anno) {
- ensureParameterAnnotationsRetrieved();
- if (parameterAnnotations == NO_PARAMETER_ANNOTATIONXS) {
- // First time we've added any, so lets set up the array
- parameterAnnotations = new AnnotationAJ[getArity()][];
- for (int i = 0; i < getArity(); i++) {
- parameterAnnotations[i] = NO_PARAMETER_ANNOTATIONS;
- }
- }
- int existingCount = parameterAnnotations[param].length;
- if (existingCount == 0) {
- AnnotationAJ[] annoArray = new AnnotationAJ[1];
- annoArray[0] = anno;
- parameterAnnotations[param] = annoArray;
- } else {
- AnnotationAJ[] newAnnoArray = new AnnotationAJ[existingCount + 1];
- System.arraycopy(parameterAnnotations[param], 0, newAnnoArray, 0, existingCount);
- newAnnoArray[existingCount] = anno;
- parameterAnnotations[param] = newAnnoArray;
- }
- }
-
- private void ensureAnnotationsRetrieved() {
- if (method == null) {
- return; // must be ok, we have evicted it
- }
- if ((bitflags & HAVE_DETERMINED_ANNOTATIONS) != 0) {
- return;
- }
- bitflags |= HAVE_DETERMINED_ANNOTATIONS;
- AnnotationGen annos[] = method.getAnnotations();
- if (annos.length == 0) {
- annotationTypes = ResolvedType.NONE;
- annotations = AnnotationAJ.EMPTY_ARRAY;
- } else {
- int annoCount = annos.length;
- annotationTypes = new ResolvedType[annoCount];
- annotations = new AnnotationAJ[annoCount];
- for (int i = 0; i < annoCount; i++) {
- AnnotationGen annotation = annos[i];
- annotations[i] = new BcelAnnotation(annotation, bcelObjectType.getWorld());
- annotationTypes[i] = annotations[i].getType();
- }
- bitflags |= HAS_ANNOTATIONS;
- }
- }
-
- private void ensureParameterAnnotationsRetrieved() {
- if (method == null) {
- return; // must be ok, we have evicted it
- }
- AnnotationGen[][] pAnns = method.getParameterAnnotations();
- if (parameterAnnotationTypes == null || pAnns.length != parameterAnnotationTypes.length) {
- if (pAnns == Method.NO_PARAMETER_ANNOTATIONS) {
- parameterAnnotationTypes = BcelMethod.NO_PARAMETER_ANNOTATION_TYPES;
- parameterAnnotations = BcelMethod.NO_PARAMETER_ANNOTATIONXS;
- } else {
- AnnotationGen annos[][] = method.getParameterAnnotations();
- parameterAnnotations = new AnnotationAJ[annos.length][];
- parameterAnnotationTypes = new ResolvedType[annos.length][];
- for (int i = 0; i < annos.length; i++) {
- AnnotationGen[] annosOnThisParam = annos[i];
- if (annos[i].length == 0) {
- parameterAnnotations[i] = AnnotationAJ.EMPTY_ARRAY;
- parameterAnnotationTypes[i] = ResolvedType.NONE;
- } else {
- parameterAnnotations[i] = new AnnotationAJ[annosOnThisParam.length];
- parameterAnnotationTypes[i] = new ResolvedType[annosOnThisParam.length];
- for (int j = 0; j < annosOnThisParam.length; j++) {
- parameterAnnotations[i][j] = new BcelAnnotation(annosOnThisParam[j], bcelObjectType.getWorld());
- parameterAnnotationTypes[i][j] = bcelObjectType.getWorld().resolve(
- UnresolvedType.forSignature(annosOnThisParam[j].getTypeSignature()));
- }
- }
- }
- }
- }
- }
-
- @Override
- public AnnotationAJ[][] getParameterAnnotations() {
- ensureParameterAnnotationsRetrieved();
- return parameterAnnotations;
- }
-
- @Override
- public ResolvedType[][] getParameterAnnotationTypes() {
- ensureParameterAnnotationsRetrieved();
- return parameterAnnotationTypes;
- }
-
- /**
- * A method can be parameterized if it has one or more generic parameters. A generic parameter (type variable parameter) is
- * identified by the prefix "T"
- */
- @Override
- public boolean canBeParameterized() {
- unpackGenericSignature();
- return (bitflags & CAN_BE_PARAMETERIZED) != 0;
- }
-
- @Override
- public UnresolvedType[] getGenericParameterTypes() {
- unpackGenericSignature();
- return genericParameterTypes;
- }
-
- /**
- * Return the parameterized/generic return type or the normal return type if the method is not generic.
- */
- @Override
- public UnresolvedType getGenericReturnType() {
- unpackGenericSignature();
- return genericReturnType;
- }
-
- /** For testing only */
- public Method getMethod() {
- return method;
- }
-
- private void unpackGenericSignature() {
- if ((bitflags & UNPACKED_GENERIC_SIGNATURE) != 0) {
- return;
- }
- bitflags |= UNPACKED_GENERIC_SIGNATURE;
- if (!bcelObjectType.getWorld().isInJava5Mode()) {
- genericReturnType = getReturnType();
- genericParameterTypes = getParameterTypes();
- return;
- }
- String gSig = method.getGenericSignature();
- if (gSig != null) {
- GenericSignature.MethodTypeSignature mSig = new GenericSignatureParser().parseAsMethodSignature(gSig);// method
- // .
- // getGenericSignature
- // ());
- if (mSig.formalTypeParameters.length > 0) {
- // generic method declaration
- bitflags |= CAN_BE_PARAMETERIZED;
- }
-
- typeVariables = new TypeVariable[mSig.formalTypeParameters.length];
- for (int i = 0; i < typeVariables.length; i++) {
- GenericSignature.FormalTypeParameter methodFtp = mSig.formalTypeParameters[i];
- try {
- typeVariables[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable(methodFtp,
- mSig.formalTypeParameters, bcelObjectType.getWorld());
- } catch (GenericSignatureFormatException e) {
- // this is a development bug, so fail fast with good info
- throw new IllegalStateException("While getting the type variables for method " + this.toString()
- + " with generic signature " + mSig + " the following error condition was detected: " + e.getMessage());
- }
- }
-
- GenericSignature.FormalTypeParameter[] parentFormals = bcelObjectType.getAllFormals();
- GenericSignature.FormalTypeParameter[] formals = new GenericSignature.FormalTypeParameter[parentFormals.length
- + mSig.formalTypeParameters.length];
- // put method formal in front of type formals for overriding in
- // lookup
- System.arraycopy(mSig.formalTypeParameters, 0, formals, 0, mSig.formalTypeParameters.length);
- System.arraycopy(parentFormals, 0, formals, mSig.formalTypeParameters.length, parentFormals.length);
- GenericSignature.TypeSignature returnTypeSignature = mSig.returnType;
- try {
- genericReturnType = BcelGenericSignatureToTypeXConverter.typeSignature2TypeX(returnTypeSignature, formals,
- bcelObjectType.getWorld());
- } catch (GenericSignatureFormatException e) {
- // development bug, fail fast with good info
- throw new IllegalStateException("While determing the generic return type of " + this.toString()
- + " with generic signature " + gSig + " the following error was detected: " + e.getMessage());
- }
- GenericSignature.TypeSignature[] paramTypeSigs = mSig.parameters;
- if (paramTypeSigs.length == 0) {
- genericParameterTypes = UnresolvedType.NONE;
- } else {
- genericParameterTypes = new UnresolvedType[paramTypeSigs.length];
- }
- for (int i = 0; i < paramTypeSigs.length; i++) {
- try {
- genericParameterTypes[i] = BcelGenericSignatureToTypeXConverter.typeSignature2TypeX(paramTypeSigs[i], formals,
- bcelObjectType.getWorld());
- } catch (GenericSignatureFormatException e) {
- // development bug, fail fast with good info
- throw new IllegalStateException("While determining the generic parameter types of " + this.toString()
- + " with generic signature " + gSig + " the following error was detected: " + e.getMessage());
- }
- if (paramTypeSigs[i] instanceof TypeVariableSignature) {
- bitflags |= CAN_BE_PARAMETERIZED;
- }
- }
- } else {
- genericReturnType = getReturnType();
- genericParameterTypes = getParameterTypes();
- }
- }
-
- @Override
- public void evictWeavingState() {
- if (method != null) {
- unpackGenericSignature();
- unpackJavaAttributes();
- ensureAnnotationsRetrieved();
- ensureParameterAnnotationsRetrieved();
- determineParameterNames();
- // this.sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
- method = null;
- }
- }
-
- @Override
- public boolean isSynthetic() {
- if ((bitflags & KNOW_IF_SYNTHETIC) == 0) {
- workOutIfSynthetic();
- }
- return (bitflags & IS_SYNTHETIC) != 0;// isSynthetic;
- }
-
- // Pre Java5 synthetic is an attribute 'Synthetic', post Java5 it is a
- // modifier (4096 or 0x1000)
- private void workOutIfSynthetic() {
- if ((bitflags & KNOW_IF_SYNTHETIC) != 0) {
- return;
- }
- bitflags |= KNOW_IF_SYNTHETIC;
- JavaClass jc = bcelObjectType.getJavaClass();
- bitflags &= IS_SYNTHETIC_INVERSE; // unset the bit
- if (jc == null) {
- return; // what the hell has gone wrong?
- }
- if (jc.getMajor() < 49/* Java5 */) {
- // synthetic is an attribute
- String[] synthetics = getAttributeNames(false);
- if (synthetics != null) {
- for (int i = 0; i < synthetics.length; i++) {
- if (synthetics[i].equals("Synthetic")) {
- bitflags |= IS_SYNTHETIC;
- break;
- }
- }
- }
- } else {
- // synthetic is a modifier (4096)
- if ((modifiers & 4096) != 0) {
- bitflags |= IS_SYNTHETIC;
- }
- }
- }
-
- /**
- * Returns whether or not the given object is equivalent to the current one. Returns true if
- * getMethod().getCode().getCodeString() are equal. Allows for different line number tables.
- */
- // bug 154054: is similar to equals(Object) however
- // doesn't require implementing equals in Method and Code
- // which proved expensive. Currently used within
- // CrosscuttingMembers.replaceWith() to decide if we need
- // to do a full build
- @Override
- public boolean isEquivalentTo(Object other) {
- if (!(other instanceof BcelMethod)) {
- return false;
- }
- BcelMethod o = (BcelMethod) other;
- return getMethod().getCode().getCodeString().equals(o.getMethod().getCode().getCodeString());
- }
-
- /**
- * Return true if the method represents the default constructor. Hard to determine this from bytecode, but the existence of the
- * MethodDeclarationLineNumber attribute should tell us.
- *
- * @return true if this BcelMethod represents the default constructor
- */
- @Override
- public boolean isDefaultConstructor() {
- boolean mightBe = !hasDeclarationLineNumberInfo() && name.equals("<init>") && parameterTypes.length == 0;
- if (mightBe) {
- // TODO would be nice to do a check to see if the file was compiled with javac or ajc?
- // maybe by checking the constant pool for aspectj strings?
- return true;
- } else {
- return false;
- }
- }
-
- }
|