From c3587474e9f348ff64d3de42dd15319943dbcd6f Mon Sep 17 00:00:00 2001 From: aclement Date: Fri, 5 Sep 2008 17:05:43 +0000 Subject: [PATCH] 246125: comment 3: reworked AnnotationX - got rid of the thing --- .../aspectj/weaver/AbstractAnnotationAJ.java | 158 ++ .../org/aspectj/weaver/AnnotatedElement.java | 6 +- .../src/org/aspectj/weaver/AnnotationAJ.java | 180 +- .../weaver/AnnotationOnTypeMunger.java | 46 +- .../src/org/aspectj/weaver/AnnotationX.java | 224 -- .../aspectj/weaver/BoundedReferenceType.java | 182 +- .../aspectj/weaver/JoinPointSignature.java | 37 +- weaver/src/org/aspectj/weaver/Member.java | 54 +- weaver/src/org/aspectj/weaver/MemberImpl.java | 160 +- .../src/org/aspectj/weaver/ReferenceType.java | 224 +- .../aspectj/weaver/ReferenceTypeDelegate.java | 85 +- .../org/aspectj/weaver/ResolvedMember.java | 42 +- .../aspectj/weaver/ResolvedMemberImpl.java | 459 +-- .../src/org/aspectj/weaver/ResolvedType.java | 936 +++++-- .../aspectj/weaver/StandardAnnotation.java | 139 + .../weaver/bcel/AnnotationAccessFieldVar.java | 15 +- .../aspectj/weaver/bcel/BcelAnnotation.java | 107 + .../aspectj/weaver/bcel/BcelClassWeaver.java | 469 +++- .../org/aspectj/weaver/bcel/BcelField.java | 22 +- .../org/aspectj/weaver/bcel/BcelMethod.java | 65 +- .../aspectj/weaver/bcel/BcelObjectType.java | 102 +- .../aspectj/weaver/bcel/BcelTypeMunger.java | 2451 +++++++++-------- .../org/aspectj/weaver/bcel/BcelWeaver.java | 814 ++++-- .../org/aspectj/weaver/bcel/BcelWorld.java | 203 +- .../aspectj/weaver/bcel/LazyMethodGen.java | 163 +- .../src/org/aspectj/weaver/bcel/Utility.java | 57 +- .../weaver/patterns/DeclareAnnotation.java | 346 +-- .../patterns/ExactAnnotationTypePattern.java | 318 ++- .../weaver/reflect/AnnotationFinder.java | 25 +- .../ReflectionBasedReferenceTypeDelegate.java | 262 +- .../ReflectionBasedResolvedMemberImpl.java | 99 +- .../patterns/AnnotationPatternTestCase.java | 436 +-- 32 files changed, 5315 insertions(+), 3571 deletions(-) create mode 100644 weaver/src/org/aspectj/weaver/AbstractAnnotationAJ.java delete mode 100644 weaver/src/org/aspectj/weaver/AnnotationX.java create mode 100644 weaver/src/org/aspectj/weaver/StandardAnnotation.java create mode 100644 weaver/src/org/aspectj/weaver/bcel/BcelAnnotation.java diff --git a/weaver/src/org/aspectj/weaver/AbstractAnnotationAJ.java b/weaver/src/org/aspectj/weaver/AbstractAnnotationAJ.java new file mode 100644 index 000000000..f9922cf97 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/AbstractAnnotationAJ.java @@ -0,0 +1,158 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * 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 + * + * ******************************************************************/ +package org.aspectj.weaver; + +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; + +public abstract class AbstractAnnotationAJ implements AnnotationAJ { + + protected final ResolvedType type; + + private Set supportedTargets = null; // @target meta annotation + + public AbstractAnnotationAJ(ResolvedType type) { + this.type = type; + } + + /** + * {@inheritDoc} + */ + public final ResolvedType getType() { + return type; + } + + /** + * {@inheritDoc} + */ + public final String getTypeSignature() { + return type.getSignature(); + } + + /** + * {@inheritDoc} + */ + public final String getTypeName() { + return type.getName(); + } + + /** + * {@inheritDoc} + */ + public final boolean allowedOnAnnotationType() { + ensureAtTargetInitialized(); + if (supportedTargets.isEmpty()) { + return true; + } + return supportedTargets.contains("ANNOTATION_TYPE"); + } + + /** + * {@inheritDoc} + */ + public final boolean allowedOnField() { + ensureAtTargetInitialized(); + if (supportedTargets.isEmpty()) { + return true; + } + return supportedTargets.contains("FIELD"); + } + + /** + * {@inheritDoc} + */ + public final boolean allowedOnRegularType() { + ensureAtTargetInitialized(); + if (supportedTargets.isEmpty()) { + return true; + } + return supportedTargets.contains("TYPE"); + } + + /** + * {@inheritDoc} + */ + public final void ensureAtTargetInitialized() { + if (supportedTargets == null) { + AnnotationAJ atTargetAnnotation = retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET); + if (atTargetAnnotation == null) { + supportedTargets = Collections.EMPTY_SET; + } else { + supportedTargets = atTargetAnnotation.getTargets(); + } + } + } + + /** + * {@inheritDoc} + */ + public final String getValidTargets() { + StringBuffer sb = new StringBuffer(); + sb.append("{"); + for (Iterator iter = supportedTargets.iterator(); iter.hasNext();) { + String evalue = (String) iter.next(); + sb.append(evalue); + if (iter.hasNext()) { + sb.append(","); + } + } + sb.append("}"); + return sb.toString(); + } + + /** + * {@inheritDoc} + */ + public final boolean specifiesTarget() { + ensureAtTargetInitialized(); + return !supportedTargets.isEmpty(); + } + + /** + * Helper method to retrieve an annotation on an annotation e.g. retrieveAnnotationOnAnnotation(UnresolvedType.AT_TARGET) + */ + private final AnnotationAJ retrieveAnnotationOnAnnotation(UnresolvedType requiredAnnotationSignature) { + AnnotationAJ[] annos = type.getAnnotations(); + for (int i = 0; i < annos.length; i++) { + AnnotationAJ a = annos[i]; + if (a.getTypeSignature().equals(requiredAnnotationSignature.getSignature())) { + return annos[i]; + } + } + return null; + } + + /** + * {@inheritDoc} + */ + public abstract boolean isRuntimeVisible(); + + /** + * {@inheritDoc} + */ + public abstract Set getTargets(); + + /** + * {@inheritDoc} + */ + public abstract boolean hasNameValuePair(String name, String value); + + /** + * {@inheritDoc} + */ + public abstract boolean hasNamedValue(String name); + + /** + * {@inheritDoc} + */ + public abstract String stringify(); + +} diff --git a/weaver/src/org/aspectj/weaver/AnnotatedElement.java b/weaver/src/org/aspectj/weaver/AnnotatedElement.java index bb65e36f6..86297b85b 100644 --- a/weaver/src/org/aspectj/weaver/AnnotatedElement.java +++ b/weaver/src/org/aspectj/weaver/AnnotatedElement.java @@ -14,8 +14,8 @@ package org.aspectj.weaver; */ public interface AnnotatedElement { boolean hasAnnotation(UnresolvedType ofType); - + ResolvedType[] getAnnotationTypes(); - - AnnotationX getAnnotationOfType(UnresolvedType ofType); + + AnnotationAJ getAnnotationOfType(UnresolvedType ofType); } diff --git a/weaver/src/org/aspectj/weaver/AnnotationAJ.java b/weaver/src/org/aspectj/weaver/AnnotationAJ.java index ceb11cf25..5b51dbd25 100644 --- a/weaver/src/org/aspectj/weaver/AnnotationAJ.java +++ b/weaver/src/org/aspectj/weaver/AnnotationAJ.java @@ -1,121 +1,93 @@ /* ******************************************************************* - * Copyright (c) 2006 Contributors + * Copyright (c) 2006-2008 Contributors * 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: - * Andy Clement IBM initial implementation * ******************************************************************/ package org.aspectj.weaver; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.util.Set; /** - * This type represents the weavers abstraction of an annotation - it is - * not tied to any underlying BCI toolkit. The weaver actualy handles these - * through AnnotationX wrapper objects - until we start transforming the - * BCEL annotations into this form (expensive) or offer a clever - * visitor mechanism over the BCEL annotation stuff that builds these - * annotation types directly. - * + * Simple representation of an annotation that the weaver can work with. + * * @author AndyClement */ -public class AnnotationAJ { - - private String type; - private boolean isRuntimeVisible; - - private List /*of AnnotationNVPair*/ nvPairs = null; - - public AnnotationAJ(String type,boolean isRuntimeVisible) { - this.type = type; - this.isRuntimeVisible = isRuntimeVisible; - } - - public String getTypeSignature() { - return type; - } - - public List getNameValuePairs() { - return nvPairs; - } - - public boolean hasNameValuePairs() { - return nvPairs!=null && nvPairs.size()!=0; - } - - public boolean isRuntimeVisible() { - return isRuntimeVisible; - } - - public String stringify() { - StringBuffer sb = new StringBuffer(); - sb.append("@").append(UnresolvedType.forSignature(type).getClassName()); - if (hasNameValuePairs()) { - sb.append("("); - for (Iterator iter = nvPairs.iterator(); iter.hasNext();) { - AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next(); - sb.append(element.stringify()); - } - sb.append(")"); - } - return sb.toString(); - } - - public String getStringValueOf(Object name) { - if (!hasNameValuePairs()) return null; - for (Iterator iter = nvPairs.iterator(); iter.hasNext();) { - AnnotationNameValuePair nvpair = (AnnotationNameValuePair) iter.next(); - if (nvpair.getName().equals(name)) return nvpair.getValue().stringify(); - } - return null; - } - - public void addNameValuePair(AnnotationNameValuePair pair) { - if (nvPairs==null) nvPairs=new ArrayList(); - nvPairs.add(pair); - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append("ANNOTATION ["+getTypeSignature()+"] ["+ - (isRuntimeVisible?"runtimeVisible":"runtimeInvisible")+"] ["); - if (nvPairs!=null) { - for (Iterator iter = nvPairs.iterator(); iter.hasNext();) { - AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next(); - sb.append(element.toString()); - if (iter.hasNext()) sb.append(","); - } - } - sb.append("]"); - return sb.toString(); - } - - public boolean hasNamedValue(String n) { - if (nvPairs==null) return false; - for (int i=0;i 0) { - ResolvedType[] allInterfaces = - new ResolvedType[interfaces.length + additionalInterfaceBounds.length]; - System.arraycopy(interfaces, 0, allInterfaces, 0, interfaces.length); - System.arraycopy(additionalInterfaceBounds,0,allInterfaces,interfaces.length,additionalInterfaceBounds.length); + ResolvedType[] allInterfaces = new ResolvedType[interfaces.length + + additionalInterfaceBounds.length]; + System + .arraycopy(interfaces, 0, allInterfaces, 0, + interfaces.length); + System.arraycopy(additionalInterfaceBounds, 0, allInterfaces, + interfaces.length, additionalInterfaceBounds.length); return allInterfaces; } else { return interfaces; } } - + public boolean isGenericWildcard() { return true; } - - protected static class ReferenceTypeReferenceTypeDelegate extends AbstractReferenceTypeDelegate { + + protected static class ReferenceTypeReferenceTypeDelegate extends + AbstractReferenceTypeDelegate { public ReferenceTypeReferenceTypeDelegate(ReferenceType backing) { - super(backing,false); + super(backing, false); } - - public void addAnnotation(AnnotationX annotationX) { - throw new UnsupportedOperationException("What on earth do you think you are doing???"); + + public void addAnnotation(AnnotationAJ annotationX) { + throw new UnsupportedOperationException( + "What on earth do you think you are doing???"); } public boolean isAspect() { @@ -203,19 +233,19 @@ public class BoundedReferenceType extends ReferenceType { public boolean isAnnotationWithRuntimeRetention() { return resolvedTypeX.isAnnotationWithRuntimeRetention(); } - + public boolean isAnonymous() { return resolvedTypeX.isAnonymous(); } - + public boolean isNested() { return resolvedTypeX.isNested(); } - + public ResolvedType getOuterClass() { return resolvedTypeX.getOuterClass(); } - + public String getRetentionPolicy() { return resolvedTypeX.getRetentionPolicy(); } @@ -223,11 +253,11 @@ public class BoundedReferenceType extends ReferenceType { public boolean canAnnotationTargetType() { return resolvedTypeX.canAnnotationTargetType(); } - + public AnnotationTargetKind[] getAnnotationTargetKinds() { return resolvedTypeX.getAnnotationTargetKinds(); } - + public boolean isGeneric() { return resolvedTypeX.isGenericType(); } @@ -235,12 +265,12 @@ public class BoundedReferenceType extends ReferenceType { public String getDeclaredGenericSignature() { return resolvedTypeX.getDeclaredGenericSignature(); } - + public boolean hasAnnotation(UnresolvedType ofType) { return resolvedTypeX.hasAnnotation(ofType); } - public AnnotationX[] getAnnotations() { + public AnnotationAJ[] getAnnotations() { return resolvedTypeX.getAnnotations(); } diff --git a/weaver/src/org/aspectj/weaver/JoinPointSignature.java b/weaver/src/org/aspectj/weaver/JoinPointSignature.java index af4538369..399c73115 100644 --- a/weaver/src/org/aspectj/weaver/JoinPointSignature.java +++ b/weaver/src/org/aspectj/weaver/JoinPointSignature.java @@ -22,10 +22,12 @@ import org.aspectj.bridge.ISourceLocation; import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute; /** - * @author colyer Instances of this class are created by ResolvedMember.getSignatures() when collating all of the signatures for a - * member. We need to create entries in the set for the "gaps" in the hierarchy. For example: + * @author colyer Instances of this class are created by + * ResolvedMember.getSignatures() when collating all of the signatures + * for a member. We need to create entries in the set for the "gaps" in + * the hierarchy. For example: * - * class A { void foo(); } + * class A { void foo(); } * * class B extends A {} * @@ -33,7 +35,8 @@ import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute; * * has signatures: * - * B.foo() AND A.foo() B.foo() will be created as a ResolvedMemberWithSubstituteDeclaringType + * B.foo() AND A.foo() B.foo() will be created as a + * ResolvedMemberWithSubstituteDeclaringType * * Oh for a JDK 1.4 dynamic proxy.... we have to run on 1.3 :( */ @@ -87,7 +90,7 @@ public class JoinPointSignature implements ResolvedMember { return realMember.getAnnotationTypes(); } - public AnnotationX getAnnotationOfType(UnresolvedType ofType) { + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { return realMember.getAnnotationOfType(ofType); } @@ -95,7 +98,7 @@ public class JoinPointSignature implements ResolvedMember { realMember.setAnnotationTypes(annotationtypes); } - public void addAnnotation(AnnotationX annotation) { + public void addAnnotation(AnnotationAJ annotation) { realMember.addAnnotation(annotation); } @@ -203,14 +206,18 @@ public class JoinPointSignature implements ResolvedMember { return realMember.getGenericParameterTypes(); } - public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, + public ResolvedMemberImpl parameterizedWith( + UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized) { - return realMember.parameterizedWith(typeParameters, newDeclaringType, isParameterized); + return realMember.parameterizedWith(typeParameters, newDeclaringType, + isParameterized); } - public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, + public ResolvedMemberImpl parameterizedWith( + UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized, List aliases) { - return realMember.parameterizedWith(typeParameters, newDeclaringType, isParameterized, aliases); + return realMember.parameterizedWith(typeParameters, newDeclaringType, + isParameterized, aliases); } public void setTypeVariables(TypeVariable[] types) { @@ -257,7 +264,7 @@ public class JoinPointSignature implements ResolvedMember { return realMember.getParameterTypes(); } - public AnnotationX[][] getParameterAnnotations() { + public AnnotationAJ[][] getParameterAnnotations() { return realMember.getParameterAnnotations(); } @@ -297,12 +304,13 @@ public class JoinPointSignature implements ResolvedMember { return realMember.canBeParameterized(); } - public AnnotationX[] getAnnotations() { + public AnnotationAJ[] getAnnotations() { return realMember.getAnnotations(); } public Collection getDeclaringTypes(World world) { - throw new UnsupportedOperationException("Adrian doesn't think you should be calling this..."); + throw new UnsupportedOperationException( + "Adrian doesn't think you should be calling this..."); } public Iterator getJoinPointSignatures(World world) { @@ -367,7 +375,8 @@ public class JoinPointSignature implements ResolvedMember { } public int hashCode() { - return 17 + (37 * realMember.hashCode()) + (37 * substituteDeclaringType.hashCode()); + return 17 + (37 * realMember.hashCode()) + + (37 * substituteDeclaringType.hashCode()); } public boolean hasBackingGenericMember() { diff --git a/weaver/src/org/aspectj/weaver/Member.java b/weaver/src/org/aspectj/weaver/Member.java index 00254e54e..04c67e178 100644 --- a/weaver/src/org/aspectj/weaver/Member.java +++ b/weaver/src/org/aspectj/weaver/Member.java @@ -24,29 +24,33 @@ public interface Member extends Comparable { public static final Member[] NONE = new Member[0]; public static final MemberKind METHOD = new MemberKind("METHOD", 1); public static final MemberKind FIELD = new MemberKind("FIELD", 2); - public static final MemberKind CONSTRUCTOR = new MemberKind("CONSTRUCTOR", 3); - public static final MemberKind STATIC_INITIALIZATION = new MemberKind("STATIC_INITIALIZATION", 4); + public static final MemberKind CONSTRUCTOR = new MemberKind("CONSTRUCTOR", + 3); + public static final MemberKind STATIC_INITIALIZATION = new MemberKind( + "STATIC_INITIALIZATION", 4); public static final MemberKind POINTCUT = new MemberKind("POINTCUT", 5); public static final MemberKind ADVICE = new MemberKind("ADVICE", 6); public static final MemberKind HANDLER = new MemberKind("HANDLER", 7); - public static final MemberKind MONITORENTER = new MemberKind("MONITORENTER", 8); - public static final MemberKind MONITOREXIT = new MemberKind("MONITOREXIT", 9); + public static final MemberKind MONITORENTER = new MemberKind( + "MONITORENTER", 8); + public static final MemberKind MONITOREXIT = new MemberKind("MONITOREXIT", + 9); + + public static final AnnotationAJ[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationAJ[][] {}; + public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][] {}; - public static final AnnotationX[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationX[][]{}; - public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][]{}; - public MemberKind getKind(); - + public ResolvedMember resolve(World world); - public int compareTo(Object other); + public int compareTo(Object other); public UnresolvedType getDeclaringType(); public UnresolvedType getReturnType(); - + public UnresolvedType getGenericReturnType(); - + public UnresolvedType[] getGenericParameterTypes(); public UnresolvedType getType(); @@ -56,28 +60,30 @@ public interface Member extends Comparable { public UnresolvedType[] getParameterTypes(); /** - * Return full signature, including return type, e.g. "()LFastCar;". For a signature without the return type, - * use getParameterSignature() - it is important to choose the right one in the face of covariance. + * Return full signature, including return type, e.g. "()LFastCar;". For a + * signature without the return type, use getParameterSignature() - it is + * important to choose the right one in the face of covariance. */ public String getSignature(); - - public Iterator getJoinPointSignatures(World world); + + public Iterator getJoinPointSignatures(World world); public int getArity(); /** - * Return signature without return type, e.g. "()" for a signature *with* the return type, - * use getSignature() - it is important to choose the right one in the face of covariance. + * Return signature without return type, e.g. "()" for a signature *with* + * the return type, use getSignature() - it is important to choose the right + * one in the face of covariance. */ public String getParameterSignature(); public int getModifiers(World world); - + public int getModifiers(); - public boolean isStatic(); + public boolean isStatic(); - public boolean isInterface(); + public boolean isInterface(); public boolean isPrivate(); @@ -86,11 +92,11 @@ public interface Member extends Comparable { */ public boolean canBeParameterized(); - public AnnotationX[] getAnnotations(); - - public Collection/* ResolvedType */getDeclaringTypes(World world); + public AnnotationAJ[] getAnnotations(); + + public Collection/* ResolvedType */getDeclaringTypes(World world); public String[] getParameterNames(World world); - public UnresolvedType[] getExceptions(World world); + public UnresolvedType[] getExceptions(World world); } \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/MemberImpl.java b/weaver/src/org/aspectj/weaver/MemberImpl.java index 06640e3ff..f51146f63 100644 --- a/weaver/src/org/aspectj/weaver/MemberImpl.java +++ b/weaver/src/org/aspectj/weaver/MemberImpl.java @@ -35,11 +35,13 @@ public class MemberImpl implements Member { private boolean reportedUnresolvableMember = false; /** - * All the signatures that a join point with this member as its signature has. + * All the signatures that a join point with this member as its signature + * has. */ private JoinPointSignatureIterator joinPointSignatures = null; - public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String signature) { + public MemberImpl(MemberKind kind, UnresolvedType declaringType, + int modifiers, String name, String signature) { this.kind = kind; this.declaringType = declaringType; this.modifiers = modifiers; @@ -58,7 +60,8 @@ public class MemberImpl implements Member { } } - public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, + public MemberImpl(MemberKind kind, UnresolvedType declaringType, + int modifiers, UnresolvedType returnType, String name, UnresolvedType[] parameterTypes) { this.kind = kind; this.declaringType = declaringType; @@ -80,9 +83,10 @@ public class MemberImpl implements Member { // ---- utility methods /** - * returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type, argument types parsed from the JVM - * bytecode signature of a method. Yes, this should actually return a nice statically-typed pair object, but we don't have one - * of those. + * returns an Object[] pair of UnresolvedType, UnresolvedType[] representing + * return type, argument types parsed from the JVM bytecode signature of a + * method. Yes, this should actually return a nice statically-typed pair + * object, but we don't have one of those. * *
* @@ -94,11 +98,15 @@ public class MemberImpl implements Member { * *
* - * @param signature the JVM bytecode method signature string we want to break apart - * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. + * @param signature + * the JVM bytecode method signature string we want to break + * apart + * @return a pair of UnresolvedType, UnresolvedType[] representing the + * return types and parameter types. */ // OPTIMIZE move static util methods out into a memberutils class - public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean useRawTypes) { + public static String typesToSignature(UnresolvedType returnType, + UnresolvedType[] paramTypes, boolean useRawTypes) { StringBuffer buf = new StringBuffer(); buf.append("("); for (int i = 0, len = paramTypes.length; i < len; i++) { @@ -120,8 +128,9 @@ public class MemberImpl implements Member { } /** - * Returns "(,...)" - unlike the other typesToSignature that also includes the return type, this one - * just deals with the parameter types. + * Returns "(,...)" - unlike the other + * typesToSignature that also includes the return type, this one just deals + * with the parameter types. */ public static String typesToSignature(UnresolvedType[] paramTypes) { StringBuffer buf = new StringBuffer(); @@ -134,9 +143,10 @@ public class MemberImpl implements Member { } /** - * returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type, argument types parsed from the JVM - * bytecode signature of a method. Yes, this should actually return a nice statically-typed pair object, but we don't have one - * of those. + * returns an Object[] pair of UnresolvedType, UnresolvedType[] representing + * return type, argument types parsed from the JVM bytecode signature of a + * method. Yes, this should actually return a nice statically-typed pair + * object, but we don't have one of those. * *
* @@ -148,10 +158,14 @@ public class MemberImpl implements Member { * *
* - * @param signature the JVM bytecode method signature string we want to break apart - * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types. + * @param signature + * the JVM bytecode method signature string we want to break + * apart + * @return a pair of UnresolvedType, UnresolvedType[] representing the + * return types and parameter types. */ - private static Object[] signatureToTypes(String sig, boolean keepParameterizationInfo) { + private static Object[] signatureToTypes(String sig, + boolean keepParameterizationInfo) { boolean hasParameters = sig.charAt(1) != ')'; if (hasParameters) { List l = new ArrayList(); @@ -166,10 +180,13 @@ public class MemberImpl implements Member { c = sig.charAt(++i); if (c == 'L' || c == 'P') { int nextSemicolon = sig.indexOf(';', start); - int firstAngly = (hasAnyAnglies ? sig.indexOf('<', start) : -1); - if (!hasAnyAnglies || firstAngly == -1 || firstAngly > nextSemicolon) { + int firstAngly = (hasAnyAnglies ? sig.indexOf('<', start) + : -1); + if (!hasAnyAnglies || firstAngly == -1 + || firstAngly > nextSemicolon) { i = nextSemicolon + 1; - l.add(UnresolvedType.forSignature(sig.substring(start, i))); + l.add(UnresolvedType.forSignature(sig.substring(start, + i))); } else { // generics generics generics // Have to skip to the *correct* ';' @@ -194,9 +211,11 @@ public class MemberImpl implements Member { } // posn now points to the correct nextSemicolon :) i = posn; - l.add(UnresolvedType.forSignature(sig.substring(start, i))); + l.add(UnresolvedType.forSignature(sig.substring(start, + i))); } - } else if (c == 'T') { // assumed 'reference' to a type variable, so just "Tname;" + } else if (c == 'T') { // assumed 'reference' to a type + // variable, so just "Tname;" int nextSemicolon = sig.indexOf(';', start); String nextbit = sig.substring(start, nextSemicolon); l.add(UnresolvedType.forSignature(nextbit)); @@ -206,74 +225,97 @@ public class MemberImpl implements Member { l.add(UnresolvedType.forSignature(sig.substring(start, i))); } } - UnresolvedType[] paramTypes = (UnresolvedType[]) l.toArray(new UnresolvedType[l.size()]); - UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(i + 1, sig.length())); + UnresolvedType[] paramTypes = (UnresolvedType[]) l + .toArray(new UnresolvedType[l.size()]); + UnresolvedType returnType = UnresolvedType.forSignature(sig + .substring(i + 1, sig.length())); return new Object[] { returnType, paramTypes }; } else { - UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(2)); + UnresolvedType returnType = UnresolvedType.forSignature(sig + .substring(2)); return new Object[] { returnType, UnresolvedType.NONE }; } } // ---- factory methods - public static MemberImpl field(String declaring, int mods, String name, String signature) { - return field(declaring, mods, UnresolvedType.forSignature(signature), name); + public static MemberImpl field(String declaring, int mods, String name, + String signature) { + return field(declaring, mods, UnresolvedType.forSignature(signature), + name); } - // public static Member field(UnresolvedType declaring, int mods, String name, UnresolvedType type) { - // return new MemberImpl(FIELD, declaring, mods, type, name, UnresolvedType.NONE); + // public static Member field(UnresolvedType declaring, int mods, String + // name, UnresolvedType type) { + // return new MemberImpl(FIELD, declaring, mods, type, name, + // UnresolvedType.NONE); // } - // OPTIMIZE do we need to call this? unless necessary the signatureToTypes() call smacks of laziness on the behalf of the caller + // OPTIMIZE do we need to call this? unless necessary the signatureToTypes() + // call smacks of laziness on the behalf of the caller // of this method - public static MemberImpl method(UnresolvedType declaring, int mods, String name, String signature) { + public static MemberImpl method(UnresolvedType declaring, int mods, + String name, String signature) { Object[] pair = signatureToTypes(signature, false); - return method(declaring, mods, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); + return method(declaring, mods, (UnresolvedType) pair[0], name, + (UnresolvedType[]) pair[1]); } public static MemberImpl monitorEnter() { - return new MemberImpl(MONITORENTER, UnresolvedType.OBJECT, Modifier.STATIC, ResolvedType.VOID, "", + return new MemberImpl(MONITORENTER, UnresolvedType.OBJECT, + Modifier.STATIC, ResolvedType.VOID, "", UnresolvedType.ARRAY_WITH_JUST_OBJECT); } public static MemberImpl monitorExit() { - return new MemberImpl(MONITOREXIT, UnresolvedType.OBJECT, Modifier.STATIC, ResolvedType.VOID, "", + return new MemberImpl(MONITOREXIT, UnresolvedType.OBJECT, + Modifier.STATIC, ResolvedType.VOID, "", UnresolvedType.ARRAY_WITH_JUST_OBJECT); } - public static Member pointcut(UnresolvedType declaring, String name, String signature) { + public static Member pointcut(UnresolvedType declaring, String name, + String signature) { Object[] pair = signatureToTypes(signature, false); - return pointcut(declaring, 0, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]); + return pointcut(declaring, 0, (UnresolvedType) pair[0], name, + (UnresolvedType[]) pair[1]); } - private static MemberImpl field(String declaring, int mods, UnresolvedType ty, String name) { - return new MemberImpl(FIELD, UnresolvedType.forName(declaring), mods, ty, name, UnresolvedType.NONE); + private static MemberImpl field(String declaring, int mods, + UnresolvedType ty, String name) { + return new MemberImpl(FIELD, UnresolvedType.forName(declaring), mods, + ty, name, UnresolvedType.NONE); } - public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { + public static MemberImpl method(UnresolvedType declTy, int mods, + UnresolvedType rTy, String name, UnresolvedType[] paramTys) { return new MemberImpl( - // ??? this calls a method - name.equals("") ? CONSTRUCTOR : METHOD, declTy, mods, rTy, name, paramTys); + // ??? this calls a method + name.equals("") ? CONSTRUCTOR : METHOD, declTy, mods, + rTy, name, paramTys); } - private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) { + private static Member pointcut(UnresolvedType declTy, int mods, + UnresolvedType rTy, String name, UnresolvedType[] paramTys) { return new MemberImpl(POINTCUT, declTy, mods, rTy, name, paramTys); } - public static ResolvedMemberImpl makeExceptionHandlerSignature(UnresolvedType inType, UnresolvedType catchType) { - return new ResolvedMemberImpl(HANDLER, inType, Modifier.STATIC, "", "(" + catchType.getSignature() + ")V"); + public static ResolvedMemberImpl makeExceptionHandlerSignature( + UnresolvedType inType, UnresolvedType catchType) { + return new ResolvedMemberImpl(HANDLER, inType, Modifier.STATIC, + "", "(" + catchType.getSignature() + ")V"); } public boolean equals(Object other) { if (!(other instanceof Member)) return false; Member o = (Member) other; - return (getKind() == o.getKind() && getName().equals(o.getName()) && getSignature().equals(o.getSignature()) && getDeclaringType() + return (getKind() == o.getKind() && getName().equals(o.getName()) + && getSignature().equals(o.getSignature()) && getDeclaringType() .equals(o.getDeclaringType())); } /** - * Equality is checked based on the underlying signature, so the hash code of a member is based on its kind, name, signature, - * and declaring type. The algorithm for this was taken from page 38 of effective java. + * Equality is checked based on the underlying signature, so the hash code + * of a member is based on its kind, name, signature, and declaring type. + * The algorithm for this was taken from page 38 of effective java. */ private volatile int hashCode = 0; @@ -372,7 +414,8 @@ public class MemberImpl implements Member { return paramSignature; } - // OPTIMIZE see next line. Why the hell are they in here if we only know it once resolution has occurred... + // OPTIMIZE see next line. Why the hell are they in here if we only know it + // once resolution has occurred... // ---- things we know only with resolution public int getModifiers(World world) { @@ -413,9 +456,10 @@ public class MemberImpl implements Member { return modifiers; } - public AnnotationX[] getAnnotations() { - throw new UnsupportedOperationException("You should resolve this member '" + this - + "' and call getAnnotations() on the result..."); + public AnnotationAJ[] getAnnotations() { + throw new UnsupportedOperationException( + "You should resolve this member '" + this + + "' and call getAnnotations() on the result..."); } // ---- fields 'n' stuff @@ -424,7 +468,8 @@ public class MemberImpl implements Member { ResolvedType myType = getDeclaringType().resolve(world); Collection ret = new HashSet(); if (kind == CONSTRUCTOR) { - // this is wrong if the member doesn't exist, but that doesn't matter + // this is wrong if the member doesn't exist, but that doesn't + // matter ret.add(myType); } else if (isStatic() || kind == FIELD) { walkUpStatic(ret, myType); @@ -484,7 +529,8 @@ public class MemberImpl implements Member { } /** - * All the signatures that a join point with this member as its signature has. + * All the signatures that a join point with this member as its signature + * has. */ public Iterator getJoinPointSignatures(World inAWorld) { if (joinPointSignatures == null) { @@ -495,15 +541,17 @@ public class MemberImpl implements Member { } /** - * Raises an [Xlint:cantFindType] message if the declaring type cannot be found or an [Xlint:unresolvableMember] message if the - * type can be found (bug 149908) + * Raises an [Xlint:cantFindType] message if the declaring type cannot be + * found or an [Xlint:unresolvableMember] message if the type can be found + * (bug 149908) */ private void reportDidntFindMember(World world) { if (reportedCantFindDeclaringType || reportedUnresolvableMember) return; ResolvedType rType = getDeclaringType().resolve(world); if (rType.isMissing()) { - world.getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE, rType.getName()), null); + world.getLint().cantFindType.signal(WeaverMessages.format( + WeaverMessages.CANT_FIND_TYPE, rType.getName()), null); reportedCantFindDeclaringType = true; } else { world.getLint().unresolvableMember.signal(getName(), null); diff --git a/weaver/src/org/aspectj/weaver/ReferenceType.java b/weaver/src/org/aspectj/weaver/ReferenceType.java index e587294d2..905b0c6ef 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceType.java +++ b/weaver/src/org/aspectj/weaver/ReferenceType.java @@ -24,21 +24,27 @@ import org.aspectj.weaver.patterns.Declare; import org.aspectj.weaver.patterns.PerClause; /** - * A reference type represents some 'real' type, not a primitive, not an array - but a real type, for example java.util.List. Each - * ReferenceType has a delegate that is the underlying artifact - either an eclipse artifact or a bcel artifact. If the type - * represents a raw type (i.e. there is a generic form) then the genericType field is set to point to the generic type. If it is for - * a parameterized type then the generic type is also set to point to the generic form. + * A reference type represents some 'real' type, not a primitive, not an array - + * but a real type, for example java.util.List. Each ReferenceType has a + * delegate that is the underlying artifact - either an eclipse artifact or a + * bcel artifact. If the type represents a raw type (i.e. there is a generic + * form) then the genericType field is set to point to the generic type. If it + * is for a parameterized type then the generic type is also set to point to the + * generic form. */ public class ReferenceType extends ResolvedType { /** - * For generic types, this list holds references to all the derived raw and parameterized versions. We need this so that if the - * generic delegate is swapped during incremental compilation, the delegate of the derivatives is swapped also. + * For generic types, this list holds references to all the derived raw and + * parameterized versions. We need this so that if the generic delegate is + * swapped during incremental compilation, the delegate of the derivatives + * is swapped also. */ private List/* ReferenceType */derivativeTypes = new ArrayList(); /** - * For parameterized types (or the raw type) - this field points to the actual reference type from which they are derived. + * For parameterized types (or the raw type) - this field points to the + * actual reference type from which they are derived. */ ReferenceType genericType = null; @@ -72,8 +78,10 @@ public class ReferenceType extends ResolvedType { /** * Constructor used when creating a parameterized type. */ - public ReferenceType(ResolvedType theGenericType, ResolvedType[] theParameters, World aWorld) { - super(makeParameterizedSignature(theGenericType, theParameters), theGenericType.signatureErasure, aWorld); + public ReferenceType(ResolvedType theGenericType, + ResolvedType[] theParameters, World aWorld) { + super(makeParameterizedSignature(theGenericType, theParameters), + theGenericType.signatureErasure, aWorld); ReferenceType genericReferenceType = (ReferenceType) theGenericType; this.typeParameters = theParameters; this.genericType = genericReferenceType; @@ -129,11 +137,11 @@ public class ReferenceType extends ResolvedType { return (sig == null) ? "" : sig; } - public AnnotationX[] getAnnotations() { + public AnnotationAJ[] getAnnotations() { return delegate.getAnnotations(); } - public void addAnnotation(AnnotationX annotationX) { + public void addAnnotation(AnnotationAJ annotationX) { delegate.addAnnotation(annotationX); } @@ -145,12 +153,13 @@ public class ReferenceType extends ResolvedType { return delegate.getAnnotationTypes(); } - public AnnotationX getAnnotationOfType(UnresolvedType ofType) { - AnnotationX[] axs = delegate.getAnnotations(); - if (axs == null) + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { + AnnotationAJ[] axs = delegate.getAnnotations(); + if (axs == null) { return null; + } for (int i = 0; i < axs.length; i++) { - if (axs[i].getSignature().equals(ofType)) { + if (axs[i].getTypeSignature().equals(ofType.getSignature())) { return axs[i]; } } @@ -221,7 +230,8 @@ public class ReferenceType extends ResolvedType { } // ??? needs to be Methods, not just declared methods? JLS 5.5 unclear ResolvedMember[] a = getDeclaredMethods(); - ResolvedMember[] b = other.getDeclaredMethods(); // ??? is this cast always safe + ResolvedMember[] b = other.getDeclaredMethods(); // ??? is this cast + // always safe for (int ai = 0, alen = a.length; ai < alen; ai++) { for (int bi = 0, blen = b.length; bi < blen; bi++) { if (!b[bi].isCompatibleWith(a[ai])) @@ -240,21 +250,26 @@ public class ReferenceType extends ResolvedType { if (getTypeParameters().length == other.getTypeParameters().length) { // there's a chance it can be done ResolvedType[] myTypeParameters = getResolvedTypeParameters(); - ResolvedType[] theirTypeParameters = other.getResolvedTypeParameters(); + ResolvedType[] theirTypeParameters = other + .getResolvedTypeParameters(); for (int i = 0; i < myTypeParameters.length; i++) { if (myTypeParameters[i] != theirTypeParameters[i]) { - // thin ice now... but List may still be coerceable from e.g. List + // thin ice now... but List may still be + // coerceable from e.g. List if (myTypeParameters[i].isGenericWildcard()) { BoundedReferenceType wildcard = (BoundedReferenceType) myTypeParameters[i]; - if (!wildcard.canBeCoercedTo(theirTypeParameters[i])) + if (!wildcard + .canBeCoercedTo(theirTypeParameters[i])) return false; - } else if (myTypeParameters[i].isTypeVariableReference()) { + } else if (myTypeParameters[i] + .isTypeVariableReference()) { TypeVariableReferenceType tvrt = (TypeVariableReferenceType) myTypeParameters[i]; TypeVariable tv = tvrt.getTypeVariable(); tv.resolve(world); if (!tv.canBeBoundTo(theirTypeParameters[i])) return false; - } else if (theirTypeParameters[i].isTypeVariableReference()) { + } else if (theirTypeParameters[i] + .isTypeVariableReference()) { TypeVariableReferenceType tvrt = (TypeVariableReferenceType) theirTypeParameters[i]; TypeVariable tv = tvrt.getTypeVariable(); tv.resolve(world); @@ -289,7 +304,8 @@ public class ReferenceType extends ResolvedType { if (other.isPrimitiveType()) { if (!world.isInJava5Mode()) return false; - if (ResolvedType.validBoxing.contains(this.getSignature() + other.getSignature())) + if (ResolvedType.validBoxing.contains(this.getSignature() + + other.getSignature())) return true; } if (this == other) @@ -297,7 +313,8 @@ public class ReferenceType extends ResolvedType { if (this.getSignature().equals(ResolvedType.OBJECT.getSignature())) return true; - if ((this.isRawType() || this.isGenericType()) && other.isParameterizedType()) { + if ((this.isRawType() || this.isGenericType()) + && other.isParameterizedType()) { if (isAssignableFrom((ResolvedType) other.getRawType())) return true; } @@ -328,13 +345,15 @@ public class ReferenceType extends ResolvedType { if (wildcardsAllTheWay && !other.isParameterizedType()) return true; // we have to match by parameters one at a time - ResolvedType[] theirParameters = other.getResolvedTypeParameters(); + ResolvedType[] theirParameters = other + .getResolvedTypeParameters(); boolean parametersAssignable = true; if (myParameters.length == theirParameters.length) { for (int i = 0; i < myParameters.length; i++) { if (myParameters[i] == theirParameters[i]) continue; - if (myParameters[i].isAssignableFrom(theirParameters[i], allowMissing)) { + if (myParameters[i].isAssignableFrom( + theirParameters[i], allowMissing)) { continue; } if (!myParameters[i].isGenericWildcard()) { @@ -356,20 +375,38 @@ public class ReferenceType extends ResolvedType { } } - if (isTypeVariableReference() && !other.isTypeVariableReference()) { // eg. this=T other=Ljava/lang/Object; - TypeVariable aVar = ((TypeVariableReference) this).getTypeVariable(); + if (isTypeVariableReference() && !other.isTypeVariableReference()) { // eg + // . + // this + // = + // T + // other + // = + // Ljava + // / + // lang + // / + // Object + // ; + TypeVariable aVar = ((TypeVariableReference) this) + .getTypeVariable(); return aVar.resolve(world).canBeBoundTo(other); } if (other.isTypeVariableReference()) { TypeVariableReferenceType otherType = (TypeVariableReferenceType) other; if (this instanceof TypeVariableReference) { - return ((TypeVariableReference) this).getTypeVariable().resolve(world).canBeBoundTo( - otherType.getTypeVariable().getFirstBound().resolve(world));// pr171952 - // return ((TypeVariableReference)this).getTypeVariable()==otherType.getTypeVariable(); + return ((TypeVariableReference) this).getTypeVariable() + .resolve(world).canBeBoundTo( + otherType.getTypeVariable().getFirstBound() + .resolve(world));// pr171952 + // return + // ((TypeVariableReference)this).getTypeVariable()==otherType + // .getTypeVariable(); } else { // FIXME asc should this say canBeBoundTo?? - return this.isAssignableFrom(otherType.getTypeVariable().getFirstBound().resolve(world)); + return this.isAssignableFrom(otherType.getTypeVariable() + .getFirstBound().resolve(world)); } } @@ -393,7 +430,9 @@ public class ReferenceType extends ResolvedType { } public boolean isExposedToWeaver() { - return (delegate == null) || delegate.isExposedToWeaver(); // ??? where does this belong + return (delegate == null) || delegate.isExposedToWeaver(); // ??? where + // does this + // belong } public WeaverStateInfo getWeaverState() { @@ -407,7 +446,8 @@ public class ReferenceType extends ResolvedType { ResolvedMember[] delegateFields = delegate.getDeclaredFields(); parameterizedFields = new ResolvedMember[delegateFields.length]; for (int i = 0; i < delegateFields.length; i++) { - parameterizedFields[i] = delegateFields[i].parameterizedWith(getTypesForMemberParameterization(), this, + parameterizedFields[i] = delegateFields[i].parameterizedWith( + getTypesForMemberParameterization(), this, isParameterizedType()); } return parameterizedFields; @@ -417,40 +457,52 @@ public class ReferenceType extends ResolvedType { } /** - * Find out from the generic signature the true signature of any interfaces I implement. If I am parameterized, these may then - * need to be parameterized before returning. + * Find out from the generic signature the true signature of any interfaces + * I implement. If I am parameterized, these may then need to be + * parameterized before returning. */ public ResolvedType[] getDeclaredInterfaces() { if (parameterizedInterfaces != null) return parameterizedInterfaces; if (isParameterizedType()) { - ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces(); - // UnresolvedType[] paramTypes = getTypesForMemberParameterization(); + ResolvedType[] delegateInterfaces = delegate + .getDeclaredInterfaces(); + // UnresolvedType[] paramTypes = + // getTypesForMemberParameterization(); parameterizedInterfaces = new ResolvedType[delegateInterfaces.length]; for (int i = 0; i < delegateInterfaces.length; i++) { - // We may have to sub/super set the set of parametertypes if the implemented interface + // We may have to sub/super set the set of parametertypes if the + // implemented interface // needs more or less than this type does. (pr124803/pr125080) if (delegateInterfaces[i].isParameterizedType()) { - parameterizedInterfaces[i] = delegateInterfaces[i].parameterize(getMemberParameterizationMap()).resolve(world); + parameterizedInterfaces[i] = delegateInterfaces[i] + .parameterize(getMemberParameterizationMap()) + .resolve(world); } else { parameterizedInterfaces[i] = delegateInterfaces[i]; } } return parameterizedInterfaces; } else if (isRawType()) { - ResolvedType[] delegateInterfaces = delegate.getDeclaredInterfaces(); + ResolvedType[] delegateInterfaces = delegate + .getDeclaredInterfaces(); UnresolvedType[] paramTypes = getTypesForMemberParameterization(); parameterizedInterfaces = new ResolvedType[delegateInterfaces.length]; for (int i = 0; i < parameterizedInterfaces.length; i++) { parameterizedInterfaces[i] = delegateInterfaces[i]; if (parameterizedInterfaces[i].isGenericType()) { - // a generic supertype of a raw type is replaced by its raw equivalent - parameterizedInterfaces[i] = parameterizedInterfaces[i].getRawType().resolve(getWorld()); + // a generic supertype of a raw type is replaced by its raw + // equivalent + parameterizedInterfaces[i] = parameterizedInterfaces[i] + .getRawType().resolve(getWorld()); } else if (parameterizedInterfaces[i].isParameterizedType()) { - // a parameterized supertype collapses any type vars to their upper bounds - UnresolvedType[] toUseForParameterization = determineThoseTypesToUse(parameterizedInterfaces[i], paramTypes); - parameterizedInterfaces[i] = parameterizedInterfaces[i].parameterizedWith(toUseForParameterization); + // a parameterized supertype collapses any type vars to + // their upper bounds + UnresolvedType[] toUseForParameterization = determineThoseTypesToUse( + parameterizedInterfaces[i], paramTypes); + parameterizedInterfaces[i] = parameterizedInterfaces[i] + .parameterizedWith(toUseForParameterization); } } return parameterizedInterfaces; @@ -459,10 +511,12 @@ public class ReferenceType extends ResolvedType { } /** - * Locates the named type variable in the list of those on this generic type and returns the type parameter from the second list - * supplied. Returns null if it can't be found + * Locates the named type variable in the list of those on this generic type + * and returns the type parameter from the second list supplied. Returns + * null if it can't be found */ - // private UnresolvedType findTypeParameterInList(String name, TypeVariable[] tvarsOnThisGenericType, UnresolvedType[] + // private UnresolvedType findTypeParameterInList(String name, + // TypeVariable[] tvarsOnThisGenericType, UnresolvedType[] // paramTypes) { // int position = -1; // for (int i = 0; i < tvarsOnThisGenericType.length; i++) { @@ -473,31 +527,38 @@ public class ReferenceType extends ResolvedType { // return paramTypes[position]; // } /** - * It is possible this type has multiple type variables but the interface we are about to parameterize only uses a subset - this - * method determines the subset to use by looking at the type variable names used. For example: + * It is possible this type has multiple type variables but the interface we + * are about to parameterize only uses a subset - this method determines the + * subset to use by looking at the type variable names used. For example: + * * class Foo implements SuperInterface {} * where * interface SuperInterface {} - * In that - * example, a use of the 'Foo' raw type should know that it implements the SuperInterface. + * In that example, a use of the 'Foo' raw type should + * know that it implements the SuperInterface. */ - private UnresolvedType[] determineThoseTypesToUse(ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) { + private UnresolvedType[] determineThoseTypesToUse( + ResolvedType parameterizedInterface, UnresolvedType[] paramTypes) { // What are the type parameters for the supertype? UnresolvedType[] tParms = parameterizedInterface.getTypeParameters(); UnresolvedType[] retVal = new UnresolvedType[tParms.length]; - // Go through the supertypes type parameters, if any of them is a type variable, use the + // Go through the supertypes type parameters, if any of them is a type + // variable, use the // real type variable on the declaring type. - // it is possibly overkill to look up the type variable - ideally the entry in the type parameter list for the - // interface should be the a ref to the type variable in the current type ... but I'm not 100% confident right now. + // it is possibly overkill to look up the type variable - ideally the + // entry in the type parameter list for the + // interface should be the a ref to the type variable in the current + // type ... but I'm not 100% confident right now. for (int i = 0; i < tParms.length; i++) { UnresolvedType tParm = tParms[i]; if (tParm.isTypeVariableReference()) { TypeVariableReference tvrt = (TypeVariableReference) tParm; TypeVariable tv = tvrt.getTypeVariable(); int rank = getRank(tv.getName()); - // -1 probably means it is a reference to a type variable on the outer generic type (see pr129566) + // -1 probably means it is a reference to a type variable on the + // outer generic type (see pr129566) if (rank != -1) { retVal[i] = paramTypes[rank]; } else { @@ -512,8 +573,9 @@ public class ReferenceType extends ResolvedType { } /** - * Returns the position within the set of type variables for this type for the specified type variable name. Returns -1 if there - * is no type variable with the specified name. + * Returns the position within the set of type variables for this type for + * the specified type variable name. Returns -1 if there is no type variable + * with the specified name. */ private int getRank(String tvname) { TypeVariable[] thisTypesTVars = getGenericType().getTypeVariables(); @@ -533,7 +595,8 @@ public class ReferenceType extends ResolvedType { UnresolvedType[] parameters = getTypesForMemberParameterization(); parameterizedMethods = new ResolvedMember[delegateMethods.length]; for (int i = 0; i < delegateMethods.length; i++) { - parameterizedMethods[i] = delegateMethods[i].parameterizedWith(parameters, this, isParameterizedType()); + parameterizedMethods[i] = delegateMethods[i].parameterizedWith( + parameters, this, isParameterizedType()); } return parameterizedMethods; } else { @@ -545,11 +608,13 @@ public class ReferenceType extends ResolvedType { if (parameterizedPointcuts != null) return parameterizedPointcuts; if (isParameterizedType()) { - ResolvedMember[] delegatePointcuts = delegate.getDeclaredPointcuts(); + ResolvedMember[] delegatePointcuts = delegate + .getDeclaredPointcuts(); parameterizedPointcuts = new ResolvedMember[delegatePointcuts.length]; for (int i = 0; i < delegatePointcuts.length; i++) { - parameterizedPointcuts[i] = delegatePointcuts[i].parameterizedWith(getTypesForMemberParameterization(), this, - isParameterizedType()); + parameterizedPointcuts[i] = delegatePointcuts[i] + .parameterizedWith(getTypesForMemberParameterization(), + this, isParameterizedType()); } return parameterizedPointcuts; } else { @@ -590,7 +655,8 @@ public class ReferenceType extends ResolvedType { PerClause pclause = delegate.getPerClause(); if (isParameterizedType()) { // could cache the result here... Map parameterizationMap = getAjMemberParameterizationMap(); - pclause = (PerClause) pclause.parameterizeWith(parameterizationMap, world); + pclause = (PerClause) pclause.parameterizeWith(parameterizationMap, + world); } return pclause; } @@ -605,7 +671,8 @@ public class ReferenceType extends ResolvedType { Map parameterizationMap = getAjMemberParameterizationMap(); for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) { Declare declareStatement = (Declare) iter.next(); - parameterizedDeclares.add(declareStatement.parameterizeWith(parameterizationMap, world)); + parameterizedDeclares.add(declareStatement.parameterizeWith( + parameterizationMap, world)); } declares = parameterizedDeclares; } else { @@ -633,7 +700,8 @@ public class ReferenceType extends ResolvedType { // Map parameterizationMap = getAjMemberParameterizationMap(); // for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) { // ConcreteTypeMunger munger = (ConcreteTypeMunger)iter.next(); - // parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,world)); + // parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap, + // world)); // } // ret = parameterizedTypeMungers; // } else { @@ -659,7 +727,8 @@ public class ReferenceType extends ResolvedType { world.setTypeVariableLookupScope(null); } if (this.isParameterizedType() && ret.isParameterizedType()) { - ret = ret.parameterize(getMemberParameterizationMap()).resolve(getWorld()); + ret = ret.parameterize(getMemberParameterizationMap()).resolve( + getWorld()); } return ret; } @@ -669,10 +738,13 @@ public class ReferenceType extends ResolvedType { } public void setDelegate(ReferenceTypeDelegate delegate) { - // Don't copy from BcelObjectType to EclipseSourceType - the context may be tidied (result null'd) after previous weaving - if (this.delegate != null && !(this.delegate instanceof BcelObjectType) + // Don't copy from BcelObjectType to EclipseSourceType - the context may + // be tidied (result null'd) after previous weaving + if (this.delegate != null + && !(this.delegate instanceof BcelObjectType) && this.delegate.getSourceContext() != SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) - ((AbstractReferenceTypeDelegate) delegate).setSourceContext(this.delegate.getSourceContext()); + ((AbstractReferenceTypeDelegate) delegate) + .setSourceContext(this.delegate.getSourceContext()); this.delegate = delegate; for (Iterator it = this.derivativeTypes.iterator(); it.hasNext();) { ReferenceType dependent = (ReferenceType) it.next(); @@ -744,13 +816,15 @@ public class ReferenceType extends ResolvedType { } /** - * a parameterized signature starts with a "P" in place of the "L", see the comment on signatures in UnresolvedType. + * a parameterized signature starts with a "P" in place of the "L", see the + * comment on signatures in UnresolvedType. * * @param aGenericType * @param someParameters * @return */ - private static String makeParameterizedSignature(ResolvedType aGenericType, ResolvedType[] someParameters) { + private static String makeParameterizedSignature(ResolvedType aGenericType, + ResolvedType[] someParameters) { String rawSignature = aGenericType.getErasureSignature(); StringBuffer ret = new StringBuffer(); ret.append(PARAMETERIZED_TYPE_IDENTIFIER); @@ -763,13 +837,15 @@ public class ReferenceType extends ResolvedType { return ret.toString(); } - private static String makeDeclaredSignature(ResolvedType aGenericType, UnresolvedType[] someParameters) { + private static String makeDeclaredSignature(ResolvedType aGenericType, + UnresolvedType[] someParameters) { StringBuffer ret = new StringBuffer(); String rawSig = aGenericType.getErasureSignature(); ret.append(rawSig.substring(0, rawSig.length() - 1)); ret.append("<"); for (int i = 0; i < someParameters.length; i++) { - ret.append(((ReferenceType) someParameters[i]).getSignatureForAttribute()); + ret.append(((ReferenceType) someParameters[i]) + .getSignatureForAttribute()); } ret.append(">;"); return ret.toString(); diff --git a/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java b/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java index 0f21b25be..a19d5ca67 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java +++ b/weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java @@ -17,55 +17,88 @@ import java.util.Collection; import org.aspectj.weaver.patterns.PerClause; /** - * Abstraction over a type - a reference type is Object and a descendant of Object, other types (int/etc) are - * considered primitive types. Abstract implementation provided by AbstractReferenceTypeDelegate. + * Abstraction over a type - a reference type is Object and a descendant of + * Object, other types (int/etc) are considered primitive types. Abstract + * implementation provided by AbstractReferenceTypeDelegate. */ public interface ReferenceTypeDelegate { - + // TODO asc move to proxy - public void addAnnotation(AnnotationX annotationX); - public void ensureDelegateConsistent(); // Required evil because of mutator methods in delegates :( (see pr85132) - + public void addAnnotation(AnnotationAJ annotationX); + + public void ensureDelegateConsistent(); // Required evil because of mutator + + // methods in delegates :( (see + // pr85132) + public boolean isAspect(); - public boolean isAnnotationStyleAspect(); - public boolean isInterface(); - public boolean isEnum(); - public boolean isAnnotation(); - public String getRetentionPolicy(); - public boolean canAnnotationTargetType(); - public AnnotationTargetKind[] getAnnotationTargetKinds(); - public boolean isAnnotationWithRuntimeRetention(); + + public boolean isAnnotationStyleAspect(); + + public boolean isInterface(); + + public boolean isEnum(); + + public boolean isAnnotation(); + + public String getRetentionPolicy(); + + public boolean canAnnotationTargetType(); + + public AnnotationTargetKind[] getAnnotationTargetKinds(); + + public boolean isAnnotationWithRuntimeRetention(); + public boolean isClass(); + public boolean isGeneric(); + public boolean isAnonymous(); + public boolean isNested(); + public boolean isExposedToWeaver(); - + public boolean hasAnnotation(UnresolvedType ofType); - - public AnnotationX[] getAnnotations(); - public ResolvedType[] getAnnotationTypes(); + + public AnnotationAJ[] getAnnotations(); + + public ResolvedType[] getAnnotationTypes(); + public ResolvedMember[] getDeclaredFields(); - public ResolvedType[] getDeclaredInterfaces(); + + public ResolvedType[] getDeclaredInterfaces(); + public ResolvedMember[] getDeclaredMethods(); + public ResolvedMember[] getDeclaredPointcuts(); + public TypeVariable[] getTypeVariables(); - public PerClause getPerClause(); - public Collection getDeclares() ; + public PerClause getPerClause(); + + public Collection getDeclares(); + public Collection getTypeMungers(); + public Collection getPrivilegedAccesses(); + public int getModifiers(); - public ResolvedType getSuperclass(); + + public ResolvedType getSuperclass(); + public WeaverStateInfo getWeaverState(); + public ReferenceType getResolvedTypeX(); + public boolean doesNotExposeShadowMungers(); - + public ISourceContext getSourceContext(); - + public String getSourcefilename(); - + public String getDeclaredGenericSignature(); + public ResolvedType getOuterClass(); - + } \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java index 2b7ab4e43..3cbf33ecb 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMember.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java @@ -20,7 +20,8 @@ import java.util.Map; import org.aspectj.bridge.ISourceLocation; -public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDeclaringElement { +public interface ResolvedMember extends Member, AnnotatedElement, + TypeVariableDeclaringElement { public static final ResolvedMember[] NONE = new ResolvedMember[0]; @@ -42,13 +43,13 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe public boolean hasAnnotation(UnresolvedType ofType); - public AnnotationX[] getAnnotations(); + public AnnotationAJ[] getAnnotations(); public ResolvedType[] getAnnotationTypes(); public void setAnnotationTypes(UnresolvedType[] annotationtypes); - public void addAnnotation(AnnotationX annotation); + public void addAnnotation(AnnotationAJ annotation); public boolean isBridgeMethod(); @@ -64,7 +65,7 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe public void setParameterNames(String[] names); - public AnnotationX[][] getParameterAnnotations(); + public AnnotationAJ[][] getParameterAnnotations(); public ResolvedType[][] getParameterAnnotationTypes(); @@ -118,26 +119,34 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe public ResolvedMember getBackingGenericMember(); /** - * Get the UnresolvedType for the return type, taking generic signature into account + * Get the UnresolvedType for the return type, taking generic signature into + * account */ public UnresolvedType getGenericReturnType(); /** - * Get the TypeXs of the parameter types, taking generic signature into account + * Get the TypeXs of the parameter types, taking generic signature into + * account */ public UnresolvedType[] getGenericParameterTypes(); - // return a resolved member in which all type variables in the signature of this + // return a resolved member in which all type variables in the signature of + // this // member have been replaced with the given bindings. - // the isParameterized flag tells us whether we are creating a raw type version or not + // the isParameterized flag tells us whether we are creating a raw type + // version or not // if isParameterized List will turn into List (for example), // but if !isParameterized List will turn into List. - public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, + public ResolvedMemberImpl parameterizedWith( + UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized); - // this variant allows for aliases for type variables (i.e. allowing them to have another name) - // this is used for processing ITDs that share type variables with their target generic type - public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, + // this variant allows for aliases for type variables (i.e. allowing them to + // have another name) + // this is used for processing ITDs that share type variables with their + // target generic type + public ResolvedMemberImpl parameterizedWith( + UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized, List aliases); public void setTypeVariables(TypeVariable[] types); @@ -145,7 +154,8 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe public TypeVariable[] getTypeVariables(); // /** - // * If this member is defined by a parameterized super-type, return the erasure + // * If this member is defined by a parameterized super-type, return the + // erasure // * of that member. // * For example: // * interface I { T foo(T aTea); } @@ -160,8 +170,10 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe // public ResolvedMember getErasure(); /** - * Returns true if this member matches the other. The matching takes into account name and parameter types only. When comparing - * parameter types, we allow any type variable to match any other type variable regardless of bounds. + * Returns true if this member matches the other. The matching takes into + * account name and parameter types only. When comparing parameter types, we + * allow any type variable to match any other type variable regardless of + * bounds. */ public boolean matches(ResolvedMember aCandidateMatch); diff --git a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java index 60577604a..dcd2f457c 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java @@ -26,27 +26,32 @@ import java.util.Set; import org.aspectj.bridge.ISourceLocation; /** - * This is the declared member, i.e. it will always correspond to an actual method/... declaration + * This is the declared member, i.e. it will always correspond to an actual + * method/... declaration */ -public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, AnnotatedElement, TypeVariableDeclaringElement, - ResolvedMember { +public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, + AnnotatedElement, TypeVariableDeclaringElement, ResolvedMember { private String[] parameterNames = null; protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE; /** - * if this member is a parameterized version of a member in a generic type, then this field holds a reference to the member we - * parameterize. + * if this member is a parameterized version of a member in a generic type, + * then this field holds a reference to the member we parameterize. */ protected ResolvedMember backingGenericMember = null; protected Set annotationTypes = null; protected ResolvedType[][] parameterAnnotationTypes = null; - // Some members are 'created' to represent other things (for example ITDs). These - // members have their annotations stored elsewhere, and this flag indicates that is + // Some members are 'created' to represent other things (for example ITDs). + // These + // members have their annotations stored elsewhere, and this flag indicates + // that is // the case. It is up to the caller to work out where that is! - // Once determined the caller may choose to stash the annotations in this member... - private boolean isAnnotatedElsewhere = false; // this field is not serialized. + // Once determined the caller may choose to stash the annotations in this + // member... + private boolean isAnnotatedElsewhere = false; // this field is not + // serialized. private boolean isAjSynthetic = false; // generic methods have type variables @@ -57,33 +62,43 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno protected ISourceContext sourceContext = null; // XXX deprecate this in favor of the constructor below - public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, + public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, + int modifiers, UnresolvedType returnType, String name, UnresolvedType[] parameterTypes) { super(kind, declaringType, modifiers, returnType, name, parameterTypes); } - public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, + public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, + int modifiers, UnresolvedType returnType, String name, UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions) { super(kind, declaringType, modifiers, returnType, name, parameterTypes); this.checkedExceptions = checkedExceptions; } - public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name, - UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions, ResolvedMember backingGenericMember) { - this(kind, declaringType, modifiers, returnType, name, parameterTypes, checkedExceptions); + public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, + int modifiers, UnresolvedType returnType, String name, + UnresolvedType[] parameterTypes, + UnresolvedType[] checkedExceptions, + ResolvedMember backingGenericMember) { + this(kind, declaringType, modifiers, returnType, name, parameterTypes, + checkedExceptions); this.backingGenericMember = backingGenericMember; this.isAjSynthetic = backingGenericMember.isAjSynthetic(); } - public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String signature) { + public ResolvedMemberImpl(MemberKind kind, UnresolvedType declaringType, + int modifiers, String name, String signature) { super(kind, declaringType, modifiers, name, signature); } /** - * Compute the full set of signatures for a member. This walks up the hierarchy giving the ResolvedMember in each defining type - * in the hierarchy. A shadowMember can be created with a target type (declaring type) that does not actually define the member. - * This is ok as long as the member is inherited in the declaring type. Each declaring type in the line to the actual declaring - * type is added as an additional signature. For example: + * Compute the full set of signatures for a member. This walks up the + * hierarchy giving the ResolvedMember in each defining type in the + * hierarchy. A shadowMember can be created with a target type (declaring + * type) that does not actually define the member. This is ok as long as the + * member is inherited in the declaring type. Each declaring type in the + * line to the actual declaring type is added as an additional signature. + * For example: * * class A { void foo(); } class B extends A {} * @@ -94,19 +109,26 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno * @param joinPointSignature * @param inAWorld */ - public static JoinPointSignature[] getJoinPointSignatures(Member joinPointSignature, World inAWorld) { + public static JoinPointSignature[] getJoinPointSignatures( + Member joinPointSignature, World inAWorld) { - // Walk up hierarchy creating one member for each type up to and including the + // Walk up hierarchy creating one member for each type up to and + // including the // first defining type - ResolvedType originalDeclaringType = joinPointSignature.getDeclaringType().resolve(inAWorld); - ResolvedMemberImpl firstDefiningMember = (ResolvedMemberImpl) joinPointSignature.resolve(inAWorld); + ResolvedType originalDeclaringType = joinPointSignature + .getDeclaringType().resolve(inAWorld); + ResolvedMemberImpl firstDefiningMember = (ResolvedMemberImpl) joinPointSignature + .resolve(inAWorld); if (firstDefiningMember == null) { return new JoinPointSignature[0]; } - // declaringType can be unresolved if we matched a synthetic member generated by Aj... - // should be fixed elsewhere but add this resolve call on the end for now so that we can + // declaringType can be unresolved if we matched a synthetic member + // generated by Aj... + // should be fixed elsewhere but add this resolve call on the end for + // now so that we can // focus on one problem at a time... - ResolvedType firstDefiningType = firstDefiningMember.getDeclaringType().resolve(inAWorld); + ResolvedType firstDefiningType = firstDefiningMember.getDeclaringType() + .resolve(inAWorld); if (firstDefiningType != originalDeclaringType) { if (joinPointSignature.getKind() == Member.CONSTRUCTOR) { return new JoinPointSignature[0]; @@ -117,23 +139,30 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } List declaringTypes = new ArrayList(); - accumulateTypesInBetween(originalDeclaringType, firstDefiningType, declaringTypes); + accumulateTypesInBetween(originalDeclaringType, firstDefiningType, + declaringTypes); Set memberSignatures = new HashSet(); for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { ResolvedType declaringType = (ResolvedType) iter.next(); - ResolvedMember member = firstDefiningMember.withSubstituteDeclaringType(declaringType); + ResolvedMember member = firstDefiningMember + .withSubstituteDeclaringType(declaringType); memberSignatures.add(member); } if (shouldWalkUpHierarchyFor(firstDefiningMember)) { - // now walk up the hierarchy from the firstDefiningMember and include the signature for - // every type between the firstDefiningMember and the root defining member. - Iterator superTypeIterator = firstDefiningType.getDirectSupertypes(); + // now walk up the hierarchy from the firstDefiningMember and + // include the signature for + // every type between the firstDefiningMember and the root defining + // member. + Iterator superTypeIterator = firstDefiningType + .getDirectSupertypes(); List typesAlreadyVisited = new ArrayList(); - accumulateMembersMatching(firstDefiningMember, superTypeIterator, typesAlreadyVisited, memberSignatures); + accumulateMembersMatching(firstDefiningMember, superTypeIterator, + typesAlreadyVisited, memberSignatures); } - JoinPointSignature[] ret = new JoinPointSignature[memberSignatures.size()]; + JoinPointSignature[] ret = new JoinPointSignature[memberSignatures + .size()]; memberSignatures.toArray(ret); return ret; } @@ -149,9 +178,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * Build a list containing every type between subtype and supertype, inclusively. + * Build a list containing every type between subtype and supertype, + * inclusively. */ - private static void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List types) { + private static void accumulateTypesInBetween(ResolvedType subType, + ResolvedType superType, List types) { types.add(subType); if (subType == superType) { return; @@ -166,48 +197,67 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * We have a resolved member, possibly with type parameter references as parameters or return type. We need to find all its - * ancestor members. When doing this, a type parameter matches regardless of bounds (bounds can be narrowed down the hierarchy). + * We have a resolved member, possibly with type parameter references as + * parameters or return type. We need to find all its ancestor members. When + * doing this, a type parameter matches regardless of bounds (bounds can be + * narrowed down the hierarchy). */ - private static void accumulateMembersMatching(ResolvedMemberImpl memberToMatch, Iterator typesToLookIn, + private static void accumulateMembersMatching( + ResolvedMemberImpl memberToMatch, Iterator typesToLookIn, List typesAlreadyVisited, Set foundMembers) { while (typesToLookIn.hasNext()) { ResolvedType toLookIn = (ResolvedType) typesToLookIn.next(); if (!typesAlreadyVisited.contains(toLookIn)) { typesAlreadyVisited.add(toLookIn); - ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn.lookupResolvedMember(memberToMatch, true); - if (foundMember != null && isVisibleTo(memberToMatch, foundMember)) { + ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn + .lookupResolvedMember(memberToMatch, true); + if (foundMember != null + && isVisibleTo(memberToMatch, foundMember)) { List declaringTypes = new ArrayList(); - // declaring type can be unresolved if the member can from an ITD... - ResolvedType resolvedDeclaringType = foundMember.getDeclaringType().resolve(toLookIn.getWorld()); - accumulateTypesInBetween(toLookIn, resolvedDeclaringType, declaringTypes); - for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { + // declaring type can be unresolved if the member can from + // an ITD... + ResolvedType resolvedDeclaringType = foundMember + .getDeclaringType().resolve(toLookIn.getWorld()); + accumulateTypesInBetween(toLookIn, resolvedDeclaringType, + declaringTypes); + for (Iterator iter = declaringTypes.iterator(); iter + .hasNext();) { ResolvedType declaringType = (ResolvedType) iter.next(); // typesAlreadyVisited.add(declaringType); - ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType); + ResolvedMember member = foundMember + .withSubstituteDeclaringType(declaringType); foundMembers.add(member); } - if (toLookIn.isParameterizedType() && (foundMember.backingGenericMember != null)) { - foundMembers.add(new JoinPointSignature(foundMember.backingGenericMember, foundMember.declaringType - .resolve(toLookIn.getWorld()))); + if (toLookIn.isParameterizedType() + && (foundMember.backingGenericMember != null)) { + foundMembers.add(new JoinPointSignature( + foundMember.backingGenericMember, + foundMember.declaringType.resolve(toLookIn + .getWorld()))); } - accumulateMembersMatching(foundMember, toLookIn.getDirectSupertypes(), typesAlreadyVisited, foundMembers); - // if this was a parameterized type, look in the generic type that backs it too + accumulateMembersMatching(foundMember, toLookIn + .getDirectSupertypes(), typesAlreadyVisited, + foundMembers); + // if this was a parameterized type, look in the generic + // type that backs it too } } } } /** - * Returns true if the parent member is visible to the child member In the same declaring type this is always true, otherwise if - * parent is private it is false. + * Returns true if the parent member is visible to the child member In the + * same declaring type this is always true, otherwise if parent is private + * it is false. * * @param childMember * @param parentMember * @return */ - private static boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) { - if (childMember.getDeclaringType().equals(parentMember.getDeclaringType())) + private static boolean isVisibleTo(ResolvedMember childMember, + ResolvedMember parentMember) { + if (childMember.getDeclaringType().equals( + parentMember.getDeclaringType())) return true; if (Modifier.isPrivate(parentMember.getModifiers())) { return false; @@ -254,12 +304,15 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * Check if this member has an annotation of the specified type. If the member has a backing generic member then this member - * represents a parameterization of a member in a generic type and the annotations available on the backing generic member - * should be used. + * Check if this member has an annotation of the specified type. If the + * member has a backing generic member then this member represents a + * parameterization of a member in a generic type and the annotations + * available on the backing generic member should be used. * - * @param ofType the type of the annotation being searched for - * @return true if the annotation is found on this member or its backing generic member + * @param ofType + * the type of the annotation being searched for + * @return true if the annotation is found on this member or its backing + * generic member */ public boolean hasAnnotation(UnresolvedType ofType) { // The ctors don't allow annotations to be specified ... yet - but @@ -268,7 +321,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno // this type - BcelField/BcelMethod if (backingGenericMember != null) { if (annotationTypes != null) { - throw new BCException("Unexpectedly found a backing generic member and a local set of annotations"); + throw new BCException( + "Unexpectedly found a backing generic member and a local set of annotations"); } return backingGenericMember.hasAnnotation(ofType); } @@ -285,7 +339,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno // this type - BcelField/BcelMethod if (backingGenericMember != null) { if (annotationTypes != null) { - throw new BCException("Unexpectedly found a backing generic member and a local set of annotations"); + throw new BCException( + "Unexpectedly found a backing generic member and a local set of annotations"); } return backingGenericMember.getAnnotationTypes(); } @@ -299,7 +354,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno "You should resolve this member and call getAnnotationDefaultValue() on the result..."); } - public AnnotationX[] getAnnotations() { + public AnnotationAJ[] getAnnotations() { if (backingGenericMember != null) return backingGenericMember.getAnnotations(); return super.getAnnotations(); @@ -320,22 +375,25 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return parameterAnnotationTypes; } - public AnnotationX[][] getParameterAnnotations() { + public AnnotationAJ[][] getParameterAnnotations() { if (backingGenericMember != null) return backingGenericMember.getParameterAnnotations(); - throw new BCException("Cannot return parameter annotations for a " + this.getClass().getName() + " member"); + throw new BCException("Cannot return parameter annotations for a " + + this.getClass().getName() + " member"); // return super.getParameterAnnotations(); } - public void addAnnotation(AnnotationX annotation) { - // FIXME asc only allows for annotation types, not instances - should it? + public void addAnnotation(AnnotationAJ annotation) { + // FIXME asc only allows for annotation types, not instances - should + // it? if (annotationTypes == null) annotationTypes = new HashSet(); - annotationTypes.add(annotation.getSignature()); + annotationTypes.add(annotation.getType()); } public boolean isBridgeMethod() { - return (modifiers & Constants.ACC_BRIDGE) != 0 && getKind().equals(METHOD); + return (modifiers & Constants.ACC_BRIDGE) != 0 + && getKind().equals(METHOD); } public boolean isVarargsMethod() { @@ -347,7 +405,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } public boolean isSynthetic() { - // See Bcelmethod.isSynthetic() which takes account of preJava5 Synthetic modifier + // See Bcelmethod.isSynthetic() which takes account of preJava5 + // Synthetic modifier return (modifiers & 4096) != 0; // do we know better? } @@ -387,17 +446,22 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * Return the member generic signature that would be suitable for inclusion in a class file Signature attribute. For: - * List getThem(T t) {} we would create: (TT;)Ljava/util/List;; + * Return the member generic signature that would be suitable for inclusion + * in a class file Signature attribute. For: List getThem(T t) + * {} we would create: + * (TT;)Ljava/util/List;; * - * @return the generic signature for the member that could be inserted into a class file + * @return the generic signature for the member that could be inserted into + * a class file */ public String getSignatureForAttribute() { StringBuffer sb = new StringBuffer(); if (typeVariables != null) { sb.append("<"); for (int i = 0; i < typeVariables.length; i++) { - sb.append(typeVariables[i].getSignatureForAttribute()); // need a 'getSignatureForAttribute()' + sb.append(typeVariables[i].getSignatureForAttribute()); // need + // a + // 'getSignatureForAttribute()' } sb.append(">"); } @@ -430,18 +494,20 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return sb.toString(); } - public static void writeArray(ResolvedMember[] members, DataOutputStream s) throws IOException { + public static void writeArray(ResolvedMember[] members, DataOutputStream s) + throws IOException { s.writeInt(members.length); for (int i = 0, len = members.length; i < len; i++) { members[i].write(s); } } - public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) + public static ResolvedMemberImpl readResolvedMember( + VersionedDataInputStream s, ISourceContext sourceContext) throws IOException { - ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(), s.readUTF(), s - .readUTF()); + ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), + UnresolvedType.read(s), s.readInt(), s.readUTF(), s.readUTF()); m.checkedExceptions = UnresolvedType.readArray(s); m.start = s.readInt(); @@ -470,9 +536,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno int ps = s.readInt(); UnresolvedType[] params = new UnresolvedType[ps]; for (int i = 0; i < params.length; i++) { - params[i] = TypeFactory.createTypeFromSignature(s.readUTF()); + params[i] = TypeFactory.createTypeFromSignature(s + .readUTF()); } - UnresolvedType rt = TypeFactory.createTypeFromSignature(s.readUTF()); + UnresolvedType rt = TypeFactory.createTypeFromSignature(s + .readUTF()); m.parameterTypes = params; m.returnType = rt; } @@ -481,7 +549,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return m; } - public static ResolvedMember[] readResolvedMemberArray(VersionedDataInputStream s, ISourceContext context) throws IOException { + public static ResolvedMember[] readResolvedMemberArray( + VersionedDataInputStream s, ISourceContext context) + throws IOException { int len = s.readInt(); ResolvedMember[] members = new ResolvedMember[len]; for (int i = 0; i < len; i++) { @@ -490,7 +560,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return members; } - // OPTIMIZE dont like how resolve(world) on ResolvedMemberImpl does something different to world.resolve(member) + // OPTIMIZE dont like how resolve(world) on ResolvedMemberImpl does + // something different to world.resolve(member) public ResolvedMember resolve(World world) { // make sure all the pieces of a resolvedmember really are resolved try { @@ -510,7 +581,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } declaringType = declaringType.resolve(world); if (declaringType.isRawType()) - declaringType = ((ReferenceType) declaringType).getGenericType(); + declaringType = ((ReferenceType) declaringType) + .getGenericType(); if (parameterTypes != null && parameterTypes.length > 0) { for (int i = 0; i < parameterTypes.length; i++) { @@ -602,7 +674,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno public boolean isVisible(ResolvedType fromType) { World world = fromType.getWorld(); - return ResolvedType.isVisible(getModifiers(), getDeclaringType().resolve(world), fromType); + return ResolvedType.isVisible(getModifiers(), getDeclaringType() + .resolve(world), fromType); } public void setCheckedExceptions(UnresolvedType[] checkedExceptions) { @@ -618,70 +691,89 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * Get the UnresolvedType for the return type, taking generic signature into account + * Get the UnresolvedType for the return type, taking generic signature into + * account */ public UnresolvedType getGenericReturnType() { return getReturnType(); } /** - * Get the TypeXs of the parameter types, taking generic signature into account + * Get the TypeXs of the parameter types, taking generic signature into + * account */ public UnresolvedType[] getGenericParameterTypes() { return getParameterTypes(); } - public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, + public ResolvedMemberImpl parameterizedWith( + UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized) { - return parameterizedWith(typeParameters, newDeclaringType, isParameterized, null); + return parameterizedWith(typeParameters, newDeclaringType, + isParameterized, null); } /** - * Return a resolvedmember in which all the type variables in the signature have been replaced with the given bindings. The - * 'isParameterized' flag tells us whether we are creating a raw type version or not. if (isParameterized) then List will - * turn into List (for example) - if (!isParameterized) then List will turn into List. + * Return a resolvedmember in which all the type variables in the signature + * have been replaced with the given bindings. The 'isParameterized' flag + * tells us whether we are creating a raw type version or not. if + * (isParameterized) then List will turn into List (for example) + * - if (!isParameterized) then List will turn into List. */ - public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, + public ResolvedMemberImpl parameterizedWith( + UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized, List aliases) { if (// isParameterized && <-- might need this bit... !getDeclaringType().isGenericType()) { - throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: " + getDeclaringType() - + " kind(" + getDeclaringType().typeKind + ")"); + throw new IllegalStateException( + "Can't ask to parameterize a member of non-generic type: " + + getDeclaringType() + " kind(" + + getDeclaringType().typeKind + ")"); } TypeVariable[] typeVariables = getDeclaringType().getTypeVariables(); if (isParameterized && (typeVariables.length != typeParameters.length)) { - throw new IllegalStateException("Wrong number of type parameters supplied"); + throw new IllegalStateException( + "Wrong number of type parameters supplied"); } Map typeMap = new HashMap(); - boolean typeParametersSupplied = typeParameters != null && typeParameters.length > 0; + boolean typeParametersSupplied = typeParameters != null + && typeParameters.length > 0; if (typeVariables != null) { - // If no 'replacements' were supplied in the typeParameters array then collapse + // If no 'replacements' were supplied in the typeParameters array + // then collapse // type variables to their first bound. for (int i = 0; i < typeVariables.length; i++) { - UnresolvedType ut = (!typeParametersSupplied ? typeVariables[i].getFirstBound() : typeParameters[i]); + UnresolvedType ut = (!typeParametersSupplied ? typeVariables[i] + .getFirstBound() : typeParameters[i]); typeMap.put(typeVariables[i].getName(), ut); } } - // For ITDs on generic types that use type variables from the target type, the aliases - // record the alternative names used throughout the ITD expression that must map to + // For ITDs on generic types that use type variables from the target + // type, the aliases + // record the alternative names used throughout the ITD expression that + // must map to // the same value as the type variables real name. if (aliases != null) { int posn = 0; for (Iterator iter = aliases.iterator(); iter.hasNext();) { String typeVariableAlias = (String) iter.next(); - typeMap.put(typeVariableAlias, (!typeParametersSupplied ? typeVariables[posn].getFirstBound() - : typeParameters[posn])); + typeMap.put(typeVariableAlias, + (!typeParametersSupplied ? typeVariables[posn] + .getFirstBound() : typeParameters[posn])); posn++; } } - UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(), typeMap, isParameterized); + UnresolvedType parameterizedReturnType = parameterize( + getGenericReturnType(), typeMap, isParameterized); UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length]; UnresolvedType[] genericParameterTypes = getGenericParameterTypes(); for (int i = 0; i < parameterizedParameterTypes.length; i++) { - parameterizedParameterTypes[i] = parameterize(genericParameterTypes[i], typeMap, isParameterized); + parameterizedParameterTypes[i] = parameterize( + genericParameterTypes[i], typeMap, isParameterized); } - ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(), newDeclaringType, getModifiers(), parameterizedReturnType, + ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(), + newDeclaringType, getModifiers(), parameterizedReturnType, getName(), parameterizedParameterTypes, getExceptions(), this); ret.setTypeVariables(getTypeVariables()); ret.setSourceContext(getSourceContext()); @@ -691,51 +783,67 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * Replace occurrences of type variables in the signature with values contained in the map. The map is of the form - * A=String,B=Integer and so a signature List Foo.m(B i) {} would become List Foo.m(Integer i) {} + * Replace occurrences of type variables in the signature with values + * contained in the map. The map is of the form A=String,B=Integer and so a + * signature List Foo.m(B i) {} would become List Foo.m(Integer + * i) {} */ public ResolvedMember parameterizedWith(Map m, World w) { // if (//isParameterized && <-- might need this bit... // !getDeclaringType().isGenericType()) { - // throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+ + // throw new IllegalStateException( + // "Can't ask to parameterize a member of non-generic type: " + // +getDeclaringType()+" kind("+ // getDeclaringType().typeKind+")"); // } declaringType = declaringType.resolve(w); if (declaringType.isRawType()) declaringType = ((ResolvedType) declaringType).getGenericType(); // TypeVariable[] typeVariables = getDeclaringType().getTypeVariables(); - // if (isParameterized && (typeVariables.length != typeParameters.length)) { - // throw new IllegalStateException("Wrong number of type parameters supplied"); + // if (isParameterized && (typeVariables.length != + // typeParameters.length)) { + // throw new + // IllegalStateException("Wrong number of type parameters supplied"); // } // Map typeMap = new HashMap(); - // boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0; + // boolean typeParametersSupplied = typeParameters!=null && + // typeParameters.length>0; // if (typeVariables!=null) { - // // If no 'replacements' were supplied in the typeParameters array then collapse + // // If no 'replacements' were supplied in the typeParameters array + // then collapse // // type variables to their first bound. // for (int i = 0; i < typeVariables.length; i++) { - // UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]); + // UnresolvedType ut = + // (!typeParametersSupplied?typeVariables[i].getFirstBound + // ():typeParameters[i]); // typeMap.put(typeVariables[i].getName(),ut); // } // } - // // For ITDs on generic types that use type variables from the target type, the aliases - // // record the alternative names used throughout the ITD expression that must map to + // // For ITDs on generic types that use type variables from the target + // type, the aliases + // // record the alternative names used throughout the ITD expression + // that must map to // // the same value as the type variables real name. // if (aliases!=null) { // int posn = 0; // for (Iterator iter = aliases.iterator(); iter.hasNext();) { // String typeVariableAlias = (String) iter.next(); - // typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn])); + // typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[ + // posn].getFirstBound():typeParameters[posn])); // posn++; // } // } - UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(), m, true, w); + UnresolvedType parameterizedReturnType = parameterize( + getGenericReturnType(), m, true, w); UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length]; UnresolvedType[] genericParameterTypes = getGenericParameterTypes(); for (int i = 0; i < parameterizedParameterTypes.length; i++) { - parameterizedParameterTypes[i] = parameterize(genericParameterTypes[i], m, true, w); + parameterizedParameterTypes[i] = parameterize( + genericParameterTypes[i], m, true, w); } - ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(), declaringType, getModifiers(), parameterizedReturnType, + ResolvedMemberImpl ret = new ResolvedMemberImpl(getKind(), + declaringType, getModifiers(), parameterizedReturnType, getName(), parameterizedParameterTypes, getExceptions(), this); ret.setTypeVariables(getTypeVariables()); ret.setSourceContext(getSourceContext()); @@ -752,15 +860,19 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return typeVariables; } - protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) { + protected UnresolvedType parameterize(UnresolvedType aType, + Map typeVariableMap, boolean inParameterizedType) { return parameterize(aType, typeVariableMap, inParameterizedType, null); } - protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType, World w) { + protected UnresolvedType parameterize(UnresolvedType aType, + Map typeVariableMap, boolean inParameterizedType, World w) { if (aType instanceof TypeVariableReference) { - String variableName = ((TypeVariableReference) aType).getTypeVariable().getName(); + String variableName = ((TypeVariableReference) aType) + .getTypeVariable().getName(); if (!typeVariableMap.containsKey(variableName)) { - return aType; // if the type variable comes from the method (and not the type) thats OK + return aType; // if the type variable comes from the method (and + // not the type) thats OK } return (UnresolvedType) typeVariableMap.get(variableName); } else if (aType.isParameterizedType()) { @@ -772,7 +884,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno if (w != null) aType = aType.resolve(w); else { - aType = aType.resolve(((ResolvedType) getDeclaringType()).getWorld()); + aType = aType.resolve(((ResolvedType) getDeclaringType()) + .getWorld()); } // } return aType.parameterize(typeVariableMap); @@ -785,19 +898,22 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno String sig = aType.getSignature(); while (sig.charAt(dims) == '[') dims++; - UnresolvedType componentSig = UnresolvedType.forSignature(sig.substring(dims)); - UnresolvedType arrayType = ResolvedType.makeArray(parameterize(componentSig, typeVariableMap, inParameterizedType), - dims); + UnresolvedType componentSig = UnresolvedType.forSignature(sig + .substring(dims)); + UnresolvedType arrayType = ResolvedType.makeArray(parameterize( + componentSig, typeVariableMap, inParameterizedType), dims); return arrayType; } return aType; } /** - * If this member is defined by a parameterized super-type, return the erasure of that member. For example: interface I { T - * foo(T aTea); } class C implements I { String foo(String aString) { return "something"; } } The resolved member for - * C.foo has signature String foo(String). The erasure of that member is Object foo(Object) -- use upper bound of type variable. - * A type is a supertype of itself. + * If this member is defined by a parameterized super-type, return the + * erasure of that member. For example: interface I { T foo(T aTea); } + * class C implements I { String foo(String aString) { return + * "something"; } } The resolved member for C.foo has signature String + * foo(String). The erasure of that member is Object foo(Object) -- use + * upper bound of type variable. A type is a supertype of itself. */ // public ResolvedMember getErasure() { // if (calculatedMyErasure) return myErasure; @@ -809,14 +925,17 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno // } else { // // we have one or more parameterized super types. // // this member may be defined by one of them... we need to find out. - // Collection declaringTypes = this.getDeclaringTypes(resolvedDeclaringType.getWorld()); + // Collection declaringTypes = + // this.getDeclaringTypes(resolvedDeclaringType.getWorld()); // for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) { // ResolvedType aDeclaringType = (ResolvedType) iter.next(); // if (aDeclaringType.isParameterizedType()) { // // we've found the (a?) parameterized type that defines this member. // // now get the erasure of it - // ResolvedMemberImpl matchingMember = (ResolvedMemberImpl) aDeclaringType.lookupMemberNoSupers(this); - // if (matchingMember != null && matchingMember.backingGenericMember != null) { + // ResolvedMemberImpl matchingMember = (ResolvedMemberImpl) + // aDeclaringType.lookupMemberNoSupers(this); + // if (matchingMember != null && matchingMember.backingGenericMember != + // null) { // myErasure = matchingMember.backingGenericMember; // return myErasure; // } @@ -837,8 +956,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * For ITDs, we use the default factory methods to build a resolved member, then alter a couple of characteristics using this - * method - this is safe. + * For ITDs, we use the default factory methods to build a resolved member, + * then alter a couple of characteristics using this method - this is safe. */ public void resetName(String newName) { this.name = newName; @@ -857,41 +976,49 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno } /** - * Returns a copy of this member but with the declaring type swapped. Copy only needs to be shallow. + * Returns a copy of this member but with the declaring type swapped. Copy + * only needs to be shallow. * * @param newDeclaringType */ - public JoinPointSignature withSubstituteDeclaringType(ResolvedType newDeclaringType) { + public JoinPointSignature withSubstituteDeclaringType( + ResolvedType newDeclaringType) { JoinPointSignature ret = new JoinPointSignature(this, newDeclaringType); return ret; } /** - * Returns true if this member matches the other. The matching takes into account name and parameter types only. When comparing - * parameter types, we allow any type variable to match any other type variable regardless of bounds. + * Returns true if this member matches the other. The matching takes into + * account name and parameter types only. When comparing parameter types, we + * allow any type variable to match any other type variable regardless of + * bounds. */ public boolean matches(ResolvedMember aCandidateMatch) { ResolvedMemberImpl candidateMatchImpl = (ResolvedMemberImpl) aCandidateMatch; if (!getName().equals(aCandidateMatch.getName())) return false; UnresolvedType[] myParameterTypes = getGenericParameterTypes(); - UnresolvedType[] candidateParameterTypes = aCandidateMatch.getGenericParameterTypes(); + UnresolvedType[] candidateParameterTypes = aCandidateMatch + .getGenericParameterTypes(); if (myParameterTypes.length != candidateParameterTypes.length) return false; String myParameterSignature = getParameterSigWithBoundsRemoved(); - String candidateParameterSignature = candidateMatchImpl.getParameterSigWithBoundsRemoved(); + String candidateParameterSignature = candidateMatchImpl + .getParameterSigWithBoundsRemoved(); if (myParameterSignature.equals(candidateParameterSignature)) { return true; } else { // try erasure myParameterSignature = getParameterSignatureErased(); - candidateParameterSignature = candidateMatchImpl.getParameterSignatureErased(); + candidateParameterSignature = candidateMatchImpl + .getParameterSignatureErased(); return myParameterSignature.equals(candidateParameterSignature); } } /** - * converts e.g. .... List to just Ljava/util/List; whereas the full signature would be + * converts e.g. .... List to just Ljava/util/List; + * whereas the full signature would be * Ljava/util/List; */ private String myParameterSignatureWithBoundsRemoved = null; @@ -900,7 +1027,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno */ private String myParameterSignatureErasure = null; - // does NOT produce a meaningful java signature, but does give a unique string suitable for + // does NOT produce a meaningful java signature, but does give a unique + // string suitable for // comparison. private String getParameterSigWithBoundsRemoved() { if (myParameterSignatureWithBoundsRemoved != null) @@ -908,15 +1036,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno StringBuffer sig = new StringBuffer(); UnresolvedType[] myParameterTypes = getGenericParameterTypes(); for (int i = 0; i < myParameterTypes.length; i++) { - appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig, new HashSet()); + appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig, + new HashSet()); } myParameterSignatureWithBoundsRemoved = sig.toString(); return myParameterSignatureWithBoundsRemoved; } /** - * Return the erased form of the signature with bounds collapsed for type variables, etc. Does not include the return type, @see - * getParam + * Return the erased form of the signature with bounds collapsed for type + * variables, etc. Does not include the return type, @see getParam */ public String getParameterSignatureErased() { if (myParameterSignatureErasure != null) @@ -945,9 +1074,11 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return sb.toString(); } - // does NOT produce a meaningful java signature, but does give a unique string suitable for + // does NOT produce a meaningful java signature, but does give a unique + // string suitable for // comparison. - public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer, Set alreadyUsedTypeVars) { + public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, + StringBuffer toBuffer, Set alreadyUsedTypeVars) { if (aType.isTypeVariableReference()) { TypeVariableReferenceType typeVariableRT = (TypeVariableReferenceType) aType; // pr204505 @@ -955,14 +1086,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno toBuffer.append("..."); } else { alreadyUsedTypeVars.add(aType); - appendSigWithTypeVarBoundsRemoved(typeVariableRT.getUpperBound(), toBuffer, alreadyUsedTypeVars); + appendSigWithTypeVarBoundsRemoved(typeVariableRT + .getUpperBound(), toBuffer, alreadyUsedTypeVars); } // toBuffer.append("T;"); } else if (aType.isParameterizedType()) { toBuffer.append(aType.getRawType().getSignature()); toBuffer.append("<"); for (int i = 0; i < aType.getTypeParameters().length; i++) { - appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer, alreadyUsedTypeVars); + appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], + toBuffer, alreadyUsedTypeVars); } toBuffer.append(">;"); } else { @@ -979,11 +1112,14 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno // modifiers int mods = modifiers; if ((mods & 4096) > 0) - mods = mods - 4096; // remove synthetic (added in the ASM case but not in the BCEL case...) + mods = mods - 4096; // remove synthetic (added in the ASM case but + // not in the BCEL case...) if ((mods & 512) > 0) - mods = mods - 512; // remove interface (added in the BCEL case but not in the ASM case...) + mods = mods - 512; // remove interface (added in the BCEL case but + // not in the ASM case...) if ((mods & 131072) > 0) - mods = mods - 131072; // remove deprecated (added in the ASM case but not in the BCEL case...) + mods = mods - 131072; // remove deprecated (added in the ASM case + // but not in the BCEL case...) String modsStr = Modifier.toString(mods); if (modsStr.length() != 0) r.append(modsStr).append("(" + mods + ")").append(" "); @@ -1013,7 +1149,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno if (kind != FIELD) { r.append("("); UnresolvedType[] params = getGenericParameterTypes(); - boolean parameterNamesExist = showParameterNames && parameterNames != null && parameterNames.length == params.length; + boolean parameterNamesExist = showParameterNames + && parameterNames != null + && parameterNames.length == params.length; if (params.length != 0) { for (int i = 0, len = params.length; i < len; i++) { if (i > 0) @@ -1028,7 +1166,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return r.toString(); } - // SECRETAPI - controlling whether parameter names come out in the debug string (for testing purposes) + // SECRETAPI - controlling whether parameter names come out in the debug + // string (for testing purposes) public static boolean showParameterNames = true; public String toGenericString() { @@ -1085,14 +1224,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno // check the declaring type! return declaringType.getTypeVariableNamed(name); - // Do generic aspects with ITDs that share type variables with the aspect and the target type and have their own tvars cause + // Do generic aspects with ITDs that share type variables with the + // aspect and the target type and have their own tvars cause // this to be messier? } public void evictWeavingState() { } - public AnnotationX getAnnotationOfType(UnresolvedType ofType) { - throw new UnsupportedOperationException("You should resolve this member and call getAnnotationOfType() on the result..."); + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { + throw new UnsupportedOperationException( + "You should resolve this member and call getAnnotationOfType() on the result..."); } } diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index d61ecfe20..c9c862ab2 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -33,12 +33,14 @@ import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.patterns.Declare; import org.aspectj.weaver.patterns.PerClause; -public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement { +public abstract class ResolvedType extends UnresolvedType implements + AnnotatedElement { public static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0]; public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P"; - // Set during a type pattern match call - this currently used to hold the annotations + // Set during a type pattern match call - this currently used to hold the + // annotations // that may be attached to a type when it used as a parameter public ResolvedType[] temporaryAnnotationTypes; private ResolvedType[] resolvedTypeParams; @@ -51,7 +53,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl this.world = world; } - protected ResolvedType(String signature, String signatureErasure, World world) { + protected ResolvedType(String signature, String signatureErasure, + World world) { super(signature, signatureErasure); this.world = world; } @@ -59,8 +62,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // ---- things that don't require a world /** - * Returns an iterator through ResolvedType objects representing all the direct supertypes of this type. That is, through the - * superclass, if any, and all declared interfaces. + * Returns an iterator through ResolvedType objects representing all the + * direct supertypes of this type. That is, through the superclass, if any, + * and all declared interfaces. */ public final Iterator getDirectSupertypes() { Iterator ifacesIterator = Iterators.array(getDeclaredInterfaces()); @@ -81,27 +85,32 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public abstract ResolvedMember[] getDeclaredPointcuts(); /** - * Returns a ResolvedType object representing the superclass of this type, or null. If this represents a java.lang.Object, a - * primitive type, or void, this method returns null. + * Returns a ResolvedType object representing the superclass of this type, + * or null. If this represents a java.lang.Object, a primitive type, or + * void, this method returns null. */ public abstract ResolvedType getSuperclass(); /** - * Returns the modifiers for this type.

See {@link Class#getModifiers()} for a description of the weirdness of this methods - * on primitives and arrays. + * Returns the modifiers for this type.

See + * {@link Class#getModifiers()} for a description of the weirdness of this + * methods on primitives and arrays. * - * @param world the {@link World} in which the lookup is made. + * @param world + * the {@link World} in which the lookup is made. * @return an int representing the modifiers for this type * @see java.lang.reflect.Modifier */ public abstract int getModifiers(); - // return true if this resolved type couldn't be found (but we know it's name maybe) + // return true if this resolved type couldn't be found (but we know it's + // name maybe) public boolean isMissing() { return false; } - // FIXME asc I wonder if in some circumstances MissingWithKnownSignature should not be considered + // FIXME asc I wonder if in some circumstances MissingWithKnownSignature + // should not be considered // 'really' missing as some code can continue based solely on the signature public static boolean isMissing(UnresolvedType unresolved) { if (unresolved instanceof ResolvedType) { @@ -115,7 +124,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return EMPTY_RESOLVED_TYPE_ARRAY; } - public AnnotationX getAnnotationOfType(UnresolvedType ofType) { + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { return null; } @@ -169,20 +178,22 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // ---- difficult things /** - * returns an iterator through all of the fields of this type, in order for checking from JVM spec 2ed 5.4.3.2. This means that - * the order is

+ * returns an iterator through all of the fields of this type, in order for + * checking from JVM spec 2ed 5.4.3.2. This means that the order is

*

    *
  • fields from current class
  • *
  • recur into direct superinterfaces
  • *
  • recur into superclass
  • *
- *

We keep a hashSet of interfaces that we've visited so we don't spiral out into 2^n land. + *

We keep a hashSet of interfaces that we've visited so we don't + * spiral out into 2^n land. */ public Iterator getFields() { final Iterators.Filter dupFilter = Iterators.dupFilter(); Iterators.Getter typeGetter = new Iterators.Getter() { public Iterator get(Object o) { - return dupFilter.filter(((ResolvedType) o).getDirectSupertypes()); + return dupFilter.filter(((ResolvedType) o) + .getDirectSupertypes()); } }; Iterators.Getter fieldGetter = new Iterators.Getter() { @@ -190,25 +201,29 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return Iterators.array(((ResolvedType) o).getDeclaredFields()); } }; - return Iterators.mapOver(Iterators.recur(this, typeGetter), fieldGetter); + return Iterators + .mapOver(Iterators.recur(this, typeGetter), fieldGetter); } /** - * returns an iterator through all of the methods of this type, in order for checking from JVM spec 2ed 5.4.3.3. This means that - * the order is

+ * returns an iterator through all of the methods of this type, in order for + * checking from JVM spec 2ed 5.4.3.3. This means that the order is

*

    *
  • methods from current class
  • *
  • recur into superclass, all the way up, not touching interfaces
  • *
  • recur into all superinterfaces, in some unspecified order
  • *
- *

We keep a hashSet of interfaces that we've visited so we don't spiral out into 2^n land. NOTE: Take a look at the - * javadoc on getMethodsWithoutIterator() to see if you are sensitive to a quirk in getMethods() + *

We keep a hashSet of interfaces that we've visited so we don't + * spiral out into 2^n land. NOTE: Take a look at the javadoc on + * getMethodsWithoutIterator() to see if you are sensitive to a quirk in + * getMethods() */ public Iterator getMethods() { final Iterators.Filter dupFilter = Iterators.dupFilter(); Iterators.Getter ifaceGetter = new Iterators.Getter() { public Iterator get(Object o) { - return dupFilter.filter(Iterators.array(((ResolvedType) o).getDeclaredInterfaces())); + return dupFilter.filter(Iterators.array(((ResolvedType) o) + .getDeclaredInterfaces())); } }; Iterators.Getter methodGetter = new Iterators.Getter() { @@ -236,26 +251,35 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Return a list of methods, first those declared on this class, then those declared on the superclass (recurse) and then those - * declared on the superinterfaces. The getMethods() call above doesn't quite work the same as it will (through the iterator) - * return methods declared on *this* class twice, once at the start and once at the end - I couldn't debug that problem, so - * created this alternative. + * Return a list of methods, first those declared on this class, then those + * declared on the superclass (recurse) and then those declared on the + * superinterfaces. The getMethods() call above doesn't quite work the same + * as it will (through the iterator) return methods declared on *this* class + * twice, once at the start and once at the end - I couldn't debug that + * problem, so created this alternative. */ - public List getMethodsWithoutIterator(boolean includeITDs, boolean allowMissing) { + public List getMethodsWithoutIterator(boolean includeITDs, + boolean allowMissing) { List methods = new ArrayList(); Set knowninterfaces = new HashSet(); addAndRecurse(knowninterfaces, methods, this, includeITDs, allowMissing); return methods; } - private void addAndRecurse(Set knowninterfaces, List collector, ResolvedType rtx, boolean includeITDs, boolean allowMissing) { - collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the methods declared on this type + private void addAndRecurse(Set knowninterfaces, List collector, + ResolvedType rtx, boolean includeITDs, boolean allowMissing) { + collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the + // methods + // declared + // on this + // type // now add all the inter-typed members too if (includeITDs && rtx.interTypeMungers != null) { for (Iterator i = interTypeMungers.iterator(); i.hasNext();) { ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next(); ResolvedMember rm = tm.getSignature(); - if (rm != null) { // new parent type munger can have null signature... + if (rm != null) { // new parent type munger can have null + // signature... collector.add(tm.getSignature()); } } @@ -263,10 +287,17 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (!rtx.equals(ResolvedType.OBJECT)) { ResolvedType superType = rtx.getSuperclass(); if (superType != null && !superType.isMissing()) { - addAndRecurse(knowninterfaces, collector, superType, includeITDs, allowMissing); // Recurse if we aren't at the top + addAndRecurse(knowninterfaces, collector, superType, + includeITDs, allowMissing); // Recurse if we aren't at + // the top } } - ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through the interfaces on the way back down + ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through + // the + // interfaces + // on the + // way back + // down for (int i = 0; i < interfaces.length; i++) { ResolvedType iface = interfaces[i]; @@ -274,23 +305,31 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // as those are used for @AJ ITD and we precisely want to skip those boolean shouldSkip = false; for (int j = 0; j < rtx.interTypeMungers.size(); j++) { - ConcreteTypeMunger munger = (ConcreteTypeMunger) rtx.interTypeMungers.get(j); - if (munger.getMunger() != null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent - && ((NewParentTypeMunger) munger.getMunger()).getNewParent().equals(iface) // pr171953 + ConcreteTypeMunger munger = (ConcreteTypeMunger) rtx.interTypeMungers + .get(j); + if (munger.getMunger() != null + && munger.getMunger().getKind() == ResolvedTypeMunger.Parent + && ((NewParentTypeMunger) munger.getMunger()) + .getNewParent().equals(iface) // pr171953 ) { shouldSkip = true; break; } } - if (!shouldSkip && !knowninterfaces.contains(iface)) { // Dont do interfaces more than once + if (!shouldSkip && !knowninterfaces.contains(iface)) { // Dont do + // interfaces + // more than + // once knowninterfaces.add(iface); if (allowMissing && iface.isMissing()) { if (iface instanceof MissingResolvedTypeWithKnownSignature) { - ((MissingResolvedTypeWithKnownSignature) iface).raiseWarningOnMissingInterfaceWhilstFindingMethods(); + ((MissingResolvedTypeWithKnownSignature) iface) + .raiseWarningOnMissingInterfaceWhilstFindingMethods(); } } else { - addAndRecurse(knowninterfaces, collector, iface, includeITDs, allowMissing); + addAndRecurse(knowninterfaces, collector, iface, + includeITDs, allowMissing); } } } @@ -337,7 +376,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl ResolvedMember f = (ResolvedMember) i.next(); if (matches(f, m)) return f; - if (f.hasBackingGenericMember() && m.getName().equals(f.getName())) { // might be worth checking the method behind the + if (f.hasBackingGenericMember() && m.getName().equals(f.getName())) { // might + // be + // worth + // checking + // the + // method + // behind + // the // parameterized method (see pr137496) if (matches(f.getBackingGenericMember(), m)) return f; @@ -360,18 +406,23 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Looks for the first member in the hierarchy matching aMember. This method differs from lookupMember(Member) in that it takes - * into account parameters which are type variables - which clearly an unresolved Member cannot do since it does not know - * anything about type variables. + * Looks for the first member in the hierarchy matching aMember. This method + * differs from lookupMember(Member) in that it takes into account + * parameters which are type variables - which clearly an unresolved Member + * cannot do since it does not know anything about type variables. */ - public ResolvedMember lookupResolvedMember(ResolvedMember aMember, boolean allowMissing) { + public ResolvedMember lookupResolvedMember(ResolvedMember aMember, + boolean allowMissing) { Iterator toSearch = null; ResolvedMember found = null; - if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) { + if ((aMember.getKind() == Member.METHOD) + || (aMember.getKind() == Member.CONSTRUCTOR)) { toSearch = getMethodsWithoutIterator(true, allowMissing).iterator(); } else { if (aMember.getKind() != Member.FIELD) - throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind()); + throw new IllegalStateException( + "I didn't know you would look for members of kind " + + aMember.getKind()); toSearch = getFields(); } while (toSearch.hasNext()) { @@ -401,9 +452,11 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (equalSignatures) return true; - // If they aren't the same, we need to allow for covariance ... where one sig might be ()LCar; and + // If they aren't the same, we need to allow for covariance ... where + // one sig might be ()LCar; and // the subsig might be ()LFastCar; - where FastCar is a subclass of Car - boolean equalCovariantSignatures = m1.getParameterSignature().equals(m2.getParameterSignature()); + boolean equalCovariantSignatures = m1.getParameterSignature().equals( + m2.getParameterSignature()); if (equalCovariantSignatures) return true; @@ -445,36 +498,42 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * returns an iterator through all of the pointcuts of this type, in order for checking from JVM spec 2ed 5.4.3.2 (as for - * fields). This means that the order is

+ * returns an iterator through all of the pointcuts of this type, in order + * for checking from JVM spec 2ed 5.4.3.2 (as for fields). This means that + * the order is

*

    *
  • pointcuts from current class
  • *
  • recur into direct superinterfaces
  • *
  • recur into superclass
  • *
- *

We keep a hashSet of interfaces that we've visited so we don't spiral out into 2^n land. + *

We keep a hashSet of interfaces that we've visited so we don't + * spiral out into 2^n land. */ public Iterator getPointcuts() { final Iterators.Filter dupFilter = Iterators.dupFilter(); // same order as fields Iterators.Getter typeGetter = new Iterators.Getter() { public Iterator get(Object o) { - return dupFilter.filter(((ResolvedType) o).getDirectSupertypes()); + return dupFilter.filter(((ResolvedType) o) + .getDirectSupertypes()); } }; Iterators.Getter pointcutGetter = new Iterators.Getter() { public Iterator get(Object o) { // System.err.println("getting for " + o); - return Iterators.array(((ResolvedType) o).getDeclaredPointcuts()); + return Iterators.array(((ResolvedType) o) + .getDeclaredPointcuts()); } }; - return Iterators.mapOver(Iterators.recur(this, typeGetter), pointcutGetter); + return Iterators.mapOver(Iterators.recur(this, typeGetter), + pointcutGetter); } public ResolvedPointcutDefinition findPointcut(String name) { // System.err.println("looking for pointcuts " + this); for (Iterator i = getPointcuts(); i.hasNext();) { - ResolvedPointcutDefinition f = (ResolvedPointcutDefinition) i.next(); + ResolvedPointcutDefinition f = (ResolvedPointcutDefinition) i + .next(); // System.err.println(f); if (name.equals(f.getName())) { return f; @@ -494,18 +553,23 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // ??? collecting data-structure, shouldn't really be a field public CrosscuttingMembers crosscuttingMembers; - public CrosscuttingMembers collectCrosscuttingMembers(boolean shouldConcretizeIfNeeded) { - crosscuttingMembers = new CrosscuttingMembers(this, shouldConcretizeIfNeeded); + public CrosscuttingMembers collectCrosscuttingMembers( + boolean shouldConcretizeIfNeeded) { + crosscuttingMembers = new CrosscuttingMembers(this, + shouldConcretizeIfNeeded); crosscuttingMembers.setPerClause(getPerClause()); crosscuttingMembers.addShadowMungers(collectShadowMungers()); // GENERICITDFIX // crosscuttingMembers.addTypeMungers(collectTypeMungers()); crosscuttingMembers.addTypeMungers(getTypeMungers()); - // FIXME AV - skip but needed ?? or ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers()); - crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers())); + // FIXME AV - skip but needed ?? or ?? + // crosscuttingMembers.addLateTypeMungers(getLateTypeMungers()); + crosscuttingMembers.addDeclares(collectDeclares(!this + .doesNotExposeShadowMungers())); crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses()); - // System.err.println("collected cc members: " + this + ", " + collectDeclares()); + // System.err.println("collected cc members: " + this + ", " + + // collectDeclares()); return crosscuttingMembers; } @@ -527,7 +591,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl final Iterators.Filter dupFilter = Iterators.dupFilter(); Iterators.Getter typeGetter = new Iterators.Getter() { public Iterator get(Object o) { - return dupFilter.filter(((ResolvedType) o).getDirectSupertypes()); + return dupFilter.filter(((ResolvedType) o) + .getDirectSupertypes()); } }; Iterator typeIterator = Iterators.recur(this, typeGetter); @@ -551,14 +616,16 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } private final Collection collectShadowMungers() { - if (!this.isAspect() || this.isAbstract() || this.doesNotExposeShadowMungers()) + if (!this.isAspect() || this.isAbstract() + || this.doesNotExposeShadowMungers()) return Collections.EMPTY_LIST; ArrayList acc = new ArrayList(); final Iterators.Filter dupFilter = Iterators.dupFilter(); Iterators.Getter typeGetter = new Iterators.Getter() { public Iterator get(Object o) { - return dupFilter.filter(((ResolvedType) o).getDirectSupertypes()); + return dupFilter.filter(((ResolvedType) o) + .getDirectSupertypes()); } }; Iterator typeIterator = Iterators.recur(this, typeGetter); @@ -635,12 +702,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return false; } - public void addAnnotation(AnnotationX annotationX) { - throw new RuntimeException("ResolvedType.addAnnotation() should never be called"); + public void addAnnotation(AnnotationAJ annotationX) { + throw new RuntimeException( + "ResolvedType.addAnnotation() should never be called"); } - public AnnotationX[] getAnnotations() { - throw new RuntimeException("ResolvedType.getAnnotations() should never be called"); + public AnnotationAJ[] getAnnotations() { + throw new RuntimeException( + "ResolvedType.getAnnotations() should never be called"); } /** @@ -693,18 +762,23 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl ShadowMunger munger = methods[i].getAssociatedShadowMunger(); if (munger != null) { if (ajMembersNeedParameterization()) { - // munger.setPointcut(munger.getPointcut().parameterizeWith(typeVariableMap)); + // munger.setPointcut(munger.getPointcut().parameterizeWith( + // typeVariableMap)); munger = munger.parameterizeWith(this, typeVariableMap); if (munger instanceof Advice) { Advice advice = (Advice) munger; // update to use the parameterized signature... - UnresolvedType[] ptypes = methods[i].getGenericParameterTypes(); + UnresolvedType[] ptypes = methods[i] + .getGenericParameterTypes(); UnresolvedType[] newPTypes = new UnresolvedType[ptypes.length]; for (int j = 0; j < ptypes.length; j++) { if (ptypes[j] instanceof TypeVariableReferenceType) { TypeVariableReferenceType tvrt = (TypeVariableReferenceType) ptypes[j]; - if (typeVariableMap.containsKey(tvrt.getTypeVariable().getName())) { - newPTypes[j] = (UnresolvedType) typeVariableMap.get(tvrt.getTypeVariable().getName()); + if (typeVariableMap.containsKey(tvrt + .getTypeVariable().getName())) { + newPTypes[j] = (UnresolvedType) typeVariableMap + .get(tvrt.getTypeVariable() + .getName()); } else { newPTypes[j] = ptypes[j]; } @@ -745,7 +819,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) { List l = new ArrayList(); for (int i = 0, len = ms.length; i < len; i++) { - if (!ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) { + if (!ms[i].isAjSynthetic() + && ms[i].getAssociatedShadowMunger() == null) { l.add(ms[i]); } } @@ -770,7 +845,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public static final Missing MISSING = new Missing(); /** Reset the static state in the primitive types */ - // OPTIMIZE I think we have a bug here because primitives are static and the world they use may vary (or may even be + // OPTIMIZE I think we have a bug here because primitives are static and the + // world they use may vary (or may even be // null) public static void resetPrimitives() { BYTE.world = null; @@ -788,8 +864,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public static ResolvedType makeArray(ResolvedType type, int dim) { if (dim == 0) return type; - ResolvedType array = new ArrayReferenceType("[" + type.getSignature(), "[" + type.getErasureSignature(), type.getWorld(), - type); + ResolvedType array = new ArrayReferenceType("[" + type.getSignature(), + "[" + type.getErasureSignature(), type.getWorld(), type); return makeArray(array, dim - 1); } @@ -824,12 +900,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (!other.isPrimitiveType()) { if (!world.isInJava5Mode()) return false; - return validBoxing.contains(this.getSignature() + other.getSignature()); + return validBoxing.contains(this.getSignature() + + other.getSignature()); } return assignTable[((Primitive) other).index][index]; } - public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) { + public final boolean isAssignableFrom(ResolvedType other, + boolean allowMissing) { return isAssignableFrom(other); } @@ -854,8 +932,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return noConvertTable[((Primitive) other).index][index]; } - private static final boolean[][] assignTable = {// to: B C D F I J S V Z from - { true, true, true, true, true, true, true, false, false }, // B + private static final boolean[][] assignTable = {// to: B C D F I J S V Z + // from + { true, true, true, true, true, true, true, false, false }, // B { false, true, true, true, true, true, false, false, false }, // C { false, false, true, false, false, false, false, false, false }, // D { false, false, true, true, false, false, false, false, false }, // F @@ -865,8 +944,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl { false, false, false, false, false, false, false, true, false }, // V { false, false, false, false, false, false, false, false, true }, // Z }; - private static final boolean[][] noConvertTable = {// to: B C D F I J S V Z from - { true, true, false, false, true, false, true, false, false }, // B + private static final boolean[][] noConvertTable = {// to: B C D F I J S + // V Z from + { true, true, false, false, true, false, true, false, false }, // B { false, true, false, false, true, false, false, false, false }, // C { false, false, true, false, false, false, false, false, false }, // D { false, false, false, true, false, false, false, false, false }, // F @@ -953,7 +1033,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return false; } - public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) { + public final boolean isAssignableFrom(ResolvedType other, + boolean allowMissing) { return false; } @@ -972,7 +1053,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Look up a member, takes into account any ITDs on this type. return null if not found + * Look up a member, takes into account any ITDs on this type. return null + * if not found */ public ResolvedMember lookupMemberNoSupers(Member member) { ResolvedMember ret = lookupDirectlyDeclaredMemberNoSupers(member); @@ -1013,15 +1095,17 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (member.getKind() == Member.FIELD) { ret = lookupMember(member, getDeclaredFields()); } else { - // assert member.getKind() == Member.METHOD || member.getKind() == Member.CONSTRUCTOR + // assert member.getKind() == Member.METHOD || member.getKind() == + // Member.CONSTRUCTOR ret = lookupMember(member, getDeclaredMethods()); } return ret; } /** - * This lookup has specialized behaviour - a null result tells the EclipseTypeMunger that it should make a default - * implementation of a method on this type. + * This lookup has specialized behaviour - a null result tells the + * EclipseTypeMunger that it should make a default implementation of a + * method on this type. * * @param member * @return @@ -1030,7 +1114,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return lookupMemberIncludingITDsOnInterfaces(member, this); } - private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) { + private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, + ResolvedType onType) { ResolvedMember ret = onType.lookupMemberNoSupers(member); if (ret != null) { return ret; @@ -1069,7 +1154,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * ??? This method is O(N*M) where N = number of methods and M is number of inter-type declarations in my super + * ??? This method is O(N*M) where N = number of methods and M is number of + * inter-type declarations in my super */ public List getInterTypeMungersIncludingSupers() { ArrayList ret = new ArrayList(); @@ -1095,7 +1181,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl for (Iterator iter = getDirectSupertypes(); iter.hasNext();) { ResolvedType superType = (ResolvedType) iter.next(); if (superType == null) { - throw new BCException("UnexpectedProblem: a supertype in the hierarchy for " + this.getName() + " is null"); + throw new BCException( + "UnexpectedProblem: a supertype in the hierarchy for " + + this.getName() + " is null"); } superType.collectInterTypeMungers(collector); } @@ -1108,9 +1196,11 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (!superMunger.getSignature().isAbstract()) continue; - for (Iterator iter = getInterTypeMungers().iterator(); iter.hasNext();) { + for (Iterator iter = getInterTypeMungers().iterator(); iter + .hasNext();) { ConcreteTypeMunger myMunger = (ConcreteTypeMunger) iter.next(); - if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) { + if (conflictingSignature(myMunger.getSignature(), superMunger + .getSignature())) { iter1.remove(); continue outer; } @@ -1132,8 +1222,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Check: 1) That we don't have any abstract type mungers unless this type is abstract. 2) That an abstract ITDM on an interface - * is declared public. (Compiler limitation) (PR70794) + * Check: 1) That we don't have any abstract type mungers unless this type + * is abstract. 2) That an abstract ITDM on an interface is declared public. + * (Compiler limitation) (PR70794) */ public void checkInterTypeMungers() { if (isAbstract()) @@ -1141,25 +1232,36 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl boolean itdProblem = false; - for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) { + for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter + .hasNext();) { ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next(); - itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2 + itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule + // 2 } if (itdProblem) return; // If the rules above are broken, return right now - for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) { + for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter + .hasNext();) { ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next(); - if (munger.getSignature() != null && munger.getSignature().isAbstract()) { // Rule 1 + if (munger.getSignature() != null + && munger.getSignature().isAbstract()) { // Rule 1 if (munger.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate) { - // ignore for @AJ ITD as munger.getSignature() is the interface method hence abstract + // ignore for @AJ ITD as munger.getSignature() is the + // interface method hence abstract } else { - world.getMessageHandler() + world + .getMessageHandler() .handleMessage( - new Message("must implement abstract inter-type declaration: " + munger.getSignature(), "", - IMessage.ERROR, getSourceLocation(), null, + new Message( + "must implement abstract inter-type declaration: " + + munger.getSignature(), + "", + IMessage.ERROR, + getSourceLocation(), + null, new ISourceLocation[] { getMungerLocation(munger) })); } } @@ -1167,20 +1269,34 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * See PR70794. This method checks that if an abstract inter-type method declaration is made on an interface then it must also - * be public. This is a compiler limitation that could be made to work in the future (if someone provides a worthwhile usecase) + * See PR70794. This method checks that if an abstract inter-type method + * declaration is made on an interface then it must also be public. This is + * a compiler limitation that could be made to work in the future (if + * someone provides a worthwhile usecase) * * @return indicates if the munger failed the check */ private boolean checkAbstractDeclaration(ConcreteTypeMunger munger) { - if (munger.getMunger() != null && (munger.getMunger() instanceof NewMethodTypeMunger)) { + if (munger.getMunger() != null + && (munger.getMunger() instanceof NewMethodTypeMunger)) { ResolvedMember itdMember = munger.getSignature(); ResolvedType onType = itdMember.getDeclaringType().resolve(world); - if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) { - world.getMessageHandler().handleMessage( - new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE, munger - .getSignature(), onType), "", Message.ERROR, getSourceLocation(), null, - new ISourceLocation[] { getMungerLocation(munger) })); + if (onType.isInterface() && itdMember.isAbstract() + && !itdMember.isPublic()) { + world + .getMessageHandler() + .handleMessage( + new Message( + WeaverMessages + .format( + WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE, + munger.getSignature(), + onType), + "", + Message.ERROR, + getSourceLocation(), + null, + new ISourceLocation[] { getMungerLocation(munger) })); return true; } } @@ -1188,8 +1304,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Get a source location for the munger. Until intertype mungers remember where they came from, the source location for the - * munger itself is null. In these cases use the source location for the aspect containing the ITD. + * Get a source location for the munger. Until intertype mungers remember + * where they came from, the source location for the munger itself is null. + * In these cases use the source location for the aspect containing the ITD. */ private ISourceLocation getMungerLocation(ConcreteTypeMunger munger) { ISourceLocation sloc = munger.getSourceLocation(); @@ -1200,10 +1317,13 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Returns a ResolvedType object representing the declaring type of this type, or null if this type does not represent a - * non-package-level-type.

Warning: This is guaranteed to work for all member types. For anonymous/local - * types, the only guarantee is given in JLS 13.1, where it guarantees that if you call getDeclaringType() repeatedly, you will - * eventually get the top-level class, but it does not say anything about classes in between. + * Returns a ResolvedType object representing the declaring type of this + * type, or null if this type does not represent a non-package-level-type. + *

Warning: This is guaranteed to work for all member + * types. For anonymous/local types, the only guarantee is given in JLS + * 13.1, where it guarantees that if you call getDeclaringType() repeatedly, + * you will eventually get the top-level class, but it does not say anything + * about classes in between. * * @return the declaring UnresolvedType object, or null. */ @@ -1213,7 +1333,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl String name = getName(); int lastDollar = name.lastIndexOf('$'); while (lastDollar > 0) { // allow for classes starting '$' (pr120474) - ResolvedType ret = world.resolve(UnresolvedType.forName(name.substring(0, lastDollar)), true); + ResolvedType ret = world.resolve(UnresolvedType.forName(name + .substring(0, lastDollar)), true); if (!ResolvedType.isMissing(ret)) return ret; lastDollar = name.lastIndexOf('$', lastDollar - 1); @@ -1221,21 +1342,26 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return null; } - public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) { - // System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType); + public static boolean isVisible(int modifiers, ResolvedType targetType, + ResolvedType fromType) { + // System.err.println("mod: " + modifiers + ", " + targetType + " and " + // + fromType); if (Modifier.isPublic(modifiers)) { return true; } else if (Modifier.isPrivate(modifiers)) { - return targetType.getOutermostType().equals(fromType.getOutermostType()); + return targetType.getOutermostType().equals( + fromType.getOutermostType()); } else if (Modifier.isProtected(modifiers)) { - return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType); + return samePackage(targetType, fromType) + || targetType.isAssignableFrom(fromType); } else { // package-visible return samePackage(targetType, fromType); } } - private static boolean samePackage(ResolvedType targetType, ResolvedType fromType) { + private static boolean samePackage(ResolvedType targetType, + ResolvedType fromType) { String p1 = targetType.getPackageName(); String p2 = fromType.getPackageName(); if (p1 == null) @@ -1246,28 +1372,35 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Checks if the generic type for 'this' and the generic type for 'other' are the same - it can be passed raw or parameterized - * versions and will just compare the underlying generic type. + * Checks if the generic type for 'this' and the generic type for 'other' + * are the same - it can be passed raw or parameterized versions and will + * just compare the underlying generic type. */ private boolean genericTypeEquals(ResolvedType other) { ResolvedType rt = other; if (rt.isParameterizedType() || rt.isRawType()) rt.getGenericType(); - if (((isParameterizedType() || isRawType()) && getGenericType().equals(rt)) || (this.equals(other))) + if (((isParameterizedType() || isRawType()) && getGenericType().equals( + rt)) + || (this.equals(other))) return true; return false; } /** - * Look up the actual occurence of a particular type in the hierarchy for 'this' type. The input is going to be a generic type, - * and the caller wants to know if it was used in its RAW or a PARAMETERIZED form in this hierarchy. + * Look up the actual occurence of a particular type in the hierarchy for + * 'this' type. The input is going to be a generic type, and the caller + * wants to know if it was used in its RAW or a PARAMETERIZED form in this + * hierarchy. * * returns null if it can't be found. */ - public ResolvedType discoverActualOccurrenceOfTypeInHierarchy(ResolvedType lookingFor) { + public ResolvedType discoverActualOccurrenceOfTypeInHierarchy( + ResolvedType lookingFor) { if (!lookingFor.isGenericType()) - throw new BCException("assertion failed: method should only be called with generic type, but " + lookingFor + " is " - + lookingFor.typeKind); + throw new BCException( + "assertion failed: method should only be called with generic type, but " + + lookingFor + " is " + lookingFor.typeKind); if (this.equals(ResolvedType.OBJECT)) return null; @@ -1284,7 +1417,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl ResolvedType superI = superIs[i]; if (superI.genericTypeEquals(lookingFor)) return superI; - ResolvedType checkTheSuperI = superI.discoverActualOccurrenceOfTypeInHierarchy(lookingFor); + ResolvedType checkTheSuperI = superI + .discoverActualOccurrenceOfTypeInHierarchy(lookingFor); if (checkTheSuperI != null) return checkTheSuperI; } @@ -1292,41 +1426,56 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Called for all type mungers but only does something if they share type variables with a generic type which they target. When - * this happens this routine will check for the target type in the target hierarchy and 'bind' any type parameters as - * appropriate. For example, for the ITD "List I.x" against a type like this: "class A implements I" this routine - * will return a parameterized form of the ITD "List I.x" + * Called for all type mungers but only does something if they share type + * variables with a generic type which they target. When this happens this + * routine will check for the target type in the target hierarchy and 'bind' + * any type parameters as appropriate. For example, for the ITD + * "List I.x" against a type like this: "class A implements I" + * this routine will return a parameterized form of the ITD + * "List I.x" */ public ConcreteTypeMunger fillInAnyTypeParameters(ConcreteTypeMunger munger) { boolean debug = false; ResolvedMember member = munger.getSignature(); if (munger.isTargetTypeParameterized()) { if (debug) - System.err.println("Processing attempted parameterization of " + munger + " targetting type " + this); + System.err.println("Processing attempted parameterization of " + + munger + " targetting type " + this); if (debug) - System.err.println(" This type is " + this + " (" + typeKind + ")"); + System.err.println(" This type is " + this + " (" + typeKind + + ")"); // need to tailor this munger instance for the particular target... if (debug) - System.err.println(" Signature that needs parameterizing: " + member); + System.err.println(" Signature that needs parameterizing: " + + member); // Retrieve the generic type - ResolvedType onType = world.resolve(member.getDeclaringType()).getGenericType(); - member.resolve(world); // Ensure all parts of the member are resolved + ResolvedType onType = world.resolve(member.getDeclaringType()) + .getGenericType(); + member.resolve(world); // Ensure all parts of the member are + // resolved if (debug) - System.err.println(" Actual target ontype: " + onType + " (" + onType.typeKind + ")"); - // quickly find the targettype in the type hierarchy for this type (it will be either RAW or PARAMETERIZED) + System.err.println(" Actual target ontype: " + onType + " (" + + onType.typeKind + ")"); + // quickly find the targettype in the type hierarchy for this type + // (it will be either RAW or PARAMETERIZED) ResolvedType actualTarget = discoverActualOccurrenceOfTypeInHierarchy(onType); if (actualTarget == null) - throw new BCException("assertion failed: asked " + this + " for occurrence of " + onType + " in its hierarchy??"); + throw new BCException("assertion failed: asked " + this + + " for occurrence of " + onType + + " in its hierarchy??"); - // only bind the tvars if its a parameterized type or the raw type (in which case they collapse to bounds) - don't do it + // only bind the tvars if its a parameterized type or the raw type + // (in which case they collapse to bounds) - don't do it // for generic types ;) if (!actualTarget.isGenericType()) { if (debug) - System.err.println("Occurrence in " + this + " is actually " + actualTarget + " (" + actualTarget.typeKind - + ")"); + System.err.println("Occurrence in " + this + + " is actually " + actualTarget + " (" + + actualTarget.typeKind + ")"); // parameterize the signature // ResolvedMember newOne = - // member.parameterizedWith(actualTarget.getTypeParameters(),onType,actualTarget.isParameterizedType()); + // member.parameterizedWith(actualTarget.getTypeParameters(), + // onType,actualTarget.isParameterizedType()); } // if (!actualTarget.isRawType()) munger = munger.parameterizedFor(actualTarget); @@ -1341,54 +1490,74 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public void addInterTypeMunger(ConcreteTypeMunger munger) { ResolvedMember sig = munger.getSignature(); - if (sig == null || munger.getMunger() == null || munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) { + if (sig == null + || munger.getMunger() == null + || munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) { interTypeMungers.add(munger); return; } // ConcreteTypeMunger originalMunger = munger; - // we will use the 'parameterized' ITD for all the comparisons but we say the original - // one passed in actually matched as it will be added to the intertype member finder - // for the target type. It is possible we only want to do this if a generic type + // we will use the 'parameterized' ITD for all the comparisons but we + // say the original + // one passed in actually matched as it will be added to the intertype + // member finder + // for the target type. It is possible we only want to do this if a + // generic type // is discovered and the tvar is collapsed to a bound? munger = fillInAnyTypeParameters(munger); - sig = munger.getSignature(); // possibly changed when type parms filled in + sig = munger.getSignature(); // possibly changed when type parms filled + // in - // System.err.println("add: " + munger + " to " + this.getClassName() + " with " + interTypeMungers); + // System.err.println("add: " + munger + " to " + this.getClassName() + + // " with " + interTypeMungers); if (sig.getKind() == Member.METHOD) { - if (!compareToExistingMembers(munger, getMethodsWithoutIterator(false, true) /* getMethods() */)) + if (!compareToExistingMembers(munger, getMethodsWithoutIterator( + false, true) /* getMethods() */)) return; if (this.isInterface()) { - if (!compareToExistingMembers(munger, Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) + if (!compareToExistingMembers(munger, Arrays.asList( + world.getCoreType(OBJECT).getDeclaredMethods()) + .iterator())) return; } } else if (sig.getKind() == Member.FIELD) { - if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) + if (!compareToExistingMembers(munger, Arrays.asList( + getDeclaredFields()).iterator())) return; } else { - if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) + if (!compareToExistingMembers(munger, Arrays.asList( + getDeclaredMethods()).iterator())) return; } // now compare to existingMungers for (Iterator i = interTypeMungers.iterator(); i.hasNext();) { ConcreteTypeMunger existingMunger = (ConcreteTypeMunger) i.next(); - if (conflictingSignature(existingMunger.getSignature(), munger.getSignature())) { - // System.err.println("match " + munger + " with " + existingMunger); - if (isVisible(munger.getSignature().getModifiers(), munger.getAspectType(), existingMunger.getAspectType())) { + if (conflictingSignature(existingMunger.getSignature(), munger + .getSignature())) { + // System.err.println("match " + munger + " with " + + // existingMunger); + if (isVisible(munger.getSignature().getModifiers(), munger + .getAspectType(), existingMunger.getAspectType())) { // System.err.println(" is visible"); - int c = compareMemberPrecedence(sig, existingMunger.getSignature()); + int c = compareMemberPrecedence(sig, existingMunger + .getSignature()); if (c == 0) { - c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType()); + c = getWorld().compareByPrecedenceAndHierarchy( + munger.getAspectType(), + existingMunger.getAspectType()); } // System.err.println(" compare: " + c); if (c < 0) { // the existing munger dominates the new munger - checkLegalOverride(munger.getSignature(), existingMunger.getSignature()); + checkLegalOverride(munger.getSignature(), + existingMunger.getSignature()); return; } else if (c > 0) { // the new munger dominates the existing one - checkLegalOverride(existingMunger.getSignature(), munger.getSignature()); + checkLegalOverride(existingMunger.getSignature(), + munger.getSignature()); i.remove(); break; } else { @@ -1406,93 +1575,138 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl interTypeMungers.add(munger); } - private boolean compareToExistingMembers(ConcreteTypeMunger munger, List existingMembersList) { + private boolean compareToExistingMembers(ConcreteTypeMunger munger, + List existingMembersList) { return compareToExistingMembers(munger, existingMembersList.iterator()); } // ??? returning too soon - private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) { + private boolean compareToExistingMembers(ConcreteTypeMunger munger, + Iterator existingMembers) { ResolvedMember sig = munger.getSignature(); // ResolvedType declaringAspectType = munger.getAspectType(); - // if (declaringAspectType.isRawType()) declaringAspectType = declaringAspectType.getGenericType(); + // if (declaringAspectType.isRawType()) declaringAspectType = + // declaringAspectType.getGenericType(); // if (declaringAspectType.isGenericType()) { // - // ResolvedType genericOnType = getWorld().resolve(sig.getDeclaringType()).getGenericType(); - // ConcreteTypeMunger ctm = munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy(genericOnType)); + // ResolvedType genericOnType = + // getWorld().resolve(sig.getDeclaringType()).getGenericType(); + // ConcreteTypeMunger ctm = + // munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy + // (genericOnType)); // sig = ctm.getSignature(); // possible sig change when type // } // if (munger.getMunger().hasTypeVariableAliases()) { // ResolvedType genericOnType = // getWorld().resolve(sig.getDeclaringType()).getGenericType(); // ConcreteTypeMunger ctm = - // munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy(genericOnType)); - // sig = ctm.getSignature(); // possible sig change when type parameters filled in + // munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy( + // genericOnType)); + // sig = ctm.getSignature(); // possible sig change when type parameters + // filled in // } while (existingMembers.hasNext()) { - ResolvedMember existingMember = (ResolvedMember) existingMembers.next(); + ResolvedMember existingMember = (ResolvedMember) existingMembers + .next(); // don't worry about clashing with bridge methods if (existingMember.isBridgeMethod()) continue; - // System.err.println("Comparing munger: "+sig+" with member "+existingMember); + // System.err.println("Comparing munger: "+sig+" with member "+ + // existingMember); if (conflictingSignature(existingMember, munger.getSignature())) { - // System.err.println("conflict: existingMember=" + existingMember + " typeMunger=" + munger); - // System.err.println(munger.getSourceLocation() + ", " + munger.getSignature() + ", " + + // System.err.println("conflict: existingMember=" + + // existingMember + " typeMunger=" + munger); + // System.err.println(munger.getSourceLocation() + ", " + + // munger.getSignature() + ", " + // munger.getSignature().getSourceLocation()); - if (isVisible(existingMember.getModifiers(), this, munger.getAspectType())) { + if (isVisible(existingMember.getModifiers(), this, munger + .getAspectType())) { int c = compareMemberPrecedence(sig, existingMember); // System.err.println(" c: " + c); if (c < 0) { // existingMember dominates munger - checkLegalOverride(munger.getSignature(), existingMember); + checkLegalOverride(munger.getSignature(), + existingMember); return false; } else if (c > 0) { // munger dominates existingMember - checkLegalOverride(existingMember, munger.getSignature()); + checkLegalOverride(existingMember, munger + .getSignature()); // interTypeMungers.add(munger); // ??? might need list of these overridden abstracts continue; } else { // bridge methods can differ solely in return type. - // FIXME this whole method seems very hokey - unaware of covariance/varargs/bridging - it + // FIXME this whole method seems very hokey - unaware of + // covariance/varargs/bridging - it // could do with a rewrite ! - boolean sameReturnTypes = (existingMember.getReturnType().equals(sig.getReturnType())); + boolean sameReturnTypes = (existingMember + .getReturnType().equals(sig.getReturnType())); if (sameReturnTypes) { - // pr206732 - if the existingMember is due to a previous application of this same ITD (which can - // happen if this is a binary type being brought in from the aspectpath). The 'better' fix is - // to recognize it is from the aspectpath at a higher level and dont do this, but that is rather + // pr206732 - if the existingMember is due to a + // previous application of this same ITD (which can + // happen if this is a binary type being brought in + // from the aspectpath). The 'better' fix is + // to recognize it is from the aspectpath at a + // higher level and dont do this, but that is rather // more work. boolean isDuplicateOfPreviousITD = false; - ResolvedType declaringRt = existingMember.getDeclaringType().resolve(world); + ResolvedType declaringRt = existingMember + .getDeclaringType().resolve(world); WeaverStateInfo wsi = declaringRt.getWeaverState(); if (wsi != null) { - List mungersAffectingThisType = wsi.getTypeMungers(declaringRt); + List mungersAffectingThisType = wsi + .getTypeMungers(declaringRt); if (mungersAffectingThisType != null) { - for (Iterator iterator = mungersAffectingThisType.iterator(); iterator.hasNext() + for (Iterator iterator = mungersAffectingThisType + .iterator(); iterator.hasNext() && !isDuplicateOfPreviousITD;) { - ConcreteTypeMunger ctMunger = (ConcreteTypeMunger) iterator.next(); - // relatively crude check - is the ITD for the same as the existingmember and does it come + ConcreteTypeMunger ctMunger = (ConcreteTypeMunger) iterator + .next(); + // relatively crude check - is the ITD + // for the same as the existingmember + // and does it come // from the same aspect - if (ctMunger.getSignature().equals(existingMember) - && ctMunger.aspectType.equals(munger.getAspectType())) { + if (ctMunger.getSignature().equals( + existingMember) + && ctMunger.aspectType + .equals(munger + .getAspectType())) { isDuplicateOfPreviousITD = true; } } } } if (!isDuplicateOfPreviousITD) { - getWorld().getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger - .getAspectType().getName(), existingMember), munger.getSourceLocation())); + getWorld() + .getMessageHandler() + .handleMessage( + MessageUtil + .error( + WeaverMessages + .format( + WeaverMessages.ITD_MEMBER_CONFLICT, + munger + .getAspectType() + .getName(), + existingMember), + munger + .getSourceLocation())); } } } - } else if (isDuplicateMemberWithinTargetType(existingMember, this, sig)) { + } else if (isDuplicateMemberWithinTargetType(existingMember, + this, sig)) { getWorld().getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger.getAspectType() - .getName(), existingMember), munger.getSourceLocation())); + MessageUtil + .error(WeaverMessages.format( + WeaverMessages.ITD_MEMBER_CONFLICT, + munger.getAspectType().getName(), + existingMember), munger + .getSourceLocation())); } // return; @@ -1501,10 +1715,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return true; } - // we know that the member signature matches, but that the member in the target type is not visible to the aspect. - // this may still be disallowed if it would result in two members within the same declaring type with the same - // signature AND more than one of them is concrete AND they are both visible within the target type. - private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType, + // we know that the member signature matches, but that the member in the + // target type is not visible to the aspect. + // this may still be disallowed if it would result in two members within the + // same declaring type with the same + // signature AND more than one of them is concrete AND they are both visible + // within the target type. + private boolean isDuplicateMemberWithinTargetType( + ResolvedMember existingMember, ResolvedType targetType, ResolvedMember itdMember) { if ((existingMember.isAbstract() || itdMember.isAbstract())) return false; @@ -1517,21 +1735,27 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (itdMember.isPublic()) return true; // must be in same package to be visible then... - if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) + if (!targetType.getPackageName().equals( + itdMember.getDeclaringType().getPackageName())) return false; - // trying to put two members with the same signature into the exact same type..., and both visible in that type. + // trying to put two members with the same signature into the exact same + // type..., and both visible in that type. return true; } /** - * @return true if the override is legal note: calling showMessage with two locations issues TWO messages, not ONE message with - * an additional source location. + * @return true if the override is legal note: calling showMessage with two + * locations issues TWO messages, not ONE message with an additional + * source location. */ - public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child) { - // System.err.println("check: " + child.getDeclaringType() + " overrides " + parent.getDeclaringType()); + public boolean checkLegalOverride(ResolvedMember parent, + ResolvedMember child) { + // System.err.println("check: " + child.getDeclaringType() + + // " overrides " + parent.getDeclaringType()); if (Modifier.isFinal(parent.getModifiers())) { - world.showMessage(Message.ERROR, WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER, parent), child + world.showMessage(Message.ERROR, WeaverMessages.format( + WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER, parent), child .getSourceLocation(), null); return false; } @@ -1541,42 +1765,53 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (world.isInJava5Mode() && parent.getKind() == Member.METHOD) { // Look at the generic types when doing this comparison - ResolvedType rtParentReturnType = parent.resolve(world).getGenericReturnType().resolve(world); - ResolvedType rtChildReturnType = child.resolve(world).getGenericReturnType().resolve(world); - incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType); - // For debug, uncomment this bit and we'll repeat the check - stick a breakpoint on the call + ResolvedType rtParentReturnType = parent.resolve(world) + .getGenericReturnType().resolve(world); + ResolvedType rtChildReturnType = child.resolve(world) + .getGenericReturnType().resolve(world); + incompatibleReturnTypes = !rtParentReturnType + .isAssignableFrom(rtChildReturnType); + // For debug, uncomment this bit and we'll repeat the check - stick + // a breakpoint on the call // if (incompatibleReturnTypes) { - // incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType); + // incompatibleReturnTypes = + // !rtParentReturnType.isAssignableFrom(rtChildReturnType); // } } else { - incompatibleReturnTypes = !parent.getReturnType().equals(child.getReturnType()); + incompatibleReturnTypes = !parent.getReturnType().equals( + child.getReturnType()); } if (incompatibleReturnTypes) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH, parent, child), child - .getSourceLocation(), parent.getSourceLocation()); + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.ITD_RETURN_TYPE_MISMATCH, parent, child), + child.getSourceLocation(), parent.getSourceLocation()); return false; } if (parent.getKind() == Member.POINTCUT) { UnresolvedType[] pTypes = parent.getParameterTypes(); UnresolvedType[] cTypes = child.getParameterTypes(); if (!Arrays.equals(pTypes, cTypes)) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH, parent, child), + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.ITD_PARAM_TYPE_MISMATCH, parent, child), child.getSourceLocation(), parent.getSourceLocation()); return false; } } - // System.err.println("check: " + child.getModifiers() + " more visible " + parent.getModifiers()); + // System.err.println("check: " + child.getModifiers() + + // " more visible " + parent.getModifiers()); if (isMoreVisible(parent.getModifiers(), child.getModifiers())) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION, parent, child), child - .getSourceLocation(), parent.getSourceLocation()); + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.ITD_VISIBILITY_REDUCTION, parent, child), + child.getSourceLocation(), parent.getSourceLocation()); return false; } // check declared exceptions ResolvedType[] childExceptions = world.resolve(child.getExceptions()); ResolvedType[] parentExceptions = world.resolve(parent.getExceptions()); - ResolvedType runtimeException = world.resolve("java.lang.RuntimeException"); + ResolvedType runtimeException = world + .resolve("java.lang.RuntimeException"); ResolvedType error = world.resolve("java.lang.Error"); outer: for (int i = 0, leni = childExceptions.length; i < leni; i++) { @@ -1593,17 +1828,20 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // this message is now better handled my MethodVerifier in JDT core. // world.showMessage(IMessage.ERROR, - // WeaverMessages.format(WeaverMessages.ITD_DOESNT_THROW,childExceptions[i].getName()), + // WeaverMessages.format(WeaverMessages.ITD_DOESNT_THROW, + // childExceptions[i].getName()), // child.getSourceLocation(), null); return false; } if (parent.isStatic() && !child.isStatic()) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC, child, parent), child + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.ITD_OVERRIDDEN_STATIC, child, parent), child .getSourceLocation(), null); return false; } else if (child.isStatic() && !parent.isStatic()) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC, child, parent), child + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.ITD_OVERIDDING_STATIC, child, parent), child .getSourceLocation(), null); return false; } @@ -1614,14 +1852,17 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) { // if (!m1.getReturnType().equals(m2.getReturnType())) return 0; - // need to allow for the special case of 'clone' - which is like abstract but is - // not marked abstract. The code below this next line seems to make assumptions + // need to allow for the special case of 'clone' - which is like + // abstract but is + // not marked abstract. The code below this next line seems to make + // assumptions // about what will have gotten through the compiler based on the normal // java rules. clone goes against these... if (m2.isProtected() && m2.getName().charAt(0) == 'c') { UnresolvedType declaring = m2.getDeclaringType(); if (declaring != null) { - if (declaring.getName().equals("java.lang.Object") && m2.getName().equals("clone")) + if (declaring.getName().equals("java.lang.Object") + && m2.getName().equals("clone")) return +1; } } @@ -1661,15 +1902,18 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED))); } - private void interTypeConflictError(ConcreteTypeMunger m1, ConcreteTypeMunger m2) { + private void interTypeConflictError(ConcreteTypeMunger m1, + ConcreteTypeMunger m2) { // XXX this works only if we ignore separate compilation issues // XXX dual errors possible if (this instanceof BcelObjectType) return; // System.err.println("conflict at " + m2.getSourceLocation()); getWorld().showMessage( IMessage.ERROR, - WeaverMessages.format(WeaverMessages.ITD_CONFLICT, m1.getAspectType().getName(), m2.getSignature(), m2 - .getAspectType().getName()), m2.getSourceLocation(), getSourceLocation()); + WeaverMessages.format(WeaverMessages.ITD_CONFLICT, m1 + .getAspectType().getName(), m2.getSignature(), m2 + .getAspectType().getName()), m2.getSourceLocation(), + getSourceLocation()); } public ResolvedMember lookupSyntheticMember(Member member) { @@ -1688,13 +1932,16 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // Handling members for the new array join point if (world.isJoinpointArrayConstructionEnabled() && this.isArray()) { if (member.getKind() == Member.CONSTRUCTOR) { - ResolvedMemberImpl ret = new ResolvedMemberImpl(Member.CONSTRUCTOR, this, Modifier.PUBLIC, ResolvedType.VOID, - "", world.resolve(member.getParameterTypes())); + ResolvedMemberImpl ret = new ResolvedMemberImpl( + Member.CONSTRUCTOR, this, Modifier.PUBLIC, + ResolvedType.VOID, "", world.resolve(member + .getParameterTypes())); return ret; } } - // if (this.getSuperclass() != ResolvedType.OBJECT && this.getSuperclass() != null) { + // if (this.getSuperclass() != ResolvedType.OBJECT && + // this.getSuperclass() != null) { // return getSuperclass().lookupSyntheticMember(member); // } @@ -1714,7 +1961,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return false; // check that I'm truly the topmost implementor if (this.getSuperclass().isMissing()) - return true; // we don't know anything about supertype, and it can't be exposed to weaver + return true; // we don't know anything about supertype, and it can't + // be exposed to weaver if (interfaceType.isAssignableFrom(this.getSuperclass(), true)) { return false; } @@ -1727,7 +1975,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (!interfaceType.isAssignableFrom(this)) return null; // Check if my super class is an implementor? - ResolvedType higherType = this.getSuperclass().getTopmostImplementor(interfaceType); + ResolvedType higherType = this.getSuperclass().getTopmostImplementor( + interfaceType); if (higherType != null) return higherType; return this; @@ -1738,20 +1987,29 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts()); - for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext();) { + for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i + .hasNext();) { ResolvedType t = (ResolvedType) i.next(); - addPointcutsResolvingConflicts(ret, Arrays.asList(t.getDeclaredPointcuts()), false); + addPointcutsResolvingConflicts(ret, Arrays.asList(t + .getDeclaredPointcuts()), false); } - addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true); + addPointcutsResolvingConflicts(ret, Arrays + .asList(getDeclaredPointcuts()), true); for (Iterator i = ret.iterator(); i.hasNext();) { - ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition) i.next(); + ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition) i + .next(); // System.err.println("looking at: " + inherited + " in " + this); - // System.err.println(" " + inherited.isAbstract() + " in " + this.isAbstract()); + // System.err.println(" " + inherited.isAbstract() + + // " in " + this.isAbstract()); if (inherited.isAbstract()) { if (!this.isAbstract()) { - getWorld().showMessage(IMessage.ERROR, - WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE, inherited, this.getName()), - inherited.getSourceLocation(), this.getSourceLocation()); + getWorld().showMessage( + IMessage.ERROR, + WeaverMessages.format( + WeaverMessages.POINCUT_NOT_CONCRETE, + inherited, this.getName()), + inherited.getSourceLocation(), + this.getSourceLocation()); } } } @@ -1759,21 +2017,31 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return ret; } - private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) { + private void addPointcutsResolvingConflicts(List acc, List added, + boolean isOverriding) { for (Iterator i = added.iterator(); i.hasNext();) { - ResolvedPointcutDefinition toAdd = (ResolvedPointcutDefinition) i.next(); + ResolvedPointcutDefinition toAdd = (ResolvedPointcutDefinition) i + .next(); // System.err.println("adding: " + toAdd); for (Iterator j = acc.iterator(); j.hasNext();) { - ResolvedPointcutDefinition existing = (ResolvedPointcutDefinition) j.next(); + ResolvedPointcutDefinition existing = (ResolvedPointcutDefinition) j + .next(); if (existing == toAdd) continue; - if (!isVisible(existing.getModifiers(), existing.getDeclaringType().resolve(getWorld()), this)) { - // if they intended to override it but it is not visible, give them a nicer message - if (existing.isAbstract() && conflictingSignature(existing, toAdd)) { + if (!isVisible(existing.getModifiers(), existing + .getDeclaringType().resolve(getWorld()), this)) { + // if they intended to override it but it is not visible, + // give them a nicer message + if (existing.isAbstract() + && conflictingSignature(existing, toAdd)) { getWorld().showMessage( IMessage.ERROR, - WeaverMessages.format(WeaverMessages.POINTCUT_NOT_VISIBLE, existing.getDeclaringType().getName() - + "." + existing.getName() + "()", this.getName()), toAdd.getSourceLocation(), null); + WeaverMessages.format( + WeaverMessages.POINTCUT_NOT_VISIBLE, + existing.getDeclaringType().getName() + + "." + existing.getName() + + "()", this.getName()), + toAdd.getSourceLocation(), null); j.remove(); } continue; @@ -1783,10 +2051,17 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl checkLegalOverride(existing, toAdd); j.remove(); } else { - getWorld().showMessage( - IMessage.ERROR, - WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS, this.getName() - + toAdd.getSignature()), existing.getSourceLocation(), toAdd.getSourceLocation()); + getWorld() + .showMessage( + IMessage.ERROR, + WeaverMessages + .format( + WeaverMessages.CONFLICTING_INHERITED_POINTCUTS, + this.getName() + + toAdd + .getSignature()), + existing.getSourceLocation(), + toAdd.getSourceLocation()); j.remove(); } } @@ -1808,32 +2083,39 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Overridden by ReferenceType to return a sensible answer for parameterized and raw types. + * Overridden by ReferenceType to return a sensible answer for parameterized + * and raw types. * * @return */ public ResolvedType getGenericType() { if (!(isParameterizedType() || isRawType())) - throw new BCException("The type " + getBaseName() + " is not parameterized or raw - it has no generic type"); + throw new BCException("The type " + getBaseName() + + " is not parameterized or raw - it has no generic type"); return null; } public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) { if (!(isGenericType() || isParameterizedType())) return this; - return TypeFactory.createParameterizedType(this.getGenericType(), typeParameters, getWorld()); + return TypeFactory.createParameterizedType(this.getGenericType(), + typeParameters, getWorld()); } /** - * Iff I am a parameterized type, and any of my parameters are type variable references, return a version with those type - * parameters replaced in accordance with the passed bindings. + * Iff I am a parameterized type, and any of my parameters are type variable + * references, return a version with those type parameters replaced in + * accordance with the passed bindings. */ public UnresolvedType parameterize(Map typeBindings) { if (!isParameterizedType()) - return this;// throw new IllegalStateException("Can't parameterize a type that is not a parameterized type"); + return this;// throw new IllegalStateException( + // "Can't parameterize a type that is not a parameterized type" + // ); boolean workToDo = false; for (int i = 0; i < typeParameters.length; i++) { - if (typeParameters[i].isTypeVariableReference() || (typeParameters[i] instanceof BoundedReferenceType)) { + if (typeParameters[i].isTypeVariableReference() + || (typeParameters[i] instanceof BoundedReferenceType)) { workToDo = true; } } @@ -1845,7 +2127,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl newTypeParams[i] = typeParameters[i]; if (newTypeParams[i].isTypeVariableReference()) { TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i]; - UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName()); + UnresolvedType binding = (UnresolvedType) typeBindings + .get(tvrt.getTypeVariable().getName()); if (binding != null) newTypeParams[i] = binding; } else if (newTypeParams[i] instanceof BoundedReferenceType) { @@ -1854,7 +2137,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // brType.parameterize(typeBindings) } } - return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld()); + return TypeFactory.createParameterizedType(getGenericType(), + newTypeParams, getWorld()); } } @@ -1888,12 +2172,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl // parameterizedSuperTypes = (ResolvedType[]) accumulatedTypes.toArray(ret); // return parameterizedSuperTypes; // } - // private void accumulateParameterizedSuperTypes(ResolvedType forType, List parameterizedTypeList) { + // private void accumulateParameterizedSuperTypes(ResolvedType forType, List + // parameterizedTypeList) { // if (forType.isParameterizedType()) { // parameterizedTypeList.add(forType); // } // if (forType.getSuperclass() != null) { - // accumulateParameterizedSuperTypes(forType.getSuperclass(), parameterizedTypeList); + // accumulateParameterizedSuperTypes(forType.getSuperclass(), + // parameterizedTypeList); // } // ResolvedType[] interfaces = forType.getDeclaredInterfaces(); // for (int i = 0; i < interfaces.length; i++) { @@ -1904,35 +2190,45 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl * @return true if assignable to java.lang.Exception */ public boolean isException() { - return (world.getCoreType(UnresolvedType.JAVA_LANG_EXCEPTION).isAssignableFrom(this)); + return (world.getCoreType(UnresolvedType.JAVA_LANG_EXCEPTION) + .isAssignableFrom(this)); } /** - * @return true if it is an exception and it is a checked one, false otherwise. + * @return true if it is an exception and it is a checked one, false + * otherwise. */ public boolean isCheckedException() { if (!isException()) return false; - if (world.getCoreType(UnresolvedType.RUNTIME_EXCEPTION).isAssignableFrom(this)) + if (world.getCoreType(UnresolvedType.RUNTIME_EXCEPTION) + .isAssignableFrom(this)) return false; return true; } /** - * Determines if variables of this type could be assigned values of another with lots of help. java.lang.Object is convertable - * from all types. A primitive type is convertable from X iff it's assignable from X. A reference type is convertable from X iff - * it's coerceable from X. In other words, X isConvertableFrom Y iff the compiler thinks that _some_ value of Y could be - * assignable to a variable of type X without loss of precision. + * Determines if variables of this type could be assigned values of another + * with lots of help. java.lang.Object is convertable from all types. A + * primitive type is convertable from X iff it's assignable from X. A + * reference type is convertable from X iff it's coerceable from X. In other + * words, X isConvertableFrom Y iff the compiler thinks that _some_ value of + * Y could be assignable to a variable of type X without loss of precision. * - * @param other the other type - * @param world the {@link World} in which the possible assignment should be checked. - * @return true iff variables of this type could be assigned values of other with possible conversion + * @param other + * the other type + * @param world + * the {@link World} in which the possible assignment should be + * checked. + * @return true iff variables of this type could be assigned values of other + * with possible conversion */ public final boolean isConvertableFrom(ResolvedType other) { // // version from TypeX // if (this.equals(OBJECT)) return true; - // if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other); + // if (this.isPrimitiveType() || other.isPrimitiveType()) return + // this.isAssignableFrom(other); // return this.isCoerceableFrom(other); // @@ -1940,8 +2236,13 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl if (this.equals(OBJECT)) return true; if (world.isInJava5Mode()) { - if (this.isPrimitiveType() ^ other.isPrimitiveType()) { // If one is primitive and the other isnt - if (validBoxing.contains(this.getSignature() + other.getSignature())) + if (this.isPrimitiveType() ^ other.isPrimitiveType()) { // If one is + // primitive + // and the + // other + // isnt + if (validBoxing.contains(this.getSignature() + + other.getSignature())) return true; } } @@ -1951,23 +2252,32 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Determines if the variables of this type could be assigned values of another type without casting. This still allows for - * assignment conversion as per JLS 2ed 5.2. For object types, this means supertypeOrEqual(THIS, OTHER). + * Determines if the variables of this type could be assigned values of + * another type without casting. This still allows for assignment conversion + * as per JLS 2ed 5.2. For object types, this means supertypeOrEqual(THIS, + * OTHER). * - * @param other the other type - * @param world the {@link World} in which the possible assignment should be checked. - * @return true iff variables of this type could be assigned values of other without casting - * @throws NullPointerException if other is null + * @param other + * the other type + * @param world + * the {@link World} in which the possible assignment should be + * checked. + * @return true iff variables of this type could be assigned values of other + * without casting + * @throws NullPointerException + * if other is null */ public abstract boolean isAssignableFrom(ResolvedType other); - public abstract boolean isAssignableFrom(ResolvedType other, boolean allowMissing); + public abstract boolean isAssignableFrom(ResolvedType other, + boolean allowMissing); /** - * Determines if values of another type could possibly be cast to this type. The rules followed are from JLS 2ed 5.5, - * "Casting Conversion".

+ * Determines if values of another type could possibly be cast to this type. + * The rules followed are from JLS 2ed 5.5, "Casting Conversion".

*

- * This method should be commutative, i.e., for all UnresolvedType a, b and all World w:

+ * This method should be commutative, i.e., for all UnresolvedType a, b and + * all World w:

* *
 	 * a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
@@ -1975,10 +2285,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
 	 * 
 	 * 
* - * @param other the other type - * @param world the {@link World} in which the possible coersion should be checked. + * @param other + * the other type + * @param world + * the {@link World} in which the possible coersion should be + * checked. * @return true iff values of other could possibly be cast to this type. - * @throws NullPointerException if other is null. + * @throws NullPointerException + * if other is null. */ public abstract boolean isCoerceableFrom(ResolvedType other); @@ -1987,14 +2301,15 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } public String getSignatureForAttribute() { - return signature; // Assume if this is being called that it is for a simple type (eg. void, int, etc) + return signature; // Assume if this is being called that it is for a + // simple type (eg. void, int, etc) } private FuzzyBoolean parameterizedWithTypeVariable = FuzzyBoolean.MAYBE; /** - * return true if the parameterization of this type includes a member type variable. Member type variables occur in generic - * methods/ctors. + * return true if the parameterization of this type includes a member type + * variable. Member type variables occur in generic methods/ctors. */ public boolean isParameterizedWithTypeVariable() { // MAYBE means we haven't worked it out yet... @@ -2010,13 +2325,18 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl ResolvedType aType = (ResolvedType) typeParameters[i]; if (aType.isTypeVariableReference() // Changed according to the problems covered in bug 222648 - // Don't care what kind of type variable - the fact that there is one - // at all means we can't risk caching it against we get confused later - // by another variation of the parameterization that just happens to + // Don't care what kind of type variable - the fact that there + // is one + // at all means we can't risk caching it against we get confused + // later + // by another variation of the parameterization that just + // happens to // use the same type variable name - // assume the worst - if its definetly not a type declared one, it could be anything - // && ((TypeVariableReference)aType).getTypeVariable().getDeclaringElementKind()!=TypeVariable.TYPE + // assume the worst - if its definetly not a type declared one, + // it could be anything + // && ((TypeVariableReference)aType).getTypeVariable(). + // getDeclaringElementKind()!=TypeVariable.TYPE ) { parameterizedWithTypeVariable = FuzzyBoolean.YES; return true; @@ -2034,9 +2354,12 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl boolean b = false; UnresolvedType upperBound = boundedRT.getUpperBound(); if (upperBound.isParameterizedType()) { - b = ((ResolvedType) upperBound).isParameterizedWithTypeVariable(); + b = ((ResolvedType) upperBound) + .isParameterizedWithTypeVariable(); } else if (upperBound.isTypeVariableReference() - && ((TypeVariableReference) upperBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) { + && ((TypeVariableReference) upperBound) + .getTypeVariable() + .getDeclaringElementKind() == TypeVariable.METHOD) { b = true; } if (b) { @@ -2049,9 +2372,12 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl boolean b = false; UnresolvedType lowerBound = boundedRT.getLowerBound(); if (lowerBound.isParameterizedType()) { - b = ((ResolvedType) lowerBound).isParameterizedWithTypeVariable(); + b = ((ResolvedType) lowerBound) + .isParameterizedWithTypeVariable(); } else if (lowerBound.isTypeVariableReference() - && ((TypeVariableReference) lowerBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) { + && ((TypeVariableReference) lowerBound) + .getTypeVariable() + .getDeclaringElementKind() == TypeVariable.METHOD) { b = true; } if (b) { @@ -2077,7 +2403,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl protected Map getAjMemberParameterizationMap() { Map myMap = getMemberParameterizationMap(); if (myMap.isEmpty()) { - // might extend a parameterized aspect that we also need to consider... + // might extend a parameterized aspect that we also need to + // consider... if (getSuperclass() != null) return getSuperclass().getAjMemberParameterizationMap(); } @@ -2089,7 +2416,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl } /** - * Returns the path to the jar or class file from which this binary aspect came or null if not a binary aspect + * Returns the path to the jar or class file from which this binary aspect + * came or null if not a binary aspect */ public String getBinaryPath() { return binaryPath; diff --git a/weaver/src/org/aspectj/weaver/StandardAnnotation.java b/weaver/src/org/aspectj/weaver/StandardAnnotation.java new file mode 100644 index 000000000..64962ecf4 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/StandardAnnotation.java @@ -0,0 +1,139 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * 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 + * + * ******************************************************************/ +package org.aspectj.weaver; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * This type represents the weavers abstraction of an annotation - it is not tied to any underlying BCI toolkit. The weaver actualy + * handles these through AnnotationX wrapper objects - until we start transforming the BCEL annotations into this form (expensive) + * or offer a clever visitor mechanism over the BCEL annotation stuff that builds these annotation types directly. + * + * @author AndyClement + */ +public class StandardAnnotation extends AbstractAnnotationAJ { + + private final boolean isRuntimeVisible; + + private List /* of AnnotationNVPair */nvPairs = null; + + public StandardAnnotation(ResolvedType type, boolean isRuntimeVisible) { + super(type); + this.isRuntimeVisible = isRuntimeVisible; + } + + /** + * {@inheritDoc} + */ + public boolean isRuntimeVisible() { + return isRuntimeVisible; + } + + /** + * {@inheritDoc} + */ + public String stringify() { + StringBuffer sb = new StringBuffer(); + sb.append("@").append(type.getClassName()); + if (hasNameValuePairs()) { + sb.append("("); + for (Iterator iter = nvPairs.iterator(); iter.hasNext();) { + AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next(); + sb.append(element.stringify()); + } + sb.append(")"); + } + return sb.toString(); + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("ANNOTATION [" + getTypeSignature() + "] [" + (isRuntimeVisible ? "runtimeVisible" : "runtimeInvisible") + "] ["); + if (nvPairs != null) { + for (Iterator iter = nvPairs.iterator(); iter.hasNext();) { + AnnotationNameValuePair element = (AnnotationNameValuePair) iter.next(); + sb.append(element.toString()); + if (iter.hasNext()) + sb.append(","); + } + } + sb.append("]"); + return sb.toString(); + } + + /** + * {@inheritDoc} + */ + public boolean hasNamedValue(String n) { + if (nvPairs == null) + return false; + for (int i = 0; i < nvPairs.size(); i++) { + AnnotationNameValuePair pair = (AnnotationNameValuePair) nvPairs.get(i); + if (pair.getName().equals(n)) + return true; + } + return false; + } + + /** + * {@inheritDoc} + */ + public boolean hasNameValuePair(String n, String v) { + if (nvPairs == null) + return false; + for (int i = 0; i < nvPairs.size(); i++) { + AnnotationNameValuePair pair = (AnnotationNameValuePair) nvPairs.get(i); + if (pair.getName().equals(n)) { + if (pair.getValue().stringify().equals(v)) + return true; + } + } + return false; + } + + /** + * {@inheritDoc} + */ + public Set /* */getTargets() { + if (!type.equals(UnresolvedType.AT_TARGET)) { + return Collections.EMPTY_SET; + } + AnnotationNameValuePair nvp = (AnnotationNameValuePair) nvPairs.get(0); + ArrayAnnotationValue aav = (ArrayAnnotationValue) nvp.getValue(); + AnnotationValue[] avs = aav.getValues(); + Set targets = new HashSet(); + for (int i = 0; i < avs.length; i++) { + AnnotationValue value = avs[i]; + targets.add(value.stringify()); + } + return targets; + } + + public List getNameValuePairs() { + return nvPairs; + } + + public boolean hasNameValuePairs() { + return nvPairs != null && nvPairs.size() != 0; + } + + public void addNameValuePair(AnnotationNameValuePair pair) { + if (nvPairs == null) { + nvPairs = new ArrayList(); + } + nvPairs.add(pair); + } + +} diff --git a/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java b/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java index 7232cfd64..af73d4497 100644 --- a/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java +++ b/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessFieldVar.java @@ -20,7 +20,7 @@ import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen; import org.aspectj.apache.bcel.generic.InstructionFactory; import org.aspectj.apache.bcel.generic.InstructionList; import org.aspectj.apache.bcel.generic.Type; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.Member; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; @@ -45,16 +45,18 @@ class AnnotationAccessFieldVar extends BcelVar { } public void appendLoadAndConvert(InstructionList il, InstructionFactory fact, ResolvedType toType) { - // Only possible to do annotation field value extraction at MethodExecution + // Only possible to do annotation field value extraction at + // MethodExecution if (annoAccessor.getKind() != Shadow.MethodExecution) { return; } String annotationOfInterestSignature = annoAccessor.getType().getSignature(); - // So we have an entity that has an annotation on and within it is the value we want + // So we have an entity that has an annotation on and within it is the + // value we want Member holder = annoAccessor.getMember(); - AnnotationX[] annos = holder.getAnnotations(); + AnnotationAJ[] annos = holder.getAnnotations(); for (int i = 0; i < annos.length; i++) { - AnnotationGen annotation = annos[i].getBcelAnnotation(); + AnnotationGen annotation = ((BcelAnnotation) annos[i]).getBcelAnnotation(); if (annotation.getTypeSignature().equals(annotationOfInterestSignature)) { List vals = annotation.getValues(); boolean doneAndDusted = false; @@ -76,7 +78,8 @@ class AnnotationAccessFieldVar extends BcelVar { for (int ii = 0; ii < annotationFields.length; ii++) { if (annotationFields[ii].getType().equals(annoFieldOfInterest)) { String dvalue = annotationFields[ii].getAnnotationDefaultValue(); - // form will be LBLAHBLAHBLAH;X where X is the field within X + // form will be LBLAHBLAHBLAH;X where X is the field + // within X String typename = dvalue.substring(0, dvalue.lastIndexOf(';') + 1); String field = dvalue.substring(dvalue.lastIndexOf(';') + 1); ResolvedType rt = toType.getWorld().resolve(UnresolvedType.forSignature(typename)); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAnnotation.java b/weaver/src/org/aspectj/weaver/bcel/BcelAnnotation.java new file mode 100644 index 000000000..9d7e83bca --- /dev/null +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAnnotation.java @@ -0,0 +1,107 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * 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 + * + * ******************************************************************/ +package org.aspectj.weaver.bcel; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen; +import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; +import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen; +import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen; +import org.aspectj.weaver.AbstractAnnotationAJ; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; + +/** + * Wraps a Bcel Annotation object and uses it to answer AnnotationAJ method calls. This is cheaper than translating all Bcel + * annotations into AnnotationAJ objects. + * + * @author AndyClement + */ +public class BcelAnnotation extends AbstractAnnotationAJ { + + private final AnnotationGen bcelAnnotation; + + public BcelAnnotation(AnnotationGen theBcelAnnotation, World world) { + super(UnresolvedType.forSignature(theBcelAnnotation.getTypeSignature()).resolve(world)); + this.bcelAnnotation = theBcelAnnotation; + } + + /** + * {@inheritDoc} + */ + public Set /* of String */getTargets() { + if (!type.equals(UnresolvedType.AT_TARGET)) { + return Collections.EMPTY_SET; + } + List values = bcelAnnotation.getValues(); + ElementNameValuePairGen envp = (ElementNameValuePairGen) values.get(0); + ArrayElementValueGen aev = (ArrayElementValueGen) envp.getValue(); + ElementValueGen[] evs = aev.getElementValuesArray(); + Set targets = new HashSet(); + for (int i = 0; i < evs.length; i++) { + EnumElementValueGen ev = (EnumElementValueGen) evs[i]; + targets.add(ev.getEnumValueString()); + } + return targets; + } + + /** + * {@inheritDoc} + */ + public boolean hasNameValuePair(String name, String value) { + return bcelAnnotation.hasNameValuePair(name, value); + } + + /** + * {@inheritDoc} + */ + public boolean hasNamedValue(String name) { + return bcelAnnotation.hasNamedValue(name); + } + + /** + * {@inheritDoc} + */ + public String stringify() { + StringBuffer sb = new StringBuffer(); + sb.append("@").append(type.getClassName()); + List values = bcelAnnotation.getValues(); + if (values != null && values.size() != 0) { + sb.append("("); + for (Iterator iterator = values.iterator(); iterator.hasNext();) { + ElementNameValuePairGen nvPair = (ElementNameValuePairGen) iterator.next(); + sb.append(nvPair.getNameString()).append("=").append(nvPair.getValue().stringifyValue()); + } + sb.append(")"); + } + return sb.toString(); + } + + /** + * {@inheritDoc} + */ + public boolean isRuntimeVisible() { + return this.bcelAnnotation.isRuntimeVisible(); + } + + /** + * @return return the real bcel annotation being wrapped + */ + public AnnotationGen getBcelAnnotation() { + return bcelAnnotation; + } + +} diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index 45fe0fa3a..a58fcf7c6 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -60,7 +60,7 @@ import org.aspectj.bridge.context.ContextToken; import org.aspectj.util.PartialOrder; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjcMemberMaker; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AsmRelationshipProvider; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ConcreteTypeMunger; @@ -96,7 +96,8 @@ class BcelClassWeaver implements IClassWeaver { */ public static boolean weave(BcelWorld world, LazyClassGen clazz, List shadowMungers, List typeMungers, List lateTypeMungers) { boolean b = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers, lateTypeMungers).weave(); - // System.out.println(clazz.getClassName() + ", " + clazz.getType().getWeaverState()); + // System.out.println(clazz.getClassName() + ", " + + // clazz.getType().getWeaverState()); // clazz.print(); return b; } @@ -120,9 +121,11 @@ class BcelClassWeaver implements IClassWeaver { private static boolean inReweavableMode = false; private List addedSuperInitializersAsList = null; // List - private final Map addedSuperInitializers = new HashMap(); // Interface -> IfaceInitList + private final Map addedSuperInitializers = new HashMap(); // Interface -> + // IfaceInitList private List addedThisInitializers = new ArrayList(); // List - private List addedClassInitializers = new ArrayList(); // List + private List addedClassInitializers = new ArrayList(); // List private Map mapToAnnotations = new HashMap(); @@ -210,12 +213,14 @@ class BcelClassWeaver implements IClassWeaver { return perKindShadowMungers[kind.getKey()] != null; } - // private void fastMatchShadowMungers(List shadowMungers, ArrayList mungers, Kind kind) { + // private void fastMatchShadowMungers(List shadowMungers, ArrayList + // mungers, Kind kind) { // FastMatchInfo info = new FastMatchInfo(clazz.getType(), kind); // for (Iterator i = shadowMungers.iterator(); i.hasNext();) { // ShadowMunger munger = (ShadowMunger) i.next(); // FuzzyBoolean fb = munger.getPointcut().fastMatch(info); - // WeaverMetrics.recordFastMatchResult(fb);// Could pass: munger.getPointcut().toString() + // WeaverMetrics.recordFastMatchResult(fb);// Could pass: + // munger.getPointcut().toString() // if (fb.maybeTrue()) mungers.add(munger); // } // } @@ -367,11 +372,24 @@ class BcelClassWeaver implements IClassWeaver { whatToBridgeToMethodGen.getAccessFlags(), whatToBridgeToMethodGen.getName(), whatToBridgeToMethodGen .getSignature()); } - LazyMethodGen bridgeMethod = makeBridgeMethod(clazz, theBridgeMethod); // The bridge method in this type will have the same + LazyMethodGen bridgeMethod = makeBridgeMethod(clazz, theBridgeMethod); // The + // bridge + // method + // in + // this + // type + // will + // have + // the + // same // signature as the one in the supertype - int newflags = bridgeMethod.getAccessFlags() | 0x00000040;/* BRIDGE = 0x00000040 */ + int newflags = bridgeMethod.getAccessFlags() | 0x00000040;/* + * BRIDGE = 0x00000040 + */ if ((newflags & 0x00000100) != 0) - newflags = newflags - 0x100;/* NATIVE = 0x00000100 - need to clear it */ + newflags = newflags - 0x100;/* + * NATIVE = 0x00000100 - need to clear it + */ bridgeMethod.setAccessFlags(newflags); Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType()); Type[] paramTypes = BcelWorld.makeBcelTypes(theBridgeMethod.getParameterTypes()); @@ -467,7 +485,8 @@ class BcelClassWeaver implements IClassWeaver { } boolean shadowMungerMatched = match(mg); if (shadowMungerMatched) { - // For matching mungers, add their declaring aspects to the list that affected this type + // For matching mungers, add their declaring aspects to the list + // that affected this type if (inReweavableMode || clazz.getType().isAspect()) aspectsAffectingType.addAll(findAspectsForMungers(mg)); isChanged = true; @@ -507,14 +526,17 @@ class BcelClassWeaver implements IClassWeaver { } } - // FIXME AV - see #75442, for now this is not enough to fix the bug, comment that out until we really fix it + // FIXME AV - see #75442, for now this is not enough to fix the bug, + // comment that out until we really fix it // // flush to save some memory - // PerObjectInterfaceTypeMunger.unregisterFromAsAdvisedBy(clazz.getType()); + // PerObjectInterfaceTypeMunger.unregisterFromAsAdvisedBy(clazz.getType() + // ); // finally, if we changed, we add in the introduced methods. if (isChanged) { clazz.getOrCreateWeaverStateInfo(inReweavableMode); - weaveInAddedMethods(); // FIXME asc are these potentially affected by declare annotation? + weaveInAddedMethods(); // FIXME asc are these potentially affected + // by declare annotation? } if (inReweavableMode) { @@ -537,7 +559,8 @@ class BcelClassWeaver implements IClassWeaver { return isChanged; } - // **************************** start of bridge method creation code ***************** + // **************************** start of bridge method creation code + // ***************** // FIXME asc tidy this lot up !! @@ -553,7 +576,8 @@ class BcelClassWeaver implements IClassWeaver { if (methodThatMightBeGettingOverridden.isPrivate()) return null; // we can't be overriding a private method if (!methodThatMightBeGettingOverridden.getName().equals(mname)) - return null; // names dont match (this will also skip and too) + return null; // names dont match (this will also skip and + // too) if (methodThatMightBeGettingOverridden.getParameterTypes().length != methodParamsArray.length) return null; // check same number of parameters if (!isVisibilityOverride(mmods, methodThatMightBeGettingOverridden, inSamePackage)) @@ -571,10 +595,14 @@ class BcelClassWeaver implements IClassWeaver { sameParams = false; } - // If the 'typeToCheck' represents a parameterized type then the method will be the parameterized form of the - // generic method in the generic type. So if the method was 'void m(List lt, T t)' and the parameterized type here - // is I then the method we are looking at will be 'void m(List lt, String t)' which when erased - // is 'void m(List lt,String t)' - so if the parameters *do* match then there is a generic method we are + // If the 'typeToCheck' represents a parameterized type then the method + // will be the parameterized form of the + // generic method in the generic type. So if the method was 'void + // m(List lt, T t)' and the parameterized type here + // is I then the method we are looking at will be 'void + // m(List lt, String t)' which when erased + // is 'void m(List lt,String t)' - so if the parameters *do* match then + // there is a generic method we are // overriding if (sameParams) { @@ -583,7 +611,8 @@ class BcelClassWeaver implements IClassWeaver { return methodThatMightBeGettingOverridden.getBackingGenericMember(); } else if (!methodThatMightBeGettingOverridden.getReturnType().getErasureSignature().equals(mrettype)) { // addressing the wierd situation from bug 147801 - // just check whether these things are in the right relationship for covariance... + // just check whether these things are in the right relationship + // for covariance... ResolvedType superReturn = typeToCheck.getWorld().resolve( UnresolvedType.forSignature(methodThatMightBeGettingOverridden.getReturnType().getErasureSignature())); ResolvedType subReturn = typeToCheck.getWorld().resolve(UnresolvedType.forSignature(mrettype)); @@ -635,11 +664,19 @@ class BcelClassWeaver implements IClassWeaver { String packageName = typeToCheck.getPackageName(); if (packageName == null) packageName = ""; - boolean inSamePackage = packageName.equals(mpkg); // used when looking at visibility rules + boolean inSamePackage = packageName.equals(mpkg); // used when looking + // at visibility + // rules ResolvedMember[] methods = typeToCheck.getDeclaredMethods(); for (int ii = 0; ii < methods.length; ii++) { - ResolvedMember methodThatMightBeGettingOverridden = methods[ii]; // the method we are going to check + ResolvedMember methodThatMightBeGettingOverridden = methods[ii]; // the + // method + // we + // are + // going + // to + // check ResolvedMember isOverriding = isOverriding(typeToCheck, methodThatMightBeGettingOverridden, mname, mrettype, mmods, inSamePackage, methodParamsArray); if (isOverriding != null) @@ -648,7 +685,8 @@ class BcelClassWeaver implements IClassWeaver { List l = typeToCheck.getInterTypeMungers(); for (Iterator iterator = l.iterator(); iterator.hasNext();) { Object o = iterator.next(); - // FIXME asc if its not a BcelTypeMunger then its an EclipseTypeMunger ... do I need to worry about that? + // FIXME asc if its not a BcelTypeMunger then its an + // EclipseTypeMunger ... do I need to worry about that? if (o instanceof BcelTypeMunger) { BcelTypeMunger element = (BcelTypeMunger) o; if (element.getMunger() instanceof NewMethodTypeMunger) { @@ -691,7 +729,8 @@ class BcelClassWeaver implements IClassWeaver { public static boolean calculateAnyRequiredBridgeMethods(BcelWorld world, LazyClassGen clazz) { world.ensureAdvancedConfigurationProcessed(); if (!world.isInJava5Mode()) - return false; // just double check... the caller should have already verified this + return false; // just double check... the caller should have already + // verified this if (clazz.isInterface()) return false; // dont bother if we're an interface boolean didSomething = false; // set if we build any bridge methods @@ -699,12 +738,14 @@ class BcelClassWeaver implements IClassWeaver { // So what methods do we have right now in this class? List /* LazyMethodGen */methods = clazz.getMethodGens(); - // Keep a set of all methods from this type - it'll help us to check if bridge methods + // Keep a set of all methods from this type - it'll help us to check if + // bridge methods // have already been created, we don't want to do it twice! Set methodsSet = new HashSet(); for (int i = 0; i < methods.size(); i++) { LazyMethodGen aMethod = (LazyMethodGen) methods.get(i); - methodsSet.add(aMethod.getName() + aMethod.getSignature()); // e.g. "foo(Ljava/lang/String;)V" + methodsSet.add(aMethod.getName() + aMethod.getSignature()); // e.g. + // "foo(Ljava/lang/String;)V" } // Now go through all the methods in this type @@ -738,7 +779,8 @@ class BcelClassWeaver implements IClassWeaver { pkgName, bm); if (overriddenMethod != null) { String key = new StringBuffer().append(overriddenMethod.getName()).append(overriddenMethod.getSignatureErased()) - .toString(); // pr 237419 + .toString(); // pr + // 237419 boolean alreadyHaveABridgeMethod = methodsSet.contains(key); if (!alreadyHaveABridgeMethod) { if (world.forDEBUG_bridgingCode) @@ -760,7 +802,8 @@ class BcelClassWeaver implements IClassWeaver { .getPackageName(), bm); if (overriddenMethod != null) { String key = new StringBuffer().append(overriddenMethod.getName()) - .append(overriddenMethod.getSignatureErased()).toString(); // pr 237419 + .append(overriddenMethod.getSignatureErased()).toString(); // pr + // 237419 boolean alreadyHaveABridgeMethod = methodsSet.contains(key); if (!alreadyHaveABridgeMethod) { createBridgeMethod(world, bridgeToCandidate, clazz, overriddenMethod); @@ -777,7 +820,8 @@ class BcelClassWeaver implements IClassWeaver { return didSomething; } - // **************************** end of bridge method creation code ***************** + // **************************** end of bridge method creation code + // ***************** /** * Weave any declare @method/@ctor statements into the members of the supplied class @@ -795,7 +839,8 @@ class BcelClassWeaver implements IClassWeaver { List itdMethodsCtors = getITDSubset(clazz, ResolvedTypeMunger.Method); itdMethodsCtors.addAll(getITDSubset(clazz, ResolvedTypeMunger.Constructor)); if (!itdMethodsCtors.isEmpty()) { - // Can't use the subset called 'decaMs' as it won't be right for ITDs... + // Can't use the subset called 'decaMs' as it won't be right for + // ITDs... isChanged = weaveAtMethodOnITDSRepeatedly(allDecams, itdMethodsCtors, reportedProblems); } @@ -820,7 +865,8 @@ class BcelClassWeaver implements IClassWeaver { if (decaM.matches(mg.getMemberView(), world)) { if (doesAlreadyHaveAnnotation(mg.getMemberView(), decaM, reportedProblems)) { - // remove the declare @method since don't want an error when + // remove the declare @method since don't want + // an error when // the annotation is already there unusedDecams.remove(decaM); continue; // skip this one... @@ -828,7 +874,7 @@ class BcelClassWeaver implements IClassWeaver { if (annotationsToAdd == null) annotationsToAdd = new ArrayList(); - AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); + AnnotationGen a = ((BcelAnnotation) decaM.getAnnotationX()).getBcelAnnotation(); AnnotationGen ag = new AnnotationGen(a, clazz.getConstantPool(), true); annotationsToAdd.add(ag); mg.addAnnotation(decaM.getAnnotationX()); @@ -838,11 +884,16 @@ class BcelClassWeaver implements IClassWeaver { reportMethodCtorWeavingMessage(clazz, mg.getMemberView(), decaM, mg.getDeclarationLineNumber()); isChanged = true; modificationOccured = true; - // remove the declare @method since have matched against it + // remove the declare @method since have matched + // against it unusedDecams.remove(decaM); } else { if (!decaM.isStarredAnnotationPattern()) - worthRetrying.add(decaM); // an annotation is specified that might be put on by a subsequent decaf + worthRetrying.add(decaM); // an annotation is + // specified that + // might be put on + // by a subsequent + // decaf } } @@ -855,7 +906,8 @@ class BcelClassWeaver implements IClassWeaver { DeclareAnnotation decaM = (DeclareAnnotation) iter.next(); if (decaM.matches(mg.getMemberView(), world)) { if (doesAlreadyHaveAnnotation(mg.getMemberView(), decaM, reportedProblems)) { - // remove the declare @method since don't want an error when + // remove the declare @method since don't + // want an error when // the annotation is already there unusedDecams.remove(decaM); continue; // skip this one... @@ -863,9 +915,11 @@ class BcelClassWeaver implements IClassWeaver { if (annotationsToAdd == null) annotationsToAdd = new ArrayList(); - AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation(); + AnnotationGen a = ((BcelAnnotation) decaM.getAnnotationX()).getBcelAnnotation(); // CUSTARD superfluous? - // AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true); + // AnnotationGen ag = new + // AnnotationGen(a,clazz.getConstantPool + // (),true); annotationsToAdd.add(a); mg.addAnnotation(decaM.getAnnotationX()); @@ -874,7 +928,8 @@ class BcelClassWeaver implements IClassWeaver { isChanged = true; modificationOccured = true; forRemoval.add(decaM); - // remove the declare @method since have matched against it + // remove the declare @method since have matched + // against it unusedDecams.remove(decaM); } } @@ -882,7 +937,8 @@ class BcelClassWeaver implements IClassWeaver { } if (annotationsToAdd != null) { Method oldMethod = mg.getMethod(); - MethodGen myGen = new MethodGen(oldMethod, clazz.getClassName(), clazz.getConstantPool(), false);// dont use + MethodGen myGen = new MethodGen(oldMethod, clazz.getClassName(), clazz.getConstantPool(), false);// dont + // use // tags, // they // won't @@ -1053,7 +1109,9 @@ class BcelClassWeaver implements IClassWeaver { } else { if (!decaF.isStarredAnnotationPattern()) - worthRetrying.add(decaF); // an annotation is specified that might be put on by a subsequent decaf + worthRetrying.add(decaF); // an annotation is specified + // that might be put on by a + // subsequent decaf } } @@ -1108,7 +1166,9 @@ class BcelClassWeaver implements IClassWeaver { modificationOccured = true; } else { if (!decaMC.isStarredAnnotationPattern()) - worthRetrying.add(decaMC); // an annotation is specified that might be put on by a subsequent decaf + worthRetrying.add(decaMC); // an annotation is specified + // that might be put on by a + // subsequent decaf } } @@ -1136,11 +1196,12 @@ class BcelClassWeaver implements IClassWeaver { return isChanged; } - private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX[] dontAddMeTwice) { + private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationAJ[] dontAddMeTwice) { for (int i = 0; i < dontAddMeTwice.length; i++) { - AnnotationX ann = dontAddMeTwice[i]; + AnnotationAJ ann = dontAddMeTwice[i]; if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())) { - // dontAddMeTwice[i] = null; // incase it really has been added twice! + // dontAddMeTwice[i] = null; // incase it really has been added + // twice! return true; } } @@ -1159,7 +1220,8 @@ class BcelClassWeaver implements IClassWeaver { // BUGWARNING not getting enough warnings out on declare @field ? // There is a potential problem here with warnings not coming out - this - // will occur if they are created on the second iteration round this loop. + // will occur if they are created on the second iteration round this + // loop. // We currently deactivate error reporting for the second time round. // A possible solution is to record what annotations were added by what // decafs and check that to see if an error needs to be reported - this @@ -1193,7 +1255,7 @@ class BcelClassWeaver implements IClassWeaver { List worthRetrying = new ArrayList(); boolean modificationOccured = false; - AnnotationX[] dontAddMeTwice = aBcelField.getAnnotations(); + AnnotationAJ[] dontAddMeTwice = aBcelField.getAnnotations(); // go through all the declare @field statements for (Iterator iter = decaFs.iterator(); iter.hasNext();) { @@ -1202,24 +1264,37 @@ class BcelClassWeaver implements IClassWeaver { if (!dontAddTwice(decaF, dontAddMeTwice)) { if (doesAlreadyHaveAnnotation(aBcelField, decaF, reportedProblems)) { - // remove the declare @field since don't want an error when + // remove the declare @field since don't + // want an error when // the annotation is already there unusedDecafs.remove(decaF); continue; } - if (decaF.getAnnotationX().isRuntimeVisible()) { // isAnnotationWithRuntimeRetention(clazz. + if (decaF.getAnnotationX().isRuntimeVisible()) { // isAnnotationWithRuntimeRetention + // ( + // clazz + // . // getJavaClass(world))){ - // if(decaF.getAnnotationTypeX().isAnnotationWithRuntimeRetention(world)){ - // it should be runtime visible, so put it on the Field - // Annotation a = decaF.getAnnotationX().getBcelAnnotation(); - // AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true); - // FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen()); + // if(decaF.getAnnotationTypeX(). + // isAnnotationWithRuntimeRetention(world)){ + // it should be runtime visible, so put it + // on the Field + // Annotation a = + // decaF.getAnnotationX().getBcelAnnotation + // (); + // AnnotationGen ag = new + // AnnotationGen(a,clazz + // .getConstantPoolGen(),true); + // FieldGen myGen = new + // FieldGen(fields[fieldCounter + // ],clazz.getConstantPoolGen()); // myGen.addAnnotation(ag); // Field newField = myGen.getField(); aBcelField.addAnnotation(decaF.getAnnotationX()); - // clazz.replaceField(fields[fieldCounter],newField); + // clazz.replaceField(fields[fieldCounter], + // newField); // fields[fieldCounter]=newField; } else { @@ -1232,11 +1307,16 @@ class BcelClassWeaver implements IClassWeaver { reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF); isChanged = true; modificationOccured = true; - // remove the declare @field since have matched against it + // remove the declare @field since have matched + // against it unusedDecafs.remove(decaF); } else { if (!decaF.isStarredAnnotationPattern()) - worthRetrying.add(decaF); // an annotation is specified that might be put on by a subsequent decaf + worthRetrying.add(decaF); // an annotation is + // specified that + // might be put on + // by a subsequent + // decaf } } @@ -1250,7 +1330,8 @@ class BcelClassWeaver implements IClassWeaver { if (decaF.matches(aBcelField, world)) { // below code is for recursive things if (doesAlreadyHaveAnnotation(aBcelField, decaF, reportedProblems)) { - // remove the declare @field since don't want an error when + // remove the declare @field since don't + // want an error when // the annotation is already there unusedDecafs.remove(decaF); continue; // skip this one... @@ -1261,7 +1342,8 @@ class BcelClassWeaver implements IClassWeaver { isChanged = true; modificationOccured = true; forRemoval.add(decaF); - // remove the declare @field since have matched against it + // remove the declare @field since have matched + // against it unusedDecafs.remove(decaF); } } @@ -1381,7 +1463,8 @@ class BcelClassWeaver implements IClassWeaver { aspectsAffectingType.add(bAdvice.getConcreteAspect().getName()); } } else { - // It is a 'Checker' - we don't need to remember aspects that only contributed Checkers... + // It is a 'Checker' - we don't need to remember aspects + // that only contributed Checkers... } } } @@ -1421,7 +1504,8 @@ class BcelClassWeaver implements IClassWeaver { r.associateWithShadow(s); if (s.getKind() == Shadow.PreInitialization) { // XXX assert first instruction is an ALOAD_0. - // a pre shadow goes from AFTER the first instruction (which we believe to + // a pre shadow goes from AFTER the first instruction (which we + // believe to // be an ALOAD_0) to just before the call to super r.associateWithTargets(Range.genStart(body, body.getStart().getNext()), Range.genEnd(body, call.getPrev())); } else { @@ -1471,7 +1555,8 @@ class BcelClassWeaver implements IClassWeaver { } // public BcelVar genTempVar(UnresolvedType typeX) { - // return new BcelVar(typeX.resolve(world), genTempVarIndex(typeX.getSize())); + // return new BcelVar(typeX.resolve(world), + // genTempVarIndex(typeX.getSize())); // } // // private int genTempVarIndex(int size) { @@ -1490,7 +1575,8 @@ class BcelClassWeaver implements IClassWeaver { public static void transformSynchronizedMethod(LazyMethodGen synchronizedMethod) { if (trace.isTraceEnabled()) trace.enter("transformSynchronizedMethod", synchronizedMethod); - // System.err.println("DEBUG: Transforming synchronized method: "+synchronizedMethod.getName()); + // System.err.println("DEBUG: Transforming synchronized method: "+ + // synchronizedMethod.getName()); final InstructionFactory fact = synchronizedMethod.getEnclosingClass().getFactory(); InstructionList body = synchronizedMethod.getBody(); InstructionList prepend = new InstructionList(); @@ -1515,8 +1601,10 @@ class BcelClassWeaver implements IClassWeaver { // MONITOREXIT logic: - // We basically need to wrap the code from the method in a finally block that - // will ensure monitorexit is called. Content on the finally block seems to + // We basically need to wrap the code from the method in a + // finally block that + // will ensure monitorexit is called. Content on the finally + // block seems to // be always: // // E1: ALOAD_1 @@ -1530,9 +1618,11 @@ class BcelClassWeaver implements IClassWeaver { finallyBlock.append(InstructionConstants.ATHROW); // finally -> E1 - // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) + // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line + // 21) // | LDC "hello" - // | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V + // | INVOKEVIRTUAL java.io.PrintStream.println + // (Ljava/lang/String;)V // | ALOAD_1 (line 20) // | MONITOREXIT // finally -> E1 @@ -1544,7 +1634,8 @@ class BcelClassWeaver implements IClassWeaver { // ATHROW // L0: RETURN (line 23) - // search for 'returns' and make them jump to the aload_,monitorexit + // search for 'returns' and make them jump to the + // aload_,monitorexit InstructionHandle walker = body.getStart(); List rets = new ArrayList(); while (walker != null) { @@ -1554,7 +1645,8 @@ class BcelClassWeaver implements IClassWeaver { walker = walker.getNext(); } if (!rets.isEmpty()) { - // need to ensure targeters for 'return' now instead target the load instruction + // need to ensure targeters for 'return' now instead target + // the load instruction // (so we never jump over the monitorexit logic) for (Iterator iter = rets.iterator(); iter.hasNext();) { @@ -1562,11 +1654,14 @@ class BcelClassWeaver implements IClassWeaver { InstructionList monitorExitBlock = new InstructionList(); monitorExitBlock.append(InstructionFactory.createLoad(enclosingClassType, slotForLockObject)); monitorExitBlock.append(InstructionConstants.MONITOREXIT); - // monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); - // element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); + // monitorExitBlock.append(Utility.copyInstruction(element + // .getInstruction())); + // element.setInstruction(InstructionFactory.createLoad( + // classType,slotForThis)); InstructionHandle monitorExitBlockStart = body.insert(element, monitorExitBlock); - // now move the targeters from the RET to the start of the monitorexit block + // now move the targeters from the RET to the start of + // the monitorexit block InstructionTargeter[] targeters = element.getTargetersArray(); if (targeters != null) { for (int i = 0; i < targeters.length; i++) { @@ -1577,9 +1672,12 @@ class BcelClassWeaver implements IClassWeaver { // ignore } else if (targeter instanceof LineNumberTag) { // ignore - // } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) { + // } else if (targeter instanceof + // InstructionBranch && + // ((InstructionBranch)targeter).isGoto()) { // // move it... - // targeter.updateTarget(element, monitorExitBlockStart); + // targeter.updateTarget(element, + // monitorExitBlockStart); } else if (targeter instanceof InstructionBranch) { // move it targeter.updateTarget(element, monitorExitBlockStart); @@ -1596,7 +1694,8 @@ class BcelClassWeaver implements IClassWeaver { InstructionHandle tryPosition = body.getStart(); InstructionHandle catchPosition = body.getEnd(); - body.insert(body.getStart(), prepend); // now we can put the monitorenter stuff on + body.insert(body.getStart(), prepend); // now we can put the + // monitorenter stuff on synchronizedMethod.getBody().append(finallyBlock); synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false); synchronizedMethod.addExceptionHandler(finallyStart, finallyStart.getNext(), finallyStart, null, false); @@ -1613,7 +1712,8 @@ class BcelClassWeaver implements IClassWeaver { // 7: pop // try // 8: ldc #61; //String java.lang.String - // 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; + // 10: invokestatic #44; //Method + // java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; // 13: dup // catch // 14: putstatic #59; //Field class$1:Ljava/lang/Class; @@ -1621,8 +1721,10 @@ class BcelClassWeaver implements IClassWeaver { // 20: new #46; //class java/lang/NoClassDefFoundError // 23: dup_x1 // 24: swap - // 25: invokevirtual #52; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; - // 28: invokespecial #54; //Method java/lang/NoClassDefFoundError."":(Ljava/lang/String;)V + // 25: invokevirtual #52; //Method + // java/lang/Throwable.getMessage:()Ljava/lang/String; + // 28: invokespecial #54; //Method + // java/lang/NoClassDefFoundError."":(Ljava/lang/String;)V // 31: athrow // 32: dup <-- partTwo (branch target) // 33: astore_0 @@ -1645,15 +1747,18 @@ class BcelClassWeaver implements IClassWeaver { synchronizedMethod.getEnclosingClass().getConstantPool()); synchronizedMethod.getEnclosingClass().addField(f, null); - // 10: invokestatic #44; //Method java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; + // 10: invokestatic #44; //Method + // java/lang/Class.forName:(Ljava/lang/String;)Ljava/lang/Class; // 13: dup // 14: putstatic #59; //Field class$1:Ljava/lang/Class; // 17: goto 32 // 20: new #46; //class java/lang/NoClassDefFoundError // 23: dup_x1 // 24: swap - // 25: invokevirtual #52; //Method java/lang/Throwable.getMessage:()Ljava/lang/String; - // 28: invokespecial #54; //Method java/lang/NoClassDefFoundError."":(Ljava/lang/String;)V + // 25: invokevirtual #52; //Method + // java/lang/Throwable.getMessage:()Ljava/lang/String; + // 28: invokespecial #54; //Method + // java/lang/NoClassDefFoundError."":(Ljava/lang/String;)V // 31: athrow String name = synchronizedMethod.getEnclosingClass().getName(); @@ -1687,20 +1792,25 @@ class BcelClassWeaver implements IClassWeaver { prepend.append(catchBlockForLiteralLoadingFail); prepend.append(parttwo); // MONITORENTER - // pseudocode: load up 'this' (var0), dup it, store it in a new local var (for use with monitorexit) and call + // pseudocode: load up 'this' (var0), dup it, store it in a new + // local var (for use with monitorexit) and call // monitorenter: // ALOAD_0, DUP, ASTORE_, MONITORENTER // prepend.append(InstructionFactory.createLoad(classType,0)); // prepend.append(InstructionFactory.createDup(1)); - // int slotForThis = synchronizedMethod.allocateLocal(classType); - // prepend.append(InstructionFactory.createStore(classType, slotForThis)); + // int slotForThis = + // synchronizedMethod.allocateLocal(classType); + // prepend.append(InstructionFactory.createStore(classType, + // slotForThis)); // prepend.append(InstructionFactory.MONITORENTER); // MONITOREXIT // here be dragons - // We basically need to wrap the code from the method in a finally block that - // will ensure monitorexit is called. Content on the finally block seems to + // We basically need to wrap the code from the method in a + // finally block that + // will ensure monitorexit is called. Content on the finally + // block seems to // be always: // // E1: ALOAD_1 @@ -1714,9 +1824,11 @@ class BcelClassWeaver implements IClassWeaver { finallyBlock.append(InstructionConstants.ATHROW); // finally -> E1 - // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line 21) + // | GETSTATIC java.lang.System.out Ljava/io/PrintStream; (line + // 21) // | LDC "hello" - // | INVOKEVIRTUAL java.io.PrintStream.println (Ljava/lang/String;)V + // | INVOKEVIRTUAL java.io.PrintStream.println + // (Ljava/lang/String;)V // | ALOAD_1 (line 20) // | MONITOREXIT // finally -> E1 @@ -1729,7 +1841,8 @@ class BcelClassWeaver implements IClassWeaver { // L0: RETURN (line 23) // frameEnv.put(donorFramePos, thisSlot); - // search for 'returns' and make them to the aload_,monitorexit + // search for 'returns' and make them to the + // aload_,monitorexit InstructionHandle walker = body.getStart(); List rets = new ArrayList(); while (walker != null) { // !walker.equals(body.getEnd())) { @@ -1739,20 +1852,25 @@ class BcelClassWeaver implements IClassWeaver { walker = walker.getNext(); } if (rets.size() > 0) { - // need to ensure targeters for 'return' now instead target the load instruction + // need to ensure targeters for 'return' now instead target + // the load instruction // (so we never jump over the monitorexit logic) for (Iterator iter = rets.iterator(); iter.hasNext();) { InstructionHandle element = (InstructionHandle) iter.next(); - // System.err.println("Adding monitor exit block at "+element); + // System.err.println("Adding monitor exit block at "+ + // element); InstructionList monitorExitBlock = new InstructionList(); monitorExitBlock.append(InstructionFactory.createLoad(classType, slotForThis)); monitorExitBlock.append(InstructionConstants.MONITOREXIT); - // monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); - // element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); + // monitorExitBlock.append(Utility.copyInstruction(element + // .getInstruction())); + // element.setInstruction(InstructionFactory.createLoad( + // classType,slotForThis)); InstructionHandle monitorExitBlockStart = body.insert(element, monitorExitBlock); - // now move the targeters from the RET to the start of the monitorexit block + // now move the targeters from the RET to the start of + // the monitorexit block InstructionTargeter[] targeters = element.getTargetersArray(); if (targeters != null) { for (int i = 0; i < targeters.length; i++) { @@ -1763,9 +1881,11 @@ class BcelClassWeaver implements IClassWeaver { // ignore } else if (targeter instanceof LineNumberTag) { // ignore - // } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { + // } else if (targeter instanceof GOTO || + // targeter instanceof GOTO_W) { // // move it... - // targeter.updateTarget(element, monitorExitBlockStart); + // targeter.updateTarget(element, + // monitorExitBlockStart); } else if (targeter instanceof InstructionBranch) { // move it targeter.updateTarget(element, monitorExitBlockStart); @@ -1776,7 +1896,9 @@ class BcelClassWeaver implements IClassWeaver { } } } - // body = rewriteWithMonitorExitCalls(body,fact,true,slotForThis,classType); + // body = + // rewriteWithMonitorExitCalls(body,fact,true,slotForThis, + // classType); // synchronizedMethod.setBody(body); // now the magic, putting the finally block around the code @@ -1784,7 +1906,8 @@ class BcelClassWeaver implements IClassWeaver { InstructionHandle tryPosition = body.getStart(); InstructionHandle catchPosition = body.getEnd(); - body.insert(body.getStart(), prepend); // now we can put the monitorenter stuff on + body.insert(body.getStart(), prepend); // now we can put the + // monitorenter stuff on synchronizedMethod.getBody().append(finallyBlock); synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false); @@ -1797,7 +1920,8 @@ class BcelClassWeaver implements IClassWeaver { // TRANSFORMING NON STATIC METHOD Type classType = BcelWorld.makeBcelType(synchronizedMethod.getEnclosingClass().getType()); // MONITORENTER - // pseudocode: load up 'this' (var0), dup it, store it in a new local var (for use with monitorexit) and call + // pseudocode: load up 'this' (var0), dup it, store it in a new + // local var (for use with monitorexit) and call // monitorenter: // ALOAD_0, DUP, ASTORE_, MONITORENTER prepend.append(InstructionFactory.createLoad(classType, 0)); @@ -1809,8 +1933,10 @@ class BcelClassWeaver implements IClassWeaver { // MONITOREXIT - // We basically need to wrap the code from the method in a finally block that - // will ensure monitorexit is called. Content on the finally block seems to + // We basically need to wrap the code from the method in a finally + // block that + // will ensure monitorexit is called. Content on the finally block + // seems to // be always: // // E1: ALOAD_1 @@ -1849,20 +1975,25 @@ class BcelClassWeaver implements IClassWeaver { walker = walker.getNext(); } if (!rets.isEmpty()) { - // need to ensure targeters for 'return' now instead target the load instruction + // need to ensure targeters for 'return' now instead target the + // load instruction // (so we never jump over the monitorexit logic) for (Iterator iter = rets.iterator(); iter.hasNext();) { InstructionHandle element = (InstructionHandle) iter.next(); - // System.err.println("Adding monitor exit block at "+element); + // System.err.println("Adding monitor exit block at "+element + // ); InstructionList monitorExitBlock = new InstructionList(); monitorExitBlock.append(InstructionFactory.createLoad(classType, slotForThis)); monitorExitBlock.append(InstructionConstants.MONITOREXIT); - // monitorExitBlock.append(Utility.copyInstruction(element.getInstruction())); - // element.setInstruction(InstructionFactory.createLoad(classType,slotForThis)); + // monitorExitBlock.append(Utility.copyInstruction(element. + // getInstruction())); + // element.setInstruction(InstructionFactory.createLoad( + // classType,slotForThis)); InstructionHandle monitorExitBlockStart = body.insert(element, monitorExitBlock); - // now move the targeters from the RET to the start of the monitorexit block + // now move the targeters from the RET to the start of the + // monitorexit block InstructionTargeter[] targeters = element.getTargetersArray(); if (targeters != null) { for (int i = 0; i < targeters.length; i++) { @@ -1873,9 +2004,11 @@ class BcelClassWeaver implements IClassWeaver { // ignore } else if (targeter instanceof LineNumberTag) { // ignore - // } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) { + // } else if (targeter instanceof GOTO || + // targeter instanceof GOTO_W) { // // move it... - // targeter.updateTarget(element, monitorExitBlockStart); + // targeter.updateTarget(element, + // monitorExitBlockStart); } else if (targeter instanceof InstructionBranch) { // move it targeter.updateTarget(element, monitorExitBlockStart); @@ -1892,18 +2025,21 @@ class BcelClassWeaver implements IClassWeaver { InstructionHandle tryPosition = body.getStart(); InstructionHandle catchPosition = body.getEnd(); - body.insert(body.getStart(), prepend); // now we can put the monitorenter stuff on + body.insert(body.getStart(), prepend); // now we can put the + // monitorenter stuff on synchronizedMethod.getBody().append(finallyBlock); synchronizedMethod.addExceptionHandler(tryPosition, catchPosition, finallyStart, null/* ==finally */, false); synchronizedMethod.addExceptionHandler(finallyStart, finallyStart.getNext(), finallyStart, null, false); // also the exception handling for the finally block jumps to itself - // max locals will already have been modified in the allocateLocal() call + // max locals will already have been modified in the allocateLocal() + // call // synchronized bit is removed on LazyMethodGen.pack() } - // gonna have to go through and change all aload_0s to load the var from a variable, + // gonna have to go through and change all aload_0s to load the var from + // a variable, // going to add a new variable for the this var if (trace.isTraceEnabled()) @@ -1933,7 +2069,8 @@ class BcelClassWeaver implements IClassWeaver { boolean isAcrossClass = donorCpg != recipientCpg; - // first pass: copy the instructions directly, populate the srcToDest map, + // first pass: copy the instructions directly, populate the srcToDest + // map, // fix frame instructions for (InstructionHandle src = sourceList.getStart(); src != null; src = src.getNext()) { Instruction fresh = Utility.copyInstruction(src.getInstruction()); @@ -1941,7 +2078,8 @@ class BcelClassWeaver implements IClassWeaver { // OPTIMIZE optimize this stuff? if (fresh.isConstantPoolInstruction()) { - // need to reset index to go to new constant pool. This is totally + // need to reset index to go to new constant pool. This is + // totally // a computation leak... we're testing this LOTS of times. Sigh. if (isAcrossClass) { InstructionCP cpi = (InstructionCP) fresh; @@ -2040,9 +2178,11 @@ class BcelClassWeaver implements IClassWeaver { freshRange.associateWithTargets(dest, (InstructionHandle) srcToDest.get(oldRange.getEnd())); shadowMap.put(oldRange, freshRange); // recipient.matchedShadows.add(freshShadow); - // XXX should go through the NEW copied shadow and update + // XXX should go through the NEW copied shadow and + // update // the thisVar, targetVar, and argsVar - // ??? Might want to also go through at this time and add + // ??? Might want to also go through at this time and + // add // "extra" vars to the shadow. } } @@ -2053,7 +2193,8 @@ class BcelClassWeaver implements IClassWeaver { return ret; } - // static InstructionList rewriteWithMonitorExitCalls(InstructionList sourceList,InstructionFactory fact,boolean keepReturns,int + // static InstructionList rewriteWithMonitorExitCalls(InstructionList + // sourceList,InstructionFactory fact,boolean keepReturns,int // monitorVarSlot,Type monitorVarType) // { // InstructionList footer = new InstructionList(); @@ -2063,21 +2204,25 @@ class BcelClassWeaver implements IClassWeaver { // // Map srcToDest = new HashMap(); // - // // first pass: copy the instructions directly, populate the srcToDest map, + // // first pass: copy the instructions directly, populate the srcToDest + // map, // // fix frame instructions - // for (InstructionHandle src = sourceList.getStart(); src != null; src = src.getNext()) { + // for (InstructionHandle src = sourceList.getStart(); src != null; src = + // src.getNext()) { // Instruction fresh = Utility.copyInstruction(src.getInstruction()); // InstructionHandle dest; // if (src.getInstruction() == Range.RANGEINSTRUCTION) { // dest = newList.append(Range.RANGEINSTRUCTION); // } else if (fresh.isReturnInstruction()) { // if (keepReturns) { - // newList.append(InstructionFactory.createLoad(monitorVarType,monitorVarSlot)); + // newList.append(InstructionFactory.createLoad(monitorVarType,monitorVarSlot + // )); // newList.append(InstructionConstants.MONITOREXIT); // dest = newList.append(fresh); // } else { // dest = - // newList.append(InstructionFactory.createBranchInstruction(Constants.GOTO, end)); + // newList.append(InstructionFactory.createBranchInstruction(Constants.GOTO, + // end)); // } // } else if (fresh instanceof InstructionBranch) { // dest = newList.append((InstructionBranch) fresh); @@ -2106,7 +2251,8 @@ class BcelClassWeaver implements IClassWeaver { // // // second pass: retarget branch instructions, copy ranges and tags // Map tagMap = new HashMap(); - // for (InstructionHandle dest = newList.getStart(), src = sourceList.getStart(); + // for (InstructionHandle dest = newList.getStart(), src = + // sourceList.getStart(); // dest != null; // dest = dest.getNext(), src = src.getNext()) { // Instruction inst = dest.getInstruction(); @@ -2151,7 +2297,8 @@ class BcelClassWeaver implements IClassWeaver { // ExceptionRange er = (ExceptionRange) old; // if (er.getStart() == src) { // ExceptionRange freshEr = - // new ExceptionRange(newList/*recipient.getBody()*/,er.getCatchType(),er.getPriority()); + // new ExceptionRange(newList/*recipient.getBody()*/,er.getCatchType(),er. + // getPriority()); // freshEr.associateWithTargets( // dest, // (InstructionHandle)srcToDest.get(er.getEnd()), @@ -2251,7 +2398,8 @@ class BcelClassWeaver implements IClassWeaver { } // void addPerSingletonField(Member field) { - // ObjectType aspectType = (ObjectType) BcelWorld.makeBcelType(field.getReturnType()); + // ObjectType aspectType = (ObjectType) + // BcelWorld.makeBcelType(field.getReturnType()); // String aspectName = field.getReturnType().getName(); // // LazyMethodGen clinit = clazz.getStaticInitializer(); @@ -2260,8 +2408,10 @@ class BcelClassWeaver implements IClassWeaver { // // setup.append(fact.createNew(aspectType)); // setup.append(InstructionFactory.createDup(1)); - // setup.append(fact.createInvoke(aspectName, "", Type.VOID, new Type[0], Constants.INVOKESPECIAL)); - // setup.append(fact.createFieldAccess(aspectName, field.getName(), aspectType, Constants.PUTSTATIC)); + // setup.append(fact.createInvoke(aspectName, "", Type.VOID, new + // Type[0], Constants.INVOKESPECIAL)); + // setup.append(fact.createFieldAccess(aspectName, field.getName(), + // aspectType, Constants.PUTSTATIC)); // clinit.getBody().insert(setup); // } @@ -2313,8 +2463,10 @@ class BcelClassWeaver implements IClassWeaver { } else if (effective.isWeaveBody()) { ResolvedMember rm = effective.getEffectiveSignature(); - // Annotations for things with effective signatures are never stored in the effective - // signature itself - we have to hunt for them. Storing them in the effective signature + // Annotations for things with effective signatures are + // never stored in the effective + // signature itself - we have to hunt for them. Storing them + // in the effective signature // would mean keeping two sets up to date (no way!!) fixAnnotationsForResolvedMember(rm, mg.getMemberView()); @@ -2330,7 +2482,8 @@ class BcelClassWeaver implements IClassWeaver { match(mg, h, enclosingShadow, shadowAccumulator); } } - // FIXME asc change from string match if we can, rather brittle. this check actually prevents field-exec jps + // FIXME asc change from string match if we can, rather brittle. + // this check actually prevents field-exec jps if (canMatch(enclosingShadow.getKind()) && !(mg.getName().charAt(0) == 'a' && mg.getName().startsWith("ajc$interFieldInit"))) { if (match(enclosingShadow, shadowAccumulator)) { @@ -2398,7 +2551,8 @@ class BcelClassWeaver implements IClassWeaver { } // actually, you only need to inline the self constructors that are - // in a particular group (partition the constructors into groups where members + // in a particular group (partition the constructors into groups where + // members // call or are called only by those in the group). Then only inline // constructors // in groups where at least one initialization jp matched. Future work. @@ -2459,15 +2613,21 @@ class BcelClassWeaver implements IClassWeaver { return; if (!ih.getInstruction().isStoreInstruction() && ih.getInstruction().getOpcode() != Constants.NOP) { - // If using cobertura, the catch block stats with INVOKESTATIC rather than ASTORE, in order that the + // If using cobertura, the catch block stats with + // INVOKESTATIC rather than ASTORE, in order that + // the // ranges - // for the methodcall and exceptionhandler shadows that occur at this same - // line, we need to modify the instruction list to split them - adding a - // NOP before the invokestatic that gets all the targeters + // for the methodcall and exceptionhandler shadows + // that occur at this same + // line, we need to modify the instruction list to + // split them - adding a + // NOP before the invokestatic that gets all the + // targeters // that were aimed at the INVOKESTATIC mg.getBody().insert(ih, InstructionConstants.NOP); InstructionHandle newNOP = ih.getPrev(); - // what about a try..catch that starts at the start of the exception handler? need to only include + // what about a try..catch that starts at the start + // of the exception handler? need to only include // certain targeters really. er.updateTarget(ih, newNOP, mg.getBody()); for (int ii = 0; ii < targeters.length; ii++) { @@ -2487,10 +2647,14 @@ class BcelClassWeaver implements IClassWeaver { FieldInstruction fi = (FieldInstruction) i; if (fi.opcode == Constants.PUTFIELD || fi.opcode == Constants.PUTSTATIC) { - // check for sets of constant fields. We first check the previous - // instruction. If the previous instruction is a LD_WHATEVER (push - // constant on the stack) then we must resolve the field to determine - // if it's final. If it is final, then we don't generate a shadow. + // check for sets of constant fields. We first check the + // previous + // instruction. If the previous instruction is a LD_WHATEVER + // (push + // constant on the stack) then we must resolve the field to + // determine + // if it's final. If it is final, then we don't generate a + // shadow. InstructionHandle prevHandle = ih.getPrev(); Instruction prevI = prevHandle.getInstruction(); if (Utility.isConstantPushInstruction(prevI)) { @@ -2499,7 +2663,8 @@ class BcelClassWeaver implements IClassWeaver { if (resolvedField == null) { // we can't find the field, so it's not a join point. } else if (Modifier.isFinal(resolvedField.getModifiers())) { - // it's final, so it's the set of a final constant, so it's + // it's final, so it's the set of a final constant, so + // it's // not a join point according to 1.0.6 and 1.1. } else { if (canMatch(Shadow.FieldSet)) @@ -2524,7 +2689,8 @@ class BcelClassWeaver implements IClassWeaver { // we are private matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); } else { - // we are a super call, and this is not a join point in AspectJ-1.{0,1} + // we are a super call, and this is not a join point in + // AspectJ-1.{0,1} } } else { matchInvokeInstruction(mg, ih, ii, enclosingShadow, shadowAccumulator); @@ -2561,7 +2727,8 @@ class BcelClassWeaver implements IClassWeaver { // } else if (i instanceof AALOAD ) { // AALOAD arrayLoad = (AALOAD)i; // Type arrayType = arrayLoad.getType(clazz.getConstantPoolGen()); - // BcelShadow arrayLoadShadow = BcelShadow.makeArrayLoadCall(world,mg,ih,enclosingShadow); + // BcelShadow arrayLoadShadow = + // BcelShadow.makeArrayLoadCall(world,mg,ih,enclosingShadow); // match(arrayLoadShadow,shadowAccumulator); // } else if (i instanceof AASTORE) { // // ... magic required @@ -2695,7 +2862,8 @@ class BcelClassWeaver implements IClassWeaver { } else { ResolvedMember realthing = AjcMemberMaker.interMethodDispatcher(rm.resolve(world), memberHostType).resolve( world); - // ResolvedMember resolvedDooberry = world.resolve(realthing); + // ResolvedMember resolvedDooberry = + // world.resolve(realthing); ResolvedMember theRealMember = findResolvedMemberNamed(memberHostType.resolve(world), realthing.getName()); // AMC temp guard for M4 if (theRealMember == null) { @@ -2723,7 +2891,8 @@ class BcelClassWeaver implements IClassWeaver { } catch (UnsupportedOperationException ex) { throw ex; } catch (Throwable t) { - // FIXME asc remove this catch after more testing has confirmed the above stuff is OK + // FIXME asc remove this catch after more testing has confirmed the + // above stuff is OK throw new BCException("Unexpectedly went bang when searching for annotations on " + rm, t); } } @@ -2752,7 +2921,8 @@ class BcelClassWeaver implements IClassWeaver { AjAttribute.EffectiveSignatureAttribute effectiveSig = declaredSig.getEffectiveSignature(); if (effectiveSig == null) return; - // System.err.println("call to inter-type member: " + effectiveSig); + // System.err.println("call to inter-type member: " + + // effectiveSig); if (effectiveSig.isWeaveBody()) return; @@ -2770,13 +2940,16 @@ class BcelClassWeaver implements IClassWeaver { } } - // static ... so all worlds will share the config for the first one created... + // static ... so all worlds will share the config for the first one + // created... private static boolean checkedXsetForLowLevelContextCapturing = false; private static boolean captureLowLevelContext = false; private boolean match(BcelShadow shadow, List shadowAccumulator) { // System.err.println("match: " + shadow); - if (captureLowLevelContext) { // duplicate blocks - one with context capture, one without, seems faster than multiple + if (captureLowLevelContext) { // duplicate blocks - one with context + // capture, one without, seems faster + // than multiple // 'ifs()' ContextToken shadowMatchToken = CompilationAndWeavingContext.enteringPhase( CompilationAndWeavingContext.MATCHING_SHADOW, shadow); @@ -2825,7 +2998,8 @@ class BcelClassWeaver implements IClassWeaver { List shadows = mg.matchedShadows; if (shadows == null) return; - // We depend on a partial order such that inner shadows are earlier on the list + // We depend on a partial order such that inner shadows are earlier on + // the list // than outer shadows. That's fine. This order is preserved if: // A preceeds B iff B.getStart() is LATER THAN A.getStart(). @@ -2856,7 +3030,8 @@ class BcelClassWeaver implements IClassWeaver { return world; } - // Called by the BcelWeaver to let us know all BcelClassWeavers need to collect reweavable info + // Called by the BcelWeaver to let us know all BcelClassWeavers need to + // collect reweavable info public static void setReweavableMode(boolean mode) { inReweavableMode = mode; } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelField.java b/weaver/src/org/aspectj/weaver/bcel/BcelField.java index 4383161bd..a9d9859af 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelField.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelField.java @@ -26,7 +26,7 @@ import org.aspectj.apache.bcel.classfile.Synthetic; import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; import org.aspectj.apache.bcel.generic.FieldGen; import org.aspectj.weaver.AjAttribute; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ResolvedMemberImpl; import org.aspectj.weaver.ResolvedType; @@ -42,7 +42,7 @@ final class BcelField extends ResolvedMemberImpl { private Field field; private boolean isAjSynthetic; private boolean isSynthetic = false; - private AnnotationX[] annotations; + private AnnotationAJ[] annotations; private World world; private BcelObjectType bcelObjectType; private UnresolvedType genericFieldType = null; @@ -129,12 +129,12 @@ final class BcelField extends ResolvedMemberImpl { return ret; } - public AnnotationX[] getAnnotations() { + public AnnotationAJ[] getAnnotations() { ensureAnnotationTypesRetrieved(); return annotations; } - public AnnotationX getAnnotationOfType(UnresolvedType ofType) { + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { ensureAnnotationTypesRetrieved(); for (int i = 0; i < annotations.length; i++) { if (annotations[i].getTypeName().equals(ofType.getName())) @@ -148,24 +148,24 @@ final class BcelField extends ResolvedMemberImpl { AnnotationGen annos[] = field.getAnnotations(); if (annos == null || annos.length == 0) { annotationTypes = Collections.EMPTY_SET; - annotations = AnnotationX.NONE; + annotations = AnnotationAJ.EMPTY_ARRAY; } else { annotationTypes = new HashSet(); - annotations = new AnnotationX[annos.length]; + annotations = new AnnotationAJ[annos.length]; for (int i = 0; i < annos.length; i++) { AnnotationGen annotation = annos[i]; annotationTypes.add(world.resolve(UnresolvedType.forSignature(annotation.getTypeSignature()))); - annotations[i] = new AnnotationX(annotation, world); + annotations[i] = new BcelAnnotation(annotation, world); } } } } - public void addAnnotation(AnnotationX annotation) { + public void addAnnotation(AnnotationAJ annotation) { ensureAnnotationTypesRetrieved(); // Add it to the set of annotations int len = annotations.length; - AnnotationX[] ret = new AnnotationX[len + 1]; + AnnotationAJ[] ret = new AnnotationAJ[len + 1]; System.arraycopy(annotations, 0, ret, 0, len); ret[len] = annotation; annotations = ret; @@ -200,7 +200,7 @@ final class BcelField extends ResolvedMemberImpl { AnnotationGen[] alreadyHas = fg.getAnnotations(); if (annotations != null) { for (int i = 0; i < annotations.length; i++) { - AnnotationX array_element = annotations[i]; + AnnotationAJ array_element = annotations[i]; boolean alreadyHasIt = false; for (int j = 0; j < alreadyHas.length; j++) { AnnotationGen gen = alreadyHas[j]; @@ -208,7 +208,7 @@ final class BcelField extends ResolvedMemberImpl { alreadyHasIt = true; } if (!alreadyHasIt) - fg.addAnnotation(new AnnotationGen(array_element.getBcelAnnotation(), cpg, true)); + fg.addAnnotation(new AnnotationGen(((BcelAnnotation) array_element).getBcelAnnotation(), cpg, true)); } } field = fg.getField(); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index f443a7361..79e4f76f6 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -37,7 +37,7 @@ import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.SourceLocation; import org.aspectj.weaver.AjAttribute; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.MemberKind; @@ -56,12 +56,15 @@ public final class BcelMethod extends ResolvedMemberImpl { // 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 ResolvedPointcutDefinition preResolvedPointcut; // used when ajc has + // pre-resolved the + // pointcut of some + // @Advice private AjAttribute.EffectiveSignatureAttribute effectiveSignature; private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber; - private AnnotationX[] annotations = null; - private AnnotationX[][] parameterAnnotations = null; + private AnnotationAJ[] annotations = null; + private AnnotationAJ[][] parameterAnnotations = null; private BcelObjectType bcelObjectType; private int bitflags; @@ -71,7 +74,9 @@ public final class BcelMethod extends ResolvedMemberImpl { 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 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; @@ -123,15 +128,15 @@ public final class BcelMethod extends ResolvedMemberImpl { if (varTable == null) { // do we have an annotation with the argNames value specified... if (hasAnnotations()) { - AnnotationX[] axs = getAnnotations(); + AnnotationAJ[] axs = getAnnotations(); for (int i = 0; i < axs.length; i++) { - AnnotationX annotationX = axs[i]; + AnnotationAJ annotationX = axs[i]; String typename = annotationX.getTypeName(); 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 = annotationX.getBcelAnnotation(); + AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation(); if (a != null) { List values = a.getValues(); for (Iterator iterator = values.iterator(); iterator.hasNext();) { @@ -198,7 +203,8 @@ public final class BcelMethod extends ResolvedMemberImpl { // System.out.println("found effective: " + this); effectiveSignature = (AjAttribute.EffectiveSignatureAttribute) a; } else if (a instanceof AjAttribute.PointcutDeclarationAttribute) { - // this is an @AspectJ annotated advice method, with pointcut pre-resolved by ajc + // this is an @AspectJ annotated advice method, with pointcut + // pre-resolved by ajc preResolvedPointcut = ((AjAttribute.PointcutDeclarationAttribute) a).reify(); } else { throw new BCException("weird method attribute " + a); @@ -206,7 +212,8 @@ public final class BcelMethod extends ResolvedMemberImpl { } } - // for testing - if we have this attribute, return it - will return null if it doesnt know anything + // 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(), @@ -247,7 +254,10 @@ public final class BcelMethod extends ResolvedMemberImpl { } public boolean isAjSynthetic() { - return (bitflags & IS_AJ_SYNTHETIC) != 0;// isAjSynthetic; // || getName().startsWith(NameMangler.PREFIX); + return (bitflags & IS_AJ_SYNTHETIC) != 0;// isAjSynthetic; // || + // getName( + // ).startsWith(NameMangler + // .PREFIX); } // FIXME ??? needs an isSynthetic method @@ -311,12 +321,12 @@ public final class BcelMethod extends ResolvedMemberImpl { return false; } - public AnnotationX[] getAnnotations() { + public AnnotationAJ[] getAnnotations() { ensureAnnotationsRetrieved(); if ((bitflags & HAS_ANNOTATIONS) != 0) { return annotations; } else { - return AnnotationX.NONE; + return AnnotationAJ.EMPTY_ARRAY; } } @@ -327,7 +337,7 @@ public final class BcelMethod extends ResolvedMemberImpl { return ret; } - public AnnotationX getAnnotationOfType(UnresolvedType ofType) { + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { ensureAnnotationsRetrieved(); if ((bitflags & HAS_ANNOTATIONS) == 0) return null; @@ -338,15 +348,15 @@ public final class BcelMethod extends ResolvedMemberImpl { return null; } - public void addAnnotation(AnnotationX annotation) { + public void addAnnotation(AnnotationAJ annotation) { ensureAnnotationsRetrieved(); if ((bitflags & HAS_ANNOTATIONS) == 0) { - annotations = new AnnotationX[1]; + annotations = new AnnotationAJ[1]; annotations[0] = annotation; } else { // Add it to the set of annotations int len = annotations.length; - AnnotationX[] ret = new AnnotationX[len + 1]; + AnnotationAJ[] ret = new AnnotationAJ[len + 1]; System.arraycopy(annotations, 0, ret, 0, len); ret[len] = annotation; annotations = ret; @@ -357,7 +367,8 @@ public final class BcelMethod extends ResolvedMemberImpl { if (annotationTypes == Collections.EMPTY_SET) annotationTypes = new HashSet(); annotationTypes.add(UnresolvedType.forName(annotation.getTypeName()).resolve(bcelObjectType.getWorld())); - // FIXME asc looks like we are managing two 'bunches' of annotations, one + // FIXME asc looks like we are managing two 'bunches' of annotations, + // one // here and one in the real 'method' - should we reduce it to one layer? // method.addAnnotation(annotation.getBcelAnnotation()); } @@ -372,11 +383,11 @@ public final class BcelMethod extends ResolvedMemberImpl { AnnotationGen annos[] = method.getAnnotations(); if (annos.length != 0) { annotationTypes = new HashSet(); - annotations = new AnnotationX[annos.length]; + annotations = new AnnotationAJ[annos.length]; for (int i = 0; i < annos.length; i++) { AnnotationGen annotation = annos[i]; annotationTypes.add(bcelObjectType.getWorld().resolve(UnresolvedType.forSignature(annotation.getTypeSignature()))); - annotations[i] = new AnnotationX(annotation, bcelObjectType.getWorld()); + annotations[i] = new BcelAnnotation(annotation, bcelObjectType.getWorld()); } bitflags |= HAS_ANNOTATIONS; } else { @@ -394,13 +405,13 @@ public final class BcelMethod extends ResolvedMemberImpl { parameterAnnotations = BcelMethod.NO_PARAMETER_ANNOTATIONXS; } else { AnnotationGen annos[][] = method.getParameterAnnotations(); - parameterAnnotations = new AnnotationX[annos.length][]; + parameterAnnotations = new AnnotationAJ[annos.length][]; parameterAnnotationTypes = new ResolvedType[annos.length][]; for (int i = 0; i < annos.length; i++) { - parameterAnnotations[i] = new AnnotationX[annos[i].length]; + parameterAnnotations[i] = new AnnotationAJ[annos[i].length]; parameterAnnotationTypes[i] = new ResolvedType[annos[i].length]; for (int j = 0; j < annos[i].length; j++) { - parameterAnnotations[i][j] = new AnnotationX(annos[i][j], bcelObjectType.getWorld()); + parameterAnnotations[i][j] = new BcelAnnotation(annos[i][j], bcelObjectType.getWorld()); parameterAnnotationTypes[i][j] = bcelObjectType.getWorld().resolve( UnresolvedType.forSignature(annos[i][j].getTypeSignature())); } @@ -409,7 +420,7 @@ public final class BcelMethod extends ResolvedMemberImpl { } } - public AnnotationX[][] getParameterAnnotations() { + public AnnotationAJ[][] getParameterAnnotations() { ensureParameterAnnotationsRetrieved(); return parameterAnnotations; } @@ -482,7 +493,8 @@ public final class BcelMethod extends ResolvedMemberImpl { Signature.FormalTypeParameter[] parentFormals = bcelObjectType.getAllFormals(); Signature.FormalTypeParameter[] formals = new Signature.FormalTypeParameter[parentFormals.length + mSig.formalTypeParameters.length]; - // put method formal in front of type formals for overriding in lookup + // 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); Signature.TypeSignature returnTypeSignature = mSig.returnType; @@ -534,7 +546,8 @@ public final class BcelMethod extends ResolvedMemberImpl { return (bitflags & IS_SYNTHETIC) != 0;// isSynthetic; } - // Pre Java5 synthetic is an attribute 'Synthetic', post Java5 it is a modifier (4096 or 0x1000) + // 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; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java index 4fbab9af4..7f2dd5787 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java @@ -37,8 +37,8 @@ import org.aspectj.bridge.MessageUtil; import org.aspectj.weaver.AbstractReferenceTypeDelegate; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjcMemberMaker; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AnnotationTargetKind; -import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ReferenceType; @@ -73,7 +73,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { private ResolvedMember[] fields = null; private ResolvedMember[] methods = null; private ResolvedType[] annotationTypes = null; - private AnnotationX[] annotations = null; + private AnnotationAJ[] annotations = null; private TypeVariable[] typeVars = null; private String retentionPolicy; private AnnotationTargetKind[] annotationTargetKinds; @@ -99,14 +99,16 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { private boolean isNested; private boolean isObject = false; // set upon construction private boolean isAnnotationStyleAspect = false;// set upon construction - private boolean isCodeStyleAspect = false; // not redundant with field above! + private boolean isCodeStyleAspect = false; // not redundant with field + // above! private int bitflag = 0x0000; // discovery bits private static final int DISCOVERED_ANNOTATION_RETENTION_POLICY = 0x0001; private static final int UNPACKED_GENERIC_SIGNATURE = 0x0002; - private static final int UNPACKED_AJATTRIBUTES = 0x0004; // see note(1) below + private static final int UNPACKED_AJATTRIBUTES = 0x0004; // see note(1) + // below private static final int DISCOVERED_ANNOTATION_TARGET_KINDS = 0x0008; private static final int DISCOVERED_DECLARED_SIGNATURE = 0x0010; private static final int DISCOVERED_WHETHER_ANNOTATION_STYLE = 0x0020; @@ -128,7 +130,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { this.javaClass = javaClass; initializeFromJavaclass(); - // ATAJ: set the delegate right now for @AJ pointcut, else it is done too late to lookup + // ATAJ: set the delegate right now for @AJ pointcut, else it is done + // too late to lookup // @AJ pc refs annotation in class hierarchy resolvedTypeX.setDelegate(this); @@ -143,7 +146,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { isObject = (javaClass.getSuperclassNameIndex() == 0); ensureAspectJAttributesUnpacked(); // if (sourceContext instanceof SourceContextImpl) { - // ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName()); + // ((SourceContextImpl)sourceContext).setSourceFileName(javaClass. + // getSourceFileName()); // } setSourcefilename(javaClass.getSourceFileName()); } @@ -274,7 +278,12 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { return TypeVariable.NONE; if (typeVars == null) { - Signature.ClassSignature classSig = getGenericClassTypeSignature();// cachedGenericClassTypeSignature;//javaClass. + Signature.ClassSignature classSig = getGenericClassTypeSignature();// cachedGenericClassTypeSignature + // ; + // / + // / + // javaClass + // . // getGenericClassTypeSignature(); typeVars = new TypeVariable[classSig.formalTypeParameters.length]; for (int i = 0; i < typeVars.length; i++) { @@ -398,7 +407,9 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { setSourcefilename(sca.getSourceFileName()); } } else if (a instanceof AjAttribute.WeaverVersionInfo) { - wvInfo = (AjAttribute.WeaverVersionInfo) a; // Set the weaver version used to build this type + wvInfo = (AjAttribute.WeaverVersionInfo) a; // Set the weaver + // version used to + // build this type } else { throw new BCException("bad attribute " + a); } @@ -444,7 +455,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { public void resetState() { if (javaClass == null) { // we might store the classname and allow reloading? - // At this point we are relying on the world to not evict if it might want to reweave multiple times + // At this point we are relying on the world to not evict if it + // might want to reweave multiple times throw new BCException("can't weave evicted type"); } @@ -478,7 +490,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { // this.perClause = null; // this.weaverState = null; // this.lazyClassGen = null; - // this next line frees up memory, but need to understand incremental implications + // this next line frees up memory, but need to understand incremental + // implications // before leaving it in. // getResolvedTypeX().setSourceContext(null); } @@ -508,7 +521,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { // System.err.println("creating lazy class gen for: " + this); ret = new LazyClassGen(this); // ret.print(System.err); - // System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName ); + // System.err.println("made LCG from : " + + // this.getJavaClass().getSuperclassName ); if (isAspect()) { lazyClassGen = ret; } @@ -549,7 +563,9 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { interfaceSignatures = newInterfaceSignatures; } } - // System.err.println("javaClass: " + Arrays.asList(javaClass.getInterfaceNames()) + " super " + superclassName); + // System.err.println("javaClass: " + + // Arrays.asList(javaClass.getInterfaceNames()) + " super " + + // superclassName); // if (lazyClassGen != null) lazyClassGen.print(); } @@ -560,7 +576,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { return annotationTypes; } - public AnnotationX[] getAnnotations() { + public AnnotationAJ[] getAnnotations() { ensureAnnotationsUnpacked(); return annotations; } @@ -576,10 +592,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { } // evil mutator - adding state not stored in the java class - public void addAnnotation(AnnotationX annotation) { + public void addAnnotation(AnnotationAJ annotation) { bitflag |= DAMAGED; int len = annotations.length; - AnnotationX[] ret = new AnnotationX[len + 1]; + AnnotationAJ[] ret = new AnnotationAJ[len + 1]; System.arraycopy(annotations, 0, ret, 0, len); ret[len] = annotation; annotations = ret; @@ -602,9 +618,9 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { if (isAnnotation()) { ensureAnnotationsUnpacked(); for (int i = annotations.length - 1; i >= 0; i--) { - AnnotationX ax = annotations[i]; + AnnotationAJ ax = annotations[i]; if (ax.getTypeName().equals(UnresolvedType.AT_RETENTION.getName())) { - List values = ax.getBcelAnnotation().getValues(); + List values = ((BcelAnnotation) ax).getBcelAnnotation().getValues(); for (Iterator it = values.iterator(); it.hasNext();) { ElementNameValuePairGen element = (ElementNameValuePairGen) it.next(); EnumElementValueGen v = (EnumElementValueGen) element.getValue(); @@ -634,7 +650,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { if ((bitflag & DISCOVERED_ANNOTATION_TARGET_KINDS) != 0) return annotationTargetKinds; bitflag |= DISCOVERED_ANNOTATION_TARGET_KINDS; - annotationTargetKinds = null; // null means we have no idea or the @Target annotation hasn't been used + annotationTargetKinds = null; // null means we have no idea or the + // @Target annotation hasn't been used List targetKinds = new ArrayList(); if (isAnnotation()) { AnnotationGen[] annotationsOnThisType = javaClass.getAnnotations(); @@ -683,15 +700,15 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { AnnotationGen annos[] = javaClass.getAnnotations(); if (annos == null || annos.length == 0) { annotationTypes = ResolvedType.NONE; - annotations = AnnotationX.NONE; + annotations = AnnotationAJ.EMPTY_ARRAY; } else { World w = getResolvedTypeX().getWorld(); annotationTypes = new ResolvedType[annos.length]; - annotations = new AnnotationX[annos.length]; + annotations = new AnnotationAJ[annos.length]; for (int i = 0; i < annos.length; i++) { AnnotationGen annotation = annos[i]; annotationTypes[i] = w.resolve(UnresolvedType.forSignature(annotation.getTypeSignature())); - annotations[i] = new AnnotationX(annotation, w); + annotations[i] = new BcelAnnotation(annotation, w); } } } @@ -714,7 +731,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { if (cSig != null) { formalsForResolution = cSig.formalTypeParameters; if (isNested()) { - // we have to find any type variables from the outer type before proceeding with resolution. + // we have to find any type variables from the outer type before + // proceeding with resolution. Signature.FormalTypeParameter[] extraFormals = getFormalTypeParametersFromOuterClass(); if (extraFormals.length > 0) { List allFormals = new ArrayList(); @@ -732,7 +750,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { try { // this.superClass = // BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( - // superSig, formalsForResolution, getResolvedTypeX().getWorld()); + // superSig, formalsForResolution, + // getResolvedTypeX().getWorld()); ResolvedType rt = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(superSig, formalsForResolution, getResolvedTypeX().getWorld()); @@ -745,7 +764,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { + " with generic signature " + getDeclaredGenericSignature() + " the following error was detected: " + e.getMessage()); } - // this.interfaces = new ResolvedType[cSig.superInterfaceSignatures.length]; + // this.interfaces = new + // ResolvedType[cSig.superInterfaceSignatures.length]; if (cSig.superInterfaceSignatures.length == 0) { this.interfaceSignatures = NO_INTERFACE_SIGS; } else { @@ -753,7 +773,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { for (int i = 0; i < cSig.superInterfaceSignatures.length; i++) { try { // this.interfaces[i] = - // BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( + // BcelGenericSignatureToTypeXConverter. + // classTypeSignature2TypeX( // cSig.superInterfaceSignatures[i], // formalsForResolution, // getResolvedTypeX().getWorld()); @@ -772,7 +793,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { if (isGeneric()) { // update resolved typex to point at generic type not raw type. ReferenceType genericType = (ReferenceType) this.resolvedTypeX.getGenericType(); - // genericType.setSourceContext(this.resolvedTypeX.getSourceContext()); + // genericType.setSourceContext(this.resolvedTypeX.getSourceContext() + // ); genericType.setStartPos(this.resolvedTypeX.getStartPos()); this.resolvedTypeX = genericType; } @@ -830,9 +852,12 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { getDeclaredInterfaces(); getDeclaredFields(); getDeclaredMethods(); - // The lazyClassGen is preserved for aspects - it exists to enable around advice - // inlining since the method will need 'injecting' into the affected class. If - // XnoInline is on, we can chuck away the lazyClassGen since it won't be required + // The lazyClassGen is preserved for aspects - it exists to enable + // around advice + // inlining since the method will need 'injecting' into the affected + // class. If + // XnoInline is on, we can chuck away the lazyClassGen since it + // won't be required // later. if (getResolvedTypeX().getWorld().isXnoInline()) lazyClassGen = null; @@ -847,8 +872,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { for (int i = fields.length - 1; i >= 0; i--) fields[i].evictWeavingState(); javaClass = null; - // setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // bit naughty - // interfaces=null; // force reinit - may get us the right instances! + // setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // + // bit naughty + // interfaces=null; // force reinit - may get us the right + // instances! // superClass=null; } } @@ -863,11 +890,15 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { // --- methods for testing - // for testing - if we have this attribute, return it - will return null if it doesnt know anything + // 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 = BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass.getAttributes(), - // getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld(),AjAttribute.WeaverVersionInfo.UNKNOWN); + // List l = + // BcelAttributes.readAjAttributes(javaClass.getClassName(),javaClass + // .getAttributes(), + // getResolvedTypeX().getSourceContext(),getResolvedTypeX().getWorld(), + // AjAttribute.WeaverVersionInfo.UNKNOWN); // for (Iterator iter = l.iterator(); iter.hasNext();) { // AjAttribute element = (AjAttribute) iter.next(); // if (element.getNameString().equals(name)) results.add(element); @@ -878,7 +909,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate { // return null; // } // - // // for testing - use with the method above - this returns *all* including those that are not Aj attributes + // // for testing - use with the method above - this returns *all* including + // those that are not Aj attributes // public String[] getAttributeNames() { // Attribute[] as = javaClass.getAttributes(); // String[] strs = new String[as.length]; diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 99d0acd35..5f83abce2 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -11,7 +11,6 @@ * Alexandre Vasseur @AspectJ ITDs * ******************************************************************/ - package org.aspectj.weaver.bcel; import java.lang.reflect.Modifier; @@ -21,11 +20,11 @@ import java.util.Map; import java.util.Set; import org.aspectj.apache.bcel.Constants; -import org.aspectj.apache.bcel.generic.FieldGen; -import org.aspectj.apache.bcel.generic.InstructionBranch; import org.aspectj.apache.bcel.classfile.ConstantPool; import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen; +import org.aspectj.apache.bcel.generic.FieldGen; +import org.aspectj.apache.bcel.generic.InstructionBranch; import org.aspectj.apache.bcel.generic.InstructionConstants; import org.aspectj.apache.bcel.generic.InstructionFactory; import org.aspectj.apache.bcel.generic.InstructionHandle; @@ -41,8 +40,8 @@ import org.aspectj.bridge.WeaveMessage; import org.aspectj.bridge.context.CompilationAndWeavingContext; import org.aspectj.bridge.context.ContextToken; import org.aspectj.weaver.AjcMemberMaker; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AnnotationOnTypeMunger; -import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.AsmRelationshipProvider; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ConcreteTypeMunger; @@ -68,7 +67,6 @@ import org.aspectj.weaver.World; import org.aspectj.weaver.patterns.DeclareAnnotation; import org.aspectj.weaver.patterns.Pointcut; - //XXX addLazyMethodGen is probably bad everywhere public class BcelTypeMunger extends ConcreteTypeMunger { @@ -84,442 +82,489 @@ public class BcelTypeMunger extends ConcreteTypeMunger { ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MUNGING_WITH, this); boolean changed = false; boolean worthReporting = true; - + if (munger.getKind() == ResolvedTypeMunger.Field) { - changed = mungeNewField(weaver, (NewFieldTypeMunger)munger); + changed = mungeNewField(weaver, (NewFieldTypeMunger) munger); } else if (munger.getKind() == ResolvedTypeMunger.Method) { - changed = mungeNewMethod(weaver, (NewMethodTypeMunger)munger); - } else if (munger.getKind() == ResolvedTypeMunger.MethodDelegate) { - changed = mungeMethodDelegate(weaver, (MethodDelegateTypeMunger)munger); - } else if (munger.getKind() == ResolvedTypeMunger.FieldHost) { - changed = mungeFieldHost(weaver, (MethodDelegateTypeMunger.FieldHostTypeMunger)munger); + changed = mungeNewMethod(weaver, (NewMethodTypeMunger) munger); + } else if (munger.getKind() == ResolvedTypeMunger.MethodDelegate) { + changed = mungeMethodDelegate(weaver, (MethodDelegateTypeMunger) munger); + } else if (munger.getKind() == ResolvedTypeMunger.FieldHost) { + changed = mungeFieldHost(weaver, (MethodDelegateTypeMunger.FieldHostTypeMunger) munger); } else if (munger.getKind() == ResolvedTypeMunger.PerObjectInterface) { - changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger)munger); + changed = mungePerObjectInterface(weaver, (PerObjectInterfaceTypeMunger) munger); worthReporting = false; } else if (munger.getKind() == ResolvedTypeMunger.PerTypeWithinInterface) { // PTWIMPL Transform the target type (add the aspect instance field) changed = mungePerTypeWithinTransformer(weaver); worthReporting = false; } else if (munger.getKind() == ResolvedTypeMunger.PrivilegedAccess) { - changed = mungePrivilegedAccess(weaver, (PrivilegedAccessMunger)munger); + changed = mungePrivilegedAccess(weaver, (PrivilegedAccessMunger) munger); worthReporting = false; } else if (munger.getKind() == ResolvedTypeMunger.Constructor) { - changed = mungeNewConstructor(weaver, (NewConstructorTypeMunger)munger); + changed = mungeNewConstructor(weaver, (NewConstructorTypeMunger) munger); } else if (munger.getKind() == ResolvedTypeMunger.Parent) { - changed = mungeNewParent(weaver, (NewParentTypeMunger)munger); + changed = mungeNewParent(weaver, (NewParentTypeMunger) munger); } else if (munger.getKind() == ResolvedTypeMunger.AnnotationOnType) { - changed = mungeNewAnnotationOnType(weaver,(AnnotationOnTypeMunger)munger); - worthReporting=false; - } else { + changed = mungeNewAnnotationOnType(weaver, (AnnotationOnTypeMunger) munger); + worthReporting = false; + } else { throw new RuntimeException("unimplemented"); } - + if (changed && munger.changesPublicSignature()) { - WeaverStateInfo info = - weaver.getLazyClassGen().getOrCreateWeaverStateInfo(BcelClassWeaver.getReweavableMode()); + WeaverStateInfo info = weaver.getLazyClassGen().getOrCreateWeaverStateInfo(BcelClassWeaver.getReweavableMode()); info.addConcreteMunger(this); } if (changed && worthReporting) { - AsmRelationshipProvider.getDefault().addRelationship(weaver.getLazyClassGen().getType(), munger,getAspectType()); + AsmRelationshipProvider.getDefault().addRelationship(weaver.getLazyClassGen().getType(), munger, getAspectType()); } - + // TAG: WeavingMessage - if (changed && worthReporting && munger!=null && !weaver.getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { + if (changed && worthReporting && munger != null && !weaver.getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { String tName = weaver.getLazyClassGen().getType().getSourceLocation().getSourceFile().getName(); - if (tName.indexOf("no debug info available")!=-1) tName = "no debug info available"; - else tName = getShortname(weaver.getLazyClassGen().getType().getSourceLocation().getSourceFile().getPath()); + if (tName.indexOf("no debug info available") != -1) + tName = "no debug info available"; + else + tName = getShortname(weaver.getLazyClassGen().getType().getSourceLocation().getSourceFile().getPath()); String fName = getShortname(getAspectType().getSourceLocation().getSourceFile().getPath()); - if (munger.getKind().equals(ResolvedTypeMunger.Parent)) { - // This message could come out of AjLookupEnvironment.addParent if doing parents - // munging at compile time only... - NewParentTypeMunger parentTM = (NewParentTypeMunger)munger; - if (parentTM.getNewParent().isInterface()) { - weaver.getWorld().getMessageHandler().handleMessage(WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS, - new String[]{weaver.getLazyClassGen().getType().getName(), - tName,parentTM.getNewParent().getName(),fName}, - weaver.getLazyClassGen().getClassName(), getAspectType().getName())); - } else { - weaver.getWorld().getMessageHandler().handleMessage( - WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSEXTENDS, - new String[]{weaver.getLazyClassGen().getType().getName(), - tName,parentTM.getNewParent().getName(),fName - })); -// TAG: WeavingMessage DECLARE PARENTS: EXTENDS -// reportDeclareParentsMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSEXTENDS,sourceType,parent); - - } - } else if (munger.getKind().equals(ResolvedTypeMunger.FieldHost)) { - //hidden - } else { - ResolvedMember declaredSig = munger.getSignature(); -// if (declaredSig==null) declaredSig= munger.getSignature(); - weaver.getWorld().getMessageHandler().handleMessage(WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ITD, - new String[]{weaver.getLazyClassGen().getType().getName(), - tName,munger.getKind().toString().toLowerCase(), - getAspectType().getName(), - fName+":'"+declaredSig+"'"}, - weaver.getLazyClassGen().getClassName(), getAspectType().getName())); - } + if (munger.getKind().equals(ResolvedTypeMunger.Parent)) { + // This message could come out of AjLookupEnvironment.addParent + // if doing parents + // munging at compile time only... + NewParentTypeMunger parentTM = (NewParentTypeMunger) munger; + if (parentTM.getNewParent().isInterface()) { + weaver.getWorld().getMessageHandler().handleMessage( + WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS, + new String[] { weaver.getLazyClassGen().getType().getName(), tName, + parentTM.getNewParent().getName(), fName }, weaver.getLazyClassGen().getClassName(), + getAspectType().getName())); + } else { + weaver.getWorld().getMessageHandler().handleMessage( + WeaveMessage + .constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSEXTENDS, new String[] { + weaver.getLazyClassGen().getType().getName(), tName, parentTM.getNewParent().getName(), + fName })); + // TAG: WeavingMessage DECLARE PARENTS: EXTENDS + // reportDeclareParentsMessage(WeaveMessage. + // WEAVEMESSAGE_DECLAREPARENTSEXTENDS,sourceType,parent); + + } + } else if (munger.getKind().equals(ResolvedTypeMunger.FieldHost)) { + // hidden + } else { + ResolvedMember declaredSig = munger.getSignature(); + // if (declaredSig==null) declaredSig= munger.getSignature(); + weaver.getWorld().getMessageHandler().handleMessage( + WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ITD, new String[] { + weaver.getLazyClassGen().getType().getName(), tName, munger.getKind().toString().toLowerCase(), + getAspectType().getName(), fName + ":'" + declaredSig + "'" }, weaver.getLazyClassGen() + .getClassName(), getAspectType().getName())); + } } - + CompilationAndWeavingContext.leavingPhase(tok); return changed; } - private String getShortname(String path) { + private String getShortname(String path) { int takefrom = path.lastIndexOf('/'); if (takefrom == -1) { takefrom = path.lastIndexOf('\\'); } - return path.substring(takefrom+1); + return path.substring(takefrom + 1); } - - private boolean mungeNewAnnotationOnType(BcelClassWeaver weaver,AnnotationOnTypeMunger munger) { - // FIXME asc this has already been done up front, need to do it here too? - weaver.getLazyClassGen().addAnnotation(munger.getNewAnnotation().getBcelAnnotation()); + + private boolean mungeNewAnnotationOnType(BcelClassWeaver weaver, AnnotationOnTypeMunger munger) { + // FIXME asc this has already been done up front, need to do it here + // too? + weaver.getLazyClassGen().addAnnotation(((BcelAnnotation) munger.getNewAnnotation()).getBcelAnnotation()); return true; } - /** - * For a long time, AspectJ did not allow binary weaving of declare parents. This restriction is now lifted - * but could do with more testing! + /** + * For a long time, AspectJ did not allow binary weaving of declare parents. This restriction is now lifted but could do with + * more testing! */ private boolean mungeNewParent(BcelClassWeaver weaver, NewParentTypeMunger munger) { - LazyClassGen newParentTarget = weaver.getLazyClassGen(); - ResolvedType newParent = munger.getNewParent(); - - boolean cont = true; // Set to false when we error, so we don't actually *do* the munge - cont = enforceDecpRule1_abstractMethodsImplemented(weaver, munger.getSourceLocation(),newParentTarget, newParent); - cont = enforceDecpRule2_cantExtendFinalClass(weaver,munger.getSourceLocation(),newParentTarget,newParent) && cont; - - List methods = newParent.getMethodsWithoutIterator(false,true); - for (Iterator iter = methods.iterator(); iter.hasNext();) { - ResolvedMember superMethod = (ResolvedMember) iter.next(); - if (!superMethod.getName().equals("")) { - LazyMethodGen subMethod = findMatchingMethod(newParentTarget, superMethod); - if (subMethod!=null && !subMethod.isBridgeMethod()) { // FIXME asc is this safe for all bridge methods? - if (!(subMethod.isSynthetic() && superMethod.isSynthetic())) { - if (!(subMethod.isStatic() && subMethod.getName().startsWith("access$"))) { // ignore generated accessors - cont = enforceDecpRule3_visibilityChanges(weaver, newParent, superMethod, subMethod) && cont; - cont = enforceDecpRule4_compatibleReturnTypes(weaver, superMethod, subMethod) && cont; - cont = enforceDecpRule5_cantChangeFromStaticToNonstatic(weaver,munger.getSourceLocation(),superMethod,subMethod) && cont; - } - } - } - } - } - if (!cont) return false; // A rule was violated and an error message already reported - - if (newParent.isClass()) { // Changing the supertype - if (!attemptToModifySuperCalls(weaver,newParentTarget,newParent)) return false; - newParentTarget.setSuperClass(newParent); + LazyClassGen newParentTarget = weaver.getLazyClassGen(); + ResolvedType newParent = munger.getNewParent(); + + boolean cont = true; // Set to false when we error, so we don't actually + // *do* the munge + cont = enforceDecpRule1_abstractMethodsImplemented(weaver, munger.getSourceLocation(), newParentTarget, newParent); + cont = enforceDecpRule2_cantExtendFinalClass(weaver, munger.getSourceLocation(), newParentTarget, newParent) && cont; + + List methods = newParent.getMethodsWithoutIterator(false, true); + for (Iterator iter = methods.iterator(); iter.hasNext();) { + ResolvedMember superMethod = (ResolvedMember) iter.next(); + if (!superMethod.getName().equals("")) { + LazyMethodGen subMethod = findMatchingMethod(newParentTarget, superMethod); + if (subMethod != null && !subMethod.isBridgeMethod()) { // FIXME + // asc + // is + // this + // safe + // for + // all + // bridge + // methods + // ? + if (!(subMethod.isSynthetic() && superMethod.isSynthetic())) { + if (!(subMethod.isStatic() && subMethod.getName().startsWith("access$"))) { // ignore generated + // accessors + cont = enforceDecpRule3_visibilityChanges(weaver, newParent, superMethod, subMethod) && cont; + cont = enforceDecpRule4_compatibleReturnTypes(weaver, superMethod, subMethod) && cont; + cont = enforceDecpRule5_cantChangeFromStaticToNonstatic(weaver, munger.getSourceLocation(), + superMethod, subMethod) + && cont; + } + } + } + } + } + if (!cont) + return false; // A rule was violated and an error message already + // reported + + if (newParent.isClass()) { // Changing the supertype + if (!attemptToModifySuperCalls(weaver, newParentTarget, newParent)) + return false; + newParentTarget.setSuperClass(newParent); } else { // Adding a new interface - newParentTarget.addInterface(newParent,getSourceLocation()); + newParentTarget.addInterface(newParent, getSourceLocation()); } return true; } + /** + * Rule 1: For the declare parents to be allowed, the target type must override and implement inherited abstract methods (if the + * type is not declared abstract) + */ + private boolean enforceDecpRule1_abstractMethodsImplemented(BcelClassWeaver weaver, ISourceLocation mungerLoc, + LazyClassGen newParentTarget, ResolvedType newParent) { + boolean ruleCheckingSucceeded = true; + if (!(newParentTarget.isAbstract() || newParentTarget.isInterface())) { // Ignore + // abstract + // classes + // or + // interfaces + List methods = newParent.getMethodsWithoutIterator(false, true); + for (Iterator i = methods.iterator(); i.hasNext();) { + ResolvedMember o = (ResolvedMember) i.next(); + if (o.isAbstract() && !o.getName().startsWith("ajc$interField")) { // Ignore + // abstract + // methods + // of + // ajc$interField + // prefixed + // methods + ResolvedMember discoveredImpl = null; + List newParentTargetMethods = newParentTarget.getType().getMethodsWithoutIterator(false, true); + for (Iterator ii = newParentTargetMethods.iterator(); ii.hasNext() && discoveredImpl == null;) { + ResolvedMember gen2 = (ResolvedMember) ii.next(); + if (gen2.getName().equals(o.getName()) && gen2.getParameterSignature().equals(o.getParameterSignature()) + && !gen2.isAbstract()) { + discoveredImpl = gen2; // Found a valid + // implementation ! + } + } + if (discoveredImpl == null) { + // didnt find a valid implementation, lets check the + // ITDs on this type to see if they satisfy it + boolean satisfiedByITD = false; + for (Iterator ii = newParentTarget.getType().getInterTypeMungersIncludingSupers().iterator(); ii.hasNext();) { + ConcreteTypeMunger m = (ConcreteTypeMunger) ii.next(); + if (m.getMunger() != null && m.getMunger().getKind() == ResolvedTypeMunger.Method) { + ResolvedMember sig = m.getSignature(); + if (!Modifier.isAbstract(sig.getModifiers())) { + + // If the ITD shares a type variable with + // some target type, we need to tailor it + // for that + // type + if (m.isTargetTypeParameterized()) { + ResolvedType genericOnType = getWorld().resolve(sig.getDeclaringType()).getGenericType(); + m = m.parameterizedFor(newParent.discoverActualOccurrenceOfTypeInHierarchy(genericOnType)); + sig = m.getSignature(); // possible sig + // change when + // type + // parameters + // filled in + } + if (ResolvedType.matches(AjcMemberMaker.interMethod(sig, m.getAspectType(), sig + .getDeclaringType().resolve(weaver.getWorld()).isInterface()), o)) { + satisfiedByITD = true; + } + } + } else if (m.getMunger() != null && m.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate) { + satisfiedByITD = true;// AV - that should be + // enough, no need to + // check more + } + } + if (!satisfiedByITD) { + error(weaver, "The type " + newParentTarget.getName() + + " must implement the inherited abstract method " + o.getDeclaringType() + "." + o.getName() + + o.getParameterSignature(), newParentTarget.getType().getSourceLocation(), + new ISourceLocation[] { o.getSourceLocation(), mungerLoc }); + ruleCheckingSucceeded = false; + } + } + } + } + } + return ruleCheckingSucceeded; + } - /** - * Rule 1: For the declare parents to be allowed, the target type must override and implement - * inherited abstract methods (if the type is not declared abstract) - */ - private boolean enforceDecpRule1_abstractMethodsImplemented(BcelClassWeaver weaver, ISourceLocation mungerLoc,LazyClassGen newParentTarget, ResolvedType newParent) { - boolean ruleCheckingSucceeded = true; - if (!(newParentTarget.isAbstract() || newParentTarget.isInterface())) { // Ignore abstract classes or interfaces - List methods = newParent.getMethodsWithoutIterator(false,true); - for (Iterator i = methods.iterator(); i.hasNext();) { - ResolvedMember o = (ResolvedMember)i.next(); - if (o.isAbstract() && !o.getName().startsWith("ajc$interField")) { // Ignore abstract methods of ajc$interField prefixed methods - ResolvedMember discoveredImpl = null; - List newParentTargetMethods = newParentTarget.getType().getMethodsWithoutIterator(false,true); - for (Iterator ii = newParentTargetMethods.iterator(); ii.hasNext() && discoveredImpl==null;) { - ResolvedMember gen2 = (ResolvedMember) ii.next(); - if (gen2.getName().equals(o.getName()) && - gen2.getParameterSignature().equals(o.getParameterSignature()) && !gen2.isAbstract()) { - discoveredImpl = gen2; // Found a valid implementation ! - } - } - if (discoveredImpl == null) { - // didnt find a valid implementation, lets check the ITDs on this type to see if they satisfy it - boolean satisfiedByITD = false; - for (Iterator ii = newParentTarget.getType().getInterTypeMungersIncludingSupers().iterator(); ii.hasNext(); ) { - ConcreteTypeMunger m = (ConcreteTypeMunger)ii.next(); - if (m.getMunger()!=null && m.getMunger().getKind() == ResolvedTypeMunger.Method) { - ResolvedMember sig = m.getSignature(); - if (!Modifier.isAbstract(sig.getModifiers())) { - - // If the ITD shares a type variable with some target type, we need to tailor it for that - // type - if (m.isTargetTypeParameterized()) { - ResolvedType genericOnType = getWorld().resolve(sig.getDeclaringType()).getGenericType(); - m = m.parameterizedFor(newParent.discoverActualOccurrenceOfTypeInHierarchy(genericOnType)); - sig = m.getSignature(); // possible sig change when type parameters filled in - } - if (ResolvedType - .matches( - AjcMemberMaker.interMethod( - sig,m.getAspectType(),sig.getDeclaringType().resolve(weaver.getWorld()).isInterface()),o)) { - satisfiedByITD = true; - } - } - } else if (m.getMunger()!=null && m.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate) { - satisfiedByITD = true;//AV - that should be enough, no need to check more - } - } - if (!satisfiedByITD) { - error(weaver, - "The type " + newParentTarget.getName() + " must implement the inherited abstract method "+o.getDeclaringType()+"."+o.getName()+o.getParameterSignature(), - newParentTarget.getType().getSourceLocation(),new ISourceLocation[]{o.getSourceLocation(),mungerLoc}); - ruleCheckingSucceeded=false; - } - } - } - } - } - return ruleCheckingSucceeded; - } - - /** - * Rule 2. Can't extend final types - */ - private boolean enforceDecpRule2_cantExtendFinalClass(BcelClassWeaver weaver, ISourceLocation mungerLoc, - LazyClassGen newParentTarget, ResolvedType newParent) { - if (newParent.isFinal()) { - error(weaver,"Cannot make type "+newParentTarget.getName()+" extend final class "+newParent.getName(), - newParentTarget.getType().getSourceLocation(), - new ISourceLocation[]{mungerLoc}); - return false; - } + /** + * Rule 2. Can't extend final types + */ + private boolean enforceDecpRule2_cantExtendFinalClass(BcelClassWeaver weaver, ISourceLocation mungerLoc, + LazyClassGen newParentTarget, ResolvedType newParent) { + if (newParent.isFinal()) { + error(weaver, "Cannot make type " + newParentTarget.getName() + " extend final class " + newParent.getName(), + newParentTarget.getType().getSourceLocation(), new ISourceLocation[] { mungerLoc }); + return false; + } return true; } + /** + * Rule 3. Can't narrow visibility of methods when overriding + */ + private boolean enforceDecpRule3_visibilityChanges(BcelClassWeaver weaver, ResolvedType newParent, ResolvedMember superMethod, + LazyMethodGen subMethod) { + boolean cont = true; + if (superMethod.isPublic()) { + if (subMethod.isProtected() || subMethod.isDefault() || subMethod.isPrivate()) { + weaver.getWorld().getMessageHandler().handleMessage( + MessageUtil.error("Cannot reduce the visibility of the inherited method '" + superMethod + "' from " + + newParent.getName(), superMethod.getSourceLocation())); + cont = false; + } + } else if (superMethod.isProtected()) { + if (subMethod.isDefault() || subMethod.isPrivate()) { + weaver.getWorld().getMessageHandler().handleMessage( + MessageUtil.error("Cannot reduce the visibility of the inherited method '" + superMethod + "' from " + + newParent.getName(), superMethod.getSourceLocation())); + cont = false; + } + } else if (superMethod.isDefault()) { + if (subMethod.isPrivate()) { + weaver.getWorld().getMessageHandler().handleMessage( + MessageUtil.error("Cannot reduce the visibility of the inherited method '" + superMethod + "' from " + + newParent.getName(), superMethod.getSourceLocation())); + cont = false; + } + } + return cont; + } /** - * Rule 3. Can't narrow visibility of methods when overriding + * Rule 4. Can't have incompatible return types */ - private boolean enforceDecpRule3_visibilityChanges(BcelClassWeaver weaver, ResolvedType newParent, ResolvedMember superMethod, LazyMethodGen subMethod) { - boolean cont = true; - if (superMethod.isPublic()) { - if (subMethod.isProtected() || subMethod.isDefault() || subMethod.isPrivate()) { - weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error( - "Cannot reduce the visibility of the inherited method '"+superMethod+"' from "+newParent.getName(), - superMethod.getSourceLocation())); - cont=false; - } - } else if (superMethod.isProtected()) { - if (subMethod.isDefault() || subMethod.isPrivate()) { - weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error( - "Cannot reduce the visibility of the inherited method '"+superMethod+"' from "+newParent.getName(), - superMethod.getSourceLocation())); - cont=false; - } - } else if (superMethod.isDefault()) { - if (subMethod.isPrivate()) { - weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error( - "Cannot reduce the visibility of the inherited method '"+superMethod+"' from "+newParent.getName(), - superMethod.getSourceLocation())); - cont=false; - } - } + private boolean enforceDecpRule4_compatibleReturnTypes(BcelClassWeaver weaver, ResolvedMember superMethod, + LazyMethodGen subMethod) { + boolean cont = true; + String superReturnTypeSig = superMethod.getGenericReturnType().getSignature(); // eg. Pjava/util/Collection + String subReturnTypeSig = subMethod.getGenericReturnTypeSignature(); + superReturnTypeSig = superReturnTypeSig.replace('.', '/'); + subReturnTypeSig = subReturnTypeSig.replace('.', '/'); + if (!superReturnTypeSig.equals(subReturnTypeSig)) { + // Check for covariance + ResolvedType subType = weaver.getWorld().resolve(subMethod.getReturnType()); + ResolvedType superType = weaver.getWorld().resolve(superMethod.getReturnType()); + if (!superType.isAssignableFrom(subType)) { + weaver.getWorld().getMessageHandler().handleMessage( + MessageUtil.error("The return type is incompatible with " + superMethod.getDeclaringType() + "." + + superMethod.getName() + superMethod.getParameterSignature(), subMethod.getSourceLocation())); + // this just might be a better error message... + // "The return type '"+subReturnTypeSig+ + // "' is incompatible with the overridden method " + // +superMethod.getDeclaringType()+"."+ + // superMethod.getName()+superMethod.getParameterSignature()+ + // " which returns '"+superReturnTypeSig+"'", + cont = false; + } + } return cont; } - - /** - * Rule 4. Can't have incompatible return types - */ - private boolean enforceDecpRule4_compatibleReturnTypes(BcelClassWeaver weaver, ResolvedMember superMethod, LazyMethodGen subMethod) { - boolean cont = true; - String superReturnTypeSig = superMethod.getGenericReturnType().getSignature(); // eg. Pjava/util/Collection - String subReturnTypeSig = subMethod.getGenericReturnTypeSignature(); - superReturnTypeSig = superReturnTypeSig.replace('.', '/'); - subReturnTypeSig = subReturnTypeSig.replace('.', '/'); - if (!superReturnTypeSig.equals(subReturnTypeSig)) { - // Check for covariance - ResolvedType subType = weaver.getWorld().resolve(subMethod.getReturnType()); - ResolvedType superType = weaver.getWorld().resolve(superMethod.getReturnType()); - if (!superType.isAssignableFrom(subType)) { - weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error( - "The return type is incompatible with " + superMethod.getDeclaringType() + "." + superMethod.getName() - + superMethod.getParameterSignature(), subMethod.getSourceLocation())); -// this just might be a better error message... -// "The return type '"+subReturnTypeSig+"' is incompatible with the overridden method "+superMethod.getDeclaringType()+"."+ -// superMethod.getName()+superMethod.getParameterSignature()+" which returns '"+superReturnTypeSig+"'", - cont=false; - } - } - return cont; - } - - /** - * Rule5. Method overrides can't change the staticality (word?) - you can't override and make an instance - * method static or override and make a static method an instance method. - */ - private boolean enforceDecpRule5_cantChangeFromStaticToNonstatic(BcelClassWeaver weaver,ISourceLocation mungerLoc,ResolvedMember superMethod, LazyMethodGen subMethod ) { - if (superMethod.isStatic() && !subMethod.isStatic()) { - error(weaver,"This instance method "+subMethod.getName()+subMethod.getParameterSignature()+ - " cannot override the static method from "+superMethod.getDeclaringType().getName(), - subMethod.getSourceLocation(),new ISourceLocation[]{mungerLoc}); - return false; - } else if (!superMethod.isStatic() && subMethod.isStatic()) { - error(weaver,"The static method "+subMethod.getName()+subMethod.getParameterSignature()+ - " cannot hide the instance method from "+superMethod.getDeclaringType().getName(), - subMethod.getSourceLocation(),new ISourceLocation[]{mungerLoc}); - return false; - } - return true; - } - - public void error(BcelClassWeaver weaver,String text,ISourceLocation primaryLoc,ISourceLocation[] extraLocs) { - IMessage msg = new Message(text, primaryLoc, true, extraLocs); - weaver.getWorld().getMessageHandler().handleMessage(msg); - } - - - /** - * Search the specified type for a particular method - do not use the return value in the comparison as it is not - * considered for overriding. - */ + + /** + * Rule5. Method overrides can't change the staticality (word?) - you can't override and make an instance method static or + * override and make a static method an instance method. + */ + private boolean enforceDecpRule5_cantChangeFromStaticToNonstatic(BcelClassWeaver weaver, ISourceLocation mungerLoc, + ResolvedMember superMethod, LazyMethodGen subMethod) { + if (superMethod.isStatic() && !subMethod.isStatic()) { + error(weaver, "This instance method " + subMethod.getName() + subMethod.getParameterSignature() + + " cannot override the static method from " + superMethod.getDeclaringType().getName(), subMethod + .getSourceLocation(), new ISourceLocation[] { mungerLoc }); + return false; + } else if (!superMethod.isStatic() && subMethod.isStatic()) { + error(weaver, "The static method " + subMethod.getName() + subMethod.getParameterSignature() + + " cannot hide the instance method from " + superMethod.getDeclaringType().getName(), subMethod + .getSourceLocation(), new ISourceLocation[] { mungerLoc }); + return false; + } + return true; + } + + public void error(BcelClassWeaver weaver, String text, ISourceLocation primaryLoc, ISourceLocation[] extraLocs) { + IMessage msg = new Message(text, primaryLoc, true, extraLocs); + weaver.getWorld().getMessageHandler().handleMessage(msg); + } + + /** + * Search the specified type for a particular method - do not use the return value in the comparison as it is not considered for + * overriding. + */ private LazyMethodGen findMatchingMethod(LazyClassGen newParentTarget, ResolvedMember m) { - LazyMethodGen found = null; - List methodGens = newParentTarget.getMethodGens(); - for (Iterator i = methodGens.iterator(); i.hasNext() && found == null;) { - LazyMethodGen gen = (LazyMethodGen) i.next(); - if (gen.getName().equals(m.getName()) && - gen.getParameterSignature().equals(m.getParameterSignature())) { - found = gen; - } - } + LazyMethodGen found = null; + List methodGens = newParentTarget.getMethodGens(); + for (Iterator i = methodGens.iterator(); i.hasNext() && found == null;) { + LazyMethodGen gen = (LazyMethodGen) i.next(); + if (gen.getName().equals(m.getName()) && gen.getParameterSignature().equals(m.getParameterSignature())) { + found = gen; + } + } return found; } - /** - * The main part of implementing declare parents extends. Modify super ctor calls to target the new type. - */ - public boolean attemptToModifySuperCalls(BcelClassWeaver weaver,LazyClassGen newParentTarget, ResolvedType newParent) { - String currentParent = newParentTarget.getSuperClassname(); - if (newParent.getGenericType()!=null) newParent = newParent.getGenericType(); // target new super calls at the generic type if its raw or parameterized - List mgs = newParentTarget.getMethodGens(); - - // Look for ctors to modify - for (Iterator iter = mgs.iterator(); iter.hasNext();) { - LazyMethodGen aMethod = (LazyMethodGen) iter.next(); - - if (aMethod.getName().equals("")) { - InstructionList insList = aMethod.getBody(); - InstructionHandle handle = insList.getStart(); - while (handle!= null) { - if (handle.getInstruction().opcode==Constants.INVOKESPECIAL) { - ConstantPool cpg = newParentTarget.getConstantPool(); - InvokeInstruction invokeSpecial = (InvokeInstruction)handle.getInstruction(); - if (invokeSpecial.getClassName(cpg).equals(currentParent) && invokeSpecial.getMethodName(cpg).equals("")) { - // System.err.println("Transforming super call '"+sp.getSignature(cpg)+"'"); - - // 1. Check there is a ctor in the new parent with the same signature - ResolvedMember newCtor = getConstructorWithSignature(newParent,invokeSpecial.getSignature(cpg)); - - if (newCtor == null) { - - // 2. Check ITDCs to see if the necessary ctor is provided that way - boolean satisfiedByITDC = false; - for (Iterator ii = newParentTarget.getType().getInterTypeMungersIncludingSupers().iterator(); ii.hasNext() && !satisfiedByITDC; ) { - ConcreteTypeMunger m = (ConcreteTypeMunger)ii.next(); - if (m.getMunger() instanceof NewConstructorTypeMunger) { - if (m.getSignature().getSignature().equals(invokeSpecial.getSignature(cpg))) { - satisfiedByITDC = true; - } - } - } - - if (!satisfiedByITDC) { - String csig = createReadableCtorSig(newParent, cpg, invokeSpecial); - weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error( - "Unable to modify hierarchy for "+newParentTarget.getClassName()+" - the constructor "+ - csig+" is missing",this.getSourceLocation())); - return false; - } - } - - int idx = cpg.addMethodref(newParent.getName(), invokeSpecial.getMethodName(cpg), invokeSpecial.getSignature(cpg)); - invokeSpecial.setIndex(idx); - } - } - handle = handle.getNext(); - } - } - } - return true; - } - + /** + * The main part of implementing declare parents extends. Modify super ctor calls to target the new type. + */ + public boolean attemptToModifySuperCalls(BcelClassWeaver weaver, LazyClassGen newParentTarget, ResolvedType newParent) { + String currentParent = newParentTarget.getSuperClassname(); + if (newParent.getGenericType() != null) + newParent = newParent.getGenericType(); // target new super calls at + // the generic type if its + // raw or parameterized + List mgs = newParentTarget.getMethodGens(); + + // Look for ctors to modify + for (Iterator iter = mgs.iterator(); iter.hasNext();) { + LazyMethodGen aMethod = (LazyMethodGen) iter.next(); + + if (aMethod.getName().equals("")) { + InstructionList insList = aMethod.getBody(); + InstructionHandle handle = insList.getStart(); + while (handle != null) { + if (handle.getInstruction().opcode == Constants.INVOKESPECIAL) { + ConstantPool cpg = newParentTarget.getConstantPool(); + InvokeInstruction invokeSpecial = (InvokeInstruction) handle.getInstruction(); + if (invokeSpecial.getClassName(cpg).equals(currentParent) + && invokeSpecial.getMethodName(cpg).equals("")) { + // System.err.println( + // "Transforming super call '" + // +sp.getSignature(cpg)+"'"); + + // 1. Check there is a ctor in the new parent with + // the same signature + ResolvedMember newCtor = getConstructorWithSignature(newParent, invokeSpecial.getSignature(cpg)); + + if (newCtor == null) { + + // 2. Check ITDCs to see if the necessary ctor + // is provided that way + boolean satisfiedByITDC = false; + for (Iterator ii = newParentTarget.getType().getInterTypeMungersIncludingSupers().iterator(); ii + .hasNext() + && !satisfiedByITDC;) { + ConcreteTypeMunger m = (ConcreteTypeMunger) ii.next(); + if (m.getMunger() instanceof NewConstructorTypeMunger) { + if (m.getSignature().getSignature().equals(invokeSpecial.getSignature(cpg))) { + satisfiedByITDC = true; + } + } + } + + if (!satisfiedByITDC) { + String csig = createReadableCtorSig(newParent, cpg, invokeSpecial); + weaver.getWorld().getMessageHandler().handleMessage( + MessageUtil.error("Unable to modify hierarchy for " + newParentTarget.getClassName() + + " - the constructor " + csig + " is missing", this.getSourceLocation())); + return false; + } + } + + int idx = cpg.addMethodref(newParent.getName(), invokeSpecial.getMethodName(cpg), invokeSpecial + .getSignature(cpg)); + invokeSpecial.setIndex(idx); + } + } + handle = handle.getNext(); + } + } + } + return true; + } /** - * Creates a nice signature for the ctor, something like "(int,Integer,String)" + * Creates a nice signature for the ctor, something like "(int,Integer,String)" */ private String createReadableCtorSig(ResolvedType newParent, ConstantPool cpg, InvokeInstruction invokeSpecial) { - StringBuffer sb = new StringBuffer(); + StringBuffer sb = new StringBuffer(); Type[] ctorArgs = invokeSpecial.getArgumentTypes(cpg); - sb.append(newParent.getClassName()); - sb.append("("); - for (int i = 0; i < ctorArgs.length; i++) { + sb.append(newParent.getClassName()); + sb.append("("); + for (int i = 0; i < ctorArgs.length; i++) { String argtype = ctorArgs[i].toString(); - if (argtype.lastIndexOf(".")!=-1) - sb.append(argtype.substring(argtype.lastIndexOf(".")+1)); + if (argtype.lastIndexOf(".") != -1) + sb.append(argtype.substring(argtype.lastIndexOf(".") + 1)); else sb.append(argtype); - if (i+1")) { + if (rm.getSignature().equals(signature)) + return rm; + } + } + return null; } - private ResolvedMember getConstructorWithSignature(ResolvedType tx,String signature) { - ResolvedMember[] mems = tx.getDeclaredJavaMethods(); - for (int i = 0; i < mems.length; i++) { - ResolvedMember rm = mems[i]; - if (rm.getName().equals("")) { - if (rm.getSignature().equals(signature)) return rm; - } - } - return null; - } - - - private boolean mungePrivilegedAccess( - BcelClassWeaver weaver, - PrivilegedAccessMunger munger) - { + private boolean mungePrivilegedAccess(BcelClassWeaver weaver, PrivilegedAccessMunger munger) { LazyClassGen gen = weaver.getLazyClassGen(); ResolvedMember member = munger.getMember(); - - ResolvedType onType = weaver.getWorld().resolve(member.getDeclaringType(),munger.getSourceLocation()); - if (onType.isRawType()) onType = onType.getGenericType(); - //System.out.println("munging: " + gen + " with " + member); + ResolvedType onType = weaver.getWorld().resolve(member.getDeclaringType(), munger.getSourceLocation()); + if (onType.isRawType()) + onType = onType.getGenericType(); + + // System.out.println("munging: " + gen + " with " + member); if (onType.equals(gen.getType())) { if (member.getKind() == Member.FIELD) { - //System.out.println("matched: " + gen); - addFieldGetter(gen, member, - AjcMemberMaker.privilegedAccessMethodForFieldGet(aspectType, member)); - addFieldSetter(gen, member, - AjcMemberMaker.privilegedAccessMethodForFieldSet(aspectType, member)); + // System.out.println("matched: " + gen); + addFieldGetter(gen, member, AjcMemberMaker.privilegedAccessMethodForFieldGet(aspectType, member)); + addFieldSetter(gen, member, AjcMemberMaker.privilegedAccessMethodForFieldSet(aspectType, member)); return true; } else if (member.getKind() == Member.METHOD) { - addMethodDispatch(gen, member, - AjcMemberMaker.privilegedAccessMethodForMethod(aspectType, member)); + addMethodDispatch(gen, member, AjcMemberMaker.privilegedAccessMethodForMethod(aspectType, member)); return true; } else if (member.getKind() == Member.CONSTRUCTOR) { - for (Iterator i = gen.getMethodGens().iterator(); i.hasNext(); ) { - LazyMethodGen m = (LazyMethodGen)i.next(); - if (m.getMemberView() != null - && m.getMemberView().getKind() == Member.CONSTRUCTOR) { + for (Iterator i = gen.getMethodGens().iterator(); i.hasNext();) { + LazyMethodGen m = (LazyMethodGen) i.next(); + if (m.getMemberView() != null && m.getMemberView().getKind() == Member.CONSTRUCTOR) { // m.getMemberView().equals(member)) { m.forcePublic(); - //return true; + // return true; } } return true; - //throw new BCException("no match for " + member + " in " + gen); + // throw new BCException("no match for " + member + " in " + + // gen); } else if (member.getKind() == Member.STATIC_INITIALIZATION) { gen.forcePublic(); return true; @@ -530,75 +575,53 @@ public class BcelTypeMunger extends ConcreteTypeMunger { return false; } - private void addFieldGetter( - LazyClassGen gen, - ResolvedMember field, - ResolvedMember accessMethod) - { + private void addFieldGetter(LazyClassGen gen, ResolvedMember field, ResolvedMember accessMethod) { LazyMethodGen mg = makeMethodGen(gen, accessMethod); InstructionList il = new InstructionList(); InstructionFactory fact = gen.getFactory(); if (field.isStatic()) { - il.append(fact.createFieldAccess( - gen.getClassName(), - field.getName(), - BcelWorld.makeBcelType(field.getType()), Constants.GETSTATIC)); + il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), BcelWorld.makeBcelType(field.getType()), + Constants.GETSTATIC)); } else { il.append(InstructionConstants.ALOAD_0); - il.append(fact.createFieldAccess( - gen.getClassName(), - field.getName(), - BcelWorld.makeBcelType(field.getType()), Constants.GETFIELD)); + il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), BcelWorld.makeBcelType(field.getType()), + Constants.GETFIELD)); } il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(field.getType()))); mg.getBody().insert(il); - - gen.addMethodGen(mg,getSignature().getSourceLocation()); + + gen.addMethodGen(mg, getSignature().getSourceLocation()); } - - private void addFieldSetter( - LazyClassGen gen, - ResolvedMember field, - ResolvedMember accessMethod) - { + + private void addFieldSetter(LazyClassGen gen, ResolvedMember field, ResolvedMember accessMethod) { LazyMethodGen mg = makeMethodGen(gen, accessMethod); InstructionList il = new InstructionList(); InstructionFactory fact = gen.getFactory(); Type fieldType = BcelWorld.makeBcelType(field.getType()); - + if (field.isStatic()) { il.append(InstructionFactory.createLoad(fieldType, 0)); - il.append(fact.createFieldAccess( - gen.getClassName(), - field.getName(), - fieldType, Constants.PUTSTATIC)); + il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), fieldType, Constants.PUTSTATIC)); } else { il.append(InstructionConstants.ALOAD_0); il.append(InstructionFactory.createLoad(fieldType, 1)); - il.append(fact.createFieldAccess( - gen.getClassName(), - field.getName(), - fieldType, Constants.PUTFIELD)); + il.append(fact.createFieldAccess(gen.getClassName(), field.getName(), fieldType, Constants.PUTFIELD)); } il.append(InstructionFactory.createReturn(Type.VOID)); mg.getBody().insert(il); - - gen.addMethodGen(mg,getSignature().getSourceLocation()); + + gen.addMethodGen(mg, getSignature().getSourceLocation()); } - - private void addMethodDispatch( - LazyClassGen gen, - ResolvedMember method, - ResolvedMember accessMethod) - { + + private void addMethodDispatch(LazyClassGen gen, ResolvedMember method, ResolvedMember accessMethod) { LazyMethodGen mg = makeMethodGen(gen, accessMethod); InstructionList il = new InstructionList(); InstructionFactory fact = gen.getFactory(); - //Type fieldType = BcelWorld.makeBcelType(field.getType()); + // Type fieldType = BcelWorld.makeBcelType(field.getType()); Type[] paramTypes = BcelWorld.makeBcelTypes(method.getParameterTypes()); - + int pos = 0; - + if (!method.isStatic()) { il.append(InstructionConstants.ALOAD_0); pos++; @@ -606,231 +629,204 @@ public class BcelTypeMunger extends ConcreteTypeMunger { for (int i = 0, len = paramTypes.length; i < len; i++) { Type paramType = paramTypes[i]; il.append(InstructionFactory.createLoad(paramType, pos)); - pos+=paramType.getSize(); + pos += paramType.getSize(); } - il.append(Utility.createInvoke(fact, (BcelWorld)aspectType.getWorld(), - method)); + il.append(Utility.createInvoke(fact, (BcelWorld) aspectType.getWorld(), method)); il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(method.getReturnType()))); mg.getBody().insert(il); - + gen.addMethodGen(mg); } - - + protected LazyMethodGen makeMethodGen(LazyClassGen gen, ResolvedMember member) { - LazyMethodGen ret = new LazyMethodGen( - member.getModifiers(), - BcelWorld.makeBcelType(member.getReturnType()), - member.getName(), - BcelWorld.makeBcelTypes(member.getParameterTypes()), - UnresolvedType.getNames(member.getExceptions()), - gen); - - // 43972 : Static crosscutting makes interfaces unusable for javac - // ret.makeSynthetic(); + LazyMethodGen ret = new LazyMethodGen(member.getModifiers(), BcelWorld.makeBcelType(member.getReturnType()), member + .getName(), BcelWorld.makeBcelTypes(member.getParameterTypes()), UnresolvedType.getNames(member.getExceptions()), + gen); + + // 43972 : Static crosscutting makes interfaces unusable for javac + // ret.makeSynthetic(); return ret; } - protected FieldGen makeFieldGen(LazyClassGen gen, ResolvedMember member) { - return new FieldGen( - member.getModifiers(), - BcelWorld.makeBcelType(member.getReturnType()), - member.getName(), - gen.getConstantPool()); + return new FieldGen(member.getModifiers(), BcelWorld.makeBcelType(member.getReturnType()), member.getName(), gen + .getConstantPool()); } - - - - private boolean mungePerObjectInterface( - BcelClassWeaver weaver, - PerObjectInterfaceTypeMunger munger) - { - //System.err.println("Munging perobject ["+munger+"] onto "+weaver.getLazyClassGen().getClassName()); + private boolean mungePerObjectInterface(BcelClassWeaver weaver, PerObjectInterfaceTypeMunger munger) { + // System.err.println("Munging perobject ["+munger+"] onto "+weaver. + // getLazyClassGen().getClassName()); LazyClassGen gen = weaver.getLazyClassGen(); - + if (couldMatch(gen.getBcelObjectType(), munger.getTestPointcut())) { - FieldGen fg = makeFieldGen(gen, - AjcMemberMaker.perObjectField(gen.getType(), aspectType)); - - gen.addField(fg,getSourceLocation()); - - - Type fieldType = BcelWorld.makeBcelType(aspectType); - LazyMethodGen mg = new LazyMethodGen( - Modifier.PUBLIC, - fieldType, - NameMangler.perObjectInterfaceGet(aspectType), - new Type[0], new String[0], - gen); + FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perObjectField(gen.getType(), aspectType)); + + gen.addField(fg, getSourceLocation()); + + Type fieldType = BcelWorld.makeBcelType(aspectType); + LazyMethodGen mg = new LazyMethodGen(Modifier.PUBLIC, fieldType, NameMangler.perObjectInterfaceGet(aspectType), + new Type[0], new String[0], gen); InstructionList il = new InstructionList(); InstructionFactory fact = gen.getFactory(); il.append(InstructionConstants.ALOAD_0); - il.append(fact.createFieldAccess( - gen.getClassName(), - fg.getName(), - fieldType, Constants.GETFIELD)); + il.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.GETFIELD)); il.append(InstructionFactory.createReturn(fieldType)); mg.getBody().insert(il); - + gen.addMethodGen(mg); - - LazyMethodGen mg1 = new LazyMethodGen( - Modifier.PUBLIC, - Type.VOID, - NameMangler.perObjectInterfaceSet(aspectType), - - new Type[]{fieldType,}, new String[0], - gen); + + LazyMethodGen mg1 = new LazyMethodGen(Modifier.PUBLIC, Type.VOID, NameMangler.perObjectInterfaceSet(aspectType), + + new Type[] { fieldType, }, new String[0], gen); InstructionList il1 = new InstructionList(); il1.append(InstructionConstants.ALOAD_0); il1.append(InstructionFactory.createLoad(fieldType, 1)); - il1.append(fact.createFieldAccess( - gen.getClassName(), - fg.getName(), - fieldType, Constants.PUTFIELD)); + il1.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.PUTFIELD)); il1.append(InstructionFactory.createReturn(Type.VOID)); mg1.getBody().insert(il1); - + gen.addMethodGen(mg1); - - gen.addInterface(munger.getInterfaceType(),getSourceLocation()); + + gen.addInterface(munger.getInterfaceType(), getSourceLocation()); return true; } else { return false; } } - + // PTWIMPL Add field to hold aspect instance and an accessor private boolean mungePerTypeWithinTransformer(BcelClassWeaver weaver) { LazyClassGen gen = weaver.getLazyClassGen(); - + // if (couldMatch(gen.getBcelObjectType(), munger.getTestPointcut())) { - - // Add (to the target type) the field that will hold the aspect instance - // e.g ajc$com_blah_SecurityAspect$ptwAspectInstance - FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perTypeWithinField(gen.getType(), aspectType)); - gen.addField(fg,getSourceLocation()); - - // Add an accessor for this new field, the ajc$$localAspectOf() method - // e.g. "public com_blah_SecurityAspect ajc$com_blah_SecurityAspect$localAspectOf()" - Type fieldType = BcelWorld.makeBcelType(aspectType); - LazyMethodGen mg = new LazyMethodGen( - Modifier.PUBLIC | Modifier.STATIC,fieldType, - NameMangler.perTypeWithinLocalAspectOf(aspectType), - new Type[0], new String[0],gen); - InstructionList il = new InstructionList(); - //PTWIMPL ?? Should check if it is null and throw NoAspectBoundException - InstructionFactory fact = gen.getFactory(); - il.append(fact.createFieldAccess( - gen.getClassName(), - fg.getName(), - fieldType, Constants.GETSTATIC)); - il.append(InstructionFactory.createReturn(fieldType)); - mg.getBody().insert(il); - gen.addMethodGen(mg); - return true; -// } else { -// return false; -// } + + // Add (to the target type) the field that will hold the aspect instance + // e.g ajc$com_blah_SecurityAspect$ptwAspectInstance + FieldGen fg = makeFieldGen(gen, AjcMemberMaker.perTypeWithinField(gen.getType(), aspectType)); + gen.addField(fg, getSourceLocation()); + + // Add an accessor for this new field, the + // ajc$$localAspectOf() method + // e.g. + // "public com_blah_SecurityAspect ajc$com_blah_SecurityAspect$localAspectOf()" + Type fieldType = BcelWorld.makeBcelType(aspectType); + LazyMethodGen mg = new LazyMethodGen(Modifier.PUBLIC | Modifier.STATIC, fieldType, NameMangler + .perTypeWithinLocalAspectOf(aspectType), new Type[0], new String[0], gen); + InstructionList il = new InstructionList(); + // PTWIMPL ?? Should check if it is null and throw + // NoAspectBoundException + InstructionFactory fact = gen.getFactory(); + il.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.GETSTATIC)); + il.append(InstructionFactory.createReturn(fieldType)); + mg.getBody().insert(il); + gen.addMethodGen(mg); + return true; + // } else { + // return false; + // } } - // ??? Why do we have this method? I thought by now we would know if it matched or not - private boolean couldMatch( - BcelObjectType bcelObjectType, - Pointcut pointcut) { + // ??? Why do we have this method? I thought by now we would know if it + // matched or not + private boolean couldMatch(BcelObjectType bcelObjectType, Pointcut pointcut) { return !bcelObjectType.isInterface(); } - + private boolean mungeNewMethod(BcelClassWeaver weaver, NewMethodTypeMunger munger) { World w = weaver.getWorld(); // Resolving it will sort out the tvars ResolvedMember unMangledInterMethod = munger.getSignature().resolve(w); - // do matching on the unMangled one, but actually add them to the mangled method - ResolvedMember interMethodBody = munger.getDeclaredInterMethodBody(aspectType,w); - ResolvedMember interMethodDispatcher = munger.getDeclaredInterMethodDispatcher(aspectType,w); + // do matching on the unMangled one, but actually add them to the + // mangled method + ResolvedMember interMethodBody = munger.getDeclaredInterMethodBody(aspectType, w); + ResolvedMember interMethodDispatcher = munger.getDeclaredInterMethodDispatcher(aspectType, w); ResolvedMember memberHoldingAnyAnnotations = interMethodDispatcher; - ResolvedType onType = weaver.getWorld().resolve(unMangledInterMethod.getDeclaringType(),munger.getSourceLocation()); + ResolvedType onType = weaver.getWorld().resolve(unMangledInterMethod.getDeclaringType(), munger.getSourceLocation()); LazyClassGen gen = weaver.getLazyClassGen(); boolean mungingInterface = gen.isInterface(); - - if (onType.isRawType()) onType = onType.getGenericType(); + + if (onType.isRawType()) + onType = onType.getGenericType(); boolean onInterface = onType.isInterface(); - - + // Simple checks, can't ITD on annotations or enums if (onType.isAnnotation()) { - signalError(WeaverMessages.ITDM_ON_ANNOTATION_NOT_ALLOWED,weaver,onType); - return false; + signalError(WeaverMessages.ITDM_ON_ANNOTATION_NOT_ALLOWED, weaver, onType); + return false; } - + if (onType.isEnum()) { - signalError(WeaverMessages.ITDM_ON_ENUM_NOT_ALLOWED,weaver,onType); + signalError(WeaverMessages.ITDM_ON_ENUM_NOT_ALLOWED, weaver, onType); return false; } - - if (onInterface && gen.getLazyMethodGen(unMangledInterMethod.getName(), unMangledInterMethod.getSignature(),true) != null) { - // this is ok, we could be providing the default implementation of a method - // that the target has already declared - return false; + + if (onInterface && gen.getLazyMethodGen(unMangledInterMethod.getName(), unMangledInterMethod.getSignature(), true) != null) { + // this is ok, we could be providing the default implementation of a + // method + // that the target has already declared + return false; } - - // If we are processing the intended ITD target type (might be an interface) + + // If we are processing the intended ITD target type (might be an + // interface) if (onType.equals(gen.getType())) { - ResolvedMember mangledInterMethod = - AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, onInterface); - - + ResolvedMember mangledInterMethod = AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, onInterface); + LazyMethodGen newMethod = makeMethodGen(gen, mangledInterMethod); if (mungingInterface) { - // we want the modifiers of the ITD to be used for all *implementors* of the - // interface, but the method itself we add to the interface must be public abstract + // we want the modifiers of the ITD to be used for all + // *implementors* of the + // interface, but the method itself we add to the interface must + // be public abstract newMethod.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT); } - + // pr98901 - // For copying the annotations across, we have to discover the real member in the aspect - // which is holding them. - if (weaver.getWorld().isInJava5Mode()){ - AnnotationX annotationsOnRealMember[] = null; + // For copying the annotations across, we have to discover the real + // member in the aspect + // which is holding them. + if (weaver.getWorld().isInJava5Mode()) { + AnnotationAJ annotationsOnRealMember[] = null; ResolvedType toLookOn = aspectType; - if (aspectType.isRawType()) toLookOn = aspectType.getGenericType(); - ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn,memberHoldingAnyAnnotations,false); - if (realMember==null) throw new BCException("Couldn't find ITD holder member '"+ - memberHoldingAnyAnnotations+"' on aspect "+aspectType); + if (aspectType.isRawType()) + toLookOn = aspectType.getGenericType(); + ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn, memberHoldingAnyAnnotations, false); + if (realMember == null) + throw new BCException("Couldn't find ITD holder member '" + memberHoldingAnyAnnotations + "' on aspect " + + aspectType); annotationsOnRealMember = realMember.getAnnotations(); - - if (annotationsOnRealMember!=null) { + + if (annotationsOnRealMember != null) { for (int i = 0; i < annotationsOnRealMember.length; i++) { - AnnotationX annotationX = annotationsOnRealMember[i]; - AnnotationGen a = annotationX.getBcelAnnotation(); - AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); - newMethod.addAnnotation(new AnnotationX(ag,weaver.getWorld())); + AnnotationAJ annotationX = annotationsOnRealMember[i]; + AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation(); + AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true); + newMethod.addAnnotation(new BcelAnnotation(ag, weaver.getWorld())); } } // the below loop fixes the very special (and very stupid) // case where an aspect declares an annotation // on an ITD it declared on itself. List allDecams = weaver.getWorld().getDeclareAnnotationOnMethods(); - for (Iterator i = allDecams.iterator(); i.hasNext();){ - DeclareAnnotation decaMC = (DeclareAnnotation) i.next(); - if (decaMC.matches(unMangledInterMethod,weaver.getWorld()) + for (Iterator i = allDecams.iterator(); i.hasNext();) { + DeclareAnnotation decaMC = (DeclareAnnotation) i.next(); + if (decaMC.matches(unMangledInterMethod, weaver.getWorld()) && newMethod.getEnclosingClass().getType() == aspectType) { newMethod.addAnnotation(decaMC.getAnnotationX()); } } } - // If it doesn't target an interface and there is a body (i.e. it isnt abstract) + // If it doesn't target an interface and there is a body (i.e. it + // isnt abstract) if (!onInterface && !Modifier.isAbstract(mangledInterMethod.getModifiers())) { InstructionList body = newMethod.getBody(); InstructionFactory fact = gen.getFactory(); int pos = 0; - + if (!unMangledInterMethod.isStatic()) { body.append(InstructionFactory.createThis()); pos++; @@ -839,214 +835,233 @@ public class BcelTypeMunger extends ConcreteTypeMunger { for (int i = 0, len = paramTypes.length; i < len; i++) { Type paramType = paramTypes[i]; body.append(InstructionFactory.createLoad(paramType, pos)); - pos+=paramType.getSize(); + pos += paramType.getSize(); } body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody)); - body.append( - InstructionFactory.createReturn( - BcelWorld.makeBcelType(mangledInterMethod.getReturnType()))); - - if (weaver.getWorld().isInJava5Mode()) { // Don't need bridge methods if not in 1.5 mode. + body.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(mangledInterMethod.getReturnType()))); + + if (weaver.getWorld().isInJava5Mode()) { // Don't need bridge + // methods if not in + // 1.5 mode. createAnyBridgeMethodsForCovariance(weaver, munger, unMangledInterMethod, onType, gen, paramTypes); } - + } else { - //??? this is okay - //if (!(mg.getBody() == null)) throw new RuntimeException("bas"); + // ??? this is okay + // if (!(mg.getBody() == null)) throw new + // RuntimeException("bas"); } - - if (weaver.getWorld().isInJava5Mode()){ + if (weaver.getWorld().isInJava5Mode()) { String basicSignature = mangledInterMethod.getSignature(); - String genericSignature = ((ResolvedMemberImpl)mangledInterMethod).getSignatureForAttribute(); + String genericSignature = ((ResolvedMemberImpl) mangledInterMethod).getSignatureForAttribute(); if (!basicSignature.equals(genericSignature)) { // Add a signature attribute to it - newMethod.addAttribute(createSignatureAttribute(gen.getConstantPool(),genericSignature)); + newMethod.addAttribute(createSignatureAttribute(gen.getConstantPool(), genericSignature)); } } - // XXX make sure to check that we set exceptions properly on this guy. + // XXX make sure to check that we set exceptions properly on this + // guy. weaver.addLazyMethodGen(newMethod); - weaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(),getSignature().getSourceLocation()); - + weaver.getLazyClassGen().warnOnAddedMethod(newMethod.getMethod(), getSignature().getSourceLocation()); + addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled()); - - return true; - + + return true; + } else if (onInterface && !Modifier.isAbstract(unMangledInterMethod.getModifiers())) { - + // This means the 'gen' should be the top most implementor // - if it is *not* then something went wrong after we worked // out that it was the top most implementor (see pr49657) - if (!gen.getType().isTopmostImplementor(onType)) { - ResolvedType rtx = gen.getType().getTopmostImplementor(onType); - if (!rtx.isExposedToWeaver()) { - ISourceLocation sLoc = munger.getSourceLocation(); - weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error( - WeaverMessages.format(WeaverMessages.ITD_NON_EXPOSED_IMPLEMENTOR,rtx,getAspectType().getName()), - (sLoc==null?getAspectType().getSourceLocation():sLoc))); - } else { - // XXX what does this state mean? - // We have incorrectly identified what is the top most implementor and its not because - // a type wasn't exposed to the weaver - } + if (!gen.getType().isTopmostImplementor(onType)) { + ResolvedType rtx = gen.getType().getTopmostImplementor(onType); + if (!rtx.isExposedToWeaver()) { + ISourceLocation sLoc = munger.getSourceLocation(); + weaver.getWorld().getMessageHandler().handleMessage( + MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_NON_EXPOSED_IMPLEMENTOR, rtx, + getAspectType().getName()), (sLoc == null ? getAspectType().getSourceLocation() : sLoc))); + } else { + // XXX what does this state mean? + // We have incorrectly identified what is the top most + // implementor and its not because + // a type wasn't exposed to the weaver + } return false; - } else { - - ResolvedMember mangledInterMethod = - AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, false); - - LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod); - - // From 98901#29 - need to copy annotations across - if (weaver.getWorld().isInJava5Mode()){ - AnnotationX annotationsOnRealMember[] = null; + } else { + + ResolvedMember mangledInterMethod = AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, false); + + LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod); + + // From 98901#29 - need to copy annotations across + if (weaver.getWorld().isInJava5Mode()) { + AnnotationAJ annotationsOnRealMember[] = null; ResolvedType toLookOn = aspectType; - if (aspectType.isRawType()) toLookOn = aspectType.getGenericType(); - ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn,memberHoldingAnyAnnotations,false); - if (realMember==null) throw new BCException("Couldn't find ITD holder member '"+ - memberHoldingAnyAnnotations+"' on aspect "+aspectType); + if (aspectType.isRawType()) + toLookOn = aspectType.getGenericType(); + ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn, memberHoldingAnyAnnotations, false); + if (realMember == null) + throw new BCException("Couldn't find ITD holder member '" + memberHoldingAnyAnnotations + "' on aspect " + + aspectType); annotationsOnRealMember = realMember.getAnnotations(); - - if (annotationsOnRealMember!=null) { + + if (annotationsOnRealMember != null) { for (int i = 0; i < annotationsOnRealMember.length; i++) { - AnnotationX annotationX = annotationsOnRealMember[i]; - AnnotationGen a = annotationX.getBcelAnnotation(); - AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); - mg.addAnnotation(new AnnotationX(ag,weaver.getWorld())); + AnnotationAJ annotationX = annotationsOnRealMember[i]; + AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation(); + AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true); + mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld())); } } - } - - if (mungingInterface) { - // we want the modifiers of the ITD to be used for all *implementors* of the - // interface, but the method itself we add to the interface must be public abstract - mg.setAccessFlags(Modifier.PUBLIC | Modifier.ABSTRACT); - } - - Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes()); - Type returnType = BcelWorld.makeBcelType(mangledInterMethod.getReturnType()); - - InstructionList body = mg.getBody(); - InstructionFactory fact = gen.getFactory(); - int pos = 0; - - if (!mangledInterMethod.isStatic()) { - body.append(InstructionFactory.createThis()); - pos++; - } - for (int i = 0, len = paramTypes.length; i < len; i++) { - Type paramType = paramTypes[i]; - body.append(InstructionFactory.createLoad(paramType, pos)); - pos+=paramType.getSize(); - } - - body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody)); - Type t= BcelWorld.makeBcelType(interMethodBody.getReturnType()); - if (!t.equals(returnType)) { - body.append(fact.createCast(t,returnType)); - } - body.append(InstructionFactory.createReturn(returnType)); - mg.definingType = onType; - - - if (weaver.getWorld().isInJava5Mode()) { - String basicSignature = mangledInterMethod.getSignature(); - String genericSignature = ((ResolvedMemberImpl)mangledInterMethod).getSignatureForAttribute(); - if (!basicSignature.equals(genericSignature)) { - // Add a signature attribute to it - mg.addAttribute(createSignatureAttribute(gen.getConstantPool(),genericSignature)); - } - } - - weaver.addOrReplaceLazyMethodGen(mg); - - addNeededSuperCallMethods(weaver, onType, munger.getSuperMethodsCalled()); - - // Work out if we need a bridge method for the new method added to the topmostimplementor. - if (munger.getDeclaredSignature()!=null) { // Check if the munger being processed is a parameterized form of some original munger. - boolean needsbridging = false; - ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,munger.getSignature().getDeclaringType().resolve(getWorld()),false,munger.getTypeVariableAliases()); - if (!toBridgeTo.getReturnType().getErasureSignature().equals(munger.getSignature().getReturnType().getErasureSignature())) needsbridging = true; - UnresolvedType[] originalParams = toBridgeTo.getParameterTypes(); - UnresolvedType[] newParams = munger.getSignature().getParameterTypes(); - for (int ii = 0;ii;" + + /** + * Helper method to create a signature attribute based on a string signature: e.g. "Ljava/lang/Object;LI;" */ - private Signature createSignatureAttribute(ConstantPool cp,String signature) { + private Signature createSignatureAttribute(ConstantPool cp, String signature) { int nameIndex = cp.addUtf8("Signature"); - int sigIndex = cp.addUtf8(signature); - return new Signature(nameIndex,2,sigIndex,cp); + int sigIndex = cp.addUtf8(signature); + return new Signature(nameIndex, 2, sigIndex, cp); } - + /** - * Create any bridge method required because of covariant returns being used. This method is used in the case - * where an ITD is applied to some type and it may be in an override relationship with a method from the supertype - but - * due to covariance there is a mismatch in return values. - * Example of when required: - Super defines: Object m(String s) - Sub defines: String m(String s) - then we need a bridge method in Sub called 'Object m(String s)' that forwards to 'String m(String s)' + * Create any bridge method required because of covariant returns being used. This method is used in the case where an ITD is + * applied to some type and it may be in an override relationship with a method from the supertype - but due to covariance there + * is a mismatch in return values. Example of when required: Super defines: Object m(String s) Sub defines: String m(String s) + * then we need a bridge method in Sub called 'Object m(String s)' that forwards to 'String m(String s)' */ - private void createAnyBridgeMethodsForCovariance(BcelClassWeaver weaver, NewMethodTypeMunger munger, ResolvedMember unMangledInterMethod, ResolvedType onType, LazyClassGen gen, Type[] paramTypes) { - // PERFORMANCE BOTTLENECK? Might need investigating, method analysis between types in a hierarchy just seems expensive... + private void createAnyBridgeMethodsForCovariance(BcelClassWeaver weaver, NewMethodTypeMunger munger, + ResolvedMember unMangledInterMethod, ResolvedType onType, LazyClassGen gen, Type[] paramTypes) { + // PERFORMANCE BOTTLENECK? Might need investigating, method analysis + // between types in a hierarchy just seems expensive... // COVARIANCE BRIDGING - // Algorithm: Step1. Check in this type - has someone already created the bridge method? - // Step2. Look above us - do we 'override' a method and yet differ in return type (i.e. covariance) - // Step3. Create a forwarding bridge method -// ResolvedType superclass = onType.getSuperclass(); + // Algorithm: Step1. Check in this type - has someone already created + // the bridge method? + // Step2. Look above us - do we 'override' a method and yet differ in + // return type (i.e. covariance) + // Step3. Create a forwarding bridge method + // ResolvedType superclass = onType.getSuperclass(); boolean quitRightNow = false; - - String localMethodName = unMangledInterMethod.getName(); - String localParameterSig = unMangledInterMethod.getParameterSignature(); - String localReturnTypeESig = unMangledInterMethod.getReturnType().getErasureSignature(); + + String localMethodName = unMangledInterMethod.getName(); + String localParameterSig = unMangledInterMethod.getParameterSignature(); + String localReturnTypeESig = unMangledInterMethod.getReturnType().getErasureSignature(); // Step1 boolean alreadyDone = false; // Compiler might have done it @@ -1055,18 +1070,22 @@ public class BcelTypeMunger extends ConcreteTypeMunger { ResolvedMember member = localMethods[i]; if (member.getName().equals(localMethodName)) { // Check the params - if (member.getParameterSignature().equals(localParameterSig)) alreadyDone = true; + if (member.getParameterSignature().equals(localParameterSig)) + alreadyDone = true; } } - + // Step2 if (!alreadyDone) { - // Use the iterator form of 'getMethods()' so we do as little work as necessary - for (Iterator iter = onType.getSuperclass().getMethods();iter.hasNext() && !quitRightNow;) { + // Use the iterator form of 'getMethods()' so we do as little work + // as necessary + for (Iterator iter = onType.getSuperclass().getMethods(); iter.hasNext() && !quitRightNow;) { ResolvedMember aMethod = (ResolvedMember) iter.next(); if (aMethod.getName().equals(localMethodName) && aMethod.getParameterSignature().equals(localParameterSig)) { - // check the return types, if they are different we need a bridging method. - if (!aMethod.getReturnType().getErasureSignature().equals(localReturnTypeESig) && !Modifier.isPrivate(aMethod.getModifiers())) { + // check the return types, if they are different we need a + // bridging method. + if (!aMethod.getReturnType().getErasureSignature().equals(localReturnTypeESig) + && !Modifier.isPrivate(aMethod.getModifiers())) { // Step3 createBridgeMethod(weaver.getWorld(), munger, unMangledInterMethod, gen, paramTypes, aMethod); quitRightNow = true; @@ -1077,370 +1096,384 @@ public class BcelTypeMunger extends ConcreteTypeMunger { } /** - * Create a bridge method for a particular munger. + * Create a bridge method for a particular munger. + * * @param world * @param munger * @param unMangledInterMethod the method to bridge 'to' that we have already created in the 'subtype' * @param clazz the class in which to put the bridge method - * @param paramTypes Parameter types for the bridge method, passed in as an optimization since the caller is likely to have already created them. - * @param theBridgeMethod + * @param paramTypes Parameter types for the bridge method, passed in as an optimization since the caller is likely to have + * already created them. + * @param theBridgeMethod */ - private void createBridgeMethod(BcelWorld world, NewMethodTypeMunger munger, - ResolvedMember unMangledInterMethod, LazyClassGen clazz, Type[] paramTypes, ResolvedMember theBridgeMethod) { + private void createBridgeMethod(BcelWorld world, NewMethodTypeMunger munger, ResolvedMember unMangledInterMethod, + LazyClassGen clazz, Type[] paramTypes, ResolvedMember theBridgeMethod) { InstructionList body; InstructionFactory fact; int pos = 0; - - LazyMethodGen bridgeMethod = makeMethodGen(clazz,theBridgeMethod); // The bridge method in this type will have the same signature as the one in the supertype - bridgeMethod.setAccessFlags(bridgeMethod.getAccessFlags() | 0x00000040 /*BRIDGE = 0x00000040*/ ); -// UnresolvedType[] newParams = munger.getSignature().getParameterTypes(); - Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType()); + + LazyMethodGen bridgeMethod = makeMethodGen(clazz, theBridgeMethod); // The + // bridge + // method + // in + // this + // type + // will + // have + // the + // same + // signature + // as + // the + // one + // in + // the + // supertype + bridgeMethod.setAccessFlags(bridgeMethod.getAccessFlags() | 0x00000040 /* + * BRIDGE = 0x00000040 + */); + // UnresolvedType[] newParams = + // munger.getSignature().getParameterTypes(); + Type returnType = BcelWorld.makeBcelType(theBridgeMethod.getReturnType()); body = bridgeMethod.getBody(); fact = clazz.getFactory(); if (!unMangledInterMethod.isStatic()) { - body.append(InstructionFactory.createThis()); - pos++; + body.append(InstructionFactory.createThis()); + pos++; } for (int i = 0, len = paramTypes.length; i < len; i++) { - Type paramType = paramTypes[i]; - body.append(InstructionFactory.createLoad(paramType, pos)); -// if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(unMangledInterMethod.getParameterTypes()[i].getErasureSignature())) { -// System.err.println("Putting in cast from "+paramType+" to "+bridgingToParms[i]); -// body.append(fact.createCast(paramType,bridgingToParms[i])); -// } - pos+=paramType.getSize(); + Type paramType = paramTypes[i]; + body.append(InstructionFactory.createLoad(paramType, pos)); + // if (!bridgingSetter.getParameterTypes()[i].getErasureSignature(). + // equals + // (unMangledInterMethod.getParameterTypes()[i].getErasureSignature + // ())) { + // System.err.println("Putting in cast from "+paramType+" to "+ + // bridgingToParms[i]); + // body.append(fact.createCast(paramType,bridgingToParms[i])); + // } + pos += paramType.getSize(); } - body.append(Utility.createInvoke(fact, world,unMangledInterMethod)); + body.append(Utility.createInvoke(fact, world, unMangledInterMethod)); body.append(InstructionFactory.createReturn(returnType)); clazz.addMethodGen(bridgeMethod); } - + // Unlike toString() on a member, this does not include the declaring type private String stringifyMember(ResolvedMember member) { StringBuffer buf = new StringBuffer(); - buf.append(member.getReturnType().getName()); - buf.append(' '); - buf.append(member.getName()); - if (member.getKind() != Member.FIELD) { - buf.append("("); - UnresolvedType[] params = member.getParameterTypes(); - if (params.length != 0) { - buf.append(params[0]); - for (int i=1, len = params.length; i < len; i++) { - buf.append(", "); - buf.append(params[i].getName()); - } - } - buf.append(")"); - } - return buf.toString(); + buf.append(member.getReturnType().getName()); + buf.append(' '); + buf.append(member.getName()); + if (member.getKind() != Member.FIELD) { + buf.append("("); + UnresolvedType[] params = member.getParameterTypes(); + if (params.length != 0) { + buf.append(params[0]); + for (int i = 1, len = params.length; i < len; i++) { + buf.append(", "); + buf.append(params[i].getName()); + } + } + buf.append(")"); + } + return buf.toString(); } - - private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) { - ResolvedMember introduced = munger.getSignature(); - - LazyClassGen gen = weaver.getLazyClassGen(); - - ResolvedType fromType = weaver.getWorld().resolve(introduced.getDeclaringType(),munger.getSourceLocation()); - if (fromType.isRawType()) fromType = fromType.getGenericType(); - - if (gen.getType().isAnnotation() || gen.getType().isEnum()) { - // don't signal error as it could be a consequence of a wild type pattern - return false; - } - - boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType); - if (shouldApply) { - - // If no implementation class was specified, the intention was that the types matching the pattern - // already implemented the interface, let's check that now! - if (munger.getImplClassName()==null) { - boolean isOK = false; - List/*LazyMethodGen*/ existingMethods = gen.getMethodGens(); - for (Iterator i = existingMethods.iterator(); i.hasNext() && !isOK;) { - LazyMethodGen m = (LazyMethodGen) i.next(); - if (m.getName().equals(introduced.getName()) && - m.getParameterSignature().equals(introduced.getParameterSignature()) && - m.getReturnType().equals(introduced.getReturnType())) { - isOK = true; - } - } - if (!isOK) { - // the class does not implement this method, they needed to supply a default impl class - IMessage msg = new Message("@DeclareParents: No defaultImpl was specified but the type '"+gen.getName()+ - "' does not implement the method '"+stringifyMember(introduced)+"' defined on the interface '"+introduced.getDeclaringType()+"'", - weaver.getLazyClassGen().getType().getSourceLocation(),true,new ISourceLocation[]{munger.getSourceLocation()}); - weaver.getWorld().getMessageHandler().handleMessage(msg); - return false; - } - - return true; - } - - - - LazyMethodGen mg = new LazyMethodGen( - introduced.getModifiers() - Modifier.ABSTRACT, - BcelWorld.makeBcelType(introduced.getReturnType()), - introduced.getName(), - BcelWorld.makeBcelTypes(introduced.getParameterTypes()), - BcelWorld.makeBcelTypesAsClassNames(introduced.getExceptions()), - gen - ); - - //annotation copy from annotation on ITD interface - if (weaver.getWorld().isInJava5Mode()){ - AnnotationX annotationsOnRealMember[] = null; - ResolvedType toLookOn = weaver.getWorld().lookupOrCreateName(introduced.getDeclaringType()); - if (fromType.isRawType()) toLookOn = fromType.getGenericType(); - // lookup the method - ResolvedMember[] ms = toLookOn.getDeclaredJavaMethods(); - for (int i = 0; i < ms.length; i++) { - ResolvedMember m = ms[i]; - if (introduced.getName().equals(m.getName()) && introduced.getSignature().equals(m.getSignature())) { - annotationsOnRealMember = m.getAnnotations(); - } - } - if (annotationsOnRealMember!=null) { - for (int i = 0; i < annotationsOnRealMember.length; i++) { - AnnotationX annotationX = annotationsOnRealMember[i]; - AnnotationGen a = annotationX.getBcelAnnotation(); - AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); - mg.addAnnotation(new AnnotationX(ag,weaver.getWorld())); - } - } - } - - InstructionList body = new InstructionList(); - InstructionFactory fact = gen.getFactory(); - - // getfield - body.append(InstructionConstants.ALOAD_0); - body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); - InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); - body.append(ifNonNull); - - // Create and store a new instance - body.append(InstructionConstants.ALOAD_0); - body.append(fact.createNew(munger.getImplClassName())); - body.append(InstructionConstants.DUP); - body.append(fact.createInvoke(munger.getImplClassName(), "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); - body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); - - // if not null use the instance we've got - InstructionHandle ifNonNullElse = body.append(InstructionConstants.ALOAD_0); - ifNonNull.setTarget(ifNonNullElse); - body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); - - //args - int pos = 0; - if (!introduced.isStatic()) { // skip 'this' (?? can this really happen) - //body.append(InstructionFactory.createThis()); - pos++; - } - Type[] paramTypes = BcelWorld.makeBcelTypes(introduced.getParameterTypes()); - for (int i = 0, len = paramTypes.length; i < len; i++) { - Type paramType = paramTypes[i]; - body.append(InstructionFactory.createLoad(paramType, pos)); - pos+=paramType.getSize(); - } - body.append(Utility.createInvoke(fact, Constants.INVOKEINTERFACE, introduced)); - body.append( - InstructionFactory.createReturn( - BcelWorld.makeBcelType(introduced.getReturnType()) - ) - ); - - mg.getBody().append(body); - weaver.addLazyMethodGen(mg); - weaver.getLazyClassGen().warnOnAddedMethod(mg.getMethod(),getSignature().getSourceLocation()); - return true; - } - return false; - } - - private boolean mungeFieldHost(BcelClassWeaver weaver, MethodDelegateTypeMunger.FieldHostTypeMunger munger) { - LazyClassGen gen = weaver.getLazyClassGen(); - if (gen.getType().isAnnotation() || gen.getType().isEnum()) { - // don't signal error as it could be a consequence of a wild type pattern - return false; - } -// boolean shouldApply = - munger.matches(weaver.getLazyClassGen().getType(), aspectType); // why do this? - ResolvedMember host = AjcMemberMaker.itdAtDeclareParentsField( - weaver.getLazyClassGen().getType(), - munger.getSignature().getType(), - aspectType); - weaver.getLazyClassGen().addField(makeFieldGen( - weaver.getLazyClassGen(), - host), null); - return true; - } - - - private ResolvedMember getRealMemberForITDFromAspect(ResolvedType aspectType,ResolvedMember lookingFor,boolean isCtorRelated) { + + private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) { + ResolvedMember introduced = munger.getSignature(); + + LazyClassGen gen = weaver.getLazyClassGen(); + + ResolvedType fromType = weaver.getWorld().resolve(introduced.getDeclaringType(), munger.getSourceLocation()); + if (fromType.isRawType()) + fromType = fromType.getGenericType(); + + if (gen.getType().isAnnotation() || gen.getType().isEnum()) { + // don't signal error as it could be a consequence of a wild type + // pattern + return false; + } + + boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType); + if (shouldApply) { + + // If no implementation class was specified, the intention was that + // the types matching the pattern + // already implemented the interface, let's check that now! + if (munger.getImplClassName() == null) { + boolean isOK = false; + List/* LazyMethodGen */existingMethods = gen.getMethodGens(); + for (Iterator i = existingMethods.iterator(); i.hasNext() && !isOK;) { + LazyMethodGen m = (LazyMethodGen) i.next(); + if (m.getName().equals(introduced.getName()) + && m.getParameterSignature().equals(introduced.getParameterSignature()) + && m.getReturnType().equals(introduced.getReturnType())) { + isOK = true; + } + } + if (!isOK) { + // the class does not implement this method, they needed to + // supply a default impl class + IMessage msg = new Message("@DeclareParents: No defaultImpl was specified but the type '" + gen.getName() + + "' does not implement the method '" + stringifyMember(introduced) + "' defined on the interface '" + + introduced.getDeclaringType() + "'", weaver.getLazyClassGen().getType().getSourceLocation(), true, + new ISourceLocation[] { munger.getSourceLocation() }); + weaver.getWorld().getMessageHandler().handleMessage(msg); + return false; + } + + return true; + } + + LazyMethodGen mg = new LazyMethodGen(introduced.getModifiers() - Modifier.ABSTRACT, BcelWorld.makeBcelType(introduced + .getReturnType()), introduced.getName(), BcelWorld.makeBcelTypes(introduced.getParameterTypes()), BcelWorld + .makeBcelTypesAsClassNames(introduced.getExceptions()), gen); + + // annotation copy from annotation on ITD interface + if (weaver.getWorld().isInJava5Mode()) { + AnnotationAJ annotationsOnRealMember[] = null; + ResolvedType toLookOn = weaver.getWorld().lookupOrCreateName(introduced.getDeclaringType()); + if (fromType.isRawType()) + toLookOn = fromType.getGenericType(); + // lookup the method + ResolvedMember[] ms = toLookOn.getDeclaredJavaMethods(); + for (int i = 0; i < ms.length; i++) { + ResolvedMember m = ms[i]; + if (introduced.getName().equals(m.getName()) && introduced.getSignature().equals(m.getSignature())) { + annotationsOnRealMember = m.getAnnotations(); + } + } + if (annotationsOnRealMember != null) { + for (int i = 0; i < annotationsOnRealMember.length; i++) { + AnnotationAJ annotationX = annotationsOnRealMember[i]; + AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation(); + AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true); + mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld())); + } + } + } + + InstructionList body = new InstructionList(); + InstructionFactory fact = gen.getFactory(); + + // getfield + body.append(InstructionConstants.ALOAD_0); + body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); + InstructionBranch ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); + body.append(ifNonNull); + + // Create and store a new instance + body.append(InstructionConstants.ALOAD_0); + body.append(fact.createNew(munger.getImplClassName())); + body.append(InstructionConstants.DUP); + body.append(fact.createInvoke(munger.getImplClassName(), "", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + body.append(Utility.createSet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); + + // if not null use the instance we've got + InstructionHandle ifNonNullElse = body.append(InstructionConstants.ALOAD_0); + ifNonNull.setTarget(ifNonNullElse); + body.append(Utility.createGet(fact, munger.getDelegate(weaver.getLazyClassGen().getType()))); + + // args + int pos = 0; + if (!introduced.isStatic()) { // skip 'this' (?? can this really + // happen) + // body.append(InstructionFactory.createThis()); + pos++; + } + Type[] paramTypes = BcelWorld.makeBcelTypes(introduced.getParameterTypes()); + for (int i = 0, len = paramTypes.length; i < len; i++) { + Type paramType = paramTypes[i]; + body.append(InstructionFactory.createLoad(paramType, pos)); + pos += paramType.getSize(); + } + body.append(Utility.createInvoke(fact, Constants.INVOKEINTERFACE, introduced)); + body.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(introduced.getReturnType()))); + + mg.getBody().append(body); + weaver.addLazyMethodGen(mg); + weaver.getLazyClassGen().warnOnAddedMethod(mg.getMethod(), getSignature().getSourceLocation()); + return true; + } + return false; + } + + private boolean mungeFieldHost(BcelClassWeaver weaver, MethodDelegateTypeMunger.FieldHostTypeMunger munger) { + LazyClassGen gen = weaver.getLazyClassGen(); + if (gen.getType().isAnnotation() || gen.getType().isEnum()) { + // don't signal error as it could be a consequence of a wild type + // pattern + return false; + } + // boolean shouldApply = + munger.matches(weaver.getLazyClassGen().getType(), aspectType); // why + // do + // this? + ResolvedMember host = AjcMemberMaker.itdAtDeclareParentsField(weaver.getLazyClassGen().getType(), munger.getSignature() + .getType(), aspectType); + weaver.getLazyClassGen().addField(makeFieldGen(weaver.getLazyClassGen(), host), null); + return true; + } + + private ResolvedMember getRealMemberForITDFromAspect(ResolvedType aspectType, ResolvedMember lookingFor, boolean isCtorRelated) { World world = aspectType.getWorld(); boolean debug = false; if (debug) { - System.err.println("Searching for a member on type: "+aspectType); - System.err.println("Member we are looking for: "+lookingFor); + System.err.println("Searching for a member on type: " + aspectType); + System.err.println("Member we are looking for: " + lookingFor); } ResolvedMember aspectMethods[] = aspectType.getDeclaredMethods(); - UnresolvedType [] lookingForParams = lookingFor.getParameterTypes(); - + UnresolvedType[] lookingForParams = lookingFor.getParameterTypes(); + ResolvedMember realMember = null; - for (int i = 0; realMember==null && i < aspectMethods.length; i++) { + for (int i = 0; realMember == null && i < aspectMethods.length; i++) { ResolvedMember member = aspectMethods[i]; - if (member.getName().equals(lookingFor.getName())){ - UnresolvedType [] memberParams = member.getGenericParameterTypes(); - if (memberParams.length == lookingForParams.length){ - if (debug) System.err.println("Reviewing potential candidates: "+member); + if (member.getName().equals(lookingFor.getName())) { + UnresolvedType[] memberParams = member.getGenericParameterTypes(); + if (memberParams.length == lookingForParams.length) { + if (debug) + System.err.println("Reviewing potential candidates: " + member); boolean matchOK = true; - // If not related to a ctor ITD then the name is enough to confirm we have the - // right one. If it is ctor related we need to check the params all match, although + // If not related to a ctor ITD then the name is enough to + // confirm we have the + // right one. If it is ctor related we need to check the + // params all match, although // only the erasure. if (isCtorRelated) { - for (int j = 0; j < memberParams.length && matchOK; j++){ - ResolvedType pMember = memberParams[j].resolve(world); - ResolvedType pLookingFor = lookingForParams[j].resolve(world); - - if (pMember.isTypeVariableReference()) - pMember = ((TypeVariableReference)pMember).getTypeVariable().getFirstBound().resolve(world); - if (pMember.isParameterizedType() || pMember.isGenericType()) - pMember = pMember.getRawType().resolve(aspectType.getWorld()); - - if (pLookingFor.isTypeVariableReference()) - pLookingFor = ((TypeVariableReference)pLookingFor).getTypeVariable().getFirstBound().resolve(world); - if (pLookingFor.isParameterizedType() || pLookingFor.isGenericType()) - pLookingFor = pLookingFor.getRawType().resolve(world); - - if (debug) System.err.println("Comparing parameter "+j+" member="+pMember+" lookingFor="+pLookingFor); - if (!pMember.equals(pLookingFor)){ - matchOK=false; + for (int j = 0; j < memberParams.length && matchOK; j++) { + ResolvedType pMember = memberParams[j].resolve(world); + ResolvedType pLookingFor = lookingForParams[j].resolve(world); + + if (pMember.isTypeVariableReference()) + pMember = ((TypeVariableReference) pMember).getTypeVariable().getFirstBound().resolve(world); + if (pMember.isParameterizedType() || pMember.isGenericType()) + pMember = pMember.getRawType().resolve(aspectType.getWorld()); + + if (pLookingFor.isTypeVariableReference()) + pLookingFor = ((TypeVariableReference) pLookingFor).getTypeVariable().getFirstBound() + .resolve(world); + if (pLookingFor.isParameterizedType() || pLookingFor.isGenericType()) + pLookingFor = pLookingFor.getRawType().resolve(world); + + if (debug) + System.err.println("Comparing parameter " + j + " member=" + pMember + " lookingFor=" + + pLookingFor); + if (!pMember.equals(pLookingFor)) { + matchOK = false; + } } - } } - if (matchOK) realMember = member; + if (matchOK) + realMember = member; } } } - if (debug && realMember==null) System.err.println("Didn't find a match"); + if (debug && realMember == null) + System.err.println("Didn't find a match"); return realMember; } - private void addNeededSuperCallMethods( - BcelClassWeaver weaver, - ResolvedType onType, - Set neededSuperCalls) - { + private void addNeededSuperCallMethods(BcelClassWeaver weaver, ResolvedType onType, Set neededSuperCalls) { LazyClassGen gen = weaver.getLazyClassGen(); - + for (Iterator iter = neededSuperCalls.iterator(); iter.hasNext();) { ResolvedMember superMethod = (ResolvedMember) iter.next(); if (weaver.addDispatchTarget(superMethod)) { - //System.err.println("super type: " + superMethod.getDeclaringType() + ", " + gen.getType()); + // System.err.println("super type: " + + // superMethod.getDeclaringType() + ", " + gen.getType()); boolean isSuper = !superMethod.getDeclaringType().equals(gen.getType()); String dispatchName; if (isSuper) - dispatchName = - NameMangler.superDispatchMethod(onType, superMethod.getName()); + dispatchName = NameMangler.superDispatchMethod(onType, superMethod.getName()); else - dispatchName = - NameMangler.protectedDispatchMethod( - onType, - superMethod.getName()); + dispatchName = NameMangler.protectedDispatchMethod(onType, superMethod.getName()); superMethod = superMethod.resolve(weaver.getWorld()); - LazyMethodGen dispatcher = - makeDispatcher( - gen, - dispatchName, - superMethod, - weaver.getWorld(), - isSuper); + LazyMethodGen dispatcher = makeDispatcher(gen, dispatchName, superMethod, weaver.getWorld(), isSuper); weaver.addLazyMethodGen(dispatcher); } } } - private void signalError(String msgid,BcelClassWeaver weaver,UnresolvedType onType) { - IMessage msg = MessageUtil.error( - WeaverMessages.format(msgid,onType.getName()),getSourceLocation()); + private void signalError(String msgid, BcelClassWeaver weaver, UnresolvedType onType) { + IMessage msg = MessageUtil.error(WeaverMessages.format(msgid, onType.getName()), getSourceLocation()); weaver.getWorld().getMessageHandler().handleMessage(msg); } - private boolean mungeNewConstructor( - BcelClassWeaver weaver, - NewConstructorTypeMunger newConstructorTypeMunger) - { - + private boolean mungeNewConstructor(BcelClassWeaver weaver, NewConstructorTypeMunger newConstructorTypeMunger) { + final LazyClassGen currentClass = weaver.getLazyClassGen(); final InstructionFactory fact = currentClass.getFactory(); ResolvedMember newConstructorMember = newConstructorTypeMunger.getSyntheticConstructor(); - ResolvedType onType = newConstructorMember.getDeclaringType().resolve(weaver.getWorld()); - if (onType.isRawType()) onType = onType.getGenericType(); - + ResolvedType onType = newConstructorMember.getDeclaringType().resolve(weaver.getWorld()); + if (onType.isRawType()) + onType = onType.getGenericType(); + if (onType.isAnnotation()) { - signalError(WeaverMessages.ITDC_ON_ANNOTATION_NOT_ALLOWED,weaver,onType); + signalError(WeaverMessages.ITDC_ON_ANNOTATION_NOT_ALLOWED, weaver, onType); return false; } - + if (onType.isEnum()) { - signalError(WeaverMessages.ITDC_ON_ENUM_NOT_ALLOWED,weaver,onType); + signalError(WeaverMessages.ITDC_ON_ENUM_NOT_ALLOWED, weaver, onType); return false; } - - if (! onType.equals(currentClass.getType())) return false; + + if (!onType.equals(currentClass.getType())) + return false; ResolvedMember explicitConstructor = newConstructorTypeMunger.getExplicitConstructor(); - //int declaredParameterCount = newConstructorTypeMunger.getDeclaredParameterCount(); - LazyMethodGen mg = - makeMethodGen(currentClass, newConstructorMember); - mg.setEffectiveSignature(newConstructorTypeMunger.getSignature(),Shadow.ConstructorExecution,true); - -// pr98901 - // For copying the annotations across, we have to discover the real member in the aspect - // which is holding them. - if (weaver.getWorld().isInJava5Mode()){ - - ResolvedMember interMethodDispatcher =AjcMemberMaker.postIntroducedConstructor(aspectType,onType,newConstructorTypeMunger.getSignature().getParameterTypes()); - AnnotationX annotationsOnRealMember[] = null; - ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType,interMethodDispatcher,true); - if (realMember==null) throw new BCException("Couldn't find ITD holder member '"+ - interMethodDispatcher+"' on aspect "+aspectType); + // int declaredParameterCount = + // newConstructorTypeMunger.getDeclaredParameterCount(); + LazyMethodGen mg = makeMethodGen(currentClass, newConstructorMember); + mg.setEffectiveSignature(newConstructorTypeMunger.getSignature(), Shadow.ConstructorExecution, true); + + // pr98901 + // For copying the annotations across, we have to discover the real + // member in the aspect + // which is holding them. + if (weaver.getWorld().isInJava5Mode()) { + + ResolvedMember interMethodDispatcher = AjcMemberMaker.postIntroducedConstructor(aspectType, onType, + newConstructorTypeMunger.getSignature().getParameterTypes()); + AnnotationAJ annotationsOnRealMember[] = null; + ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType, interMethodDispatcher, true); + if (realMember == null) + throw new BCException("Couldn't find ITD holder member '" + interMethodDispatcher + "' on aspect " + aspectType); annotationsOnRealMember = realMember.getAnnotations(); - if (annotationsOnRealMember!=null) { + if (annotationsOnRealMember != null) { for (int i = 0; i < annotationsOnRealMember.length; i++) { - AnnotationX annotationX = annotationsOnRealMember[i]; - AnnotationGen a = annotationX.getBcelAnnotation(); - AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); - mg.addAnnotation(new AnnotationX(ag,weaver.getWorld())); + AnnotationAJ annotationX = annotationsOnRealMember[i]; + AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation(); + AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true); + mg.addAnnotation(new BcelAnnotation(ag, weaver.getWorld())); } } // the below loop fixes the very special (and very stupid) // case where an aspect declares an annotation // on an ITD it declared on itself. List allDecams = weaver.getWorld().getDeclareAnnotationOnMethods(); - for (Iterator i = allDecams.iterator(); i.hasNext();){ - DeclareAnnotation decaMC = (DeclareAnnotation) i.next(); - if (decaMC.matches(explicitConstructor,weaver.getWorld()) - && mg.getEnclosingClass().getType() == aspectType) { + for (Iterator i = allDecams.iterator(); i.hasNext();) { + DeclareAnnotation decaMC = (DeclareAnnotation) i.next(); + if (decaMC.matches(explicitConstructor, weaver.getWorld()) && mg.getEnclosingClass().getType() == aspectType) { mg.addAnnotation(decaMC.getAnnotationX()); } } } - + currentClass.addMethodGen(mg); - //weaver.addLazyMethodGen(freshConstructor); - + // weaver.addLazyMethodGen(freshConstructor); + InstructionList body = mg.getBody(); - - // add to body: push arts for call to pre, from actual args starting at 1 (skipping this), going to - // declared argcount + 1 + + // add to body: push arts for call to pre, from actual args starting at + // 1 (skipping this), going to + // declared argcount + 1 UnresolvedType[] declaredParams = newConstructorTypeMunger.getSignature().getParameterTypes(); Type[] paramTypes = mg.getArgumentTypes(); int frameIndex = 1; @@ -1449,100 +1482,80 @@ public class BcelTypeMunger extends ConcreteTypeMunger { frameIndex += paramTypes[i].getSize(); } // do call to pre - Member preMethod = - AjcMemberMaker.preIntroducedConstructor(aspectType, onType, declaredParams); + Member preMethod = AjcMemberMaker.preIntroducedConstructor(aspectType, onType, declaredParams); body.append(Utility.createInvoke(fact, null, preMethod)); - + // create a local, and store return pre stuff into it. int arraySlot = mg.allocateLocal(1); body.append(InstructionFactory.createStore(Type.OBJECT, arraySlot)); - + // put this on the stack body.append(InstructionConstants.ALOAD_0); - + // unpack pre args onto stack UnresolvedType[] superParamTypes = explicitConstructor.getParameterTypes(); - + for (int i = 0, len = superParamTypes.length; i < len; i++) { body.append(InstructionFactory.createLoad(Type.OBJECT, arraySlot)); body.append(Utility.createConstant(fact, i)); body.append(InstructionFactory.createArrayLoad(Type.OBJECT)); - body.append( - Utility.createConversion( - fact, - Type.OBJECT, - BcelWorld.makeBcelType(superParamTypes[i]))); + body.append(Utility.createConversion(fact, Type.OBJECT, BcelWorld.makeBcelType(superParamTypes[i]))); } // call super/this - + body.append(Utility.createInvoke(fact, null, explicitConstructor)); - + // put this back on the stack body.append(InstructionConstants.ALOAD_0); - + // unpack params onto stack - Member postMethod = - AjcMemberMaker.postIntroducedConstructor(aspectType, onType, declaredParams); + Member postMethod = AjcMemberMaker.postIntroducedConstructor(aspectType, onType, declaredParams); UnresolvedType[] postParamTypes = postMethod.getParameterTypes(); - + for (int i = 1, len = postParamTypes.length; i < len; i++) { body.append(InstructionFactory.createLoad(Type.OBJECT, arraySlot)); - body.append(Utility.createConstant(fact, superParamTypes.length + i-1)); + body.append(Utility.createConstant(fact, superParamTypes.length + i - 1)); body.append(InstructionFactory.createArrayLoad(Type.OBJECT)); - body.append( - Utility.createConversion( - fact, - Type.OBJECT, - BcelWorld.makeBcelType(postParamTypes[i]))); - } - + body.append(Utility.createConversion(fact, Type.OBJECT, BcelWorld.makeBcelType(postParamTypes[i]))); + } + // call post body.append(Utility.createInvoke(fact, null, postMethod)); - + // don't forget to return!! body.append(InstructionConstants.RETURN); - - return true; - } + return true; + } - private static LazyMethodGen makeDispatcher( - LazyClassGen onGen, - String dispatchName, - ResolvedMember superMethod, - BcelWorld world, - boolean isSuper) - { + private static LazyMethodGen makeDispatcher(LazyClassGen onGen, String dispatchName, ResolvedMember superMethod, + BcelWorld world, boolean isSuper) { Type[] paramTypes = BcelWorld.makeBcelTypes(superMethod.getParameterTypes()); Type returnType = BcelWorld.makeBcelType(superMethod.getReturnType()); - + int modifiers = Modifier.PUBLIC; - if (onGen.isInterface()) modifiers |= Modifier.ABSTRACT; - - LazyMethodGen mg = - new LazyMethodGen( - modifiers, - returnType, - dispatchName, - paramTypes, - UnresolvedType.getNames(superMethod.getExceptions()), - onGen); + if (onGen.isInterface()) + modifiers |= Modifier.ABSTRACT; + + LazyMethodGen mg = new LazyMethodGen(modifiers, returnType, dispatchName, paramTypes, UnresolvedType.getNames(superMethod + .getExceptions()), onGen); InstructionList body = mg.getBody(); - - if (onGen.isInterface()) return mg; - + + if (onGen.isInterface()) + return mg; + // assert (!superMethod.isStatic()) InstructionFactory fact = onGen.getFactory(); int pos = 0; - + body.append(InstructionFactory.createThis()); pos++; for (int i = 0, len = paramTypes.length; i < len; i++) { Type paramType = paramTypes[i]; body.append(InstructionFactory.createLoad(paramType, pos)); - pos+=paramType.getSize(); + pos += paramType.getSize(); } if (isSuper) { body.append(Utility.createSuperInvoke(fact, world, superMethod)); @@ -1552,265 +1565,267 @@ public class BcelTypeMunger extends ConcreteTypeMunger { body.append(InstructionFactory.createReturn(returnType)); return mg; - } - + } + private boolean mungeNewField(BcelClassWeaver weaver, NewFieldTypeMunger munger) { - /*ResolvedMember initMethod = */munger.getInitMethod(aspectType); + /* ResolvedMember initMethod = */munger.getInitMethod(aspectType); LazyClassGen gen = weaver.getLazyClassGen(); ResolvedMember field = munger.getSignature(); - - ResolvedType onType = weaver.getWorld().resolve(field.getDeclaringType(),munger.getSourceLocation()); - if (onType.isRawType()) onType = onType.getGenericType(); + + ResolvedType onType = weaver.getWorld().resolve(field.getDeclaringType(), munger.getSourceLocation()); + if (onType.isRawType()) + onType = onType.getGenericType(); boolean onInterface = onType.isInterface(); - + if (onType.isAnnotation()) { - signalError(WeaverMessages.ITDF_ON_ANNOTATION_NOT_ALLOWED,weaver,onType); + signalError(WeaverMessages.ITDF_ON_ANNOTATION_NOT_ALLOWED, weaver, onType); return false; } - + if (onType.isEnum()) { - signalError(WeaverMessages.ITDF_ON_ENUM_NOT_ALLOWED,weaver,onType); + signalError(WeaverMessages.ITDF_ON_ENUM_NOT_ALLOWED, weaver, onType); return false; } - + ResolvedMember interMethodBody = munger.getInitMethod(aspectType); - - AnnotationX annotationsOnRealMember[] = null; + + AnnotationAJ annotationsOnRealMember[] = null; // pr98901 - // For copying the annotations across, we have to discover the real member in the aspect - // which is holding them. - if (weaver.getWorld().isInJava5Mode()){ - // the below line just gets the method with the same name in aspectType.getDeclaredMethods(); - ResolvedType toLookOn = aspectType; - if (aspectType.isRawType()) toLookOn = aspectType.getGenericType(); - ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn,interMethodBody,false); - if (realMember==null) throw new BCException("Couldn't find ITD init member '"+ - interMethodBody+"' on aspect "+aspectType); - annotationsOnRealMember = realMember.getAnnotations(); + // For copying the annotations across, we have to discover the real + // member in the aspect + // which is holding them. + if (weaver.getWorld().isInJava5Mode()) { + // the below line just gets the method with the same name in + // aspectType.getDeclaredMethods(); + ResolvedType toLookOn = aspectType; + if (aspectType.isRawType()) + toLookOn = aspectType.getGenericType(); + ResolvedMember realMember = getRealMemberForITDFromAspect(toLookOn, interMethodBody, false); + if (realMember == null) + throw new BCException("Couldn't find ITD init member '" + interMethodBody + "' on aspect " + aspectType); + annotationsOnRealMember = realMember.getAnnotations(); } - + if (onType.equals(gen.getType())) { if (onInterface) { ResolvedMember itdfieldGetter = AjcMemberMaker.interFieldInterfaceGetter(field, onType, aspectType); LazyMethodGen mg = makeMethodGen(gen, itdfieldGetter); gen.addMethodGen(mg); - - LazyMethodGen mg1 = makeMethodGen(gen, - AjcMemberMaker.interFieldInterfaceSetter(field, onType, aspectType)); + + LazyMethodGen mg1 = makeMethodGen(gen, AjcMemberMaker.interFieldInterfaceSetter(field, onType, aspectType)); gen.addMethodGen(mg1); } else { weaver.addInitializer(this); - FieldGen fg = makeFieldGen(gen, - AjcMemberMaker.interFieldClassField(field, aspectType)); - - if (annotationsOnRealMember!=null) { + FieldGen fg = makeFieldGen(gen, AjcMemberMaker.interFieldClassField(field, aspectType)); + + if (annotationsOnRealMember != null) { for (int i = 0; i < annotationsOnRealMember.length; i++) { - AnnotationX annotationX = annotationsOnRealMember[i]; - AnnotationGen a = annotationX.getBcelAnnotation(); - AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); + AnnotationAJ annotationX = annotationsOnRealMember[i]; + AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation(); + AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true); fg.addAnnotation(ag); } } - - - if (weaver.getWorld().isInJava5Mode()){ + if (weaver.getWorld().isInJava5Mode()) { String basicSignature = field.getSignature(); String genericSignature = field.getReturnType().resolve(weaver.getWorld()).getSignatureForAttribute(); - // String genericSignature = ((ResolvedMemberImpl)field).getSignatureForAttribute(); + // String genericSignature = + // ((ResolvedMemberImpl)field).getSignatureForAttribute(); if (!basicSignature.equals(genericSignature)) { - // Add a signature attribute to it - fg.addAttribute(createSignatureAttribute(gen.getConstantPool(),genericSignature)); + // Add a signature attribute to it + fg.addAttribute(createSignatureAttribute(gen.getConstantPool(), genericSignature)); } } - gen.addField(fg,getSourceLocation()); - + gen.addField(fg, getSourceLocation()); + } - return true; + return true; } else if (onInterface && gen.getType().isTopmostImplementor(onType)) { - // wew know that we can't be static since we don't allow statics on interfaces - if (field.isStatic()) throw new RuntimeException("unimplemented"); + // wew know that we can't be static since we don't allow statics on + // interfaces + if (field.isStatic()) + throw new RuntimeException("unimplemented"); weaver.addInitializer(this); - //System.err.println("impl body on " + gen.getType() + " for " + munger); - - - Type fieldType = BcelWorld.makeBcelType(field.getType()); - - FieldGen fg = makeFieldGen(gen,AjcMemberMaker.interFieldInterfaceField(field, onType, aspectType)); - - if (annotationsOnRealMember!=null) { - for (int i = 0; i < annotationsOnRealMember.length; i++) { - AnnotationX annotationX = annotationsOnRealMember[i]; - AnnotationGen a = annotationX.getBcelAnnotation(); - AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPool(),true); - fg.addAnnotation(ag); - } + // System.err.println("impl body on " + gen.getType() + " for " + + // munger); + + Type fieldType = BcelWorld.makeBcelType(field.getType()); + + FieldGen fg = makeFieldGen(gen, AjcMemberMaker.interFieldInterfaceField(field, onType, aspectType)); + + if (annotationsOnRealMember != null) { + for (int i = 0; i < annotationsOnRealMember.length; i++) { + AnnotationAJ annotationX = annotationsOnRealMember[i]; + AnnotationGen a = ((BcelAnnotation) annotationX).getBcelAnnotation(); + AnnotationGen ag = new AnnotationGen(a, weaver.getLazyClassGen().getConstantPool(), true); + fg.addAnnotation(ag); } - - gen.addField(fg,getSourceLocation()); - //this uses a shadow munger to add init method to constructors - //weaver.getShadowMungers().add(makeInitCallShadowMunger(initMethod)); - - ResolvedMember itdfieldGetter = AjcMemberMaker.interFieldInterfaceGetter(field, gen.getType()/*onType*/, aspectType); + } + + gen.addField(fg, getSourceLocation()); + // this uses a shadow munger to add init method to constructors + // weaver.getShadowMungers().add(makeInitCallShadowMunger(initMethod) + // ); + + ResolvedMember itdfieldGetter = AjcMemberMaker.interFieldInterfaceGetter(field, gen.getType()/* onType */, aspectType); LazyMethodGen mg = makeMethodGen(gen, itdfieldGetter); InstructionList il = new InstructionList(); InstructionFactory fact = gen.getFactory(); if (field.isStatic()) { - il.append(fact.createFieldAccess( - gen.getClassName(), - fg.getName(), - fieldType, Constants.GETSTATIC)); + il.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.GETSTATIC)); } else { il.append(InstructionConstants.ALOAD_0); - il.append(fact.createFieldAccess( - gen.getClassName(), - fg.getName(), - fieldType, Constants.GETFIELD)); + il.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.GETFIELD)); } il.append(InstructionFactory.createReturn(fieldType)); mg.getBody().insert(il); - + gen.addMethodGen(mg); - + // Check if we need bridge methods for the field getter and setter - if (munger.getDeclaredSignature()!=null) { // is this munger a parameterized form of some original munger? - ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,munger.getSignature().getDeclaringType().resolve(getWorld()),false,munger.getTypeVariableAliases()); + if (munger.getDeclaredSignature() != null) { // is this munger a + // parameterized + // form of some + // original munger? + ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null, + munger.getSignature().getDeclaringType().resolve(getWorld()), false, munger.getTypeVariableAliases()); boolean needsbridging = false; - if (!toBridgeTo.getReturnType().getErasureSignature().equals(munger.getSignature().getReturnType().getErasureSignature())) needsbridging = true; + if (!toBridgeTo.getReturnType().getErasureSignature().equals( + munger.getSignature().getReturnType().getErasureSignature())) + needsbridging = true; if (needsbridging) { - ResolvedMember bridgingGetter = AjcMemberMaker.interFieldInterfaceGetter(toBridgeTo, gen.getType(), aspectType); - createBridgeMethodForITDF(weaver,gen,itdfieldGetter,bridgingGetter); - } - } - + ResolvedMember bridgingGetter = AjcMemberMaker.interFieldInterfaceGetter(toBridgeTo, gen.getType(), aspectType); + createBridgeMethodForITDF(weaver, gen, itdfieldGetter, bridgingGetter); + } + } + ResolvedMember itdfieldSetter = AjcMemberMaker.interFieldInterfaceSetter(field, gen.getType(), aspectType); LazyMethodGen mg1 = makeMethodGen(gen, itdfieldSetter); InstructionList il1 = new InstructionList(); if (field.isStatic()) { il1.append(InstructionFactory.createLoad(fieldType, 0)); - il1.append(fact.createFieldAccess( - gen.getClassName(), - fg.getName(), - fieldType, Constants.PUTSTATIC)); + il1.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.PUTSTATIC)); } else { il1.append(InstructionConstants.ALOAD_0); il1.append(InstructionFactory.createLoad(fieldType, 1)); - il1.append(fact.createFieldAccess( - gen.getClassName(), - fg.getName(), - fieldType, Constants.PUTFIELD)); + il1.append(fact.createFieldAccess(gen.getClassName(), fg.getName(), fieldType, Constants.PUTFIELD)); } il1.append(InstructionFactory.createReturn(Type.VOID)); mg1.getBody().insert(il1); - + gen.addMethodGen(mg1); - - if (munger.getDeclaredSignature()!=null) { - ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null,munger.getSignature().getDeclaringType().resolve(getWorld()),false,munger.getTypeVariableAliases()); - boolean needsbridging = false; - if (!toBridgeTo.getReturnType().getErasureSignature().equals(munger.getSignature().getReturnType().getErasureSignature())) { - needsbridging = true; - } - if (needsbridging) { - ResolvedMember bridgingSetter = AjcMemberMaker.interFieldInterfaceSetter(toBridgeTo, gen.getType(), aspectType); - createBridgeMethodForITDF(weaver, gen, itdfieldSetter, bridgingSetter); - } - } - - return true; + + if (munger.getDeclaredSignature() != null) { + ResolvedMember toBridgeTo = munger.getDeclaredSignature().parameterizedWith(null, + munger.getSignature().getDeclaringType().resolve(getWorld()), false, munger.getTypeVariableAliases()); + boolean needsbridging = false; + if (!toBridgeTo.getReturnType().getErasureSignature().equals( + munger.getSignature().getReturnType().getErasureSignature())) { + needsbridging = true; + } + if (needsbridging) { + ResolvedMember bridgingSetter = AjcMemberMaker.interFieldInterfaceSetter(toBridgeTo, gen.getType(), aspectType); + createBridgeMethodForITDF(weaver, gen, itdfieldSetter, bridgingSetter); + } + } + + return true; } else { return false; } } - // FIXME asc combine with other createBridge.. method in this class, avoid the duplication... - private void createBridgeMethodForITDF(BcelClassWeaver weaver, LazyClassGen gen, ResolvedMember itdfieldSetter, ResolvedMember bridgingSetter) { + // FIXME asc combine with other createBridge.. method in this class, avoid + // the duplication... + private void createBridgeMethodForITDF(BcelClassWeaver weaver, LazyClassGen gen, ResolvedMember itdfieldSetter, + ResolvedMember bridgingSetter) { InstructionFactory fact; - LazyMethodGen bridgeMethod = makeMethodGen(gen,bridgingSetter); + LazyMethodGen bridgeMethod = makeMethodGen(gen, bridgingSetter); Type[] paramTypes = BcelWorld.makeBcelTypes(bridgingSetter.getParameterTypes()); - Type[] bridgingToParms = BcelWorld.makeBcelTypes(itdfieldSetter.getParameterTypes()); - Type returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType()); - InstructionList body = bridgeMethod.getBody(); - fact = gen.getFactory(); - int pos = 0; + Type[] bridgingToParms = BcelWorld.makeBcelTypes(itdfieldSetter.getParameterTypes()); + Type returnType = BcelWorld.makeBcelType(bridgingSetter.getReturnType()); + InstructionList body = bridgeMethod.getBody(); + fact = gen.getFactory(); + int pos = 0; - if (!bridgingSetter.isStatic()) { + if (!bridgingSetter.isStatic()) { body.append(InstructionFactory.createThis()); pos++; - } - for (int i = 0, len = paramTypes.length; i < len; i++) { + } + for (int i = 0, len = paramTypes.length; i < len; i++) { Type paramType = paramTypes[i]; body.append(InstructionFactory.createLoad(paramType, pos)); - if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals(itdfieldSetter.getParameterTypes()[i].getErasureSignature()) ) { + if (!bridgingSetter.getParameterTypes()[i].getErasureSignature().equals( + itdfieldSetter.getParameterTypes()[i].getErasureSignature())) { // une cast est required - System.err.println("Putting in cast from "+paramType+" to "+bridgingToParms[i]); - body.append(fact.createCast(paramType,bridgingToParms[i])); + System.err.println("Putting in cast from " + paramType + " to " + bridgingToParms[i]); + body.append(fact.createCast(paramType, bridgingToParms[i])); } - pos+=paramType.getSize(); - } - - body.append(Utility.createInvoke(fact, weaver.getWorld(), itdfieldSetter)); - body.append(InstructionFactory.createReturn(returnType)); - gen.addMethodGen(bridgeMethod); + pos += paramType.getSize(); + } + + body.append(Utility.createInvoke(fact, weaver.getWorld(), itdfieldSetter)); + body.append(InstructionFactory.createReturn(returnType)); + gen.addMethodGen(bridgeMethod); } - + public ConcreteTypeMunger parameterizedFor(ResolvedType target) { - return new BcelTypeMunger(munger.parameterizedFor(target),aspectType); + return new BcelTypeMunger(munger.parameterizedFor(target), aspectType); } - + public ConcreteTypeMunger parameterizeWith(Map m, World w) { - return new BcelTypeMunger(munger.parameterizeWith(m,w),aspectType); + return new BcelTypeMunger(munger.parameterizeWith(m, w), aspectType); } - + /** - * Returns a list of type variable aliases used in this munger. For example, if the - * ITD is 'int I.m(List
las,List lbs) {}' then this returns a list containing - * the strings "A" and "B". + * Returns a list of type variable aliases used in this munger. For example, if the ITD is 'int I.m(List las,List + * lbs) {}' then this returns a list containing the strings "A" and "B". */ - public List /*String*/ getTypeVariableAliases() { + public List /* String */getTypeVariableAliases() { return munger.getTypeVariableAliases(); } - + public boolean equals(Object other) { - if (! (other instanceof BcelTypeMunger)) return false; - BcelTypeMunger o = (BcelTypeMunger) other; - return ((o.getMunger() == null) ? (getMunger() == null) : o.getMunger().equals(getMunger())) - && ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType())) - && (AsmManager.getDefault().getHandleProvider().dependsOnLocation() - ?((o.getSourceLocation()==null)? (getSourceLocation()==null): o.getSourceLocation().equals(getSourceLocation())):true); // pr134471 - remove when handles are improved to be independent of location - - } - - private volatile int hashCode = 0; - public int hashCode() { - if (hashCode == 0) { - int result = 17; - result = 37*result + ((getMunger() == null) ? 0 : getMunger().hashCode()); - result = 37*result + ((getAspectType() == null) ? 0 : getAspectType().hashCode()); - hashCode = result; - } - return hashCode; - } - - + if (!(other instanceof BcelTypeMunger)) + return false; + BcelTypeMunger o = (BcelTypeMunger) other; + return ((o.getMunger() == null) ? (getMunger() == null) : o.getMunger().equals(getMunger())) + && ((o.getAspectType() == null) ? (getAspectType() == null) : o.getAspectType().equals(getAspectType())) + && (AsmManager.getDefault().getHandleProvider().dependsOnLocation() ? ((o.getSourceLocation() == null) ? (getSourceLocation() == null) + : o.getSourceLocation().equals(getSourceLocation())) + : true); // pr134471 - remove when handles are improved + // to be independent of location + + } + + private volatile int hashCode = 0; + + public int hashCode() { + if (hashCode == 0) { + int result = 17; + result = 37 * result + ((getMunger() == null) ? 0 : getMunger().hashCode()); + result = 37 * result + ((getAspectType() == null) ? 0 : getAspectType().hashCode()); + hashCode = result; + } + return hashCode; + } + /** - * Some type mungers are created purely to help with the implementation of shadow mungers. - * For example to support the cflow() pointcut we create a new cflow field in the aspect, and - * that is added via a BcelCflowCounterFieldAdder. + * Some type mungers are created purely to help with the implementation of shadow mungers. For example to support the cflow() + * pointcut we create a new cflow field in the aspect, and that is added via a BcelCflowCounterFieldAdder. * - * During compilation we need to compare sets of type mungers, and if some only come into - * existence after the 'shadowy' type things have been processed, we need to ignore - * them during the comparison. + * During compilation we need to compare sets of type mungers, and if some only come into existence after the 'shadowy' type + * things have been processed, we need to ignore them during the comparison. * - * Returning true from this method indicates the type munger exists to support 'shadowy' stuff - - * and so can be ignored in some comparison. + * Returning true from this method indicates the type munger exists to support 'shadowy' stuff - and so can be ignored in some + * comparison. */ public boolean existsToSupportShadowMunging() { if (munger != null) { return munger.existsToSupportShadowMunging(); } - return false; + return false; } } - \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index 1430f0929..e70694256 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -55,8 +55,8 @@ import org.aspectj.bridge.context.ContextToken; import org.aspectj.util.FileUtil; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.Advice; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AnnotationOnTypeMunger; -import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.AsmRelationshipProvider; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ConcreteTypeMunger; @@ -104,7 +104,8 @@ public class BcelWeaver { private boolean inReweavableMode = false; - private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWeaver.class); + private static Trace trace = TraceFactory.getTraceFactory().getTrace( + BcelWeaver.class); public BcelWeaver(BcelWorld world) { super(); @@ -117,7 +118,8 @@ public class BcelWeaver { } // ---- fields - // private Map sourceJavaClasses = new HashMap(); /* String -> UnwovenClassFile */ + // private Map sourceJavaClasses = new HashMap(); /* String -> + // UnwovenClassFile */ private List addedClasses = new ArrayList(); /* List */ private List deletedTypenames = new ArrayList(); /* List */ // private Map resources = new HashMap(); /* String -> UnwovenClassFile */ @@ -141,7 +143,8 @@ public class BcelWeaver { } /** - * Add the given aspect to the weaver. The type is resolved to support DOT for static inner classes as well as DOLLAR + * Add the given aspect to the weaver. The type is resolved to support DOT + * for static inner classes as well as DOLLAR * * @param aspectName * @return aspect @@ -159,7 +162,8 @@ public class BcelWeaver { String fixedName = aspectName; int hasDot = fixedName.lastIndexOf('.'); while (hasDot > 0) { - // System.out.println("BcelWeaver.addLibraryAspect " + fixedName); + // System.out.println("BcelWeaver.addLibraryAspect " + + // fixedName); char[] fixedNameChars = fixedName.toCharArray(); fixedNameChars[hasDot] = '$'; fixedName = new String(fixedNameChars); @@ -181,31 +185,43 @@ public class BcelWeaver { if (wsi != null && wsi.isReweavable()) { BcelObjectType classType = getClassType(type.getName()); JavaClass wovenJavaClass = classType.getJavaClass(); - JavaClass unwovenJavaClass = Utility.makeJavaClass(wovenJavaClass.getFileName(), wsi - .getUnwovenClassFileData(wovenJavaClass.getBytes())); + JavaClass unwovenJavaClass = Utility.makeJavaClass( + wovenJavaClass.getFileName(), wsi + .getUnwovenClassFileData(wovenJavaClass + .getBytes())); world.storeClass(unwovenJavaClass); classType.setJavaClass(unwovenJavaClass); - // classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), - // wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes()))); + // classType.setJavaClass(Utility.makeJavaClass(classType. + // getJavaClass().getFileName(), + //wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes( + // )))); } - // TODO AV - happens to reach that a lot of time: for each type flagged reweavable X for each aspect in the weaverstate - // => mainly for nothing for LTW - pbly for something in incremental build... + // TODO AV - happens to reach that a lot of time: for each type + // flagged reweavable X for each aspect in the weaverstate + // => mainly for nothing for LTW - pbly for something in incremental + // build... xcutSet.addOrReplaceAspect(type); if (trace.isTraceEnabled()) trace.exit("addLibraryAspect", type); if (type.getSuperclass().isAspect()) { - // If the supertype includes ITDs and the user has not included that aspect in the aop.xml, they will - // not get picked up, which can give unusual behaviour! See bug 223094 - // This change causes us to pick up the super aspect regardless of what was said in the aop.xml - giving - // predictable behaviour. If the user also supplied it, there will be no problem other than the second + // If the supertype includes ITDs and the user has not included + // that aspect in the aop.xml, they will + // not get picked up, which can give unusual behaviour! See bug + // 223094 + // This change causes us to pick up the super aspect regardless + // of what was said in the aop.xml - giving + // predictable behaviour. If the user also supplied it, there + // will be no problem other than the second // addition overriding the first addLibraryAspect(type.getSuperclass().getName()); } return type; } else { // FIXME AV - better warning upon no such aspect from aop.xml - RuntimeException ex = new RuntimeException("Cannot register non aspect: " + type.getName() + " , " + aspectName); + RuntimeException ex = new RuntimeException( + "Cannot register non aspect: " + type.getName() + " , " + + aspectName); if (trace.isTraceEnabled()) trace.exit("addLibraryAspect", ex); throw ex; @@ -214,7 +230,8 @@ public class BcelWeaver { /** * - * @param inFile File path to class directory or zip/jar class archive + * @param inFile + * File path to class directory or zip/jar class archive * @throws IOException */ public void addLibraryJarFile(File inFile) throws IOException { @@ -231,8 +248,10 @@ public class BcelWeaver { } } - private List addAspectsFromJarFile(File inFile) throws FileNotFoundException, IOException { - ZipInputStream inStream = new ZipInputStream(new FileInputStream(inFile)); // ??? buffered + private List addAspectsFromJarFile(File inFile) + throws FileNotFoundException, IOException { + ZipInputStream inStream = new ZipInputStream( + new FileInputStream(inFile)); // ??? buffered List addedAspects = new ArrayList(); while (true) { ZipEntry entry = inStream.getNextEntry(); @@ -244,11 +263,13 @@ public class BcelWeaver { } // FIXME ASC performance? of this alternative soln. - ClassParser parser = new ClassParser(new ByteArrayInputStream(FileUtil.readAsByteArray(inStream)), entry.getName()); + ClassParser parser = new ClassParser(new ByteArrayInputStream( + FileUtil.readAsByteArray(inStream)), entry.getName()); JavaClass jc = parser.parse(); inStream.closeEntry(); - ResolvedType type = world.addSourceObjectType(jc).getResolvedTypeX(); + ResolvedType type = world.addSourceObjectType(jc) + .getResolvedTypeX(); type.setBinaryPath(inFile.getAbsolutePath()); if (type.isAspect()) { addedAspects.add(type); @@ -260,7 +281,8 @@ public class BcelWeaver { return addedAspects; } - private List addAspectsFromDirectory(File dir) throws FileNotFoundException, IOException { + private List addAspectsFromDirectory(File dir) + throws FileNotFoundException, IOException { List addedAspects = new ArrayList(); File[] classFiles = FileUtil.listFiles(dir, new FileFilter() { @@ -272,20 +294,24 @@ public class BcelWeaver { for (int i = 0; i < classFiles.length; i++) { FileInputStream fis = new FileInputStream(classFiles[i]); byte[] bytes = FileUtil.readAsByteArray(fis); - addIfAspect(bytes, classFiles[i].getAbsolutePath(), addedAspects, dir); + addIfAspect(bytes, classFiles[i].getAbsolutePath(), addedAspects, + dir); fis.close(); } return addedAspects; } - private void addIfAspect(byte[] bytes, String name, List toList, File dir) throws IOException { - ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), name); + private void addIfAspect(byte[] bytes, String name, List toList, File dir) + throws IOException { + ClassParser parser = new ClassParser(new ByteArrayInputStream(bytes), + name); JavaClass jc = parser.parse(); ResolvedType type = world.addSourceObjectType(jc).getResolvedTypeX(); String typeName = type.getName().replace('.', File.separatorChar); int end = name.lastIndexOf(typeName + ".class"); String binaryPath = null; - // if end is -1 then something wierd happened, the class file is not in the correct place, something like + // if end is -1 then something wierd happened, the class file is not in + // the correct place, something like // bin/A.class when the declaration for A specifies it is in a package. if (end == -1) { binaryPath = dir.getAbsolutePath(); @@ -299,14 +325,17 @@ public class BcelWeaver { } // // The ANT copy task should be used to copy resources across. - // private final static boolean CopyResourcesFromInpathDirectoriesToOutput=false; + // private final static boolean + // CopyResourcesFromInpathDirectoriesToOutput=false; /** - * Add any .class files in the directory to the outdir. Anything other than .class files in the directory (or its - * subdirectories) are considered resources and are also copied. + * Add any .class files in the directory to the outdir. Anything other than + * .class files in the directory (or its subdirectories) are considered + * resources and are also copied. * */ - public List addDirectoryContents(File inFile, File outDir) throws IOException { + public List addDirectoryContents(File inFile, File outDir) + throws IOException { List addedClassFiles = new ArrayList(); // Get a list of all files (i.e. everything that isnt a directory) @@ -350,8 +379,10 @@ public class BcelWeaver { byte[] bytes = FileUtil.readAsByteArray(inStream); String filename = entry.getName(); - // System.out.println("? addJarFile() filename='" + filename + "'"); - UnwovenClassFile classFile = new UnwovenClassFile(new File(outDir, filename).getAbsolutePath(), bytes); + // System.out.println("? addJarFile() filename='" + filename + // + "'"); + UnwovenClassFile classFile = new UnwovenClassFile(new File( + outDir, filename).getAbsolutePath(), bytes); if (filename.endsWith(".class")) { this.addClassFile(classFile); @@ -368,11 +399,13 @@ public class BcelWeaver { inJar.close(); } } catch (FileNotFoundException ex) { - IMessage message = new Message("Could not find input jar file " + inFile.getPath() + ", ignoring", new SourceLocation( + IMessage message = new Message("Could not find input jar file " + + inFile.getPath() + ", ignoring", new SourceLocation( inFile, 0), false); world.getMessageHandler().handleMessage(message); } catch (IOException ex) { - IMessage message = new Message("Could not read input jar file " + inFile.getPath() + "(" + ex.getMessage() + ")", + IMessage message = new Message("Could not read input jar file " + + inFile.getPath() + "(" + ex.getMessage() + ")", new SourceLocation(inFile, 0), true); world.getMessageHandler().handleMessage(message); } finally { @@ -380,8 +413,10 @@ public class BcelWeaver { try { inJar.close(); } catch (IOException ex) { - IMessage message = new Message("Could not close input jar file " + inFile.getPath() + "(" + ex.getMessage() - + ")", new SourceLocation(inFile, 0), true); + IMessage message = new Message( + "Could not close input jar file " + + inFile.getPath() + "(" + ex.getMessage() + + ")", new SourceLocation(inFile, 0), true); world.getMessageHandler().handleMessage(message); } } @@ -390,17 +425,21 @@ public class BcelWeaver { return addedClassFiles; } - // public void addResource(String name, File inPath, File outDir) throws IOException { + // public void addResource(String name, File inPath, File outDir) throws + // IOException { // // /* Eliminate CVS files. Relative paths use "/" */ - // if (!name.startsWith("CVS/") && (-1 == name.indexOf("/CVS/")) && !name.endsWith("/CVS")) { + // if (!name.startsWith("CVS/") && (-1 == name.indexOf("/CVS/")) && + // !name.endsWith("/CVS")) { // // System.err.println("? addResource('" + name + "')"); - // // BufferedInputStream inStream = new BufferedInputStream(new FileInputStream(inPath)); + // // BufferedInputStream inStream = new BufferedInputStream(new + // FileInputStream(inPath)); // // byte[] bytes = new byte[(int)inPath.length()]; // // inStream.read(bytes); // // inStream.close(); // byte[] bytes = FileUtil.readAsByteArray(inPath); - // UnwovenClassFile resourceFile = new UnwovenClassFile(new File(outDir, name).getAbsolutePath(), bytes); + // UnwovenClassFile resourceFile = new UnwovenClassFile(new File(outDir, + // name).getAbsolutePath(), bytes); // addResource(name,resourceFile); // } // } @@ -414,23 +453,29 @@ public class BcelWeaver { */ public void addClassFile(UnwovenClassFile classFile) { addedClasses.add(classFile); - // if (null != sourceJavaClasses.put(classFile.getClassName(), classFile)) { + // if (null != sourceJavaClasses.put(classFile.getClassName(), + // classFile)) { // // throw new RuntimeException(classFile.getClassName()); // } world.addSourceObjectType(classFile.getJavaClass()); } - public UnwovenClassFile addClassFile(File classFile, File inPathDir, File outDir) throws IOException { + public UnwovenClassFile addClassFile(File classFile, File inPathDir, + File outDir) throws IOException { FileInputStream fis = new FileInputStream(classFile); byte[] bytes = FileUtil.readAsByteArray(fis); // String relativePath = files[i].getPath(); - // ASSERT: files[i].getAbsolutePath().startsWith(inFile.getAbsolutePath() + // ASSERT: + // files[i].getAbsolutePath().startsWith(inFile.getAbsolutePath() // or we are in trouble... - String filename = classFile.getAbsolutePath().substring(inPathDir.getAbsolutePath().length() + 1); - UnwovenClassFile ucf = new UnwovenClassFile(new File(outDir, filename).getAbsolutePath(), bytes); + String filename = classFile.getAbsolutePath().substring( + inPathDir.getAbsolutePath().length() + 1); + UnwovenClassFile ucf = new UnwovenClassFile(new File(outDir, filename) + .getAbsolutePath(), bytes); if (filename.endsWith(".class")) { - // System.err.println("BCELWeaver: processing class from input directory "+classFile); + // System.err.println( + // "BCELWeaver: processing class from input directory "+classFile); this.addClassFile(ucf); } fis.close(); @@ -470,7 +515,8 @@ public class BcelWeaver { UnwovenClassFile jc = (UnwovenClassFile) i.next(); String name = jc.getClassName(); ResolvedType type = world.resolve(name); - // System.err.println("added: " + type + " aspect? " + type.isAspect()); + // System.err.println("added: " + type + " aspect? " + + // type.isAspect()); if (type.isAspect()) { needToReweaveWorld |= xcutSet.addOrReplaceAspect(type); } @@ -485,8 +531,10 @@ public class BcelWeaver { shadowMungerList = xcutSet.getShadowMungers(); // world.debug("shadow mungers=" + shadowMungerList); rewritePointcuts(shadowMungerList); - // Sometimes an error occurs during rewriting pointcuts (for example, if ambiguous bindings - // are detected) - we ought to fail the prepare when this happens because continuing with + // Sometimes an error occurs during rewriting pointcuts (for example, if + // ambiguous bindings + // are detected) - we ought to fail the prepare when this happens + // because continuing with // inconsistent pointcuts could lead to problems typeMungerList = xcutSet.getTypeMungers(); lateTypeMungerList = xcutSet.getLateTypeMungers(); @@ -494,13 +542,19 @@ public class BcelWeaver { addCustomMungers(); - // The ordering here used to be based on a string compare on toString() for the two mungers - - // that breaks for the @AJ style where advice names aren't programmatically generated. So we - // have changed the sorting to be based on source location in the file - this is reliable, in - // the case of source locations missing, we assume they are 'sorted' - i.e. the order in - // which they were added to the collection is correct, this enables the @AJ stuff to work properly. - - // When @AJ processing starts filling in source locations for mungers, this code may need + // The ordering here used to be based on a string compare on toString() + // for the two mungers - + // that breaks for the @AJ style where advice names aren't + // programmatically generated. So we + // have changed the sorting to be based on source location in the file - + // this is reliable, in + // the case of source locations missing, we assume they are 'sorted' - + // i.e. the order in + // which they were added to the collection is correct, this enables the + // @AJ stuff to work properly. + + // When @AJ processing starts filling in source locations for mungers, + // this code may need // a bit of alteration... Collections.sort(shadowMungerList, new Comparator() { @@ -512,12 +566,14 @@ public class BcelWeaver { if (sm2.getSourceLocation() == null) return -1; - return (sm2.getSourceLocation().getOffset() - sm1.getSourceLocation().getOffset()); + return (sm2.getSourceLocation().getOffset() - sm1 + .getSourceLocation().getOffset()); } }); if (inReweavableMode) - world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.REWEAVABLE_MODE), null, null); + world.showMessage(IMessage.INFO, WeaverMessages + .format(WeaverMessages.REWEAVABLE_MODE), null, null); if (trace.isTraceEnabled()) trace.exit("prepareForWeave"); @@ -530,11 +586,13 @@ public class BcelWeaver { String name = jc.getClassName(); ResolvedType type = world.resolve(name); if (type.isAspect()) { - Collection/* ShadowMunger */shadowMungers = customMungerFactory.createCustomShadowMungers(type); + Collection/* ShadowMunger */shadowMungers = customMungerFactory + .createCustomShadowMungers(type); if (shadowMungers != null) { shadowMungerList.addAll(shadowMungers); } - Collection/* ConcreteTypeMunger */typeMungers = customMungerFactory.createCustomTypeMungers(type); + Collection/* ConcreteTypeMunger */typeMungers = customMungerFactory + .createCustomTypeMungers(type); if (typeMungers != null) typeMungerList.addAll(typeMungers); } @@ -547,10 +605,13 @@ public class BcelWeaver { } /* - * Rewrite all of the pointcuts in the world into their most efficient form for subsequent matching. Also ensure that if - * pc1.equals(pc2) then pc1 == pc2 (for non-binding pcds) by making references all point to the same instance. Since pointcuts - * remember their match decision on the last shadow, this makes matching faster when many pointcuts share common elements, or - * even when one single pointcut has one common element (which can be a side-effect of DNF rewriting). + * Rewrite all of the pointcuts in the world into their most efficient form + * for subsequent matching. Also ensure that if pc1.equals(pc2) then pc1 == + * pc2 (for non-binding pcds) by making references all point to the same + * instance. Since pointcuts remember their match decision on the last + * shadow, this makes matching faster when many pointcuts share common + * elements, or even when one single pointcut has one common element (which + * can be a side-effect of DNF rewriting). */ private void rewritePointcuts(List/* ShadowMunger */shadowMungers) { PointcutRewriter rewriter = new PointcutRewriter(); @@ -566,15 +627,20 @@ public class BcelWeaver { if (advice.getSignature() != null) { final int numFormals; final String names[]; - // If the advice is being concretized in a @AJ aspect *and* the advice was declared in - // an @AJ aspect (it could have been inherited from a code style aspect) then + // If the advice is being concretized in a @AJ aspect *and* + // the advice was declared in + // an @AJ aspect (it could have been inherited from a code + // style aspect) then // evaluate the alternative set of formals. pr125699 - if (advice.getConcreteAspect().isAnnotationStyleAspect() && advice.getDeclaringAspect() != null - && advice.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) { + if (advice.getConcreteAspect().isAnnotationStyleAspect() + && advice.getDeclaringAspect() != null + && advice.getDeclaringAspect().resolve(world) + .isAnnotationStyleAspect()) { numFormals = advice.getBaseParameterCount(); int numArgs = advice.getSignature().getParameterTypes().length; if (numFormals > 0) { - names = advice.getSignature().getParameterNames(world); + names = advice.getSignature().getParameterNames( + world); validateBindings(newP, p, numArgs, names); } } else { @@ -636,10 +702,13 @@ public class BcelWeaver { // userPointcut is the pointcut that the user wrote in the program text. // dnfPointcut is the same pointcut rewritten in DNF // numFormals is the number of formal parameters in the pointcut - // if numFormals > 0 then every branch of a disjunction must bind each formal once and only once. - // in addition, the left and right branches of a disjunction must hold on join point kinds in + // if numFormals > 0 then every branch of a disjunction must bind each + // formal once and only once. + // in addition, the left and right branches of a disjunction must hold on + // join point kinds in // common. - private void validateBindings(Pointcut dnfPointcut, Pointcut userPointcut, int numFormals, String[] names) { + private void validateBindings(Pointcut dnfPointcut, Pointcut userPointcut, + int numFormals, String[] names) { if (numFormals == 0) return; // nothing to check if (dnfPointcut.couldMatchKinds() == Shadow.NO_SHADOW_KINDS_BITS) @@ -648,34 +717,43 @@ public class BcelWeaver { OrPointcut orBasedDNFPointcut = (OrPointcut) dnfPointcut; Pointcut[] leftBindings = new Pointcut[numFormals]; Pointcut[] rightBindings = new Pointcut[numFormals]; - validateOrBranch(orBasedDNFPointcut, userPointcut, numFormals, names, leftBindings, rightBindings); + validateOrBranch(orBasedDNFPointcut, userPointcut, numFormals, + names, leftBindings, rightBindings); } else { Pointcut[] bindings = new Pointcut[numFormals]; - validateSingleBranch(dnfPointcut, userPointcut, numFormals, names, bindings); + validateSingleBranch(dnfPointcut, userPointcut, numFormals, names, + bindings); } } - private void validateOrBranch(OrPointcut pc, Pointcut userPointcut, int numFormals, String[] names, Pointcut[] leftBindings, + private void validateOrBranch(OrPointcut pc, Pointcut userPointcut, + int numFormals, String[] names, Pointcut[] leftBindings, Pointcut[] rightBindings) { Pointcut left = pc.getLeft(); Pointcut right = pc.getRight(); if (left instanceof OrPointcut) { Pointcut[] newRightBindings = new Pointcut[numFormals]; - validateOrBranch((OrPointcut) left, userPointcut, numFormals, names, leftBindings, newRightBindings); + validateOrBranch((OrPointcut) left, userPointcut, numFormals, + names, leftBindings, newRightBindings); } else { if (left.couldMatchKinds() != Shadow.NO_SHADOW_KINDS_BITS) - validateSingleBranch(left, userPointcut, numFormals, names, leftBindings); + validateSingleBranch(left, userPointcut, numFormals, names, + leftBindings); } if (right instanceof OrPointcut) { Pointcut[] newLeftBindings = new Pointcut[numFormals]; - validateOrBranch((OrPointcut) right, userPointcut, numFormals, names, newLeftBindings, rightBindings); + validateOrBranch((OrPointcut) right, userPointcut, numFormals, + names, newLeftBindings, rightBindings); } else { if (right.couldMatchKinds() != Shadow.NO_SHADOW_KINDS_BITS) - validateSingleBranch(right, userPointcut, numFormals, names, rightBindings); + validateSingleBranch(right, userPointcut, numFormals, names, + rightBindings); } int kindsInCommon = left.couldMatchKinds() & right.couldMatchKinds(); - if (kindsInCommon != Shadow.NO_SHADOW_KINDS_BITS && couldEverMatchSameJoinPoints(left, right)) { - // we know that every branch binds every formal, so there is no ambiguity + if (kindsInCommon != Shadow.NO_SHADOW_KINDS_BITS + && couldEverMatchSameJoinPoints(left, right)) { + // we know that every branch binds every formal, so there is no + // ambiguity // if each branch binds it in exactly the same way... List ambiguousNames = new ArrayList(); for (int i = 0; i < numFormals; i++) { @@ -695,18 +773,23 @@ public class BcelWeaver { // pc is a pointcut that does not contain any disjunctions // check that every formal is bound (negation doesn't count). // we know that numFormals > 0 or else we would not be called - private void validateSingleBranch(Pointcut pc, Pointcut userPointcut, int numFormals, String[] names, Pointcut[] bindings) { + private void validateSingleBranch(Pointcut pc, Pointcut userPointcut, + int numFormals, String[] names, Pointcut[] bindings) { boolean[] foundFormals = new boolean[numFormals]; for (int i = 0; i < foundFormals.length; i++) { foundFormals[i] = false; } - validateSingleBranchRecursion(pc, userPointcut, foundFormals, names, bindings); + validateSingleBranchRecursion(pc, userPointcut, foundFormals, names, + bindings); for (int i = 0; i < foundFormals.length; i++) { if (!foundFormals[i]) { boolean ignore = false; - // ATAJ soften the unbound error for implicit bindings like JoinPoint in @AJ style + // ATAJ soften the unbound error for implicit bindings like + // JoinPoint in @AJ style for (int j = 0; j < userPointcut.m_ignoreUnboundBindingForNames.length; j++) { - if (names[i] != null && names[i].equals(userPointcut.m_ignoreUnboundBindingForNames[j])) { + if (names[i] != null + && names[i] + .equals(userPointcut.m_ignoreUnboundBindingForNames[j])) { ignore = true; break; } @@ -719,22 +802,28 @@ public class BcelWeaver { } // each formal must appear exactly once - private void validateSingleBranchRecursion(Pointcut pc, Pointcut userPointcut, boolean[] foundFormals, String[] names, + private void validateSingleBranchRecursion(Pointcut pc, + Pointcut userPointcut, boolean[] foundFormals, String[] names, Pointcut[] bindings) { if (pc instanceof NotPointcut) { // nots can only appear at leaves in DNF NotPointcut not = (NotPointcut) pc; if (not.getNegatedPointcut() instanceof NameBindingPointcut) { - NameBindingPointcut nnbp = (NameBindingPointcut) not.getNegatedPointcut(); - if (!nnbp.getBindingAnnotationTypePatterns().isEmpty() && !nnbp.getBindingTypePatterns().isEmpty()) + NameBindingPointcut nnbp = (NameBindingPointcut) not + .getNegatedPointcut(); + if (!nnbp.getBindingAnnotationTypePatterns().isEmpty() + && !nnbp.getBindingTypePatterns().isEmpty()) raiseNegationBindingError(userPointcut); } } else if (pc instanceof AndPointcut) { AndPointcut and = (AndPointcut) pc; - validateSingleBranchRecursion(and.getLeft(), userPointcut, foundFormals, names, bindings); - validateSingleBranchRecursion(and.getRight(), userPointcut, foundFormals, names, bindings); + validateSingleBranchRecursion(and.getLeft(), userPointcut, + foundFormals, names, bindings); + validateSingleBranchRecursion(and.getRight(), userPointcut, + foundFormals, names, bindings); } else if (pc instanceof NameBindingPointcut) { - List/* BindingTypePattern */btps = ((NameBindingPointcut) pc).getBindingTypePatterns(); + List/* BindingTypePattern */btps = ((NameBindingPointcut) pc) + .getBindingTypePatterns(); for (Iterator iter = btps.iterator(); iter.hasNext();) { BindingTypePattern btp = (BindingTypePattern) iter.next(); int index = btp.getFormalIndex(); @@ -745,7 +834,8 @@ public class BcelWeaver { foundFormals[index] = true; } } - List/* BindingPattern */baps = ((NameBindingPointcut) pc).getBindingAnnotationTypePatterns(); + List/* BindingPattern */baps = ((NameBindingPointcut) pc) + .getBindingAnnotationTypePatterns(); for (Iterator iter = baps.iterator(); iter.hasNext();) { BindingPattern bap = (BindingPattern) iter.next(); int index = bap.getFormalIndex(); @@ -796,15 +886,19 @@ public class BcelWeaver { } // look for withins - WithinPointcut leftWithin = (WithinPointcut) findFirstPointcutIn(left, WithinPointcut.class); - WithinPointcut rightWithin = (WithinPointcut) findFirstPointcutIn(right, WithinPointcut.class); + WithinPointcut leftWithin = (WithinPointcut) findFirstPointcutIn(left, + WithinPointcut.class); + WithinPointcut rightWithin = (WithinPointcut) findFirstPointcutIn( + right, WithinPointcut.class); if ((leftWithin != null) && (rightWithin != null)) { if (!leftWithin.couldEverMatchSameJoinPointsAs(rightWithin)) return false; } // look for kinded - KindedPointcut leftKind = (KindedPointcut) findFirstPointcutIn(left, KindedPointcut.class); - KindedPointcut rightKind = (KindedPointcut) findFirstPointcutIn(right, KindedPointcut.class); + KindedPointcut leftKind = (KindedPointcut) findFirstPointcutIn(left, + KindedPointcut.class); + KindedPointcut rightKind = (KindedPointcut) findFirstPointcutIn(right, + KindedPointcut.class); if ((leftKind != null) && (rightKind != null)) { if (!leftKind.couldEverMatchSameJoinPointsAs(rightKind)) return false; @@ -831,8 +925,10 @@ public class BcelWeaver { * @param userPointcut */ private void raiseNegationBindingError(Pointcut userPointcut) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.NEGATION_DOESNT_ALLOW_BINDING), userPointcut - .getSourceContext().makeSourceLocation(userPointcut), null); + world.showMessage(IMessage.ERROR, WeaverMessages + .format(WeaverMessages.NEGATION_DOESNT_ALLOW_BINDING), + userPointcut.getSourceContext() + .makeSourceLocation(userPointcut), null); } /** @@ -840,21 +936,25 @@ public class BcelWeaver { * @param userPointcut */ private void raiseAmbiguousBindingError(String name, Pointcut userPointcut) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.AMBIGUOUS_BINDING, name), userPointcut + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.AMBIGUOUS_BINDING, name), userPointcut .getSourceContext().makeSourceLocation(userPointcut), null); } /** * @param userPointcut */ - private void raiseAmbiguityInDisjunctionError(Pointcut userPointcut, List names) { + private void raiseAmbiguityInDisjunctionError(Pointcut userPointcut, + List names) { StringBuffer formalNames = new StringBuffer(names.get(0).toString()); for (int i = 1; i < names.size(); i++) { formalNames.append(", "); formalNames.append(names.get(i)); } - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.AMBIGUOUS_BINDING_IN_OR, formalNames), userPointcut - .getSourceContext().makeSourceLocation(userPointcut), null); + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.AMBIGUOUS_BINDING_IN_OR, formalNames), + userPointcut.getSourceContext() + .makeSourceLocation(userPointcut), null); } /** @@ -862,7 +962,8 @@ public class BcelWeaver { * @param userPointcut */ private void raiseUnboundFormalError(String name, Pointcut userPointcut) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.UNBOUND_FORMAL, name), userPointcut + world.showMessage(IMessage.ERROR, WeaverMessages.format( + WeaverMessages.UNBOUND_FORMAL, name), userPointcut .getSourceLocation(), null); } @@ -885,7 +986,8 @@ public class BcelWeaver { // } // public void dumpResourcesToOutPath() throws IOException { - // // System.err.println("? dumpResourcesToOutPath() resources=" + resources.keySet()); + // // System.err.println("? dumpResourcesToOutPath() resources=" + + // resources.keySet()); // Iterator i = resources.keySet().iterator(); // while (i.hasNext()) { // UnwovenClassFile res = (UnwovenClassFile)resources.get(i.next()); @@ -896,7 +998,8 @@ public class BcelWeaver { // /* BUG #40943 */ // public void dumpResourcesToOutJar() throws IOException { - // // System.err.println("? dumpResourcesToOutJar() resources=" + resources.keySet()); + // // System.err.println("? dumpResourcesToOutJar() resources=" + + // resources.keySet()); // Iterator i = resources.keySet().iterator(); // while (i.hasNext()) { // String name = (String)i.next(); @@ -906,9 +1009,11 @@ public class BcelWeaver { // resources = new HashMap(); // } // - // // halfway house for when the jar is managed outside of the weaver, but the resources + // // halfway house for when the jar is managed outside of the weaver, but + // the resources // // to be copied are known in the weaver. - // public void dumpResourcesToOutJar(ZipOutputStream zos) throws IOException { + // public void dumpResourcesToOutJar(ZipOutputStream zos) throws IOException + // { // this.zipOutputStream = zos; // dumpResourcesToOutJar(); // } @@ -1024,7 +1129,8 @@ public class BcelWeaver { // for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) { // UnwovenClassFile classFile = (UnwovenClassFile)i.next(); // String className = classFile.getClassName(); - // BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(className)); + // BcelObjectType classType = + // BcelWorld.getBcelObjectType(world.resolve(className)); // if (classType.isAspect()) { // weave(classFile, classType); // wovenClassNames.add(className); @@ -1035,7 +1141,8 @@ public class BcelWeaver { // for (Iterator i = filesToWeave.iterator(); i.hasNext(); ) { // UnwovenClassFile classFile = (UnwovenClassFile)i.next(); // String className = classFile.getClassName(); - // BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(className)); + // BcelObjectType classType = + // BcelWorld.getBcelObjectType(world.resolve(className)); // if (! classType.isAspect()) { // weave(classFile, classType); // wovenClassNames.add(className); @@ -1061,19 +1168,23 @@ public class BcelWeaver { public Collection weave(IClassFileProvider input) throws IOException { if (trace.isTraceEnabled()) trace.enter("weave", this, input); - ContextToken weaveToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING, ""); + ContextToken weaveToken = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.WEAVING, ""); Collection wovenClassNames = new ArrayList(); IWeaveRequestor requestor = input.getRequestor(); for (Iterator i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = (UnwovenClassFile) i.next(); if (AsmManager.isCreatingModel() && !isBatchWeave) { - // remove all relationships where this file being woven is the target of the relationship - AsmManager.getDefault().removeRelationshipsTargettingThisType(classFile.getClassName()); + // remove all relationships where this file being woven is the + // target of the relationship + AsmManager.getDefault().removeRelationshipsTargettingThisType( + classFile.getClassName()); } } - // Go through the types and ensure any 'damaged' during compile time are repaired prior to weaving + // Go through the types and ensure any 'damaged' during compile time are + // repaired prior to weaving for (Iterator i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = (UnwovenClassFile) i.next(); String className = classFile.getClassName(); @@ -1087,22 +1198,28 @@ public class BcelWeaver { // special case for AtAspectJMungerOnly - see #113587 if (input.isApplyAtAspectJMungersOnly()) { - ContextToken atAspectJMungersOnly = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY, ""); + ContextToken atAspectJMungersOnly = CompilationAndWeavingContext + .enteringPhase( + CompilationAndWeavingContext.PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY, + ""); requestor.weavingAspects(); // ContextToken aspectToken = - CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, ""); + CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.WEAVING_ASPECTS, ""); for (Iterator i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = (UnwovenClassFile) i.next(); String className = classFile.getClassName(); ResolvedType theType = world.resolve(className); if (theType.isAnnotationStyleAspect()) { - BcelObjectType classType = BcelWorld.getBcelObjectType(theType); + BcelObjectType classType = BcelWorld + .getBcelObjectType(theType); if (classType == null) { - throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); + throw new BCException("Can't find bcel delegate for " + + className + " type=" + theType.getClass()); } LazyClassGen clazz = classType.getLazyClassGen(); - BcelPerClauseAspectAdder selfMunger = new BcelPerClauseAspectAdder(theType, theType.getPerClause().getKind()); + BcelPerClauseAspectAdder selfMunger = new BcelPerClauseAspectAdder( + theType, theType.getPerClause().getKind()); selfMunger.forceMunge(clazz, true); classType.finishedWith(); UnwovenClassFile[] newClasses = getClassFilesFor(clazz); @@ -1127,11 +1244,14 @@ public class BcelWeaver { String className = classFile.getClassName(); BcelObjectType classType = getClassType(className); - // null return from getClassType() means the delegate is an eclipse source type - so + // null return from getClassType() means the delegate is an eclipse + // source type - so // there *cant* be any reweavable state... (he bravely claimed...) if (classType != null) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, className); + ContextToken tok = CompilationAndWeavingContext + .enteringPhase( + CompilationAndWeavingContext.PROCESSING_REWEAVABLE_STATE, + className); processReweavableStateIfPresent(className, classType); CompilationAndWeavingContext.leavingPhase(tok); } @@ -1139,14 +1259,18 @@ public class BcelWeaver { CompilationAndWeavingContext.leavingPhase(reweaveToken); - ContextToken typeMungingToken = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, ""); + ContextToken typeMungingToken = CompilationAndWeavingContext + .enteringPhase( + CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, + ""); requestor.addingTypeMungers(); - // We process type mungers in two groups, first mungers that change the type + // We process type mungers in two groups, first mungers that change the + // type // hierarchy, then 'normal' ITD type mungers. - // Process the types in a predictable order (rather than the order encountered). + // Process the types in a predictable order (rather than the order + // encountered). // For class A, the order is superclasses of A then superinterfaces of A // (and this mechanism is applied recursively) List typesToProcess = new ArrayList(); @@ -1167,7 +1291,8 @@ public class BcelWeaver { CompilationAndWeavingContext.leavingPhase(typeMungingToken); requestor.weavingAspects(); - ContextToken aspectToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_ASPECTS, ""); + ContextToken aspectToken = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.WEAVING_ASPECTS, ""); // first weave into aspects for (Iterator i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = (UnwovenClassFile) i.next(); @@ -1177,15 +1302,21 @@ public class BcelWeaver { BcelObjectType classType = BcelWorld.getBcelObjectType(theType); if (classType == null) { - // Sometimes.. if the Bcel Delegate couldn't be found then a problem occurred at compile time - on - // a previous compiler run. In this case I assert the delegate will still be an EclipseSourceType - // and we can ignore the problem here (the original compile error will be reported again from + // Sometimes.. if the Bcel Delegate couldn't be found then a + // problem occurred at compile time - on + // a previous compiler run. In this case I assert the + // delegate will still be an EclipseSourceType + // and we can ignore the problem here (the original compile + // error will be reported again from // the eclipse source type) - pr113531 - ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate(); - if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) + ReferenceTypeDelegate theDelegate = ((ReferenceType) theType) + .getDelegate(); + if (theDelegate.getClass().getName().endsWith( + "EclipseSourceType")) continue; - throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); + throw new BCException("Can't find bcel delegate for " + + className + " type=" + theType.getClass()); } weaveAndNotify(classFile, classType, requestor); wovenClassNames.add(className); @@ -1195,7 +1326,8 @@ public class BcelWeaver { CompilationAndWeavingContext.leavingPhase(aspectToken); requestor.weavingClasses(); - ContextToken classToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_CLASSES, ""); + ContextToken classToken = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.WEAVING_CLASSES, ""); // then weave into non-aspects for (Iterator i = input.getClassFileIterator(); i.hasNext();) { UnwovenClassFile classFile = (UnwovenClassFile) i.next(); @@ -1206,13 +1338,17 @@ public class BcelWeaver { if (classType == null) { // bug 119882 - see above comment for bug 113531 - ReferenceTypeDelegate theDelegate = ((ReferenceType) theType).getDelegate(); + ReferenceTypeDelegate theDelegate = ((ReferenceType) theType) + .getDelegate(); - // TODO urgh - put a method on the interface to check this, string compare is hideous - if (theDelegate.getClass().getName().endsWith("EclipseSourceType")) + // TODO urgh - put a method on the interface to check this, + // string compare is hideous + if (theDelegate.getClass().getName().endsWith( + "EclipseSourceType")) continue; - throw new BCException("Can't find bcel delegate for " + className + " type=" + theType.getClass()); + throw new BCException("Can't find bcel delegate for " + + className + " type=" + theType.getClass()); } weaveAndNotify(classFile, classType, requestor); wovenClassNames.add(className); @@ -1235,7 +1371,8 @@ public class BcelWeaver { } /** - * In 1.5 mode and with XLint:adviceDidNotMatch enabled, put out messages for any mungers that did not match anything. + * In 1.5 mode and with XLint:adviceDidNotMatch enabled, put out messages + * for any mungers that did not match anything. */ private void warnOnUnmatchedAdvice() { @@ -1264,23 +1401,32 @@ public class BcelWeaver { } } - // FIXME asc Should be factored out into Xlint code and done automatically for all xlint messages, ideally. - // if a piece of advice hasn't matched anywhere and we are in -1.5 mode, put out a warning - if (world.isInJava5Mode() && world.getLint().adviceDidNotMatch.isEnabled()) { + // FIXME asc Should be factored out into Xlint code and done + // automatically for all xlint messages, ideally. + // if a piece of advice hasn't matched anywhere and we are in -1.5 mode, + // put out a warning + if (world.isInJava5Mode() + && world.getLint().adviceDidNotMatch.isEnabled()) { List l = world.getCrosscuttingMembersSet().getShadowMungers(); Set alreadyWarnedLocations = new HashSet(); for (Iterator iter = l.iterator(); iter.hasNext();) { ShadowMunger element = (ShadowMunger) iter.next(); - if (element instanceof BcelAdvice) { // This will stop us incorrectly reporting deow Checkers + if (element instanceof BcelAdvice) { // This will stop us + // incorrectly reporting + // deow Checkers BcelAdvice ba = (BcelAdvice) element; if (!ba.hasMatchedSomething()) { - // Because we implement some features of AJ itself by creating our own kind of mungers, you sometimes - // find that ba.getSignature() is not a BcelMethod - for example it might be a cflow entry munger. + // Because we implement some features of AJ itself by + // creating our own kind of mungers, you sometimes + // find that ba.getSignature() is not a BcelMethod - for + // example it might be a cflow entry munger. if (ba.getSignature() != null) { - // check we haven't already warned on this advice and line - // (cflow creates multiple mungers for the same advice) + // check we haven't already warned on this advice + // and line + // (cflow creates multiple mungers for the same + // advice) AdviceLocation loc = new AdviceLocation(ba); if (alreadyWarnedLocations.contains(loc)) { continue; @@ -1289,9 +1435,20 @@ public class BcelWeaver { } if (!(ba.getSignature() instanceof BcelMethod) - || !Utility.isSuppressing(ba.getSignature(), "adviceDidNotMatch")) { - world.getLint().adviceDidNotMatch.signal(ba.getDeclaringAspect().toString(), new SourceLocation( - element.getSourceLocation().getSourceFile(), element.getSourceLocation().getLine()));// element + || !Utility.isSuppressing( + ba.getSignature(), + "adviceDidNotMatch")) { + world.getLint().adviceDidNotMatch + .signal( + ba.getDeclaringAspect() + .toString(), + new SourceLocation( + element + .getSourceLocation() + .getSourceFile(), + element + .getSourceLocation() + .getLine()));// element // . // getSourceLocation // ( @@ -1307,13 +1464,16 @@ public class BcelWeaver { } /** - * 'typeToWeave' is one from the 'typesForWeaving' list. This routine ensures we process supertypes (classes/interfaces) of - * 'typeToWeave' that are in the 'typesForWeaving' list before 'typeToWeave' itself. 'typesToWeave' is then removed from the - * 'typesForWeaving' list. + * 'typeToWeave' is one from the 'typesForWeaving' list. This routine + * ensures we process supertypes (classes/interfaces) of 'typeToWeave' that + * are in the 'typesForWeaving' list before 'typeToWeave' itself. + * 'typesToWeave' is then removed from the 'typesForWeaving' list. * - * Note: Future gotcha in here ... when supplying partial hierarchies, this algorithm may break down. If you have a hierarchy - * A>B>C and only give A and C to the weaver, it may choose to weave them in either order - but you'll probably have other - * problems if you are supplying partial hierarchies like that ! + * Note: Future gotcha in here ... when supplying partial hierarchies, this + * algorithm may break down. If you have a hierarchy A>B>C and only give A + * and C to the weaver, it may choose to weave them in either order - but + * you'll probably have other problems if you are supplying partial + * hierarchies like that ! */ private void weaveParentsFor(List typesForWeaving, String typeToWeave) { // Look at the supertype first @@ -1332,73 +1492,120 @@ public class BcelWeaver { weaveParentsFor(typesForWeaving, rtxI.getName()); } } - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS, rtx - .getName()); + ContextToken tok = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS, rtx + .getName()); weaveParentTypeMungers(rtx); // Now do this type CompilationAndWeavingContext.leavingPhase(tok); - typesForWeaving.remove(typeToWeave); // and remove it from the list of those to process + typesForWeaving.remove(typeToWeave); // and remove it from the list of + // those to process } public void prepareToProcessReweavableState() { } - public void processReweavableStateIfPresent(String className, BcelObjectType classType) { - // If the class is marked reweavable, check any aspects around when it was built are in this world + public void processReweavableStateIfPresent(String className, + BcelObjectType classType) { + // If the class is marked reweavable, check any aspects around when it + // was built are in this world WeaverStateInfo wsi = classType.getWeaverState(); - if (wsi != null && wsi.isReweavable()) { // Check all necessary types are around! - world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.PROCESSING_REWEAVABLE, className, classType - .getSourceLocation().getSourceFile()), null, null); + if (wsi != null && wsi.isReweavable()) { // Check all necessary types + // are around! + world.showMessage(IMessage.INFO, WeaverMessages.format( + WeaverMessages.PROCESSING_REWEAVABLE, className, classType + .getSourceLocation().getSourceFile()), null, null); Set aspectsPreviouslyInWorld = wsi.getAspectsAffectingType(); if (aspectsPreviouslyInWorld != null) { - // keep track of them just to ensure unique missing aspect error reporting + // keep track of them just to ensure unique missing aspect error + // reporting Set alreadyConfirmedReweavableState = new HashSet(); - for (Iterator iter = aspectsPreviouslyInWorld.iterator(); iter.hasNext();) { + for (Iterator iter = aspectsPreviouslyInWorld.iterator(); iter + .hasNext();) { String requiredTypeName = (String) iter.next(); - if (!alreadyConfirmedReweavableState.contains(requiredTypeName)) { - ResolvedType rtx = world.resolve(UnresolvedType.forName(requiredTypeName), true); + if (!alreadyConfirmedReweavableState + .contains(requiredTypeName)) { + ResolvedType rtx = world.resolve(UnresolvedType + .forName(requiredTypeName), true); boolean exists = !rtx.isMissing(); if (!exists) { - world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.MISSING_REWEAVABLE_TYPE, - requiredTypeName, className), classType.getSourceLocation(), null); + world + .showMessage( + IMessage.ERROR, + WeaverMessages + .format( + WeaverMessages.MISSING_REWEAVABLE_TYPE, + requiredTypeName, + className), + classType.getSourceLocation(), null); } else { - // weaved in aspect that are not declared in aop.xml trigger an error for now - // may cause headhache for LTW and packaged lib without aop.xml in + // weaved in aspect that are not declared in aop.xml + // trigger an error for now + // may cause headhache for LTW and packaged lib + // without aop.xml in // see #104218 if (!xcutSet.containsAspect(rtx)) { - world.showMessage(IMessage.ERROR, WeaverMessages.format( - WeaverMessages.REWEAVABLE_ASPECT_NOT_REGISTERED, requiredTypeName, className), null, null); - } else if (!world.getMessageHandler().isIgnoring(IMessage.INFO)) - world.showMessage(IMessage.INFO, WeaverMessages.format(WeaverMessages.VERIFIED_REWEAVABLE_TYPE, - requiredTypeName, rtx.getSourceLocation().getSourceFile()), null, null); - alreadyConfirmedReweavableState.add(requiredTypeName); + world + .showMessage( + IMessage.ERROR, + WeaverMessages + .format( + WeaverMessages.REWEAVABLE_ASPECT_NOT_REGISTERED, + requiredTypeName, + className), + null, null); + } else if (!world.getMessageHandler().isIgnoring( + IMessage.INFO)) + world + .showMessage( + IMessage.INFO, + WeaverMessages + .format( + WeaverMessages.VERIFIED_REWEAVABLE_TYPE, + requiredTypeName, + rtx + .getSourceLocation() + .getSourceFile()), + null, null); + alreadyConfirmedReweavableState + .add(requiredTypeName); } } } } // old: - // classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData())); + //classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass + // ().getFileName(), wsi.getUnwovenClassFileData())); // new: reweavable default with clever diff - classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi - .getUnwovenClassFileData(classType.getJavaClass().getBytes()))); + classType.setJavaClass(Utility.makeJavaClass(classType + .getJavaClass().getFileName(), wsi + .getUnwovenClassFileData(classType.getJavaClass() + .getBytes()))); // } else { // classType.resetState(); } } - private void weaveAndNotify(UnwovenClassFile classFile, BcelObjectType classType, IWeaveRequestor requestor) throws IOException { - trace.enter("weaveAndNotify", this, new Object[] { classFile, classType, requestor }); + private void weaveAndNotify(UnwovenClassFile classFile, + BcelObjectType classType, IWeaveRequestor requestor) + throws IOException { + trace.enter("weaveAndNotify", this, new Object[] { classFile, + classType, requestor }); - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_TYPE, classType - .getResolvedTypeX().getName()); + ContextToken tok = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.WEAVING_TYPE, classType + .getResolvedTypeX().getName()); LazyClassGen clazz = weaveWithoutDump(classFile, classType); classType.finishedWith(); // clazz is null if the classfile was unchanged by weaving... if (clazz != null) { UnwovenClassFile[] newClasses = getClassFilesFor(clazz); - // OPTIMIZE can we avoid using the string name at all in UnwovenClassFile instances? - // Copy the char[] across as it means the WeaverAdapter.removeFromMap() can be fast! + // OPTIMIZE can we avoid using the string name at all in + // UnwovenClassFile instances? + // Copy the char[] across as it means the + // WeaverAdapter.removeFromMap() can be fast! if (newClasses[0].getClassName().equals(classFile.getClassName())) { - newClasses[0].setClassNameAsChars(classFile.getClassNameAsChars()); + newClasses[0].setClassNameAsChars(classFile + .getClassNameAsChars()); } for (int i = 0; i < newClasses.length; i++) { requestor.acceptResult(newClasses[i]); @@ -1412,7 +1619,10 @@ public class BcelWeaver { trace.exit("weaveAndNotify"); } - /** helper method - will return NULL if the underlying delegate is an EclipseSourceType and not a BcelObjectType */ + /** + * helper method - will return NULL if the underlying delegate is an + * EclipseSourceType and not a BcelObjectType + */ public BcelObjectType getClassType(String forClass) { return BcelWorld.getBcelObjectType(world.resolve(forClass)); } @@ -1428,23 +1638,31 @@ public class BcelWeaver { public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) { List childClasses = clazz.getChildClasses(world); UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()]; - ret[0] = new UnwovenClassFile(clazz.getFileName(), clazz.getClassName(), clazz.getJavaClassBytesIncludingReweavable(world)); + ret[0] = new UnwovenClassFile(clazz.getFileName(), + clazz.getClassName(), clazz + .getJavaClassBytesIncludingReweavable(world)); int index = 1; for (Iterator iter = childClasses.iterator(); iter.hasNext();) { - UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next(); - UnwovenClassFile childClass = new UnwovenClassFile(clazz.getFileName() + "$" + element.name, element.bytes); + UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter + .next(); + UnwovenClassFile childClass = new UnwovenClassFile(clazz + .getFileName() + + "$" + element.name, element.bytes); ret[index++] = childClass; } return ret; } /** - * Weaves new parents and annotations onto a type ("declare parents" and "declare @type") + * Weaves new parents and annotations onto a type ("declare parents" and + * "declare @type") * - * Algorithm: 1. First pass, do parents then do annotations. During this pass record: - any parent mungers that don't match but - * have a non-wild annotation type pattern - any annotation mungers that don't match 2. Multiple subsequent passes which go over - * the munger lists constructed in the first pass, repeatedly applying them until nothing changes. FIXME asc confirm that - * algorithm is optimal ?? + * Algorithm: 1. First pass, do parents then do annotations. During this + * pass record: - any parent mungers that don't match but have a non-wild + * annotation type pattern - any annotation mungers that don't match 2. + * Multiple subsequent passes which go over the munger lists constructed in + * the first pass, repeatedly applying them until nothing changes. FIXME asc + * confirm that algorithm is optimal ?? */ public void weaveParentTypeMungers(ResolvedType onType) { if (onType.isRawType()) @@ -1467,7 +1685,8 @@ public class BcelWeaver { } // Still first pass - apply all dec @type mungers - for (Iterator i = xcutSet.getDeclareAnnotationOnTypes().iterator(); i.hasNext();) { + for (Iterator i = xcutSet.getDeclareAnnotationOnTypes().iterator(); i + .hasNext();) { DeclareAnnotation decA = (DeclareAnnotation) i.next(); boolean typeChanged = applyDeclareAtType(decA, onType, true); if (typeChanged) { @@ -1475,7 +1694,8 @@ public class BcelWeaver { } } - while ((aParentChangeOccurred || anAnnotationChangeOccurred) && !decpToRepeat.isEmpty()) { + while ((aParentChangeOccurred || anAnnotationChangeOccurred) + && !decpToRepeat.isEmpty()) { anAnnotationChangeOccurred = aParentChangeOccurred = false; List decpToRepeatNextTime = new ArrayList(); for (Iterator iter = decpToRepeat.iterator(); iter.hasNext();) { @@ -1488,7 +1708,8 @@ public class BcelWeaver { } } - for (Iterator iter = xcutSet.getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) { + for (Iterator iter = xcutSet.getDeclareAnnotationOnTypes() + .iterator(); iter.hasNext();) { DeclareAnnotation decA = (DeclareAnnotation) iter.next(); boolean typeChanged = applyDeclareAtType(decA, onType, false); if (typeChanged) { @@ -1502,40 +1723,57 @@ public class BcelWeaver { /** * Apply a declare @type - return true if we change the type */ - private boolean applyDeclareAtType(DeclareAnnotation decA, ResolvedType onType, boolean reportProblems) { + private boolean applyDeclareAtType(DeclareAnnotation decA, + ResolvedType onType, boolean reportProblems) { boolean didSomething = false; if (decA.matches(onType)) { - if (onType.hasAnnotation(decA.getAnnotationX().getSignature())) { + if (onType.hasAnnotation(decA.getAnnotationX().getType())) { // Could put out a lint here for an already annotated type ... // if (reportProblems) { // world.getLint().elementAlreadyAnnotated.signal( - // new String[]{onType.toString(),decA.getAnnotationTypeX().toString()}, - // onType.getSourceLocation(),new ISourceLocation[]{decA.getSourceLocation()}); + // new + // String[]{onType.toString(),decA.getAnnotationTypeX().toString + // ()}, + // onType.getSourceLocation(),new + // ISourceLocation[]{decA.getSourceLocation()}); // } return false; } - AnnotationX annoX = decA.getAnnotationX(); + AnnotationAJ annoX = decA.getAnnotationX(); // check the annotation is suitable for the target - boolean problemReported = verifyTargetIsOK(decA, onType, annoX, reportProblems); + boolean problemReported = verifyTargetIsOK(decA, onType, annoX, + reportProblems); if (!problemReported) { - AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decA.getSourceLocation(), - onType.getSourceLocation()); + AsmRelationshipProvider.getDefault() + .addDeclareAnnotationRelationship( + decA.getSourceLocation(), + onType.getSourceLocation()); // TAG: WeavingMessage - if (!getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { + if (!getWorld().getMessageHandler().isIgnoring( + IMessage.WEAVEINFO)) { getWorld().getMessageHandler().handleMessage( - WeaveMessage.constructWeavingMessage(WeaveMessage.WEAVEMESSAGE_ANNOTATES, new String[] { - onType.toString(), Utility.beautifyLocation(onType.getSourceLocation()), - decA.getAnnotationString(), "type", decA.getAspect().toString(), - Utility.beautifyLocation(decA.getSourceLocation()) })); + WeaveMessage.constructWeavingMessage( + WeaveMessage.WEAVEMESSAGE_ANNOTATES, + new String[] { + onType.toString(), + Utility.beautifyLocation(onType + .getSourceLocation()), + decA.getAnnotationString(), + "type", + decA.getAspect().toString(), + Utility.beautifyLocation(decA + .getSourceLocation()) })); } didSomething = true; - ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger(annoX); + ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger( + annoX); newAnnotationTM.setSourceLocation(decA.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, decA.getAspect().resolve(world))); + onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, + decA.getAspect().resolve(world))); decA.copyAnnotationTo(onType); } } @@ -1543,23 +1781,43 @@ public class BcelWeaver { } /** - * Checks for an @target() on the annotation and if found ensures it allows the annotation to be attached to the target type - * that matched. + * Checks for an @target() on the annotation and if found ensures it allows + * the annotation to be attached to the target type that matched. */ - private boolean verifyTargetIsOK(DeclareAnnotation decA, ResolvedType onType, AnnotationX annoX, boolean outputProblems) { + private boolean verifyTargetIsOK(DeclareAnnotation decA, + ResolvedType onType, AnnotationAJ annoX, boolean outputProblems) { boolean problemReported = false; if (annoX.specifiesTarget()) { - if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) || (!annoX.allowedOnRegularType())) { + if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) + || (!annoX.allowedOnRegularType())) { if (outputProblems) { - if (decA.isExactPattern()) { - world.getMessageHandler().handleMessage( - MessageUtil.error(WeaverMessages.format(WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, - onType.getName(), annoX.stringify(), annoX.getValidTargets()), decA.getSourceLocation())); + if (decA.isExactPattern()) { + world + .getMessageHandler() + .handleMessage( + MessageUtil + .error( + WeaverMessages + .format( + WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, + onType + .getName(), + annoX + .getTypeName(), + annoX + .getValidTargets()), + decA + .getSourceLocation())); } else { - if (world.getLint().invalidTargetForAnnotation.isEnabled()) { - world.getLint().invalidTargetForAnnotation.signal(new String[] { onType.getName(), annoX.stringify(), - annoX.getValidTargets() }, decA.getSourceLocation(), new ISourceLocation[] { onType - .getSourceLocation() }); + if (world.getLint().invalidTargetForAnnotation + .isEnabled()) { + world.getLint().invalidTargetForAnnotation.signal( + new String[] { onType.getName(), + annoX.getTypeName(), + annoX.getValidTargets() }, decA + .getSourceLocation(), + new ISourceLocation[] { onType + .getSourceLocation() }); } } } @@ -1582,21 +1840,27 @@ public class BcelWeaver { for (Iterator j = newParents.iterator(); j.hasNext();) { ResolvedType newParent = (ResolvedType) j.next(); - // We set it here so that the imminent matching for ITDs can succeed - we - // still haven't done the necessary changes to the class file itself - // (like transform super calls) - that is done in BcelTypeMunger.mungeNewParent() + // We set it here so that the imminent matching for ITDs can + // succeed - we + // still haven't done the necessary changes to the class file + // itself + // (like transform super calls) - that is done in + // BcelTypeMunger.mungeNewParent() classType.addParent(newParent); - ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent); + ResolvedTypeMunger newParentMunger = new NewParentTypeMunger( + newParent); newParentMunger.setSourceLocation(p.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, xcutSet.findAspectDeclaringParents(p))); + onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, + xcutSet.findAspectDeclaringParents(p))); } } return didSomething; } public void weaveNormalTypeMungers(ResolvedType onType) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, onType - .getName()); + ContextToken tok = CompilationAndWeavingContext.enteringPhase( + CompilationAndWeavingContext.PROCESSING_TYPE_MUNGERS, onType + .getName()); if (onType.isRawType() || onType.isParameterizedType()) onType = onType.getGenericType(); for (Iterator i = typeMungerList.iterator(); i.hasNext();) { @@ -1609,48 +1873,61 @@ public class BcelWeaver { } // exposed for ClassLoader dynamic weaving - public LazyClassGen weaveWithoutDump(UnwovenClassFile classFile, BcelObjectType classType) throws IOException { + public LazyClassGen weaveWithoutDump(UnwovenClassFile classFile, + BcelObjectType classType) throws IOException { return weave(classFile, classType, false); } // non-private for testing - LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType) throws IOException { + LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType) + throws IOException { LazyClassGen ret = weave(classFile, classType, true); return ret; } - private LazyClassGen weave(UnwovenClassFile classFile, BcelObjectType classType, boolean dump) throws IOException { + private LazyClassGen weave(UnwovenClassFile classFile, + BcelObjectType classType, boolean dump) throws IOException { if (classType.isSynthetic()) { // Don't touch synthetic classes if (dump) dumpUnchanged(classFile); return null; } - List shadowMungers = fastMatch(shadowMungerList, classType.getResolvedTypeX()); + List shadowMungers = fastMatch(shadowMungerList, classType + .getResolvedTypeX()); List typeMungers = classType.getResolvedTypeX().getInterTypeMungers(); classType.getResolvedTypeX().checkInterTypeMungers(); // Decide if we need to do actual weaving for this class - boolean mightNeedToWeave = shadowMungers.size() > 0 || typeMungers.size() > 0 || classType.isAspect() - || world.getDeclareAnnotationOnMethods().size() > 0 || world.getDeclareAnnotationOnFields().size() > 0; - - // May need bridge methods if on 1.5 and something in our hierarchy is affected by ITDs - boolean mightNeedBridgeMethods = world.isInJava5Mode() && !classType.isInterface() - && classType.getResolvedTypeX().getInterTypeMungersIncludingSupers().size() > 0; + boolean mightNeedToWeave = shadowMungers.size() > 0 + || typeMungers.size() > 0 || classType.isAspect() + || world.getDeclareAnnotationOnMethods().size() > 0 + || world.getDeclareAnnotationOnFields().size() > 0; + + // May need bridge methods if on 1.5 and something in our hierarchy is + // affected by ITDs + boolean mightNeedBridgeMethods = world.isInJava5Mode() + && !classType.isInterface() + && classType.getResolvedTypeX() + .getInterTypeMungersIncludingSupers().size() > 0; LazyClassGen clazz = null; if (mightNeedToWeave || mightNeedBridgeMethods) { clazz = classType.getLazyClassGen(); - // System.err.println("got lazy gen: " + clazz + ", " + clazz.getWeaverState()); + // System.err.println("got lazy gen: " + clazz + ", " + + // clazz.getWeaverState()); try { boolean isChanged = false; if (mightNeedToWeave) - isChanged = BcelClassWeaver.weave(world, clazz, shadowMungers, typeMungers, lateTypeMungerList); + isChanged = BcelClassWeaver.weave(world, clazz, + shadowMungers, typeMungers, lateTypeMungerList); if (mightNeedBridgeMethods) - isChanged = BcelClassWeaver.calculateAnyRequiredBridgeMethods(world, clazz) || isChanged; + isChanged = BcelClassWeaver + .calculateAnyRequiredBridgeMethods(world, clazz) + || isChanged; if (isChanged) { if (dump) @@ -1666,7 +1943,8 @@ public class BcelWeaver { classDebugInfo = clazz.getClassName(); } String messageText = "trouble in: \n" + classDebugInfo; - getWorld().getMessageHandler().handleMessage(new Message(messageText, IMessage.ABORT, re, null)); + getWorld().getMessageHandler().handleMessage( + new Message(messageText, IMessage.ABORT, re, null)); } catch (Error re) { String classDebugInfo = null; try { @@ -1676,7 +1954,8 @@ public class BcelWeaver { classDebugInfo = clazz.getClassName(); } String messageText = "trouble in: \n" + classDebugInfo; - getWorld().getMessageHandler().handleMessage(new Message(messageText, IMessage.ABORT, re, null)); + getWorld().getMessageHandler().handleMessage( + new Message(messageText, IMessage.ABORT, re, null)); } } @@ -1685,9 +1964,12 @@ public class BcelWeaver { dumpUnchanged(classFile); return clazz; } else { - // ATAJ: the class was not weaved, but since it gets there early it may have new generated inner classes - // attached to it to support LTW perX aspectOf support (see BcelPerClauseAspectAdder) - // that aggressively defines the inner $mayHaveAspect interface. + // ATAJ: the class was not weaved, but since it gets there early it + // may have new generated inner classes + // attached to it to support LTW perX aspectOf support (see + // BcelPerClauseAspectAdder) + // that aggressively defines the inner $mayHaveAspect + // interface. if (clazz != null && !clazz.getChildClasses(world).isEmpty()) { return clazz; } @@ -1699,7 +1981,9 @@ public class BcelWeaver { private void dumpUnchanged(UnwovenClassFile classFile) throws IOException { if (zipOutputStream != null) { - writeZipEntry(getEntryName(classFile.getJavaClass().getClassName()), classFile.getBytes()); + writeZipEntry( + getEntryName(classFile.getJavaClass().getClassName()), + classFile.getBytes()); } else { classFile.writeUnchangedBytes(); } @@ -1710,23 +1994,30 @@ public class BcelWeaver { return className.replace('.', '/') + ".class"; } - private void dump(UnwovenClassFile classFile, LazyClassGen clazz) throws IOException { + private void dump(UnwovenClassFile classFile, LazyClassGen clazz) + throws IOException { if (zipOutputStream != null) { String mainClassName = classFile.getJavaClass().getClassName(); - writeZipEntry(getEntryName(mainClassName), clazz.getJavaClass(world).getBytes()); + writeZipEntry(getEntryName(mainClassName), clazz + .getJavaClass(world).getBytes()); if (!clazz.getChildClasses(world).isEmpty()) { - for (Iterator i = clazz.getChildClasses(world).iterator(); i.hasNext();) { - UnwovenClassFile.ChildClass c = (UnwovenClassFile.ChildClass) i.next(); - writeZipEntry(getEntryName(mainClassName + "$" + c.name), c.bytes); + for (Iterator i = clazz.getChildClasses(world).iterator(); i + .hasNext();) { + UnwovenClassFile.ChildClass c = (UnwovenClassFile.ChildClass) i + .next(); + writeZipEntry(getEntryName(mainClassName + "$" + c.name), + c.bytes); } } } else { - classFile.writeWovenBytes(clazz.getJavaClass(world).getBytes(), clazz.getChildClasses(world)); + classFile.writeWovenBytes(clazz.getJavaClass(world).getBytes(), + clazz.getChildClasses(world)); } } private void writeZipEntry(String name, byte[] bytes) throws IOException { - ZipEntry newEntry = new ZipEntry(name); // ??? get compression scheme right + ZipEntry newEntry = new ZipEntry(name); // ??? get compression scheme + // right zipOutputStream.putNextEntry(newEntry); zipOutputStream.write(bytes); @@ -1738,7 +2029,8 @@ public class BcelWeaver { return Collections.EMPTY_LIST; // here we do the coarsest grained fast match with no kind constraints - // this will remove all obvious non-matches and see if we need to do any weaving + // this will remove all obvious non-matches and see if we need to do any + // weaving FastMatchInfo info = new FastMatchInfo(type, null); List result = new ArrayList(); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java index 19030715d..3b66a8eec 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWorld.java @@ -41,8 +41,8 @@ import org.aspectj.apache.bcel.util.Repository; import org.aspectj.bridge.IMessageHandler; import org.aspectj.weaver.Advice; import org.aspectj.weaver.AjAttribute; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.AnnotationOnTypeMunger; -import org.aspectj.weaver.AnnotationX; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ConcreteTypeMunger; import org.aspectj.weaver.ICrossReferenceHandler; @@ -75,7 +75,8 @@ public class BcelWorld extends World implements Repository { // private ClassPathManager aspectPath = null; // private List aspectPathEntries; - private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelWorld.class); + private static Trace trace = TraceFactory.getTraceFactory().getTrace( + BcelWorld.class); // ---- constructors @@ -106,7 +107,8 @@ public class BcelWorld extends World implements Repository { return ret; } - public BcelWorld(List classPath, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { + public BcelWorld(List classPath, IMessageHandler handler, + ICrossReferenceHandler xrefHandler) { // this.aspectPath = new ClassPathManager(aspectPath, handler); this.classPath = new ClassPathManager(classPath, handler); setMessageHandler(handler); @@ -115,7 +117,8 @@ public class BcelWorld extends World implements Repository { delegate = this; } - public BcelWorld(ClassPathManager cpm, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { + public BcelWorld(ClassPathManager cpm, IMessageHandler handler, + ICrossReferenceHandler xrefHandler) { this.classPath = cpm; setMessageHandler(handler); setCrossReferenceHandler(xrefHandler); @@ -130,7 +133,8 @@ public class BcelWorld extends World implements Repository { * @param handler * @param xrefHandler */ - public BcelWorld(ClassLoader loader, IMessageHandler handler, ICrossReferenceHandler xrefHandler) { + public BcelWorld(ClassLoader loader, IMessageHandler handler, + ICrossReferenceHandler xrefHandler) { this.classPath = null; this.loaderRef = new WeakClassLoaderReference(loader); setMessageHandler(handler); @@ -206,8 +210,10 @@ public class BcelWorld extends World implements Repository { } } - public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, JavaClass jc, boolean exposedToWeaver) { - BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, exposedToWeaver); + public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, + JavaClass jc, boolean exposedToWeaver) { + BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, + exposedToWeaver); return ret; } @@ -217,21 +223,25 @@ public class BcelWorld extends World implements Repository { ensureRepositorySetup(); JavaClass jc = delegate.loadClass(name); if (trace.isTraceEnabled()) - trace.event("lookupJavaClass", this, new Object[] { name, jc }); + trace.event("lookupJavaClass", this, new Object[] { name, + jc }); return jc; } catch (ClassNotFoundException e) { if (trace.isTraceEnabled()) - trace.error("Unable to find class '" + name + "' in repository", e); + trace.error("Unable to find class '" + name + + "' in repository", e); return null; } } try { - ClassPathManager.ClassFile file = classPath.find(UnresolvedType.forName(name)); + ClassPathManager.ClassFile file = classPath.find(UnresolvedType + .forName(name)); if (file == null) return null; - ClassParser parser = new ClassParser(file.getInputStream(), file.getPath()); + ClassParser parser = new ClassParser(file.getInputStream(), file + .getPath()); JavaClass jc = parser.parse(); file.close(); @@ -243,15 +253,18 @@ public class BcelWorld extends World implements Repository { public BcelObjectType addSourceObjectType(JavaClass jc) { BcelObjectType ret = null; - String signature = UnresolvedType.forName(jc.getClassName()).getSignature(); + String signature = UnresolvedType.forName(jc.getClassName()) + .getSignature(); Object fromTheMap = typeMap.get(signature); if (fromTheMap != null && !(fromTheMap instanceof ReferenceType)) { // what on earth is it then? See pr 112243 StringBuffer exceptionText = new StringBuffer(); - exceptionText.append("Found invalid (not a ReferenceType) entry in the type map. "); - exceptionText.append("Signature=[" + signature + "] Found=[" + fromTheMap + "] Class=[" + fromTheMap.getClass() + "]"); + exceptionText + .append("Found invalid (not a ReferenceType) entry in the type map. "); + exceptionText.append("Signature=[" + signature + "] Found=[" + + fromTheMap + "] Class=[" + fromTheMap.getClass() + "]"); throw new BCException(exceptionText.toString()); } @@ -260,10 +273,12 @@ public class BcelWorld extends World implements Repository { if (nameTypeX == null) { if (jc.isGeneric() && isInJava5Mode()) { - nameTypeX = ReferenceType.fromTypeX(UnresolvedType.forRawTypeName(jc.getClassName()), this); + nameTypeX = ReferenceType.fromTypeX(UnresolvedType + .forRawTypeName(jc.getClassName()), this); ret = buildBcelDelegate(nameTypeX, jc, true); - ReferenceType genericRefType = new ReferenceType(UnresolvedType.forGenericTypeSignature(signature, ret - .getDeclaredGenericSignature()), this); + ReferenceType genericRefType = new ReferenceType(UnresolvedType + .forGenericTypeSignature(signature, ret + .getDeclaredGenericSignature()), this); nameTypeX.setDelegate(ret); genericRefType.setDelegate(ret); nameTypeX.setGenericType(genericRefType); @@ -283,21 +298,26 @@ public class BcelWorld extends World implements Repository { typeMap.remove(ty.getSignature()); } - public static Member makeFieldJoinPointSignature(LazyClassGen cg, FieldInstruction fi) { + public static Member makeFieldJoinPointSignature(LazyClassGen cg, + FieldInstruction fi) { ConstantPool cpg = cg.getConstantPool(); - return MemberImpl.field(fi.getClassName(cpg), - (fi.opcode == Constants.GETSTATIC || fi.opcode == Constants.PUTSTATIC) ? Modifier.STATIC : 0, fi.getName(cpg), fi - .getSignature(cpg)); + return MemberImpl + .field( + fi.getClassName(cpg), + (fi.opcode == Constants.GETSTATIC || fi.opcode == Constants.PUTSTATIC) ? Modifier.STATIC + : 0, fi.getName(cpg), fi.getSignature(cpg)); } - public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) { + public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, + MemberKind kind) { Member ret = mg.getMemberView(); if (ret == null) { int mods = mg.getAccessFlags(); if (mg.getEnclosingClass().isInterface()) { mods |= Modifier.INTERFACE; } - return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg.getClassName()), mods, fromBcel(mg.getReturnType()), mg + return new ResolvedMemberImpl(kind, UnresolvedType.forName(mg + .getClassName()), mods, fromBcel(mg.getReturnType()), mg .getName(), fromBcel(mg.getArgumentTypes())); } else { return ret; @@ -305,15 +325,18 @@ public class BcelWorld extends World implements Repository { } - public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg, InstructionHandle h) { + public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg, + InstructionHandle h) { return MemberImpl.monitorEnter(); } - public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg, InstructionHandle h) { + public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg, + InstructionHandle h) { return MemberImpl.monitorExit(); } - public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, InstructionHandle handle) { + public Member makeJoinPointSignatureForArrayConstruction(LazyClassGen cg, + InstructionHandle handle) { Instruction i = handle.getInstruction(); ConstantPool cpg = cg.getConstantPool(); Member retval = null; @@ -323,7 +346,8 @@ public class BcelWorld extends World implements Repository { Type ot = i.getType(cpg); UnresolvedType ut = fromBcel(ot); ut = UnresolvedType.makeArray(ut, 1); - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "", new ResolvedType[] { ResolvedType.INT }); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, + "", new ResolvedType[] { ResolvedType.INT }); } else if (i instanceof MULTIANEWARRAY) { MULTIANEWARRAY arrayInstruction = (MULTIANEWARRAY) i; UnresolvedType ut = null; @@ -339,20 +363,25 @@ public class BcelWorld extends World implements Repository { ResolvedType[] parms = new ResolvedType[dimensions]; for (int ii = 0; ii < dimensions; ii++) parms[ii] = ResolvedType.INT; - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "", parms); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, + "", parms); } else if (i.opcode == Constants.NEWARRAY) { // NEWARRAY arrayInstruction = (NEWARRAY)i; Type ot = i.getType(); UnresolvedType ut = fromBcel(ot); - retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, "", new ResolvedType[] { ResolvedType.INT }); + retval = MemberImpl.method(ut, Modifier.PUBLIC, ResolvedType.VOID, + "", new ResolvedType[] { ResolvedType.INT }); } else { - throw new BCException("Cannot create array construction signature for this non-array instruction:" + i); + throw new BCException( + "Cannot create array construction signature for this non-array instruction:" + + i); } return retval; } - public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, InvokeInstruction ii) { + public Member makeJoinPointSignatureForMethodInvocation(LazyClassGen cg, + InvokeInstruction ii) { ConstantPool cpg = cg.getConstantPool(); String name = ii.getName(cpg); String declaring = ii.getClassName(cpg); @@ -361,19 +390,23 @@ public class BcelWorld extends World implements Repository { String signature = ii.getSignature(cpg); int modifier = (ii instanceof INVOKEINTERFACE) ? Modifier.INTERFACE - : (ii.opcode == Constants.INVOKESTATIC) ? Modifier.STATIC : (ii.opcode == Constants.INVOKESPECIAL && !name - .equals("")) ? Modifier.PRIVATE : 0; + : (ii.opcode == Constants.INVOKESTATIC) ? Modifier.STATIC + : (ii.opcode == Constants.INVOKESPECIAL && !name + .equals("")) ? Modifier.PRIVATE : 0; - // in Java 1.4 and after, static method call of super class within subclass method appears + // in Java 1.4 and after, static method call of super class within + // subclass method appears // as declared by the subclass in the bytecode - but they are not // see #104212 if (ii.opcode == Constants.INVOKESTATIC) { ResolvedType appearsDeclaredBy = resolve(declaring); // look for the method there - for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator.hasNext();) { + for (Iterator iterator = appearsDeclaredBy.getMethods(); iterator + .hasNext();) { ResolvedMember method = (ResolvedMember) iterator.next(); if (method.isStatic()) { - if (name.equals(method.getName()) && signature.equals(method.getSignature())) { + if (name.equals(method.getName()) + && signature.equals(method.getSignature())) { // we found it declaringType = method.getDeclaringType(); break; @@ -400,12 +433,15 @@ public class BcelWorld extends World implements Repository { return buf.toString(); } - public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature) { - // System.err.println("concrete advice: " + signature + " context " + sourceContext); + public Advice createAdviceMunger(AjAttribute.AdviceAttribute attribute, + Pointcut pointcut, Member signature) { + // System.err.println("concrete advice: " + signature + " context " + + // sourceContext); return new BcelAdvice(attribute, pointcut, signature, null); } - public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType) { + public ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, + ResolvedType aspectType) { return new BcelTypeMunger(munger, aspectType); } @@ -413,27 +449,32 @@ public class BcelWorld extends World implements Repository { return new BcelCflowStackFieldAdder(cflowField); } - public ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField) { + public ConcreteTypeMunger makeCflowCounterFieldAdder( + ResolvedMember cflowField) { return new BcelCflowCounterFieldAdder(cflowField); } /** - * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed + * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to + * them as needed * * @param aspect * @param kind * @return munger */ - public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind) { + public ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, + PerClause.Kind kind) { return new BcelPerClauseAspectAdder(aspect, kind); } /** - * Retrieve a bcel delegate for an aspect - this will return NULL if the delegate is an EclipseSourceType and not a - * BcelObjectType - this happens quite often when incrementally compiling. + * Retrieve a bcel delegate for an aspect - this will return NULL if the + * delegate is an EclipseSourceType and not a BcelObjectType - this happens + * quite often when incrementally compiling. */ public static BcelObjectType getBcelObjectType(ResolvedType concreteAspect) { - ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect).getDelegate(); + ReferenceTypeDelegate rtDelegate = ((ReferenceType) concreteAspect) + .getDelegate(); if (rtDelegate instanceof BcelObjectType) { return (BcelObjectType) rtDelegate; } else { @@ -442,7 +483,8 @@ public class BcelWorld extends World implements Repository { } public void tidyUp() { - // At end of compile, close any open files so deletion of those archives is possible + // At end of compile, close any open files so deletion of those archives + // is possible classPath.closeArchives(); typeMap.report(); ResolvedType.resetPrimitives(); @@ -477,8 +519,9 @@ public class BcelWorld extends World implements Repository { // @Override /** - * The aim of this method is to make sure a particular type is 'ok'. Some operations on the delegate for a type modify it and - * this method is intended to undo that... see pr85132 + * The aim of this method is to make sure a particular type is 'ok'. Some + * operations on the delegate for a type modify it and this method is + * intended to undo that... see pr85132 */ public void validateType(UnresolvedType type) { ResolvedType result = typeMap.get(type.getSignature()); @@ -489,7 +532,8 @@ public class BcelWorld extends World implements Repository { ReferenceType rt = (ReferenceType) result; rt.getDelegate().ensureDelegateConsistent(); // If we want to rebuild it 'from scratch' then: - // ClassParser cp = new ClassParser(new ByteArrayInputStream(newbytes),new String(cs)); + // ClassParser cp = new ClassParser(new + // ByteArrayInputStream(newbytes),new String(cs)); // try { // rt.setDelegate(makeBcelObjectType(rt,cp.parse(),true)); // } catch (ClassFormatException e) { @@ -512,14 +556,19 @@ public class BcelWorld extends World implements Repository { for (Iterator j = newParents.iterator(); j.hasNext();) { ResolvedType newParent = (ResolvedType) j.next(); - // We set it here so that the imminent matching for ITDs can succeed - we - // still haven't done the necessary changes to the class file itself - // (like transform super calls) - that is done in BcelTypeMunger.mungeNewParent() + // We set it here so that the imminent matching for ITDs can + // succeed - we + // still haven't done the necessary changes to the class file + // itself + // (like transform super calls) - that is done in + // BcelTypeMunger.mungeNewParent() classType.addParent(newParent); - ResolvedTypeMunger newParentMunger = new NewParentTypeMunger(newParent); + ResolvedTypeMunger newParentMunger = new NewParentTypeMunger( + newParent); newParentMunger.setSourceLocation(p.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, getCrosscuttingMembersSet() - .findAspectDeclaringParents(p))); + onType.addInterTypeMunger(new BcelTypeMunger(newParentMunger, + getCrosscuttingMembersSet().findAspectDeclaringParents( + p))); } } return didSomething; @@ -528,25 +577,28 @@ public class BcelWorld extends World implements Repository { /** * Apply a declare @type - return true if we change the type */ - private boolean applyDeclareAtType(DeclareAnnotation decA, ResolvedType onType, boolean reportProblems) { + private boolean applyDeclareAtType(DeclareAnnotation decA, + ResolvedType onType, boolean reportProblems) { boolean didSomething = false; if (decA.matches(onType)) { - if (onType.hasAnnotation(decA.getAnnotationX().getSignature())) { + if (onType.hasAnnotation(decA.getAnnotationX().getType())) { // already has it return false; } - AnnotationX annoX = decA.getAnnotationX(); + AnnotationAJ annoX = decA.getAnnotationX(); // check the annotation is suitable for the target boolean isOK = checkTargetOK(decA, onType, annoX); if (isOK) { didSomething = true; - ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger(annoX); + ResolvedTypeMunger newAnnotationTM = new AnnotationOnTypeMunger( + annoX); newAnnotationTM.setSourceLocation(decA.getSourceLocation()); - onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, decA.getAspect().resolve(this))); + onType.addInterTypeMunger(new BcelTypeMunger(newAnnotationTM, + decA.getAspect().resolve(this))); decA.copyAnnotationTo(onType); } } @@ -554,23 +606,28 @@ public class BcelWorld extends World implements Repository { } /** - * Checks for an @target() on the annotation and if found ensures it allows the annotation to be attached to the target type - * that matched. + * Checks for an @target() on the annotation and if found ensures it allows + * the annotation to be attached to the target type that matched. */ - private boolean checkTargetOK(DeclareAnnotation decA, ResolvedType onType, AnnotationX annoX) { + private boolean checkTargetOK(DeclareAnnotation decA, ResolvedType onType, + AnnotationAJ annoX) { if (annoX.specifiesTarget()) { - if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) || (!annoX.allowedOnRegularType())) { + if ((onType.isAnnotation() && !annoX.allowedOnAnnotationType()) + || (!annoX.allowedOnRegularType())) { return false; } } return true; } - // Hmmm - very similar to the code in BcelWeaver.weaveParentTypeMungers - this code - // doesn't need to produce errors/warnings though as it won't really be weaving. + // Hmmm - very similar to the code in BcelWeaver.weaveParentTypeMungers - + // this code + // doesn't need to produce errors/warnings though as it won't really be + // weaving. protected void weaveInterTypeDeclarations(ResolvedType onType) { - List declareParentsList = getCrosscuttingMembersSet().getDeclareParents(); + List declareParentsList = getCrosscuttingMembersSet() + .getDeclareParents(); if (onType.isRawType()) onType = onType.getGenericType(); onType.clearInterTypeMungers(); @@ -585,14 +642,16 @@ public class BcelWorld extends World implements Repository { boolean typeChanged = applyDeclareParents(decp, onType); if (typeChanged) { aParentChangeOccurred = true; - } else { // Perhaps it would have matched if a 'dec @type' had modified the type + } else { // Perhaps it would have matched if a 'dec @type' had + // modified the type if (!decp.getChild().isStarAnnotation()) decpToRepeat.add(decp); } } // Still first pass - apply all dec @type mungers - for (Iterator i = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); i.hasNext();) { + for (Iterator i = getCrosscuttingMembersSet() + .getDeclareAnnotationOnTypes().iterator(); i.hasNext();) { DeclareAnnotation decA = (DeclareAnnotation) i.next(); boolean typeChanged = applyDeclareAtType(decA, onType, true); if (typeChanged) { @@ -600,7 +659,8 @@ public class BcelWorld extends World implements Repository { } } - while ((aParentChangeOccurred || anAnnotationChangeOccurred) && !decpToRepeat.isEmpty()) { + while ((aParentChangeOccurred || anAnnotationChangeOccurred) + && !decpToRepeat.isEmpty()) { anAnnotationChangeOccurred = aParentChangeOccurred = false; List decpToRepeatNextTime = new ArrayList(); for (Iterator iter = decpToRepeat.iterator(); iter.hasNext();) { @@ -613,7 +673,8 @@ public class BcelWorld extends World implements Repository { } } - for (Iterator iter = getCrosscuttingMembersSet().getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) { + for (Iterator iter = getCrosscuttingMembersSet() + .getDeclareAnnotationOnTypes().iterator(); iter.hasNext();) { DeclareAnnotation decA = (DeclareAnnotation) iter.next(); boolean typeChanged = applyDeclareAtType(decA, onType, false); if (typeChanged) { diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index fd073f079..720626882 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -51,7 +51,7 @@ import org.aspectj.apache.bcel.generic.Type; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.weaver.AjAttribute; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.MemberImpl; @@ -134,8 +134,10 @@ public final class LazyMethodGen implements Traceable { public LazyMethodGen(int accessFlags, Type returnType, String name, Type[] paramTypes, String[] declaredExceptions, LazyClassGen enclosingClass) { - // System.err.println("raw create of: " + name + ", " + enclosingClass.getName() + ", " + returnType); - this.memberView = null; // ??? should be okay, since constructed ones aren't woven into + // System.err.println("raw create of: " + name + ", " + + // enclosingClass.getName() + ", " + returnType); + this.memberView = null; // ??? should be okay, since constructed ones + // aren't woven into this.accessFlags = accessFlags; this.returnType = returnType; this.name = name; @@ -154,8 +156,10 @@ public final class LazyMethodGen implements Traceable { // @AJ advice are not inlined by default since requires further analysis // and weaving ordering control - // TODO AV - improve - note: no room for improvement as long as aspects are reweavable - // since the inlined version with wrappers and an to be done annotation to keep + // TODO AV - improve - note: no room for improvement as long as aspects + // are reweavable + // since the inlined version with wrappers and an to be done annotation + // to keep // inline state will be garbaged due to reweavable impl if (memberView != null && isAdviceMethod()) { if (enclosingClass.getType().isAnnotationStyleAspect()) { @@ -177,7 +181,8 @@ public final class LazyMethodGen implements Traceable { private Method savedMethod = null; - // build from an existing method, lazy build saves most work for initialization + // build from an existing method, lazy build saves most work for + // initialization public LazyMethodGen(Method m, LazyClassGen enclosingClass) { savedMethod = m; @@ -195,8 +200,10 @@ public final class LazyMethodGen implements Traceable { // @AJ advice are not inlined by default since requires further analysis // and weaving ordering control - // TODO AV - improve - note: no room for improvement as long as aspects are reweavable - // since the inlined version with wrappers and an to be done annotation to keep + // TODO AV - improve - note: no room for improvement as long as aspects + // are reweavable + // since the inlined version with wrappers and an to be done annotation + // to keep // inline state will be garbaged due to reweavable impl if (memberView != null && isAdviceMethod()) { if (enclosingClass.getType().isAnnotationStyleAspect()) { @@ -215,15 +222,18 @@ public final class LazyMethodGen implements Traceable { if ((m.isAbstract() || m.isNative()) && savedMethod.getCode() != null) { throw new RuntimeException("bad abstract method with code: " + m + " on " + enclosingClass); } - // this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m); + // this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), + // m); this.memberView = m; this.accessFlags = savedMethod.getModifiers(); this.name = m.getName(); // @AJ advice are not inlined by default since requires further analysis // and weaving ordering control - // TODO AV - improve - note: no room for improvement as long as aspects are reweavable - // since the inlined version with wrappers and an to be done annotation to keep + // TODO AV - improve - note: no room for improvement as long as aspects + // are reweavable + // since the inlined version with wrappers and an to be done annotation + // to keep // inline state will be garbaged due to reweavable impl if (memberView != null && isAdviceMethod()) { if (enclosingClass.getType().isAnnotationStyleAspect()) { @@ -254,7 +264,7 @@ public final class LazyMethodGen implements Traceable { } } - public void addAnnotation(AnnotationX ax) { + public void addAnnotation(AnnotationAJ ax) { initialize(); if (memberView == null) { // If member view is null, we manage them in newAnnotations @@ -272,9 +282,10 @@ public final class LazyMethodGen implements Traceable { // Check local annotations first if (newAnnotations != null) { for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) { - AnnotationX element = (AnnotationX) iter.next(); - if (element.getBcelAnnotation().getTypeName().equals(annotationTypeX.getName())) + AnnotationAJ element = (AnnotationAJ) iter.next(); + if (element.getTypeSignature().equals(annotationTypeX.getSignature())) { return true; + } } } memberView = new BcelMethod(getEnclosingClass().getBcelObjectType(), getMethod()); @@ -287,7 +298,8 @@ public final class LazyMethodGen implements Traceable { if (returnType != null) return; - // System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + + // System.err.println("initializing: " + getName() + ", " + + // enclosingClass.getName() + ", " + returnType + ", " + // savedMethod); MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(), true); @@ -301,9 +313,12 @@ public final class LazyMethodGen implements Traceable { this.maxLocals = gen.getMaxLocals(); // this.returnType = BcelWorld.makeBcelType(memberView.getReturnType()); - // this.argumentTypes = BcelWorld.makeBcelTypes(memberView.getParameterTypes()); + // this.argumentTypes = + // BcelWorld.makeBcelTypes(memberView.getParameterTypes()); // - // this.declaredExceptions = UnresolvedType.getNames(memberView.getExceptions()); //gen.getExceptions(); + // this.declaredExceptions = + // UnresolvedType.getNames(memberView.getExceptions()); + // //gen.getExceptions(); // this.attributes = new Attribute[0]; //gen.getAttributes(); // this.maxLocals = savedMethod.getCode().getMaxLocals(); @@ -321,13 +336,17 @@ public final class LazyMethodGen implements Traceable { } assertGoodBody(); - // System.err.println("initialized: " + this.getClassName() + "." + this.getName()); + // System.err.println("initialized: " + this.getClassName() + "." + + // this.getName()); } - // XXX we're relying on the javac promise I've just made up that we won't have an early exception + // XXX we're relying on the javac promise I've just made up that we won't + // have an early exception // in the list mask a later exception: That is, for two exceptions E and F, - // if E preceeds F, then either E \cup F = {}, or E \nonstrictsubset F. So when we add F, - // we add it on the _OUTSIDE_ of any handlers that share starts or ends with it. + // if E preceeds F, then either E \cup F = {}, or E \nonstrictsubset F. So + // when we add F, + // we add it on the _OUTSIDE_ of any handlers that share starts or ends with + // it. // with that in mind, we merrily go adding ranges for exceptions. @@ -412,7 +431,8 @@ public final class LazyMethodGen implements Traceable { public Method getMethod() { if (savedMethod != null) - return savedMethod; // ??? this relies on gentle treatment of constant pool + return savedMethod; // ??? this relies on gentle treatment of + // constant pool try { MethodGen gen = pack(); @@ -423,7 +443,8 @@ public final class LazyMethodGen implements Traceable { IMessage.ERROR, WeaverMessages.format(WeaverMessages.PROBLEM_GENERATING_METHOD, this.getClassName(), this.getName(), e .getMessage()), this.getMemberView() == null ? null : this.getMemberView().getSourceLocation(), null); - // throw e; PR 70201.... let the normal problem reporting infrastructure deal with this rather than crashing. + // throw e; PR 70201.... let the normal problem reporting + // infrastructure deal with this rather than crashing. body = null; MethodGen gen = pack(); return gen.getMethod(); @@ -517,7 +538,8 @@ public final class LazyMethodGen implements Traceable { List as = Utility.readAjAttributes(getClassName(), (Attribute[]) attributes.toArray(new Attribute[] {}), context, null, weaverVersion); if (!as.isEmpty()) { - out.println(" " + as.get(0)); // XXX assuming exactly one attribute, munger... + out.println(" " + as.get(0)); // XXX assuming exactly one + // attribute, munger... } } @@ -555,7 +577,11 @@ public final class LazyMethodGen implements Traceable { for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) { Iterator tIter = ih.getTargeters().iterator(); while (tIter.hasNext()) { - InstructionTargeter t = (InstructionTargeter) tIter.next();// targeters[i]; + InstructionTargeter t = (InstructionTargeter) tIter.next();// targeters + // [ + // i + // ] + // ; if (t instanceof ExceptionRange) { // assert isRangeHandle(h); ExceptionRange r = (ExceptionRange) t; @@ -594,13 +620,15 @@ public final class LazyMethodGen implements Traceable { bodyPrint: for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) { if (Range.isRangeHandle(ih)) { Range r = Range.getRange(ih); - // don't print empty ranges, that is, ranges who contain no actual instructions + // don't print empty ranges, that is, ranges who contain no + // actual instructions for (InstructionHandle xx = r.getStart(); Range.isRangeHandle(xx); xx = xx.getNext()) { if (xx == r.getEnd()) continue bodyPrint; } - // doesn't handle nested: if (r.getStart().getNext() == r.getEnd()) continue; + // doesn't handle nested: if (r.getStart().getNext() == + // r.getEnd()) continue; if (r.getStart() == ih) { printRangeString(r, depth++); } else { @@ -691,7 +719,8 @@ public final class LazyMethodGen implements Traceable { out.print(" "); out.print(labelMap.get(brinst.getTarget())); } else if (inst.isLocalVariableInstruction()) { - // LocalVariableInstruction lvinst = (LocalVariableInstruction) inst; + // LocalVariableInstruction lvinst = (LocalVariableInstruction) + // inst; out.print(inst.toString(false).toUpperCase()); int index = inst.getIndex(); LocalVariableTag tag = getLocalVariableTag(h, index); @@ -864,15 +893,15 @@ public final class LazyMethodGen implements Traceable { if (newAnnotations != null) { for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) { - AnnotationX element = (AnnotationX) iter.next(); - gen.addAnnotation(new AnnotationGen(element.getBcelAnnotation(), gen.getConstantPool(), true)); + AnnotationAJ element = (AnnotationAJ) iter.next(); + gen.addAnnotation(new AnnotationGen(((BcelAnnotation)element).getBcelAnnotation(), gen.getConstantPool(), true)); } } if (memberView != null && memberView.getAnnotations() != null && memberView.getAnnotations().length != 0) { - AnnotationX[] ans = memberView.getAnnotations(); + AnnotationAJ[] ans = memberView.getAnnotations(); for (int i = 0, len = ans.length; i < len; i++) { - AnnotationGen a = ans[i].getBcelAnnotation(); + AnnotationGen a = ((BcelAnnotation) ans[i]).getBcelAnnotation(); gen.addAnnotation(new AnnotationGen(a, gen.getConstantPool(), true)); } } @@ -881,7 +910,8 @@ public final class LazyMethodGen implements Traceable { if (enclosingClass.getWorld().isInJava5Mode()) { gen.setModifiers(gen.getModifiers() | ACC_SYNTHETIC); } - // belt and braces, do the attribute even on Java 5 in addition to the modifier flag + // belt and braces, do the attribute even on Java 5 in addition to + // the modifier flag ConstantPool cpg = gen.getConstantPool(); int index = cpg.addUtf8("Synthetic"); gen.addAttribute(new Synthetic(index, 0, new byte[0], cpg)); @@ -950,7 +980,8 @@ public final class LazyMethodGen implements Traceable { while (oldInstructionHandle != null) { if (map.get(oldInstructionHandle) == null) { - // must be a range instruction since they're the only things we didn't copy across + // must be a range instruction since they're the only things we + // didn't copy across handleRangeInstruction(oldInstructionHandle, exceptionList); // just increment ih. oldInstructionHandle = oldInstructionHandle.getNext(); @@ -977,7 +1008,8 @@ public final class LazyMethodGen implements Traceable { } else if (targeter instanceof LocalVariableTag) { LocalVariableTag lvt = (LocalVariableTag) targeter; LVPosition p = (LVPosition) localVariables.get(lvt); - // If we don't know about it, create a new position and store + // If we don't know about it, create a new position and + // store // If we do know about it - update its end position if (p == null) { LVPosition newp = new LVPosition(); @@ -998,10 +1030,13 @@ public final class LazyMethodGen implements Traceable { addExceptionHandlers(gen, map, exceptionList); addLocalVariables(gen, localVariables); - // JAVAC adds line number tables (with just one entry) to generated accessor methods - this - // keeps some tools that rely on finding at least some form of linenumbertable happy. + // JAVAC adds line number tables (with just one entry) to generated + // accessor methods - this + // keeps some tools that rely on finding at least some form of + // linenumbertable happy. // Let's check if we have one - if we don't then let's add one. - // TODO Could be made conditional on whether line debug info is being produced + // TODO Could be made conditional on whether line debug info is being + // produced if (gen.getLineNumbers().length == 0) { gen.addLineNumber(gen.getInstructionList().getStart(), 1); } @@ -1021,18 +1056,21 @@ public final class LazyMethodGen implements Traceable { LinkedList exceptionList = new LinkedList(); Set forDeletion = new HashSet(); Set branchInstructions = new HashSet(); - // OPTIMIZE sort out in here: getRange()/insertHandler() and type of exceptionList + // OPTIMIZE sort out in here: getRange()/insertHandler() and type of + // exceptionList while (iHandle != null) { Instruction inst = iHandle.getInstruction(); // InstructionHandle nextInst = iHandle.getNext(); - // OPTIMIZE remove this instructionhandle as it now points to nowhere? + // OPTIMIZE remove this instructionhandle as it now points to + // nowhere? if (inst == Range.RANGEINSTRUCTION) { Range r = Range.getRange(iHandle); if (r instanceof ExceptionRange) { ExceptionRange er = (ExceptionRange) r; if (er.getStart() == iHandle) { if (!er.isEmpty()) { - // order is important, insert handlers in order of start + // order is important, insert handlers in order of + // start insertHandler(er, exceptionList); } } @@ -1056,7 +1094,8 @@ public final class LazyMethodGen implements Traceable { } else if (targeter instanceof LocalVariableTag) { LocalVariableTag lvt = (LocalVariableTag) targeter; LVPosition p = (LVPosition) localVariables.get(lvt); - // If we don't know about it, create a new position and store + // If we don't know about it, create a new position + // and store // If we do know about it - update its end position if (p == null) { LVPosition newp = new LVPosition(); @@ -1095,10 +1134,13 @@ public final class LazyMethodGen implements Traceable { gen.setInstructionList(theBody); addLocalVariables(gen, localVariables); - // JAVAC adds line number tables (with just one entry) to generated accessor methods - this - // keeps some tools that rely on finding at least some form of linenumbertable happy. + // JAVAC adds line number tables (with just one entry) to generated + // accessor methods - this + // keeps some tools that rely on finding at least some form of + // linenumbertable happy. // Let's check if we have one - if we don't then let's add one. - // TODO Could be made conditional on whether line debug info is being produced + // TODO Could be made conditional on whether line debug info is being + // produced if (gen.getLineNumbers().length == 0) { gen.addLineNumber(gen.getInstructionList().getStart(), 1); } @@ -1117,7 +1159,8 @@ public final class LazyMethodGen implements Traceable { Map duplicatedLocalMap = new HashMap(); for (Iterator iter = localVariables.keySet().iterator(); iter.hasNext();) { LocalVariableTag tag = (LocalVariableTag) iter.next(); - // have we already added one with the same slot number and start location? + // have we already added one with the same slot number and start + // location? // if so, just continue. LVPosition lvpos = (LVPosition) localVariables.get(tag); InstructionHandle start = lvpos.start; @@ -1155,7 +1198,8 @@ public final class LazyMethodGen implements Traceable { private void handleBranchInstruction(Map map, Instruction oldInstruction, Instruction newInstruction) { InstructionBranch oldBranchInstruction = (InstructionBranch) oldInstruction; InstructionBranch newBranchInstruction = (InstructionBranch) newInstruction; - InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target + InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old + // target // New target is in hash map newBranchInstruction.setTarget(remap(oldTarget, map)); @@ -1301,18 +1345,24 @@ public final class LazyMethodGen implements Traceable { // block (pr78021,pr79554). // exception ordering. - // What we should be doing is dealing with priority inversions way earlier than we are - // and counting on the tree structure. In which case, the below code is in fact right. + // What we should be doing is dealing with priority inversions way earlier + // than we are + // and counting on the tree structure. In which case, the below code is in + // fact right. // XXX THIS COMMENT BELOW IS CURRENTLY WRONG. // An exception A preceeds an exception B in the exception table iff: - // * A and B were in the original method, and A preceeded B in the original exception table + // * A and B were in the original method, and A preceeded B in the original + // exception table // * If A has a higher priority than B, than it preceeds B. - // * If A and B have the same priority, then the one whose START happens EARLIEST has LEAST priority. + // * If A and B have the same priority, then the one whose START happens + // EARLIEST has LEAST priority. // in short, the outermost exception has least priority. - // we implement this with a LinkedList. We could possibly implement this with a java.util.SortedSet, - // but I don't trust the only implementation, TreeSet, to do the right thing. + // we implement this with a LinkedList. We could possibly implement this + // with a java.util.SortedSet, + // but I don't trust the only implementation, TreeSet, to do the right + // thing. /* private */static void insertHandler(ExceptionRange fresh, LinkedList l) { // Old implementation, simply: l.add(0,fresh); @@ -1369,8 +1419,11 @@ public final class LazyMethodGen implements Traceable { public void assertGoodBody() { if (true) - return; // only enable for debugging, consider using cheaper toString() - assertGoodBody(getBody(), toString()); // definingType.getNameAsIdentifier() + "." + getName()); //toString()); + return; // only enable for debugging, consider using cheaper + // toString() + assertGoodBody(getBody(), toString()); // definingType.getNameAsIdentifier + // () + "." + getName()); + // //toString()); } public static void assertGoodBody(InstructionList il, String from) { diff --git a/weaver/src/org/aspectj/weaver/bcel/Utility.java b/weaver/src/org/aspectj/weaver/bcel/Utility.java index 901168efb..52d46b6c0 100644 --- a/weaver/src/org/aspectj/weaver/bcel/Utility.java +++ b/weaver/src/org/aspectj/weaver/bcel/Utility.java @@ -54,7 +54,7 @@ import org.aspectj.apache.bcel.generic.TargetLostException; import org.aspectj.apache.bcel.generic.Type; import org.aspectj.bridge.ISourceLocation; import org.aspectj.weaver.AjAttribute; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.Lint; @@ -112,7 +112,8 @@ public class Utility { if (isl == null || isl.getSourceFile() == null || isl.getSourceFile().getName().indexOf("no debug info available") != -1) { nice.append("no debug info available"); } else { - // can't use File.getName() as this fails when a Linux box encounters a path created on Windows and vice-versa + // can't use File.getName() as this fails when a Linux box + // encounters a path created on Windows and vice-versa int takeFrom = isl.getSourceFile().getPath().lastIndexOf('/'); if (takeFrom == -1) { takeFrom = isl.getSourceFile().getPath().lastIndexOf('\\'); @@ -268,7 +269,8 @@ public class Utility { private static String[] argNames = new String[] { "arg0", "arg1", "arg2", "arg3", "arg4" }; - // ??? these should perhaps be cached. Remember to profile this to see if it's a problem. + // ??? these should perhaps be cached. Remember to profile this to see if + // it's a problem. public static String[] makeArgNames(int n) { String[] ret = new String[n]; for (int i = 0; i < n; i++) { @@ -308,7 +310,8 @@ public class Utility { if (!toType.isConvertableFrom(fromType) && !fromType.isConvertableFrom(toType)) { throw new BCException("can't convert from " + fromType + " to " + toType); } - // XXX I'm sure this test can be simpler but my brain hurts and this works + // XXX I'm sure this test can be simpler but my brain hurts and this + // works if (!toType.getWorld().isInJava5Mode()) { if (toType.needsNoConversionFrom(fromType)) return; @@ -339,7 +342,8 @@ public class Utility { il.append(fact.createInvoke("org.aspectj.runtime.internal.Conversions", name, Type.OBJECT, new Type[] { from }, Constants.INVOKESTATIC)); } else if (toType.getWorld().isInJava5Mode() && validBoxing.get(toType.getSignature() + fromType.getSignature()) != null) { - // XXX could optimize by using any java boxing code that may be just before the call... + // XXX could optimize by using any java boxing code that may be just + // before the call... Type from = BcelWorld.makeBcelType(fromType); Type to = BcelWorld.makeBcelType(toType); String name = (String) validBoxing.get(toType.getSignature() + fromType.getSignature()); @@ -598,7 +602,8 @@ public class Utility { } /** returns -1 if no source line attribute */ - // this naive version overruns the JVM stack size, if only Java understood tail recursion... + // this naive version overruns the JVM stack size, if only Java understood + // tail recursion... // public static int getSourceLine(InstructionHandle ih) { // if (ih == null) return -1; // @@ -613,9 +618,11 @@ public class Utility { // } // return getSourceLine(ih.getNext()); // } - public static int getSourceLine(InstructionHandle ih) {// ,boolean goforwards) { + public static int getSourceLine(InstructionHandle ih) {// ,boolean + // goforwards) { int lookahead = 0; - // arbitrary rule that we will never lookahead more than 100 instructions for a line # + // arbitrary rule that we will never lookahead more than 100 + // instructions for a line # while (lookahead++ < 100) { if (ih == null) return -1; @@ -637,9 +644,11 @@ public class Utility { // return getSourceLine(ih,false); // } - // assumes that there is no already extant source line tag. Otherwise we'll have to be better. + // assumes that there is no already extant source line tag. Otherwise we'll + // have to be better. public static void setSourceLine(InstructionHandle ih, int lineNumber) { - // OPTIMIZE LineNumberTag instances for the same line could be shared throughout a method... + // OPTIMIZE LineNumberTag instances for the same line could be shared + // throughout a method... ih.addTargeter(new LineNumberTag(lineNumber)); } @@ -687,18 +696,19 @@ public class Utility { * (identified by its key) should be ignored. * */ - public static boolean isSuppressing(AnnotationX[] anns, String lintkey) { + public static boolean isSuppressing(AnnotationAJ[] anns, String lintkey) { if (anns == null) return false; boolean suppressed = false; // Go through the annotation types on the advice for (int i = 0; !suppressed && i < anns.length; i++) { // Check for the SuppressAjWarnings annotation - if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) { + if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getTypeSignature())) { // Two possibilities: // 1. there are no values specified (i.e. @SuppressAjWarnings) - // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"}) - List vals = anns[i].getBcelAnnotation().getValues(); + // 2. there are values specified (i.e. @SuppressAjWarnings("A") + // or @SuppressAjWarnings({"A","B"}) + List vals = ((BcelAnnotation) anns[i]).getBcelAnnotation().getValues(); if (vals == null || vals.isEmpty()) { // (1) suppressed = true; } else { // (2) @@ -718,7 +728,7 @@ public class Utility { return suppressed; } - public static List/* Lint.Kind */getSuppressedWarnings(AnnotationX[] anns, Lint lint) { + public static List/* Lint.Kind */getSuppressedWarnings(AnnotationAJ[] anns, Lint lint) { if (anns == null) return Collections.EMPTY_LIST; // Go through the annotation types @@ -726,12 +736,14 @@ public class Utility { boolean found = false; for (int i = 0; !found && i < anns.length; i++) { // Check for the SuppressAjWarnings annotation - if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals(anns[i].getBcelAnnotation().getTypeSignature())) { + if (UnresolvedType.SUPPRESS_AJ_WARNINGS.getSignature().equals( + ((BcelAnnotation) anns[i]).getBcelAnnotation().getTypeSignature())) { found = true; // Two possibilities: // 1. there are no values specified (i.e. @SuppressAjWarnings) - // 2. there are values specified (i.e. @SuppressAjWarnings("A") or @SuppressAjWarnings({"A","B"}) - List vals = anns[i].getBcelAnnotation().getValues(); + // 2. there are values specified (i.e. @SuppressAjWarnings("A") + // or @SuppressAjWarnings({"A","B"}) + List vals = ((BcelAnnotation) anns[i]).getBcelAnnotation().getValues(); if (vals == null || vals.isEmpty()) { // (1) suppressedWarnings.addAll(lint.allKinds()); } else { // (2) @@ -755,18 +767,21 @@ public class Utility { // public static boolean isSimple(Method method) { // if (method.getCode()==null) return true; // if (method.getCode().getCode().length>10) return false; - // InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive! + // InstructionList instrucs = new + // InstructionList(method.getCode().getCode()); // expensive! // InstructionHandle InstrHandle = instrucs.getStart(); // while (InstrHandle != null) { // Instruction Instr = InstrHandle.getInstruction(); // int opCode = Instr.opcode; - // // if current instruction is a branch instruction, see if it's a backward branch. + // // if current instruction is a branch instruction, see if it's a backward + // branch. // // if it is return immediately (can't be trivial) // if (Instr instanceof InstructionBranch) { // // InstructionBranch BI = (InstructionBranch) Instr; // if (Instr.getIndex() < 0) return false; // } else if (Instr instanceof InvokeInstruction) { - // // if current instruction is an invocation, indicate that it can't be trivial + // // if current instruction is an invocation, indicate that it can't be + // trivial // return false; // } // InstrHandle = InstrHandle.getNext(); diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java b/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java index e1ecb777c..3958566be 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java @@ -18,7 +18,7 @@ import java.util.Iterator; import java.util.Map; import org.aspectj.bridge.MessageUtil; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ResolvedMember; import org.aspectj.weaver.ResolvedType; @@ -28,111 +28,124 @@ import org.aspectj.weaver.WeaverMessages; import org.aspectj.weaver.World; public class DeclareAnnotation extends Declare { - - public static final Kind AT_TYPE = new Kind(1,"type"); - public static final Kind AT_FIELD = new Kind(2,"field"); - public static final Kind AT_METHOD = new Kind(3,"method"); - public static final Kind AT_CONSTRUCTOR = new Kind(4,"constructor"); - + + public static final Kind AT_TYPE = new Kind(1, "type"); + public static final Kind AT_FIELD = new Kind(2, "field"); + public static final Kind AT_METHOD = new Kind(3, "method"); + public static final Kind AT_CONSTRUCTOR = new Kind(4, "constructor"); + private Kind kind; - private TypePattern typePattern; // for declare @type - private SignaturePattern sigPattern; // for declare @field,@method,@constructor + private TypePattern typePattern; // for declare @type + private SignaturePattern sigPattern; // for declare + // @field,@method,@constructor private String annotationMethod = "unknown"; private String annotationString = "@"; private ResolvedType containingAspect; - private AnnotationX annotation; - - /** - * Captures type of declare annotation (method/type/field/constructor) - */ + private AnnotationAJ annotation; + + /** + * Captures type of declare annotation (method/type/field/constructor) + */ public static class Kind { private final int id; private String s; - - private Kind(int n,String name) { + + private Kind(int n, String name) { id = n; s = name; } - + public int hashCode() { - return (19 + 37*id); + return (19 + 37 * id); } - public boolean equals(Object obj) { - if (!(obj instanceof Kind)) return false; - Kind other = (Kind) obj; - return other.id == id; - } - - public String toString() { - return "at_"+s; - } - } + public boolean equals(Object obj) { + if (!(obj instanceof Kind)) + return false; + Kind other = (Kind) obj; + return other.id == id; + } - + public String toString() { + return "at_" + s; + } + } public DeclareAnnotation(Kind kind, TypePattern typePattern) { this.typePattern = typePattern; this.kind = kind; } - - /** - * Returns the string, useful before the real annotation has been resolved - */ - public String getAnnotationString() { return annotationString;} - + + /** + * Returns the string, useful before the real annotation has been resolved + */ + public String getAnnotationString() { + return annotationString; + } + public DeclareAnnotation(Kind kind, SignaturePattern sigPattern) { this.sigPattern = sigPattern; this.kind = kind; } - + public boolean isExactPattern() { return typePattern instanceof ExactTypePattern; } - - public String getAnnotationMethod() { return annotationMethod;} - + + public String getAnnotationMethod() { + return annotationMethod; + } + public String toString() { StringBuffer ret = new StringBuffer(); ret.append("declare @"); ret.append(kind); ret.append(" : "); - ret.append(typePattern != null ? typePattern.toString() : sigPattern.toString()); + ret.append(typePattern != null ? typePattern.toString() : sigPattern + .toString()); ret.append(" : "); ret.append(annotationString); return ret.toString(); } - + public Object accept(PatternNodeVisitor visitor, Object data) { - return visitor.visit(this,data); + return visitor.visit(this, data); } - + public void resolve(IScope scope) { if (!scope.getWorld().isInJava5Mode()) { String msg = null; - if (kind == AT_TYPE) { msg = WeaverMessages.DECLARE_ATTYPE_ONLY_SUPPORTED_AT_JAVA5_LEVEL; } - else if (kind == AT_METHOD) { msg = WeaverMessages.DECLARE_ATMETHOD_ONLY_SUPPORTED_AT_JAVA5_LEVEL;} - else if (kind == AT_FIELD) { msg = WeaverMessages.DECLARE_ATFIELD_ONLY_SUPPORTED_AT_JAVA5_LEVEL;} - else if (kind == AT_CONSTRUCTOR) { msg = WeaverMessages.DECLARE_ATCONS_ONLY_SUPPORTED_AT_JAVA5_LEVEL;} + if (kind == AT_TYPE) { + msg = WeaverMessages.DECLARE_ATTYPE_ONLY_SUPPORTED_AT_JAVA5_LEVEL; + } else if (kind == AT_METHOD) { + msg = WeaverMessages.DECLARE_ATMETHOD_ONLY_SUPPORTED_AT_JAVA5_LEVEL; + } else if (kind == AT_FIELD) { + msg = WeaverMessages.DECLARE_ATFIELD_ONLY_SUPPORTED_AT_JAVA5_LEVEL; + } else if (kind == AT_CONSTRUCTOR) { + msg = WeaverMessages.DECLARE_ATCONS_ONLY_SUPPORTED_AT_JAVA5_LEVEL; + } scope.message(MessageUtil.error(WeaverMessages.format(msg), getSourceLocation())); return; } if (typePattern != null) { - typePattern = typePattern.resolveBindings(scope,Bindings.NONE,false,false); + typePattern = typePattern.resolveBindings(scope, Bindings.NONE, + false, false); } if (sigPattern != null) { - sigPattern = sigPattern.resolveBindings(scope,Bindings.NONE); + sigPattern = sigPattern.resolveBindings(scope, Bindings.NONE); } this.containingAspect = scope.getEnclosingType(); } - public Declare parameterizeWith(Map typeVariableBindingMap,World w) { + public Declare parameterizeWith(Map typeVariableBindingMap, World w) { DeclareAnnotation ret; if (this.kind == AT_TYPE) { - ret = new DeclareAnnotation(kind,this.typePattern.parameterizeWith(typeVariableBindingMap,w)); + ret = new DeclareAnnotation(kind, this.typePattern + .parameterizeWith(typeVariableBindingMap, w)); } else { - ret = new DeclareAnnotation(kind, this.sigPattern.parameterizeWith(typeVariableBindingMap,w)); + ret = new DeclareAnnotation(kind, this.sigPattern.parameterizeWith( + typeVariableBindingMap, w)); } ret.annotationMethod = this.annotationMethod; ret.annotationString = this.annotationString; @@ -141,7 +154,7 @@ public class DeclareAnnotation extends Declare { ret.copyLocationFrom(this); return ret; } - + public boolean isAdviceLike() { return false; } @@ -149,49 +162,60 @@ public class DeclareAnnotation extends Declare { public void setAnnotationString(String as) { this.annotationString = as; } - - public void setAnnotationMethod(String methName){ + + public void setAnnotationMethod(String methName) { this.annotationMethod = methName; } - - - + public boolean equals(Object obj) { - if (!(obj instanceof DeclareAnnotation)) return false; + if (!(obj instanceof DeclareAnnotation)) + return false; DeclareAnnotation other = (DeclareAnnotation) obj; - if (!this.kind.equals(other.kind)) return false; - if (!this.annotationString.equals(other.annotationString)) return false; - if (!this.annotationMethod.equals(other.annotationMethod)) return false; + if (!this.kind.equals(other.kind)) + return false; + if (!this.annotationString.equals(other.annotationString)) + return false; + if (!this.annotationMethod.equals(other.annotationMethod)) + return false; if (this.typePattern != null) { - if (!typePattern.equals(other.typePattern)) return false; + if (!typePattern.equals(other.typePattern)) + return false; } if (this.sigPattern != null) { - if (!sigPattern.equals(other.sigPattern)) return false; + if (!sigPattern.equals(other.sigPattern)) + return false; } return true; } - + public int hashCode() { - int result = 19; - result = 37*result + kind.hashCode(); - result = 37*result + annotationString.hashCode(); - result = 37*result + annotationMethod.hashCode(); - if (typePattern != null) result = 37*result + typePattern.hashCode(); - if (sigPattern != null) result = 37*result + sigPattern.hashCode(); - return result; - } - - /* (non-Javadoc) - * @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream) + int result = 19; + result = 37 * result + kind.hashCode(); + result = 37 * result + annotationString.hashCode(); + result = 37 * result + annotationMethod.hashCode(); + if (typePattern != null) + result = 37 * result + typePattern.hashCode(); + if (sigPattern != null) + result = 37 * result + sigPattern.hashCode(); + return result; + } + + /* + * (non-Javadoc) + * + * @see + * org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream) */ public void write(DataOutputStream s) throws IOException { s.writeByte(Declare.ANNOTATION); s.writeInt(kind.id); s.writeUTF(annotationString); s.writeUTF(annotationMethod); - if (typePattern != null) typePattern.write(s); - if (sigPattern != null) sigPattern.write(s); - writeLocation(s); + if (typePattern != null) + typePattern.write(s); + if (sigPattern != null) + sigPattern.write(s); + writeLocation(s); } public static Declare read(VersionedDataInputStream s, @@ -203,61 +227,60 @@ public class DeclareAnnotation extends Declare { TypePattern tp = null; SignaturePattern sp = null; switch (kind) { - case 1: - tp = TypePattern.read(s,context); - ret = new DeclareAnnotation(AT_TYPE,tp); + case 1: + tp = TypePattern.read(s, context); + ret = new DeclareAnnotation(AT_TYPE, tp); break; - case 2: - sp = SignaturePattern.read(s,context); - ret = new DeclareAnnotation(AT_FIELD,sp); + case 2: + sp = SignaturePattern.read(s, context); + ret = new DeclareAnnotation(AT_FIELD, sp); break; - case 3: - sp = SignaturePattern.read(s,context); - ret = new DeclareAnnotation(AT_METHOD,sp); + case 3: + sp = SignaturePattern.read(s, context); + ret = new DeclareAnnotation(AT_METHOD, sp); break; - case 4: - sp = SignaturePattern.read(s,context); - ret = new DeclareAnnotation(AT_CONSTRUCTOR,sp); + case 4: + sp = SignaturePattern.read(s, context); + ret = new DeclareAnnotation(AT_CONSTRUCTOR, sp); break; - + } -// if (kind==AT_TYPE.id) { -// tp = TypePattern.read(s,context); -// ret = new DeclareAnnotation(AT_TYPE,tp); -// } else { -// sp = SignaturePattern.read(s,context); -// ret = new DeclareAnnotation(kind,sp); -// } + // if (kind==AT_TYPE.id) { + // tp = TypePattern.read(s,context); + // ret = new DeclareAnnotation(AT_TYPE,tp); + // } else { + // sp = SignaturePattern.read(s,context); + // ret = new DeclareAnnotation(kind,sp); + // } ret.setAnnotationString(annotationString); ret.setAnnotationMethod(annotationMethod); - ret.readLocation(context,s); + ret.readLocation(context, s); return ret; } + // public boolean getAnnotationIfMatches(ResolvedType onType) { + // return (match(onType)); + // } -// public boolean getAnnotationIfMatches(ResolvedType onType) { -// return (match(onType)); -// } - - - /** - * For @constructor, @method, @field - */ - public boolean matches(ResolvedMember rm,World world) { - return sigPattern.matches(rm,world,false); + /** + * For @constructor, @method, @field + */ + public boolean matches(ResolvedMember rm, World world) { + return sigPattern.matches(rm, world, false); } - - /** - * For @type - */ + + /** + * For @type + */ public boolean matches(ResolvedType typeX) { - if (!typePattern.matchesStatically(typeX)) return false; - if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() && - !typeX.isExposedToWeaver()) - { - typeX.getWorld().getLint().typeNotExposedToWeaver.signal(typeX.getName(), getSourceLocation()); + if (!typePattern.matchesStatically(typeX)) + return false; + if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() + && !typeX.isExposedToWeaver()) { + typeX.getWorld().getLint().typeNotExposedToWeaver.signal(typeX + .getName(), getSourceLocation()); } - return true; + return true; } public void setAspect(ResolvedType typeX) { @@ -270,47 +293,49 @@ public class DeclareAnnotation extends Declare { public void copyAnnotationTo(ResolvedType onType) { ensureAnnotationDiscovered(); - if (!onType.hasAnnotation(annotation.getSignature())) { - onType.addAnnotation(annotation); + if (!onType.hasAnnotation(annotation.getType())) { + onType.addAnnotation(annotation); } } - - public AnnotationX getAnnotationX() { + + public AnnotationAJ getAnnotationX() { ensureAnnotationDiscovered(); return annotation; } - /** - * The annotation specified in the declare @type is stored against - * a simple method of the form "ajc$declare_", this method - * finds that method and retrieves the annotation + * The annotation specified in the declare @type is stored against a simple + * method of the form "ajc$declare_", this method finds that method and + * retrieves the annotation */ private void ensureAnnotationDiscovered() { - if (annotation!=null) return; + if (annotation != null) + return; for (Iterator iter = containingAspect.getMethods(); iter.hasNext();) { ResolvedMember member = (ResolvedMember) iter.next(); if (member.getName().equals(annotationMethod)) { annotation = member.getAnnotations()[0]; - } + } } } public TypePattern getTypePattern() { return typePattern; } - + public SignaturePattern getSignaturePattern() { return sigPattern; } - + public boolean isStarredAnnotationPattern() { - if (typePattern!=null) return typePattern.isStarAnnotation(); - if (sigPattern!=null) return sigPattern.isStarAnnotation(); - throw new RuntimeException("Impossible! what kind of deca is this: "+this); + if (typePattern != null) + return typePattern.isStarAnnotation(); + if (sigPattern != null) + return sigPattern.isStarAnnotation(); + throw new RuntimeException("Impossible! what kind of deca is this: " + + this); } - public Kind getKind() { return kind; } @@ -318,61 +343,66 @@ public class DeclareAnnotation extends Declare { public boolean isDeclareAtConstuctor() { return kind.equals(AT_CONSTRUCTOR); } + public boolean isDeclareAtMethod() { return kind.equals(AT_METHOD); } + public boolean isDeclareAtType() { return kind.equals(AT_TYPE); } + public boolean isDeclareAtField() { return kind.equals(AT_FIELD); } - /** - * @return UnresolvedType for the annotation - */ + /** + * @return UnresolvedType for the annotation + */ public UnresolvedType getAnnotationTypeX() { - ensureAnnotationDiscovered(); - return this.annotation.getSignature(); + ensureAnnotationDiscovered(); + return this.annotation.getType(); } /** * @return true if the annotation specified is allowed on a field */ public boolean isAnnotationAllowedOnField() { - ensureAnnotationDiscovered(); + ensureAnnotationDiscovered(); return annotation.allowedOnField(); } public String getPatternAsString() { - if (sigPattern!=null) return sigPattern.toString(); - if (typePattern!=null) return typePattern.toString(); - return "DONT KNOW"; + if (sigPattern != null) + return sigPattern.toString(); + if (typePattern != null) + return typePattern.toString(); + return "DONT KNOW"; } /** - * Return true if this declare annotation could ever match something - * in the specified type - only really able to make intelligent - * decision if a type was specified in the sig/type pattern - * signature. + * Return true if this declare annotation could ever match something in the + * specified type - only really able to make intelligent decision if a type + * was specified in the sig/type pattern signature. */ public boolean couldEverMatch(ResolvedType type) { - // Haven't implemented variant for typePattern (doesn't seem worth it!) - // BUGWARNING This test might not be sufficient for funny cases relating + // Haven't implemented variant for typePattern (doesn't seem worth it!) + // BUGWARNING This test might not be sufficient for funny cases relating // to interfaces and the use of '+' - but it seems really important to // do something here so we don't iterate over all fields and all methods - // in all types exposed to the weaver! So look out for bugs here and + // in all types exposed to the weaver! So look out for bugs here and // we can update the test as appropriate. - if (sigPattern!=null) - return sigPattern.getDeclaringType().matches(type,TypePattern.STATIC).maybeTrue(); + if (sigPattern != null) + return sigPattern.getDeclaringType().matches(type, + TypePattern.STATIC).maybeTrue(); return true; } - + /** - * Provide a name suffix so that we can tell the different declare annotations - * forms apart in the AjProblemReporter + * Provide a name suffix so that we can tell the different declare + * annotations forms apart in the AjProblemReporter */ public String getNameSuffix() { - return getKind().toString(); + return getKind().toString(); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java index 93e40b4be..539dc6bb7 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java @@ -20,7 +20,7 @@ import org.aspectj.bridge.IMessage; import org.aspectj.bridge.MessageUtil; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.AnnotatedElement; -import org.aspectj.weaver.AnnotationX; +import org.aspectj.weaver.AnnotationAJ; import org.aspectj.weaver.BCException; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ReferenceType; @@ -43,14 +43,16 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { protected boolean resolved = false; protected boolean bindingPattern = false; private Map annotationValues; - - // OPTIMIZE is annotationtype really unresolved???? surely it is resolved by now... - public ExactAnnotationTypePattern(UnresolvedType annotationType, Map annotationValues) { + + // OPTIMIZE is annotationtype really unresolved???? surely it is resolved by + // now... + public ExactAnnotationTypePattern(UnresolvedType annotationType, + Map annotationValues) { this.annotationType = annotationType; this.annotationValues = annotationValues; this.resolved = (annotationType instanceof ResolvedType); } - + // Used when deserializing, values will be added private ExactAnnotationTypePattern(UnresolvedType annotationType) { this.annotationType = annotationType; @@ -65,114 +67,144 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { } public ResolvedType getResolvedAnnotationType() { - if (!resolved) throw new IllegalStateException("I need to be resolved first!"); + if (!resolved) + throw new IllegalStateException("I need to be resolved first!"); return (ResolvedType) annotationType; } - - public UnresolvedType getAnnotationType() { - return annotationType; - } - - public Map getAnnotationValues() { - return annotationValues; - } + + public UnresolvedType getAnnotationType() { + return annotationType; + } + + public Map getAnnotationValues() { + return annotationValues; + } public FuzzyBoolean fastMatches(AnnotatedElement annotated) { if (annotated.hasAnnotation(annotationType) && annotationValues == null) { return FuzzyBoolean.YES; } else { - // could be inherited, but we don't know that until we are + // could be inherited, but we don't know that until we are // resolved, and we're not yet... return FuzzyBoolean.MAYBE; } } - + public FuzzyBoolean matches(AnnotatedElement annotated) { - return matches(annotated,null); + return matches(annotated, null); } - - public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) { + + public FuzzyBoolean matches(AnnotatedElement annotated, + ResolvedType[] parameterAnnotations) { if (!isForParameterAnnotationMatch()) { boolean checkSupers = false; - if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) { + if (getResolvedAnnotationType().hasAnnotation( + UnresolvedType.AT_INHERITED)) { if (annotated instanceof ResolvedType) { checkSupers = true; } } - + if (annotated.hasAnnotation(annotationType)) { if (annotationType instanceof ReferenceType) { - ReferenceType rt = (ReferenceType)annotationType; - if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) { - rt.getWorld().getMessageHandler().handleMessage( - MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation())); + ReferenceType rt = (ReferenceType) annotationType; + if (rt.getRetentionPolicy() != null + && rt.getRetentionPolicy().equals("SOURCE")) { + rt + .getWorld() + .getMessageHandler() + .handleMessage( + MessageUtil + .warn( + WeaverMessages + .format( + WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION, + annotationType, + annotated), + getSourceLocation())); return FuzzyBoolean.NO; } } - - + // Are we also matching annotation values? - if (annotationValues!=null) { - AnnotationX theAnnotation = annotated.getAnnotationOfType(annotationType); - + if (annotationValues != null) { + AnnotationAJ theAnnotation = annotated + .getAnnotationOfType(annotationType); + // Check each one Set keys = annotationValues.keySet(); for (Iterator keyIter = keys.iterator(); keyIter.hasNext();) { String k = (String) keyIter.next(); - String v = (String)annotationValues.get(k); + String v = (String) annotationValues.get(k); if (theAnnotation.hasNamedValue(k)) { - // Simple case, value is 'name=value' and the annotation specified the same thing - if (!theAnnotation.hasNameValuePair(k,v)) { + // Simple case, value is 'name=value' and the + // annotation specified the same thing + if (!theAnnotation.hasNameValuePair(k, v)) { return FuzzyBoolean.NO; - } + } } else { // Complex case, look at the default value - ResolvedMember[] ms = ((ResolvedType)annotationType).getDeclaredMethods(); + ResolvedMember[] ms = ((ResolvedType) annotationType) + .getDeclaredMethods(); boolean foundMatch = false; - for (int i=0; i VERSION) { - throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ"); + throw new BCException( + "ExactAnnotationTypePattern was written by a newer version of AspectJ"); } boolean isBindingPattern = s.readBoolean(); if (isBindingPattern) { ret = new ExactAnnotationTypePattern(s.readUTF()); } else { - ret = new ExactAnnotationTypePattern(UnresolvedType.read(s)); + ret = new ExactAnnotationTypePattern(UnresolvedType.read(s)); } - ret.readLocation(context,s); - if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160) { - if (s.readBoolean()) ret.setForParameterAnnotationMatch(); + ret.readLocation(context, s); + if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160) { + if (s.readBoolean()) + ret.setForParameterAnnotationMatch(); } - if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) { + if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) { int annotationValueCount = s.readInt(); - if (annotationValueCount>0) { + if (annotationValueCount > 0) { Map aValues = new HashMap(); - for (int i=0;i