summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraclement <aclement>2010-04-22 02:24:45 +0000
committeraclement <aclement>2010-04-22 02:24:45 +0000
commit0ca15bb18dde892f599a1b2c8ae06cbcda847c7f (patch)
tree678d76eddc560e7bbf8ac6e0ff4af56bb47e7452
parentef9124cf8c379663c9cd477384983f03df7e7263 (diff)
downloadaspectj-0ca15bb18dde892f599a1b2c8ae06cbcda847c7f.tar.gz
aspectj-0ca15bb18dde892f599a1b2c8ae06cbcda847c7f.zip
310043: override final rogue message
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java8
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java58
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java4
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java42
-rw-r--r--org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java4
5 files changed, 85 insertions, 31 deletions
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java b/org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java
index 2377f91b7..da5927840 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java
@@ -20,6 +20,8 @@ import java.util.Map;
import org.aspectj.bridge.ISourceLocation;
import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute;
+import sun.security.krb5.Realm;
+
/**
* @author colyer Instances of this class are created by ResolvedMember.getSignatures() when collating all of the signatures for a
* member. We need to create entries in the set for the "gaps" in the hierarchy. For example:
@@ -165,7 +167,7 @@ public class JoinPointSignature implements ResolvedMember {
public boolean isPublic() {
return realMember.isPublic();
}
-
+
public boolean isDefault() {
return realMember.isDefault();
}
@@ -370,4 +372,8 @@ public class JoinPointSignature implements ResolvedMember {
public boolean isDefaultConstructor() {
return realMember.isDefaultConstructor();
}
+
+ public boolean equalsApartFromDeclaringType(Object other) {
+ return realMember.equalsApartFromDeclaringType(other);
+ }
}
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java b/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java
index 46e10a717..b34c34946 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java
@@ -28,7 +28,7 @@ public class MemberImpl implements Member {
protected UnresolvedType returnType;
protected UnresolvedType[] parameterTypes;
private final String erasedSignature; // eg. (Ljava/util/Set;V)Ljava/lang/String;
- private String paramSignature; // eg. (Ljava/util/Set<Ljava/lang/String;>;V) // no return type
+ private String paramSignature; // eg. (Ljava/util/Set<Ljava/lang/String;>;V) // no return type
// OPTIMIZE move out of the member!
private boolean reportedCantFindDeclaringType = false;
@@ -40,7 +40,8 @@ public class MemberImpl implements Member {
private JoinPointSignatureIterator joinPointSignatures = null;
/**
- * Construct a MemberImpl using an erased signature for the parameters and return type (member method/ctor) or type (member field)
+ * Construct a MemberImpl using an erased signature for the parameters and return type (member method/ctor) or type (member
+ * field)
*/
public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String erasedSignature) {
this.kind = kind;
@@ -59,7 +60,8 @@ public class MemberImpl implements Member {
}
/**
- * Construct a MemberImpl using real type information for the parameters and return type (member method/ctor) or type (member field)
+ * Construct a MemberImpl using real type information for the parameters and return type (member method/ctor) or type (member
+ * field)
*/
public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name,
UnresolvedType[] parameterTypes) {
@@ -73,19 +75,20 @@ public class MemberImpl implements Member {
this.erasedSignature = returnType.getErasureSignature();
} else {
this.erasedSignature = typesToSignature(returnType, parameterTypes, true);
-
+
// Check parameter recovery by collapsing types to the string then rebuilding them from that
// this will check we are capable of having WeakRefs to the parameter types
-// String nonErasedSignature = getParameterSignature()+getReturnType().getSignature();
-// Object[] returnAndParams = signatureToTypes(nonErasedSignature);
-// UnresolvedType[] recoveredParams = (UnresolvedType[]) returnAndParams[1];
-// for (int jj=0;jj<parameterTypes.length;jj++) {
-// if (!parameterTypes[jj].getSignature().equals(recoveredParams[jj].getSignature())) {
-// throw new RuntimeException(parameterTypes[jj].getSignature()+" != "+recoveredParams[jj].getSignature()+" "+paramSignature);
-// }
-// }
+ // String nonErasedSignature = getParameterSignature()+getReturnType().getSignature();
+ // Object[] returnAndParams = signatureToTypes(nonErasedSignature);
+ // UnresolvedType[] recoveredParams = (UnresolvedType[]) returnAndParams[1];
+ // for (int jj=0;jj<parameterTypes.length;jj++) {
+ // if (!parameterTypes[jj].getSignature().equals(recoveredParams[jj].getSignature())) {
+ // throw new
+ // RuntimeException(parameterTypes[jj].getSignature()+" != "+recoveredParams[jj].getSignature()+" "+paramSignature);
+ // }
+ // }
}
-
+
}
public ResolvedMember resolve(World world) {
@@ -95,22 +98,22 @@ public class MemberImpl implements Member {
// ---- utility methods
/**
- * Build a signature based on the return type and parameter types. For example: "(Ljava/util/Set<Ljava/lang/String;>;)V"
- * or "(Ljava/util/Set;)V". The latter form shows what happens when the generics are erased
+ * Build a signature based on the return type and parameter types. For example: "(Ljava/util/Set<Ljava/lang/String;>;)V" or
+ * "(Ljava/util/Set;)V". The latter form shows what happens when the generics are erased
*/
public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean eraseGenerics) {
StringBuilder buf = new StringBuilder();
buf.append("(");
- for (UnresolvedType paramType: paramTypes) {
+ for (UnresolvedType paramType : paramTypes) {
if (eraseGenerics && (paramType.isParameterizedType() || paramType.isTypeVariableReference())) {
- buf.append(paramType.getErasureSignature());
+ buf.append(paramType.getErasureSignature());
} else {
- buf.append(paramType.getSignature());
+ buf.append(paramType.getSignature());
}
}
buf.append(")");
if (eraseGenerics && (returnType.isParameterizedType() || returnType.isTypeVariableReference())) {
- buf.append(returnType.getErasureSignature());
+ buf.append(returnType.getErasureSignature());
} else {
buf.append(returnType.getSignature());
}
@@ -200,7 +203,7 @@ public class MemberImpl implements Member {
} else if (c == 'T') { // assumed 'reference' to a type
// variable, so just "Tname;"
int nextSemicolon = sig.indexOf(';', start);
- String nextbit = sig.substring(start, nextSemicolon+1);
+ String nextbit = sig.substring(start, nextSemicolon + 1);
l.add(UnresolvedType.forSignature(nextbit));
i = nextSemicolon + 1;
} else {
@@ -251,7 +254,7 @@ public class MemberImpl implements Member {
public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
return new MemberImpl(
// ??? this calls <clinit> a method
- name.equals("<init>") ? CONSTRUCTOR : METHOD, declTy, mods, rTy, name, paramTys);
+ name.equals("<init>") ? CONSTRUCTOR : METHOD, declTy, mods, rTy, name, paramTys);
}
private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
@@ -263,7 +266,7 @@ public class MemberImpl implements Member {
}
@Override
- public boolean equals(Object other) {
+ public final boolean equals(Object other) {
if (!(other instanceof Member)) {
return false;
}
@@ -273,6 +276,17 @@ public class MemberImpl implements Member {
}
/**
+ * @return true if this member equals the one supplied in every respect other than the declaring type
+ */
+ public final boolean equalsApartFromDeclaringType(Object other) {
+ if (!(other instanceof Member)) {
+ return false;
+ }
+ Member o = (Member) other;
+ return (getKind() == o.getKind() && getName().equals(o.getName()) && getSignature().equals(o.getSignature()));
+ }
+
+ /**
* Equality is checked based on the underlying signature, so the hash code of a member is based on its kind, name, signature,
* and declaring type. The algorithm for this was taken from page 38 of effective java.
*/
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
index 1f82713e4..93d1361a5 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
@@ -81,7 +81,7 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
public ISourceLocation getSourceLocation();
public int getStart();
-
+
public int getEnd();
public ISourceContext getSourceContext();
@@ -123,6 +123,8 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
*/
public UnresolvedType[] getGenericParameterTypes();
+ public boolean equalsApartFromDeclaringType(Object other);
+
// return a resolved member in which all type variables in the signature of
// this
// member have been replaced with the given bindings.
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
index 0b7f27c08..7e4932f96 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
@@ -1771,11 +1771,11 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
// System.err.println(" compare: " + c);
if (c < 0) {
// the existing munger dominates the new munger
- checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
+ checkLegalOverride(munger.getSignature(), existingMunger.getSignature(), 0x11, null);
return;
} else if (c > 0) {
// the new munger dominates the existing one
- checkLegalOverride(existingMunger.getSignature(), munger.getSignature());
+ checkLegalOverride(existingMunger.getSignature(), munger.getSignature(), 0x11, null);
i.remove();
break;
} else {
@@ -1841,11 +1841,11 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
// System.err.println(" c: " + c);
if (c < 0) {
// existingMember dominates munger
- checkLegalOverride(typeTransformerSignature, existingMember);
+ checkLegalOverride(typeTransformerSignature, existingMember, 0x10, typeTransformer.getAspectType());
return true;
} else if (c > 0) {
// munger dominates existingMember
- checkLegalOverride(existingMember, typeTransformerSignature);
+ checkLegalOverride(existingMember, typeTransformerSignature, 0x01, typeTransformer.getAspectType());
// interTypeMungers.add(munger);
// ??? might need list of these overridden abstracts
continue;
@@ -1953,13 +1953,43 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
/**
+ * @param transformerPosition which parameter is the type transformer (0x10 for first, 0x01 for second, 0x11 for both, 0x00 for
+ * neither)
+ * @param aspectType the declaring type of aspect defining the *first* type transformer
* @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) {
+ public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child, int transformerPosition, ResolvedType aspectType) {
// System.err.println("check: " + child.getDeclaringType() +
// " overrides " + parent.getDeclaringType());
if (Modifier.isFinal(parent.getModifiers())) {
+ // If the ITD matching is occurring due to pulling in a BinaryTypeBinding then this check can incorrectly
+ // signal an error because the ITD transformer being examined here will exactly match the member it added
+ // during the first round of compilation. This situation can only occur if the ITD is on an interface whilst
+ // the class is the top most implementor. If the ITD is on the same type that received it during compilation,
+ // this method won't be called as the previous check for precedence level will return 0.
+
+ if (transformerPosition == 0x10 && aspectType != null) {
+ ResolvedType nonItdDeclaringType = child.getDeclaringType().resolve(world);
+ WeaverStateInfo wsi = nonItdDeclaringType.getWeaverState();
+ if (wsi != null) {
+ List<ConcreteTypeMunger> transformersOnThisType = wsi.getTypeMungers(nonItdDeclaringType);
+ if (transformersOnThisType != null) {
+ for (ConcreteTypeMunger transformer : transformersOnThisType) {
+ // relatively crude check - is the ITD
+ // for the same as the existingmember
+ // and does it come
+ // from the same aspect
+ if (transformer.aspectType.equals(aspectType)) {
+ if (parent.equalsApartFromDeclaringType(transformer.getSignature())) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+
world.showMessage(Message.ERROR, WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER, parent), child
.getSourceLocation(), null);
return false;
@@ -2332,7 +2362,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
}
if (conflictingSignature(existing, toAdd)) {
if (isOverriding) {
- checkLegalOverride(existing, toAdd);
+ checkLegalOverride(existing, toAdd, 0x00, null);
j.remove();
} else {
getWorld().showMessage(
diff --git a/org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java b/org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java
index 2d31b597a..0e0a89fce 100644
--- a/org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java
+++ b/org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java
@@ -14,7 +14,7 @@ import java.util.Map;
/**
* Some methods need a temporary type munger (because ConcreteTypeMunger is abstract - dont ask...).
*
- * TODO ought to remove the need for this or at least sort out the two methods that are in it, they look wierd...
+ * TODO ought to remove the need for this or at least sort out the two methods that are in it, they look weird...
*
* @author AndyClement
*/
@@ -24,10 +24,12 @@ public class TemporaryTypeMunger extends ConcreteTypeMunger {
super(munger, aspectType);
}
+ @Override
public ConcreteTypeMunger parameterizeWith(Map parameterizationMap, World world) {
throw new UnsupportedOperationException("Cannot be called on a TemporaryTypeMunger");
}
+ @Override
public ConcreteTypeMunger parameterizedFor(ResolvedType targetType) {
throw new UnsupportedOperationException("Cannot be called on a TemporaryTypeMunger");
}