]> source.dussan.org Git - aspectj.git/commitdiff
310043: override final rogue message
authoraclement <aclement>
Thu, 22 Apr 2010 02:24:45 +0000 (02:24 +0000)
committeraclement <aclement>
Thu, 22 Apr 2010 02:24:45 +0000 (02:24 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/JoinPointSignature.java
org.aspectj.matcher/src/org/aspectj/weaver/MemberImpl.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedMember.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/TemporaryTypeMunger.java

index 2377f91b742e4a348cf7f3887cc2284c628684e7..da5927840a5d99ed4b0e10c105331866bf7af41d 100644 (file)
@@ -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);
+       }
 }
index 46e10a717578382be04f935c8caf28a3cabce3c7..b34c34946faf3d2f264e13f9a295f89705d98c9c 100644 (file)
@@ -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;
                }
@@ -272,6 +275,17 @@ public class MemberImpl implements Member {
                                .equals(o.getDeclaringType()));
        }
 
+       /**
+        * @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.
index 1f82713e4f07158b9da3f8bab3a6c9e3f3082a75..93d1361a5cf83a9699b85e87b95c92011ddb0838 100644 (file)
@@ -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.
index 0b7f27c082f59cf63913db90f83a20146121550e..7e4932f9646d6e7d4b8fcad47b2f961564dff29d 100644 (file)
@@ -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(
index 2d31b597aad1c61ef0be80fa1f5f7848b8a846e2..0e0a89fceb328f00008cd7f1cfb93d1ea31c640f 100644 (file)
@@ -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");
        }