aboutsummaryrefslogtreecommitdiffstats
path: root/weaver/src
diff options
context:
space:
mode:
authoraclement <aclement>2008-08-28 16:27:48 +0000
committeraclement <aclement>2008-08-28 16:27:48 +0000
commit1361ef2f8e345f0a6fc1f8d518d0c938228d8ad7 (patch)
treee6b7d126be7b05cc0e65f06e0db7c70c6e0f3b5e /weaver/src
parentc778fc5e3ccec7fc253fc7be2fe2247684ab7930 (diff)
downloadaspectj-1361ef2f8e345f0a6fc1f8d518d0c938228d8ad7.tar.gz
aspectj-1361ef2f8e345f0a6fc1f8d518d0c938228d8ad7.zip
removed unused code and chewed on by formatter
Diffstat (limited to 'weaver/src')
-rw-r--r--weaver/src/org/aspectj/weaver/ResolvedType.java3012
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelShadow.java5048
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/IfFinder.java56
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/PoliceExtensionUse.java87
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java234
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java246
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java399
7 files changed, 4212 insertions, 4870 deletions
diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java
index 79ede540a..0e910c047 100644
--- a/weaver/src/org/aspectj/weaver/ResolvedType.java
+++ b/weaver/src/org/aspectj/weaver/ResolvedType.java
@@ -11,7 +11,6 @@
* Alexandre Vasseur @AspectJ ITDs
* ******************************************************************/
-
package org.aspectj.weaver;
import java.lang.reflect.Modifier;
@@ -36,309 +35,290 @@ import org.aspectj.weaver.patterns.PerClause;
public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement {
- public static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0];
+ 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
// that may be attached to a type when it used as a parameter
public ResolvedType[] temporaryAnnotationTypes;
private ResolvedType[] resolvedTypeParams;
private String binaryPath;
-
- protected World world;
-
- protected ResolvedType(String signature, World world) {
- super(signature);
- this.world = world;
- }
-
- protected ResolvedType(String signature, String signatureErasure, World world) {
- super(signature,signatureErasure);
- this.world = world;
- }
-
- // ---- 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.
- */
- public final Iterator getDirectSupertypes() {
- Iterator ifacesIterator = Iterators.array(getDeclaredInterfaces());
- ResolvedType superclass = getSuperclass();
- if (superclass == null) {
- return ifacesIterator;
- } else {
- return Iterators.snoc(ifacesIterator, superclass);
- }
- }
-
- public abstract ResolvedMember[] getDeclaredFields();
- public abstract ResolvedMember[] getDeclaredMethods();
- public abstract ResolvedType[] getDeclaredInterfaces();
- 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.
- */
- public abstract ResolvedType getSuperclass();
-
- /**
- * Returns the modifiers for this type.
- * <p/>
- * 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.
- * @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)
- public boolean isMissing() {
- return false;
- }
-
- // 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) {
- ResolvedType resolved = (ResolvedType)unresolved;
- return resolved.isMissing();
- }
- else return (unresolved == MISSING);
- }
-
- public ResolvedType[] getAnnotationTypes() {
- return EMPTY_RESOLVED_TYPE_ARRAY;
- }
-
- public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
- return null;
- }
-
- public final UnresolvedType getSuperclass(World world) {
- return getSuperclass();
- }
-
-
- // This set contains pairs of types whose signatures are concatenated
- // together, this means with a fast lookup we can tell if two types
- // are equivalent.
- protected static Set validBoxing = new HashSet();
-
- static {
- validBoxing.add("Ljava/lang/Byte;B");
- validBoxing.add("Ljava/lang/Character;C");
- validBoxing.add("Ljava/lang/Double;D");
- validBoxing.add("Ljava/lang/Float;F");
- validBoxing.add("Ljava/lang/Integer;I");
- validBoxing.add("Ljava/lang/Long;J");
- validBoxing.add("Ljava/lang/Short;S");
- validBoxing.add("Ljava/lang/Boolean;Z");
- validBoxing.add("BLjava/lang/Byte;");
- validBoxing.add("CLjava/lang/Character;");
- validBoxing.add("DLjava/lang/Double;");
- validBoxing.add("FLjava/lang/Float;");
- validBoxing.add("ILjava/lang/Integer;");
- validBoxing.add("JLjava/lang/Long;");
- validBoxing.add("SLjava/lang/Short;");
- validBoxing.add("ZLjava/lang/Boolean;");
- }
-
-
-
- // utilities
- public ResolvedType getResolvedComponentType() {
- return null;
- }
+
+ protected World world;
+
+ protected ResolvedType(String signature, World world) {
+ super(signature);
+ this.world = world;
+ }
+
+ protected ResolvedType(String signature, String signatureErasure, World world) {
+ super(signature, signatureErasure);
+ this.world = world;
+ }
+
+ // ---- 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.
+ */
+ public final Iterator getDirectSupertypes() {
+ Iterator ifacesIterator = Iterators.array(getDeclaredInterfaces());
+ ResolvedType superclass = getSuperclass();
+ if (superclass == null) {
+ return ifacesIterator;
+ } else {
+ return Iterators.snoc(ifacesIterator, superclass);
+ }
+ }
+
+ public abstract ResolvedMember[] getDeclaredFields();
+
+ public abstract ResolvedMember[] getDeclaredMethods();
+
+ public abstract ResolvedType[] getDeclaredInterfaces();
+
+ 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.
+ */
+ public abstract ResolvedType getSuperclass();
+
+ /**
+ * Returns the modifiers for this type. <p/> 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.
+ * @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)
+ public boolean isMissing() {
+ return false;
+ }
+
+ // 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) {
+ ResolvedType resolved = (ResolvedType) unresolved;
+ return resolved.isMissing();
+ } else
+ return (unresolved == MISSING);
+ }
+
+ public ResolvedType[] getAnnotationTypes() {
+ return EMPTY_RESOLVED_TYPE_ARRAY;
+ }
+
+ public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
+ return null;
+ }
+
+ public final UnresolvedType getSuperclass(World world) {
+ return getSuperclass();
+ }
+
+ // This set contains pairs of types whose signatures are concatenated
+ // together, this means with a fast lookup we can tell if two types
+ // are equivalent.
+ protected static Set validBoxing = new HashSet();
+
+ static {
+ validBoxing.add("Ljava/lang/Byte;B");
+ validBoxing.add("Ljava/lang/Character;C");
+ validBoxing.add("Ljava/lang/Double;D");
+ validBoxing.add("Ljava/lang/Float;F");
+ validBoxing.add("Ljava/lang/Integer;I");
+ validBoxing.add("Ljava/lang/Long;J");
+ validBoxing.add("Ljava/lang/Short;S");
+ validBoxing.add("Ljava/lang/Boolean;Z");
+ validBoxing.add("BLjava/lang/Byte;");
+ validBoxing.add("CLjava/lang/Character;");
+ validBoxing.add("DLjava/lang/Double;");
+ validBoxing.add("FLjava/lang/Float;");
+ validBoxing.add("ILjava/lang/Integer;");
+ validBoxing.add("JLjava/lang/Long;");
+ validBoxing.add("SLjava/lang/Short;");
+ validBoxing.add("ZLjava/lang/Boolean;");
+ }
+
+ // utilities
+ public ResolvedType getResolvedComponentType() {
+ return null;
+ }
public World getWorld() {
return world;
}
- // ---- things from object
-
- public final boolean equals(Object other) {
- if (other instanceof ResolvedType) {
- return this == other;
- } else {
- return super.equals(other);
- }
- }
-
- // ---- 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
- * <p/>
- * <ul><li> fields from current class </li>
- * <li> recur into direct superinterfaces </li>
- * <li> recur into superclass </li>
- * </ul>
- * <p/>
- * 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());
- }
- };
- Iterators.Getter fieldGetter = new Iterators.Getter() {
- public Iterator get(Object o) {
- return Iterators.array(((ResolvedType)o).getDeclaredFields());
- }
- };
- 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
- * <p/>
- * <ul><li> methods from current class </li>
- * <li> recur into superclass, all the way up, not touching interfaces </li>
- * <li> recur into all superinterfaces, in some unspecified order </li>
- * </ul>
- * <p/>
- * 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())
- );
- }
- };
- Iterators.Getter methodGetter = new Iterators.Getter() {
- public Iterator get(Object o) {
- return Iterators.array(((ResolvedType)o).getDeclaredMethods());
- }
- };
- return
- Iterators.mapOver(
- Iterators.append(
- new Iterator() {
- ResolvedType curr = ResolvedType.this;
- public boolean hasNext() {
- return curr != null;
- }
- public Object next() {
- ResolvedType ret = curr;
- curr = curr.getSuperclass();
- return ret;
- }
- public void remove() {
- throw new UnsupportedOperationException();
- }
- },
- Iterators.recur(this, ifaceGetter)),
- methodGetter);
- }
-
- /**
- * 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) {
- 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
- // 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();
+ // ---- things from object
+
+ public final boolean equals(Object other) {
+ if (other instanceof ResolvedType) {
+ return this == other;
+ } else {
+ return super.equals(other);
+ }
+ }
+
+ // ---- 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 <p/>
+ * <ul>
+ * <li>fields from current class</li>
+ * <li>recur into direct superinterfaces</li>
+ * <li>recur into superclass</li>
+ * </ul>
+ * <p/> 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());
+ }
+ };
+ Iterators.Getter fieldGetter = new Iterators.Getter() {
+ public Iterator get(Object o) {
+ return Iterators.array(((ResolvedType) o).getDeclaredFields());
+ }
+ };
+ 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 <p/>
+ * <ul>
+ * <li>methods from current class</li>
+ * <li>recur into superclass, all the way up, not touching interfaces</li>
+ * <li>recur into all superinterfaces, in some unspecified order</li>
+ * </ul>
+ * <p/> 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()));
+ }
+ };
+ Iterators.Getter methodGetter = new Iterators.Getter() {
+ public Iterator get(Object o) {
+ return Iterators.array(((ResolvedType) o).getDeclaredMethods());
+ }
+ };
+ return Iterators.mapOver(Iterators.append(new Iterator() {
+ ResolvedType curr = ResolvedType.this;
+
+ public boolean hasNext() {
+ return curr != null;
+ }
+
+ public Object next() {
+ ResolvedType ret = curr;
+ curr = curr.getSuperclass();
+ return ret;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }, Iterators.recur(this, ifaceGetter)), methodGetter);
+ }
+
+ /**
+ * 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) {
+ 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
+ // 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());
- }
+ }
+ }
+ }
+ 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
+ }
+ }
+ 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];
+
+ // we need to know if it is an interface from Parent kind munger
+ // 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
+ ) {
+ shouldSkip = true;
+ break;
+ }
+ }
+
+ 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();
+ }
+ } else {
+ addAndRecurse(knowninterfaces, collector, iface, includeITDs, allowMissing);
+ }
}
- }
- 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
- }
- }
- 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];
-
- // we need to know if it is an interface from Parent kind munger
- // 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
- ) {
- shouldSkip = true;
- break;
- }
- }
-
- 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();
- }
- } else {
- addAndRecurse(knowninterfaces,collector,iface,includeITDs,allowMissing);
- }
- }
- }
- }
-
- public ResolvedType[] getResolvedTypeParameters() {
- if (resolvedTypeParams == null) {
- resolvedTypeParams = world.resolve(typeParameters);
- }
- return resolvedTypeParams;
- }
-
- /**
- * described in JVM spec 2ed 5.4.3.2
- */
- public ResolvedMember lookupField(Member m) {
- return lookupMember(m, getFields());
- }
-
- /**
- * described in JVM spec 2ed 5.4.3.3.
- * Doesnt check ITDs.
- */
- public ResolvedMember lookupMethod(Member m) {
- return lookupMember(m, getMethods());
- }
-
- public ResolvedMember lookupMethodInITDs(Member m) {
- if (interTypeMungers != null) {
+ }
+ }
+
+ public ResolvedType[] getResolvedTypeParameters() {
+ if (resolvedTypeParams == null) {
+ resolvedTypeParams = world.resolve(typeParameters);
+ }
+ return resolvedTypeParams;
+ }
+
+ /**
+ * described in JVM spec 2ed 5.4.3.2
+ */
+ public ResolvedMember lookupField(Member m) {
+ return lookupMember(m, getFields());
+ }
+
+ /**
+ * described in JVM spec 2ed 5.4.3.3. Doesnt check ITDs.
+ */
+ public ResolvedMember lookupMethod(Member m) {
+ return lookupMember(m, getMethods());
+ }
+
+ public ResolvedMember lookupMethodInITDs(Member m) {
+ if (interTypeMungers != null) {
for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
if (matches(tm.getSignature(), m)) {
@@ -346,394 +326,389 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
}
}
- return null;
- }
-
- /**
- * return null if not found
- */
- private ResolvedMember lookupMember(Member m, Iterator i) {
- while (i.hasNext()) {
- 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 parameterized method (see pr137496)
- if (matches(f.getBackingGenericMember(),m)) return f;
- }
- }
- return null; //ResolvedMember.Missing;
- //throw new BCException("can't find " + m);
- }
-
- /**
- * return null if not found
- */
- private ResolvedMember lookupMember(Member m, ResolvedMember[] a) {
+ return null;
+ }
+
+ /**
+ * return null if not found
+ */
+ private ResolvedMember lookupMember(Member m, Iterator i) {
+ while (i.hasNext()) {
+ 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
+ // parameterized method (see pr137496)
+ if (matches(f.getBackingGenericMember(), m))
+ return f;
+ }
+ }
+ return null; // ResolvedMember.Missing;
+ // throw new BCException("can't find " + m);
+ }
+
+ /**
+ * return null if not found
+ */
+ private ResolvedMember lookupMember(Member m, ResolvedMember[] a) {
for (int i = 0; i < a.length; i++) {
ResolvedMember f = a[i];
- if (matches(f, m)) return f;
+ if (matches(f, m))
+ return f;
}
return null;
- }
-
-
- /**
- * 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) {
- Iterator toSearch = null;
- ResolvedMember found = null;
- 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());
- toSearch = getFields();
- }
- while(toSearch.hasNext()) {
- ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next();
+ }
+
+ /**
+ * 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) {
+ Iterator toSearch = null;
+ ResolvedMember found = null;
+ 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());
+ toSearch = getFields();
+ }
+ while (toSearch.hasNext()) {
+ ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next();
if (candidate.matches(aMember)) {
found = candidate;
break;
- }
- }
-
- return found;
- }
-
- public static boolean matches(Member m1, Member m2) {
- if (m1 == null) return m2 == null;
- if (m2 == null) return false;
-
- // Check the names
- boolean equalNames = m1.getName().equals(m2.getName());
- if (!equalNames) return false;
-
- // Check the signatures
- boolean equalSignatures = m1.getSignature().equals(m2.getSignature());
- if (equalSignatures) return true;
-
- // 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());
- if (equalCovariantSignatures) return true;
-
- return false;
- }
-
- public static boolean conflictingSignature(Member m1, Member m2) {
- if (m1 == null || m2 == null) return false;
-
- if (!m1.getName().equals(m2.getName())) {
- return false;
- }
- if (m1.getKind() != m2.getKind()) {
- return false;
- }
-
- if (m1.getKind() == Member.FIELD) {
- return m1.getDeclaringType().equals(m2.getDeclaringType());
- } else if (m1.getKind() == Member.POINTCUT) {
- return true;
- }
-
-
- UnresolvedType[] p1 = m1.getGenericParameterTypes();
- UnresolvedType[] p2 = m2.getGenericParameterTypes();
- if (p1==null) p1 = m1.getParameterTypes();
- if (p2==null) p2 = m2.getParameterTypes();
- int n = p1.length;
- if (n != p2.length) return false;
-
- for (int i=0; i < n; i++) {
- if (!p1[i].equals(p2[i])) return false;
- }
- return true;
- }
-
-
- /**
- * 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
- * <p/>
- * <ul><li> pointcuts from current class </li>
- * <li> recur into direct superinterfaces </li>
- * <li> recur into superclass </li>
- * </ul>
- * <p/>
- * 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());
- }
- };
- 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.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();
- //System.err.println(f);
- if (name.equals(f.getName())) {
- return f;
- }
- }
- // pr120521
- if (!getOutermostType().equals(this)) {
- ResolvedType outerType = getOutermostType().resolve(world);
- ResolvedPointcutDefinition rpd = outerType.findPointcut(name);
- return rpd;
- }
- return null; // should we throw an exception here?
- }
-
-
- // all about collecting CrosscuttingMembers
-
- //??? collecting data-structure, shouldn't really be a field
- public CrosscuttingMembers crosscuttingMembers;
+ }
+ }
+
+ return found;
+ }
+
+ public static boolean matches(Member m1, Member m2) {
+ if (m1 == null)
+ return m2 == null;
+ if (m2 == null)
+ return false;
+
+ // Check the names
+ boolean equalNames = m1.getName().equals(m2.getName());
+ if (!equalNames)
+ return false;
+
+ // Check the signatures
+ boolean equalSignatures = m1.getSignature().equals(m2.getSignature());
+ if (equalSignatures)
+ return true;
+
+ // 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());
+ if (equalCovariantSignatures)
+ return true;
+
+ return false;
+ }
+
+ public static boolean conflictingSignature(Member m1, Member m2) {
+ if (m1 == null || m2 == null)
+ return false;
+
+ if (!m1.getName().equals(m2.getName())) {
+ return false;
+ }
+ if (m1.getKind() != m2.getKind()) {
+ return false;
+ }
+
+ if (m1.getKind() == Member.FIELD) {
+ return m1.getDeclaringType().equals(m2.getDeclaringType());
+ } else if (m1.getKind() == Member.POINTCUT) {
+ return true;
+ }
+
+ UnresolvedType[] p1 = m1.getGenericParameterTypes();
+ UnresolvedType[] p2 = m2.getGenericParameterTypes();
+ if (p1 == null)
+ p1 = m1.getParameterTypes();
+ if (p2 == null)
+ p2 = m2.getParameterTypes();
+ int n = p1.length;
+ if (n != p2.length)
+ return false;
+
+ for (int i = 0; i < n; i++) {
+ if (!p1[i].equals(p2[i]))
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 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 <p/>
+ * <ul>
+ * <li>pointcuts from current class</li>
+ * <li>recur into direct superinterfaces</li>
+ * <li>recur into superclass</li>
+ * </ul>
+ * <p/> 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());
+ }
+ };
+ 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.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();
+ // System.err.println(f);
+ if (name.equals(f.getName())) {
+ return f;
+ }
+ }
+ // pr120521
+ if (!getOutermostType().equals(this)) {
+ ResolvedType outerType = getOutermostType().resolve(world);
+ ResolvedPointcutDefinition rpd = outerType.findPointcut(name);
+ return rpd;
+ }
+ return null; // should we throw an exception here?
+ }
+
+ // all about collecting CrosscuttingMembers
+
+ // ??? collecting data-structure, shouldn't really be a field
+ public CrosscuttingMembers crosscuttingMembers;
public CrosscuttingMembers collectCrosscuttingMembers(boolean shouldConcretizeIfNeeded) {
- crosscuttingMembers = new CrosscuttingMembers(this,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.addTypeMungers(collectTypeMungers());
+ crosscuttingMembers.addTypeMungers(getTypeMungers());
+ // 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;
}
-
+
public final Collection collectTypeMungers() {
- if (! this.isAspect() ) return Collections.EMPTY_LIST;
-
+ if (!this.isAspect())
+ return Collections.EMPTY_LIST;
+
ArrayList ret = new ArrayList();
- //if (this.isAbstract()) {
-// for (Iterator i = getDeclares().iterator(); i.hasNext();) {
-// Declare dec = (Declare) i.next();
-// if (!dec.isAdviceLike()) ret.add(dec);
-// }
-//
-// if (!includeAdviceLike) return ret;
-
+ // if (this.isAbstract()) {
+ // for (Iterator i = getDeclares().iterator(); i.hasNext();) {
+ // Declare dec = (Declare) i.next();
+ // if (!dec.isAdviceLike()) ret.add(dec);
+ // }
+ //
+ // if (!includeAdviceLike) return ret;
+
if (!this.isAbstract()) {
final Iterators.Filter dupFilter = Iterators.dupFilter();
- Iterators.Getter typeGetter = new Iterators.Getter() {
- public Iterator get(Object o) {
- return
- dupFilter.filter(
- ((ResolvedType)o).getDirectSupertypes());
- }
- };
- Iterator typeIterator = Iterators.recur(this, typeGetter);
-
- while (typeIterator.hasNext()) {
- ResolvedType ty = (ResolvedType) typeIterator.next();
- for (Iterator i = ty.getTypeMungers().iterator(); i.hasNext();) {
- ConcreteTypeMunger dec = (ConcreteTypeMunger) i.next();
+ Iterators.Getter typeGetter = new Iterators.Getter() {
+ public Iterator get(Object o) {
+ return dupFilter.filter(((ResolvedType) o).getDirectSupertypes());
+ }
+ };
+ Iterator typeIterator = Iterators.recur(this, typeGetter);
+
+ while (typeIterator.hasNext()) {
+ ResolvedType ty = (ResolvedType) typeIterator.next();
+ for (Iterator i = ty.getTypeMungers().iterator(); i.hasNext();) {
+ ConcreteTypeMunger dec = (ConcreteTypeMunger) i.next();
ret.add(dec);
}
- }
+ }
}
-
+
return ret;
- }
-
+ }
+
public final Collection collectDeclares(boolean includeAdviceLike) {
- if (! this.isAspect() ) return Collections.EMPTY_LIST;
-
+ if (!this.isAspect())
+ return Collections.EMPTY_LIST;
+
ArrayList ret = new ArrayList();
- //if (this.isAbstract()) {
-// for (Iterator i = getDeclares().iterator(); i.hasNext();) {
-// Declare dec = (Declare) i.next();
-// if (!dec.isAdviceLike()) ret.add(dec);
-// }
-//
-// if (!includeAdviceLike) return ret;
-
+ // if (this.isAbstract()) {
+ // for (Iterator i = getDeclares().iterator(); i.hasNext();) {
+ // Declare dec = (Declare) i.next();
+ // if (!dec.isAdviceLike()) ret.add(dec);
+ // }
+ //
+ // if (!includeAdviceLike) return ret;
+
if (!this.isAbstract()) {
- //ret.addAll(getDeclares());
+ // ret.addAll(getDeclares());
final Iterators.Filter dupFilter = Iterators.dupFilter();
- Iterators.Getter typeGetter = new Iterators.Getter() {
- public Iterator get(Object o) {
- return
- dupFilter.filter(
- ((ResolvedType)o).getDirectSupertypes());
- }
- };
- Iterator typeIterator = Iterators.recur(this, typeGetter);
-
- while (typeIterator.hasNext()) {
- ResolvedType ty = (ResolvedType) typeIterator.next();
- //System.out.println("super: " + ty + ", " + );
- for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
+ Iterators.Getter typeGetter = new Iterators.Getter() {
+ public Iterator get(Object o) {
+ return dupFilter.filter(((ResolvedType) o).getDirectSupertypes());
+ }
+ };
+ Iterator typeIterator = Iterators.recur(this, typeGetter);
+
+ while (typeIterator.hasNext()) {
+ ResolvedType ty = (ResolvedType) typeIterator.next();
+ // System.out.println("super: " + ty + ", " + );
+ for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
Declare dec = (Declare) i.next();
if (dec.isAdviceLike()) {
- if (includeAdviceLike) ret.add(dec);
+ if (includeAdviceLike)
+ ret.add(dec);
} else {
ret.add(dec);
}
}
- }
+ }
}
-
+
return ret;
- }
-
-
-
-
- private final Collection collectShadowMungers() {
- if (! this.isAspect() || this.isAbstract() || this.doesNotExposeShadowMungers()) return Collections.EMPTY_LIST;
+ }
+
+ private final Collection collectShadowMungers() {
+ 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());
- }
- };
- Iterator typeIterator = Iterators.recur(this, typeGetter);
-
- while (typeIterator.hasNext()) {
- ResolvedType ty = (ResolvedType) typeIterator.next();
- acc.addAll(ty.getDeclaredShadowMungers());
- }
-
- return acc;
- }
-
+ final Iterators.Filter dupFilter = Iterators.dupFilter();
+ Iterators.Getter typeGetter = new Iterators.Getter() {
+ public Iterator get(Object o) {
+ return dupFilter.filter(((ResolvedType) o).getDirectSupertypes());
+ }
+ };
+ Iterator typeIterator = Iterators.recur(this, typeGetter);
+
+ while (typeIterator.hasNext()) {
+ ResolvedType ty = (ResolvedType) typeIterator.next();
+ acc.addAll(ty.getDeclaredShadowMungers());
+ }
+
+ return acc;
+ }
+
protected boolean doesNotExposeShadowMungers() {
return false;
}
- public PerClause getPerClause() {
- return null;
- }
+ public PerClause getPerClause() {
+ return null;
+ }
protected Collection getDeclares() {
- return Collections.EMPTY_LIST;
- }
-
- protected Collection getTypeMungers() {
- return Collections.EMPTY_LIST;
- }
-
- protected Collection getPrivilegedAccesses() {
- return Collections.EMPTY_LIST;
- }
-
-
- // ---- useful things
-
- public final boolean isInterface() {
- return Modifier.isInterface(getModifiers());
- }
-
- public final boolean isAbstract() {
- return Modifier.isAbstract(getModifiers());
- }
-
- public boolean isClass() {
- return false;
- }
-
- public boolean isAspect() {
- return false;
- }
-
- public boolean isAnnotationStyleAspect() {
- return false;
- }
-
- /**
- * Note: Only overridden by Name subtype.
- */
- public boolean isEnum() {
- return false;
- }
-
- /**
- * Note: Only overridden by Name subtype.
- */
- public boolean isAnnotation() {
- return false;
- }
-
- public boolean isAnonymous() {
- return false;
- }
-
- public boolean isNested() {
- return false;
- }
-
-
- public void addAnnotation(AnnotationX annotationX) {
- throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
- }
-
+ return Collections.EMPTY_LIST;
+ }
+
+ protected Collection getTypeMungers() {
+ return Collections.EMPTY_LIST;
+ }
+
+ protected Collection getPrivilegedAccesses() {
+ return Collections.EMPTY_LIST;
+ }
+
+ // ---- useful things
+
+ public final boolean isInterface() {
+ return Modifier.isInterface(getModifiers());
+ }
+
+ public final boolean isAbstract() {
+ return Modifier.isAbstract(getModifiers());
+ }
+
+ public boolean isClass() {
+ return false;
+ }
+
+ public boolean isAspect() {
+ return false;
+ }
+
+ public boolean isAnnotationStyleAspect() {
+ return false;
+ }
+
+ /**
+ * Note: Only overridden by Name subtype.
+ */
+ public boolean isEnum() {
+ return false;
+ }
+
+ /**
+ * Note: Only overridden by Name subtype.
+ */
+ public boolean isAnnotation() {
+ return false;
+ }
+
+ public boolean isAnonymous() {
+ return false;
+ }
+
+ public boolean isNested() {
+ return false;
+ }
+
+ public void addAnnotation(AnnotationX annotationX) {
+ throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
+ }
+
public AnnotationX[] getAnnotations() {
throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
}
-
+
/**
* Note: Only overridden by ReferenceType subtype
*/
public boolean canAnnotationTargetType() {
return false;
}
-
+
/**
* Note: Only overridden by ReferenceType subtype
- */
+ */
public AnnotationTargetKind[] getAnnotationTargetKinds() {
return null;
}
-
- /**
- * Note: Only overridden by Name subtype.
- */
- public boolean isAnnotationWithRuntimeRetention() {
- return false;
- }
-
- public boolean isSynthetic() {
- return signature.indexOf("$ajc") != -1;
- }
-
- public final boolean isFinal() {
- return Modifier.isFinal(getModifiers());
- }
-
- protected Map /*Type variable name -> UnresolvedType*/ getMemberParameterizationMap() {
- if (!isParameterizedType()) return Collections.EMPTY_MAP;
+
+ /**
+ * Note: Only overridden by Name subtype.
+ */
+ public boolean isAnnotationWithRuntimeRetention() {
+ return false;
+ }
+
+ public boolean isSynthetic() {
+ return signature.indexOf("$ajc") != -1;
+ }
+
+ public final boolean isFinal() {
+ return Modifier.isFinal(getModifiers());
+ }
+
+ protected Map /* Type variable name -> UnresolvedType */getMemberParameterizationMap() {
+ if (!isParameterizedType())
+ return Collections.EMPTY_MAP;
TypeVariable[] tvs = getGenericType().getTypeVariables();
Map parameterizationMap = new HashMap();
for (int i = 0; i < tvs.length; i++) {
@@ -742,22 +717,22 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
return parameterizationMap;
}
-
public Collection getDeclaredAdvice() {
List l = new ArrayList();
ResolvedMember[] methods = getDeclaredMethods();
- if (isParameterizedType()) methods = getGenericType().getDeclaredMethods();
+ if (isParameterizedType())
+ methods = getGenericType().getDeclaredMethods();
Map typeVariableMap = getAjMemberParameterizationMap();
- for (int i=0, len = methods.length; i < len; i++) {
+ for (int i = 0, len = methods.length; i < len; i++) {
ShadowMunger munger = methods[i].getAssociatedShadowMunger();
if (munger != null) {
if (ajMembersNeedParameterization()) {
- //munger.setPointcut(munger.getPointcut().parameterizeWith(typeVariableMap));
- munger = munger.parameterizeWith(this,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) {
@@ -780,309 +755,259 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
return l;
}
-
+
public Collection getDeclaredShadowMungers() {
Collection c = getDeclaredAdvice();
return c;
}
-
- // ---- only for testing!
+ // ---- only for testing!
public ResolvedMember[] getDeclaredJavaFields() {
return filterInJavaVisible(getDeclaredFields());
}
+
public ResolvedMember[] getDeclaredJavaMethods() {
return filterInJavaVisible(getDeclaredMethods());
}
+
public ShadowMunger[] getDeclaredShadowMungersArray() {
List l = (List) getDeclaredShadowMungers();
return (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]);
}
+
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) {
+ for (int i = 0, len = ms.length; i < len; i++) {
+ if (!ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
l.add(ms[i]);
}
}
return (ResolvedMember[]) l.toArray(new ResolvedMember[l.size()]);
}
-
+
public abstract ISourceContext getSourceContext();
+ // ---- fields
+
+ public static final ResolvedType[] NONE = new ResolvedType[0];
+
+ public static final Primitive BYTE = new Primitive("B", 1, 0);
+ public static final Primitive CHAR = new Primitive("C", 1, 1);
+ public static final Primitive DOUBLE = new Primitive("D", 2, 2);
+ public static final Primitive FLOAT = new Primitive("F", 1, 3);
+ public static final Primitive INT = new Primitive("I", 1, 4);
+ public static final Primitive LONG = new Primitive("J", 2, 5);
+ public static final Primitive SHORT = new Primitive("S", 1, 6);
+ public static final Primitive VOID = new Primitive("V", 0, 8);
+ public static final Primitive BOOLEAN = new Primitive("Z", 1, 7);
+ 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
+ // null)
+ public static void resetPrimitives() {
+ BYTE.world = null;
+ CHAR.world = null;
+ DOUBLE.world = null;
+ FLOAT.world = null;
+ INT.world = null;
+ LONG.world = null;
+ SHORT.world = null;
+ VOID.world = null;
+ BOOLEAN.world = null;
+ }
+
+ // ---- types
+ public static ResolvedType makeArray(ResolvedType type, int dim) {
+ if (dim == 0)
+ return type;
+ ResolvedType array = new ArrayReferenceType("[" + type.getSignature(), "[" + type.getErasureSignature(), type.getWorld(),
+ type);
+ return makeArray(array, dim - 1);
+ }
+
+ static class Primitive extends ResolvedType {
+ private int size;
+ private int index;
+
+ Primitive(String signature, int size, int index) {
+ super(signature, null);
+ this.size = size;
+ this.index = index;
+ this.typeKind = TypeKind.PRIMITIVE;
+ }
+
+ public final int getSize() {
+ return size;
+ }
+
+ public final int getModifiers() {
+ return Modifier.PUBLIC | Modifier.FINAL;
+ }
- // ---- fields
-
- public static final ResolvedType[] NONE = new ResolvedType[0];
-
- public static final Primitive BYTE = new Primitive("B", 1, 0);
- public static final Primitive CHAR = new Primitive("C", 1, 1);
- public static final Primitive DOUBLE = new Primitive("D", 2, 2);
- public static final Primitive FLOAT = new Primitive("F", 1, 3);
- public static final Primitive INT = new Primitive("I", 1, 4);
- public static final Primitive LONG = new Primitive("J", 2, 5);
- public static final Primitive SHORT = new Primitive("S", 1, 6);
- public static final Primitive VOID = new Primitive("V", 0, 8);
- public static final Primitive BOOLEAN = new Primitive("Z", 1, 7);
- 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
- // null)
- public static void resetPrimitives() {
- BYTE.world=null;
- CHAR.world=null;
- DOUBLE.world=null;
- FLOAT.world=null;
- INT.world=null;
- LONG.world=null;
- SHORT.world=null;
- VOID.world=null;
- BOOLEAN.world=null;
- }
-
-
- // ---- types
- public static ResolvedType makeArray(ResolvedType type, int dim) {
- if (dim == 0) return type;
- ResolvedType array = new ArrayReferenceType("[" + type.getSignature(),"["+type.getErasureSignature(),type.getWorld(),type);
- return makeArray(array,dim-1);
- }
-
- static class Array extends ResolvedType {
- ResolvedType componentType;
-
-
- // Sometimes the erasure is different, eg. [TT; and [Ljava/lang/Object;
- Array(String sig, String erasureSig,World world, ResolvedType componentType) {
- super(sig,erasureSig, world);
- this.componentType = componentType;
- }
- public final ResolvedMember[] getDeclaredFields() {
- return ResolvedMember.NONE;
- }
- public final ResolvedMember[] getDeclaredMethods() {
- // ??? should this return clone? Probably not...
- // If it ever does, here is the code:
- // ResolvedMember cloneMethod =
- // new ResolvedMember(Member.METHOD,this,Modifier.PUBLIC,UnresolvedType.OBJECT,"clone",new UnresolvedType[]{});
- // return new ResolvedMember[]{cloneMethod};
- return ResolvedMember.NONE;
- }
- public final ResolvedType[] getDeclaredInterfaces() {
- return
- new ResolvedType[] {
- world.getCoreType(CLONEABLE),
- world.getCoreType(SERIALIZABLE)
- };
- }
- public final ResolvedMember[] getDeclaredPointcuts() {
- return ResolvedMember.NONE;
- }
-
- public boolean hasAnnotation(UnresolvedType ofType) {
- return false;
- }
-
- public final ResolvedType getSuperclass() {
- return world.getCoreType(OBJECT);
- }
- public final boolean isAssignableFrom(ResolvedType o) {
- if (! o.isArray()) return false;
- if (o.getComponentType().isPrimitiveType()) {
- return o.equals(this);
- } else {
- return getComponentType().resolve(world).isAssignableFrom(o.getComponentType().resolve(world));
- }
- }
-
- public boolean isAssignableFrom(ResolvedType o, boolean allowMissing) {
- return isAssignableFrom(o);
- }
-
- public final boolean isCoerceableFrom(ResolvedType o) {
- if (o.equals(UnresolvedType.OBJECT) ||
- o.equals(UnresolvedType.SERIALIZABLE) ||
- o.equals(UnresolvedType.CLONEABLE)) {
- return true;
- }
- if (! o.isArray()) return false;
- if (o.getComponentType().isPrimitiveType()) {
- return o.equals(this);
- } else {
- return getComponentType().resolve(world).isCoerceableFrom(o.getComponentType().resolve(world));
- }
- }
- public final int getModifiers() {
- int mask = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
- return (componentType.getModifiers() & mask) | Modifier.FINAL;
- }
- public UnresolvedType getComponentType() {
- return componentType;
- }
- public ResolvedType getResolvedComponentType() {
- return componentType;
- }
- public ISourceContext getSourceContext() {
- return getResolvedComponentType().getSourceContext();
- }
- }
-
- static class Primitive extends ResolvedType {
- private int size;
- private int index;
- Primitive(String signature, int size, int index) {
- super(signature, null);
- this.size = size;
- this.index = index;
- this.typeKind=TypeKind.PRIMITIVE;
- }
- public final int getSize() {
- return size;
- }
- public final int getModifiers() {
- return Modifier.PUBLIC | Modifier.FINAL;
- }
- public final boolean isPrimitiveType() {
- return true;
- }
- public boolean hasAnnotation(UnresolvedType ofType) {
- return false;
- }
- public final boolean isAssignableFrom(ResolvedType other) {
- if (!other.isPrimitiveType()) {
- if (!world.isInJava5Mode()) return false;
- return validBoxing.contains(this.getSignature()+other.getSignature());
- }
- return assignTable[((Primitive)other).index][index];
- }
- public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
- return isAssignableFrom(other);
- }
- public final boolean isCoerceableFrom(ResolvedType other) {
- if (this == other) return true;
- if (! other.isPrimitiveType()) return false;
- if (index > 6 || ((Primitive)other).index > 6) return false;
- return true;
- }
- public ResolvedType resolve(World world) {
- this.world = world;
- return super.resolve(world);
- }
- public final boolean needsNoConversionFrom(ResolvedType other) {
- if (! other.isPrimitiveType()) return false;
- 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
- { 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
- { false, false, true , true , true , true , false, false, false }, // I
- { false, false, true , true , false, true , false, false, false }, // J
- { false, false, true , true , true , true , true , false, false }, // S
- { 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
- { 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
- { false, false, false, false, true , false, false, false, false }, // I
- { false, false, false, false, false, true , false, false, false }, // J
- { false, false, false, false, true , false, true , false, false }, // S
- { false, false, false, false, false, false, false, true , false }, // V
- { false, false, false, false, false, false, false, false, true }, // Z
- };
-
- // ----
-
- public final ResolvedMember[] getDeclaredFields() {
- return ResolvedMember.NONE;
- }
- public final ResolvedMember[] getDeclaredMethods() {
- return ResolvedMember.NONE;
- }
- public final ResolvedType[] getDeclaredInterfaces() {
- return ResolvedType.NONE;
- }
- public final ResolvedMember[] getDeclaredPointcuts() {
- return ResolvedMember.NONE;
- }
-
- public final ResolvedType getSuperclass() {
- return null;
- }
-
- public ISourceContext getSourceContext() {
- return null;
- }
-
- }
-
- static class Missing extends ResolvedType {
- Missing() {
- super(MISSING_NAME, null);
- }
-// public final String toString() {
-// return "<missing>";
-// }
- public final String getName() {
- return MISSING_NAME;
- }
-
- public final boolean isMissing() {
- return true;
- }
-
- public boolean hasAnnotation(UnresolvedType ofType) {
- return false;
- }
- public final ResolvedMember[] getDeclaredFields() {
- return ResolvedMember.NONE;
- }
- public final ResolvedMember[] getDeclaredMethods() {
- return ResolvedMember.NONE;
- }
- public final ResolvedType[] getDeclaredInterfaces() {
- return ResolvedType.NONE;
- }
-
- public final ResolvedMember[] getDeclaredPointcuts() {
- return ResolvedMember.NONE;
- }
- public final ResolvedType getSuperclass() {
- return null;
- }
- public final int getModifiers() {
- return 0;
- }
- public final boolean isAssignableFrom(ResolvedType other) {
- return false;
- }
- public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
- return false;
- }
- public final boolean isCoerceableFrom(ResolvedType other) {
- return false;
- }
- public boolean needsNoConversionFrom(ResolvedType other) {
- return false;
- }
- public ISourceContext getSourceContext() {
- return null;
- }
-
- }
-
- /**
- * Look up a member, takes into account any ITDs on this type.
- * return null if not found
- */
+ public final boolean isPrimitiveType() {
+ return true;
+ }
+
+ public boolean hasAnnotation(UnresolvedType ofType) {
+ return false;
+ }
+
+ public final boolean isAssignableFrom(ResolvedType other) {
+ if (!other.isPrimitiveType()) {
+ if (!world.isInJava5Mode())
+ return false;
+ return validBoxing.contains(this.getSignature() + other.getSignature());
+ }
+ return assignTable[((Primitive) other).index][index];
+ }
+
+ public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
+ return isAssignableFrom(other);
+ }
+
+ public final boolean isCoerceableFrom(ResolvedType other) {
+ if (this == other)
+ return true;
+ if (!other.isPrimitiveType())
+ return false;
+ if (index > 6 || ((Primitive) other).index > 6)
+ return false;
+ return true;
+ }
+
+ public ResolvedType resolve(World world) {
+ this.world = world;
+ return super.resolve(world);
+ }
+
+ public final boolean needsNoConversionFrom(ResolvedType other) {
+ if (!other.isPrimitiveType())
+ return false;
+ 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
+ { 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
+ { false, false, true, true, true, true, false, false, false }, // I
+ { false, false, true, true, false, true, false, false, false }, // J
+ { false, false, true, true, true, true, true, false, false }, // S
+ { 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
+ { 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
+ { false, false, false, false, true, false, false, false, false }, // I
+ { false, false, false, false, false, true, false, false, false }, // J
+ { false, false, false, false, true, false, true, false, false }, // S
+ { false, false, false, false, false, false, false, true, false }, // V
+ { false, false, false, false, false, false, false, false, true }, // Z
+ };
+
+ // ----
+
+ public final ResolvedMember[] getDeclaredFields() {
+ return ResolvedMember.NONE;
+ }
+
+ public final ResolvedMember[] getDeclaredMethods() {
+ return ResolvedMember.NONE;
+ }
+
+ public final ResolvedType[] getDeclaredInterfaces() {
+ return ResolvedType.NONE;
+ }
+
+ public final ResolvedMember[] getDeclaredPointcuts() {
+ return ResolvedMember.NONE;
+ }
+
+ public final ResolvedType getSuperclass() {
+ return null;
+ }
+
+ public ISourceContext getSourceContext() {
+ return null;
+ }
+
+ }
+
+ static class Missing extends ResolvedType {
+ Missing() {
+ super(MISSING_NAME, null);
+ }
+
+ // public final String toString() {
+ // return "<missing>";
+ // }
+ public final String getName() {
+ return MISSING_NAME;
+ }
+
+ public final boolean isMissing() {
+ return true;
+ }
+
+ public boolean hasAnnotation(UnresolvedType ofType) {
+ return false;
+ }
+
+ public final ResolvedMember[] getDeclaredFields() {
+ return ResolvedMember.NONE;
+ }
+
+ public final ResolvedMember[] getDeclaredMethods() {
+ return ResolvedMember.NONE;
+ }
+
+ public final ResolvedType[] getDeclaredInterfaces() {
+ return ResolvedType.NONE;
+ }
+
+ public final ResolvedMember[] getDeclaredPointcuts() {
+ return ResolvedMember.NONE;
+ }
+
+ public final ResolvedType getSuperclass() {
+ return null;
+ }
+
+ public final int getModifiers() {
+ return 0;
+ }
+
+ public final boolean isAssignableFrom(ResolvedType other) {
+ return false;
+ }
+
+ public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
+ return false;
+ }
+
+ public final boolean isCoerceableFrom(ResolvedType other) {
+ return false;
+ }
+
+ public boolean needsNoConversionFrom(ResolvedType other) {
+ return false;
+ }
+
+ public ISourceContext getSourceContext() {
+ return null;
+ }
+
+ }
+
+ /**
+ * 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);
if (ret == null && interTypeMungers != null) {
@@ -1095,23 +1020,25 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
return ret;
}
-
+
public ResolvedMember lookupMemberWithSupersAndITDs(Member member) {
ResolvedMember ret = lookupMemberNoSupers(member);
- if (ret != null) return ret;
-
+ if (ret != null)
+ return ret;
+
ResolvedType supert = getSuperclass();
- while (ret==null && supert!=null) {
+ while (ret == null && supert != null) {
ret = supert.lookupMemberNoSupers(member);
- if (ret==null) supert = supert.getSuperclass();
+ if (ret == null)
+ supert = supert.getSuperclass();
}
-
+
return ret;
}
-
+
/**
* as lookupMemberNoSupers, but does not include ITDs
- *
+ *
* @param member
* @return
*/
@@ -1125,19 +1052,18 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
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
*/
public ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member) {
return lookupMemberIncludingITDsOnInterfaces(member, this);
}
-
+
private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) {
ResolvedMember ret = onType.lookupMemberNoSupers(member);
if (ret != null) {
@@ -1145,199 +1071,193 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
} else {
ResolvedType superType = onType.getSuperclass();
if (superType != null) {
- ret = lookupMemberIncludingITDsOnInterfaces(member,superType);
+ ret = lookupMemberIncludingITDsOnInterfaces(member, superType);
}
if (ret == null) {
// try interfaces then, but only ITDs now...
ResolvedType[] superInterfaces = onType.getDeclaredInterfaces();
for (int i = 0; i < superInterfaces.length; i++) {
ret = superInterfaces[i].lookupMethodInITDs(member);
- if (ret != null) return ret;
+ if (ret != null)
+ return ret;
}
}
}
return ret;
}
-
+
protected List interTypeMungers = new ArrayList(0);
-
+
public List getInterTypeMungers() {
return interTypeMungers;
}
-
- public List getInterTypeParentMungers() {
- List l = new ArrayList();
- for (Iterator iter = interTypeMungers.iterator(); iter.hasNext();) {
- ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next();
- if (element.getMunger() instanceof NewParentTypeMunger) l.add(element);
+
+ public List getInterTypeParentMungers() {
+ List l = new ArrayList();
+ for (Iterator iter = interTypeMungers.iterator(); iter.hasNext();) {
+ ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next();
+ if (element.getMunger() instanceof NewParentTypeMunger)
+ l.add(element);
+ }
+ return l;
}
- return l;
- }
-
+
/**
- * ??? 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();
- collectInterTypeMungers(ret);
- return ret;
- }
-
-
- public List getInterTypeParentMungersIncludingSupers() {
- ArrayList ret = new ArrayList();
- collectInterTypeParentMungers(ret);
- return ret;
- }
-
- private void collectInterTypeParentMungers(List collector) {
- for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
- ResolvedType superType = (ResolvedType) iter.next();
- superType.collectInterTypeParentMungers(collector);
- }
- collector.addAll(getInterTypeParentMungers());
- }
-
-
- protected void collectInterTypeMungers(List collector) {
- for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
+ public List getInterTypeMungersIncludingSupers() {
+ ArrayList ret = new ArrayList();
+ collectInterTypeMungers(ret);
+ return ret;
+ }
+
+ public List getInterTypeParentMungersIncludingSupers() {
+ ArrayList ret = new ArrayList();
+ collectInterTypeParentMungers(ret);
+ return ret;
+ }
+
+ private void collectInterTypeParentMungers(List collector) {
+ for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
+ ResolvedType superType = (ResolvedType) iter.next();
+ superType.collectInterTypeParentMungers(collector);
+ }
+ collector.addAll(getInterTypeParentMungers());
+ }
+
+ protected void collectInterTypeMungers(List collector) {
+ 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");
- }
- superType.collectInterTypeMungers(collector);
- }
-
- outer:
- for (Iterator iter1 = collector.iterator(); iter1.hasNext();) {
- ConcreteTypeMunger superMunger = (ConcreteTypeMunger) iter1.next();
- if ( superMunger.getSignature() == null) continue;
-
- if ( !superMunger.getSignature().isAbstract()) continue;
-
- for (Iterator iter = getInterTypeMungers().iterator(); iter.hasNext();) {
- ConcreteTypeMunger myMunger = (ConcreteTypeMunger) iter.next();
- if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) {
- iter1.remove();
- continue outer;
- }
- }
-
- if (!superMunger.getSignature().isPublic()) continue;
-
- for (Iterator iter = getMethods(); iter.hasNext(); ) {
- ResolvedMember method = (ResolvedMember)iter.next();
- if (conflictingSignature(method, superMunger.getSignature())) {
- iter1.remove();
- continue outer;
- }
- }
- }
-
- collector.addAll(getInterTypeMungers());
- }
-
-
-
- /**
- * 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()) return;
-
- boolean itdProblem = false;
-
- for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
+ throw new BCException("UnexpectedProblem: a supertype in the hierarchy for " + this.getName() + " is null");
+ }
+ superType.collectInterTypeMungers(collector);
+ }
+
+ outer: for (Iterator iter1 = collector.iterator(); iter1.hasNext();) {
+ ConcreteTypeMunger superMunger = (ConcreteTypeMunger) iter1.next();
+ if (superMunger.getSignature() == null)
+ continue;
+
+ if (!superMunger.getSignature().isAbstract())
+ continue;
+
+ for (Iterator iter = getInterTypeMungers().iterator(); iter.hasNext();) {
+ ConcreteTypeMunger myMunger = (ConcreteTypeMunger) iter.next();
+ if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) {
+ iter1.remove();
+ continue outer;
+ }
+ }
+
+ if (!superMunger.getSignature().isPublic())
+ continue;
+
+ for (Iterator iter = getMethods(); iter.hasNext();) {
+ ResolvedMember method = (ResolvedMember) iter.next();
+ if (conflictingSignature(method, superMunger.getSignature())) {
+ iter1.remove();
+ continue outer;
+ }
+ }
+ }
+
+ collector.addAll(getInterTypeMungers());
+ }
+
+ /**
+ * 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())
+ return;
+
+ boolean itdProblem = false;
+
+ for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2
- }
-
- if (itdProblem) return; // If the rules above are broken, return right now
-
+ }
+
+ if (itdProblem)
+ return; // If the rules above are broken, return right now
+
for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
- 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
- } else {
- world.getMessageHandler().handleMessage(
- new Message("must implement abstract inter-type declaration: " + munger.getSignature(),
- "", IMessage.ERROR, getSourceLocation(), null,
- new ISourceLocation[] { getMungerLocation(munger) }));
- }
- }
- }
- }
-
- /**
- * 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.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
+ } else {
+ world.getMessageHandler()
+ .handleMessage(
+ new Message("must implement abstract inter-type declaration: " + munger.getSignature(), "",
+ IMessage.ERROR, getSourceLocation(), null,
+ new ISourceLocation[] { getMungerLocation(munger) }));
+ }
+ }
+ }
+ }
+
+ /**
+ * 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)) {
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)})
- );
- return true;
- }
+ 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;
+ }
}
return false;
- }
-
- /**
- * 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();
- if (sloc == null) {
- sloc = munger.getAspectType().getSourceLocation();
- }
- return sloc;
- }
-
- /**
- * Returns a ResolvedType object representing the declaring type of this type, or
- * null if this type does not represent a non-package-level-type.
- * <p/>
- * <strong>Warning</strong>: 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.
- */
- public ResolvedType getDeclaringType() {
- if (isArray()) return null;
+ }
+
+ /**
+ * 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();
+ if (sloc == null) {
+ sloc = munger.getAspectType().getSourceLocation();
+ }
+ return sloc;
+ }
+
+ /**
+ * Returns a ResolvedType object representing the declaring type of this type, or null if this type does not represent a
+ * non-package-level-type. <p/> <strong>Warning</strong>: 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.
+ */
+ public ResolvedType getDeclaringType() {
+ if (isArray())
+ return null;
String name = getName();
int lastDollar = name.lastIndexOf('$');
- while (lastDollar >0) { // allow for classes starting '$' (pr120474)
+ while (lastDollar > 0) { // allow for classes starting '$' (pr120474)
ResolvedType ret = world.resolve(UnresolvedType.forName(name.substring(0, lastDollar)), true);
- if (!ResolvedType.isMissing(ret)) return ret;
- lastDollar = name.lastIndexOf('$', lastDollar-1);
+ if (!ResolvedType.isMissing(ret))
+ return ret;
+ lastDollar = name.lastIndexOf('$', lastDollar - 1);
}
return null;
- }
-
-
+ }
+
public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) {
- //System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
-
+ // System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
+
if (Modifier.isPublic(modifiers)) {
return true;
} else if (Modifier.isPrivate(modifiers)) {
@@ -1346,154 +1266,160 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
} else { // package-visible
return samePackage(targetType, fromType);
- }
+ }
}
-
+
public static boolean hasBridgeModifier(int modifiers) {
- return (modifiers & Constants.ACC_BRIDGE)!=0;
+ return (modifiers & Constants.ACC_BRIDGE) != 0;
}
- 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) return p2 == null;
- if (p2 == null) return false;
+ if (p1 == null)
+ return p2 == null;
+ if (p2 == null)
+ return false;
return p1.equals(p2);
}
/**
- * 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))) 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.
- *
- * returns null if it can't be found.
- */
- 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);
-
- if (this.equals(ResolvedType.OBJECT)) return null;
-
- if (genericTypeEquals(lookingFor)) return this;
-
- ResolvedType superT = getSuperclass();
- if (superT.genericTypeEquals(lookingFor)) return superT;
-
- ResolvedType[] superIs = getDeclaredInterfaces();
- for (int i = 0; i < superIs.length; i++) {
- ResolvedType superI = superIs[i];
- if (superI.genericTypeEquals(lookingFor)) return superI;
- ResolvedType checkTheSuperI = superI.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
- if (checkTheSuperI!=null) return checkTheSuperI;
- }
- return superT.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
- }
-
- /**
- * 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<T> I<T>.x" against a type like this:
- * "class A implements I<String>" this routine will return a parameterized form of
- * the ITD "List<String> I.x"
- */
- public ConcreteTypeMunger fillInAnyTypeParameters(ConcreteTypeMunger munger) {
- boolean debug = false;
+ private boolean genericTypeEquals(ResolvedType other) {
+ ResolvedType rt = other;
+ if (rt.isParameterizedType() || rt.isRawType())
+ rt.getGenericType();
+ 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.
+ *
+ * returns null if it can't be found.
+ */
+ 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);
+
+ if (this.equals(ResolvedType.OBJECT))
+ return null;
+
+ if (genericTypeEquals(lookingFor))
+ return this;
+
+ ResolvedType superT = getSuperclass();
+ if (superT.genericTypeEquals(lookingFor))
+ return superT;
+
+ ResolvedType[] superIs = getDeclaredInterfaces();
+ for (int i = 0; i < superIs.length; i++) {
+ ResolvedType superI = superIs[i];
+ if (superI.genericTypeEquals(lookingFor))
+ return superI;
+ ResolvedType checkTheSuperI = superI.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
+ if (checkTheSuperI != null)
+ return checkTheSuperI;
+ }
+ return superT.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
+ }
+
+ /**
+ * 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<T> I<T>.x" against a type like this: "class A implements I<String>" this routine
+ * will return a parameterized form of the ITD "List<String> 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);
- if (debug) 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);
- // Retrieve the generic type
- 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)
- ResolvedType actualTarget = discoverActualOccurrenceOfTypeInHierarchy(onType);
- if (actualTarget==null)
- 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 for generic types ;)
- if (!actualTarget.isGenericType()) {
- if (debug) System.err.println("Occurrence in "+this+" is actually "+actualTarget+" ("+actualTarget.typeKind+")");
- // parameterize the signature
- // ResolvedMember newOne = member.parameterizedWith(actualTarget.getTypeParameters(),onType,actualTarget.isParameterizedType());
- }
- //if (!actualTarget.isRawType())
- munger = munger.parameterizedFor(actualTarget);
- if (debug) System.err.println("New sig: "+munger.getSignature());
-
-
- if (debug) System.err.println("=====================================");
+ if (debug)
+ System.err.println("Processing attempted parameterization of " + munger + " targetting type " + this);
+ if (debug)
+ 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);
+ // Retrieve the generic type
+ 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)
+ ResolvedType actualTarget = discoverActualOccurrenceOfTypeInHierarchy(onType);
+ if (actualTarget == null)
+ 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
+ // for generic types ;)
+ if (!actualTarget.isGenericType()) {
+ if (debug)
+ System.err.println("Occurrence in " + this + " is actually " + actualTarget + " (" + actualTarget.typeKind
+ + ")");
+ // parameterize the signature
+ // ResolvedMember newOne =
+ // member.parameterizedWith(actualTarget.getTypeParameters(),onType,actualTarget.isParameterizedType());
+ }
+ // if (!actualTarget.isRawType())
+ munger = munger.parameterizedFor(actualTarget);
+ if (debug)
+ System.err.println("New sig: " + munger.getSignature());
+
+ if (debug)
+ System.err.println("=====================================");
}
return munger;
- }
+ }
-
-
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;
+
+ // 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
+ // 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
-
- //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()*/)) return;
+ if (!compareToExistingMembers(munger, getMethodsWithoutIterator(false, true) /* getMethods() */))
+ return;
if (this.isInterface()) {
- if (!compareToExistingMembers(munger,
- Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) return;
+ if (!compareToExistingMembers(munger, Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator()))
+ return;
}
} else if (sig.getKind() == Member.FIELD) {
- if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) return;
+ if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator()))
+ return;
} else {
- if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) return;
+ if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator()))
+ return;
}
-
// now compare to existingMungers
- for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
- ConcreteTypeMunger existingMunger = (ConcreteTypeMunger)i.next();
+ 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()))
- {
- //System.err.println(" is visible");
+ // 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());
if (c == 0) {
c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType());
}
- //System.err.println(" compare: " + c);
+ // System.err.println(" compare: " + c);
if (c < 0) {
// the existing munger dominates the new munger
checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
@@ -1507,53 +1433,55 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
interTypeConflictError(munger, existingMunger);
interTypeConflictError(existingMunger, munger);
return;
- }
+ }
}
}
}
- //System.err.println("adding: " + munger + " to " + this);
+ // System.err.println("adding: " + munger + " to " + this);
// we are adding the parameterized form of the ITD to the list of
- // mungers. Within it, the munger knows the original declared
+ // mungers. Within it, the munger knows the original declared
// signature for the ITD so it can be retrieved.
interTypeMungers.add(munger);
}
-
+
private boolean compareToExistingMembers(ConcreteTypeMunger munger, List existingMembersList) {
- return compareToExistingMembers(munger,existingMembersList.iterator());
+ return compareToExistingMembers(munger, existingMembersList.iterator());
}
-
- //??? returning too soon
+
+ // ??? returning too soon
private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
ResolvedMember sig = munger.getSignature();
-
-// ResolvedType declaringAspectType = munger.getAspectType();
-// if (declaringAspectType.isRawType()) declaringAspectType = declaringAspectType.getGenericType();
-// if (declaringAspectType.isGenericType()) {
-//
-// 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
-// }
+
+ // ResolvedType declaringAspectType = munger.getAspectType();
+ // if (declaringAspectType.isRawType()) declaringAspectType = declaringAspectType.getGenericType();
+ // if (declaringAspectType.isGenericType()) {
+ //
+ // 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
+ // }
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);
+ if (existingMember.isBridgeMethod())
+ continue;
+ // 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() + ", " + munger.getSignature().getSourceLocation());
-
+ // 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())) {
int c = compareMemberPrecedence(sig, existingMember);
- //System.err.println(" c: " + c);
+ // System.err.println(" c: " + c);
if (c < 0) {
// existingMember dominates munger
checkLegalOverride(munger.getSignature(), existingMember);
@@ -1561,185 +1489,189 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
} else if (c > 0) {
// munger dominates existingMember
checkLegalOverride(existingMember, munger.getSignature());
- //interTypeMungers.add(munger);
- //??? might need list of these overridden abstracts
+ // 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
- // could do with a rewrite !
- 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
- // more work.
- boolean isDuplicateOfPreviousITD = false;
- ResolvedType declaringRt = existingMember.getDeclaringType().resolve(world);
- WeaverStateInfo wsi = declaringRt.getWeaverState();
- if (wsi!=null) {
- List mungersAffectingThisType = wsi.getTypeMungers(declaringRt);
- if (mungersAffectingThisType!=null) {
- 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 from the same aspect
- if (ctMunger.getSignature().equals(existingMember) && ctMunger.aspectType.equals(munger.getAspectType())) {
- isDuplicateOfPreviousITD=true;
+ // bridge methods can differ solely in return type.
+ // 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()));
+ 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
+ // more work.
+ boolean isDuplicateOfPreviousITD = false;
+ ResolvedType declaringRt = existingMember.getDeclaringType().resolve(world);
+ WeaverStateInfo wsi = declaringRt.getWeaverState();
+ if (wsi != null) {
+ List mungersAffectingThisType = wsi.getTypeMungers(declaringRt);
+ if (mungersAffectingThisType != null) {
+ 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
+ // from the same aspect
+ 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())
- );
- }
- }
+ }
+ }
+ if (!isDuplicateOfPreviousITD) {
+ getWorld().getMessageHandler().handleMessage(
+ MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger
+ .getAspectType().getName(), existingMember), munger.getSourceLocation()));
+ }
+ }
}
- } else if (isDuplicateMemberWithinTargetType(existingMember,this,sig)) {
- getWorld().getMessageHandler().handleMessage(
- MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
- existingMember),
- munger.getSourceLocation())
- );
-
+ } else if (isDuplicateMemberWithinTargetType(existingMember, this, sig)) {
+ getWorld().getMessageHandler().handleMessage(
+ MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT, munger.getAspectType()
+ .getName(), existingMember), munger.getSourceLocation()));
+
}
- //return;
+ // return;
}
}
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,ResolvedMember itdMember) {
- if ( (existingMember.isAbstract() || itdMember.isAbstract())) return false;
- UnresolvedType declaringType = existingMember.getDeclaringType();
- if (!targetType.equals(declaringType)) return false;
- // now have to test that itdMember is visible from targetType
- if (itdMember.isPrivate()) return false;
- if (itdMember.isPublic()) return true;
- // must be in same package to be visible then...
- 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.
- return true;
- }
-
+ private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType,
+ ResolvedMember itdMember) {
+ if ((existingMember.isAbstract() || itdMember.isAbstract()))
+ return false;
+ UnresolvedType declaringType = existingMember.getDeclaringType();
+ if (!targetType.equals(declaringType))
+ return false;
+ // now have to test that itdMember is visible from targetType
+ if (itdMember.isPrivate())
+ return false;
+ if (itdMember.isPublic())
+ return true;
+ // must be in same package to be visible then...
+ 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.
+ 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());
+ // 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.getSourceLocation(),null);
+ world.showMessage(Message.ERROR, WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER, parent), child
+ .getSourceLocation(), null);
return false;
}
-
+
boolean incompatibleReturnTypes = false;
// In 1.5 mode, allow for covariance on return type
- 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
-// if (incompatibleReturnTypes) {
-// incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
-// }
+ 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
+ // if (incompatibleReturnTypes) {
+ // 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 error = world.resolve("java.lang.Error");
-
- outer:
- for (int i = 0, leni = childExceptions.length; i < leni; i++) {
- //System.err.println("checking: " + childExceptions[i]);
- if (runtimeException.isAssignableFrom(childExceptions[i])) continue;
- if (error.isAssignableFrom(childExceptions[i])) continue;
-
+
+ outer: for (int i = 0, leni = childExceptions.length; i < leni; i++) {
+ // System.err.println("checking: " + childExceptions[i]);
+ if (runtimeException.isAssignableFrom(childExceptions[i]))
+ continue;
+ if (error.isAssignableFrom(childExceptions[i]))
+ continue;
+
for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
- if (parentExceptions[j].isAssignableFrom(childExceptions[i])) continue outer;
+ if (parentExceptions[j].isAssignableFrom(childExceptions[i]))
+ continue outer;
}
-
+
// this message is now better handled my MethodVerifier in JDT core.
-// world.showMessage(IMessage.ERROR,
-// WeaverMessages.format(WeaverMessages.ITD_DOESNT_THROW,childExceptions[i].getName()),
-// child.getSourceLocation(), null);
-
+ // world.showMessage(IMessage.ERROR,
+ // 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.getSourceLocation(),null);
+ 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.getSourceLocation(),null);
+ world.showMessage(IMessage.ERROR, WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC, child, parent), child
+ .getSourceLocation(), null);
return false;
}
return true;
-
+
}
-
+
private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
- //if (!m1.getReturnType().equals(m2.getReturnType())) return 0;
-
+ // 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
+ // 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') {
+ // 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")) return +1;
+ if (declaring != null) {
+ if (declaring.getName().equals("java.lang.Object") && m2.getName().equals("clone"))
+ return +1;
}
}
- if (Modifier.isAbstract(m1.getModifiers())) return -1;
- if (Modifier.isAbstract(m2.getModifiers())) return +1;
-
- if (m1.getDeclaringType().equals(m2.getDeclaringType())) return 0;
-
+ if (Modifier.isAbstract(m1.getModifiers()))
+ return -1;
+ if (Modifier.isAbstract(m2.getModifiers()))
+ return +1;
+
+ if (m1.getDeclaringType().equals(m2.getDeclaringType()))
+ return 0;
+
ResolvedType t1 = m1.getDeclaringType().resolve(world);
ResolvedType t2 = m2.getDeclaringType().resolve(world);
if (t1.isAssignableFrom(t2)) {
@@ -1750,13 +1682,16 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
return 0;
}
-
public static boolean isMoreVisible(int m1, int m2) {
- if (Modifier.isPrivate(m1)) return false;
- if (isPackage(m1)) return Modifier.isPrivate(m2);
- if (Modifier.isProtected(m1)) return /* private package */ (Modifier.isPrivate(m2) || isPackage(m2));
- if (Modifier.isPublic(m1)) return /* private package protected */ ! Modifier.isPublic(m2);
+ if (Modifier.isPrivate(m1))
+ return false;
+ if (isPackage(m1))
+ return Modifier.isPrivate(m2);
+ if (Modifier.isProtected(m1))
+ return /* private package */(Modifier.isPrivate(m2) || isPackage(m2));
+ if (Modifier.isPublic(m1))
+ return /* private package protected */!Modifier.isPublic(m2);
throw new RuntimeException("bad modifier: " + m1);
}
@@ -1764,121 +1699,119 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
}
- 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());
- }
-
-
+ 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());
+ }
+
public ResolvedMember lookupSyntheticMember(Member member) {
- //??? horribly inefficient
- //for (Iterator i =
- //System.err.println("lookup " + member + " in " + interTypeMungers);
- for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
- ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
+ // ??? horribly inefficient
+ // for (Iterator i =
+ // System.err.println("lookup " + member + " in " + interTypeMungers);
+ for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
+ ConcreteTypeMunger m = (ConcreteTypeMunger) i.next();
ResolvedMember ret = m.getMatchingSyntheticMember(member);
if (ret != null) {
- //System.err.println(" found: " + ret);
+ // System.err.println(" found: " + ret);
return ret;
}
}
-
+
// 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,"<init>",world.resolve(member.getParameterTypes()));
+ if (member.getKind() == Member.CONSTRUCTOR) {
+ ResolvedMemberImpl ret = new ResolvedMemberImpl(Member.CONSTRUCTOR, this, Modifier.PUBLIC, ResolvedType.VOID,
+ "<init>", world.resolve(member.getParameterTypes()));
return ret;
}
}
-
-// if (this.getSuperclass() != ResolvedType.OBJECT && this.getSuperclass() != null) {
-// return getSuperclass().lookupSyntheticMember(member);
-// }
-
+
+ // if (this.getSuperclass() != ResolvedType.OBJECT && this.getSuperclass() != null) {
+ // return getSuperclass().lookupSyntheticMember(member);
+ // }
+
return null;
}
public void clearInterTypeMungers() {
- if (isRawType()) getGenericType().clearInterTypeMungers();
+ if (isRawType())
+ getGenericType().clearInterTypeMungers();
interTypeMungers = new ArrayList();
}
-
public boolean isTopmostImplementor(ResolvedType interfaceType) {
- if (isInterface()) return false;
- if (!interfaceType.isAssignableFrom(this,true)) return false;
+ if (isInterface())
+ return false;
+ if (!interfaceType.isAssignableFrom(this, true))
+ 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
- if (interfaceType.isAssignableFrom(this.getSuperclass(),true)) {
+ if (this.getSuperclass().isMissing())
+ 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;
}
return true;
}
-
+
public ResolvedType getTopmostImplementor(ResolvedType interfaceType) {
- if (isInterface()) return null;
- if (!interfaceType.isAssignableFrom(this)) return null;
+ if (isInterface())
+ return null;
+ if (!interfaceType.isAssignableFrom(this))
+ return null;
// Check if my super class is an implementor?
- ResolvedType higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
- if (higherType!=null) return higherType;
+ ResolvedType higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
+ if (higherType != null)
+ return higherType;
return this;
}
-
+
public List getExposedPointcuts() {
List ret = new ArrayList();
- if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
-
- for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext(); ) {
- ResolvedType t = (ResolvedType)i.next();
+ if (getSuperclass() != null)
+ ret.addAll(getSuperclass().getExposedPointcuts());
+
+ 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(getDeclaredPointcuts()), true);
- for (Iterator i = ret.iterator(); i.hasNext(); ) {
- ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition)i.next();
-// System.err.println("looking at: " + inherited + " in " + this);
-// System.err.println(" " + inherited.isAbstract() + " in " + this.isAbstract());
+ for (Iterator i = ret.iterator(); i.hasNext();) {
+ ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition) i.next();
+ // System.err.println("looking at: " + inherited + " in " + this);
+ // 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()),
+ WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE, inherited, this.getName()),
inherited.getSourceLocation(), this.getSourceLocation());
}
}
- }
-
-
+ }
+
return ret;
}
-
+
private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) {
for (Iterator i = added.iterator(); i.hasNext();) {
- ResolvedPointcutDefinition toAdd =
- (ResolvedPointcutDefinition) i.next();
- //System.err.println("adding: " + toAdd);
+ ResolvedPointcutDefinition toAdd = (ResolvedPointcutDefinition) i.next();
+ // System.err.println("adding: " + toAdd);
for (Iterator j = acc.iterator(); j.hasNext();) {
- ResolvedPointcutDefinition existing =
- (ResolvedPointcutDefinition) j.next();
- if (existing == toAdd) continue;
- if (!isVisible(existing.getModifiers(),
- existing.getDeclaringType().resolve(getWorld()),
- this)) {
+ 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 (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;
@@ -1889,10 +1822,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
j.remove();
} else {
getWorld().showMessage(
- IMessage.ERROR,
- WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS,this.getName() + toAdd.getSignature()),
- existing.getSourceLocation(),
- toAdd.getSourceLocation());
+ IMessage.ERROR,
+ WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS, this.getName()
+ + toAdd.getSignature()), existing.getSourceLocation(), toAdd.getSourceLocation());
j.remove();
}
}
@@ -1900,106 +1832,110 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
acc.add(toAdd);
}
}
-
- public ISourceLocation getSourceLocation() {
- return null;
- }
- public boolean isExposedToWeaver() {
- return false;
- }
+ public ISourceLocation getSourceLocation() {
+ return null;
+ }
+
+ public boolean isExposedToWeaver() {
+ return false;
+ }
public WeaverStateInfo getWeaverState() {
return null;
}
-
+
/**
* 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;
}
-
+
/**
* overriden by ReferenceType to return the gsig for a generic type
+ *
* @return
*/
public String getGenericSignature() {
return "";
}
-
-
+
public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) {
- if (!(isGenericType() || isParameterizedType())) return this;
+ if (!(isGenericType() || isParameterizedType()))
+ return this;
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");
- boolean workToDo = false;
- for (int i = 0; i < typeParameters.length; i++) {
- if (typeParameters[i].isTypeVariableReference() ||
- (typeParameters[i] instanceof BoundedReferenceType)) {
+ if (!isParameterizedType())
+ 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)) {
workToDo = true;
}
}
- if (!workToDo) {
- return this;
- } else {
- UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
- for (int i = 0; i < newTypeParams.length; i++) {
+ if (!workToDo) {
+ return this;
+ } else {
+ UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
+ for (int i = 0; i < newTypeParams.length; i++) {
newTypeParams[i] = typeParameters[i];
if (newTypeParams[i].isTypeVariableReference()) {
TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i];
UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName());
- if (binding != null) newTypeParams[i] = binding;
+ if (binding != null)
+ newTypeParams[i] = binding;
} else if (newTypeParams[i] instanceof BoundedReferenceType) {
- BoundedReferenceType brType = (BoundedReferenceType)newTypeParams[i];
+ BoundedReferenceType brType = (BoundedReferenceType) newTypeParams[i];
newTypeParams[i] = brType.parameterize(typeBindings);
-// brType.parameterize(typeBindings)
+ // brType.parameterize(typeBindings)
}
}
- return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
- }
- }
-
+ return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
+ }
+ }
+
public boolean hasParameterizedSuperType() {
getParameterizedSuperTypes();
return parameterizedSuperTypes.length > 0;
}
-
+
public boolean hasGenericSuperType() {
ResolvedType[] superTypes = getDeclaredInterfaces();
for (int i = 0; i < superTypes.length; i++) {
- if (superTypes[i].isGenericType()) return true;
+ if (superTypes[i].isGenericType())
+ return true;
}
return false;
}
-
+
private ResolvedType[] parameterizedSuperTypes = null;
+
/**
* Similar to the above method, but accumulates the super types
- *
+ *
* @return
*/
public ResolvedType[] getParameterizedSuperTypes() {
- if (parameterizedSuperTypes != null) return parameterizedSuperTypes;
+ if (parameterizedSuperTypes != null)
+ return parameterizedSuperTypes;
List accumulatedTypes = new ArrayList();
- accumulateParameterizedSuperTypes(this,accumulatedTypes);
+ accumulateParameterizedSuperTypes(this, accumulatedTypes);
ResolvedType[] ret = new ResolvedType[accumulatedTypes.size()];
parameterizedSuperTypes = (ResolvedType[]) accumulatedTypes.toArray(ret);
return parameterizedSuperTypes;
}
-
+
private void accumulateParameterizedSuperTypes(ResolvedType forType, List parameterizedTypeList) {
if (forType.isParameterizedType()) {
parameterizedTypeList.add(forType);
@@ -2017,124 +1953,127 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
* Types may have pointcuts just as they have methods and fields.
*/
public ResolvedPointcutDefinition findPointcut(String name, World world) {
- throw new UnsupportedOperationException("Not yet implemenented");
+ throw new UnsupportedOperationException("Not yet implemenented");
}
-
+
/**
* @return true if assignable to java.lang.Exception
*/
public boolean isException() {
return (world.getCoreType(UnresolvedType.JAVA_LANG_EXCEPTION).isAssignableFrom(this));
}
-
+
/**
* @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)) return false;
+ if (!isException())
+ return false;
+ 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
*/
- public final boolean isConvertableFrom(ResolvedType other) {
-
-// // version from TypeX
-// if (this.equals(OBJECT)) return true;
-// if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
-// return this.isCoerceableFrom(other);
-//
-
- // version from ResolvedTypeX
- 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())) return true;
- }
- }
- if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
- return this.isCoerceableFrom(other);
- }
+ public final boolean isConvertableFrom(ResolvedType other) {
+
+ // // version from TypeX
+ // if (this.equals(OBJECT)) return true;
+ // if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
+ // return this.isCoerceableFrom(other);
+ //
+
+ // version from ResolvedTypeX
+ 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()))
+ return true;
+ }
+ }
+ if (this.isPrimitiveType() || other.isPrimitiveType())
+ return this.isAssignableFrom(other);
+ return this.isCoerceableFrom(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).
+ * 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
+ * @throws NullPointerException if other is null
*/
public abstract boolean isAssignableFrom(ResolvedType other);
-
+
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".
- * <p/>
- * <p> This method should be commutative, i.e., for all UnresolvedType a, b and all World w:
- * <p/>
- * <blockquote><pre>
- * a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
- * </pre></blockquote>
- *
+ * Determines if values of another type could possibly be cast to this type. The rules followed are from JLS 2ed 5.5,
+ * "Casting Conversion". <p/>
+ * <p>
+ * This method should be commutative, i.e., for all UnresolvedType a, b and all World w: <p/> <blockquote>
+ *
+ * <pre>
+ * a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
+ * </pre>
+ *
+ * </blockquote>
+ *
* @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.
+ * @return true iff values of other could possibly be cast to this type.
+ * @throws NullPointerException if other is null.
*/
public abstract boolean isCoerceableFrom(ResolvedType other);
-
+
public boolean needsNoConversionFrom(ResolvedType o) {
- return isAssignableFrom(o);
+ return isAssignableFrom(o);
}
-
+
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...
- if (parameterizedWithTypeVariable==FuzzyBoolean.MAYBE) {
-
+ if (parameterizedWithTypeVariable == FuzzyBoolean.MAYBE) {
+
// if there are no type parameters then we cant be...
- if (typeParameters==null || typeParameters.length==0) {
+ if (typeParameters == null || typeParameters.length == 0) {
parameterizedWithTypeVariable = FuzzyBoolean.NO;
return false;
}
-
+
for (int i = 0; i < typeParameters.length; i++) {
- 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
- // 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
- ) {
+ 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
+ // 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
+ ) {
parameterizedWithTypeVariable = FuzzyBoolean.YES;
return true;
}
@@ -2146,13 +2085,14 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
}
if (aType.isGenericWildcard()) {
- BoundedReferenceType boundedRT = (BoundedReferenceType) aType;
+ BoundedReferenceType boundedRT = (BoundedReferenceType) aType;
if (boundedRT.isExtends()) {
boolean b = false;
UnresolvedType upperBound = boundedRT.getUpperBound();
if (upperBound.isParameterizedType()) {
- b = ((ResolvedType)upperBound).isParameterizedWithTypeVariable();
- } else if (upperBound.isTypeVariableReference() && ((TypeVariableReference)upperBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
+ b = ((ResolvedType) upperBound).isParameterizedWithTypeVariable();
+ } else if (upperBound.isTypeVariableReference()
+ && ((TypeVariableReference) upperBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
b = true;
}
if (b) {
@@ -2165,8 +2105,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
boolean b = false;
UnresolvedType lowerBound = boundedRT.getLowerBound();
if (lowerBound.isParameterizedType()) {
- b = ((ResolvedType)lowerBound).isParameterizedWithTypeVariable();
- } else if (lowerBound.isTypeVariableReference() && ((TypeVariableReference)lowerBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
+ b = ((ResolvedType) lowerBound).isParameterizedWithTypeVariable();
+ } else if (lowerBound.isTypeVariableReference()
+ && ((TypeVariableReference) lowerBound).getTypeVariable().getDeclaringElementKind() == TypeVariable.METHOD) {
b = true;
}
if (b) {
@@ -2176,14 +2117,16 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
}
}
- parameterizedWithTypeVariable=FuzzyBoolean.NO;
+ parameterizedWithTypeVariable = FuzzyBoolean.NO;
}
return parameterizedWithTypeVariable.alwaysTrue();
}
protected boolean ajMembersNeedParameterization() {
- if (isParameterizedType()) return true;
- if (getSuperclass() != null) return getSuperclass().ajMembersNeedParameterization();
+ if (isParameterizedType())
+ return true;
+ if (getSuperclass() != null)
+ return getSuperclass().ajMembersNeedParameterization();
return false;
}
@@ -2191,22 +2134,21 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
Map myMap = getMemberParameterizationMap();
if (myMap.isEmpty()) {
// might extend a parameterized aspect that we also need to consider...
- if (getSuperclass() != null) return getSuperclass().getAjMemberParameterizationMap();
+ if (getSuperclass() != null)
+ return getSuperclass().getAjMemberParameterizationMap();
}
return myMap;
}
-
+
public void setBinaryPath(String binaryPath) {
this.binaryPath = binaryPath;
}
/**
- * 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/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
index 26fbf0566..153335a74 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
@@ -11,7 +11,6 @@
* Alexandre Vasseur support for @AJ aspects
* ******************************************************************/
-
package org.aspectj.weaver.bcel;
import java.lang.reflect.Modifier;
@@ -64,13 +63,12 @@ import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
import org.aspectj.weaver.ast.Var;
+import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
import org.aspectj.weaver.patterns.AndPointcut;
-import org.aspectj.weaver.patterns.IdentityPointcutVisitor;
import org.aspectj.weaver.patterns.NotPointcut;
import org.aspectj.weaver.patterns.OrPointcut;
import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
-
/*
* Some fun implementation stuff:
*
@@ -122,22 +120,21 @@ import org.aspectj.weaver.patterns.ThisOrTargetPointcut;
*/
public class BcelShadow extends Shadow {
-
- private ShadowRange range;
- private final BcelWorld world;
- private final LazyMethodGen enclosingMethod;
-
+
+ private ShadowRange range;
+ private final BcelWorld world;
+ private final LazyMethodGen enclosingMethod;
+
// SECRETAPI - for testing, this will tell us if the optimization succeeded *on the last shadow processed*
public static boolean appliedLazyTjpOptimization;
-
- // Some instructions have a target type that will vary
- // from the signature (pr109728) (1.4 declaring type issue)
- private String actualInstructionTargetType;
+
+ // Some instructions have a target type that will vary
+ // from the signature (pr109728) (1.4 declaring type issue)
+ private String actualInstructionTargetType;
/**
- * This generates an unassociated shadow, rooted in a particular method but not rooted
- * to any particular point in the code. It should be given to a rooted ShadowRange
- * in the {@link ShadowRange#associateWithShadow(BcelShadow)} method.
+ * This generates an unassociated shadow, rooted in a particular method but not rooted to any particular point in the code. It
+ * should be given to a rooted ShadowRange in the {@link ShadowRange#associateWithShadow(BcelShadow)} method.
*/
public BcelShadow(BcelWorld world, Kind kind, Member signature, LazyMethodGen enclosingMethod, BcelShadow enclosingShadow) {
super(kind, signature, enclosingShadow);
@@ -149,19 +146,20 @@ public class BcelShadow extends Shadow {
public BcelShadow copyInto(LazyMethodGen recipient, BcelShadow enclosing) {
BcelShadow s = new BcelShadow(world, getKind(), getSignature(), recipient, enclosing);
- if (mungers.size()>0) {
+ if (mungers.size() > 0) {
List src = mungers;
- if (s.mungers==Collections.EMPTY_LIST) s.mungers = new ArrayList();
+ if (s.mungers == Collections.EMPTY_LIST)
+ s.mungers = new ArrayList();
List dest = s.mungers;
-
- for (Iterator i = src.iterator(); i.hasNext(); ) {
+
+ for (Iterator i = src.iterator(); i.hasNext();) {
dest.add(i.next());
}
}
return s;
}
- // ---- overridden behaviour
+ // ---- overridden behaviour
public World getIWorld() {
return world;
@@ -172,67 +170,67 @@ public class BcelShadow extends Shadow {
int depth = 1;
InstructionHandle ih = range.getStart();
- // Go back from where we are looking for 'NEW' that takes us to a stack depth of 0. INVOKESPECIAL <init>
+ // Go back from where we are looking for 'NEW' that takes us to a stack depth of 0. INVOKESPECIAL <init>
while (true) {
Instruction inst = ih.getInstruction();
- if (inst.opcode==Constants.INVOKESPECIAL
- && ((InvokeInstruction) inst).getName(cpg).equals("<init>")) {
+ if (inst.opcode == Constants.INVOKESPECIAL && ((InvokeInstruction) inst).getName(cpg).equals("<init>")) {
depth++;
- } else if (inst.opcode==Constants.NEW) {
+ } else if (inst.opcode == Constants.NEW) {
depth--;
- if (depth == 0) break;
- } else if (inst.opcode==Constants.DUP_X2) {
+ if (depth == 0)
+ break;
+ } else if (inst.opcode == Constants.DUP_X2) {
// This code seen in the wild (by Brad):
-// 40: new #12; //class java/lang/StringBuffer
-// STACK: STRINGBUFFER
-// 43: dup
-// STACK: STRINGBUFFER/STRINGBUFFER
-// 44: aload_0
-// STACK: STRINGBUFFER/STRINGBUFFER/THIS
-// 45: dup_x2
-// STACK: THIS/STRINGBUFFER/STRINGBUFFER/THIS
-// 46: getfield #36; //Field value:Ljava/lang/String;
-// STACK: THIS/STRINGBUFFER/STRINGBUFFER/STRING<value>
-// 49: invokestatic #37; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
-// STACK: THIS/STRINGBUFFER/STRINGBUFFER/STRING
-// 52: invokespecial #19; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
-// STACK: THIS/STRINGBUFFER
-// 55: aload_1
-// STACK: THIS/STRINGBUFFER/LOCAL1
-// 56: invokevirtual #22; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
-// STACK: THIS/STRINGBUFFER
-// 59: invokevirtual #34; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
-// STACK: THIS/STRING
-// 62: putfield #36; //Field value:Ljava/lang/String;
-// STACK: <empty>
-// 65: return
-
+ // 40: new #12; //class java/lang/StringBuffer
+ // STACK: STRINGBUFFER
+ // 43: dup
+ // STACK: STRINGBUFFER/STRINGBUFFER
+ // 44: aload_0
+ // STACK: STRINGBUFFER/STRINGBUFFER/THIS
+ // 45: dup_x2
+ // STACK: THIS/STRINGBUFFER/STRINGBUFFER/THIS
+ // 46: getfield #36; //Field value:Ljava/lang/String;
+ // STACK: THIS/STRINGBUFFER/STRINGBUFFER/STRING<value>
+ // 49: invokestatic #37; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
+ // STACK: THIS/STRINGBUFFER/STRINGBUFFER/STRING
+ // 52: invokespecial #19; //Method java/lang/StringBuffer."<init>":(Ljava/lang/String;)V
+ // STACK: THIS/STRINGBUFFER
+ // 55: aload_1
+ // STACK: THIS/STRINGBUFFER/LOCAL1
+ // 56: invokevirtual #22; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
+ // STACK: THIS/STRINGBUFFER
+ // 59: invokevirtual #34; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;
+ // STACK: THIS/STRING
+ // 62: putfield #36; //Field value:Ljava/lang/String;
+ // STACK: <empty>
+ // 65: return
+
// if we attempt to match on the ctor call to StringBuffer.<init> then we get into trouble.
// if we simply delete the new/dup pair without fixing up the dup_x2 then the dup_x2 will fail due to there
- // not being 3 elements on the stack for it to work with. The fix *in this situation* is to change it to
+ // not being 3 elements on the stack for it to work with. The fix *in this situation* is to change it to
// a simple 'dup'
-
+
// this fix is *not* very clean - but a general purpose decent solution will take much longer and this
// bytecode sequence has only been seen once in the wild.
ih.setInstruction(InstructionConstants.DUP);
}
ih = ih.getPrev();
}
- // now IH points to the NEW. We're followed by the DUP, and that is followed
- // by the actual instruction we care about.
+ // now IH points to the NEW. We're followed by the DUP, and that is followed
+ // by the actual instruction we care about.
InstructionHandle newHandle = ih;
InstructionHandle endHandle = newHandle.getNext();
InstructionHandle nextHandle;
- if (endHandle.getInstruction().opcode==Constants.DUP) {
- nextHandle = endHandle.getNext();
+ if (endHandle.getInstruction().opcode == Constants.DUP) {
+ nextHandle = endHandle.getNext();
retargetFrom(newHandle, nextHandle);
retargetFrom(endHandle, nextHandle);
- } else if (endHandle.getInstruction().opcode==Constants.DUP_X1) {
+ } else if (endHandle.getInstruction().opcode == Constants.DUP_X1) {
InstructionHandle dupHandle = endHandle;
endHandle = endHandle.getNext();
nextHandle = endHandle.getNext();
- if (endHandle.getInstruction().opcode==Constants.SWAP) {}
- else {
+ if (endHandle.getInstruction().opcode == Constants.SWAP) {
+ } else {
// XXX see next XXX comment
throw new RuntimeException("Unhandled kind of new " + endHandle);
}
@@ -256,67 +254,68 @@ public class BcelShadow extends Shadow {
throw new BCException("shouldn't happen");
}
}
+
private void retargetFrom(InstructionHandle old, InstructionHandle fresh) {
InstructionTargeter[] sources = old.getTargetersArray();
if (sources != null) {
for (int i = sources.length - 1; i >= 0; i--) {
if (sources[i] instanceof ExceptionRange) {
- ExceptionRange it = (ExceptionRange)sources[i];
+ ExceptionRange it = (ExceptionRange) sources[i];
System.err.println("...");
- it.updateTarget(old,fresh,it.getBody());
+ it.updateTarget(old, fresh, it.getBody());
} else {
- sources[i].updateTarget(old, fresh);
+ sources[i].updateTarget(old, fresh);
}
}
}
}
-
+
// records advice that is stopping us doing the lazyTjp optimization
private List badAdvice = null;
-
+
public void addAdvicePreventingLazyTjp(BcelAdvice advice) {
- if (badAdvice == null) badAdvice = new ArrayList();
+ if (badAdvice == null)
+ badAdvice = new ArrayList();
badAdvice.add(advice);
}
-
- protected void prepareForMungers() {
- // if we're a constructor call, we need to remove the new:dup or the new:dup_x1:swap,
+
+ protected void prepareForMungers() {
+ // if we're a constructor call, we need to remove the new:dup or the new:dup_x1:swap,
// and store all our
// arguments on the frame.
-
- // ??? This is a bit of a hack (for the Java langauge). We do this because
- // we sometime add code "outsideBefore" when dealing with weaving join points. We only
- // do this for exposing state that is on the stack. It turns out to just work for
- // everything except for constructor calls and exception handlers. If we were to clean
- // this up, every ShadowRange would have three instructionHandle points, the start of
+
+ // ??? This is a bit of a hack (for the Java langauge). We do this because
+ // we sometime add code "outsideBefore" when dealing with weaving join points. We only
+ // do this for exposing state that is on the stack. It turns out to just work for
+ // everything except for constructor calls and exception handlers. If we were to clean
+ // this up, every ShadowRange would have three instructionHandle points, the start of
// the arg-setup code, the start of the running code, and the end of the running code.
if (getKind() == ConstructorCall) {
if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray())
- deleteNewAndDup(); // no new/dup for new array construction
+ deleteNewAndDup(); // no new/dup for new array construction
initializeArgVars();
} else if (getKind() == PreInitialization) { // pr74952
ShadowRange range = getRange();
- range.insert(InstructionConstants.NOP,Range.InsideAfter);
+ range.insert(InstructionConstants.NOP, Range.InsideAfter);
} else if (getKind() == ExceptionHandler) {
-
+
ShadowRange range = getRange();
InstructionList body = range.getBody();
- InstructionHandle start = range.getStart();
-
- // Create a store instruction to put the value from the top of the
- // stack into a local variable slot. This is a trimmed version of
+ InstructionHandle start = range.getStart();
+
+ // Create a store instruction to put the value from the top of the
+ // stack into a local variable slot. This is a trimmed version of
// what is in initializeArgVars() (since there is only one argument
// at a handler jp and only before advice is supported) (pr46298)
- argVars = new BcelVar[1];
- //int positionOffset = (hasTarget() ? 1 : 0) + ((hasThis() && !getKind().isTargetSameAsThis()) ? 1 : 0);
+ argVars = new BcelVar[1];
+ // int positionOffset = (hasTarget() ? 1 : 0) + ((hasThis() && !getKind().isTargetSameAsThis()) ? 1 : 0);
UnresolvedType tx = getArgType(0);
- argVars[0] = genTempVar(tx, "ajc$arg0");
- InstructionHandle insertedInstruction =
- range.insert(argVars[0].createStore(getFactory()), Range.OutsideBefore);
+ argVars[0] = genTempVar(tx, "ajc$arg0");
+ InstructionHandle insertedInstruction = range.insert(argVars[0].createStore(getFactory()), Range.OutsideBefore);
- // Now the exception range starts just after our new instruction.
- // The next bit of code changes the exception range to point at
- // the store instruction
+ // Now the exception range starts just after our new instruction.
+ // The next bit of code changes the exception range to point at
+ // the store instruction
InstructionTargeter[] targeters = start.getTargetersArray();
for (int i = 0; i < targeters.length; i++) {
InstructionTargeter t = targeters[i];
@@ -328,663 +327,480 @@ public class BcelShadow extends Shadow {
}
// now we ask each munger to request our state
- isThisJoinPointLazy = true;//world.isXlazyTjp(); // lazy is default now
+ isThisJoinPointLazy = true;// world.isXlazyTjp(); // lazy is default now
badAdvice = null;
for (Iterator iter = mungers.iterator(); iter.hasNext();) {
ShadowMunger munger = (ShadowMunger) iter.next();
munger.specializeOn(this);
}
-
-
+
initializeThisJoinPoint();
- if (thisJoinPointVar!=null && !isThisJoinPointLazy && badAdvice!=null && badAdvice.size()>1) {
+ if (thisJoinPointVar != null && !isThisJoinPointLazy && badAdvice != null && badAdvice.size() > 1) {
// something stopped us making it a lazy tjp
// can't build tjp lazily, no suitable test...
int valid = 0;
for (Iterator iter = badAdvice.iterator(); iter.hasNext();) {
BcelAdvice element = (BcelAdvice) iter.next();
ISourceLocation sLoc = element.getSourceLocation();
- if (sLoc!=null && sLoc.getLine()>0) valid++;
+ if (sLoc != null && sLoc.getLine() > 0)
+ valid++;
}
- if (valid!=0) {
+ if (valid != 0) {
ISourceLocation[] badLocs = new ISourceLocation[valid];
int i = 0;
for (Iterator iter = badAdvice.iterator(); iter.hasNext();) {
BcelAdvice element = (BcelAdvice) iter.next();
ISourceLocation sLoc = element.getSourceLocation();
- if (sLoc!=null) badLocs[i++]=sLoc;
+ if (sLoc != null)
+ badLocs[i++] = sLoc;
}
- world.getLint().multipleAdviceStoppingLazyTjp.signal(
- new String[] {this.toString()},
- getSourceLocation(),badLocs
- );
+ world.getLint().multipleAdviceStoppingLazyTjp
+ .signal(new String[] { this.toString() }, getSourceLocation(), badLocs);
}
}
- badAdvice=null;
-
-
- // If we are an expression kind, we require our target/arguments on the stack
- // before we do our actual thing. However, they may have been removed
- // from the stack as the shadowMungers have requested state.
- // if any of our shadowMungers requested either the arguments or target,
- // the munger will have added code
- // to pop the target/arguments into temporary variables, represented by
- // targetVar and argVars. In such a case, we must make sure to re-push the
- // values.
-
- // If we are nonExpressionKind, we don't expect arguments on the stack
- // so this is moot. If our argVars happen to be null, then we know that
- // no ShadowMunger has squirrelled away our arguments, so they're still
- // on the stack.
+ badAdvice = null;
+
+ // If we are an expression kind, we require our target/arguments on the stack
+ // before we do our actual thing. However, they may have been removed
+ // from the stack as the shadowMungers have requested state.
+ // if any of our shadowMungers requested either the arguments or target,
+ // the munger will have added code
+ // to pop the target/arguments into temporary variables, represented by
+ // targetVar and argVars. In such a case, we must make sure to re-push the
+ // values.
+
+ // If we are nonExpressionKind, we don't expect arguments on the stack
+ // so this is moot. If our argVars happen to be null, then we know that
+ // no ShadowMunger has squirrelled away our arguments, so they're still
+ // on the stack.
InstructionFactory fact = getFactory();
if (getKind().argsOnStack() && argVars != null) {
-
- // Special case first (pr46298). If we are an exception handler and the instruction
- // just after the shadow is a POP then we should remove the pop. The code
+
+ // Special case first (pr46298). If we are an exception handler and the instruction
+ // just after the shadow is a POP then we should remove the pop. The code
// above which generated the store instruction has already cleared the stack.
// We also don't generate any code for the arguments in this case as it would be
// an incorrect aload.
- if (getKind() == ExceptionHandler
- && range.getEnd().getNext().getInstruction().equals(InstructionConstants.POP)) {
+ if (getKind() == ExceptionHandler && range.getEnd().getNext().getInstruction().equals(InstructionConstants.POP)) {
// easier than deleting it ...
range.getEnd().getNext().setInstruction(InstructionConstants.NOP);
} else {
- range.insert(
- BcelRenderer.renderExprs(fact, world, argVars),
- Range.InsideBefore);
- if (targetVar != null) {
- range.insert(
- BcelRenderer.renderExpr(fact, world, targetVar),
- Range.InsideBefore);
- }
- if (getKind() == ConstructorCall) {
- if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) {
- range.insert(InstructionFactory.createDup(1), Range.InsideBefore);
- range.insert(
- fact.createNew(
- (ObjectType) BcelWorld.makeBcelType(
- getSignature().getDeclaringType())),
- Range.InsideBefore);
- }
- }
+ range.insert(BcelRenderer.renderExprs(fact, world, argVars), Range.InsideBefore);
+ if (targetVar != null) {
+ range.insert(BcelRenderer.renderExpr(fact, world, targetVar), Range.InsideBefore);
+ }
+ if (getKind() == ConstructorCall) {
+ if (!world.isJoinpointArrayConstructionEnabled() || !this.getSignature().getDeclaringType().isArray()) {
+ range.insert(InstructionFactory.createDup(1), Range.InsideBefore);
+ range.insert(fact.createNew((ObjectType) BcelWorld.makeBcelType(getSignature().getDeclaringType())),
+ Range.InsideBefore);
+ }
+ }
}
}
- }
+ }
+
+ // ---- getters
- // ---- getters
+ public ShadowRange getRange() {
+ return range;
+ }
- public ShadowRange getRange() {
- return range;
- }
public void setRange(ShadowRange range) {
this.range = range;
}
-
+
private int sourceline = -1;
-
- public int getSourceLine() {
- // if the kind of join point for which we are a shadow represents
- // a method or constructor execution, then the best source line is
- // the one from the enclosingMethod declarationLineNumber if available.
- if (sourceline!=-1) return sourceline;
- Kind kind = getKind();
- if ( (kind == MethodExecution) ||
- (kind == ConstructorExecution) ||
- (kind == AdviceExecution) ||
- (kind == StaticInitialization) ||
- (kind == PreInitialization) ||
- (kind == Initialization)) {
- if (getEnclosingMethod().hasDeclaredLineNumberInfo()) {
- sourceline= getEnclosingMethod().getDeclarationLineNumber();
- return sourceline;
- }
- }
-
- if (range == null) {
- if (getEnclosingMethod().hasBody()) {
- sourceline= Utility.getSourceLine(getEnclosingMethod().getBody().getStart());
- return sourceline;
- } else {
- sourceline= 0;
- return sourceline;
- }
- }
- sourceline = Utility.getSourceLine(range.getStart());
- if (sourceline < 0) sourceline = 0;
- return sourceline;
- }
-
- // overrides
- public UnresolvedType getEnclosingType() {
- return getEnclosingClass().getType();
- }
-
- public LazyClassGen getEnclosingClass() {
- return enclosingMethod.getEnclosingClass();
- }
-
- public BcelWorld getWorld() {
- return world;
- }
-
- // ---- factory methods
-
- public static BcelShadow makeConstructorExecution(
- BcelWorld world,
- LazyMethodGen enclosingMethod,
- InstructionHandle justBeforeStart)
- {
+
+ public int getSourceLine() {
+ // if the kind of join point for which we are a shadow represents
+ // a method or constructor execution, then the best source line is
+ // the one from the enclosingMethod declarationLineNumber if available.
+ if (sourceline != -1)
+ return sourceline;
+ Kind kind = getKind();
+ if ((kind == MethodExecution) || (kind == ConstructorExecution) || (kind == AdviceExecution)
+ || (kind == StaticInitialization) || (kind == PreInitialization) || (kind == Initialization)) {
+ if (getEnclosingMethod().hasDeclaredLineNumberInfo()) {
+ sourceline = getEnclosingMethod().getDeclarationLineNumber();
+ return sourceline;
+ }
+ }
+
+ if (range == null) {
+ if (getEnclosingMethod().hasBody()) {
+ sourceline = Utility.getSourceLine(getEnclosingMethod().getBody().getStart());
+ return sourceline;
+ } else {
+ sourceline = 0;
+ return sourceline;
+ }
+ }
+ sourceline = Utility.getSourceLine(range.getStart());
+ if (sourceline < 0)
+ sourceline = 0;
+ return sourceline;
+ }
+
+ // overrides
+ public UnresolvedType getEnclosingType() {
+ return getEnclosingClass().getType();
+ }
+
+ public LazyClassGen getEnclosingClass() {
+ return enclosingMethod.getEnclosingClass();
+ }
+
+ public BcelWorld getWorld() {
+ return world;
+ }
+
+ // ---- factory methods
+
+ public static BcelShadow makeConstructorExecution(BcelWorld world, LazyMethodGen enclosingMethod,
+ InstructionHandle justBeforeStart) {
final InstructionList body = enclosingMethod.getBody();
- BcelShadow s =
- new BcelShadow(
- world,
- ConstructorExecution,
- world.makeJoinPointSignatureFromMethod(enclosingMethod,Member.CONSTRUCTOR),
- enclosingMethod,
- null);
+ BcelShadow s = new BcelShadow(world, ConstructorExecution, world.makeJoinPointSignatureFromMethod(enclosingMethod,
+ Member.CONSTRUCTOR), enclosingMethod, null);
ShadowRange r = new ShadowRange(body);
r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, justBeforeStart.getNext()),
- Range.genEnd(body));
+ r.associateWithTargets(Range.genStart(body, justBeforeStart.getNext()), Range.genEnd(body));
return s;
}
- public static BcelShadow makeStaticInitialization(
- BcelWorld world,
- LazyMethodGen enclosingMethod)
- {
- InstructionList body = enclosingMethod.getBody();
- // move the start past ajc$preClinit
- InstructionHandle clinitStart = body.getStart();
- if (clinitStart.getInstruction() instanceof InvokeInstruction) {
- InvokeInstruction ii = (InvokeInstruction)clinitStart.getInstruction();
- if (ii
- .getName(enclosingMethod.getEnclosingClass().getConstantPool())
- .equals(NameMangler.AJC_PRE_CLINIT_NAME)) {
+ public static BcelShadow makeStaticInitialization(BcelWorld world, LazyMethodGen enclosingMethod) {
+ InstructionList body = enclosingMethod.getBody();
+ // move the start past ajc$preClinit
+ InstructionHandle clinitStart = body.getStart();
+ if (clinitStart.getInstruction() instanceof InvokeInstruction) {
+ InvokeInstruction ii = (InvokeInstruction) clinitStart.getInstruction();
+ if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPool()).equals(NameMangler.AJC_PRE_CLINIT_NAME)) {
clinitStart = clinitStart.getNext();
}
- }
-
- InstructionHandle clinitEnd = body.getEnd();
-
- //XXX should move the end before the postClinit, but the return is then tricky...
-// if (clinitEnd.getInstruction() instanceof InvokeInstruction) {
-// InvokeInstruction ii = (InvokeInstruction)clinitEnd.getInstruction();
-// if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPool()).equals(NameMangler.AJC_POST_CLINIT_NAME)) {
-// clinitEnd = clinitEnd.getPrev();
-// }
-// }
-
-
-
- BcelShadow s =
- new BcelShadow(
- world,
- StaticInitialization,
- world.makeJoinPointSignatureFromMethod(enclosingMethod,Member.STATIC_INITIALIZATION),
- enclosingMethod,
- null);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, clinitStart),
- Range.genEnd(body, clinitEnd));
- return s;
- }
-
- /** Make the shadow for an exception handler. Currently makes an empty shadow that
- * only allows before advice to be woven into it.
- */
+ }
+ InstructionHandle clinitEnd = body.getEnd();
- public static BcelShadow makeExceptionHandler(
- BcelWorld world,
- ExceptionRange exceptionRange,
- LazyMethodGen enclosingMethod,
- InstructionHandle startOfHandler,
- BcelShadow enclosingShadow)
- {
+ // XXX should move the end before the postClinit, but the return is then tricky...
+ // if (clinitEnd.getInstruction() instanceof InvokeInstruction) {
+ // InvokeInstruction ii = (InvokeInstruction)clinitEnd.getInstruction();
+ // if (ii.getName(enclosingMethod.getEnclosingClass().getConstantPool()).equals(NameMangler.AJC_POST_CLINIT_NAME)) {
+ // clinitEnd = clinitEnd.getPrev();
+ // }
+ // }
+
+ BcelShadow s = new BcelShadow(world, StaticInitialization, world.makeJoinPointSignatureFromMethod(enclosingMethod,
+ Member.STATIC_INITIALIZATION), enclosingMethod, null);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, clinitStart), Range.genEnd(body, clinitEnd));
+ return s;
+ }
+
+ /**
+ * Make the shadow for an exception handler. Currently makes an empty shadow that only allows before advice to be woven into it.
+ */
+
+ public static BcelShadow makeExceptionHandler(BcelWorld world, ExceptionRange exceptionRange, LazyMethodGen enclosingMethod,
+ InstructionHandle startOfHandler, BcelShadow enclosingShadow) {
InstructionList body = enclosingMethod.getBody();
UnresolvedType catchType = exceptionRange.getCatchType();
UnresolvedType inType = enclosingMethod.getEnclosingClass().getType();
-
- ResolvedMemberImpl sig = MemberImpl.makeExceptionHandlerSignature(inType, catchType);
- sig.setParameterNames(new String[] {findHandlerParamName(startOfHandler)});
-
- BcelShadow s =
- new BcelShadow(
- world,
- ExceptionHandler,
- sig,
- enclosingMethod,
- enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- InstructionHandle start = Range.genStart(body, startOfHandler);
- InstructionHandle end = Range.genEnd(body, start);
-
- r.associateWithTargets(start, end);
- exceptionRange.updateTarget(startOfHandler, start, body);
- return s;
- }
-
- private static String findHandlerParamName(InstructionHandle startOfHandler) {
- if (startOfHandler.getInstruction().isStoreInstruction() &&
- startOfHandler.getNext() != null)
- {
+
+ ResolvedMemberImpl sig = MemberImpl.makeExceptionHandlerSignature(inType, catchType);
+ sig.setParameterNames(new String[] { findHandlerParamName(startOfHandler) });
+
+ BcelShadow s = new BcelShadow(world, ExceptionHandler, sig, enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ InstructionHandle start = Range.genStart(body, startOfHandler);
+ InstructionHandle end = Range.genEnd(body, start);
+
+ r.associateWithTargets(start, end);
+ exceptionRange.updateTarget(startOfHandler, start, body);
+ return s;
+ }
+
+ private static String findHandlerParamName(InstructionHandle startOfHandler) {
+ if (startOfHandler.getInstruction().isStoreInstruction() && startOfHandler.getNext() != null) {
int slot = startOfHandler.getInstruction().getIndex();
- //System.out.println("got store: " + startOfHandler.getInstruction() + ", " + index);
+ // System.out.println("got store: " + startOfHandler.getInstruction() + ", " + index);
Iterator tIter = startOfHandler.getNext().getTargeters().iterator();
while (tIter.hasNext()) {
- InstructionTargeter targeter = (InstructionTargeter)tIter.next();
+ InstructionTargeter targeter = (InstructionTargeter) tIter.next();
if (targeter instanceof LocalVariableTag) {
- LocalVariableTag t = (LocalVariableTag)targeter;
+ LocalVariableTag t = (LocalVariableTag) targeter;
if (t.getSlot() == slot) {
return t.getName();
}
}
}
}
-
+
return "<missing>";
}
-
- /** create an init join point associated w/ an interface in the body of a constructor */
-
- public static BcelShadow makeIfaceInitialization(
- BcelWorld world,
- LazyMethodGen constructor,
- Member interfaceConstructorSignature)
- {
+
+ /** create an init join point associated w/ an interface in the body of a constructor */
+
+ public static BcelShadow makeIfaceInitialization(BcelWorld world, LazyMethodGen constructor,
+ Member interfaceConstructorSignature) {
// this call marks the instruction list as changed
constructor.getBody();
// UnresolvedType inType = constructor.getEnclosingClass().getType();
- BcelShadow s =
- new BcelShadow(
- world,
- Initialization,
- interfaceConstructorSignature,
- constructor,
- null);
-// s.fallsThrough = true;
-// ShadowRange r = new ShadowRange(body);
-// r.associateWithShadow(s);
-// InstructionHandle start = Range.genStart(body, handle);
-// InstructionHandle end = Range.genEnd(body, handle);
-//
-// r.associateWithTargets(start, end);
- return s;
- }
-
+ BcelShadow s = new BcelShadow(world, Initialization, interfaceConstructorSignature, constructor, null);
+ // s.fallsThrough = true;
+ // ShadowRange r = new ShadowRange(body);
+ // r.associateWithShadow(s);
+ // InstructionHandle start = Range.genStart(body, handle);
+ // InstructionHandle end = Range.genEnd(body, handle);
+ //
+ // r.associateWithTargets(start, end);
+ return s;
+ }
+
public void initIfaceInitializer(InstructionHandle end) {
final InstructionList body = enclosingMethod.getBody();
ShadowRange r = new ShadowRange(body);
r.associateWithShadow(this);
InstructionHandle nop = body.insert(end, InstructionConstants.NOP);
-
- r.associateWithTargets(
- Range.genStart(body, nop),
- Range.genEnd(body, nop));
- }
-
-// public static BcelShadow makeIfaceConstructorExecution(
-// BcelWorld world,
-// LazyMethodGen constructor,
-// InstructionHandle next,
-// Member interfaceConstructorSignature)
-// {
-// // final InstructionFactory fact = constructor.getEnclosingClass().getFactory();
-// InstructionList body = constructor.getBody();
-// // UnresolvedType inType = constructor.getEnclosingClass().getType();
-// BcelShadow s =
-// new BcelShadow(
-// world,
-// ConstructorExecution,
-// interfaceConstructorSignature,
-// constructor,
-// null);
-// s.fallsThrough = true;
-// ShadowRange r = new ShadowRange(body);
-// r.associateWithShadow(s);
-// // ??? this may or may not work
-// InstructionHandle start = Range.genStart(body, next);
-// //InstructionHandle end = Range.genEnd(body, body.append(start, fact.NOP));
-// InstructionHandle end = Range.genStart(body, next);
-// //body.append(start, fact.NOP);
-//
-// r.associateWithTargets(start, end);
-// return s;
-// }
-
-
- /** Create an initialization join point associated with a constructor, but not
- * with any body of code yet. If this is actually matched, it's range will be set
- * when we inline self constructors.
- *
- * @param constructor The constructor starting this initialization.
- */
- public static BcelShadow makeUnfinishedInitialization(
- BcelWorld world,
- LazyMethodGen constructor)
- {
- BcelShadow ret = new BcelShadow(
- world,
- Initialization,
- world.makeJoinPointSignatureFromMethod(constructor,Member.CONSTRUCTOR),
- constructor,
- null);
+
+ r.associateWithTargets(Range.genStart(body, nop), Range.genEnd(body, nop));
+ }
+
+ // public static BcelShadow makeIfaceConstructorExecution(
+ // BcelWorld world,
+ // LazyMethodGen constructor,
+ // InstructionHandle next,
+ // Member interfaceConstructorSignature)
+ // {
+ // // final InstructionFactory fact = constructor.getEnclosingClass().getFactory();
+ // InstructionList body = constructor.getBody();
+ // // UnresolvedType inType = constructor.getEnclosingClass().getType();
+ // BcelShadow s =
+ // new BcelShadow(
+ // world,
+ // ConstructorExecution,
+ // interfaceConstructorSignature,
+ // constructor,
+ // null);
+ // s.fallsThrough = true;
+ // ShadowRange r = new ShadowRange(body);
+ // r.associateWithShadow(s);
+ // // ??? this may or may not work
+ // InstructionHandle start = Range.genStart(body, next);
+ // //InstructionHandle end = Range.genEnd(body, body.append(start, fact.NOP));
+ // InstructionHandle end = Range.genStart(body, next);
+ // //body.append(start, fact.NOP);
+ //
+ // r.associateWithTargets(start, end);
+ // return s;
+ // }
+
+ /**
+ * Create an initialization join point associated with a constructor, but not with any body of code yet. If this is actually
+ * matched, it's range will be set when we inline self constructors.
+ *
+ * @param constructor The constructor starting this initialization.
+ */
+ public static BcelShadow makeUnfinishedInitialization(BcelWorld world, LazyMethodGen constructor) {
+ BcelShadow ret = new BcelShadow(world, Initialization, world.makeJoinPointSignatureFromMethod(constructor,
+ Member.CONSTRUCTOR), constructor, null);
if (constructor.getEffectiveSignature() != null) {
ret.setMatchingSignature(constructor.getEffectiveSignature().getEffectiveSignature());
}
return ret;
}
- public static BcelShadow makeUnfinishedPreinitialization(
- BcelWorld world,
- LazyMethodGen constructor)
- {
- BcelShadow ret = new BcelShadow(
- world,
- PreInitialization,
- world.makeJoinPointSignatureFromMethod(constructor,Member.CONSTRUCTOR),
- constructor,
- null);
+ public static BcelShadow makeUnfinishedPreinitialization(BcelWorld world, LazyMethodGen constructor) {
+ BcelShadow ret = new BcelShadow(world, PreInitialization, world.makeJoinPointSignatureFromMethod(constructor,
+ Member.CONSTRUCTOR), constructor, null);
if (constructor.getEffectiveSignature() != null) {
ret.setMatchingSignature(constructor.getEffectiveSignature().getEffectiveSignature());
}
return ret;
}
-
-
- public static BcelShadow makeMethodExecution(
- BcelWorld world,
- LazyMethodGen enclosingMethod,
- boolean lazyInit)
- {
- if (!lazyInit) return makeMethodExecution(world, enclosingMethod);
-
- BcelShadow s =
- new BcelShadow(
- world,
- MethodExecution,
- enclosingMethod.getMemberView(),
- enclosingMethod,
- null);
-
+
+ public static BcelShadow makeMethodExecution(BcelWorld world, LazyMethodGen enclosingMethod, boolean lazyInit) {
+ if (!lazyInit)
+ return makeMethodExecution(world, enclosingMethod);
+
+ BcelShadow s = new BcelShadow(world, MethodExecution, enclosingMethod.getMemberView(), enclosingMethod, null);
+
return s;
}
-
-
+
public void init() {
- if (range != null) return;
-
+ if (range != null)
+ return;
+
final InstructionList body = enclosingMethod.getBody();
ShadowRange r = new ShadowRange(body);
r.associateWithShadow(this);
- r.associateWithTargets(
- Range.genStart(body),
- Range.genEnd(body));
- }
-
- public static BcelShadow makeMethodExecution(
- BcelWorld world,
- LazyMethodGen enclosingMethod)
- {
- return makeShadowForMethod(world, enclosingMethod, MethodExecution,
- enclosingMethod.getMemberView()); //world.makeMethodSignature(enclosingMethod));
- }
-
-
- public static BcelShadow makeShadowForMethod(BcelWorld world,
- LazyMethodGen enclosingMethod, Shadow.Kind kind, Member sig)
- {
- final InstructionList body = enclosingMethod.getBody();
- BcelShadow s =
- new BcelShadow(
- world,
- kind,
- sig,
- enclosingMethod,
- null);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(// OPTIMIZE this occurs lots of times for all jp kinds...
- Range.genStart(body),
- Range.genEnd(body));
- return s;
- }
-
-
-
- public static BcelShadow makeAdviceExecution(
- BcelWorld world,
- LazyMethodGen enclosingMethod)
- {
+ r.associateWithTargets(Range.genStart(body), Range.genEnd(body));
+ }
+
+ public static BcelShadow makeMethodExecution(BcelWorld world, LazyMethodGen enclosingMethod) {
+ return makeShadowForMethod(world, enclosingMethod, MethodExecution, enclosingMethod.getMemberView()); // world.
+ // makeMethodSignature
+ // (
+ // enclosingMethod))
+ // ;
+ }
+
+ public static BcelShadow makeShadowForMethod(BcelWorld world, LazyMethodGen enclosingMethod, Shadow.Kind kind, Member sig) {
final InstructionList body = enclosingMethod.getBody();
- BcelShadow s =
- new BcelShadow(
- world,
- AdviceExecution,
- world.makeJoinPointSignatureFromMethod(enclosingMethod, Member.ADVICE),
- enclosingMethod,
- null);
+ BcelShadow s = new BcelShadow(world, kind, sig, enclosingMethod, null);
ShadowRange r = new ShadowRange(body);
r.associateWithShadow(s);
- r.associateWithTargets(Range.genStart(body), Range.genEnd(body));
+ r.associateWithTargets(// OPTIMIZE this occurs lots of times for all jp kinds...
+ Range.genStart(body), Range.genEnd(body));
return s;
}
+ public static BcelShadow makeAdviceExecution(BcelWorld world, LazyMethodGen enclosingMethod) {
+ final InstructionList body = enclosingMethod.getBody();
+ BcelShadow s = new BcelShadow(world, AdviceExecution, world
+ .makeJoinPointSignatureFromMethod(enclosingMethod, Member.ADVICE), enclosingMethod, null);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body), Range.genEnd(body));
+ return s;
+ }
- // constructor call shadows are <em>initially</em> just around the
- // call to the constructor. If ANY advice gets put on it, we move
- // the NEW instruction inside the join point, which involves putting
+ // constructor call shadows are <em>initially</em> just around the
+ // call to the constructor. If ANY advice gets put on it, we move
+ // the NEW instruction inside the join point, which involves putting
// all the arguments in temps.
- public static BcelShadow makeConstructorCall(
- BcelWorld world,
- LazyMethodGen enclosingMethod,
- InstructionHandle callHandle,
- BcelShadow enclosingShadow)
- {
- final InstructionList body = enclosingMethod.getBody();
-
- Member sig = world.makeJoinPointSignatureForMethodInvocation(
- enclosingMethod.getEnclosingClass(),
- (InvokeInstruction) callHandle.getInstruction());
-
- BcelShadow s =
- new BcelShadow(
- world,
- ConstructorCall,
- sig,
- enclosingMethod,
- enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, callHandle),
- Range.genEnd(body, callHandle));
- retargetAllBranches(callHandle, r.getStart());
- return s;
- }
-
- public static BcelShadow makeArrayConstructorCall(BcelWorld world,LazyMethodGen enclosingMethod,InstructionHandle arrayInstruction,BcelShadow enclosingShadow) {
- final InstructionList body = enclosingMethod.getBody();
- Member sig = world.makeJoinPointSignatureForArrayConstruction(enclosingMethod.getEnclosingClass(),arrayInstruction);
- BcelShadow s =
- new BcelShadow(
- world,
- ConstructorCall,
- sig,
- enclosingMethod,
- enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, arrayInstruction),
- Range.genEnd(body, arrayInstruction));
- retargetAllBranches(arrayInstruction, r.getStart());
- return s;
- }
-
- public static BcelShadow makeMonitorEnter(BcelWorld world,LazyMethodGen enclosingMethod,InstructionHandle monitorInstruction,BcelShadow enclosingShadow) {
- final InstructionList body = enclosingMethod.getBody();
- Member sig = world.makeJoinPointSignatureForMonitorEnter(enclosingMethod.getEnclosingClass(),monitorInstruction);
- BcelShadow s = new BcelShadow(world,SynchronizationLock,sig,enclosingMethod,enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, monitorInstruction),
- Range.genEnd(body, monitorInstruction));
- retargetAllBranches(monitorInstruction, r.getStart());
- return s;
- }
-
- public static BcelShadow makeMonitorExit(BcelWorld world,LazyMethodGen enclosingMethod,InstructionHandle monitorInstruction,BcelShadow enclosingShadow) {
- final InstructionList body = enclosingMethod.getBody();
- Member sig = world.makeJoinPointSignatureForMonitorExit(enclosingMethod.getEnclosingClass(),monitorInstruction);
- BcelShadow s = new BcelShadow(world,SynchronizationUnlock,sig,enclosingMethod,enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, monitorInstruction),
- Range.genEnd(body, monitorInstruction));
- retargetAllBranches(monitorInstruction, r.getStart());
- return s;
- }
-
- // see pr77166
-// public static BcelShadow makeArrayLoadCall(
-// BcelWorld world,
-// LazyMethodGen enclosingMethod,
-// InstructionHandle arrayInstruction,
-// BcelShadow enclosingShadow)
-// {
-// final InstructionList body = enclosingMethod.getBody();
-// Member sig = world.makeJoinPointSignatureForArrayLoad(enclosingMethod.getEnclosingClass(),arrayInstruction);
-// BcelShadow s =
-// new BcelShadow(
-// world,
-// MethodCall,
-// sig,
-// enclosingMethod,
-// enclosingShadow);
-// ShadowRange r = new ShadowRange(body);
-// r.associateWithShadow(s);
-// r.associateWithTargets(
-// Range.genStart(body, arrayInstruction),
-// Range.genEnd(body, arrayInstruction));
-// retargetAllBranches(arrayInstruction, r.getStart());
-// return s;
-// }
-
- public static BcelShadow makeMethodCall(
- BcelWorld world,
- LazyMethodGen enclosingMethod,
- InstructionHandle callHandle,
- BcelShadow enclosingShadow)
- {
- final InstructionList body = enclosingMethod.getBody();
- BcelShadow s =
- new BcelShadow(
- world,
- MethodCall,
- world.makeJoinPointSignatureForMethodInvocation(
- enclosingMethod.getEnclosingClass(),
- (InvokeInstruction) callHandle.getInstruction()),
- enclosingMethod,
- enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, callHandle),
- Range.genEnd(body, callHandle));
- retargetAllBranches(callHandle, r.getStart());
- return s;
- }
-
-
- public static BcelShadow makeShadowForMethodCall(
- BcelWorld world,
- LazyMethodGen enclosingMethod,
- InstructionHandle callHandle,
- BcelShadow enclosingShadow,
- Kind kind,
- ResolvedMember sig)
- {
- final InstructionList body = enclosingMethod.getBody();
- BcelShadow s =
- new BcelShadow(
- world,
- kind,
- sig,
- enclosingMethod,
- enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, callHandle),
- Range.genEnd(body, callHandle));
- retargetAllBranches(callHandle, r.getStart());
- return s;
- }
-
-
- public static BcelShadow makeFieldGet(
- BcelWorld world,
- ResolvedMember field,
- LazyMethodGen enclosingMethod,
- InstructionHandle getHandle,
- BcelShadow enclosingShadow)
- {
- final InstructionList body = enclosingMethod.getBody();
- BcelShadow s =
- new BcelShadow(
- world,
- FieldGet,
- field,
-// BcelWorld.makeFieldSignature(
-// enclosingMethod.getEnclosingClass(),
-// (FieldInstruction) getHandle.getInstruction()),
- enclosingMethod,
- enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, getHandle),
- Range.genEnd(body, getHandle));
- retargetAllBranches(getHandle, r.getStart());
- return s;
- }
-
- public static BcelShadow makeFieldSet(
- BcelWorld world,
- ResolvedMember field,
- LazyMethodGen enclosingMethod,
- InstructionHandle setHandle,
- BcelShadow enclosingShadow)
- {
- final InstructionList body = enclosingMethod.getBody();
- BcelShadow s =
- new BcelShadow(
- world,
- FieldSet,
- field,
-// BcelWorld.makeFieldJoinPointSignature(
-// enclosingMethod.getEnclosingClass(),
-// (FieldInstruction) setHandle.getInstruction()),
- enclosingMethod,
- enclosingShadow);
- ShadowRange r = new ShadowRange(body);
- r.associateWithShadow(s);
- r.associateWithTargets(
- Range.genStart(body, setHandle),
- Range.genEnd(body, setHandle));
- retargetAllBranches(setHandle, r.getStart());
- return s;
- }
+ public static BcelShadow makeConstructorCall(BcelWorld world, LazyMethodGen enclosingMethod, InstructionHandle callHandle,
+ BcelShadow enclosingShadow) {
+ final InstructionList body = enclosingMethod.getBody();
+
+ Member sig = world.makeJoinPointSignatureForMethodInvocation(enclosingMethod.getEnclosingClass(),
+ (InvokeInstruction) callHandle.getInstruction());
+
+ BcelShadow s = new BcelShadow(world, ConstructorCall, sig, enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, callHandle), Range.genEnd(body, callHandle));
+ retargetAllBranches(callHandle, r.getStart());
+ return s;
+ }
+
+ public static BcelShadow makeArrayConstructorCall(BcelWorld world, LazyMethodGen enclosingMethod,
+ InstructionHandle arrayInstruction, BcelShadow enclosingShadow) {
+ final InstructionList body = enclosingMethod.getBody();
+ Member sig = world.makeJoinPointSignatureForArrayConstruction(enclosingMethod.getEnclosingClass(), arrayInstruction);
+ BcelShadow s = new BcelShadow(world, ConstructorCall, sig, enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, arrayInstruction), Range.genEnd(body, arrayInstruction));
+ retargetAllBranches(arrayInstruction, r.getStart());
+ return s;
+ }
+
+ public static BcelShadow makeMonitorEnter(BcelWorld world, LazyMethodGen enclosingMethod, InstructionHandle monitorInstruction,
+ BcelShadow enclosingShadow) {
+ final InstructionList body = enclosingMethod.getBody();
+ Member sig = world.makeJoinPointSignatureForMonitorEnter(enclosingMethod.getEnclosingClass(), monitorInstruction);
+ BcelShadow s = new BcelShadow(world, SynchronizationLock, sig, enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, monitorInstruction), Range.genEnd(body, monitorInstruction));
+ retargetAllBranches(monitorInstruction, r.getStart());
+ return s;
+ }
+
+ public static BcelShadow makeMonitorExit(BcelWorld world, LazyMethodGen enclosingMethod, InstructionHandle monitorInstruction,
+ BcelShadow enclosingShadow) {
+ final InstructionList body = enclosingMethod.getBody();
+ Member sig = world.makeJoinPointSignatureForMonitorExit(enclosingMethod.getEnclosingClass(), monitorInstruction);
+ BcelShadow s = new BcelShadow(world, SynchronizationUnlock, sig, enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, monitorInstruction), Range.genEnd(body, monitorInstruction));
+ retargetAllBranches(monitorInstruction, r.getStart());
+ return s;
+ }
+
+ // see pr77166
+ // public static BcelShadow makeArrayLoadCall(
+ // BcelWorld world,
+ // LazyMethodGen enclosingMethod,
+ // InstructionHandle arrayInstruction,
+ // BcelShadow enclosingShadow)
+ // {
+ // final InstructionList body = enclosingMethod.getBody();
+ // Member sig = world.makeJoinPointSignatureForArrayLoad(enclosingMethod.getEnclosingClass(),arrayInstruction);
+ // BcelShadow s =
+ // new BcelShadow(
+ // world,
+ // MethodCall,
+ // sig,
+ // enclosingMethod,
+ // enclosingShadow);
+ // ShadowRange r = new ShadowRange(body);
+ // r.associateWithShadow(s);
+ // r.associateWithTargets(
+ // Range.genStart(body, arrayInstruction),
+ // Range.genEnd(body, arrayInstruction));
+ // retargetAllBranches(arrayInstruction, r.getStart());
+ // return s;
+ // }
+
+ public static BcelShadow makeMethodCall(BcelWorld world, LazyMethodGen enclosingMethod, InstructionHandle callHandle,
+ BcelShadow enclosingShadow) {
+ final InstructionList body = enclosingMethod.getBody();
+ BcelShadow s = new BcelShadow(world, MethodCall, world.makeJoinPointSignatureForMethodInvocation(enclosingMethod
+ .getEnclosingClass(), (InvokeInstruction) callHandle.getInstruction()), enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, callHandle), Range.genEnd(body, callHandle));
+ retargetAllBranches(callHandle, r.getStart());
+ return s;
+ }
+
+ public static BcelShadow makeShadowForMethodCall(BcelWorld world, LazyMethodGen enclosingMethod, InstructionHandle callHandle,
+ BcelShadow enclosingShadow, Kind kind, ResolvedMember sig) {
+ final InstructionList body = enclosingMethod.getBody();
+ BcelShadow s = new BcelShadow(world, kind, sig, enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, callHandle), Range.genEnd(body, callHandle));
+ retargetAllBranches(callHandle, r.getStart());
+ return s;
+ }
+
+ public static BcelShadow makeFieldGet(BcelWorld world, ResolvedMember field, LazyMethodGen enclosingMethod,
+ InstructionHandle getHandle, BcelShadow enclosingShadow) {
+ final InstructionList body = enclosingMethod.getBody();
+ BcelShadow s = new BcelShadow(world, FieldGet, field,
+ // BcelWorld.makeFieldSignature(
+ // enclosingMethod.getEnclosingClass(),
+ // (FieldInstruction) getHandle.getInstruction()),
+ enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, getHandle), Range.genEnd(body, getHandle));
+ retargetAllBranches(getHandle, r.getStart());
+ return s;
+ }
+
+ public static BcelShadow makeFieldSet(BcelWorld world, ResolvedMember field, LazyMethodGen enclosingMethod,
+ InstructionHandle setHandle, BcelShadow enclosingShadow) {
+ final InstructionList body = enclosingMethod.getBody();
+ BcelShadow s = new BcelShadow(world, FieldSet, field,
+ // BcelWorld.makeFieldJoinPointSignature(
+ // enclosingMethod.getEnclosingClass(),
+ // (FieldInstruction) setHandle.getInstruction()),
+ enclosingMethod, enclosingShadow);
+ ShadowRange r = new ShadowRange(body);
+ r.associateWithShadow(s);
+ r.associateWithTargets(Range.genStart(body, setHandle), Range.genEnd(body, setHandle));
+ retargetAllBranches(setHandle, r.getStart());
+ return s;
+ }
public static void retargetAllBranches(InstructionHandle from, InstructionHandle to) {
InstructionTargeter[] sources = from.getTargetersArray();
@@ -998,163 +814,173 @@ public class BcelShadow extends Shadow {
}
}
-// // ---- type access methods
-// private ObjectType getTargetBcelType() {
-// return (ObjectType) BcelWorld.makeBcelType(getTargetType());
-// }
-// private Type getArgBcelType(int arg) {
-// return BcelWorld.makeBcelType(getArgType(arg));
-// }
+ // // ---- type access methods
+ // private ObjectType getTargetBcelType() {
+ // return (ObjectType) BcelWorld.makeBcelType(getTargetType());
+ // }
+ // private Type getArgBcelType(int arg) {
+ // return BcelWorld.makeBcelType(getArgType(arg));
+ // }
- // ---- kinding
+ // ---- kinding
/**
- * If the end of my range has no real instructions following then
- * my context needs a return at the end.
+ * If the end of my range has no real instructions following then my context needs a return at the end.
*/
- public boolean terminatesWithReturn() {
- return getRange().getRealNext() == null;
- }
-
- /**
+ public boolean terminatesWithReturn() {
+ return getRange().getRealNext() == null;
+ }
+
+ /**
* Is arg0 occupied with the value of this
*/
- public boolean arg0HoldsThis() {
- if (getKind().isEnclosingKind()) {
- return !getSignature().isStatic();
- } else if (enclosingShadow == null) {
- //XXX this is mostly right
- // this doesn't do the right thing for calls in the pre part of introduced constructors.
- return !enclosingMethod.isStatic();
- } else {
- return ((BcelShadow)enclosingShadow).arg0HoldsThis();
- }
- }
-
- // ---- argument getting methods
-
- private BcelVar thisVar = null;
- private BcelVar targetVar = null;
- private BcelVar[] argVars = null;
- private Map/*<UnresolvedType,BcelVar>*/ kindedAnnotationVars = null;
- private Map/*<UnresolvedType,BcelVar>*/ thisAnnotationVars = null;
- private Map/*<UnresolvedType,BcelVar>*/ targetAnnotationVars = null;
- private Map/*<UnresolvedType,BcelVar>*/[] argAnnotationVars = null;
- private Map/*<UnresolvedType,BcelVar>*/ withinAnnotationVars = null;
- private Map/*<UnresolvedType,BcelVar>*/ withincodeAnnotationVars = null;
-
- public Var getThisVar() {
- if (!hasThis()) {
- throw new IllegalStateException("no this");
- }
- initializeThisVar();
- return thisVar;
- }
+ public boolean arg0HoldsThis() {
+ if (getKind().isEnclosingKind()) {
+ return !getSignature().isStatic();
+ } else if (enclosingShadow == null) {
+ // XXX this is mostly right
+ // this doesn't do the right thing for calls in the pre part of introduced constructors.
+ return !enclosingMethod.isStatic();
+ } else {
+ return ((BcelShadow) enclosingShadow).arg0HoldsThis();
+ }
+ }
+
+ // ---- argument getting methods
+
+ private BcelVar thisVar = null;
+ private BcelVar targetVar = null;
+ private BcelVar[] argVars = null;
+ private Map/* <UnresolvedType,BcelVar> */kindedAnnotationVars = null;
+ private Map/* <UnresolvedType,BcelVar> */thisAnnotationVars = null;
+ private Map/* <UnresolvedType,BcelVar> */targetAnnotationVars = null;
+ private Map/* <UnresolvedType,BcelVar> */[] argAnnotationVars = null;
+ private Map/* <UnresolvedType,BcelVar> */withinAnnotationVars = null;
+ private Map/* <UnresolvedType,BcelVar> */withincodeAnnotationVars = null;
+
+ public Var getThisVar() {
+ if (!hasThis()) {
+ throw new IllegalStateException("no this");
+ }
+ initializeThisVar();
+ return thisVar;
+ }
+
public Var getThisAnnotationVar(UnresolvedType forAnnotationType) {
- if (!hasThis()) {
- throw new IllegalStateException("no this");
- }
- initializeThisAnnotationVars(); // FIXME asc Why bother with this if we always return one?
- // Even if we can't find one, we have to return one as we might have this annotation at runtime
- Var v = (Var) thisAnnotationVars.get(forAnnotationType);
- if (v==null)
- v = new TypeAnnotationAccessVar(forAnnotationType.resolve(world),(BcelVar)getThisVar());
- return v;
- }
- public Var getTargetVar() {
- if (!hasTarget()) {
- throw new IllegalStateException("no target");
- }
- initializeTargetVar();
- return targetVar;
- }
- public Var getTargetAnnotationVar(UnresolvedType forAnnotationType) {
- if (!hasTarget()) {
- throw new IllegalStateException("no target");
- }
- initializeTargetAnnotationVars(); // FIXME asc why bother with this if we always return one?
- Var v =(Var) targetAnnotationVars.get(forAnnotationType);
- // Even if we can't find one, we have to return one as we might have this annotation at runtime
- if (v==null)
- v = new TypeAnnotationAccessVar(forAnnotationType.resolve(world),(BcelVar)getTargetVar());
+ if (!hasThis()) {
+ throw new IllegalStateException("no this");
+ }
+ initializeThisAnnotationVars(); // FIXME asc Why bother with this if we always return one?
+ // Even if we can't find one, we have to return one as we might have this annotation at runtime
+ Var v = (Var) thisAnnotationVars.get(forAnnotationType);
+ if (v == null)
+ v = new TypeAnnotationAccessVar(forAnnotationType.resolve(world), (BcelVar) getThisVar());
return v;
- }
- public Var getArgVar(int i) {
- initializeArgVars();
- return argVars[i];
- }
- public Var getArgAnnotationVar(int i,UnresolvedType forAnnotationType) {
+ }
+
+ public Var getTargetVar() {
+ if (!hasTarget()) {
+ throw new IllegalStateException("no target");
+ }
+ initializeTargetVar();
+ return targetVar;
+ }
+
+ public Var getTargetAnnotationVar(UnresolvedType forAnnotationType) {
+ if (!hasTarget()) {
+ throw new IllegalStateException("no target");
+ }
+ initializeTargetAnnotationVars(); // FIXME asc why bother with this if we always return one?
+ Var v = (Var) targetAnnotationVars.get(forAnnotationType);
+ // Even if we can't find one, we have to return one as we might have this annotation at runtime
+ if (v == null)
+ v = new TypeAnnotationAccessVar(forAnnotationType.resolve(world), (BcelVar) getTargetVar());
+ return v;
+ }
+
+ public Var getArgVar(int i) {
+ initializeArgVars();
+ return argVars[i];
+ }
+
+ public Var getArgAnnotationVar(int i, UnresolvedType forAnnotationType) {
initializeArgAnnotationVars();
-
- Var v= (Var) argAnnotationVars[i].get(forAnnotationType);
- if (v==null)
- v = new TypeAnnotationAccessVar(forAnnotationType.resolve(world),(BcelVar)getArgVar(i));
+
+ Var v = (Var) argAnnotationVars[i].get(forAnnotationType);
+ if (v == null)
+ v = new TypeAnnotationAccessVar(forAnnotationType.resolve(world), (BcelVar) getArgVar(i));
return v;
- }
- public Var getKindedAnnotationVar(UnresolvedType forAnnotationType) {
- initializeKindedAnnotationVars();
- return (Var) kindedAnnotationVars.get(forAnnotationType);
- }
+ }
+
+ public Var getKindedAnnotationVar(UnresolvedType forAnnotationType) {
+ initializeKindedAnnotationVars();
+ return (Var) kindedAnnotationVars.get(forAnnotationType);
+ }
+
public Var getWithinAnnotationVar(UnresolvedType forAnnotationType) {
initializeWithinAnnotationVars();
return (Var) withinAnnotationVars.get(forAnnotationType);
- }
+ }
+
public Var getWithinCodeAnnotationVar(UnresolvedType forAnnotationType) {
initializeWithinCodeAnnotationVars();
return (Var) withincodeAnnotationVars.get(forAnnotationType);
}
-
- // reflective thisJoinPoint support
- private BcelVar thisJoinPointVar = null;
- private boolean isThisJoinPointLazy;
- private int lazyTjpConsumers = 0;
- private BcelVar thisJoinPointStaticPartVar = null;
- // private BcelVar thisEnclosingJoinPointStaticPartVar = null;
-
+
+ // reflective thisJoinPoint support
+ private BcelVar thisJoinPointVar = null;
+ private boolean isThisJoinPointLazy;
+ private int lazyTjpConsumers = 0;
+ private BcelVar thisJoinPointStaticPartVar = null;
+
+ // private BcelVar thisEnclosingJoinPointStaticPartVar = null;
+
public final Var getThisJoinPointStaticPartVar() {
return getThisJoinPointStaticPartBcelVar();
}
+
public final Var getThisEnclosingJoinPointStaticPartVar() {
return getThisEnclosingJoinPointStaticPartBcelVar();
}
-
- public void requireThisJoinPoint(boolean hasGuardTest, boolean isAround) {
- if (!isAround){
+
+ public void requireThisJoinPoint(boolean hasGuardTest, boolean isAround) {
+ if (!isAround) {
if (!hasGuardTest) {
isThisJoinPointLazy = false;
} else {
lazyTjpConsumers++;
}
}
-// if (!hasGuardTest) {
-// isThisJoinPointLazy = false;
-// } else {
-// lazyTjpConsumers++;
-// }
- if (thisJoinPointVar == null) {
+ // if (!hasGuardTest) {
+ // isThisJoinPointLazy = false;
+ // } else {
+ // lazyTjpConsumers++;
+ // }
+ if (thisJoinPointVar == null) {
thisJoinPointVar = genTempVar(UnresolvedType.forName("org.aspectj.lang.JoinPoint"));
- }
- }
-
-
- public Var getThisJoinPointVar() {
- requireThisJoinPoint(false,false);
- return thisJoinPointVar;
- }
-
- void initializeThisJoinPoint() {
- if (thisJoinPointVar == null) return;
-
- if (isThisJoinPointLazy) {
- isThisJoinPointLazy = checkLazyTjp();
- }
-
+ }
+ }
+
+ public Var getThisJoinPointVar() {
+ requireThisJoinPoint(false, false);
+ return thisJoinPointVar;
+ }
+
+ void initializeThisJoinPoint() {
+ if (thisJoinPointVar == null)
+ return;
+
+ if (isThisJoinPointLazy) {
+ isThisJoinPointLazy = checkLazyTjp();
+ }
+
if (isThisJoinPointLazy) {
appliedLazyTjpOptimization = true;
createThisJoinPoint(); // make sure any state needed is initialized, but throw the instructions out
-
- if (lazyTjpConsumers == 1) return; // special case only one lazyTjpUser
-
+
+ if (lazyTjpConsumers == 1)
+ return; // special case only one lazyTjpUser
+
InstructionFactory fact = getFactory();
InstructionList il = new InstructionList();
il.append(InstructionConstants.ACONST_NULL);
@@ -1167,682 +993,657 @@ public class BcelShadow extends Shadow {
il.append(thisJoinPointVar.createStore(fact));
range.insert(il, Range.OutsideBefore);
}
- }
-
- private boolean checkLazyTjp() {
- // check for around advice
- for (Iterator i = mungers.iterator(); i.hasNext();) {
+ }
+
+ private boolean checkLazyTjp() {
+ // check for around advice
+ for (Iterator i = mungers.iterator(); i.hasNext();) {
ShadowMunger munger = (ShadowMunger) i.next();
if (munger instanceof Advice) {
- if ( ((Advice)munger).getKind() == AdviceKind.Around) {
- if (munger.getSourceLocation()!=null) { // do we know enough to bother reporting?
+ if (((Advice) munger).getKind() == AdviceKind.Around) {
+ if (munger.getSourceLocation() != null) { // do we know enough to bother reporting?
if (world.getLint().canNotImplementLazyTjp.isEnabled()) {
- world.getLint().canNotImplementLazyTjp.signal(
- new String[] {toString()},
- getSourceLocation(),
- new ISourceLocation[] { munger.getSourceLocation() }
- );
+ world.getLint().canNotImplementLazyTjp.signal(new String[] { toString() }, getSourceLocation(),
+ new ISourceLocation[] { munger.getSourceLocation() });
}
}
return false;
}
}
}
-
- return true;
- }
-
- InstructionList loadThisJoinPoint() {
+
+ return true;
+ }
+
+ InstructionList loadThisJoinPoint() {
InstructionFactory fact = getFactory();
InstructionList il = new InstructionList();
- if (isThisJoinPointLazy) {
- // If we're lazy, build the join point right here.
- il.append(createThisJoinPoint());
-
- // Does someone else need it? If so, store it for later retrieval
- if (lazyTjpConsumers > 1) {
+ if (isThisJoinPointLazy) {
+ // If we're lazy, build the join point right here.
+ il.append(createThisJoinPoint());
+
+ // Does someone else need it? If so, store it for later retrieval
+ if (lazyTjpConsumers > 1) {
il.append(thisJoinPointVar.createStore(fact));
-
+
InstructionHandle end = il.append(thisJoinPointVar.createLoad(fact));
-
+
il.insert(InstructionFactory.createBranchInstruction(Constants.IFNONNULL, end));
il.insert(thisJoinPointVar.createLoad(fact));
- }
- } else {
- // If not lazy, its already been built and stored, just retrieve it
+ }
+ } else {
+ // If not lazy, its already been built and stored, just retrieve it
thisJoinPointVar.appendLoad(il, fact);
- }
-
+ }
+
return il;
- }
+ }
InstructionList createThisJoinPoint() {
InstructionFactory fact = getFactory();
InstructionList il = new InstructionList();
-
+
BcelVar staticPart = getThisJoinPointStaticPartBcelVar();
staticPart.appendLoad(il, fact);
if (hasThis()) {
- ((BcelVar)getThisVar()).appendLoad(il, fact);
+ ((BcelVar) getThisVar()).appendLoad(il, fact);
} else {
il.append(InstructionConstants.ACONST_NULL);
}
if (hasTarget()) {
- ((BcelVar)getTargetVar()).appendLoad(il, fact);
+ ((BcelVar) getTargetVar()).appendLoad(il, fact);
} else {
il.append(InstructionConstants.ACONST_NULL);
}
-
- switch(getArgCount()) {
- case 0:
- il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory",
- "makeJP", LazyClassGen.tjpType,
- new Type[] { LazyClassGen.staticTjpType,
- Type.OBJECT, Type.OBJECT},
- Constants.INVOKESTATIC));
- break;
- case 1:
- ((BcelVar)getArgVar(0)).appendLoadAndConvert(il, fact, world.getCoreType(ResolvedType.OBJECT));
- il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory",
- "makeJP", LazyClassGen.tjpType,
- new Type[] { LazyClassGen.staticTjpType,
- Type.OBJECT, Type.OBJECT, Type.OBJECT},
- Constants.INVOKESTATIC));
- break;
- case 2:
- ((BcelVar)getArgVar(0)).appendLoadAndConvert(il, fact, world.getCoreType(ResolvedType.OBJECT));
- ((BcelVar)getArgVar(1)).appendLoadAndConvert(il, fact, world.getCoreType(ResolvedType.OBJECT));
- il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory",
- "makeJP", LazyClassGen.tjpType,
- new Type[] { LazyClassGen.staticTjpType,
- Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT},
- Constants.INVOKESTATIC));
- break;
- default:
- il.append(makeArgsObjectArray());
- il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory",
- "makeJP", LazyClassGen.tjpType,
- new Type[] { LazyClassGen.staticTjpType,
- Type.OBJECT, Type.OBJECT, new ArrayType(Type.OBJECT, 1)},
- Constants.INVOKESTATIC));
- break;
- }
-
+
+ switch (getArgCount()) {
+ case 0:
+ il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory", "makeJP", LazyClassGen.tjpType, new Type[] {
+ LazyClassGen.staticTjpType, Type.OBJECT, Type.OBJECT }, Constants.INVOKESTATIC));
+ break;
+ case 1:
+ ((BcelVar) getArgVar(0)).appendLoadAndConvert(il, fact, world.getCoreType(ResolvedType.OBJECT));
+ il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory", "makeJP", LazyClassGen.tjpType, new Type[] {
+ LazyClassGen.staticTjpType, Type.OBJECT, Type.OBJECT, Type.OBJECT }, Constants.INVOKESTATIC));
+ break;
+ case 2:
+ ((BcelVar) getArgVar(0)).appendLoadAndConvert(il, fact, world.getCoreType(ResolvedType.OBJECT));
+ ((BcelVar) getArgVar(1)).appendLoadAndConvert(il, fact, world.getCoreType(ResolvedType.OBJECT));
+ il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory", "makeJP", LazyClassGen.tjpType, new Type[] {
+ LazyClassGen.staticTjpType, Type.OBJECT, Type.OBJECT, Type.OBJECT, Type.OBJECT }, Constants.INVOKESTATIC));
+ break;
+ default:
+ il.append(makeArgsObjectArray());
+ il.append(fact.createInvoke("org.aspectj.runtime.reflect.Factory", "makeJP", LazyClassGen.tjpType, new Type[] {
+ LazyClassGen.staticTjpType, Type.OBJECT, Type.OBJECT, new ArrayType(Type.OBJECT, 1) }, Constants.INVOKESTATIC));
+ break;
+ }
+
return il;
}
- /**
- * Get the Var for the jpStaticPart
- * @return
- */
- public BcelVar getThisJoinPointStaticPartBcelVar() {
- return getThisJoinPointStaticPartBcelVar(false);
- }
-
- /**
- * Get the Var for the xxxxJpStaticPart, xxx = this or enclosing
- * @param isEnclosingJp true to have the enclosingJpStaticPart
- * @return
- */
- public BcelVar getThisJoinPointStaticPartBcelVar(final boolean isEnclosingJp) {
- if (thisJoinPointStaticPartVar == null) {
- Field field = getEnclosingClass().getTjpField(this, isEnclosingJp);
- ResolvedType sjpType = null;
- if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have different jpsp types in 1.2
- sjpType = world.getCoreType(UnresolvedType.JOINPOINT_STATICPART);
- } else {
- sjpType = isEnclosingJp?
- world.getCoreType(UnresolvedType.JOINPOINT_ENCLOSINGSTATICPART):
- world.getCoreType(UnresolvedType.JOINPOINT_STATICPART);
- }
- thisJoinPointStaticPartVar = new BcelFieldRef(
- sjpType,
- getEnclosingClass().getClassName(),
- field.getName());
-// getEnclosingClass().warnOnAddedStaticInitializer(this,munger.getSourceLocation());
- }
- return thisJoinPointStaticPartVar;
- }
-
- /**
- * Get the Var for the enclosingJpStaticPart
- * @return
- */
- public BcelVar getThisEnclosingJoinPointStaticPartBcelVar() {
- if (enclosingShadow == null) {
- // the enclosing of an execution is itself
- return getThisJoinPointStaticPartBcelVar(true);
- } else {
- return ((BcelShadow)enclosingShadow).getThisJoinPointStaticPartBcelVar(true);
- }
- }
-
- //??? need to better understand all the enclosing variants
- public Member getEnclosingCodeSignature() {
- if (getKind().isEnclosingKind()) {
- return getSignature();
- } else if (getKind() == Shadow.PreInitialization) {
- // PreInit doesn't enclose code but its signature
- // is correctly the signature of the ctor.
- return getSignature();
- } else if (enclosingShadow == null) {
- return getEnclosingMethod().getMemberView();
- } else {
- return enclosingShadow.getSignature();
- }
- }
-
-
- private InstructionList makeArgsObjectArray() {
- InstructionFactory fact = getFactory();
- BcelVar arrayVar = genTempVar(UnresolvedType.OBJECTARRAY);
- final InstructionList il = new InstructionList();
- int alen = getArgCount() ;
- il.append(Utility.createConstant(fact, alen));
- il.append(fact.createNewArray(Type.OBJECT, (short)1));
- arrayVar.appendStore(il, fact);
-
- int stateIndex = 0;
- for (int i = 0, len = getArgCount(); i<len; i++) {
- arrayVar.appendConvertableArrayStore(il, fact, stateIndex, (BcelVar)getArgVar(i));
- stateIndex++;
- }
- arrayVar.appendLoad(il, fact);
- return il;
- }
-
- // ---- initializing var tables
-
- /* initializing this is doesn't do anything, because this
- * is protected from side-effects, so we don't need to copy its location
- */
-
- private void initializeThisVar() {
- if (thisVar != null) return;
- thisVar = new BcelVar(getThisType().resolve(world), 0);
- thisVar.setPositionInAroundState(0);
- }
- public void initializeTargetVar() {
- InstructionFactory fact = getFactory();
- if (targetVar != null) return;
- if (getKind().isTargetSameAsThis()) {
- if (hasThis()) initializeThisVar();
- targetVar = thisVar;
- } else {
- initializeArgVars(); // gotta pop off the args before we find the target
- UnresolvedType type = getTargetType();
- type = ensureTargetTypeIsCorrect(type);
- targetVar = genTempVar(type, "ajc$target");
- range.insert(targetVar.createStore(fact), Range.OutsideBefore);
- targetVar.setPositionInAroundState(hasThis() ? 1 : 0);
- }
- }
-
- /* PR 72528
- * This method double checks the target type under certain conditions. The Java 1.4
- * compilers seem to take calls to clone methods on array types and create bytecode that
- * looks like clone is being called on Object. If we advise a clone call with around
- * advice we extract the call into a helper method which we can then refer to. Because the
- * type in the bytecode for the call to clone is Object we create a helper method with
- * an Object parameter - this is not correct as we have lost the fact that the actual
- * type is an array type. If we don't do the check below we will create code that fails
- * java verification. This method checks for the peculiar set of conditions and if they
- * are true, it has a sneak peek at the code before the call to see what is on the stack.
- */
- public UnresolvedType ensureTargetTypeIsCorrect(UnresolvedType tx) {
-
- Member msig = getSignature();
- if (msig.getArity()==0 &&
- getKind() == MethodCall &&
- msig.getName().charAt(0) == 'c' &&
- tx.equals(ResolvedType.OBJECT) &&
- msig.getReturnType().equals(ResolvedType.OBJECT) &&
- msig.getName().equals("clone")) {
-
- // Lets go back through the code from the start of the shadow
- InstructionHandle searchPtr = range.getStart().getPrev();
- while (Range.isRangeHandle(searchPtr) ||
- searchPtr.getInstruction().isStoreInstruction()) { // ignore this instruction - it doesnt give us the info we want
- searchPtr = searchPtr.getPrev();
- }
-
- // A load instruction may tell us the real type of what the clone() call is on
- if (searchPtr.getInstruction().isLoadInstruction()) {
- LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr,searchPtr.getInstruction().getIndex());
- if (lvt!=null) return UnresolvedType.forSignature(lvt.getType());
- }
- // A field access instruction may tell us the real type of what the clone() call is on
- if (searchPtr.getInstruction() instanceof FieldInstruction) {
- FieldInstruction si = (FieldInstruction)searchPtr.getInstruction();
- Type t = si.getFieldType(getEnclosingClass().getConstantPool());
- return BcelWorld.fromBcel(t);
- }
- // A new array instruction obviously tells us it is an array type !
- if (searchPtr.getInstruction().opcode==Constants.ANEWARRAY) {
- //ANEWARRAY ana = (ANEWARRAY)searchPoint.getInstruction();
-// Type t = ana.getType(getEnclosingClass().getConstantPool());
- // Just use a standard java.lang.object array - that will work fine
- return BcelWorld.fromBcel(new ArrayType(Type.OBJECT,1));
- }
- // A multi new array instruction obviously tells us it is an array type !
- if (searchPtr.getInstruction() instanceof MULTIANEWARRAY) {
- MULTIANEWARRAY ana = (MULTIANEWARRAY)searchPtr.getInstruction();
- // Type t = ana.getType(getEnclosingClass().getConstantPool());
- // t = new ArrayType(t,ana.getDimensions());
- // Just use a standard java.lang.object array - that will work fine
- return BcelWorld.fromBcel(new ArrayType(Type.OBJECT,ana.getDimensions()));
- }
- throw new BCException("Can't determine real target of clone() when processing instruction "+
- searchPtr.getInstruction()+". Perhaps avoid selecting clone with your pointcut?");
- }
- return tx;
- }
-
-
- public void initializeArgVars() {
- if (argVars != null) return;
- InstructionFactory fact = getFactory();
- int len = getArgCount();
- argVars = new BcelVar[len];
- int positionOffset = (hasTarget() ? 1 : 0) +
- ((hasThis() && !getKind().isTargetSameAsThis()) ? 1 : 0);
-
- if (getKind().argsOnStack()) {
- // we move backwards because we're popping off the stack
- for (int i = len - 1; i >= 0; i--) {
- UnresolvedType type = getArgType(i);
- BcelVar tmp = genTempVar(type, "ajc$arg" + i);
- range.insert(tmp.createStore(getFactory()), Range.OutsideBefore);
- int position = i;
- position += positionOffset;
- tmp.setPositionInAroundState(position);
- argVars[i] = tmp;
- }
- } else {
- int index = 0;
- if (arg0HoldsThis()) index++;
-
- for (int i = 0; i < len; i++) {
- UnresolvedType type = getArgType(i);
- BcelVar tmp = genTempVar(type, "ajc$arg" + i);
- range.insert(tmp.createCopyFrom(fact, index), Range.OutsideBefore);
- argVars[i] = tmp;
- int position = i;
- position += positionOffset;
-// System.out.println("set position: " + tmp + ", " + position + " in " + this);
-// System.out.println(" hasThis: " + hasThis() + ", hasTarget: " + hasTarget());
- tmp.setPositionInAroundState(position);
- index += type.getSize();
- }
- }
- }
- public void initializeForAroundClosure() {
- initializeArgVars();
- if (hasTarget()) initializeTargetVar();
- if (hasThis()) initializeThisVar();
-// System.out.println("initialized: " + this + " thisVar = " + thisVar);
- }
-
- public void initializeThisAnnotationVars() {
- if (thisAnnotationVars != null) return;
- thisAnnotationVars = new HashMap();
- // populate..
- }
- public void initializeTargetAnnotationVars() {
- if (targetAnnotationVars != null) return;
- if (getKind().isTargetSameAsThis()) {
- if (hasThis()) initializeThisAnnotationVars();
- targetAnnotationVars = thisAnnotationVars;
- } else {
- targetAnnotationVars = new HashMap();
- ResolvedType[] rtx = this.getTargetType().resolve(world).getAnnotationTypes(); // what about annotations we havent gotten yet but we will get in subclasses?
- for (int i = 0; i < rtx.length; i++) {
+ /**
+ * Get the Var for the jpStaticPart
+ *
+ * @return
+ */
+ public BcelVar getThisJoinPointStaticPartBcelVar() {
+ return getThisJoinPointStaticPartBcelVar(false);
+ }
+
+ /**
+ * Get the Var for the xxxxJpStaticPart, xxx = this or enclosing
+ *
+ * @param isEnclosingJp true to have the enclosingJpStaticPart
+ * @return
+ */
+ public BcelVar getThisJoinPointStaticPartBcelVar(final boolean isEnclosingJp) {
+ if (thisJoinPointStaticPartVar == null) {
+ Field field = getEnclosingClass().getTjpField(this, isEnclosingJp);
+ ResolvedType sjpType = null;
+ if (world.isTargettingAspectJRuntime12()) { // TAG:SUPPORTING12: We didn't have different jpsp types in 1.2
+ sjpType = world.getCoreType(UnresolvedType.JOINPOINT_STATICPART);
+ } else {
+ sjpType = isEnclosingJp ? world.getCoreType(UnresolvedType.JOINPOINT_ENCLOSINGSTATICPART) : world
+ .getCoreType(UnresolvedType.JOINPOINT_STATICPART);
+ }
+ thisJoinPointStaticPartVar = new BcelFieldRef(sjpType, getEnclosingClass().getClassName(), field.getName());
+ // getEnclosingClass().warnOnAddedStaticInitializer(this,munger.getSourceLocation());
+ }
+ return thisJoinPointStaticPartVar;
+ }
+
+ /**
+ * Get the Var for the enclosingJpStaticPart
+ *
+ * @return
+ */
+ public BcelVar getThisEnclosingJoinPointStaticPartBcelVar() {
+ if (enclosingShadow == null) {
+ // the enclosing of an execution is itself
+ return getThisJoinPointStaticPartBcelVar(true);
+ } else {
+ return ((BcelShadow) enclosingShadow).getThisJoinPointStaticPartBcelVar(true);
+ }
+ }
+
+ // ??? need to better understand all the enclosing variants
+ public Member getEnclosingCodeSignature() {
+ if (getKind().isEnclosingKind()) {
+ return getSignature();
+ } else if (getKind() == Shadow.PreInitialization) {
+ // PreInit doesn't enclose code but its signature
+ // is correctly the signature of the ctor.
+ return getSignature();
+ } else if (enclosingShadow == null) {
+ return getEnclosingMethod().getMemberView();
+ } else {
+ return enclosingShadow.getSignature();
+ }
+ }
+
+ private InstructionList makeArgsObjectArray() {
+ InstructionFactory fact = getFactory();
+ BcelVar arrayVar = genTempVar(UnresolvedType.OBJECTARRAY);
+ final InstructionList il = new InstructionList();
+ int alen = getArgCount();
+ il.append(Utility.createConstant(fact, alen));
+ il.append(fact.createNewArray(Type.OBJECT, (short) 1));
+ arrayVar.appendStore(il, fact);
+
+ int stateIndex = 0;
+ for (int i = 0, len = getArgCount(); i < len; i++) {
+ arrayVar.appendConvertableArrayStore(il, fact, stateIndex, (BcelVar) getArgVar(i));
+ stateIndex++;
+ }
+ arrayVar.appendLoad(il, fact);
+ return il;
+ }
+
+ // ---- initializing var tables
+
+ /*
+ * initializing this is doesn't do anything, because this is protected from side-effects, so we don't need to copy its location
+ */
+
+ private void initializeThisVar() {
+ if (thisVar != null)
+ return;
+ thisVar = new BcelVar(getThisType().resolve(world), 0);
+ thisVar.setPositionInAroundState(0);
+ }
+
+ public void initializeTargetVar() {
+ InstructionFactory fact = getFactory();
+ if (targetVar != null)
+ return;
+ if (getKind().isTargetSameAsThis()) {
+ if (hasThis())
+ initializeThisVar();
+ targetVar = thisVar;
+ } else {
+ initializeArgVars(); // gotta pop off the args before we find the target
+ UnresolvedType type = getTargetType();
+ type = ensureTargetTypeIsCorrect(type);
+ targetVar = genTempVar(type, "ajc$target");
+ range.insert(targetVar.createStore(fact), Range.OutsideBefore);
+ targetVar.setPositionInAroundState(hasThis() ? 1 : 0);
+ }
+ }
+
+ /*
+ * PR 72528 This method double checks the target type under certain conditions. The Java 1.4 compilers seem to take calls to
+ * clone methods on array types and create bytecode that looks like clone is being called on Object. If we advise a clone call
+ * with around advice we extract the call into a helper method which we can then refer to. Because the type in the bytecode for
+ * the call to clone is Object we create a helper method with an Object parameter - this is not correct as we have lost the fact
+ * that the actual type is an array type. If we don't do the check below we will create code that fails java verification. This
+ * method checks for the peculiar set of conditions and if they are true, it has a sneak peek at the code before the call to see
+ * what is on the stack.
+ */
+ public UnresolvedType ensureTargetTypeIsCorrect(UnresolvedType tx) {
+
+ Member msig = getSignature();
+ if (msig.getArity() == 0 && getKind() == MethodCall && msig.getName().charAt(0) == 'c' && tx.equals(ResolvedType.OBJECT)
+ && msig.getReturnType().equals(ResolvedType.OBJECT) && msig.getName().equals("clone")) {
+
+ // Lets go back through the code from the start of the shadow
+ InstructionHandle searchPtr = range.getStart().getPrev();
+ while (Range.isRangeHandle(searchPtr) || searchPtr.getInstruction().isStoreInstruction()) { // ignore this instruction -
+ // it doesnt give us the
+ // info we want
+ searchPtr = searchPtr.getPrev();
+ }
+
+ // A load instruction may tell us the real type of what the clone() call is on
+ if (searchPtr.getInstruction().isLoadInstruction()) {
+ LocalVariableTag lvt = LazyMethodGen.getLocalVariableTag(searchPtr, searchPtr.getInstruction().getIndex());
+ if (lvt != null)
+ return UnresolvedType.forSignature(lvt.getType());
+ }
+ // A field access instruction may tell us the real type of what the clone() call is on
+ if (searchPtr.getInstruction() instanceof FieldInstruction) {
+ FieldInstruction si = (FieldInstruction) searchPtr.getInstruction();
+ Type t = si.getFieldType(getEnclosingClass().getConstantPool());
+ return BcelWorld.fromBcel(t);
+ }
+ // A new array instruction obviously tells us it is an array type !
+ if (searchPtr.getInstruction().opcode == Constants.ANEWARRAY) {
+ // ANEWARRAY ana = (ANEWARRAY)searchPoint.getInstruction();
+ // Type t = ana.getType(getEnclosingClass().getConstantPool());
+ // Just use a standard java.lang.object array - that will work fine
+ return BcelWorld.fromBcel(new ArrayType(Type.OBJECT, 1));
+ }
+ // A multi new array instruction obviously tells us it is an array type !
+ if (searchPtr.getInstruction() instanceof MULTIANEWARRAY) {
+ MULTIANEWARRAY ana = (MULTIANEWARRAY) searchPtr.getInstruction();
+ // Type t = ana.getType(getEnclosingClass().getConstantPool());
+ // t = new ArrayType(t,ana.getDimensions());
+ // Just use a standard java.lang.object array - that will work fine
+ return BcelWorld.fromBcel(new ArrayType(Type.OBJECT, ana.getDimensions()));
+ }
+ throw new BCException("Can't determine real target of clone() when processing instruction "
+ + searchPtr.getInstruction() + ". Perhaps avoid selecting clone with your pointcut?");
+ }
+ return tx;
+ }
+
+ public void initializeArgVars() {
+ if (argVars != null)
+ return;
+ InstructionFactory fact = getFactory();
+ int len = getArgCount();
+ argVars = new BcelVar[len];
+ int positionOffset = (hasTarget() ? 1 : 0) + ((hasThis() && !getKind().isTargetSameAsThis()) ? 1 : 0);
+
+ if (getKind().argsOnStack()) {
+ // we move backwards because we're popping off the stack
+ for (int i = len - 1; i >= 0; i--) {
+ UnresolvedType type = getArgType(i);
+ BcelVar tmp = genTempVar(type, "ajc$arg" + i);
+ range.insert(tmp.createStore(getFactory()), Range.OutsideBefore);
+ int position = i;
+ position += positionOffset;
+ tmp.setPositionInAroundState(position);
+ argVars[i] = tmp;
+ }
+ } else {
+ int index = 0;
+ if (arg0HoldsThis())
+ index++;
+
+ for (int i = 0; i < len; i++) {
+ UnresolvedType type = getArgType(i);
+ BcelVar tmp = genTempVar(type, "ajc$arg" + i);
+ range.insert(tmp.createCopyFrom(fact, index), Range.OutsideBefore);
+ argVars[i] = tmp;
+ int position = i;
+ position += positionOffset;
+ // System.out.println("set position: " + tmp + ", " + position + " in " + this);
+ // System.out.println(" hasThis: " + hasThis() + ", hasTarget: " + hasTarget());
+ tmp.setPositionInAroundState(position);
+ index += type.getSize();
+ }
+ }
+ }
+
+ public void initializeForAroundClosure() {
+ initializeArgVars();
+ if (hasTarget())
+ initializeTargetVar();
+ if (hasThis())
+ initializeThisVar();
+ // System.out.println("initialized: " + this + " thisVar = " + thisVar);
+ }
+
+ public void initializeThisAnnotationVars() {
+ if (thisAnnotationVars != null)
+ return;
+ thisAnnotationVars = new HashMap();
+ // populate..
+ }
+
+ public void initializeTargetAnnotationVars() {
+ if (targetAnnotationVars != null)
+ return;
+ if (getKind().isTargetSameAsThis()) {
+ if (hasThis())
+ initializeThisAnnotationVars();
+ targetAnnotationVars = thisAnnotationVars;
+ } else {
+ targetAnnotationVars = new HashMap();
+ ResolvedType[] rtx = this.getTargetType().resolve(world).getAnnotationTypes(); // what about annotations we havent
+ // gotten yet but we will get in
+ // subclasses?
+ for (int i = 0; i < rtx.length; i++) {
ResolvedType typeX = rtx[i];
- targetAnnotationVars.put(typeX,new TypeAnnotationAccessVar(typeX,(BcelVar)getTargetVar()));
+ targetAnnotationVars.put(typeX, new TypeAnnotationAccessVar(typeX, (BcelVar) getTargetVar()));
}
- // populate.
- }
- }
- public void initializeArgAnnotationVars() {
- if (argAnnotationVars != null) return;
- int numArgs = getArgCount();
- argAnnotationVars = new Map[numArgs];
- for (int i = 0; i < argAnnotationVars.length; i++) {
+ // populate.
+ }
+ }
+
+ public void initializeArgAnnotationVars() {
+ if (argAnnotationVars != null)
+ return;
+ int numArgs = getArgCount();
+ argAnnotationVars = new Map[numArgs];
+ for (int i = 0; i < argAnnotationVars.length; i++) {
argAnnotationVars[i] = new HashMap();
- //FIXME asc just delete this logic - we always build the Var on demand, as we don't know at weave time
+ // FIXME asc just delete this logic - we always build the Var on demand, as we don't know at weave time
// what the full set of annotations could be (due to static/dynamic type differences...)
}
- }
-
- protected ResolvedMember getRelevantMember(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType){
- if (foundMember != null){
- return foundMember;
- }
-
-
- foundMember = getSignature().resolve(world);
- if (foundMember == null && relevantMember != null) {
- foundMember = relevantType.lookupMemberWithSupersAndITDs(relevantMember);
- }
-
- // check the ITD'd dooberries
- List mungers = relevantType.resolve(world).getInterTypeMungers();
- for (Iterator iter = mungers.iterator(); iter.hasNext();) {
- BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
- if (typeMunger.getMunger() instanceof NewMethodTypeMunger ||
- typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
- ResolvedMember fakerm = typeMunger.getSignature();
- if (fakerm.getName().equals(getSignature().getName()) &&
- fakerm.getParameterSignature().equals(getSignature().getParameterSignature())){
- if (foundMember.getKind()==ResolvedMember.CONSTRUCTOR){
- foundMember = AjcMemberMaker.interConstructor(
- relevantType,
- foundMember,
- typeMunger.getAspectType());
- } else {
- foundMember = AjcMemberMaker.interMethod(foundMember,
- typeMunger.getAspectType(), false);
- }
- // in the above.. what about if it's on an Interface? Can that happen?
- // then the last arg of the above should be true
- return foundMember;
- }
- }
- }
- return foundMember;
- }
-
- protected ResolvedType [] getAnnotations(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType){
- if (foundMember == null){
- // check the ITD'd dooberries
- List mungers = relevantType.resolve(world).getInterTypeMungers();
- for (Iterator iter = mungers.iterator(); iter.hasNext();) {
- BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
- if (typeMunger.getMunger() instanceof NewMethodTypeMunger ||
- typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
- ResolvedMember fakerm = typeMunger.getSignature();
- //if (fakerm.hasAnnotations())
-
- ResolvedMember ajcMethod = (getSignature().getKind()==ResolvedMember.CONSTRUCTOR?
- AjcMemberMaker.postIntroducedConstructor(typeMunger.getAspectType(),fakerm.getDeclaringType(),fakerm.getParameterTypes()):
- AjcMemberMaker.interMethodDispatcher(fakerm,typeMunger.getAspectType()));
- //AjcMemberMaker.interMethodBody(fakerm,typeMunger.getAspectType()));
- ResolvedMember rmm = findMethod(typeMunger.getAspectType(),ajcMethod);
- if (fakerm.getName().equals(getSignature().getName()) &&
- fakerm.getParameterSignature().equals(getSignature().getParameterSignature())) {
- relevantType = typeMunger.getAspectType();
- foundMember = rmm;
- return foundMember.getAnnotationTypes();
- }
- }
- }
- // didn't find in ITDs, look in supers
- foundMember = relevantType.lookupMemberWithSupersAndITDs(relevantMember);
- if (foundMember == null) {
- throw new IllegalStateException("Couldn't find member " + relevantMember + " for type " + relevantType);
- }
- }
- return foundMember.getAnnotationTypes();
- }
-
- /**
- * By determining what "kind" of shadow we are, we can find out the
- * annotations on the appropriate element (method, field, constructor, type).
- * Then create one BcelVar entry in the map for each annotation, keyed by
- * annotation type.
+ }
+
+ protected ResolvedMember getRelevantMember(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType) {
+ if (foundMember != null) {
+ return foundMember;
+ }
+
+ foundMember = getSignature().resolve(world);
+ if (foundMember == null && relevantMember != null) {
+ foundMember = relevantType.lookupMemberWithSupersAndITDs(relevantMember);
+ }
+
+ // check the ITD'd dooberries
+ List mungers = relevantType.resolve(world).getInterTypeMungers();
+ for (Iterator iter = mungers.iterator(); iter.hasNext();) {
+ BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
+ if (typeMunger.getMunger() instanceof NewMethodTypeMunger || typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
+ ResolvedMember fakerm = typeMunger.getSignature();
+ if (fakerm.getName().equals(getSignature().getName())
+ && fakerm.getParameterSignature().equals(getSignature().getParameterSignature())) {
+ if (foundMember.getKind() == ResolvedMember.CONSTRUCTOR) {
+ foundMember = AjcMemberMaker.interConstructor(relevantType, foundMember, typeMunger.getAspectType());
+ } else {
+ foundMember = AjcMemberMaker.interMethod(foundMember, typeMunger.getAspectType(), false);
+ }
+ // in the above.. what about if it's on an Interface? Can that happen?
+ // then the last arg of the above should be true
+ return foundMember;
+ }
+ }
+ }
+ return foundMember;
+ }
+
+ protected ResolvedType[] getAnnotations(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType) {
+ if (foundMember == null) {
+ // check the ITD'd dooberries
+ List mungers = relevantType.resolve(world).getInterTypeMungers();
+ for (Iterator iter = mungers.iterator(); iter.hasNext();) {
+ BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
+ if (typeMunger.getMunger() instanceof NewMethodTypeMunger
+ || typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
+ ResolvedMember fakerm = typeMunger.getSignature();
+ // if (fakerm.hasAnnotations())
+
+ ResolvedMember ajcMethod = (getSignature().getKind() == ResolvedMember.CONSTRUCTOR ? AjcMemberMaker
+ .postIntroducedConstructor(typeMunger.getAspectType(), fakerm.getDeclaringType(), fakerm
+ .getParameterTypes()) : AjcMemberMaker
+ .interMethodDispatcher(fakerm, typeMunger.getAspectType()));
+ // AjcMemberMaker.interMethodBody(fakerm,typeMunger.getAspectType()));
+ ResolvedMember rmm = findMethod(typeMunger.getAspectType(), ajcMethod);
+ if (fakerm.getName().equals(getSignature().getName())
+ && fakerm.getParameterSignature().equals(getSignature().getParameterSignature())) {
+ relevantType = typeMunger.getAspectType();
+ foundMember = rmm;
+ return foundMember.getAnnotationTypes();
+ }
+ }
+ }
+ // didn't find in ITDs, look in supers
+ foundMember = relevantType.lookupMemberWithSupersAndITDs(relevantMember);
+ if (foundMember == null) {
+ throw new IllegalStateException("Couldn't find member " + relevantMember + " for type " + relevantType);
+ }
+ }
+ return foundMember.getAnnotationTypes();
+ }
+
+ /**
+ * By determining what "kind" of shadow we are, we can find out the annotations on the appropriate element (method, field,
+ * constructor, type). Then create one BcelVar entry in the map for each annotation, keyed by annotation type.
*/
- public void initializeKindedAnnotationVars() {
- if (kindedAnnotationVars != null) return;
- kindedAnnotationVars = new HashMap();
-
- // FIXME asc Refactor this code, there is duplication
- ResolvedType[] annotations = null;
- Member shadowSignature = getSignature();
- Member annotationHolder = getSignature();
- ResolvedType relevantType = shadowSignature.getDeclaringType().resolve(world);
-
- if (relevantType.isRawType() || relevantType.isParameterizedType()) relevantType = relevantType.getGenericType();
-
- if (getKind() == Shadow.StaticInitialization) {
- annotations = relevantType.resolve(world).getAnnotationTypes();
- } else if (getKind() == Shadow.MethodCall || getKind() == Shadow.ConstructorCall) {
- ResolvedMember foundMember = findMethod2(relevantType.resolve(world).getDeclaredMethods(),getSignature());
- annotations = getAnnotations(foundMember, shadowSignature, relevantType);
- annotationHolder = getRelevantMember(foundMember,shadowSignature,relevantType);
- relevantType = annotationHolder.getDeclaringType().resolve(world);
-
- } else if (getKind() == Shadow.FieldSet || getKind() == Shadow.FieldGet) {
- annotationHolder = findField(relevantType.getDeclaredFields(),getSignature());
-
- if (annotationHolder==null) {
- // check the ITD'd dooberries
+ public void initializeKindedAnnotationVars() {
+ if (kindedAnnotationVars != null)
+ return;
+ kindedAnnotationVars = new HashMap();
+
+ // FIXME asc Refactor this code, there is duplication
+ ResolvedType[] annotations = null;
+ Member shadowSignature = getSignature();
+ Member annotationHolder = getSignature();
+ ResolvedType relevantType = shadowSignature.getDeclaringType().resolve(world);
+
+ if (relevantType.isRawType() || relevantType.isParameterizedType())
+ relevantType = relevantType.getGenericType();
+
+ if (getKind() == Shadow.StaticInitialization) {
+ annotations = relevantType.resolve(world).getAnnotationTypes();
+ } else if (getKind() == Shadow.MethodCall || getKind() == Shadow.ConstructorCall) {
+ ResolvedMember foundMember = findMethod2(relevantType.resolve(world).getDeclaredMethods(), getSignature());
+ annotations = getAnnotations(foundMember, shadowSignature, relevantType);
+ annotationHolder = getRelevantMember(foundMember, shadowSignature, relevantType);
+ relevantType = annotationHolder.getDeclaringType().resolve(world);
+
+ } else if (getKind() == Shadow.FieldSet || getKind() == Shadow.FieldGet) {
+ annotationHolder = findField(relevantType.getDeclaredFields(), getSignature());
+
+ if (annotationHolder == null) {
+ // check the ITD'd dooberries
List mungers = relevantType.resolve(world).getInterTypeMungers();
for (Iterator iter = mungers.iterator(); iter.hasNext();) {
BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
- ResolvedMember fakerm = typeMunger.getSignature();
- //if (fakerm.hasAnnotations())
- ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm,typeMunger.getAspectType());
- ResolvedMember rmm = findMethod(typeMunger.getAspectType(),ajcMethod);
- if (fakerm.equals(getSignature())) {
- relevantType = typeMunger.getAspectType();
- annotationHolder = rmm;
- }
+ ResolvedMember fakerm = typeMunger.getSignature();
+ // if (fakerm.hasAnnotations())
+ ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm, typeMunger.getAspectType());
+ ResolvedMember rmm = findMethod(typeMunger.getAspectType(), ajcMethod);
+ if (fakerm.equals(getSignature())) {
+ relevantType = typeMunger.getAspectType();
+ annotationHolder = rmm;
+ }
}
- }
+ }
}
- annotations = ((ResolvedMember)annotationHolder).getAnnotationTypes();
-
- } else if (getKind() == Shadow.MethodExecution || getKind() == Shadow.ConstructorExecution ||
- getKind() == Shadow.AdviceExecution) {
- //ResolvedMember rm[] = relevantType.getDeclaredMethods();
- ResolvedMember foundMember = findMethod2(relevantType.getDeclaredMethods(),getSignature());
-
- annotations = getAnnotations(foundMember, shadowSignature, relevantType);
- annotationHolder = foundMember;
- annotationHolder = getRelevantMember(foundMember, annotationHolder,relevantType);
-
- } else if (getKind() == Shadow.ExceptionHandler) {
- relevantType = getSignature().getParameterTypes()[0].resolve(world);
- annotations = relevantType.getAnnotationTypes();
- } else if (getKind() == Shadow.PreInitialization || getKind() == Shadow.Initialization) {
- ResolvedMember found = findMethod2(relevantType.getDeclaredMethods(),getSignature());
- annotations = found.getAnnotationTypes();
- }
-
- if (annotations == null) {
- // We can't have recognized the shadow - should blow up now to be on the safe side
- throw new BCException("Could not discover annotations for shadow: "+getKind());
- }
-
+ annotations = ((ResolvedMember) annotationHolder).getAnnotationTypes();
+
+ } else if (getKind() == Shadow.MethodExecution || getKind() == Shadow.ConstructorExecution
+ || getKind() == Shadow.AdviceExecution) {
+ // ResolvedMember rm[] = relevantType.getDeclaredMethods();
+ ResolvedMember foundMember = findMethod2(relevantType.getDeclaredMethods(), getSignature());
+
+ annotations = getAnnotations(foundMember, shadowSignature, relevantType);
+ annotationHolder = foundMember;
+ annotationHolder = getRelevantMember(foundMember, annotationHolder, relevantType);
+
+ } else if (getKind() == Shadow.ExceptionHandler) {
+ relevantType = getSignature().getParameterTypes()[0].resolve(world);
+ annotations = relevantType.getAnnotationTypes();
+ } else if (getKind() == Shadow.PreInitialization || getKind() == Shadow.Initialization) {
+ ResolvedMember found = findMethod2(relevantType.getDeclaredMethods(), getSignature());
+ annotations = found.getAnnotationTypes();
+ }
+
+ if (annotations == null) {
+ // We can't have recognized the shadow - should blow up now to be on the safe side
+ throw new BCException("Could not discover annotations for shadow: " + getKind());
+ }
+
for (int i = 0; i < annotations.length; i++) {
ResolvedType annotationType = annotations[i];
- AnnotationAccessVar accessVar = new AnnotationAccessVar(getKind(),annotationType.resolve(world),relevantType,annotationHolder);
- kindedAnnotationVars.put(annotationType,accessVar);
+ AnnotationAccessVar accessVar = new AnnotationAccessVar(getKind(), annotationType.resolve(world), relevantType,
+ annotationHolder);
+ kindedAnnotationVars.put(annotationType, accessVar);
}
- }
-
- //FIXME asc whats the real diff between this one and the version in findMethod()?
- ResolvedMember findMethod2(ResolvedMember rm[], Member sig) {
+ }
+
+ // FIXME asc whats the real diff between this one and the version in findMethod()?
+ ResolvedMember findMethod2(ResolvedMember rm[], Member sig) {
ResolvedMember found = null;
// String searchString = getSignature().getName()+getSignature().getParameterSignature();
- for (int i = 0; i < rm.length && found==null; i++) {
+ for (int i = 0; i < rm.length && found == null; i++) {
ResolvedMember member = rm[i];
if (member.getName().equals(sig.getName()) && member.getParameterSignature().equals(sig.getParameterSignature()))
- found = member;
+ found = member;
}
return found;
- }
-
- private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) {
- ResolvedMember decMethods[] = aspectType.getDeclaredMethods();
- for (int i = 0; i < decMethods.length; i++) {
- ResolvedMember member = decMethods[i];
- if (member.equals(ajcMethod)) return member;
- }
+ }
+
+ private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) {
+ ResolvedMember decMethods[] = aspectType.getDeclaredMethods();
+ for (int i = 0; i < decMethods.length; i++) {
+ ResolvedMember member = decMethods[i];
+ if (member.equals(ajcMethod))
+ return member;
+ }
return null;
}
-
-
- private ResolvedMember findField(ResolvedMember[] members,Member lookingFor) {
- for (int i = 0; i < members.length; i++) {
- ResolvedMember member = members[i];
- if ( member.getName().equals(getSignature().getName()) &&
- member.getType().equals(getSignature().getType())) {
- return member;
+ private ResolvedMember findField(ResolvedMember[] members, Member lookingFor) {
+ for (int i = 0; i < members.length; i++) {
+ ResolvedMember member = members[i];
+ if (member.getName().equals(getSignature().getName()) && member.getType().equals(getSignature().getType())) {
+ return member;
+ }
}
- }
- return null;
+ return null;
}
-
-
+
public void initializeWithinAnnotationVars() {
- if (withinAnnotationVars != null) return;
- withinAnnotationVars = new HashMap();
-
- ResolvedType[] annotations = getEnclosingType().resolve(world).getAnnotationTypes();
+ if (withinAnnotationVars != null)
+ return;
+ withinAnnotationVars = new HashMap();
+
+ ResolvedType[] annotations = getEnclosingType().resolve(world).getAnnotationTypes();
for (int i = 0; i < annotations.length; i++) {
ResolvedType ann = annotations[i];
Kind k = Shadow.StaticInitialization;
- withinAnnotationVars.put(ann,new AnnotationAccessVar(k,ann,getEnclosingType(),null));
- }
- }
-
- public void initializeWithinCodeAnnotationVars() {
- if (withincodeAnnotationVars != null) return;
- withincodeAnnotationVars = new HashMap();
-
- // For some shadow we are interested in annotations on the method containing that shadow.
+ withinAnnotationVars.put(ann, new AnnotationAccessVar(k, ann, getEnclosingType(), null));
+ }
+ }
+
+ public void initializeWithinCodeAnnotationVars() {
+ if (withincodeAnnotationVars != null)
+ return;
+ withincodeAnnotationVars = new HashMap();
+
+ // For some shadow we are interested in annotations on the method containing that shadow.
ResolvedType[] annotations = getEnclosingMethod().getMemberView().getAnnotationTypes();
for (int i = 0; i < annotations.length; i++) {
ResolvedType ann = annotations[i];
- Kind k = (getEnclosingMethod().getMemberView().getKind()==Member.CONSTRUCTOR?
- Shadow.ConstructorExecution:Shadow.MethodExecution);
- withincodeAnnotationVars.put(ann,
- new AnnotationAccessVar(k,ann,getEnclosingType(),getEnclosingCodeSignature()));
- }
- }
-
-
- // ---- weave methods
-
- void weaveBefore(BcelAdvice munger) {
- range.insert(
- munger.getAdviceInstructions(this, null, range.getRealStart()),
- Range.InsideBefore);
- }
-
- public void weaveAfter(BcelAdvice munger) {
- weaveAfterThrowing(munger, UnresolvedType.THROWABLE);
- weaveAfterReturning(munger);
- }
-
+ Kind k = (getEnclosingMethod().getMemberView().getKind() == Member.CONSTRUCTOR ? Shadow.ConstructorExecution
+ : Shadow.MethodExecution);
+ withincodeAnnotationVars.put(ann, new AnnotationAccessVar(k, ann, getEnclosingType(), getEnclosingCodeSignature()));
+ }
+ }
+
+ // ---- weave methods
+
+ void weaveBefore(BcelAdvice munger) {
+ range.insert(munger.getAdviceInstructions(this, null, range.getRealStart()), Range.InsideBefore);
+ }
+
+ public void weaveAfter(BcelAdvice munger) {
+ weaveAfterThrowing(munger, UnresolvedType.THROWABLE);
+ weaveAfterReturning(munger);
+ }
+
/**
- * The basic strategy here is to add a set of instructions at the end of
- * the shadow range that dispatch the advice, and then return whatever the
- * shadow was going to return anyway.
+ * The basic strategy here is to add a set of instructions at the end of the shadow range that dispatch the advice, and then
+ * return whatever the shadow was going to return anyway.
*
- * To achieve this, we note all the return statements in the advice, and
- * replace them with code that:
- * 1) stores the return value on top of the stack in a temp var
- * 2) jumps to the start of our advice block
- * 3) restores the return value at the end of the advice block before
- * ultimately returning
+ * To achieve this, we note all the return statements in the advice, and replace them with code that: 1) stores the return value
+ * on top of the stack in a temp var 2) jumps to the start of our advice block 3) restores the return value at the end of the
+ * advice block before ultimately returning
*
- * We also need to bind the return value into a returning parameter, if the
- * advice specified one.
+ * We also need to bind the return value into a returning parameter, if the advice specified one.
*/
- public void weaveAfterReturning(BcelAdvice munger) {
- List returns = findReturnInstructions();
- boolean hasReturnInstructions = !returns.isEmpty();
-
- // list of instructions that handle the actual return from the join point
- InstructionList retList = new InstructionList();
-
- // variable that holds the return value
- BcelVar returnValueVar = null;
-
- if (hasReturnInstructions) {
- returnValueVar = generateReturnInstructions(returns,retList);
- } else {
- // we need at least one instruction, as the target for jumps
- retList.append(InstructionConstants.NOP);
- }
-
- // list of instructions for dispatching to the advice itself
- InstructionList advice = getAfterReturningAdviceDispatchInstructions(
- munger, retList.getStart());
-
- if (hasReturnInstructions) {
- InstructionHandle gotoTarget = advice.getStart();
+ public void weaveAfterReturning(BcelAdvice munger) {
+ List returns = findReturnInstructions();
+ boolean hasReturnInstructions = !returns.isEmpty();
+
+ // list of instructions that handle the actual return from the join point
+ InstructionList retList = new InstructionList();
+
+ // variable that holds the return value
+ BcelVar returnValueVar = null;
+
+ if (hasReturnInstructions) {
+ returnValueVar = generateReturnInstructions(returns, retList);
+ } else {
+ // we need at least one instruction, as the target for jumps
+ retList.append(InstructionConstants.NOP);
+ }
+
+ // list of instructions for dispatching to the advice itself
+ InstructionList advice = getAfterReturningAdviceDispatchInstructions(munger, retList.getStart());
+
+ if (hasReturnInstructions) {
+ InstructionHandle gotoTarget = advice.getStart();
for (Iterator i = returns.iterator(); i.hasNext();) {
InstructionHandle ih = (InstructionHandle) i.next();
retargetReturnInstruction(munger.hasExtraParameter(), returnValueVar, gotoTarget, ih);
}
- }
-
- range.append(advice);
- range.append(retList);
- }
+ }
+
+ range.append(advice);
+ range.append(retList);
+ }
/**
* @return a list of all the return instructions in the range of this shadow
*/
private List findReturnInstructions() {
List returns = new ArrayList();
- for (InstructionHandle ih = range.getStart(); ih != range.getEnd(); ih = ih.getNext()) {
- if (ih.getInstruction().isReturnInstruction()) {
- returns.add(ih);
- }
- }
+ for (InstructionHandle ih = range.getStart(); ih != range.getEnd(); ih = ih.getNext()) {
+ if (ih.getInstruction().isReturnInstruction()) {
+ returns.add(ih);
+ }
+ }
return returns;
}
/**
- * Given a list containing all the return instruction handles for this shadow,
- * finds the last return instruction and copies it, making this the ultimate
- * return. If the shadow has a non-void return type, we also create a temporary
- * variable to hold the return value, and load the value from this var before
- * returning (see pr148007 for why we do this - it works around a JRockit bug,
- * and is also closer to what javac generates)
+ * Given a list containing all the return instruction handles for this shadow, finds the last return instruction and copies it,
+ * making this the ultimate return. If the shadow has a non-void return type, we also create a temporary variable to hold the
+ * return value, and load the value from this var before returning (see pr148007 for why we do this - it works around a JRockit
+ * bug, and is also closer to what javac generates)
*
- * Sometimes the 'last return' isnt the right one - some rogue code can
- * include the real return from the body of a subroutine that exists at the end
- * of the method. In this case the last return is RETURN but that may not be
- * correct for a method with a non-void return type... pr151673
+ * Sometimes the 'last return' isnt the right one - some rogue code can include the real return from the body of a subroutine
+ * that exists at the end of the method. In this case the last return is RETURN but that may not be correct for a method with a
+ * non-void return type... pr151673
*
* @param returns list of all the return instructions in the shadow
- * @param returnInstructions instruction list into which the return instructions should
- * be generated
+ * @param returnInstructions instruction list into which the return instructions should be generated
* @return the variable holding the return value, if needed
*/
private BcelVar generateReturnInstructions(List returns, InstructionList returnInstructions) {
BcelVar returnValueVar = null;
- if (this.hasANonVoidReturnType()) {
- // Find the last *correct* return - this is a method with a non-void return type
- // so ignore RETURN
- Instruction newReturnInstruction = null;
- int i=returns.size()-1;
- while (newReturnInstruction == null && i>=0) {
- InstructionHandle ih = (InstructionHandle)returns.get(i);
- if (ih.getInstruction().opcode!=Constants.RETURN) {
- newReturnInstruction = Utility.copyInstruction(ih.getInstruction());
- }
- i--;
- }
- returnValueVar = genTempVar(this.getReturnType());
- returnValueVar.appendLoad(returnInstructions,getFactory());
- returnInstructions.append(newReturnInstruction);
- } else {
- InstructionHandle lastReturnHandle = (InstructionHandle)returns.get(returns.size() - 1);
- Instruction newReturnInstruction = Utility.copyInstruction(lastReturnHandle.getInstruction());
- returnInstructions.append(newReturnInstruction);
- }
- return returnValueVar;
- }
-
+ if (this.hasANonVoidReturnType()) {
+ // Find the last *correct* return - this is a method with a non-void return type
+ // so ignore RETURN
+ Instruction newReturnInstruction = null;
+ int i = returns.size() - 1;
+ while (newReturnInstruction == null && i >= 0) {
+ InstructionHandle ih = (InstructionHandle) returns.get(i);
+ if (ih.getInstruction().opcode != Constants.RETURN) {
+ newReturnInstruction = Utility.copyInstruction(ih.getInstruction());
+ }
+ i--;
+ }
+ returnValueVar = genTempVar(this.getReturnType());
+ returnValueVar.appendLoad(returnInstructions, getFactory());
+ returnInstructions.append(newReturnInstruction);
+ } else {
+ InstructionHandle lastReturnHandle = (InstructionHandle) returns.get(returns.size() - 1);
+ Instruction newReturnInstruction = Utility.copyInstruction(lastReturnHandle.getInstruction());
+ returnInstructions.append(newReturnInstruction);
+ }
+ return returnValueVar;
+ }
+
/**
* @return true, iff this shadow returns a value
*/
@@ -1852,24 +1653,26 @@ public class BcelShadow extends Shadow {
/**
* Get the list of instructions used to dispatch to the after advice
+ *
* @param munger
* @param firstInstructionInReturnSequence
* @return
*/
- private InstructionList getAfterReturningAdviceDispatchInstructions(BcelAdvice munger, InstructionHandle firstInstructionInReturnSequence) {
+ private InstructionList getAfterReturningAdviceDispatchInstructions(BcelAdvice munger,
+ InstructionHandle firstInstructionInReturnSequence) {
InstructionList advice = new InstructionList();
-
- BcelVar tempVar = null;
- if (munger.hasExtraParameter()) {
- tempVar = insertAdviceInstructionsForBindingReturningParameter(advice);
- }
- advice.append(munger.getAdviceInstructions(this, tempVar, firstInstructionInReturnSequence));
+
+ BcelVar tempVar = null;
+ if (munger.hasExtraParameter()) {
+ tempVar = insertAdviceInstructionsForBindingReturningParameter(advice);
+ }
+ advice.append(munger.getAdviceInstructions(this, tempVar, firstInstructionInReturnSequence));
return advice;
}
/**
- * If the after() returning(Foo f) form is used, bind the return value to the parameter.
- * If the shadow returns void, bind null.
+ * If the after() returning(Foo f) form is used, bind the return value to the parameter. If the shadow returns void, bind null.
+ *
* @param advice
* @return
*/
@@ -1881,133 +1684,127 @@ public class BcelShadow extends Shadow {
advice.append(InstructionConstants.ACONST_NULL);
tempVar.appendStore(advice, getFactory());
} else {
- tempVar = genTempVar(tempVarType);
- advice.append(InstructionFactory.createDup(tempVarType.getSize()));
- tempVar.appendStore(advice, getFactory());
+ tempVar = genTempVar(tempVarType);
+ advice.append(InstructionFactory.createDup(tempVarType.getSize()));
+ tempVar.appendStore(advice, getFactory());
}
return tempVar;
}
-
/**
* Helper method for weaveAfterReturning
*
- * Each return instruction in the method body is retargeted by calling this method.
- * The return instruction is replaced by up to three instructions:
- * 1) if the shadow returns a value, and that value is bound to an after returning
- * parameter, then we DUP the return value on the top of the stack
- * 2) if the shadow returns a value, we store it in the returnValueVar (it will
- * be retrieved from here when we ultimately return after the advice dispatch)
- * 3) if the return was the last instruction, we add a NOP (it will fall through
- * to the advice dispatch), otherwise we add a GOTO that branches to the
- * supplied gotoTarget (start of the advice dispatch)
+ * Each return instruction in the method body is retargeted by calling this method. The return instruction is replaced by up to
+ * three instructions: 1) if the shadow returns a value, and that value is bound to an after returning parameter, then we DUP
+ * the return value on the top of the stack 2) if the shadow returns a value, we store it in the returnValueVar (it will be
+ * retrieved from here when we ultimately return after the advice dispatch) 3) if the return was the last instruction, we add a
+ * NOP (it will fall through to the advice dispatch), otherwise we add a GOTO that branches to the supplied gotoTarget (start of
+ * the advice dispatch)
*/
- private void retargetReturnInstruction(boolean hasReturningParameter, BcelVar returnValueVar, InstructionHandle gotoTarget, InstructionHandle returnHandle) {
+ private void retargetReturnInstruction(boolean hasReturningParameter, BcelVar returnValueVar, InstructionHandle gotoTarget,
+ InstructionHandle returnHandle) {
// pr148007, work around JRockit bug
// replace ret with store into returnValueVar, followed by goto if not
// at the end of the instruction list...
InstructionList newInstructions = new InstructionList();
if (returnValueVar != null) {
- if (hasReturningParameter) {
- // we have to dup the return val before consuming it...
- newInstructions.append(InstructionFactory.createDup(this.getReturnType().getSize()));
- }
+ if (hasReturningParameter) {
+ // we have to dup the return val before consuming it...
+ newInstructions.append(InstructionFactory.createDup(this.getReturnType().getSize()));
+ }
// store the return value into this var
- returnValueVar.appendStore(newInstructions,getFactory());
+ returnValueVar.appendStore(newInstructions, getFactory());
}
- if (!isLastInstructionInRange(returnHandle,range)) {
- newInstructions.append(InstructionFactory.createBranchInstruction(
- Constants.GOTO,
- gotoTarget));
+ if (!isLastInstructionInRange(returnHandle, range)) {
+ newInstructions.append(InstructionFactory.createBranchInstruction(Constants.GOTO, gotoTarget));
}
if (newInstructions.isEmpty()) {
newInstructions.append(InstructionConstants.NOP);
}
- Utility.replaceInstruction(returnHandle,newInstructions,enclosingMethod);
- }
-
- private boolean isLastInstructionInRange(InstructionHandle ih, ShadowRange aRange) {
- return ih.getNext() == aRange.getEnd();
- }
-
- public void weaveAfterThrowing(BcelAdvice munger, UnresolvedType catchType) {
- // a good optimization would be not to generate anything here
- // if the shadow is GUARANTEED empty (i.e., there's NOTHING, not even
- // a shadow, inside me).
- if (getRange().getStart().getNext() == getRange().getEnd()) return;
- InstructionFactory fact = getFactory();
- InstructionList handler = new InstructionList();
- BcelVar exceptionVar = genTempVar(catchType);
- exceptionVar.appendStore(handler, fact);
-
- // pr62642
- // I will now jump through some firey BCEL hoops to generate a trivial bit of code:
- // if (exc instanceof ExceptionInInitializerError)
- // throw (ExceptionInInitializerError)exc;
- if (this.getEnclosingMethod().getName().equals("<clinit>")) {
- ResolvedType eiieType = world.resolve("java.lang.ExceptionInInitializerError");
- ObjectType eiieBcelType = (ObjectType)BcelWorld.makeBcelType(eiieType);
- InstructionList ih = new InstructionList(InstructionConstants.NOP);
- handler.append(exceptionVar.createLoad(fact));
- handler.append(fact.createInstanceOf(eiieBcelType));
- InstructionBranch bi =
- InstructionFactory.createBranchInstruction(Constants.IFEQ,ih.getStart());
- handler.append(bi);
- handler.append(exceptionVar.createLoad(fact));
- handler.append(fact.createCheckCast(eiieBcelType));
- handler.append(InstructionConstants.ATHROW);
- handler.append(ih);
- }
-
- InstructionList endHandler = new InstructionList(
- exceptionVar.createLoad(fact));
- handler.append(munger.getAdviceInstructions(this, exceptionVar, endHandler.getStart()));
- handler.append(endHandler);
- handler.append(InstructionConstants.ATHROW);
- InstructionHandle handlerStart = handler.getStart();
-
- if (isFallsThrough()) {
- InstructionHandle jumpTarget = handler.append(InstructionConstants.NOP);
- handler.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, jumpTarget));
- }
+ Utility.replaceInstruction(returnHandle, newInstructions, enclosingMethod);
+ }
+
+ private boolean isLastInstructionInRange(InstructionHandle ih, ShadowRange aRange) {
+ return ih.getNext() == aRange.getEnd();
+ }
+
+ public void weaveAfterThrowing(BcelAdvice munger, UnresolvedType catchType) {
+ // a good optimization would be not to generate anything here
+ // if the shadow is GUARANTEED empty (i.e., there's NOTHING, not even
+ // a shadow, inside me).
+ if (getRange().getStart().getNext() == getRange().getEnd())
+ return;
+ InstructionFactory fact = getFactory();
+ InstructionList handler = new InstructionList();
+ BcelVar exceptionVar = genTempVar(catchType);
+ exceptionVar.appendStore(handler, fact);
+
+ // pr62642
+ // I will now jump through some firey BCEL hoops to generate a trivial bit of code:
+ // if (exc instanceof ExceptionInInitializerError)
+ // throw (ExceptionInInitializerError)exc;
+ if (this.getEnclosingMethod().getName().equals("<clinit>")) {
+ ResolvedType eiieType = world.resolve("java.lang.ExceptionInInitializerError");
+ ObjectType eiieBcelType = (ObjectType) BcelWorld.makeBcelType(eiieType);
+ InstructionList ih = new InstructionList(InstructionConstants.NOP);
+ handler.append(exceptionVar.createLoad(fact));
+ handler.append(fact.createInstanceOf(eiieBcelType));
+ InstructionBranch bi = InstructionFactory.createBranchInstruction(Constants.IFEQ, ih.getStart());
+ handler.append(bi);
+ handler.append(exceptionVar.createLoad(fact));
+ handler.append(fact.createCheckCast(eiieBcelType));
+ handler.append(InstructionConstants.ATHROW);
+ handler.append(ih);
+ }
+
+ InstructionList endHandler = new InstructionList(exceptionVar.createLoad(fact));
+ handler.append(munger.getAdviceInstructions(this, exceptionVar, endHandler.getStart()));
+ handler.append(endHandler);
+ handler.append(InstructionConstants.ATHROW);
+ InstructionHandle handlerStart = handler.getStart();
+
+ if (isFallsThrough()) {
+ InstructionHandle jumpTarget = handler.append(InstructionConstants.NOP);
+ handler.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, jumpTarget));
+ }
InstructionHandle protectedEnd = handler.getStart();
- range.insert(handler, Range.InsideAfter);
-
- enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(),
- handlerStart, (ObjectType)BcelWorld.makeBcelType(catchType), //???Type.THROWABLE,
- // high priority if our args are on the stack
- getKind().hasHighPriorityExceptions());
- }
-
-
- //??? this shares a lot of code with the above weaveAfterThrowing
- //??? would be nice to abstract that to say things only once
- public void weaveSoftener(BcelAdvice munger, UnresolvedType catchType) {
- // a good optimization would be not to generate anything here
- // if the shadow is GUARANTEED empty (i.e., there's NOTHING, not even
- // a shadow, inside me).
- if (getRange().getStart().getNext() == getRange().getEnd()) return;
-
- InstructionFactory fact = getFactory();
- InstructionList handler = new InstructionList();
+ range.insert(handler, Range.InsideAfter);
+
+ enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(), handlerStart,
+ (ObjectType) BcelWorld.makeBcelType(catchType), // ???Type.THROWABLE,
+ // high priority if our args are on the stack
+ getKind().hasHighPriorityExceptions());
+ }
+
+ // ??? this shares a lot of code with the above weaveAfterThrowing
+ // ??? would be nice to abstract that to say things only once
+ public void weaveSoftener(BcelAdvice munger, UnresolvedType catchType) {
+ // a good optimization would be not to generate anything here
+ // if the shadow is GUARANTEED empty (i.e., there's NOTHING, not even
+ // a shadow, inside me).
+ if (getRange().getStart().getNext() == getRange().getEnd())
+ return;
+
+ InstructionFactory fact = getFactory();
+ InstructionList handler = new InstructionList();
InstructionList rtExHandler = new InstructionList();
- BcelVar exceptionVar = genTempVar(catchType);
-
+ BcelVar exceptionVar = genTempVar(catchType);
+
handler.append(fact.createNew(NameMangler.SOFT_EXCEPTION_TYPE));
- handler.append(InstructionFactory.createDup(1));
- handler.append(exceptionVar.createLoad(fact));
- handler.append(fact.createInvoke(NameMangler.SOFT_EXCEPTION_TYPE, "<init>",
- Type.VOID, new Type[] { Type.THROWABLE }, Constants.INVOKESPECIAL)); //??? special
- handler.append(InstructionConstants.ATHROW);
+ handler.append(InstructionFactory.createDup(1));
+ handler.append(exceptionVar.createLoad(fact));
+ handler.append(fact.createInvoke(NameMangler.SOFT_EXCEPTION_TYPE, "<init>", Type.VOID, new Type[] { Type.THROWABLE },
+ Constants.INVOKESPECIAL)); // ??? special
+ handler.append(InstructionConstants.ATHROW);
// ENH 42737
- exceptionVar.appendStore(rtExHandler, fact);
+ exceptionVar.appendStore(rtExHandler, fact);
// aload_1
rtExHandler.append(exceptionVar.createLoad(fact));
// instanceof class java/lang/RuntimeException
rtExHandler.append(fact.createInstanceOf(new ObjectType("java.lang.RuntimeException")));
// ifeq go to new SOFT_EXCEPTION_TYPE instruction
- rtExHandler.append(InstructionFactory.createBranchInstruction(Constants.IFEQ,handler.getStart()));
+ rtExHandler.append(InstructionFactory.createBranchInstruction(Constants.IFEQ, handler.getStart()));
// aload_1
rtExHandler.append(exceptionVar.createLoad(fact));
// athrow
@@ -2016,327 +1813,272 @@ public class BcelShadow extends Shadow {
InstructionHandle handlerStart = rtExHandler.getStart();
if (isFallsThrough()) {
- InstructionHandle jumpTarget = range.getEnd();//handler.append(fact.NOP);
- rtExHandler.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, jumpTarget));
- }
+ InstructionHandle jumpTarget = range.getEnd();// handler.append(fact.NOP);
+ rtExHandler.insert(InstructionFactory.createBranchInstruction(Constants.GOTO, jumpTarget));
+ }
rtExHandler.append(handler);
InstructionHandle protectedEnd = rtExHandler.getStart();
- range.insert(rtExHandler, Range.InsideAfter);
-
- enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(),
- handlerStart, (ObjectType)BcelWorld.makeBcelType(catchType),
- // high priority if our args are on the stack
- getKind().hasHighPriorityExceptions());
- }
+ range.insert(rtExHandler, Range.InsideAfter);
+ enclosingMethod.addExceptionHandler(range.getStart().getNext(), protectedEnd.getPrev(), handlerStart,
+ (ObjectType) BcelWorld.makeBcelType(catchType),
+ // high priority if our args are on the stack
+ getKind().hasHighPriorityExceptions());
+ }
public void weavePerObjectEntry(final BcelAdvice munger, final BcelVar onVar) {
- final InstructionFactory fact = getFactory();
-
+ final InstructionFactory fact = getFactory();
InstructionList entryInstructions = new InstructionList();
InstructionList entrySuccessInstructions = new InstructionList();
onVar.appendLoad(entrySuccessInstructions, fact);
- entrySuccessInstructions.append(
- Utility.createInvoke(fact, world,
- AjcMemberMaker.perObjectBind(munger.getConcreteAspect())));
-
- InstructionList testInstructions =
- munger.getTestInstructions(this, entrySuccessInstructions.getStart(),
- range.getRealStart(),
- entrySuccessInstructions.getStart());
-
+ entrySuccessInstructions
+ .append(Utility.createInvoke(fact, world, AjcMemberMaker.perObjectBind(munger.getConcreteAspect())));
+
+ InstructionList testInstructions = munger.getTestInstructions(this, entrySuccessInstructions.getStart(), range
+ .getRealStart(), entrySuccessInstructions.getStart());
+
entryInstructions.append(testInstructions);
entryInstructions.append(entrySuccessInstructions);
-
+
range.insert(entryInstructions, Range.InsideBefore);
}
-
- // PTWIMPL Create static initializer to call the aspect factory
+
+ // PTWIMPL Create static initializer to call the aspect factory
/**
* Causes the aspect instance to be *set* for later retrievable through localAspectof()/aspectOf()
*/
- public void weavePerTypeWithinAspectInitialization(final BcelAdvice munger,UnresolvedType t) {
-
- if (t.resolve(world).isInterface()) return; // Don't initialize statics in
- final InstructionFactory fact = getFactory();
+ public void weavePerTypeWithinAspectInitialization(final BcelAdvice munger, UnresolvedType t) {
+
+ if (t.resolve(world).isInterface())
+ return; // Don't initialize statics in
+ final InstructionFactory fact = getFactory();
InstructionList entryInstructions = new InstructionList();
InstructionList entrySuccessInstructions = new InstructionList();
-
+
BcelWorld.getBcelObjectType(munger.getConcreteAspect());
String aspectname = munger.getConcreteAspect().getName();
-
+
String ptwField = NameMangler.perTypeWithinFieldForTarget(munger.getConcreteAspect());
- entrySuccessInstructions.append(InstructionFactory.PUSH(fact.getConstantPool(),t.getName()));
-
- entrySuccessInstructions.append(fact.createInvoke(aspectname,"ajc$createAspectInstance",new ObjectType(aspectname),
- new Type[]{new ObjectType("java.lang.String")},Constants.INVOKESTATIC));
- entrySuccessInstructions.append(fact.createPutStatic(t.getName(),ptwField,
- new ObjectType(aspectname)));
-
+ entrySuccessInstructions.append(InstructionFactory.PUSH(fact.getConstantPool(), t.getName()));
+
+ entrySuccessInstructions.append(fact.createInvoke(aspectname, "ajc$createAspectInstance", new ObjectType(aspectname),
+ new Type[] { new ObjectType("java.lang.String") }, Constants.INVOKESTATIC));
+ entrySuccessInstructions.append(fact.createPutStatic(t.getName(), ptwField, new ObjectType(aspectname)));
+
entryInstructions.append(entrySuccessInstructions);
-
+
range.insert(entryInstructions, Range.InsideBefore);
}
-
-
+
public void weaveCflowEntry(final BcelAdvice munger, final Member cflowField) {
- final boolean isPer = munger.getKind() == AdviceKind.PerCflowBelowEntry ||
- munger.getKind() == AdviceKind.PerCflowEntry;
-
+ final boolean isPer = munger.getKind() == AdviceKind.PerCflowBelowEntry || munger.getKind() == AdviceKind.PerCflowEntry;
+
final Type objectArrayType = new ArrayType(Type.OBJECT, 1);
- final InstructionFactory fact = getFactory();
+ final InstructionFactory fact = getFactory();
final BcelVar testResult = genTempVar(ResolvedType.BOOLEAN);
InstructionList entryInstructions = new InstructionList();
{
InstructionList entrySuccessInstructions = new InstructionList();
-
+
if (munger.hasDynamicTests()) {
entryInstructions.append(Utility.createConstant(fact, 0));
testResult.appendStore(entryInstructions, fact);
-
+
entrySuccessInstructions.append(Utility.createConstant(fact, 1));
testResult.appendStore(entrySuccessInstructions, fact);
}
if (isPer) {
- entrySuccessInstructions.append(
- fact.createInvoke(munger.getConcreteAspect().getName(),
- NameMangler.PERCFLOW_PUSH_METHOD,
- Type.VOID,
- new Type[] { },
- Constants.INVOKESTATIC));
+ entrySuccessInstructions.append(fact.createInvoke(munger.getConcreteAspect().getName(),
+ NameMangler.PERCFLOW_PUSH_METHOD, Type.VOID, new Type[] {}, Constants.INVOKESTATIC));
} else {
BcelVar[] cflowStateVars = munger.getExposedStateAsBcelVars(false);
-
+
if (cflowStateVars.length == 0) {
// This should be getting managed by a counter - lets make sure.
- if (!cflowField.getType().getName().endsWith("CFlowCounter"))
+ if (!cflowField.getType().getName().endsWith("CFlowCounter"))
throw new RuntimeException("Incorrectly attempting counter operation on stacked cflow");
- entrySuccessInstructions.append(
- Utility.createGet(fact, cflowField));
- //arrayVar.appendLoad(entrySuccessInstructions, fact);
- entrySuccessInstructions.append(fact.createInvoke(NameMangler.CFLOW_COUNTER_TYPE,"inc",Type.VOID,new Type[] { },Constants.INVOKEVIRTUAL));
+ entrySuccessInstructions.append(Utility.createGet(fact, cflowField));
+ // arrayVar.appendLoad(entrySuccessInstructions, fact);
+ entrySuccessInstructions.append(fact.createInvoke(NameMangler.CFLOW_COUNTER_TYPE, "inc", Type.VOID,
+ new Type[] {}, Constants.INVOKEVIRTUAL));
} else {
- BcelVar arrayVar = genTempVar(UnresolvedType.OBJECTARRAY);
-
- int alen = cflowStateVars.length;
- entrySuccessInstructions.append(Utility.createConstant(fact, alen));
- entrySuccessInstructions.append(fact.createNewArray(Type.OBJECT, (short) 1));
- arrayVar.appendStore(entrySuccessInstructions, fact);
-
- for (int i = 0; i < alen; i++) {
- arrayVar.appendConvertableArrayStore(
- entrySuccessInstructions,
- fact,
- i,
- cflowStateVars[i]);
- }
-
- entrySuccessInstructions.append(
- Utility.createGet(fact, cflowField));
- arrayVar.appendLoad(entrySuccessInstructions, fact);
-
- entrySuccessInstructions.append(
- fact.createInvoke(NameMangler.CFLOW_STACK_TYPE, "push", Type.VOID,
- new Type[] { objectArrayType },
- Constants.INVOKEVIRTUAL));
+ BcelVar arrayVar = genTempVar(UnresolvedType.OBJECTARRAY);
+
+ int alen = cflowStateVars.length;
+ entrySuccessInstructions.append(Utility.createConstant(fact, alen));
+ entrySuccessInstructions.append(fact.createNewArray(Type.OBJECT, (short) 1));
+ arrayVar.appendStore(entrySuccessInstructions, fact);
+
+ for (int i = 0; i < alen; i++) {
+ arrayVar.appendConvertableArrayStore(entrySuccessInstructions, fact, i, cflowStateVars[i]);
+ }
+
+ entrySuccessInstructions.append(Utility.createGet(fact, cflowField));
+ arrayVar.appendLoad(entrySuccessInstructions, fact);
+
+ entrySuccessInstructions.append(fact.createInvoke(NameMangler.CFLOW_STACK_TYPE, "push", Type.VOID,
+ new Type[] { objectArrayType }, Constants.INVOKEVIRTUAL));
}
}
-
- InstructionList testInstructions =
- munger.getTestInstructions(this, entrySuccessInstructions.getStart(),
- range.getRealStart(),
- entrySuccessInstructions.getStart());
+ InstructionList testInstructions = munger.getTestInstructions(this, entrySuccessInstructions.getStart(), range
+ .getRealStart(), entrySuccessInstructions.getStart());
entryInstructions.append(testInstructions);
entryInstructions.append(entrySuccessInstructions);
}
-
+
// this is the same for both per and non-per
weaveAfter(new BcelAdvice(null, null, null, 0, 0, 0, null, null) {
- public InstructionList getAdviceInstructions(
- BcelShadow s,
- BcelVar extraArgVar,
- InstructionHandle ifNoAdvice) {
+ public InstructionList getAdviceInstructions(BcelShadow s, BcelVar extraArgVar, InstructionHandle ifNoAdvice) {
InstructionList exitInstructions = new InstructionList();
if (munger.hasDynamicTests()) {
testResult.appendLoad(exitInstructions, fact);
- exitInstructions.append(
- InstructionFactory.createBranchInstruction(
- Constants.IFEQ,
- ifNoAdvice));
+ exitInstructions.append(InstructionFactory.createBranchInstruction(Constants.IFEQ, ifNoAdvice));
}
exitInstructions.append(Utility.createGet(fact, cflowField));
- if (munger.getKind() != AdviceKind.PerCflowEntry &&
- munger.getKind() != AdviceKind.PerCflowBelowEntry &&
- munger.getExposedStateAsBcelVars(false).length==0) {
- exitInstructions
- .append(
- fact
- .createInvoke(
- NameMangler.CFLOW_COUNTER_TYPE,
- "dec",
- Type.VOID,
- new Type[] {
- }, Constants.INVOKEVIRTUAL));
+ if (munger.getKind() != AdviceKind.PerCflowEntry && munger.getKind() != AdviceKind.PerCflowBelowEntry
+ && munger.getExposedStateAsBcelVars(false).length == 0) {
+ exitInstructions.append(fact.createInvoke(NameMangler.CFLOW_COUNTER_TYPE, "dec", Type.VOID, new Type[] {},
+ Constants.INVOKEVIRTUAL));
} else {
- exitInstructions
- .append(
- fact
- .createInvoke(
- NameMangler.CFLOW_STACK_TYPE,
- "pop",
- Type.VOID,
- new Type[] {
- }, Constants.INVOKEVIRTUAL));
+ exitInstructions.append(fact.createInvoke(NameMangler.CFLOW_STACK_TYPE, "pop", Type.VOID, new Type[] {},
+ Constants.INVOKEVIRTUAL));
}
return exitInstructions;
}
});
-
-
+
range.insert(entryInstructions, Range.InsideBefore);
}
-
- /* Implementation notes:
- *
- * AroundInline still extracts the instructions of the original shadow into
- * an extracted method. This allows inlining of even that advice that doesn't
- * call proceed or calls proceed more than once.
- *
- * It extracts the instructions of the original shadow into a method.
- *
- * Then it extracts the instructions of the advice into a new method defined on
- * this enclosing class. This new method can then be specialized as below.
- *
- * Then it searches in the instructions of the advice for any call to the
- * proceed method.
- *
- * At such a call, there is stuff on the stack representing the arguments to
- * proceed. Pop these into the frame.
- *
- * Now build the stack for the call to the extracted method, taking values
- * either from the join point state or from the new frame locs from proceed.
- * Now call the extracted method. The right return value should be on the
- * stack, so no cast is necessary.
- *
- * If only one call to proceed is made, we can re-inline the original shadow.
- * We are not doing that presently.
- *
- * If the body of the advice can be determined to not alter the stack, or if
- * this shadow doesn't care about the stack, i.e. method-execution, then the
- * new method for the advice can also be re-lined. We are not doing that
- * presently.
- */
- public void weaveAroundInline(BcelAdvice munger,boolean hasDynamicTest) {
-
+
+ /*
+ * Implementation notes:
+ *
+ * AroundInline still extracts the instructions of the original shadow into an extracted method. This allows inlining of even
+ * that advice that doesn't call proceed or calls proceed more than once.
+ *
+ * It extracts the instructions of the original shadow into a method.
+ *
+ * Then it extracts the instructions of the advice into a new method defined on this enclosing class. This new method can then
+ * be specialized as below.
+ *
+ * Then it searches in the instructions of the advice for any call to the proceed method.
+ *
+ * At such a call, there is stuff on the stack representing the arguments to proceed. Pop these into the frame.
+ *
+ * Now build the stack for the call to the extracted method, taking values either from the join point state or from the new
+ * frame locs from proceed. Now call the extracted method. The right return value should be on the stack, so no cast is
+ * necessary.
+ *
+ * If only one call to proceed is made, we can re-inline the original shadow. We are not doing that presently.
+ *
+ * If the body of the advice can be determined to not alter the stack, or if this shadow doesn't care about the stack, i.e.
+ * method-execution, then the new method for the advice can also be re-lined. We are not doing that presently.
+ */
+ public void weaveAroundInline(BcelAdvice munger, boolean hasDynamicTest) {
+
// !!! THIS BLOCK OF CODE SHOULD BE IN A METHOD CALLED weaveAround(...);
- Member mungerSig = munger.getSignature();
- //Member originalSig = mungerSig; // If mungerSig is on a parameterized type, originalSig is the member on the generic type
- if (mungerSig instanceof ResolvedMember) {
- ResolvedMember rm = (ResolvedMember)mungerSig;
- if (rm.hasBackingGenericMember()) mungerSig = rm.getBackingGenericMember();
- }
- ResolvedType declaringType = world.resolve(mungerSig.getDeclaringType(),true);
- if (declaringType.isMissing()) {
- world.getLint().cantFindType.signal(
- new String[] {WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE,declaringType.getClassName())},
- getSourceLocation(),
- new ISourceLocation[]{ munger.getSourceLocation()}
- );
-// IMessage msg = new Message(
-// WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE,declaringType.getClassName()),
-// "",IMessage.ERROR,getSourceLocation(),null,
-// new ISourceLocation[]{ munger.getSourceLocation()});
-// world.getMessageHandler().handleMessage(msg);
- }
- //??? might want some checks here to give better errors
- ResolvedType rt = (declaringType.isParameterizedType()?declaringType.getGenericType():declaringType);
- BcelObjectType ot = BcelWorld.getBcelObjectType(rt);
-// if (ot==null) {
-// world.getMessageHandler().handleMessage(
-// MessageUtil.warn("Unable to find modifiable delegate for the aspect '"+rt.getName()+"' containing around advice - cannot implement inlining",munger.getSourceLocation()));
-// weaveAroundClosure(munger, hasDynamicTest);
-// return;
-// }
+ Member mungerSig = munger.getSignature();
+ // Member originalSig = mungerSig; // If mungerSig is on a parameterized type, originalSig is the member on the generic type
+ if (mungerSig instanceof ResolvedMember) {
+ ResolvedMember rm = (ResolvedMember) mungerSig;
+ if (rm.hasBackingGenericMember())
+ mungerSig = rm.getBackingGenericMember();
+ }
+ ResolvedType declaringType = world.resolve(mungerSig.getDeclaringType(), true);
+ if (declaringType.isMissing()) {
+ world.getLint().cantFindType.signal(new String[] { WeaverMessages.format(
+ WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE, declaringType.getClassName()) }, getSourceLocation(),
+ new ISourceLocation[] { munger.getSourceLocation() });
+ // IMessage msg = new Message(
+ // WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE,declaringType.getClassName()),
+ // "",IMessage.ERROR,getSourceLocation(),null,
+ // new ISourceLocation[]{ munger.getSourceLocation()});
+ // world.getMessageHandler().handleMessage(msg);
+ }
+ // ??? might want some checks here to give better errors
+ ResolvedType rt = (declaringType.isParameterizedType() ? declaringType.getGenericType() : declaringType);
+ BcelObjectType ot = BcelWorld.getBcelObjectType(rt);
+ // if (ot==null) {
+ // world.getMessageHandler().handleMessage(
+ // MessageUtil.warn("Unable to find modifiable delegate for the aspect '"+rt.getName()+
+ // "' containing around advice - cannot implement inlining",munger.getSourceLocation()));
+ // weaveAroundClosure(munger, hasDynamicTest);
+ // return;
+ // }
LazyMethodGen adviceMethod = ot.getLazyClassGen().getLazyMethodGen(mungerSig);
if (!adviceMethod.getCanInline()) {
weaveAroundClosure(munger, hasDynamicTest);
return;
}
- // specific test for @AJ proceedInInners
- if (munger.getConcreteAspect().isAnnotationStyleAspect()) {
- // if we can't find one proceed() we suspect that the call
- // is happening in an inner class so we don't inline it.
- // Note: for code style, this is done at Aspect compilation time.
- boolean canSeeProceedPassedToOther = false;
- InstructionHandle curr = adviceMethod.getBody().getStart();
- InstructionHandle end = adviceMethod.getBody().getEnd();
- ConstantPool cpg = adviceMethod.getEnclosingClass().getConstantPool();
- while (curr != end) {
- InstructionHandle next = curr.getNext();
- Instruction inst = curr.getInstruction();
- if ((inst instanceof InvokeInstruction)
- && ((InvokeInstruction)inst).getSignature(cpg).indexOf("Lorg/aspectj/lang/ProceedingJoinPoint;") > 0) {
- // we may want to refine to exclude stuff returning jp ?
- // does code style skip inline if i write dump(thisJoinPoint) ?
- canSeeProceedPassedToOther = true;// we see one pjp passed around - dangerous
- break;
- }
- curr = next;
- }
- if (canSeeProceedPassedToOther) {
- // remember this decision to avoid re-analysis
- adviceMethod.setCanInline(false);
- weaveAroundClosure(munger, hasDynamicTest);
- return;
- }
- }
-
-
+ // specific test for @AJ proceedInInners
+ if (munger.getConcreteAspect().isAnnotationStyleAspect()) {
+ // if we can't find one proceed() we suspect that the call
+ // is happening in an inner class so we don't inline it.
+ // Note: for code style, this is done at Aspect compilation time.
+ boolean canSeeProceedPassedToOther = false;
+ InstructionHandle curr = adviceMethod.getBody().getStart();
+ InstructionHandle end = adviceMethod.getBody().getEnd();
+ ConstantPool cpg = adviceMethod.getEnclosingClass().getConstantPool();
+ while (curr != end) {
+ InstructionHandle next = curr.getNext();
+ Instruction inst = curr.getInstruction();
+ if ((inst instanceof InvokeInstruction)
+ && ((InvokeInstruction) inst).getSignature(cpg).indexOf("Lorg/aspectj/lang/ProceedingJoinPoint;") > 0) {
+ // we may want to refine to exclude stuff returning jp ?
+ // does code style skip inline if i write dump(thisJoinPoint) ?
+ canSeeProceedPassedToOther = true;// we see one pjp passed around - dangerous
+ break;
+ }
+ curr = next;
+ }
+ if (canSeeProceedPassedToOther) {
+ // remember this decision to avoid re-analysis
+ adviceMethod.setCanInline(false);
+ weaveAroundClosure(munger, hasDynamicTest);
+ return;
+ }
+ }
// We can't inline around methods if they have around advice on them, this
// is because the weaving will extract the body and hence the proceed call.
- //??? should consider optimizations to recognize simple cases that don't require body extraction
+ // ??? should consider optimizations to recognize simple cases that don't require body extraction
enclosingMethod.setCanInline(false);
-
+
// start by exposing various useful things into the frame
final InstructionFactory fact = getFactory();
-
+
// now generate the aroundBody method
// eg. "private static final void method_aroundBody0(M, M, String, org.aspectj.lang.JoinPoint)"
- LazyMethodGen extractedMethod =
- extractMethod(
- NameMangler.aroundCallbackMethodName(getSignature(),getEnclosingClass()),
- Modifier.PRIVATE,
- munger);
-
- // now extract the advice into its own method
- String adviceMethodName =
- NameMangler.aroundCallbackMethodName(getSignature(),getEnclosingClass()) + "$advice";
-
- List argVarList = new ArrayList();
- List proceedVarList = new ArrayList();
+ LazyMethodGen extractedMethod = extractMethod(NameMangler.aroundCallbackMethodName(getSignature(), getEnclosingClass()),
+ Modifier.PRIVATE, munger);
+
+ // now extract the advice into its own method
+ String adviceMethodName = NameMangler.aroundCallbackMethodName(getSignature(), getEnclosingClass()) + "$advice";
+
+ List argVarList = new ArrayList();
+ List proceedVarList = new ArrayList();
int extraParamOffset = 0;
-
+
// Create the extra parameters that are needed for passing to proceed
// This code is very similar to that found in makeCallToCallback and should
// be rationalized in the future
-
+
if (thisVar != null) {
argVarList.add(thisVar);
proceedVarList.add(new BcelVar(thisVar.getType(), extraParamOffset));
extraParamOffset += thisVar.getType().getSize();
}
-
+
if (targetVar != null && targetVar != thisVar) {
argVarList.add(targetVar);
proceedVarList.add(new BcelVar(targetVar.getType(), extraParamOffset));
@@ -2352,1205 +2094,1053 @@ public class BcelShadow extends Shadow {
proceedVarList.add(new BcelVar(thisJoinPointVar.getType(), extraParamOffset));
extraParamOffset += thisJoinPointVar.getType().getSize();
}
-
+
// We use the munger signature here because it allows for any parameterization of the mungers pointcut that
// may have occurred ie. if the pointcut is p(T t) in the super aspect and that has become p(Foo t) in the sub aspect
- // then here the munger signature will have 'Foo' as an argument in it whilst the adviceMethod argument type will be 'Object' - since
- // it represents the advice method in the superaspect which uses the erasure of the type variable p(Object t) - see pr174449.
-
- Type[] adviceParameterTypes =
- BcelWorld.makeBcelTypes(munger.getSignature().getParameterTypes());
-// adviceMethod.getArgumentTypes();
- adviceMethod.getArgumentTypes(); // forces initialization ... dont like this but seems to be required for some tests to pass, I think that means
- // there is a LazyMethodGen method that is not correctly setup to call initialize() when it is invoked - but I dont have
- // time right now to discover which
- Type[] extractedMethodParameterTypes = extractedMethod.getArgumentTypes();
- Type[] parameterTypes =
- new Type[extractedMethodParameterTypes.length
- + adviceParameterTypes.length
- + 1];
+ // then here the munger signature will have 'Foo' as an argument in it whilst the adviceMethod argument type will be
+ // 'Object' - since
+ // it represents the advice method in the superaspect which uses the erasure of the type variable p(Object t) - see
+ // pr174449.
+
+ Type[] adviceParameterTypes = BcelWorld.makeBcelTypes(munger.getSignature().getParameterTypes());
+ // adviceMethod.getArgumentTypes();
+ adviceMethod.getArgumentTypes(); // forces initialization ... dont like this but seems to be required for some tests to
+ // pass, I think that means
+ // there is a LazyMethodGen method that is not correctly setup to call initialize() when it is invoked - but I dont have
+ // time right now to discover which
+ Type[] extractedMethodParameterTypes = extractedMethod.getArgumentTypes();
+ Type[] parameterTypes = new Type[extractedMethodParameterTypes.length + adviceParameterTypes.length + 1];
int parameterIndex = 0;
- System.arraycopy(
- extractedMethodParameterTypes,
- 0,
- parameterTypes,
- parameterIndex,
- extractedMethodParameterTypes.length);
+ System.arraycopy(extractedMethodParameterTypes, 0, parameterTypes, parameterIndex, extractedMethodParameterTypes.length);
parameterIndex += extractedMethodParameterTypes.length;
- parameterTypes[parameterIndex++] =
- BcelWorld.makeBcelType(adviceMethod.getEnclosingClass().getType());
- System.arraycopy(
- adviceParameterTypes,
- 0,
- parameterTypes,
- parameterIndex,
- adviceParameterTypes.length);
-// parameterTypes is [Bug, C, org.aspectj.lang.JoinPoint, X, org.aspectj.lang.ProceedingJoinPoint, java.lang.Object, java.lang.Object]
- LazyMethodGen localAdviceMethod =
- new LazyMethodGen(
- Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC,
- BcelWorld.makeBcelType(mungerSig.getReturnType()),
- adviceMethodName,
- parameterTypes,
- new String[0],
- getEnclosingClass());
-
+ parameterTypes[parameterIndex++] = BcelWorld.makeBcelType(adviceMethod.getEnclosingClass().getType());
+ System.arraycopy(adviceParameterTypes, 0, parameterTypes, parameterIndex, adviceParameterTypes.length);
+ // parameterTypes is [Bug, C, org.aspectj.lang.JoinPoint, X, org.aspectj.lang.ProceedingJoinPoint, java.lang.Object,
+ // java.lang.Object]
+ LazyMethodGen localAdviceMethod = new LazyMethodGen(Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC, BcelWorld
+ .makeBcelType(mungerSig.getReturnType()), adviceMethodName, parameterTypes, new String[0], getEnclosingClass());
+
String donorFileName = adviceMethod.getEnclosingClass().getInternalFileName();
String recipientFileName = getEnclosingClass().getInternalFileName();
-// System.err.println("donor " + donorFileName);
-// System.err.println("recip " + recipientFileName);
- if (! donorFileName.equals(recipientFileName)) {
+ // System.err.println("donor " + donorFileName);
+ // System.err.println("recip " + recipientFileName);
+ if (!donorFileName.equals(recipientFileName)) {
localAdviceMethod.fromFilename = donorFileName;
- getEnclosingClass().addInlinedSourceFileInfo(
- donorFileName,
- adviceMethod.highestLineNumber);
+ getEnclosingClass().addInlinedSourceFileInfo(donorFileName, adviceMethod.highestLineNumber);
}
-
+
getEnclosingClass().addMethodGen(localAdviceMethod);
-
+
// create a map that will move all slots in advice method forward by extraParamOffset
// in order to make room for the new proceed-required arguments that are added at
// the beginning of the parameter list
int nVars = adviceMethod.getMaxLocals() + extraParamOffset;
IntMap varMap = IntMap.idMap(nVars);
- for (int i=extraParamOffset; i < nVars; i++) {
- varMap.put(i-extraParamOffset, i);
+ for (int i = extraParamOffset; i < nVars; i++) {
+ varMap.put(i - extraParamOffset, i);
}
localAdviceMethod.getBody().insert(
- BcelClassWeaver.genInlineInstructions(adviceMethod,
- localAdviceMethod, varMap, fact, true));
+ BcelClassWeaver.genInlineInstructions(adviceMethod, localAdviceMethod, varMap, fact, true));
-
-
localAdviceMethod.setMaxLocals(nVars);
-
- //System.err.println(localAdviceMethod);
-
-
- // the shadow is now empty. First, create a correct call
- // to the around advice. This includes both the call (which may involve
- // value conversion of the advice arguments) and the return
- // (which may involve value conversion of the return value). Right now
- // we push a null for the unused closure. It's sad, but there it is.
-
- InstructionList advice = new InstructionList();
- // InstructionHandle adviceMethodInvocation;
- {
- for (Iterator i = argVarList.iterator(); i.hasNext(); ) {
- BcelVar var = (BcelVar)i.next();
+
+ // System.err.println(localAdviceMethod);
+
+ // the shadow is now empty. First, create a correct call
+ // to the around advice. This includes both the call (which may involve
+ // value conversion of the advice arguments) and the return
+ // (which may involve value conversion of the return value). Right now
+ // we push a null for the unused closure. It's sad, but there it is.
+
+ InstructionList advice = new InstructionList();
+ // InstructionHandle adviceMethodInvocation;
+ {
+ for (Iterator i = argVarList.iterator(); i.hasNext();) {
+ BcelVar var = (BcelVar) i.next();
var.appendLoad(advice, fact);
- }
- // ??? we don't actually need to push NULL for the closure if we take care
- advice.append(
- munger.getAdviceArgSetup(
- this,
- null,
- (munger.getConcreteAspect().isAnnotationStyleAspect() && munger.getDeclaringAspect()!=null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect())?
- this.loadThisJoinPoint():
- new InstructionList(InstructionConstants.ACONST_NULL)));
- // adviceMethodInvocation =
- advice.append(
- Utility.createInvoke(fact, localAdviceMethod)); //(fact, getWorld(), munger.getSignature()));
- advice.append(
- Utility.createConversion(
- getFactory(),
- BcelWorld.makeBcelType(mungerSig.getReturnType()),
- extractedMethod.getReturnType(),world.isInJava5Mode()));
- if (! isFallsThrough()) {
- advice.append(InstructionFactory.createReturn(extractedMethod.getReturnType()));
- }
- }
-
+ }
+ // ??? we don't actually need to push NULL for the closure if we take care
+ advice.append(munger.getAdviceArgSetup(this, null,
+ (munger.getConcreteAspect().isAnnotationStyleAspect() && munger.getDeclaringAspect() != null && munger
+ .getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) ? this.loadThisJoinPoint()
+ : new InstructionList(InstructionConstants.ACONST_NULL)));
+ // adviceMethodInvocation =
+ advice.append(Utility.createInvoke(fact, localAdviceMethod)); // (fact, getWorld(), munger.getSignature()));
+ advice.append(Utility.createConversion(getFactory(), BcelWorld.makeBcelType(mungerSig.getReturnType()), extractedMethod
+ .getReturnType(), world.isInJava5Mode()));
+ if (!isFallsThrough()) {
+ advice.append(InstructionFactory.createReturn(extractedMethod.getReturnType()));
+ }
+ }
+
// now, situate the call inside the possible dynamic tests,
// and actually add the whole mess to the shadow
- if (! hasDynamicTest) {
- range.append(advice);
- } else {
- InstructionList afterThingie = new InstructionList(InstructionConstants.NOP);
- InstructionList callback = makeCallToCallback(extractedMethod);
+ if (!hasDynamicTest) {
+ range.append(advice);
+ } else {
+ InstructionList afterThingie = new InstructionList(InstructionConstants.NOP);
+ InstructionList callback = makeCallToCallback(extractedMethod);
if (terminatesWithReturn()) {
- callback.append(
- InstructionFactory.createReturn(extractedMethod.getReturnType()));
+ callback.append(InstructionFactory.createReturn(extractedMethod.getReturnType()));
} else {
- //InstructionHandle endNop = range.insert(fact.NOP, Range.InsideAfter);
- advice.append(
- InstructionFactory.createBranchInstruction(
- Constants.GOTO,
- afterThingie.getStart()));
+ // InstructionHandle endNop = range.insert(fact.NOP, Range.InsideAfter);
+ advice.append(InstructionFactory.createBranchInstruction(Constants.GOTO, afterThingie.getStart()));
}
- range.append(
- munger.getTestInstructions(
- this,
- advice.getStart(),
- callback.getStart(),
- advice.getStart()));
- range.append(advice);
- range.append(callback);
- range.append(afterThingie);
- }
-
-
- // now search through the advice, looking for a call to PROCEED.
- // Then we replace the call to proceed with some argument setup, and a
- // call to the extracted method.
-
- // inlining support for code style aspects
- if (!munger.getDeclaringType().isAnnotationStyleAspect()) {
- String proceedName =
- NameMangler.proceedMethodName(munger.getSignature().getName());
-
- InstructionHandle curr = localAdviceMethod.getBody().getStart();
- InstructionHandle end = localAdviceMethod.getBody().getEnd();
- ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool();
- while (curr != end) {
- InstructionHandle next = curr.getNext();
- Instruction inst = curr.getInstruction();
- if ((inst.opcode==Constants.INVOKESTATIC)
- && proceedName.equals(((InvokeInstruction) inst).getMethodName(cpg))) {
-
- localAdviceMethod.getBody().append(
- curr,
- getRedoneProceedCall(
- fact,
- extractedMethod,
- munger,
- localAdviceMethod,
- proceedVarList));
- Utility.deleteInstruction(curr, localAdviceMethod);
- }
- curr = next;
- }
- // and that's it.
- } else {
- //ATAJ inlining support for @AJ aspects
- // [TODO document @AJ code rule: don't manipulate 2 jps proceed at the same time.. in an advice body]
- InstructionHandle curr = localAdviceMethod.getBody().getStart();
- InstructionHandle end = localAdviceMethod.getBody().getEnd();
- ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool();
- while (curr != end) {
- InstructionHandle next = curr.getNext();
- Instruction inst = curr.getInstruction();
- if ((inst instanceof INVOKEINTERFACE)
- && "proceed".equals(((INVOKEINTERFACE) inst).getMethodName(cpg))) {
- final boolean isProceedWithArgs;
- if (((INVOKEINTERFACE) inst).getArgumentTypes(cpg).length == 1) {
- // proceed with args as a boxed Object[]
- isProceedWithArgs = true;
- } else {
- isProceedWithArgs = false;
- }
- InstructionList insteadProceedIl = getRedoneProceedCallForAnnotationStyle(
- fact,
- extractedMethod,
- munger,
- localAdviceMethod,
- proceedVarList,
- isProceedWithArgs
- );
- localAdviceMethod.getBody().append(curr, insteadProceedIl);
- Utility.deleteInstruction(curr, localAdviceMethod);
- }
- curr = next;
- }
- }
- }
-
- private InstructionList getRedoneProceedCall(
- InstructionFactory fact,
- LazyMethodGen callbackMethod,
- BcelAdvice munger,
- LazyMethodGen localAdviceMethod,
- List argVarList)
- {
+ range.append(munger.getTestInstructions(this, advice.getStart(), callback.getStart(), advice.getStart()));
+ range.append(advice);
+ range.append(callback);
+ range.append(afterThingie);
+ }
+
+ // now search through the advice, looking for a call to PROCEED.
+ // Then we replace the call to proceed with some argument setup, and a
+ // call to the extracted method.
+
+ // inlining support for code style aspects
+ if (!munger.getDeclaringType().isAnnotationStyleAspect()) {
+ String proceedName = NameMangler.proceedMethodName(munger.getSignature().getName());
+
+ InstructionHandle curr = localAdviceMethod.getBody().getStart();
+ InstructionHandle end = localAdviceMethod.getBody().getEnd();
+ ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool();
+ while (curr != end) {
+ InstructionHandle next = curr.getNext();
+ Instruction inst = curr.getInstruction();
+ if ((inst.opcode == Constants.INVOKESTATIC) && proceedName.equals(((InvokeInstruction) inst).getMethodName(cpg))) {
+
+ localAdviceMethod.getBody().append(curr,
+ getRedoneProceedCall(fact, extractedMethod, munger, localAdviceMethod, proceedVarList));
+ Utility.deleteInstruction(curr, localAdviceMethod);
+ }
+ curr = next;
+ }
+ // and that's it.
+ } else {
+ // ATAJ inlining support for @AJ aspects
+ // [TODO document @AJ code rule: don't manipulate 2 jps proceed at the same time.. in an advice body]
+ InstructionHandle curr = localAdviceMethod.getBody().getStart();
+ InstructionHandle end = localAdviceMethod.getBody().getEnd();
+ ConstantPool cpg = localAdviceMethod.getEnclosingClass().getConstantPool();
+ while (curr != end) {
+ InstructionHandle next = curr.getNext();
+ Instruction inst = curr.getInstruction();
+ if ((inst instanceof INVOKEINTERFACE) && "proceed".equals(((INVOKEINTERFACE) inst).getMethodName(cpg))) {
+ final boolean isProceedWithArgs;
+ if (((INVOKEINTERFACE) inst).getArgumentTypes(cpg).length == 1) {
+ // proceed with args as a boxed Object[]
+ isProceedWithArgs = true;
+ } else {
+ isProceedWithArgs = false;
+ }
+ InstructionList insteadProceedIl = getRedoneProceedCallForAnnotationStyle(fact, extractedMethod, munger,
+ localAdviceMethod, proceedVarList, isProceedWithArgs);
+ localAdviceMethod.getBody().append(curr, insteadProceedIl);
+ Utility.deleteInstruction(curr, localAdviceMethod);
+ }
+ curr = next;
+ }
+ }
+ }
+
+ private InstructionList getRedoneProceedCall(InstructionFactory fact, LazyMethodGen callbackMethod, BcelAdvice munger,
+ LazyMethodGen localAdviceMethod, List argVarList) {
InstructionList ret = new InstructionList();
// we have on stack all the arguments for the ADVICE call.
// we have in frame somewhere all the arguments for the non-advice call.
-
+
BcelVar[] adviceVars = munger.getExposedStateAsBcelVars(true);
- IntMap proceedMap = makeProceedArgumentMap(adviceVars);
+ IntMap proceedMap = makeProceedArgumentMap(adviceVars);
+
+ // System.out.println(proceedMap + " for " + this);
+ // System.out.println(argVarList);
-// System.out.println(proceedMap + " for " + this);
-// System.out.println(argVarList);
-
- ResolvedType[] proceedParamTypes =
- world.resolve(munger.getSignature().getParameterTypes());
+ ResolvedType[] proceedParamTypes = world.resolve(munger.getSignature().getParameterTypes());
// remove this*JoinPoint* as arguments to proceed
- if (munger.getBaseParameterCount()+1 < proceedParamTypes.length) {
- int len = munger.getBaseParameterCount()+1;
+ if (munger.getBaseParameterCount() + 1 < proceedParamTypes.length) {
+ int len = munger.getBaseParameterCount() + 1;
ResolvedType[] newTypes = new ResolvedType[len];
System.arraycopy(proceedParamTypes, 0, newTypes, 0, len);
proceedParamTypes = newTypes;
}
- //System.out.println("stateTypes: " + Arrays.asList(stateTypes));
- BcelVar[] proceedVars =
- Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
+ // System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+ BcelVar[] proceedVars = Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
Type[] stateTypes = callbackMethod.getArgumentTypes();
-// System.out.println("stateTypes: " + Arrays.asList(stateTypes));
-
- for (int i=0, len=stateTypes.length; i < len; i++) {
- Type stateType = stateTypes[i];
- ResolvedType stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
- if (proceedMap.hasKey(i)) {
- //throw new RuntimeException("unimplemented");
+ // System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+
+ for (int i = 0, len = stateTypes.length; i < len; i++) {
+ Type stateType = stateTypes[i];
+ ResolvedType stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
+ if (proceedMap.hasKey(i)) {
+ // throw new RuntimeException("unimplemented");
proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
- } else {
+ } else {
((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
- }
+ }
+ }
+
+ ret.append(Utility.createInvoke(fact, callbackMethod));
+ ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(), BcelWorld.makeBcelType(munger.getSignature()
+ .getReturnType())));
+ return ret;
+ }
+
+ // private static boolean bindsThisOrTarget(Pointcut pointcut) {
+ // ThisTargetFinder visitor = new ThisTargetFinder();
+ // pointcut.accept(visitor, null);
+ // return visitor.bindsThisOrTarget;
+ // }
+
+ // private static class ThisTargetFinder extends IdentityPointcutVisitor {
+ // boolean bindsThisOrTarget = false;
+ //
+ // public Object visit(ThisOrTargetPointcut node, Object data) {
+ // if (node.isBinding()) {
+ // bindsThisOrTarget = true;
+ // }
+ // return node;
+ // }
+ //
+ // public Object visit(AndPointcut node, Object data) {
+ // if (!bindsThisOrTarget) node.getLeft().accept(this, data);
+ // if (!bindsThisOrTarget) node.getRight().accept(this, data);
+ // return node;
+ // }
+ //
+ // public Object visit(NotPointcut node, Object data) {
+ // if (!bindsThisOrTarget) node.getNegatedPointcut().accept(this, data);
+ // return node;
+ // }
+ //
+ // public Object visit(OrPointcut node, Object data) {
+ // if (!bindsThisOrTarget) node.getLeft().accept(this, data);
+ // if (!bindsThisOrTarget) node.getRight().accept(this, data);
+ // return node;
+ // }
+ // }
+
+ /**
+ * Annotation style handling for inlining.
+ *
+ * Note: The proceedingjoinpoint is already on the stack (since the user was calling pjp.proceed(...)
+ *
+ * The proceed map is ignored (in terms of argument repositioning) since we have a fixed expected format for annotation style.
+ * The aim here is to change the proceed() call into a call to the xxx_aroundBody0 method.
+ *
+ *
+ */
+ private InstructionList getRedoneProceedCallForAnnotationStyle(InstructionFactory fact, LazyMethodGen callbackMethod,
+ BcelAdvice munger, LazyMethodGen localAdviceMethod, List argVarList, boolean isProceedWithArgs) {
+ InstructionList ret = new InstructionList();
+
+ // store the Object[] array on stack if proceed with args
+ if (isProceedWithArgs) {
+
+ // STORE the Object[] into a local variable
+ Type objectArrayType = Type.OBJECT_ARRAY;
+ int theObjectArrayLocalNumber = localAdviceMethod.allocateLocal(objectArrayType);
+ ret.append(InstructionFactory.createStore(objectArrayType, theObjectArrayLocalNumber));
+
+ // STORE the ProceedingJoinPoint instance into a local variable
+ Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
+ int pjpLocalNumber = localAdviceMethod.allocateLocal(proceedingJpType);
+ ret.append(InstructionFactory.createStore(proceedingJpType, pjpLocalNumber));
+
+ // Aim here initially is to determine whether the user will have provided a new
+ // this/target in the object array and consume them if they have, leaving us the rest of
+ // the arguments to process as regular arguments to the invocation at the original join point
+
+ boolean pointcutBindsThis = bindsThis(munger);
+ boolean pointcutBindsTarget = bindsTarget(munger);
+ boolean targetIsSameAsThis = getKind().isTargetSameAsThis();
+
+ int nextArgumentToProvideForCallback = 0;
+
+ if (hasThis()) {
+ if (!(pointcutBindsTarget && targetIsSameAsThis)) {
+ if (pointcutBindsThis) {
+ // they have supplied new this as first entry in object array, consume it
+ ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
+ ret.append(Utility.createConstant(fact, 0));
+ ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
+ ret.append(Utility.createConversion(fact, Type.OBJECT, callbackMethod.getArgumentTypes()[0]));
+ } else {
+ // use local variable 0
+ ret.append(InstructionFactory.createALOAD(0));
+ }
+ nextArgumentToProvideForCallback++;
+ }
+ }
+
+ if (hasTarget()) {
+ if (pointcutBindsTarget) {
+ if (getKind().isTargetSameAsThis()) {
+ ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
+ ret.append(Utility.createConstant(fact, pointcutBindsThis ? 1 : 0));
+ ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
+ ret.append(Utility.createConversion(fact, Type.OBJECT, callbackMethod.getArgumentTypes()[0]));
+ } else {
+ int position = (hasThis() && pointcutBindsThis ? 1 : 0);
+ ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
+ ret.append(Utility.createConstant(fact, position));
+ ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
+ ret.append(Utility.createConversion(fact, Type.OBJECT, callbackMethod.getArgumentTypes()[position]));
+ }
+ nextArgumentToProvideForCallback++;
+ } else {
+ if (getKind().isTargetSameAsThis()) {
+ // ret.append(new ALOAD(0));
+ } else {
+ ret.append(InstructionFactory.createLoad(localAdviceMethod.getArgumentTypes()[0], hasThis() ? 1 : 0));
+ nextArgumentToProvideForCallback++;
+ }
+ }
+ }
+
+ // Where to start in the object array in order to pick up arguments
+ int indexIntoObjectArrayForArguments = (pointcutBindsThis ? 1 : 0) + (pointcutBindsTarget ? 1 : 0);
+
+ int len = callbackMethod.getArgumentTypes().length;
+ for (int i = nextArgumentToProvideForCallback; i < len; i++) {
+ Type stateType = callbackMethod.getArgumentTypes()[i];
+ BcelWorld.fromBcel(stateType).resolve(world);
+ if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
+ ret.append(new InstructionLV(Constants.ALOAD, pjpLocalNumber));
+ } else {
+ ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
+ ret.append(Utility
+ .createConstant(fact, i - nextArgumentToProvideForCallback + indexIntoObjectArrayForArguments));
+ ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
+ ret.append(Utility.createConversion(fact, Type.OBJECT, stateType));
+ }
+ }
+
+ } else {
+ Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
+ int localJp = localAdviceMethod.allocateLocal(proceedingJpType);
+ ret.append(InstructionFactory.createStore(proceedingJpType, localJp));
+
+ for (int i = 0, len = callbackMethod.getArgumentTypes().length; i < len; i++) {
+ Type stateType = callbackMethod.getArgumentTypes()[i];
+ /* ResolvedType stateTypeX = */
+ BcelWorld.fromBcel(stateType).resolve(world);
+ if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
+ ret.append(InstructionFactory.createALOAD(localJp));// from localAdvice signature
+ // } else if ("Lorg/aspectj/lang/ProceedingJoinPoint;".equals(stateType.getSignature())) {
+ // //FIXME ALEX?
+ // ret.append(new ALOAD(localJp));// from localAdvice signature
+ // // ret.append(fact.createCheckCast(
+ // // (ReferenceType) BcelWorld.makeBcelType(stateTypeX)
+ // // ));
+ // // cast ?
+ //
+ } else {
+ ret.append(InstructionFactory.createLoad(stateType, i));
+ }
+ }
}
-
+
+ // do the callback invoke
ret.append(Utility.createInvoke(fact, callbackMethod));
- ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
- BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
+
+ // box it again. Handles cases where around advice does return something else than Object
+ if (!UnresolvedType.OBJECT.equals(munger.getSignature().getReturnType())) {
+ ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(), Type.OBJECT));
+ }
+ ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(), BcelWorld.makeBcelType(munger.getSignature()
+ .getReturnType())));
+
return ret;
+
+ //
+ //
+ //
+ // if (proceedMap.hasKey(i)) {
+ // ret.append(new ALOAD(i));
+ // //throw new RuntimeException("unimplemented");
+ // //proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
+ // } else {
+ // //((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
+ // //ret.append(new ALOAD(i));
+ // if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
+ // ret.append(new ALOAD(i));
+ // } else {
+ // ret.append(new ALOAD(i));
+ // }
+ // }
+ // }
+ //
+ // ret.append(Utility.createInvoke(fact, callbackMethod));
+ // ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
+ // BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
+ //
+ // //ret.append(new ACONST_NULL());//will be POPed
+ // if (true) return ret;
+ //
+ //
+ //
+ // // we have on stack all the arguments for the ADVICE call.
+ // // we have in frame somewhere all the arguments for the non-advice call.
+ //
+ // BcelVar[] adviceVars = munger.getExposedStateAsBcelVars();
+ // IntMap proceedMap = makeProceedArgumentMap(adviceVars);
+ //
+ // System.out.println(proceedMap + " for " + this);
+ // System.out.println(argVarList);
+ //
+ // ResolvedType[] proceedParamTypes =
+ // world.resolve(munger.getSignature().getParameterTypes());
+ // // remove this*JoinPoint* as arguments to proceed
+ // if (munger.getBaseParameterCount()+1 < proceedParamTypes.length) {
+ // int len = munger.getBaseParameterCount()+1;
+ // ResolvedType[] newTypes = new ResolvedType[len];
+ // System.arraycopy(proceedParamTypes, 0, newTypes, 0, len);
+ // proceedParamTypes = newTypes;
+ // }
+ //
+ // //System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+ // BcelVar[] proceedVars =
+ // Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
+ //
+ // Type[] stateTypes = callbackMethod.getArgumentTypes();
+ // // System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+ //
+ // for (int i=0, len=stateTypes.length; i < len; i++) {
+ // Type stateType = stateTypes[i];
+ // ResolvedType stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
+ // if (proceedMap.hasKey(i)) {
+ // //throw new RuntimeException("unimplemented");
+ // proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
+ // } else {
+ // ((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
+ // }
+ // }
+ //
+ // ret.append(Utility.createInvoke(fact, callbackMethod));
+ // ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
+ // BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
+ // return ret;
}
-
-// private static boolean bindsThisOrTarget(Pointcut pointcut) {
-// ThisTargetFinder visitor = new ThisTargetFinder();
-// pointcut.accept(visitor, null);
-// return visitor.bindsThisOrTarget;
-// }
-
-// private static class ThisTargetFinder extends IdentityPointcutVisitor {
-// boolean bindsThisOrTarget = false;
-//
-// public Object visit(ThisOrTargetPointcut node, Object data) {
-// if (node.isBinding()) {
-// bindsThisOrTarget = true;
-// }
-// return node;
-// }
-//
-// public Object visit(AndPointcut node, Object data) {
-// if (!bindsThisOrTarget) node.getLeft().accept(this, data);
-// if (!bindsThisOrTarget) node.getRight().accept(this, data);
-// return node;
-// }
-//
-// public Object visit(NotPointcut node, Object data) {
-// if (!bindsThisOrTarget) node.getNegatedPointcut().accept(this, data);
-// return node;
-// }
-//
-// public Object visit(OrPointcut node, Object data) {
-// if (!bindsThisOrTarget) node.getLeft().accept(this, data);
-// if (!bindsThisOrTarget) node.getRight().accept(this, data);
-// return node;
-// }
-// }
-
-
- /**
- * Annotation style handling for inlining.
- *
- * Note:
- * The proceedingjoinpoint is already on the stack (since the user was calling pjp.proceed(...)
- *
- * The proceed map is ignored (in terms of argument repositioning) since we have a fixed expected
- * format for annotation style. The aim here is to change the proceed() call into a call to
- * the xxx_aroundBody0 method.
- *
- *
- */
- private InstructionList getRedoneProceedCallForAnnotationStyle(
- InstructionFactory fact,
- LazyMethodGen callbackMethod,
- BcelAdvice munger,
- LazyMethodGen localAdviceMethod,
- List argVarList,
- boolean isProceedWithArgs)
- {
- InstructionList ret = new InstructionList();
-
- // store the Object[] array on stack if proceed with args
- if (isProceedWithArgs) {
-
- // STORE the Object[] into a local variable
- Type objectArrayType = Type.OBJECT_ARRAY;
- int theObjectArrayLocalNumber = localAdviceMethod.allocateLocal(objectArrayType);
- ret.append(InstructionFactory.createStore(objectArrayType, theObjectArrayLocalNumber));
-
- // STORE the ProceedingJoinPoint instance into a local variable
- Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
- int pjpLocalNumber = localAdviceMethod.allocateLocal(proceedingJpType);
- ret.append(InstructionFactory.createStore(proceedingJpType, pjpLocalNumber));
-
- // Aim here initially is to determine whether the user will have provided a new
- // this/target in the object array and consume them if they have, leaving us the rest of
- // the arguments to process as regular arguments to the invocation at the original join point
-
- boolean pointcutBindsThis = bindsThis(munger);
- boolean pointcutBindsTarget = bindsTarget(munger);
- boolean targetIsSameAsThis = getKind().isTargetSameAsThis();
-
- int nextArgumentToProvideForCallback = 0;
-
- if (hasThis() ) {
- if (!(pointcutBindsTarget && targetIsSameAsThis)) {
- if (pointcutBindsThis) {
- // they have supplied new this as first entry in object array, consume it
- ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
- ret.append(Utility.createConstant(fact, 0));
- ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
- ret.append(Utility.createConversion(fact,Type.OBJECT,callbackMethod.getArgumentTypes()[0]));
- } else {
- // use local variable 0
- ret.append(InstructionFactory.createALOAD(0));
- }
- nextArgumentToProvideForCallback++;
- }
- }
-
-
-
- if (hasTarget()) {
- if (pointcutBindsTarget) {
- if (getKind().isTargetSameAsThis()) {
- ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
- ret.append(Utility.createConstant(fact, pointcutBindsThis?1:0));
- ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
- ret.append(Utility.createConversion(fact,Type.OBJECT,callbackMethod.getArgumentTypes()[0]));
- } else {
- int position =(hasThis()&& pointcutBindsThis?1:0);
- ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
- ret.append(Utility.createConstant(fact, position));
- ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
- ret.append(Utility.createConversion(fact,Type.OBJECT,callbackMethod.getArgumentTypes()[position]));
- }
- nextArgumentToProvideForCallback++;
- } else {
- if (getKind().isTargetSameAsThis()) {
- //ret.append(new ALOAD(0));
- } else {
- ret.append(InstructionFactory.createLoad(localAdviceMethod.getArgumentTypes()[0],hasThis()?1:0));
- nextArgumentToProvideForCallback++;
- }
- }
- }
-
- // Where to start in the object array in order to pick up arguments
- int indexIntoObjectArrayForArguments = (pointcutBindsThis?1:0)+(pointcutBindsTarget?1:0);
-
- int len = callbackMethod.getArgumentTypes().length;
- for (int i = nextArgumentToProvideForCallback; i < len; i++) {
- Type stateType = callbackMethod.getArgumentTypes()[i];
- BcelWorld.fromBcel(stateType).resolve(world);
- if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
- ret.append(new InstructionLV(Constants.ALOAD, pjpLocalNumber));
- } else {
- ret.append(InstructionFactory.createLoad(objectArrayType, theObjectArrayLocalNumber));
- ret.append(Utility.createConstant(fact, i-nextArgumentToProvideForCallback+indexIntoObjectArrayForArguments));
- ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
- ret.append(Utility.createConversion(fact, Type.OBJECT, stateType));
- }
- }
-
- } else {
- Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
- int localJp = localAdviceMethod.allocateLocal(proceedingJpType);
- ret.append(InstructionFactory.createStore(proceedingJpType, localJp));
-
- for (int i = 0, len=callbackMethod.getArgumentTypes().length; i < len; i++) {
- Type stateType = callbackMethod.getArgumentTypes()[i];
- /*ResolvedType stateTypeX =*/
- BcelWorld.fromBcel(stateType).resolve(world);
- if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
- ret.append(InstructionFactory.createALOAD(localJp));// from localAdvice signature
-// } else if ("Lorg/aspectj/lang/ProceedingJoinPoint;".equals(stateType.getSignature())) {
-// //FIXME ALEX?
-// ret.append(new ALOAD(localJp));// from localAdvice signature
-//// ret.append(fact.createCheckCast(
-//// (ReferenceType) BcelWorld.makeBcelType(stateTypeX)
-//// ));
-// // cast ?
-//
- } else {
- ret.append(InstructionFactory.createLoad(stateType, i));
- }
- }
- }
-
- // do the callback invoke
- ret.append(Utility.createInvoke(fact, callbackMethod));
-
- // box it again. Handles cases where around advice does return something else than Object
- if (!UnresolvedType.OBJECT.equals(munger.getSignature().getReturnType())) {
- ret.append(Utility.createConversion(
- fact,
- callbackMethod.getReturnType(),
- Type.OBJECT
- ));
- }
- ret.append(Utility.createConversion(
- fact,
- callbackMethod.getReturnType(),
- BcelWorld.makeBcelType(munger.getSignature().getReturnType())
- ));
-
- return ret;
-
-//
-//
-//
-// if (proceedMap.hasKey(i)) {
-// ret.append(new ALOAD(i));
-// //throw new RuntimeException("unimplemented");
-// //proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
-// } else {
-// //((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
-// //ret.append(new ALOAD(i));
-// if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
-// ret.append(new ALOAD(i));
-// } else {
-// ret.append(new ALOAD(i));
-// }
-// }
-// }
-//
-// ret.append(Utility.createInvoke(fact, callbackMethod));
-// ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
-// BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
-//
-// //ret.append(new ACONST_NULL());//will be POPed
-// if (true) return ret;
-//
-//
-//
-// // we have on stack all the arguments for the ADVICE call.
-// // we have in frame somewhere all the arguments for the non-advice call.
-//
-// BcelVar[] adviceVars = munger.getExposedStateAsBcelVars();
-// IntMap proceedMap = makeProceedArgumentMap(adviceVars);
-//
-// System.out.println(proceedMap + " for " + this);
-// System.out.println(argVarList);
-//
-// ResolvedType[] proceedParamTypes =
-// world.resolve(munger.getSignature().getParameterTypes());
-// // remove this*JoinPoint* as arguments to proceed
-// if (munger.getBaseParameterCount()+1 < proceedParamTypes.length) {
-// int len = munger.getBaseParameterCount()+1;
-// ResolvedType[] newTypes = new ResolvedType[len];
-// System.arraycopy(proceedParamTypes, 0, newTypes, 0, len);
-// proceedParamTypes = newTypes;
-// }
-//
-// //System.out.println("stateTypes: " + Arrays.asList(stateTypes));
-// BcelVar[] proceedVars =
-// Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
-//
-// Type[] stateTypes = callbackMethod.getArgumentTypes();
-//// System.out.println("stateTypes: " + Arrays.asList(stateTypes));
-//
-// for (int i=0, len=stateTypes.length; i < len; i++) {
-// Type stateType = stateTypes[i];
-// ResolvedType stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
-// if (proceedMap.hasKey(i)) {
-// //throw new RuntimeException("unimplemented");
-// proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
-// } else {
-// ((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
-// }
-// }
-//
-// ret.append(Utility.createInvoke(fact, callbackMethod));
-// ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
-// BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
-// return ret;
- }
-
- private boolean bindsThis(BcelAdvice munger) {
- UsesThisVisitor utv = new UsesThisVisitor();
- munger.getPointcut().accept(utv, null);
+
+ private boolean bindsThis(BcelAdvice munger) {
+ UsesThisVisitor utv = new UsesThisVisitor();
+ munger.getPointcut().accept(utv, null);
return utv.usesThis;
}
- private boolean bindsTarget(BcelAdvice munger) {
- UsesTargetVisitor utv = new UsesTargetVisitor();
- munger.getPointcut().accept(utv, null);
+ private boolean bindsTarget(BcelAdvice munger) {
+ UsesTargetVisitor utv = new UsesTargetVisitor();
+ munger.getPointcut().accept(utv, null);
return utv.usesTarget;
}
-
- private static class UsesThisVisitor extends IdentityPointcutVisitor {
- boolean usesThis = false;
-
- public Object visit(ThisOrTargetPointcut node, Object data) {
- if (node.isThis() && node.isBinding()) usesThis=true;
- return node;
- }
-
- public Object visit(AndPointcut node, Object data) {
- if (!usesThis) node.getLeft().accept(this, data);
- if (!usesThis) node.getRight().accept(this, data);
- return node;
- }
-
- public Object visit(NotPointcut node, Object data) {
- if (!usesThis) node.getNegatedPointcut().accept(this, data);
- return node;
- }
-
- public Object visit(OrPointcut node, Object data) {
- if (!usesThis) node.getLeft().accept(this, data);
- if (!usesThis) node.getRight().accept(this, data);
- return node;
- }
- }
-
-
- private static class UsesTargetVisitor extends IdentityPointcutVisitor {
- boolean usesTarget = false;
-
- public Object visit(ThisOrTargetPointcut node, Object data) {
- if (!node.isThis() && node.isBinding()) usesTarget=true;
- return node;
- }
-
- public Object visit(AndPointcut node, Object data) {
- if (!usesTarget) node.getLeft().accept(this, data);
- if (!usesTarget) node.getRight().accept(this, data);
- return node;
- }
-
- public Object visit(NotPointcut node, Object data) {
- if (!usesTarget) node.getNegatedPointcut().accept(this, data);
- return node;
- }
-
- public Object visit(OrPointcut node, Object data) {
- if (!usesTarget) node.getLeft().accept(this, data);
- if (!usesTarget) node.getRight().accept(this, data);
- return node;
- }
- }
+
+ private static class UsesThisVisitor extends AbstractPatternNodeVisitor {
+ boolean usesThis = false;
+
+ public Object visit(ThisOrTargetPointcut node, Object data) {
+ if (node.isThis() && node.isBinding())
+ usesThis = true;
+ return node;
+ }
+
+ public Object visit(AndPointcut node, Object data) {
+ if (!usesThis)
+ node.getLeft().accept(this, data);
+ if (!usesThis)
+ node.getRight().accept(this, data);
+ return node;
+ }
+
+ public Object visit(NotPointcut node, Object data) {
+ if (!usesThis)
+ node.getNegatedPointcut().accept(this, data);
+ return node;
+ }
+
+ public Object visit(OrPointcut node, Object data) {
+ if (!usesThis)
+ node.getLeft().accept(this, data);
+ if (!usesThis)
+ node.getRight().accept(this, data);
+ return node;
+ }
+ }
+
+ private static class UsesTargetVisitor extends AbstractPatternNodeVisitor {
+ boolean usesTarget = false;
+
+ public Object visit(ThisOrTargetPointcut node, Object data) {
+ if (!node.isThis() && node.isBinding())
+ usesTarget = true;
+ return node;
+ }
+
+ public Object visit(AndPointcut node, Object data) {
+ if (!usesTarget)
+ node.getLeft().accept(this, data);
+ if (!usesTarget)
+ node.getRight().accept(this, data);
+ return node;
+ }
+
+ public Object visit(NotPointcut node, Object data) {
+ if (!usesTarget)
+ node.getNegatedPointcut().accept(this, data);
+ return node;
+ }
+
+ public Object visit(OrPointcut node, Object data) {
+ if (!usesTarget)
+ node.getLeft().accept(this, data);
+ if (!usesTarget)
+ node.getRight().accept(this, data);
+ return node;
+ }
+ }
public void weaveAroundClosure(BcelAdvice munger, boolean hasDynamicTest) {
- InstructionFactory fact = getFactory();
+ InstructionFactory fact = getFactory();
enclosingMethod.setCanInline(false);
int linenumber = getSourceLine();
- // MOVE OUT ALL THE INSTRUCTIONS IN MY SHADOW INTO ANOTHER METHOD!
- LazyMethodGen callbackMethod =
- extractMethod(
- NameMangler.aroundCallbackMethodName(
- getSignature(),
- getEnclosingClass()),
- 0,
- munger);
-
- BcelVar[] adviceVars = munger.getExposedStateAsBcelVars(true);
-
- String closureClassName =
- NameMangler.makeClosureClassName(
- getEnclosingClass().getType(),
- getEnclosingClass().getNewGeneratedNameTag());
-
- Member constructorSig = new MemberImpl(Member.CONSTRUCTOR,
- UnresolvedType.forName(closureClassName), 0, "<init>",
- "([Ljava/lang/Object;)V");
-
- BcelVar closureHolder = null;
-
- // This is not being used currently since getKind() == preinitializaiton
- // cannot happen in around advice
- if (getKind() == PreInitialization) {
- closureHolder = genTempVar(AjcMemberMaker.AROUND_CLOSURE_TYPE);
- }
-
- InstructionList closureInstantiation =
- makeClosureInstantiation(constructorSig, closureHolder);
-
- /*LazyMethodGen constructor = */
- makeClosureClassAndReturnConstructor(
- closureClassName,
- callbackMethod,
- makeProceedArgumentMap(adviceVars)
- );
-
- InstructionList returnConversionCode;
+ // MOVE OUT ALL THE INSTRUCTIONS IN MY SHADOW INTO ANOTHER METHOD!
+ LazyMethodGen callbackMethod = extractMethod(NameMangler.aroundCallbackMethodName(getSignature(), getEnclosingClass()), 0,
+ munger);
+
+ BcelVar[] adviceVars = munger.getExposedStateAsBcelVars(true);
+
+ String closureClassName = NameMangler.makeClosureClassName(getEnclosingClass().getType(), getEnclosingClass()
+ .getNewGeneratedNameTag());
+
+ Member constructorSig = new MemberImpl(Member.CONSTRUCTOR, UnresolvedType.forName(closureClassName), 0, "<init>",
+ "([Ljava/lang/Object;)V");
+
+ BcelVar closureHolder = null;
+
+ // This is not being used currently since getKind() == preinitializaiton
+ // cannot happen in around advice
+ if (getKind() == PreInitialization) {
+ closureHolder = genTempVar(AjcMemberMaker.AROUND_CLOSURE_TYPE);
+ }
+
+ InstructionList closureInstantiation = makeClosureInstantiation(constructorSig, closureHolder);
+
+ /* LazyMethodGen constructor = */
+ makeClosureClassAndReturnConstructor(closureClassName, callbackMethod, makeProceedArgumentMap(adviceVars));
+
+ InstructionList returnConversionCode;
if (getKind() == PreInitialization) {
returnConversionCode = new InstructionList();
-
+
BcelVar stateTempVar = genTempVar(UnresolvedType.OBJECTARRAY);
closureHolder.appendLoad(returnConversionCode, fact);
-
- returnConversionCode.append(
- Utility.createInvoke(
- fact,
- world,
- AjcMemberMaker.aroundClosurePreInitializationGetter()));
+
+ returnConversionCode.append(Utility.createInvoke(fact, world, AjcMemberMaker.aroundClosurePreInitializationGetter()));
stateTempVar.appendStore(returnConversionCode, fact);
-
+
Type[] stateTypes = getSuperConstructorParameterTypes();
-
+
returnConversionCode.append(InstructionConstants.ALOAD_0); // put "this" back on the stack
for (int i = 0, len = stateTypes.length; i < len; i++) {
- UnresolvedType bcelTX = BcelWorld.fromBcel(stateTypes[i]);
- ResolvedType stateRTX = world.resolve(bcelTX,true);
- if (stateRTX.isMissing()) {
- world.getLint().cantFindType.signal(
- new String[] {WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE_PREINIT,bcelTX.getClassName())},
- getSourceLocation(),
- new ISourceLocation[]{ munger.getSourceLocation()}
- );
-// IMessage msg = new Message(
-// WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE_PREINIT,bcelTX.getClassName()),
-// "",IMessage.ERROR,getSourceLocation(),null,
-// new ISourceLocation[]{ munger.getSourceLocation()});
-// world.getMessageHandler().handleMessage(msg);
- }
- stateTempVar.appendConvertableArrayLoad(
- returnConversionCode,
- fact,
- i,
- stateRTX);
+ UnresolvedType bcelTX = BcelWorld.fromBcel(stateTypes[i]);
+ ResolvedType stateRTX = world.resolve(bcelTX, true);
+ if (stateRTX.isMissing()) {
+ world.getLint().cantFindType.signal(new String[] { WeaverMessages.format(
+ WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE_PREINIT, bcelTX.getClassName()) },
+ getSourceLocation(), new ISourceLocation[] { munger.getSourceLocation() });
+ // IMessage msg = new Message(
+ // WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE_DURING_AROUND_WEAVE_PREINIT,bcelTX.getClassName()),
+ // "",IMessage.ERROR,getSourceLocation(),null,
+ // new ISourceLocation[]{ munger.getSourceLocation()});
+ // world.getMessageHandler().handleMessage(msg);
+ }
+ stateTempVar.appendConvertableArrayLoad(returnConversionCode, fact, i, stateRTX);
}
} else {
- // pr226201
+ // pr226201
Member mungerSignature = munger.getSignature();
if (munger.getSignature() instanceof ResolvedMember) {
- if (((ResolvedMember)mungerSignature).hasBackingGenericMember()) {
- mungerSignature = ((ResolvedMember)mungerSignature).getBackingGenericMember();
+ if (((ResolvedMember) mungerSignature).hasBackingGenericMember()) {
+ mungerSignature = ((ResolvedMember) mungerSignature).getBackingGenericMember();
}
}
UnresolvedType returnType = mungerSignature.getReturnType();
- returnConversionCode =
- Utility.createConversion(
- getFactory(),
- BcelWorld.makeBcelType(returnType),
- callbackMethod.getReturnType(),world.isInJava5Mode());
+ returnConversionCode = Utility.createConversion(getFactory(), BcelWorld.makeBcelType(returnType), callbackMethod
+ .getReturnType(), world.isInJava5Mode());
if (!isFallsThrough()) {
- returnConversionCode.append(
- InstructionFactory.createReturn(callbackMethod.getReturnType()));
+ returnConversionCode.append(InstructionFactory.createReturn(callbackMethod.getReturnType()));
}
}
// initialize the bit flags for this shadow
- int bitflags =0x000000;
- if (getKind().isTargetSameAsThis()) bitflags|=0x010000;
- if (hasThis()) bitflags|=0x001000;
- if (bindsThis(munger)) bitflags|=0x000100;
- if (hasTarget()) bitflags|=0x000010;
- if (bindsTarget(munger)) bitflags|=0x000001;
-
- // ATAJ for @AJ aspect we need to link the closure with the joinpoint instance
- if (munger.getConcreteAspect()!=null && munger.getConcreteAspect().isAnnotationStyleAspect()
- && munger.getDeclaringAspect()!=null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
- // stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int
- closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
- closureInstantiation.append(Utility.createInvoke(
- getFactory(),
- getWorld(),
- new MemberImpl(
- Member.METHOD,
- UnresolvedType.forName("org.aspectj.runtime.internal.AroundClosure"),
- Modifier.PUBLIC,
- "linkClosureAndJoinPoint",
- "(I)Lorg/aspectj/lang/ProceedingJoinPoint;"
- )
- ));
- }
-
- InstructionList advice = new InstructionList();
- advice.append(munger.getAdviceArgSetup(this, null, closureInstantiation));
-
- // invoke the advice
- advice.append(munger.getNonTestAdviceInstructions(this));
- advice.append(returnConversionCode);
- if (getKind()==Shadow.MethodExecution && linenumber>0) {
+ int bitflags = 0x000000;
+ if (getKind().isTargetSameAsThis())
+ bitflags |= 0x010000;
+ if (hasThis())
+ bitflags |= 0x001000;
+ if (bindsThis(munger))
+ bitflags |= 0x000100;
+ if (hasTarget())
+ bitflags |= 0x000010;
+ if (bindsTarget(munger))
+ bitflags |= 0x000001;
+
+ // ATAJ for @AJ aspect we need to link the closure with the joinpoint instance
+ if (munger.getConcreteAspect() != null && munger.getConcreteAspect().isAnnotationStyleAspect()
+ && munger.getDeclaringAspect() != null && munger.getDeclaringAspect().resolve(world).isAnnotationStyleAspect()) {
+ // stick the bitflags on the stack and call the variant of linkClosureAndJoinPoint that takes an int
+ closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
+ closureInstantiation.append(Utility.createInvoke(getFactory(), getWorld(), new MemberImpl(Member.METHOD, UnresolvedType
+ .forName("org.aspectj.runtime.internal.AroundClosure"), Modifier.PUBLIC, "linkClosureAndJoinPoint",
+ "(I)Lorg/aspectj/lang/ProceedingJoinPoint;")));
+ }
+
+ InstructionList advice = new InstructionList();
+ advice.append(munger.getAdviceArgSetup(this, null, closureInstantiation));
+
+ // invoke the advice
+ advice.append(munger.getNonTestAdviceInstructions(this));
+ advice.append(returnConversionCode);
+ if (getKind() == Shadow.MethodExecution && linenumber > 0) {
advice.getStart().addTargeter(new LineNumberTag(linenumber));
}
-
+
if (!hasDynamicTest) {
range.append(advice);
} else {
InstructionList callback = makeCallToCallback(callbackMethod);
InstructionList postCallback = new InstructionList();
if (terminatesWithReturn()) {
- callback.append(
- InstructionFactory.createReturn(callbackMethod.getReturnType()));
+ callback.append(InstructionFactory.createReturn(callbackMethod.getReturnType()));
} else {
- advice.append(
- InstructionFactory.createBranchInstruction(
- Constants.GOTO,
- postCallback.append(InstructionConstants.NOP)));
+ advice.append(InstructionFactory.createBranchInstruction(Constants.GOTO, postCallback
+ .append(InstructionConstants.NOP)));
}
- range.append(
- munger.getTestInstructions(
- this,
- advice.getStart(),
- callback.getStart(),
- advice.getStart()));
+ range.append(munger.getTestInstructions(this, advice.getStart(), callback.getStart(), advice.getStart()));
range.append(advice);
range.append(callback);
range.append(postCallback);
}
- }
-
- // exposed for testing
- InstructionList makeCallToCallback(LazyMethodGen callbackMethod) {
- InstructionFactory fact = getFactory();
- InstructionList callback = new InstructionList();
- if (thisVar != null) {
- callback.append(InstructionConstants.ALOAD_0);
- }
- if (targetVar != null && targetVar != thisVar) {
- callback.append(BcelRenderer.renderExpr(fact, world, targetVar));
- }
- callback.append(BcelRenderer.renderExprs(fact, world, argVars));
- // remember to render tjps
- if (thisJoinPointVar != null) {
- callback.append(BcelRenderer.renderExpr(fact, world, thisJoinPointVar));
- }
- callback.append(Utility.createInvoke(fact, callbackMethod));
- return callback;
- }
+ }
+
+ // exposed for testing
+ InstructionList makeCallToCallback(LazyMethodGen callbackMethod) {
+ InstructionFactory fact = getFactory();
+ InstructionList callback = new InstructionList();
+ if (thisVar != null) {
+ callback.append(InstructionConstants.ALOAD_0);
+ }
+ if (targetVar != null && targetVar != thisVar) {
+ callback.append(BcelRenderer.renderExpr(fact, world, targetVar));
+ }
+ callback.append(BcelRenderer.renderExprs(fact, world, argVars));
+ // remember to render tjps
+ if (thisJoinPointVar != null) {
+ callback.append(BcelRenderer.renderExpr(fact, world, thisJoinPointVar));
+ }
+ callback.append(Utility.createInvoke(fact, callbackMethod));
+ return callback;
+ }
/** side-effect-free */
- private InstructionList makeClosureInstantiation(Member constructor, BcelVar holder) {
-
-// LazyMethodGen constructor) {
- InstructionFactory fact = getFactory();
- BcelVar arrayVar = genTempVar(UnresolvedType.OBJECTARRAY);
- //final Type objectArrayType = new ArrayType(Type.OBJECT, 1);
- final InstructionList il = new InstructionList();
- int alen = getArgCount() + (thisVar == null ? 0 : 1) +
- ((targetVar != null && targetVar != thisVar) ? 1 : 0) +
- (thisJoinPointVar == null ? 0 : 1);
- il.append(Utility.createConstant(fact, alen));
- il.append(fact.createNewArray(Type.OBJECT, (short)1));
- arrayVar.appendStore(il, fact);
-
- int stateIndex = 0;
- if (thisVar != null) {
- arrayVar.appendConvertableArrayStore(il, fact, stateIndex, thisVar);
+ private InstructionList makeClosureInstantiation(Member constructor, BcelVar holder) {
+
+ // LazyMethodGen constructor) {
+ InstructionFactory fact = getFactory();
+ BcelVar arrayVar = genTempVar(UnresolvedType.OBJECTARRAY);
+ // final Type objectArrayType = new ArrayType(Type.OBJECT, 1);
+ final InstructionList il = new InstructionList();
+ int alen = getArgCount() + (thisVar == null ? 0 : 1) + ((targetVar != null && targetVar != thisVar) ? 1 : 0)
+ + (thisJoinPointVar == null ? 0 : 1);
+ il.append(Utility.createConstant(fact, alen));
+ il.append(fact.createNewArray(Type.OBJECT, (short) 1));
+ arrayVar.appendStore(il, fact);
+
+ int stateIndex = 0;
+ if (thisVar != null) {
+ arrayVar.appendConvertableArrayStore(il, fact, stateIndex, thisVar);
thisVar.setPositionInAroundState(stateIndex);
- stateIndex++;
- }
- if (targetVar != null && targetVar != thisVar) {
- arrayVar.appendConvertableArrayStore(il, fact, stateIndex, targetVar);
+ stateIndex++;
+ }
+ if (targetVar != null && targetVar != thisVar) {
+ arrayVar.appendConvertableArrayStore(il, fact, stateIndex, targetVar);
targetVar.setPositionInAroundState(stateIndex);
- stateIndex++;
- }
- for (int i = 0, len = getArgCount(); i<len; i++) {
- arrayVar.appendConvertableArrayStore(il, fact, stateIndex, argVars[i]);
- argVars[i].setPositionInAroundState(stateIndex);
- stateIndex++;
- }
- if (thisJoinPointVar != null) {
- arrayVar.appendConvertableArrayStore(il, fact, stateIndex, thisJoinPointVar);
- thisJoinPointVar.setPositionInAroundState(stateIndex);
- stateIndex++;
- }
- il.append(fact.createNew(new ObjectType(constructor.getDeclaringType().getName())));
- il.append(InstructionConstants.DUP);
- arrayVar.appendLoad(il, fact);
- il.append(Utility.createInvoke(fact, world, constructor));
- if (getKind() == PreInitialization) {
+ stateIndex++;
+ }
+ for (int i = 0, len = getArgCount(); i < len; i++) {
+ arrayVar.appendConvertableArrayStore(il, fact, stateIndex, argVars[i]);
+ argVars[i].setPositionInAroundState(stateIndex);
+ stateIndex++;
+ }
+ if (thisJoinPointVar != null) {
+ arrayVar.appendConvertableArrayStore(il, fact, stateIndex, thisJoinPointVar);
+ thisJoinPointVar.setPositionInAroundState(stateIndex);
+ stateIndex++;
+ }
+ il.append(fact.createNew(new ObjectType(constructor.getDeclaringType().getName())));
+ il.append(InstructionConstants.DUP);
+ arrayVar.appendLoad(il, fact);
+ il.append(Utility.createInvoke(fact, world, constructor));
+ if (getKind() == PreInitialization) {
il.append(InstructionConstants.DUP);
holder.appendStore(il, fact);
- }
- return il;
- }
-
-
- private IntMap makeProceedArgumentMap(BcelVar[] adviceArgs) {
- //System.err.println("coming in with " + Arrays.asList(adviceArgs));
-
- IntMap ret = new IntMap();
- for(int i = 0, len = adviceArgs.length; i < len; i++) {
- BcelVar v = adviceArgs[i];
- if (v == null) continue; // XXX we don't know why this is required
- int pos = v.getPositionInAroundState();
- if (pos >= 0) { // need this test to avoid args bound via cflow
- ret.put(pos, i);
- }
- }
- //System.err.println("returning " + ret);
-
- return ret;
- }
+ }
+ return il;
+ }
+
+ private IntMap makeProceedArgumentMap(BcelVar[] adviceArgs) {
+ // System.err.println("coming in with " + Arrays.asList(adviceArgs));
+
+ IntMap ret = new IntMap();
+ for (int i = 0, len = adviceArgs.length; i < len; i++) {
+ BcelVar v = adviceArgs[i];
+ if (v == null)
+ continue; // XXX we don't know why this is required
+ int pos = v.getPositionInAroundState();
+ if (pos >= 0) { // need this test to avoid args bound via cflow
+ ret.put(pos, i);
+ }
+ }
+ // System.err.println("returning " + ret);
+
+ return ret;
+ }
/**
*
*
* @param callbackMethod the method we will call back to when our run method gets called.
*
- * @param proceedMap A map from state position to proceed argument position. May be
- * non covering on state position.
+ * @param proceedMap A map from state position to proceed argument position. May be non covering on state position.
*/
- private LazyMethodGen makeClosureClassAndReturnConstructor(
- String closureClassName,
- LazyMethodGen callbackMethod,
- IntMap proceedMap)
- {
+ private LazyMethodGen makeClosureClassAndReturnConstructor(String closureClassName, LazyMethodGen callbackMethod,
+ IntMap proceedMap) {
String superClassName = "org.aspectj.runtime.internal.AroundClosure";
- Type objectArrayType = new ArrayType(Type.OBJECT, 1);
-
- LazyClassGen closureClass = new LazyClassGen(closureClassName,
- superClassName,
- getEnclosingClass().getFileName(),
- Modifier.PUBLIC,
- new String[] {},
- getWorld());
- InstructionFactory fact = new InstructionFactory(closureClass.getConstantPool());
-
- // constructor
- LazyMethodGen constructor = new LazyMethodGen(Modifier.PUBLIC,
- Type.VOID,
- "<init>",
- new Type[] {objectArrayType},
- new String[] {},
- closureClass);
- InstructionList cbody = constructor.getBody();
+ Type objectArrayType = new ArrayType(Type.OBJECT, 1);
+
+ LazyClassGen closureClass = new LazyClassGen(closureClassName, superClassName, getEnclosingClass().getFileName(),
+ Modifier.PUBLIC, new String[] {}, getWorld());
+ InstructionFactory fact = new InstructionFactory(closureClass.getConstantPool());
+
+ // constructor
+ LazyMethodGen constructor = new LazyMethodGen(Modifier.PUBLIC, Type.VOID, "<init>", new Type[] { objectArrayType },
+ new String[] {}, closureClass);
+ InstructionList cbody = constructor.getBody();
cbody.append(InstructionFactory.createLoad(Type.OBJECT, 0));
cbody.append(InstructionFactory.createLoad(objectArrayType, 1));
- cbody.append(fact.createInvoke(superClassName, "<init>", Type.VOID,
- new Type[] {objectArrayType}, Constants.INVOKESPECIAL));
+ cbody.append(fact
+ .createInvoke(superClassName, "<init>", Type.VOID, new Type[] { objectArrayType }, Constants.INVOKESPECIAL));
cbody.append(InstructionFactory.createReturn(Type.VOID));
- closureClass.addMethodGen(constructor);
-
- // method
- LazyMethodGen runMethod = new LazyMethodGen(Modifier.PUBLIC,
- Type.OBJECT,
- "run",
- new Type[] {objectArrayType},
- new String[] {},
- closureClass);
- InstructionList mbody = runMethod.getBody();
- BcelVar proceedVar = new BcelVar(UnresolvedType.OBJECTARRAY.resolve(world), 1);
- // int proceedVarIndex = 1;
- BcelVar stateVar =
- new BcelVar(UnresolvedType.OBJECTARRAY.resolve(world), runMethod.allocateLocal(1));
- // int stateVarIndex = runMethod.allocateLocal(1);
+ closureClass.addMethodGen(constructor);
+
+ // method
+ LazyMethodGen runMethod = new LazyMethodGen(Modifier.PUBLIC, Type.OBJECT, "run", new Type[] { objectArrayType },
+ new String[] {}, closureClass);
+ InstructionList mbody = runMethod.getBody();
+ BcelVar proceedVar = new BcelVar(UnresolvedType.OBJECTARRAY.resolve(world), 1);
+ // int proceedVarIndex = 1;
+ BcelVar stateVar = new BcelVar(UnresolvedType.OBJECTARRAY.resolve(world), runMethod.allocateLocal(1));
+ // int stateVarIndex = runMethod.allocateLocal(1);
mbody.append(InstructionFactory.createThis());
mbody.append(fact.createGetField(superClassName, "state", objectArrayType));
- mbody.append(stateVar.createStore(fact));
- // mbody.append(fact.createStore(objectArrayType, stateVarIndex));
-
- Type[] stateTypes = callbackMethod.getArgumentTypes();
-
- for (int i=0, len=stateTypes.length; i < len; i++) {
- Type stateType = stateTypes[i];
- ResolvedType stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
- if (proceedMap.hasKey(i)) {
- mbody.append(
- proceedVar.createConvertableArrayLoad(fact, proceedMap.get(i),
- stateTypeX));
- } else {
- mbody.append(
- stateVar.createConvertableArrayLoad(fact, i,
- stateTypeX));
- }
- }
-
-
+ mbody.append(stateVar.createStore(fact));
+ // mbody.append(fact.createStore(objectArrayType, stateVarIndex));
+
+ Type[] stateTypes = callbackMethod.getArgumentTypes();
+
+ for (int i = 0, len = stateTypes.length; i < len; i++) {
+ Type stateType = stateTypes[i];
+ ResolvedType stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
+ if (proceedMap.hasKey(i)) {
+ mbody.append(proceedVar.createConvertableArrayLoad(fact, proceedMap.get(i), stateTypeX));
+ } else {
+ mbody.append(stateVar.createConvertableArrayLoad(fact, i, stateTypeX));
+ }
+ }
+
mbody.append(Utility.createInvoke(fact, callbackMethod));
-
+
if (getKind() == PreInitialization) {
- mbody.append(Utility.createSet(
- fact,
- AjcMemberMaker.aroundClosurePreInitializationField()));
+ mbody.append(Utility.createSet(fact, AjcMemberMaker.aroundClosurePreInitializationField()));
mbody.append(InstructionConstants.ACONST_NULL);
} else {
- mbody.append(
- Utility.createConversion(
- fact,
- callbackMethod.getReturnType(),
- Type.OBJECT));
+ mbody.append(Utility.createConversion(fact, callbackMethod.getReturnType(), Type.OBJECT));
}
mbody.append(InstructionFactory.createReturn(Type.OBJECT));
closureClass.addMethodGen(runMethod);
-
+
// class
getEnclosingClass().addGeneratedInner(closureClass);
-
+
return constructor;
}
-
- // ---- extraction methods
-
- public LazyMethodGen extractMethod(String newMethodName, int visibilityModifier, ShadowMunger munger) {
+ // ---- extraction methods
+
+ public LazyMethodGen extractMethod(String newMethodName, int visibilityModifier, ShadowMunger munger) {
LazyMethodGen.assertGoodBody(range.getBody(), newMethodName);
- if (!getKind().allowsExtraction()) throw new BCException("Attempt to extract method from a shadow kind that does not support this operation (" + getKind() + ")");
- LazyMethodGen freshMethod = createMethodGen(newMethodName,visibilityModifier);
-
-// System.err.println("******");
-// System.err.println("ABOUT TO EXTRACT METHOD for" + this);
-// enclosingMethod.print(System.err);
-// System.err.println("INTO");
-// freshMethod.print(System.err);
-// System.err.println("WITH REMAP");
-// System.err.println(makeRemap());
-
- range.extractInstructionsInto(freshMethod, makeRemap(),
- (getKind() != PreInitialization) &&
- isFallsThrough());
- if (getKind() == PreInitialization) {
- addPreInitializationReturnCode(
- freshMethod,
- getSuperConstructorParameterTypes());
- }
- getEnclosingClass().addMethodGen(freshMethod,munger.getSourceLocation());
-
- return freshMethod;
- }
-
- private void addPreInitializationReturnCode(
- LazyMethodGen extractedMethod,
- Type[] superConstructorTypes)
- {
+ if (!getKind().allowsExtraction())
+ throw new BCException("Attempt to extract method from a shadow kind that does not support this operation (" + getKind()
+ + ")");
+ LazyMethodGen freshMethod = createMethodGen(newMethodName, visibilityModifier);
+
+ // System.err.println("******");
+ // System.err.println("ABOUT TO EXTRACT METHOD for" + this);
+ // enclosingMethod.print(System.err);
+ // System.err.println("INTO");
+ // freshMethod.print(System.err);
+ // System.err.println("WITH REMAP");
+ // System.err.println(makeRemap());
+
+ range.extractInstructionsInto(freshMethod, makeRemap(), (getKind() != PreInitialization) && isFallsThrough());
+ if (getKind() == PreInitialization) {
+ addPreInitializationReturnCode(freshMethod, getSuperConstructorParameterTypes());
+ }
+ getEnclosingClass().addMethodGen(freshMethod, munger.getSourceLocation());
+
+ return freshMethod;
+ }
+
+ private void addPreInitializationReturnCode(LazyMethodGen extractedMethod, Type[] superConstructorTypes) {
InstructionList body = extractedMethod.getBody();
- final InstructionFactory fact = getFactory();
-
- BcelVar arrayVar = new BcelVar(
- world.getCoreType(UnresolvedType.OBJECTARRAY),
- extractedMethod.allocateLocal(1));
-
+ final InstructionFactory fact = getFactory();
+
+ BcelVar arrayVar = new BcelVar(world.getCoreType(UnresolvedType.OBJECTARRAY), extractedMethod.allocateLocal(1));
+
int len = superConstructorTypes.length;
-
- body.append(Utility.createConstant(fact, len));
- body.append(fact.createNewArray(Type.OBJECT, (short)1));
- arrayVar.appendStore(body, fact);
+ body.append(Utility.createConstant(fact, len));
+
+ body.append(fact.createNewArray(Type.OBJECT, (short) 1));
+ arrayVar.appendStore(body, fact);
- for (int i = len - 1; i >= 0; i++) {
- // convert thing on top of stack to object
- body.append(
- Utility.createConversion(fact, superConstructorTypes[i], Type.OBJECT));
+ for (int i = len - 1; i >= 0; i++) {
+ // convert thing on top of stack to object
+ body.append(Utility.createConversion(fact, superConstructorTypes[i], Type.OBJECT));
// push object array
arrayVar.appendLoad(body, fact);
// swap
body.append(InstructionConstants.SWAP);
- // do object array store.
+ // do object array store.
body.append(Utility.createConstant(fact, i));
body.append(InstructionConstants.SWAP);
body.append(InstructionFactory.createArrayStore(Type.OBJECT));
- }
- arrayVar.appendLoad(body, fact);
- body.append(InstructionConstants.ARETURN);
+ }
+ arrayVar.appendLoad(body, fact);
+ body.append(InstructionConstants.ARETURN);
}
private Type[] getSuperConstructorParameterTypes() {
- // assert getKind() == PreInitialization
+ // assert getKind() == PreInitialization
InstructionHandle superCallHandle = getRange().getEnd().getNext();
- InvokeInstruction superCallInstruction =
- (InvokeInstruction) superCallHandle.getInstruction();
- return superCallInstruction.getArgumentTypes(
- getEnclosingClass().getConstantPool());
+ InvokeInstruction superCallInstruction = (InvokeInstruction) superCallHandle.getInstruction();
+ return superCallInstruction.getArgumentTypes(getEnclosingClass().getConstantPool());
}
-
- /** make a map from old frame location to new frame location. Any unkeyed frame
- * location picks out a copied local */
- private IntMap makeRemap() {
- IntMap ret = new IntMap(5);
- int reti = 0;
+ /**
+ * make a map from old frame location to new frame location. Any unkeyed frame location picks out a copied local
+ */
+ private IntMap makeRemap() {
+ IntMap ret = new IntMap(5);
+ int reti = 0;
if (thisVar != null) {
- ret.put(0, reti++); // thisVar guaranteed to be 0
- }
- if (targetVar != null && targetVar != thisVar) {
- ret.put(targetVar.getSlot(), reti++);
- }
- for (int i = 0, len = argVars.length; i < len; i++) {
- ret.put(argVars[i].getSlot(), reti);
- reti += argVars[i].getType().getSize();
- }
- if (thisJoinPointVar != null) {
- ret.put(thisJoinPointVar.getSlot(), reti++);
- }
- // we not only need to put the arguments, we also need to remap their
- // aliases, which we so helpfully put into temps at the beginning of this join
- // point.
- if (! getKind().argsOnStack()) {
- int oldi = 0;
- int newi = 0;
- // if we're passing in a this and we're not argsOnStack we're always
- // passing in a target too
- if (arg0HoldsThis()) { ret.put(0, 0); oldi++; newi+=1; }
- //assert targetVar == thisVar
- for (int i = 0; i < getArgCount(); i++) {
- UnresolvedType type = getArgType(i);
+ ret.put(0, reti++); // thisVar guaranteed to be 0
+ }
+ if (targetVar != null && targetVar != thisVar) {
+ ret.put(targetVar.getSlot(), reti++);
+ }
+ for (int i = 0, len = argVars.length; i < len; i++) {
+ ret.put(argVars[i].getSlot(), reti);
+ reti += argVars[i].getType().getSize();
+ }
+ if (thisJoinPointVar != null) {
+ ret.put(thisJoinPointVar.getSlot(), reti++);
+ }
+ // we not only need to put the arguments, we also need to remap their
+ // aliases, which we so helpfully put into temps at the beginning of this join
+ // point.
+ if (!getKind().argsOnStack()) {
+ int oldi = 0;
+ int newi = 0;
+ // if we're passing in a this and we're not argsOnStack we're always
+ // passing in a target too
+ if (arg0HoldsThis()) {
+ ret.put(0, 0);
+ oldi++;
+ newi += 1;
+ }
+ // assert targetVar == thisVar
+ for (int i = 0; i < getArgCount(); i++) {
+ UnresolvedType type = getArgType(i);
ret.put(oldi, newi);
- oldi += type.getSize();
- newi += type.getSize();
- }
- }
-
-// System.err.println("making remap for : " + this);
-// if (targetVar != null) System.err.println("target slot : " + targetVar.getSlot());
-// if (thisVar != null) System.err.println(" this slot : " + thisVar.getSlot());
-// System.err.println(ret);
-
- return ret;
- }
-
- /**
- * The new method always static.
- * It may take some extra arguments: this, target.
- * If it's argsOnStack, then it must take both this/target
- * If it's argsOnFrame, it shares this and target.
- * ??? rewrite this to do less array munging, please
- */
- private LazyMethodGen createMethodGen(String newMethodName, int visibilityModifier) {
- Type[] parameterTypes = BcelWorld.makeBcelTypes(getArgTypes());
- int modifiers = Modifier.FINAL | visibilityModifier;
-
- // XXX some bug
-// if (! isExpressionKind() && getSignature().isStrict(world)) {
-// modifiers |= Modifier.STRICT;
-// }
- modifiers |= Modifier.STATIC;
- if (targetVar != null && targetVar != thisVar) {
- UnresolvedType targetType = getTargetType();
- targetType = ensureTargetTypeIsCorrect(targetType);
- // see pr109728,pr229910 - this fixes the case when the declaring class is sometype 'X' but the (gs)etfield
- // in the bytecode refers to a subtype of 'X'. This makes sure we use the type originally
- // mentioned in the fieldget instruction as the method parameter and *not* the type upon which the
- // field is declared because when the instructions are extracted into the new around body,
- // they will still refer to the subtype.
- if ((getKind()==FieldGet || getKind()==FieldSet) && getActualTargetType()!=null &&
- !getActualTargetType().equals(targetType.getName())) {
- targetType = UnresolvedType.forName(getActualTargetType()).resolve(world);
- }
- ResolvedMember resolvedMember = getSignature().resolve(world);
-
- // pr230075, pr197719
- if (resolvedMember != null && Modifier.isProtected(resolvedMember.getModifiers()) &&
- !samePackage(resolvedMember.getDeclaringType().getPackageName(), getEnclosingType().getPackageName()) &&
- !resolvedMember.getName().equals("clone"))
- {
- if (!hasThis()) { // pr197719 - static accessor has been created to handle the call
- if (Modifier.isStatic(enclosingMethod.getAccessFlags()) && enclosingMethod.getName().startsWith("access$")) {
- targetType = BcelWorld.fromBcel(enclosingMethod.getArgumentTypes()[0]);
- }
- } else {
- if (!targetType.resolve(world).isAssignableFrom(getThisType().resolve(world))) {
- throw new BCException("bad bytecode");
- }
- targetType = getThisType();
- }
- }
- parameterTypes = addType(BcelWorld.makeBcelType(targetType), parameterTypes);
- }
- if (thisVar != null) {
- UnresolvedType thisType = getThisType();
- parameterTypes = addType(BcelWorld.makeBcelType(thisType), parameterTypes);
- }
-
- // We always want to pass down thisJoinPoint in case we have already woven
- // some advice in here. If we only have a single piece of around advice on a
- // join point, it is unnecessary to accept (and pass) tjp.
- if (thisJoinPointVar != null) {
- parameterTypes = addTypeToEnd(LazyClassGen.tjpType, parameterTypes);
- //FIXME ALEX? which one
- //parameterTypes = addTypeToEnd(LazyClassGen.proceedingTjpType, parameterTypes);
- }
-
- UnresolvedType returnType;
- if (getKind() == PreInitialization) {
- returnType = UnresolvedType.OBJECTARRAY;
- } else {
-
- if (getKind() == ConstructorCall) returnType = getSignature().getDeclaringType();
- else if (getKind() == FieldSet) returnType = ResolvedType.VOID;
- else returnType = getSignature().getReturnType().resolve(world);
-// returnType = getReturnType(); // for this and above lines, see pr137496
- }
- return
- new LazyMethodGen(
- modifiers,
- BcelWorld.makeBcelType(returnType),
- newMethodName,
- parameterTypes,
- new String[0],
- // XXX again, we need to look up methods!
-// UnresolvedType.getNames(getSignature().getExceptions(world)),
- getEnclosingClass());
- }
+ oldi += type.getSize();
+ newi += type.getSize();
+ }
+ }
+
+ // System.err.println("making remap for : " + this);
+ // if (targetVar != null) System.err.println("target slot : " + targetVar.getSlot());
+ // if (thisVar != null) System.err.println(" this slot : " + thisVar.getSlot());
+ // System.err.println(ret);
+
+ return ret;
+ }
+
+ /**
+ * The new method always static. It may take some extra arguments: this, target. If it's argsOnStack, then it must take both
+ * this/target If it's argsOnFrame, it shares this and target. ??? rewrite this to do less array munging, please
+ */
+ private LazyMethodGen createMethodGen(String newMethodName, int visibilityModifier) {
+ Type[] parameterTypes = BcelWorld.makeBcelTypes(getArgTypes());
+ int modifiers = Modifier.FINAL | visibilityModifier;
+
+ // XXX some bug
+ // if (! isExpressionKind() && getSignature().isStrict(world)) {
+ // modifiers |= Modifier.STRICT;
+ // }
+ modifiers |= Modifier.STATIC;
+ if (targetVar != null && targetVar != thisVar) {
+ UnresolvedType targetType = getTargetType();
+ targetType = ensureTargetTypeIsCorrect(targetType);
+ // see pr109728,pr229910 - this fixes the case when the declaring class is sometype 'X' but the (gs)etfield
+ // in the bytecode refers to a subtype of 'X'. This makes sure we use the type originally
+ // mentioned in the fieldget instruction as the method parameter and *not* the type upon which the
+ // field is declared because when the instructions are extracted into the new around body,
+ // they will still refer to the subtype.
+ if ((getKind() == FieldGet || getKind() == FieldSet) && getActualTargetType() != null
+ && !getActualTargetType().equals(targetType.getName())) {
+ targetType = UnresolvedType.forName(getActualTargetType()).resolve(world);
+ }
+ ResolvedMember resolvedMember = getSignature().resolve(world);
+
+ // pr230075, pr197719
+ if (resolvedMember != null && Modifier.isProtected(resolvedMember.getModifiers())
+ && !samePackage(resolvedMember.getDeclaringType().getPackageName(), getEnclosingType().getPackageName())
+ && !resolvedMember.getName().equals("clone")) {
+ if (!hasThis()) { // pr197719 - static accessor has been created to handle the call
+ if (Modifier.isStatic(enclosingMethod.getAccessFlags()) && enclosingMethod.getName().startsWith("access$")) {
+ targetType = BcelWorld.fromBcel(enclosingMethod.getArgumentTypes()[0]);
+ }
+ } else {
+ if (!targetType.resolve(world).isAssignableFrom(getThisType().resolve(world))) {
+ throw new BCException("bad bytecode");
+ }
+ targetType = getThisType();
+ }
+ }
+ parameterTypes = addType(BcelWorld.makeBcelType(targetType), parameterTypes);
+ }
+ if (thisVar != null) {
+ UnresolvedType thisType = getThisType();
+ parameterTypes = addType(BcelWorld.makeBcelType(thisType), parameterTypes);
+ }
+
+ // We always want to pass down thisJoinPoint in case we have already woven
+ // some advice in here. If we only have a single piece of around advice on a
+ // join point, it is unnecessary to accept (and pass) tjp.
+ if (thisJoinPointVar != null) {
+ parameterTypes = addTypeToEnd(LazyClassGen.tjpType, parameterTypes);
+ // FIXME ALEX? which one
+ // parameterTypes = addTypeToEnd(LazyClassGen.proceedingTjpType, parameterTypes);
+ }
+
+ UnresolvedType returnType;
+ if (getKind() == PreInitialization) {
+ returnType = UnresolvedType.OBJECTARRAY;
+ } else {
+
+ if (getKind() == ConstructorCall)
+ returnType = getSignature().getDeclaringType();
+ else if (getKind() == FieldSet)
+ returnType = ResolvedType.VOID;
+ else
+ returnType = getSignature().getReturnType().resolve(world);
+ // returnType = getReturnType(); // for this and above lines, see pr137496
+ }
+ return new LazyMethodGen(modifiers, BcelWorld.makeBcelType(returnType), newMethodName, parameterTypes, new String[0],
+ // XXX again, we need to look up methods!
+ // UnresolvedType.getNames(getSignature().getExceptions(world)),
+ getEnclosingClass());
+ }
private boolean samePackage(String p1, String p2) {
- if (p1 == null) return p2 == null;
- if (p2 == null) return false;
+ if (p1 == null)
+ return p2 == null;
+ if (p2 == null)
+ return false;
return p1.equals(p2);
}
-
- private Type[] addType(Type type, Type[] types) {
- int len = types.length;
- Type[] ret = new Type[len+1];
- ret[0] = type;
- System.arraycopy(types, 0, ret, 1, len);
- return ret;
- }
-
- private Type[] addTypeToEnd(Type type, Type[] types) {
- int len = types.length;
- Type[] ret = new Type[len+1];
- ret[len] = type;
- System.arraycopy(types, 0, ret, 0, len);
- return ret;
- }
-
- public BcelVar genTempVar(UnresolvedType typeX) {
- return new BcelVar(typeX.resolve(world), genTempVarIndex(typeX.getSize()));
- }
-
-// public static final boolean CREATE_TEMP_NAMES = true;
-
- public BcelVar genTempVar(UnresolvedType typeX, String localName) {
+ private Type[] addType(Type type, Type[] types) {
+ int len = types.length;
+ Type[] ret = new Type[len + 1];
+ ret[0] = type;
+ System.arraycopy(types, 0, ret, 1, len);
+ return ret;
+ }
+
+ private Type[] addTypeToEnd(Type type, Type[] types) {
+ int len = types.length;
+ Type[] ret = new Type[len + 1];
+ ret[len] = type;
+ System.arraycopy(types, 0, ret, 0, len);
+ return ret;
+ }
+
+ public BcelVar genTempVar(UnresolvedType typeX) {
+ return new BcelVar(typeX.resolve(world), genTempVarIndex(typeX.getSize()));
+ }
+
+ // public static final boolean CREATE_TEMP_NAMES = true;
+
+ public BcelVar genTempVar(UnresolvedType typeX, String localName) {
BcelVar tv = genTempVar(typeX);
-// if (CREATE_TEMP_NAMES) {
-// for (InstructionHandle ih = range.getStart(); ih != range.getEnd(); ih = ih.getNext()) {
-// if (Range.isRangeHandle(ih)) continue;
-// ih.addTargeter(new LocalVariableTag(typeX, localName, tv.getSlot()));
-// }
-// }
+ // if (CREATE_TEMP_NAMES) {
+ // for (InstructionHandle ih = range.getStart(); ih != range.getEnd(); ih = ih.getNext()) {
+ // if (Range.isRangeHandle(ih)) continue;
+ // ih.addTargeter(new LocalVariableTag(typeX, localName, tv.getSlot()));
+ // }
+ // }
return tv;
- }
-
- // eh doesn't think we need to garbage collect these (64K is a big number...)
- private int genTempVarIndex(int size) {
- return enclosingMethod.allocateLocal(size);
- }
-
- public InstructionFactory getFactory() {
- return getEnclosingClass().getFactory();
- }
-
+ }
+
+ // eh doesn't think we need to garbage collect these (64K is a big number...)
+ private int genTempVarIndex(int size) {
+ return enclosingMethod.allocateLocal(size);
+ }
+
+ public InstructionFactory getFactory() {
+ return getEnclosingClass().getFactory();
+ }
+
public ISourceLocation getSourceLocation() {
int sourceLine = getSourceLine();
if (sourceLine == 0 || sourceLine == -1) {
-// Thread.currentThread().dumpStack();
-// System.err.println(this + ": " + range);
+ // Thread.currentThread().dumpStack();
+ // System.err.println(this + ": " + range);
return getEnclosingClass().getType().getSourceLocation();
} else {
- // For staticinitialization, if we have a nice offset, don't build a new source loc
- if (getKind()==Shadow.StaticInitialization && getEnclosingClass().getType().getSourceLocation().getOffset()!=0) {
+ // For staticinitialization, if we have a nice offset, don't build a new source loc
+ if (getKind() == Shadow.StaticInitialization && getEnclosingClass().getType().getSourceLocation().getOffset() != 0) {
return getEnclosingClass().getType().getSourceLocation();
} else {
int offset = 0;
Kind kind = getKind();
- if ( (kind == MethodExecution) ||
- (kind == ConstructorExecution) ||
- (kind == AdviceExecution) ||
- (kind == StaticInitialization) ||
- (kind == PreInitialization) ||
- (kind == Initialization)) {
- if (getEnclosingMethod().hasDeclaredLineNumberInfo()) {
- offset = getEnclosingMethod().getDeclarationOffset();
- }
- }
- return getEnclosingClass().getType().getSourceContext().makeSourceLocation(sourceLine, offset);
+ if ((kind == MethodExecution) || (kind == ConstructorExecution) || (kind == AdviceExecution)
+ || (kind == StaticInitialization) || (kind == PreInitialization) || (kind == Initialization)) {
+ if (getEnclosingMethod().hasDeclaredLineNumberInfo()) {
+ offset = getEnclosingMethod().getDeclarationOffset();
+ }
+ }
+ return getEnclosingClass().getType().getSourceContext().makeSourceLocation(sourceLine, offset);
}
}
}
@@ -3570,7 +3160,7 @@ public class BcelShadow extends Shadow {
public void setActualTargetType(String className) {
this.actualInstructionTargetType = className;
}
-
+
public String getActualTargetType() {
return actualInstructionTargetType;
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/IfFinder.java b/weaver/src/org/aspectj/weaver/bcel/IfFinder.java
index e1125edc7..c66aa8939 100644
--- a/weaver/src/org/aspectj/weaver/bcel/IfFinder.java
+++ b/weaver/src/org/aspectj/weaver/bcel/IfFinder.java
@@ -11,8 +11,8 @@
* ******************************************************************/
package org.aspectj.weaver.bcel;
+import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
import org.aspectj.weaver.patterns.AndPointcut;
-import org.aspectj.weaver.patterns.IdentityPointcutVisitor;
import org.aspectj.weaver.patterns.IfPointcut;
import org.aspectj.weaver.patterns.NotPointcut;
import org.aspectj.weaver.patterns.OrPointcut;
@@ -20,31 +20,37 @@ import org.aspectj.weaver.patterns.OrPointcut;
/**
* Look for an if() pointcut
*/
-class IfFinder extends IdentityPointcutVisitor {
- boolean hasIf = false;
- public Object visit(IfPointcut node, Object data) {
- if (node.alwaysFalse() || node.alwaysTrue()) {
- //IfFalse / IfTrue
- } else {
- hasIf = true;
- }
- return node;
- }
+class IfFinder extends AbstractPatternNodeVisitor {
+ boolean hasIf = false;
- public Object visit(AndPointcut node, Object data) {
- if (!hasIf) node.getLeft().accept(this, data);
- if (!hasIf) node.getRight().accept(this, data);
- return node;
- }
+ public Object visit(IfPointcut node, Object data) {
+ if (node.alwaysFalse() || node.alwaysTrue()) {
+ // IfFalse / IfTrue
+ } else {
+ hasIf = true;
+ }
+ return node;
+ }
- public Object visit(NotPointcut node, Object data) {
- if (!hasIf) node.getNegatedPointcut().accept(this, data);
- return node;
- }
+ public Object visit(AndPointcut node, Object data) {
+ if (!hasIf)
+ node.getLeft().accept(this, data);
+ if (!hasIf)
+ node.getRight().accept(this, data);
+ return node;
+ }
- public Object visit(OrPointcut node, Object data) {
- if (!hasIf) node.getLeft().accept(this, data);
- if (!hasIf) node.getRight().accept(this, data);
- return node;
- }
+ public Object visit(NotPointcut node, Object data) {
+ if (!hasIf)
+ node.getNegatedPointcut().accept(this, data);
+ return node;
+ }
+
+ public Object visit(OrPointcut node, Object data) {
+ if (!hasIf)
+ node.getLeft().accept(this, data);
+ if (!hasIf)
+ node.getRight().accept(this, data);
+ return node;
+ }
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/PoliceExtensionUse.java b/weaver/src/org/aspectj/weaver/bcel/PoliceExtensionUse.java
index f10e8d123..5323c77f6 100644
--- a/weaver/src/org/aspectj/weaver/bcel/PoliceExtensionUse.java
+++ b/weaver/src/org/aspectj/weaver/bcel/PoliceExtensionUse.java
@@ -14,68 +14,69 @@ import org.aspectj.bridge.IMessage;
import org.aspectj.bridge.MessageUtil;
import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.World;
+import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor;
import org.aspectj.weaver.patterns.AndPointcut;
-import org.aspectj.weaver.patterns.IdentityPointcutVisitor;
import org.aspectj.weaver.patterns.KindedPointcut;
import org.aspectj.weaver.patterns.NotPointcut;
import org.aspectj.weaver.patterns.OrPointcut;
import org.aspectj.weaver.patterns.Pointcut;
/**
- * Walks a pointcut and determines if the synchronization related designators have been
- * used: lock() or unlock()
+ * Walks a pointcut and determines if the synchronization related designators have been used: lock() or unlock()
*/
-public class PoliceExtensionUse extends IdentityPointcutVisitor {
-
+public class PoliceExtensionUse extends AbstractPatternNodeVisitor {
+
private boolean synchronizationDesignatorEncountered;
- private World world;
- private Pointcut p;
-
- public PoliceExtensionUse(World w,Pointcut p) {
- this.world = w;
- this.p = p;
- this.synchronizationDesignatorEncountered = false;
- }
-
- public boolean synchronizationDesignatorEncountered() {
- return synchronizationDesignatorEncountered;
- }
+ private World world;
+ private Pointcut p;
+
+ public PoliceExtensionUse(World w, Pointcut p) {
+ this.world = w;
+ this.p = p;
+ this.synchronizationDesignatorEncountered = false;
+ }
+
+ public boolean synchronizationDesignatorEncountered() {
+ return synchronizationDesignatorEncountered;
+ }
public Object visit(KindedPointcut node, Object data) {
- if (world==null) return super.visit(node,data); // error scenario can sometimes lead to this LazyClassGen.toLongString()
- if (node.getKind()==Shadow.SynchronizationLock ||
- node.getKind()==Shadow.SynchronizationUnlock)
- synchronizationDesignatorEncountered=true;
+ if (world == null)
+ return super.visit(node, data); // error scenario can sometimes lead to this LazyClassGen.toLongString()
+ if (node.getKind() == Shadow.SynchronizationLock || node.getKind() == Shadow.SynchronizationUnlock)
+ synchronizationDesignatorEncountered = true;
// Check it!
if (!world.isJoinpointSynchronizationEnabled()) {
- if (node.getKind()==Shadow.SynchronizationLock) {
- IMessage m = MessageUtil.warn("lock() pointcut designator cannot be used without the option -Xjoinpoints:synchronization",
- p.getSourceLocation());
+ if (node.getKind() == Shadow.SynchronizationLock) {
+ IMessage m = MessageUtil.warn(
+ "lock() pointcut designator cannot be used without the option -Xjoinpoints:synchronization", p
+ .getSourceLocation());
world.getMessageHandler().handleMessage(m);
- } else if (node.getKind()==Shadow.SynchronizationUnlock) {
- IMessage m = MessageUtil.warn("unlock() pointcut designator cannot be used without the option -Xjoinpoints:synchronization",
- p.getSourceLocation());
+ } else if (node.getKind() == Shadow.SynchronizationUnlock) {
+ IMessage m = MessageUtil.warn(
+ "unlock() pointcut designator cannot be used without the option -Xjoinpoints:synchronization", p
+ .getSourceLocation());
world.getMessageHandler().handleMessage(m);
}
}
return super.visit(node, data);
}
-
- public Object visit(AndPointcut node, Object data) {
- node.getLeft().accept(this, data);
- node.getRight().accept(this, data);
- return node;
- }
- public Object visit(NotPointcut node, Object data) {
- node.getNegatedPointcut().accept(this, data);
- return node;
- }
+ public Object visit(AndPointcut node, Object data) {
+ node.getLeft().accept(this, data);
+ node.getRight().accept(this, data);
+ return node;
+ }
+
+ public Object visit(NotPointcut node, Object data) {
+ node.getNegatedPointcut().accept(this, data);
+ return node;
+ }
+
+ public Object visit(OrPointcut node, Object data) {
+ node.getLeft().accept(this, data);
+ node.getRight().accept(this, data);
+ return node;
+ }
- public Object visit(OrPointcut node, Object data) {
- node.getLeft().accept(this, data);
- node.getRight().accept(this, data);
- return node;
- }
-
} \ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java b/weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java
index 22eac78bb..14234438c 100644
--- a/weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java
+++ b/weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java
@@ -15,383 +15,439 @@ import org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut;
/**
* @author colyer
- *
+ *
*/
public abstract class AbstractPatternNodeVisitor implements PatternNodeVisitor {
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyTypePattern, java.lang.Object)
- */
public Object visit(AnyTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NoTypePattern, java.lang.Object)
- */
public Object visit(NoTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.EllipsisTypePattern, java.lang.Object)
- */
public Object visit(EllipsisTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyWithAnnotationTypePattern, java.lang.Object)
- */
public Object visit(AnyWithAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyAnnotationTypePattern, java.lang.Object)
- */
public Object visit(AnyAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.EllipsisAnnotationTypePattern, java.lang.Object)
- */
public Object visit(EllipsisAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndAnnotationTypePattern, java.lang.Object)
- */
public Object visit(AndAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndPointcut, java.lang.Object)
- */
public Object visit(AndPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndTypePattern, java.lang.Object)
- */
public Object visit(AndTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnnotationPatternList, java.lang.Object)
- */
public Object visit(AnnotationPatternList node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnnotationPointcut, java.lang.Object)
- */
public Object visit(AnnotationPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ArgsAnnotationPointcut, java.lang.Object)
- */
public Object visit(ArgsAnnotationPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ArgsPointcut, java.lang.Object)
*/
public Object visit(ArgsPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.BindingAnnotationTypePattern, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.BindingAnnotationTypePattern,
+ * java.lang.Object)
*/
public Object visit(BindingAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.BindingTypePattern, java.lang.Object)
*/
public Object visit(BindingTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.CflowPointcut, java.lang.Object)
*/
public Object visit(CflowPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ConcreteCflowPointcut, java.lang.Object)
*/
public Object visit(ConcreteCflowPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareAnnotation, java.lang.Object)
*/
public Object visit(DeclareAnnotation node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareErrorOrWarning, java.lang.Object)
*/
public Object visit(DeclareErrorOrWarning node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareParents, java.lang.Object)
*/
public Object visit(DeclareParents node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclarePrecedence, java.lang.Object)
*/
public Object visit(DeclarePrecedence node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareSoft, java.lang.Object)
*/
public Object visit(DeclareSoft node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ExactAnnotationTypePattern, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ExactAnnotationTypePattern,
+ * java.lang.Object)
*/
public Object visit(ExactAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ExactTypePattern, java.lang.Object)
*/
public Object visit(ExactTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.HandlerPointcut, java.lang.Object)
*/
public Object visit(HandlerPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.IfPointcut, java.lang.Object)
*/
public Object visit(IfPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.KindedPointcut, java.lang.Object)
*/
public Object visit(KindedPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ModifiersPattern, java.lang.Object)
*/
public Object visit(ModifiersPattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NamePattern, java.lang.Object)
*/
public Object visit(NamePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotAnnotationTypePattern, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotAnnotationTypePattern,
+ * java.lang.Object)
*/
public Object visit(NotAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotPointcut, java.lang.Object)
*/
public Object visit(NotPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotTypePattern, java.lang.Object)
*/
public Object visit(NotTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrAnnotationTypePattern, java.lang.Object)
*/
public Object visit(OrAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrPointcut, java.lang.Object)
*/
public Object visit(OrPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrTypePattern, java.lang.Object)
*/
public Object visit(OrTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerCflow, java.lang.Object)
*/
public Object visit(PerCflow node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerFromSuper, java.lang.Object)
*/
public Object visit(PerFromSuper node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerObject, java.lang.Object)
*/
public Object visit(PerObject node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerSingleton, java.lang.Object)
*/
public Object visit(PerSingleton node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerTypeWithin, java.lang.Object)
*/
public Object visit(PerTypeWithin node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PatternNode, java.lang.Object)
*/
public Object visit(PatternNode node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ReferencePointcut, java.lang.Object)
*/
public Object visit(ReferencePointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.SignaturePattern, java.lang.Object)
*/
public Object visit(SignaturePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut,
+ * java.lang.Object)
*/
public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThisOrTargetPointcut, java.lang.Object)
*/
public Object visit(ThisOrTargetPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThrowsPattern, java.lang.Object)
*/
public Object visit(ThrowsPattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.TypePatternList, java.lang.Object)
*/
public Object visit(TypePatternList node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WildAnnotationTypePattern, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WildAnnotationTypePattern,
+ * java.lang.Object)
*/
public Object visit(WildAnnotationTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WildTypePattern, java.lang.Object)
*/
public Object visit(WildTypePattern node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinAnnotationPointcut, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinAnnotationPointcut,
+ * java.lang.Object)
*/
public Object visit(WithinAnnotationPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut,
+ * java.lang.Object)
*/
public Object visit(WithinCodeAnnotationPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinPointcut, java.lang.Object)
*/
public Object visit(WithinPointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
+ /*
+ * (non-Javadoc)
+ *
* @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithincodePointcut, java.lang.Object)
*/
public Object visit(WithincodePointcut node, Object data) {
return node;
}
- /* (non-Javadoc)
- * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut, java.lang.Object)
+ /*
+ * (non-Javadoc)
+ *
+ * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut,
+ * java.lang.Object)
*/
public Object visit(MatchesNothingPointcut node, Object data) {
return node;
@@ -400,11 +456,11 @@ public abstract class AbstractPatternNodeVisitor implements PatternNodeVisitor {
public Object visit(TypeVariablePattern node, Object data) {
return node;
}
-
+
public Object visit(TypeVariablePatternList node, Object data) {
return node;
}
-
+
public Object visit(HasMemberTypePattern node, Object data) {
return node;
}
diff --git a/weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java b/weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java
deleted file mode 100644
index 1042ddcc2..000000000
--- a/weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * Alexandre Vasseur initial implementation
- *******************************************************************************/
-package org.aspectj.weaver.patterns;
-
-/**
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
-public class IdentityPointcutVisitor implements PatternNodeVisitor {
-
- public Object visit(AnyTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(NoTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(EllipsisTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(AnyWithAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(AnyAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(EllipsisAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(AndAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(AndPointcut node, Object data) {
- return node;
- }
-
- public Object visit(AndTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(AnnotationPatternList node, Object data) {
- return node;
- }
-
- public Object visit(AnnotationPointcut node, Object data) {
- return node;
- }
-
- public Object visit(ArgsAnnotationPointcut node, Object data) {
- return node;
- }
-
- public Object visit(ArgsPointcut node, Object data) {
- return node;
- }
-
- public Object visit(BindingAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(BindingTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(CflowPointcut node, Object data) {
- return node;
- }
-
- public Object visit(ConcreteCflowPointcut node, Object data) {
- return node;
- }
-
- public Object visit(DeclareAnnotation node, Object data) {
- return node;
- }
-
- public Object visit(DeclareErrorOrWarning node, Object data) {
- return node;
- }
-
- public Object visit(DeclareParents node, Object data) {
- return node;
- }
-
- public Object visit(DeclarePrecedence node, Object data) {
- return node;
- }
-
- public Object visit(DeclareSoft node, Object data) {
- return node;
- }
-
- public Object visit(ExactAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(ExactTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(HandlerPointcut node, Object data) {
- return node;
- }
-
- public Object visit(IfPointcut node, Object data) {
- return node;
- }
-
- public Object visit(KindedPointcut node, Object data) {
- return node;
- }
-
- public Object visit(ModifiersPattern node, Object data) {
- return node;
- }
-
- public Object visit(NamePattern node, Object data) {
- return node;
- }
-
- public Object visit(NotAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(NotPointcut node, Object data) {
- return node;
- }
-
- public Object visit(NotTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(OrAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(OrPointcut node, Object data) {
- return node;
- }
-
- public Object visit(OrTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(PerCflow node, Object data) {
- return node;
- }
-
- public Object visit(PerFromSuper node, Object data) {
- return node;
- }
-
- public Object visit(PerObject node, Object data) {
- return node;
- }
-
- public Object visit(PerSingleton node, Object data) {
- return node;
- }
-
- public Object visit(PerTypeWithin node, Object data) {
- return node;
- }
-
- public Object visit(PatternNode node, Object data) {
- throw new ParserException("Should implement for " + node.getClass(), null);
- }
-
- public Object visit(ReferencePointcut node, Object data) {
- return node;
- }
-
- public Object visit(SignaturePattern node, Object data) {
- return node;
- }
-
- public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
- return node;
- }
-
- public Object visit(ThisOrTargetPointcut node, Object data) {
- return node;
- }
-
- public Object visit(ThrowsPattern node, Object data) {
- return node;
- }
-
- public Object visit(TypePatternList node, Object data) {
- return node;
- }
-
- public Object visit(WildAnnotationTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(WildTypePattern node, Object data) {
- return node;
- }
-
- public Object visit(WithinAnnotationPointcut node, Object data) {
- return node;
- }
-
- public Object visit(WithinCodeAnnotationPointcut node, Object data) {
- return node;
- }
-
- public Object visit(WithinPointcut node, Object data) {
- return node;
- }
-
- public Object visit(WithincodePointcut node, Object data) {
- return node;
- }
-
- public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
- return node;
- }
-
- public Object visit(TypeVariablePattern node, Object data) {
- return node;
- }
-
- public Object visit(TypeVariablePatternList node, Object data) {
- return node;
- }
-
- public Object visit(HasMemberTypePattern node, Object data) {
- return node;
- }
-}
diff --git a/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java b/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
index 8a6665df2..7d62ae8ab 100644
--- a/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
+++ b/weaver/src/org/aspectj/weaver/patterns/PerThisOrTargetPointcutVisitor.java
@@ -11,213 +11,206 @@
*******************************************************************************/
package org.aspectj.weaver.patterns;
-import org.aspectj.weaver.Shadow;
import org.aspectj.weaver.ResolvedPointcutDefinition;
import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
/**
- * A visitor that turns a pointcut into a type pattern equivalent for a perthis or pertarget matching:
- * - pertarget(target(Foo)) => Foo+ (this one is a special case..)
- * - pertarget(execution(* Foo.do()) => Foo
- * - perthis(call(* Foo.do()) => *
- * - perthis(!call(* Foo.do()) => * (see how the ! has been absorbed here..)
- *
+ * A visitor that turns a pointcut into a type pattern equivalent for a perthis or pertarget matching: - pertarget(target(Foo)) =>
+ * Foo+ (this one is a special case..) - pertarget(execution(* Foo.do()) => Foo - perthis(call(* Foo.do()) => * - perthis(!call(*
+ * Foo.do()) => * (see how the ! has been absorbed here..)
+ *
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
-public class PerThisOrTargetPointcutVisitor extends IdentityPointcutVisitor {
-
- /** A maybe marker */
- private final static TypePattern MAYBE = new TypePatternMayBe();
-
- private final boolean m_isTarget;
- private final ResolvedType m_fromAspectType;
-
- public PerThisOrTargetPointcutVisitor(boolean isTarget, ResolvedType fromAspectType) {
- m_isTarget = isTarget;
- m_fromAspectType = fromAspectType;
- }
-
- public TypePattern getPerTypePointcut(Pointcut perClausePointcut) {
- return (TypePattern) perClausePointcut.accept(this, perClausePointcut);
- }
-
- //-- visitor methods, all is like Identity visitor except when it comes to transform pointcuts
-
- public Object visit(WithinPointcut node, Object data) {
- if (m_isTarget) {
- //pertarget(.. && within(Foo)) => true
- //pertarget(.. && !within(Foo)) => true as well !
- return MAYBE;
- } else {
- return node.getTypePattern();
- }
- }
-
- public Object visit(WithincodePointcut node, Object data) {
- if (m_isTarget) {
- //pertarget(.. && withincode(* Foo.do())) => true
- //pertarget(.. && !withincode(* Foo.do())) => true as well !
- return MAYBE;
- } else {
- return node.getSignature().getDeclaringType();
- }
- }
-
- public Object visit(WithinAnnotationPointcut node, Object data) {
- if (m_isTarget) {
- return MAYBE;
- } else {
- return new AnyWithAnnotationTypePattern( node.getAnnotationTypePattern());
- }
- }
-
- public Object visit(WithinCodeAnnotationPointcut node, Object data) {
- if (m_isTarget) {
- return MAYBE;
- } else {
- return MAYBE;//FIXME AV - can we optimize ? perthis(@withincode(Foo)) = hasmethod(..)
- }
- }
-
- public Object visit(KindedPointcut node, Object data) {
- if (node.getKind().equals(Shadow.AdviceExecution)) {
- return MAYBE;//TODO AV - can we do better ?
- } else if (node.getKind().equals(Shadow.ConstructorExecution)
- || node.getKind().equals(Shadow.Initialization)
- || node.getKind().equals(Shadow.MethodExecution)
- || node.getKind().equals(Shadow.PreInitialization)
- || node.getKind().equals(Shadow.StaticInitialization)) {
- return node.getSignature().getDeclaringType();
- } else if (node.getKind().equals(Shadow.ConstructorCall)
- || node.getKind().equals(Shadow.FieldGet)
- || node.getKind().equals(Shadow.FieldSet)
- || node.getKind().equals(Shadow.MethodCall)) {
- if (m_isTarget) {
- return node.getSignature().getDeclaringType();
- } else {
- return MAYBE;
- }
- } else if (node.getKind().equals(Shadow.ExceptionHandler)) {
- return MAYBE;
- } else {
- throw new ParserException("Undetermined - should not happen: " + node.getKind().getSimpleName(), null);
- }
- }
-
- public Object visit(AndPointcut node, Object data) {
- return new AndTypePattern(getPerTypePointcut(node.left), getPerTypePointcut(node.right));
- }
-
- public Object visit(OrPointcut node, Object data) {
- return new OrTypePattern(getPerTypePointcut(node.left), getPerTypePointcut(node.right));
- }
-
- public Object visit(NotPointcut node, Object data) {
-// TypePattern negated = getPerTypePointcut(node.getNegatedPointcut());
-// if (MAYBE.equals(negated)) {
-// return MAYBE;
-// }
-// return new NotTypePattern(negated);
- // AMC - the only safe thing to return here is maybe...
- // see for example pr114054
- return MAYBE;
- }
-
- public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
- if (m_isTarget && !node.isThis()) {
- return new AnyWithAnnotationTypePattern( node.getAnnotationTypePattern());
- } else if (!m_isTarget && node.isThis()) {
- return new AnyWithAnnotationTypePattern( node.getAnnotationTypePattern());
- } else {
- // perthis(@target(Foo))
- return MAYBE;
- }
- }
-
- public Object visit(ThisOrTargetPointcut node, Object data) {
- if ((m_isTarget && !node.isThis())
- || (!m_isTarget && node.isThis())) {
- String pointcutString = node.getType().toString();
- // see pr115788 "<nothing>" means there was a problem resolving types - that will be reported so dont blow up
- // the parser here..
- if (pointcutString.equals("<nothing>")) {
- return new NoTypePattern();
- }
- //pertarget(target(Foo)) => Foo+ for type pattern matching
- //perthis(this(Foo)) => Foo+ for type pattern matching
- // TODO AV - we do like a deep copy by parsing it again.. quite dirty, would need a clean deep copy
- TypePattern copy = new PatternParser(pointcutString.replace('$', '.')).parseTypePattern();
- // TODO AV - see dirty replace from $ to . here as inner classes are with $ instead (#108488)
- copy.includeSubtypes = true;
- return copy;
- } else {
- // perthis(target(Foo)) => maybe
- return MAYBE;
- }
- }
-
- public Object visit(ReferencePointcut node, Object data) {
- // && pc_ref()
- // we know there is no support for binding in perClause: perthis(pc_ref(java.lang.String))
- // TODO AV - may need some work for generics..
-
- ResolvedPointcutDefinition pointcutDec;
- ResolvedType searchStart = m_fromAspectType;
- if (node.onType != null) {
- searchStart = node.onType.resolve(m_fromAspectType.getWorld());
- if (searchStart.isMissing()) {
- return MAYBE;// this should not happen since concretize will fails but just in case..
- }
- }
- pointcutDec = searchStart.findPointcut(node.name);
-
- return getPerTypePointcut(pointcutDec.getPointcut());
- }
-
- public Object visit(IfPointcut node, Object data) {
- return TypePattern.ANY;
- }
-
- public Object visit(HandlerPointcut node, Object data) {
- // quiet unexpected since a KindedPointcut but do as if...
- return MAYBE;
- }
-
- public Object visit(CflowPointcut node, Object data) {
- return MAYBE;
- }
-
- public Object visit(ConcreteCflowPointcut node, Object data) {
- return MAYBE;
- }
-
- public Object visit(ArgsPointcut node, Object data) {
- return MAYBE;
- }
-
- public Object visit(ArgsAnnotationPointcut node, Object data) {
- return MAYBE;
- }
-
- public Object visit(AnnotationPointcut node, Object data) {
- return MAYBE;
- }
-
- public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
- // a small hack since the usual MatchNothing has its toString = "<nothing>" which is not parseable back
- // while I use back parsing for check purpose.
- return new NoTypePattern() {
- public String toString() {
- return "false";
- }
- };
- }
-
- /**
- * A MayBe type pattern that acts as ANY except that !MAYBE = MAYBE
- *
- * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
- */
- private static class TypePatternMayBe extends AnyTypePattern {
- }
+public class PerThisOrTargetPointcutVisitor extends AbstractPatternNodeVisitor {
+
+ /** A maybe marker */
+ private final static TypePattern MAYBE = new TypePatternMayBe();
+
+ private final boolean m_isTarget;
+ private final ResolvedType m_fromAspectType;
+
+ public PerThisOrTargetPointcutVisitor(boolean isTarget, ResolvedType fromAspectType) {
+ m_isTarget = isTarget;
+ m_fromAspectType = fromAspectType;
+ }
+
+ public TypePattern getPerTypePointcut(Pointcut perClausePointcut) {
+ return (TypePattern) perClausePointcut.accept(this, perClausePointcut);
+ }
+
+ // -- visitor methods, all is like Identity visitor except when it comes to transform pointcuts
+
+ public Object visit(WithinPointcut node, Object data) {
+ if (m_isTarget) {
+ // pertarget(.. && within(Foo)) => true
+ // pertarget(.. && !within(Foo)) => true as well !
+ return MAYBE;
+ } else {
+ return node.getTypePattern();
+ }
+ }
+
+ public Object visit(WithincodePointcut node, Object data) {
+ if (m_isTarget) {
+ // pertarget(.. && withincode(* Foo.do())) => true
+ // pertarget(.. && !withincode(* Foo.do())) => true as well !
+ return MAYBE;
+ } else {
+ return node.getSignature().getDeclaringType();
+ }
+ }
+
+ public Object visit(WithinAnnotationPointcut node, Object data) {
+ if (m_isTarget) {
+ return MAYBE;
+ } else {
+ return new AnyWithAnnotationTypePattern(node.getAnnotationTypePattern());
+ }
+ }
+
+ public Object visit(WithinCodeAnnotationPointcut node, Object data) {
+ if (m_isTarget) {
+ return MAYBE;
+ } else {
+ return MAYBE;// FIXME AV - can we optimize ? perthis(@withincode(Foo)) = hasmethod(..)
+ }
+ }
+
+ public Object visit(KindedPointcut node, Object data) {
+ if (node.getKind().equals(Shadow.AdviceExecution)) {
+ return MAYBE;// TODO AV - can we do better ?
+ } else if (node.getKind().equals(Shadow.ConstructorExecution) || node.getKind().equals(Shadow.Initialization)
+ || node.getKind().equals(Shadow.MethodExecution) || node.getKind().equals(Shadow.PreInitialization)
+ || node.getKind().equals(Shadow.StaticInitialization)) {
+ return node.getSignature().getDeclaringType();
+ } else if (node.getKind().equals(Shadow.ConstructorCall) || node.getKind().equals(Shadow.FieldGet)
+ || node.getKind().equals(Shadow.FieldSet) || node.getKind().equals(Shadow.MethodCall)) {
+ if (m_isTarget) {
+ return node.getSignature().getDeclaringType();
+ } else {
+ return MAYBE;
+ }
+ } else if (node.getKind().equals(Shadow.ExceptionHandler)) {
+ return MAYBE;
+ } else {
+ throw new ParserException("Undetermined - should not happen: " + node.getKind().getSimpleName(), null);
+ }
+ }
+
+ public Object visit(AndPointcut node, Object data) {
+ return new AndTypePattern(getPerTypePointcut(node.left), getPerTypePointcut(node.right));
+ }
+
+ public Object visit(OrPointcut node, Object data) {
+ return new OrTypePattern(getPerTypePointcut(node.left), getPerTypePointcut(node.right));
+ }
+
+ public Object visit(NotPointcut node, Object data) {
+ // TypePattern negated = getPerTypePointcut(node.getNegatedPointcut());
+ // if (MAYBE.equals(negated)) {
+ // return MAYBE;
+ // }
+ // return new NotTypePattern(negated);
+ // AMC - the only safe thing to return here is maybe...
+ // see for example pr114054
+ return MAYBE;
+ }
+
+ public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
+ if (m_isTarget && !node.isThis()) {
+ return new AnyWithAnnotationTypePattern(node.getAnnotationTypePattern());
+ } else if (!m_isTarget && node.isThis()) {
+ return new AnyWithAnnotationTypePattern(node.getAnnotationTypePattern());
+ } else {
+ // perthis(@target(Foo))
+ return MAYBE;
+ }
+ }
+
+ public Object visit(ThisOrTargetPointcut node, Object data) {
+ if ((m_isTarget && !node.isThis()) || (!m_isTarget && node.isThis())) {
+ String pointcutString = node.getType().toString();
+ // see pr115788 "<nothing>" means there was a problem resolving types - that will be reported so dont blow up
+ // the parser here..
+ if (pointcutString.equals("<nothing>")) {
+ return new NoTypePattern();
+ }
+ // pertarget(target(Foo)) => Foo+ for type pattern matching
+ // perthis(this(Foo)) => Foo+ for type pattern matching
+ // TODO AV - we do like a deep copy by parsing it again.. quite dirty, would need a clean deep copy
+ TypePattern copy = new PatternParser(pointcutString.replace('$', '.')).parseTypePattern();
+ // TODO AV - see dirty replace from $ to . here as inner classes are with $ instead (#108488)
+ copy.includeSubtypes = true;
+ return copy;
+ } else {
+ // perthis(target(Foo)) => maybe
+ return MAYBE;
+ }
+ }
+
+ public Object visit(ReferencePointcut node, Object data) {
+ // && pc_ref()
+ // we know there is no support for binding in perClause: perthis(pc_ref(java.lang.String))
+ // TODO AV - may need some work for generics..
+
+ ResolvedPointcutDefinition pointcutDec;
+ ResolvedType searchStart = m_fromAspectType;
+ if (node.onType != null) {
+ searchStart = node.onType.resolve(m_fromAspectType.getWorld());
+ if (searchStart.isMissing()) {
+ return MAYBE;// this should not happen since concretize will fails but just in case..
+ }
+ }
+ pointcutDec = searchStart.findPointcut(node.name);
+
+ return getPerTypePointcut(pointcutDec.getPointcut());
+ }
+
+ public Object visit(IfPointcut node, Object data) {
+ return TypePattern.ANY;
+ }
+
+ public Object visit(HandlerPointcut node, Object data) {
+ // quiet unexpected since a KindedPointcut but do as if...
+ return MAYBE;
+ }
+
+ public Object visit(CflowPointcut node, Object data) {
+ return MAYBE;
+ }
+
+ public Object visit(ConcreteCflowPointcut node, Object data) {
+ return MAYBE;
+ }
+
+ public Object visit(ArgsPointcut node, Object data) {
+ return MAYBE;
+ }
+
+ public Object visit(ArgsAnnotationPointcut node, Object data) {
+ return MAYBE;
+ }
+
+ public Object visit(AnnotationPointcut node, Object data) {
+ return MAYBE;
+ }
+
+ public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
+ // a small hack since the usual MatchNothing has its toString = "<nothing>" which is not parseable back
+ // while I use back parsing for check purpose.
+ return new NoTypePattern() {
+ public String toString() {
+ return "false";
+ }
+ };
+ }
+
+ /**
+ * A MayBe type pattern that acts as ANY except that !MAYBE = MAYBE
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+ private static class TypePatternMayBe extends AnyTypePattern {
+ }
}