summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authorAndy Clement <andrew.clement@gmail.com>2012-09-28 21:46:05 -0700
committerAndy Clement <andrew.clement@gmail.com>2012-09-28 21:46:05 -0700
commit0bbb4f252a1efa7408f55e06fc062baddce0dcba (patch)
tree8ed6c7f462dad7ae86fda0c4946829dec27bfe90 /weaver
parentb8ebdc33c75aa081ac3bf9b1a45f79e4177467a6 (diff)
downloadaspectj-0bbb4f252a1efa7408f55e06fc062baddce0dcba.tar.gz
aspectj-0bbb4f252a1efa7408f55e06fc062baddce0dcba.zip
390269: fix for multiple bridge candidates in hierarchy
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java97
1 files changed, 43 insertions, 54 deletions
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
index fbeb09e97..dccda0505 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
@@ -14,6 +14,7 @@ package org.aspectj.weaver.bcel;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -345,8 +346,7 @@ class BcelClassWeaver implements IClassWeaver {
/**
* Create a single bridge method called 'theBridgeMethod' that bridges to 'whatToBridgeTo'
*/
- private static void createBridgeMethod(BcelWorld world, LazyMethodGen whatToBridgeToMethodGen, LazyClassGen clazz,
- ResolvedMember theBridgeMethod) {
+ private static void createBridgeMethod(BcelWorld world, LazyMethodGen whatToBridgeToMethodGen, LazyClassGen clazz, ResolvedMember theBridgeMethod) {
InstructionList body;
InstructionFactory fact;
int pos = 0;
@@ -563,6 +563,7 @@ class BcelClassWeaver implements IClassWeaver {
// FIXASC refactor into ResolvedType or even ResolvedMember?
/**
* Check if a particular method is overriding another - refactored into this helper so it can be used from multiple places.
+ * @return method that is overriding if it
*/
private static ResolvedMember isOverriding(ResolvedType typeToCheck, ResolvedMember methodThatMightBeGettingOverridden,
String mname, String mrettype, int mmods, boolean inSamePackage, UnresolvedType[] methodParamsArray) {
@@ -693,15 +694,16 @@ class BcelClassWeaver implements IClassWeaver {
*
* @return the method being overridden or null if none is found
*/
- public static ResolvedMember checkForOverride(ResolvedType typeToCheck, String mname, String mparams, String mrettype,
- int mmods, String mpkg, UnresolvedType[] methodParamsArray) {
+ public static void checkForOverride(ResolvedType typeToCheck, String mname, String mparams, String mrettype,
+ int mmods, String mpkg, UnresolvedType[] methodParamsArray, List<ResolvedMember> overriddenMethodsCollector) {
if (typeToCheck == null) {
- return null;
+ return;
}
if (typeToCheck instanceof MissingResolvedTypeWithKnownSignature) {
- return null; // we just can't tell !
+ return; // we just can't tell !
}
+
if (typeToCheck.getWorld().forDEBUG_bridgingCode) {
System.err.println(" Bridging:checking for override of " + mname + " in " + typeToCheck);
@@ -711,9 +713,8 @@ class BcelClassWeaver implements IClassWeaver {
if (packageName == null) {
packageName = "";
}
- boolean inSamePackage = packageName.equals(mpkg); // used when looking
- // at visibility
- // rules
+ // used when looking at visibility rules
+ boolean inSamePackage = packageName.equals(mpkg);
ResolvedMember[] methods = typeToCheck.getDeclaredMethods();
for (int ii = 0; ii < methods.length; ii++) {
@@ -722,7 +723,7 @@ class BcelClassWeaver implements IClassWeaver {
ResolvedMember isOverriding = isOverriding(typeToCheck, methodThatMightBeGettingOverridden, mname, mrettype, mmods,
inSamePackage, methodParamsArray);
if (isOverriding != null) {
- return isOverriding;
+ overriddenMethodsCollector.add(isOverriding);
}
}
// was: List l = typeToCheck.getInterTypeMungers();
@@ -742,31 +743,24 @@ class BcelClassWeaver implements IClassWeaver {
ResolvedMember isOverriding = isOverriding(typeToCheck, aMethod, mname, mrettype, mmods, inSamePackage,
methodParamsArray);
if (isOverriding != null) {
- return isOverriding;
+ overriddenMethodsCollector.add(isOverriding);
}
}
}
}
if (typeToCheck.equals(UnresolvedType.OBJECT)) {
- return null;
+ return;
}
ResolvedType superclass = typeToCheck.getSuperclass();
- ResolvedMember overriddenMethod = checkForOverride(superclass, mname, mparams, mrettype, mmods, mpkg, methodParamsArray);
- if (overriddenMethod != null) {
- return overriddenMethod;
- }
-
+ checkForOverride(superclass, mname, mparams, mrettype, mmods, mpkg, methodParamsArray,overriddenMethodsCollector);
+
ResolvedType[] interfaces = typeToCheck.getDeclaredInterfaces();
for (int i = 0; i < interfaces.length; i++) {
ResolvedType anInterface = interfaces[i];
- overriddenMethod = checkForOverride(anInterface, mname, mparams, mrettype, mmods, mpkg, methodParamsArray);
- if (overriddenMethod != null) {
- return overriddenMethod;
- }
+ checkForOverride(anInterface, mname, mparams, mrettype, mmods, mpkg, methodParamsArray,overriddenMethodsCollector);
}
- return null;
}
/**
@@ -778,31 +772,30 @@ class BcelClassWeaver implements IClassWeaver {
*/
public static boolean calculateAnyRequiredBridgeMethods(BcelWorld world, LazyClassGen clazz) {
world.ensureAdvancedConfigurationProcessed();
+
if (!world.isInJava5Mode()) {
return false; // just double check... the caller should have already
}
- // verified this
if (clazz.isInterface()) {
- return false; // dont bother if we're an interface
+ return false; // dont bother if we are an interface
}
+
boolean didSomething = false; // set if we build any bridge methods
-
// So what methods do we have right now in this class?
List<LazyMethodGen> methods = clazz.getMethodGens();
- // Keep a set of all methods from this type - it'll help us to check if
- // bridge methods
+ // Keep a set of all methods from this type - it'll help us to check if bridge methods
// have already been created, we don't want to do it twice!
Set<String> methodsSet = new HashSet<String>();
for (int i = 0; i < methods.size(); i++) {
LazyMethodGen aMethod = methods.get(i);
- methodsSet.add(aMethod.getName() + aMethod.getSignature()); // e.g.
- // "foo(Ljava/lang/String;)V"
+ StringBuilder sb = new StringBuilder(aMethod.getName());
+ sb.append(aMethod.getSignature());
+ methodsSet.add(sb.toString()); // e.g. "foo(Ljava/lang/String;)V"
}
// Now go through all the methods in this type
for (int i = 0; i < methods.size(); i++) {
-
// This is the local method that we *might* have to bridge to
LazyMethodGen bridgeToCandidate = methods.get(i);
if (bridgeToCandidate.isBridgeMethod()) {
@@ -821,8 +814,7 @@ class BcelClassWeaver implements IClassWeaver {
}
if (world.forDEBUG_bridgingCode) {
- System.err.println("Bridging: Determining if we have to bridge to " + clazz.getName() + "." + name + ""
- + bridgeToCandidate.getSignature());
+ System.err.println("Bridging: Determining if we have to bridge to " + clazz.getName() + "." + name + "" + bridgeToCandidate.getSignature());
}
// Let's take a look at the superclass
@@ -832,20 +824,20 @@ class BcelClassWeaver implements IClassWeaver {
}
String pkgName = clazz.getPackageName();
UnresolvedType[] bm = BcelWorld.fromBcel(bridgeToCandidate.getArgumentTypes());
- ResolvedMember overriddenMethod = checkForOverride(theSuperclass, name, psig, rsig, bridgeToCandidate.getAccessFlags(),
- pkgName, bm);
- if (overriddenMethod != null) {
- String key = new StringBuffer().append(overriddenMethod.getName()).append(overriddenMethod.getSignatureErased())
- .toString(); // pr237419
- boolean alreadyHaveABridgeMethod = methodsSet.contains(key);
- if (!alreadyHaveABridgeMethod) {
- if (world.forDEBUG_bridgingCode) {
- System.err.println("Bridging:bridging to '" + overriddenMethod + "'");
+ List<ResolvedMember> overriddenMethodsCollector = new ArrayList<ResolvedMember>();
+ checkForOverride(theSuperclass, name, psig, rsig, bridgeToCandidate.getAccessFlags(), pkgName, bm, overriddenMethodsCollector);
+ if (overriddenMethodsCollector.size() != 0) {
+ for (ResolvedMember overriddenMethod: overriddenMethodsCollector) {
+ String key = new StringBuilder(overriddenMethod.getName()).append(overriddenMethod.getSignatureErased()).toString(); // pr237419
+ boolean alreadyHaveABridgeMethod = methodsSet.contains(key);
+ if (!alreadyHaveABridgeMethod) {
+ if (world.forDEBUG_bridgingCode) {
+ System.err.println("Bridging:bridging to '" + overriddenMethod + "'");
+ }
+ createBridgeMethod(world, bridgeToCandidate, clazz, overriddenMethod);
+ methodsSet.add(key);
+ didSomething = true;
}
- createBridgeMethod(world, bridgeToCandidate, clazz, overriddenMethod);
- methodsSet.add(key);
- didSomething = true;
- continue; // look at the next method
}
}
@@ -856,12 +848,11 @@ class BcelClassWeaver implements IClassWeaver {
System.err.println("Bridging:checking superinterface " + interfaces[j]);
}
ResolvedType interfaceType = world.resolve(interfaces[j]);
- overriddenMethod = checkForOverride(interfaceType, name, psig, rsig, bridgeToCandidate.getAccessFlags(),
- clazz.getPackageName(), bm);
- if (overriddenMethod != null) {
- String key = new StringBuffer().append(overriddenMethod.getName())
- .append(overriddenMethod.getSignatureErased()).toString(); // pr
- // 237419
+ overriddenMethodsCollector.clear();
+ checkForOverride(interfaceType, name, psig, rsig, bridgeToCandidate.getAccessFlags(),
+ clazz.getPackageName(), bm, overriddenMethodsCollector);
+ for (ResolvedMember overriddenMethod: overriddenMethodsCollector) {
+ String key = new StringBuffer().append(overriddenMethod.getName()).append(overriddenMethod.getSignatureErased()).toString(); // pr237419
boolean alreadyHaveABridgeMethod = methodsSet.contains(key);
if (!alreadyHaveABridgeMethod) {
createBridgeMethod(world, bridgeToCandidate, clazz, overriddenMethod);
@@ -870,7 +861,6 @@ class BcelClassWeaver implements IClassWeaver {
if (world.forDEBUG_bridgingCode) {
System.err.println("Bridging:bridging to " + overriddenMethod);
}
- continue; // look at the next method
}
}
}
@@ -879,8 +869,7 @@ class BcelClassWeaver implements IClassWeaver {
return didSomething;
}
- // **************************** end of bridge method creation code
- // *****************
+ // **************************** end of bridge method creation code *****************
/**
* Weave any declare @method/@ctor statements into the members of the supplied class