]> source.dussan.org Git - aspectj.git/commitdiff
299552: private ITD fields stay private in target (with unmangled name): all of it
authoraclement <aclement>
Fri, 22 Jan 2010 22:46:23 +0000 (22:46 +0000)
committeraclement <aclement>
Fri, 22 Jan 2010 22:46:23 +0000 (22:46 +0000)
13 files changed:
org.aspectj.matcher/src/org/aspectj/weaver/AbstractReferenceTypeDelegate.java
org.aspectj.matcher/src/org/aspectj/weaver/AjAttribute.java
org.aspectj.matcher/src/org/aspectj/weaver/AjcMemberMaker.java
org.aspectj.matcher/src/org/aspectj/weaver/CrosscuttingMembers.java
org.aspectj.matcher/src/org/aspectj/weaver/CrosscuttingMembersSet.java
org.aspectj.matcher/src/org/aspectj/weaver/ExposeTypeMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/NewFieldTypeMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/PrivilegedAccessMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/ReferenceType.java
org.aspectj.matcher/src/org/aspectj/weaver/ReferenceTypeDelegate.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedType.java
org.aspectj.matcher/src/org/aspectj/weaver/ResolvedTypeMunger.java
org.aspectj.matcher/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java

index 454771cc5a5827f030649af80ec224d6d8bdf1ea..6315570eef22d2182561d6fd558b8c6f91e63b70 100644 (file)
@@ -19,6 +19,7 @@ import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.util.GenericSignature;
 import org.aspectj.util.GenericSignatureParser;
 import org.aspectj.util.GenericSignature.ClassSignature;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 
 public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDelegate {
 
@@ -135,4 +136,8 @@ public abstract class AbstractReferenceTypeDelegate implements ReferenceTypeDele
                return true;
        }
 
+       public int getCompilerVersion() {
+               return WeaverVersionInfo.getCurrentWeaverMajorVersion();
+       }
+
 }
\ No newline at end of file
index af984174d3ea0508718de02031ab4a0015c3740e..a86f21b5c4c2152ecf903fb096c35509a415f71b 100644 (file)
@@ -246,14 +246,18 @@ public abstract class AjAttribute {
                public final static short WEAVER_VERSION_MINOR_AJ160 = 0;
 
                // These are the weaver major/minor numbers for AspectJ 1.6.1
-               public final static short WEAVER_VERSION_MAJOR_AJ161 = 6; // annotation
-               // value
-               // binding
+               // added annotation value binding
+               public final static short WEAVER_VERSION_MAJOR_AJ161 = 6;
                public final static short WEAVER_VERSION_MINOR_AJ161 = 0;
 
+               // 1.6.9 adds new style ITDs. This is used to see what version of AJ was used to
+               // build the ITDs so we know id the generated get/set dispatchers are using old
+               // or new style (new style will be get/setters for private ITD fields)
+               public final static short WEAVER_VERSION_AJ169 = 1609;
+
                // These are the weaver major/minor versions for *this* weaver
-               private final static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_MAJOR_AJ161;
-               private final static short CURRENT_VERSION_MINOR = WEAVER_VERSION_MINOR_AJ161;
+               private final static short CURRENT_VERSION_MAJOR = WEAVER_VERSION_AJ169;
+               private final static short CURRENT_VERSION_MINOR = 0;
 
                public final static WeaverVersionInfo UNKNOWN = new WeaverVersionInfo(WEAVER_VERSION_MAJOR_UNKNOWN,
                                WEAVER_VERSION_MINOR_UNKNOWN);
@@ -647,12 +651,8 @@ public abstract class AjAttribute {
        }
 
        public static class PrivilegedAttribute extends AjAttribute {
-               public static final String AttributeName = "org.aspectj.weaver.Privileged";
 
-               @Override
-               public String getNameString() {
-                       return AttributeName;
-               }
+               public static final String AttributeName = "org.aspectj.weaver.Privileged";
 
                private final ResolvedMember[] accessedMembers;
 
@@ -669,8 +669,14 @@ public abstract class AjAttribute {
                        return accessedMembers;
                }
 
-               public static PrivilegedAttribute read(VersionedDataInputStream s, ISourceContext context) throws IOException {
-                       return new PrivilegedAttribute(ResolvedMemberImpl.readResolvedMemberArray(s, context));
+               public static PrivilegedAttribute read(VersionedDataInputStream stream, ISourceContext context) throws IOException {
+                       PrivilegedAttribute pa = new PrivilegedAttribute(ResolvedMemberImpl.readResolvedMemberArray(stream, context));
+                       return pa;
+               }
+
+               @Override
+               public String getNameString() {
+                       return AttributeName;
                }
        }
 
index 5144b0992b542786ab6023a225580021e28e1a24..1e533918d83c7df9072a9cf0466fcd4e746a3208 100644 (file)
@@ -16,7 +16,12 @@ import java.lang.reflect.Modifier;
 
 //import org.aspectj.weaver.ResolvedType.Name;
 
+/**
+ * The AjcMemberMaker is responsible for creating the representations of methods/fields/etc that are placed in both aspects and
+ * affected target types. It uses the NameMangler class to create the actual names that will be used.
+ */
 public class AjcMemberMaker {
+
        private static final int PUBLIC_STATIC_FINAL = Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL;
 
        private static final int PRIVATE_STATIC = Modifier.PRIVATE | Modifier.STATIC;
@@ -28,6 +33,7 @@ public class AjcMemberMaker {
        private static final int VISIBILITY = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
 
        public static final UnresolvedType CFLOW_STACK_TYPE = UnresolvedType.forName(NameMangler.CFLOW_STACK_TYPE);
+
        public static final UnresolvedType AROUND_CLOSURE_TYPE = UnresolvedType
                        .forSignature("Lorg/aspectj/runtime/internal/AroundClosure;");
 
@@ -229,34 +235,77 @@ public class AjcMemberMaker {
 
        public static ResolvedMember privilegedAccessMethodForMethod(UnresolvedType aspectType, ResolvedMember method) {
                return new ResolvedMemberImpl(Member.METHOD, method.getDeclaringType(), Modifier.PUBLIC
-                               | (Modifier.isStatic(method.getModifiers()) ? Modifier.STATIC : 0), method.getReturnType(), NameMangler.privilegedAccessMethodForMethod(
-                               method.getName(), method.getDeclaringType(), aspectType), method.getParameterTypes(), method.getExceptions());
+                               | (Modifier.isStatic(method.getModifiers()) ? Modifier.STATIC : 0), method.getReturnType(), NameMangler
+                               .privilegedAccessMethodForMethod(method.getName(), method.getDeclaringType(), aspectType), method
+                               .getParameterTypes(), method.getExceptions());
        }
 
-       public static ResolvedMember privilegedAccessMethodForFieldGet(UnresolvedType aspectType, Member field) {
-               String sig;
-               if (Modifier.isStatic(field.getModifiers())) {
-                       sig = "()" + field.getReturnType().getSignature();
+       /**
+        * Return a resolvedmember representing the synthetic getter for the field. The old style (<1.6.9) is a heavyweight static
+        * method with a long name. The new style (1.6.9 and later) is short, and reusable across aspects.
+        * 
+        * @param aspectType the aspect attempting the access
+        * @param field the field to be accessed
+        * @param shortSyntax is the old (long) or new (short) style format being used
+        * @return a resolvedmember representing the synthetic getter
+        */
+       public static ResolvedMember privilegedAccessMethodForFieldGet(UnresolvedType aspectType, Member field, boolean shortSyntax) {
+               UnresolvedType fieldDeclaringType = field.getDeclaringType();
+               if (shortSyntax) {
+                       UnresolvedType[] args = null;
+                       if (Modifier.isStatic(field.getModifiers())) {
+                               args = ResolvedType.NONE;
+                       } else {
+                               args = new UnresolvedType[] { fieldDeclaringType };
+                       }
+                       StringBuffer name = new StringBuffer("ajc$get$");
+                       name.append(field.getName());
+                       return new ResolvedMemberImpl(Member.METHOD, fieldDeclaringType, PUBLIC_STATIC, field.getReturnType(), name.toString(),
+                                       args);
                } else {
-                       sig = "(" + field.getDeclaringType().getSignature() + ")" + field.getReturnType().getSignature();
+                       String getterName = NameMangler.privilegedAccessMethodForFieldGet(field.getName(), fieldDeclaringType, aspectType);
+                       String sig;
+                       if (Modifier.isStatic(field.getModifiers())) {
+                               sig = "()" + field.getReturnType().getSignature();
+                       } else {
+                               sig = "(" + fieldDeclaringType.getSignature() + ")" + field.getReturnType().getSignature();
+                       }
+                       return new ResolvedMemberImpl(Member.METHOD, fieldDeclaringType, PUBLIC_STATIC, getterName, sig);
                }
-
-               return new ResolvedMemberImpl(Member.METHOD, field.getDeclaringType(), PUBLIC_STATIC, // Modifier.PUBLIC | (field.isStatic()
-                               // ? Modifier.STATIC : 0),
-                               NameMangler.privilegedAccessMethodForFieldGet(field.getName(), field.getDeclaringType(), aspectType), sig);
        }
 
-       public static ResolvedMember privilegedAccessMethodForFieldSet(UnresolvedType aspectType, Member field) {
-               String sig;
-               if (Modifier.isStatic(field.getModifiers())) {
-                       sig = "(" + field.getReturnType().getSignature() + ")V";
+       /**
+        * Return a resolvedmember representing the synthetic setter for the field. The old style (<1.6.9) is a heavyweight static
+        * method with a long name. The new style (1.6.9 and later) is short, not always static, and reusable across aspects.
+        * 
+        * @param aspectType the aspect attempting the access
+        * @param field the field to be accessed
+        * @param shortSyntax is the old or new style format being used
+        * @return a resolvedmember representing the synthetic setter
+        */
+       public static ResolvedMember privilegedAccessMethodForFieldSet(UnresolvedType aspectType, Member field, boolean shortSyntax) {
+               UnresolvedType fieldDeclaringType = field.getDeclaringType();
+               if (shortSyntax) {
+                       UnresolvedType[] args = null;
+                       if (Modifier.isStatic(field.getModifiers())) {
+                               args = new UnresolvedType[] { field.getType() };
+                       } else {
+                               args = new UnresolvedType[] { fieldDeclaringType, field.getType() };
+                       }
+                       StringBuffer name = new StringBuffer("ajc$set$");
+                       name.append(field.getName());
+                       return new ResolvedMemberImpl(Member.METHOD, fieldDeclaringType, PUBLIC_STATIC, ResolvedType.VOID, name.toString(),
+                                       args);
                } else {
-                       sig = "(" + field.getDeclaringType().getSignature() + field.getReturnType().getSignature() + ")V";
+                       String setterName = NameMangler.privilegedAccessMethodForFieldSet(field.getName(), fieldDeclaringType, aspectType);
+                       String sig;
+                       if (Modifier.isStatic(field.getModifiers())) {
+                               sig = "(" + field.getReturnType().getSignature() + ")V";
+                       } else {
+                               sig = "(" + fieldDeclaringType.getSignature() + field.getReturnType().getSignature() + ")V";
+                       }
+                       return new ResolvedMemberImpl(Member.METHOD, fieldDeclaringType, PUBLIC_STATIC, setterName, sig);
                }
-
-               return new ResolvedMemberImpl(Member.METHOD, field.getDeclaringType(), PUBLIC_STATIC, // Modifier.PUBLIC | (field.isStatic()
-                               // ? Modifier.STATIC : 0),
-                               NameMangler.privilegedAccessMethodForFieldSet(field.getName(), field.getDeclaringType(), aspectType), sig);
        }
 
        // --- inline accessors
@@ -362,36 +411,39 @@ public class AjcMemberMaker {
                ResolvedMember ret = new ResolvedMemberImpl(Member.CONSTRUCTOR, targetType, Modifier.PUBLIC, ResolvedType.VOID, "<init>",
                                constructor.getParameterTypes(), constructor.getExceptions());
                // System.out.println("ret: " + ret + " mods: " + Modifier.toString(modifiers));
-               if (Modifier.isPublic(constructor.getModifiers()))
+               if (Modifier.isPublic(constructor.getModifiers())) {
                        return ret;
+               }
                while (true) {
                        ret = addCookieTo(ret, aspectType);
-                       if (targetType.lookupMemberNoSupers(ret) == null)
+                       if (targetType.lookupMemberNoSupers(ret) == null) {
                                return ret;
+                       }
                }
        }
 
        public static ResolvedMember interFieldInitializer(ResolvedMember field, UnresolvedType aspectType) {
                return new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, NameMangler.interFieldInitializer(aspectType, field
-                               .getDeclaringType(), field.getName()), Modifier.isStatic(field.getModifiers()) ? "()V" : "(" + field.getDeclaringType().getSignature()
-                               + ")V");
+                               .getDeclaringType(), field.getName()), Modifier.isStatic(field.getModifiers()) ? "()V" : "("
+                               + field.getDeclaringType().getSignature() + ")V");
        }
 
-       /**
-        * Makes public and non-final
-        */
        private static int makePublicNonFinal(int modifiers) {
                return (modifiers & ~VISIBILITY & ~Modifier.FINAL) | Modifier.PUBLIC;
        }
 
+       private static int makeNonFinal(int modifiers) {
+               return (modifiers & ~Modifier.FINAL);
+       }
+
        /**
         * This static method goes on the aspect that declares the inter-type field
         */
        public static ResolvedMember interFieldSetDispatcher(ResolvedMember field, UnresolvedType aspectType) {
                ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, ResolvedType.VOID, NameMangler
-                               .interFieldSetDispatcher(aspectType, field.getDeclaringType(), field.getName()),
-                               Modifier.isStatic(field.getModifiers()) ? new UnresolvedType[] { field.getReturnType() } : new UnresolvedType[] {
-                                               field.getDeclaringType(), field.getReturnType() });
+                               .interFieldSetDispatcher(aspectType, field.getDeclaringType(), field.getName()), Modifier.isStatic(field
+                               .getModifiers()) ? new UnresolvedType[] { field.getReturnType() } : new UnresolvedType[] {
+                               field.getDeclaringType(), field.getReturnType() });
                rm.setTypeVariables(field.getTypeVariables());
                return rm;
        }
@@ -401,8 +453,8 @@ public class AjcMemberMaker {
         */
        public static ResolvedMember interFieldGetDispatcher(ResolvedMember field, UnresolvedType aspectType) {
                ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, aspectType, PUBLIC_STATIC, field.getReturnType(), NameMangler
-                               .interFieldGetDispatcher(aspectType, field.getDeclaringType(), field.getName()),
-                               Modifier.isStatic(field.getModifiers()) ? UnresolvedType.NONE : new UnresolvedType[] { field.getDeclaringType() }, UnresolvedType.NONE);
+                               .interFieldGetDispatcher(aspectType, field.getDeclaringType(), field.getName()), Modifier.isStatic(field
+                               .getModifiers()) ? UnresolvedType.NONE : new UnresolvedType[] { field.getDeclaringType() }, UnresolvedType.NONE);
                rm.setTypeVariables(field.getTypeVariables());
                return rm;
        }
@@ -415,12 +467,18 @@ public class AjcMemberMaker {
        // }
 
        /**
-        * This field goes on the class the field is declared onto
+        * This field goes on the class the field is declared onto. Field names for ITDs onto interfaces are handled below.
         */
-       public static ResolvedMember interFieldClassField(ResolvedMember field, UnresolvedType aspectType) {
-               return new ResolvedMemberImpl(Member.FIELD, field.getDeclaringType(), makePublicNonFinal(field.getModifiers()), field
-                               .getReturnType(), NameMangler.interFieldClassField(field.getModifiers(), aspectType, field.getDeclaringType(),
-                               field.getName()), UnresolvedType.NONE, UnresolvedType.NONE);
+       public static ResolvedMember interFieldClassField(ResolvedMember field, UnresolvedType aspectType, boolean newStyle) {
+               int modifiers = (newStyle ? makeNonFinal(field.getModifiers()) : makePublicNonFinal(field.getModifiers()));
+               String name = null;
+               if (newStyle) {
+                       name = field.getName();
+               } else {
+                       name = NameMangler.interFieldClassField(field.getModifiers(), aspectType, field.getDeclaringType(), field.getName());
+               }
+               return new ResolvedMemberImpl(Member.FIELD, field.getDeclaringType(), modifiers, field.getReturnType(), name,
+                               UnresolvedType.NONE, UnresolvedType.NONE);
        }
 
        /**
@@ -437,8 +495,9 @@ public class AjcMemberMaker {
         */
        public static ResolvedMember interFieldInterfaceSetter(ResolvedMember field, ResolvedType onType, UnresolvedType aspectType) {
                int modifiers = Modifier.PUBLIC;
-               if (onType.isInterface())
+               if (onType.isInterface()) {
                        modifiers |= Modifier.ABSTRACT;
+               }
                ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, onType, modifiers, ResolvedType.VOID, NameMangler
                                .interFieldInterfaceSetter(aspectType, field.getDeclaringType(), field.getName()), new UnresolvedType[] { field
                                .getReturnType() }, UnresolvedType.NONE);
@@ -451,8 +510,9 @@ public class AjcMemberMaker {
         */
        public static ResolvedMember interFieldInterfaceGetter(ResolvedMember field, ResolvedType onType, UnresolvedType aspectType) {
                int modifiers = Modifier.PUBLIC;
-               if (onType.isInterface())
+               if (onType.isInterface()) {
                        modifiers |= Modifier.ABSTRACT;
+               }
                ResolvedMember rm = new ResolvedMemberImpl(Member.METHOD, onType, modifiers, field.getReturnType(), NameMangler
                                .interFieldInterfaceGetter(aspectType, field.getDeclaringType(), field.getName()), UnresolvedType.NONE,
                                UnresolvedType.NONE);
@@ -465,12 +525,14 @@ public class AjcMemberMaker {
         * an interface). The implementation will call the interMethodDispatch method on the aspect.
         */
        public static ResolvedMember interMethod(ResolvedMember meth, UnresolvedType aspectType, boolean onInterface) {
-               if (Modifier.isPublic(meth.getModifiers()) && !onInterface)
+               if (Modifier.isPublic(meth.getModifiers()) && !onInterface) {
                        return meth;
+               }
 
                int modifiers = makePublicNonFinal(meth.getModifiers());
-               if (onInterface)
+               if (onInterface) {
                        modifiers |= Modifier.ABSTRACT;
+               }
 
                ResolvedMemberImpl rmi = new ResolvedMemberImpl(Member.METHOD, meth.getDeclaringType(), modifiers, meth.getReturnType(),
                                NameMangler.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()), meth
@@ -489,8 +551,9 @@ public class AjcMemberMaker {
                // return meth;
 
                int modifiers = makePublicNonFinal(meth.getModifiers()) | BRIDGE;
-               if (onInterface)
+               if (onInterface) {
                        modifiers |= Modifier.ABSTRACT;
+               }
 
                ResolvedMemberImpl rmi = new ResolvedMemberImpl(Member.METHOD, meth.getDeclaringType(), modifiers, meth.getReturnType(),
                                NameMangler.interMethod(meth.getModifiers(), aspectType, meth.getDeclaringType(), meth.getName()), meth
@@ -576,8 +639,9 @@ public class AjcMemberMaker {
        public static Member interfaceConstructor(ResolvedType resolvedTypeX) {
                // AMC next two lines should not be needed when sig for generic type is changed
                ResolvedType declaringType = resolvedTypeX;
-               if (declaringType.isRawType())
+               if (declaringType.isRawType()) {
                        declaringType = declaringType.getGenericType();
+               }
                return new ResolvedMemberImpl(Member.CONSTRUCTOR, declaringType, Modifier.PUBLIC, "<init>", "()V");
        }
 
index 3ff22daa01af318532817186f7fe68f15aa77c6b..14de71e79e6cea577cd8ab710f8c0b3a14e52b73 100644 (file)
@@ -20,6 +20,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 import org.aspectj.weaver.patterns.Declare;
 import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
@@ -198,8 +199,12 @@ public class CrosscuttingMembers {
        }
 
        public void addPrivilegedAccesses(Collection<ResolvedMember> accessedMembers) {
+               int version = inAspect.getCompilerVersion();
                for (ResolvedMember member : accessedMembers) {
-                       addTypeMunger(world.getWeavingSupport().concreteTypeMunger(new PrivilegedAccessMunger(member), inAspect));
+                       PrivilegedAccessMunger privilegedAccessMunger = new PrivilegedAccessMunger(member,
+                                       version >= WeaverVersionInfo.WEAVER_VERSION_AJ169);
+                       ConcreteTypeMunger concreteTypeMunger = world.getWeavingSupport().concreteTypeMunger(privilegedAccessMunger, inAspect);
+                       addTypeMunger(concreteTypeMunger);
                }
        }
 
index aef04dd9883f19ba3a7b385b8266a81213934794..d81ef0b2caefca1c68ce7ff83ccc9a547a7e9fb5 100644 (file)
@@ -175,14 +175,57 @@ public class CrosscuttingMembersSet {
        public List<ConcreteTypeMunger> getTypeMungers() {
                if (typeMungers == null) {
                        List<ConcreteTypeMunger> ret = new ArrayList<ConcreteTypeMunger>();
-                       for (Iterator<CrosscuttingMembers> i = members.values().iterator(); i.hasNext();) {
-                               ret.addAll(i.next().getTypeMungers());
+                       for (CrosscuttingMembers xmembers : members.values()) {
+                               // With 1.6.9 there is a change that enables use of more optimal accessors (accessors for private fields).
+                               // Here is where we determine if two aspects are asking for access to the same field. If they are
+                               // and
+                               // In the new style multiple aspects can share the same privileged accessors, so here we check if
+                               // two aspects are asking for access to the same field. If they are then we don't add a duplicate
+                               // accessor.
+                               for (ConcreteTypeMunger mungerToAdd : xmembers.getTypeMungers()) {
+                                       ResolvedTypeMunger resolvedMungerToAdd = mungerToAdd.getMunger();
+                                       if (isNewStylePrivilegedAccessMunger(resolvedMungerToAdd)) {
+                                               String newFieldName = resolvedMungerToAdd.getSignature().getName();
+                                               boolean alreadyExists = false;
+                                               for (ConcreteTypeMunger existingMunger : ret) {
+                                                       ResolvedTypeMunger existing = existingMunger.getMunger();
+                                                       if (isNewStylePrivilegedAccessMunger(existing)) {
+                                                               String existingFieldName = existing.getSignature().getName();
+                                                               if (existingFieldName.equals(newFieldName)
+                                                                               && existing.getSignature().getDeclaringType().equals(
+                                                                                               resolvedMungerToAdd.getSignature().getDeclaringType())) {
+                                                                       alreadyExists = true;
+                                                                       break;
+                                                               }
+                                                       }
+                                               }
+                                               if (!alreadyExists) {
+                                                       ret.add(mungerToAdd);
+                                               }
+                                       } else {
+                                               ret.add(mungerToAdd);
+                                       }
+                               }
                        }
                        typeMungers = ret;
                }
                return typeMungers;
        }
 
+       /**
+        * Determine if the type munger is: (1) for privileged access (2) for a normally non visible field (3) is from an aspect wanting
+        * 'old style' (ie. long) accessor names
+        */
+       private boolean isNewStylePrivilegedAccessMunger(ResolvedTypeMunger typeMunger) {
+               boolean b = (typeMunger != null && typeMunger.getKind() == ResolvedTypeMunger.PrivilegedAccess && typeMunger.getSignature()
+                               .getKind() == Member.FIELD);
+               if (!b) {
+                       return b;
+               }
+               PrivilegedAccessMunger privAccessMunger = (PrivilegedAccessMunger) typeMunger;
+               return privAccessMunger.shortSyntax;
+       }
+
        public List<ConcreteTypeMunger> getLateTypeMungers() {
                if (lateTypeMungers == null) {
                        List<ConcreteTypeMunger> ret = new ArrayList<ConcreteTypeMunger>();
index 9a90c139dd5a5c99e54b754d02ec40d554783e7a..2f24097446c2358915d8295ebe1636bdc689aa71 100644 (file)
@@ -18,7 +18,7 @@ public class ExposeTypeMunger extends PrivilegedAccessMunger {
 
        public ExposeTypeMunger(UnresolvedType typeToExpose) {
                super(new ResolvedMemberImpl(Member.STATIC_INITIALIZATION, typeToExpose, 0, ResolvedType.VOID, "<clinit>",
-                               UnresolvedType.NONE));
+                               UnresolvedType.NONE), false);
        }
 
        public String toString() {
index ba7bad239fa8693ec6d59cbda4d74de3c244324a..8427ca74b085994a840d1a698ab0dee46da87461 100644 (file)
@@ -19,11 +19,24 @@ import java.util.Map;
 import java.util.Set;
 
 import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 
+/**
+ * Code that created version one style ITD type mungers will be using direct field access from the dispatchers
+ * 
+ * @author Andy
+ * 
+ */
 public class NewFieldTypeMunger extends ResolvedTypeMunger {
 
+       public static final int VersionOne = 1;
+       public static final int VersionTwo = 2; // new style ITDs
+
+       public int version = VersionOne;
+
        public NewFieldTypeMunger(ResolvedMember signature, Set superMethodsCalled, List typeVariableAliases) {
                super(Field, signature);
+               this.version = VersionTwo;
                this.typeVariableAliases = typeVariableAliases;
                signature.setAnnotatedElsewhere(true);
                this.setSuperMethodsCalled(superMethodsCalled);
@@ -39,6 +52,7 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger {
                writeSuperMethodsCalled(s);
                writeSourceLocation(s);
                writeOutTypeAliases(s);
+               s.writeInt(version);
        }
 
        public static ResolvedTypeMunger readField(VersionedDataInputStream s, ISourceContext context) throws IOException {
@@ -47,9 +61,15 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger {
                Set superMethodsCalled = readSuperMethodsCalled(s);
                sloc = readSourceLocation(s);
                List aliases = readInTypeAliases(s);
-               ResolvedTypeMunger munger = new NewFieldTypeMunger(fieldSignature, superMethodsCalled, aliases);
+               NewFieldTypeMunger munger = new NewFieldTypeMunger(fieldSignature, superMethodsCalled, aliases);
                if (sloc != null)
                        munger.setSourceLocation(sloc);
+               if (s.getMajorVersion() >= WeaverVersionInfo.WEAVER_VERSION_AJ169) {
+                       // there is a version int
+                       munger.version = s.readInt();
+               } else {
+                       munger.version = VersionOne;
+               }
                return munger;
        }
 
index e08798613fc1c98ae297503f6a840be7d38ec7bf..5083a304bc19f61881dc80852af5f033eaf79cab 100644 (file)
@@ -15,13 +15,26 @@ package org.aspectj.weaver;
 import java.io.DataOutputStream;
 import java.io.IOException;
 
+/**
+ * A privileged access munger is for handling privileged access to a member. It determines the names of the getter/setter that will
+ * be used to access a private field in some type, or the special method that provides access to a private method.
+ * 
+ * There are two syntax styles for field access, the older style was in use up to AspectJ 1.6.9 and involves long named getters and
+ * setters which include the requesting aspect and the target type. The short style syntax is use from AspectJ 1.6.9 onwards is
+ * simply 'ajc$get$<fieldname>' and 'ajc$set$<fieldname>' - as the requesting aspect isn't included in the name they can be shared
+ * across aspects.
+ */
 public class PrivilegedAccessMunger extends ResolvedTypeMunger {
-       public PrivilegedAccessMunger(ResolvedMember member) {
+
+       public boolean shortSyntax = false;
+
+       public PrivilegedAccessMunger(ResolvedMember member, boolean shortSyntax) {
                super(PrivilegedAccess, member);
+               this.shortSyntax = shortSyntax;
        }
 
        public void write(DataOutputStream s) throws IOException {
-               throw new RuntimeException("shouldn't be serialized");
+               throw new RuntimeException("should not be serialized");
        }
 
        public ResolvedMember getMember() {
@@ -30,11 +43,12 @@ public class PrivilegedAccessMunger extends ResolvedTypeMunger {
 
        public ResolvedMember getMatchingSyntheticMember(Member member, ResolvedType aspectType) {
                ResolvedMember ret;
+               // assert if shortSyntax then aspectType.getCompilerVersion()>=169
                if (getSignature().getKind() == Member.FIELD) {
-                       ret = AjcMemberMaker.privilegedAccessMethodForFieldGet(aspectType, getSignature());
+                       ret = AjcMemberMaker.privilegedAccessMethodForFieldGet(aspectType, getSignature(), shortSyntax);
                        if (ResolvedType.matches(ret, member))
                                return getSignature();
-                       ret = AjcMemberMaker.privilegedAccessMethodForFieldSet(aspectType, getSignature());
+                       ret = AjcMemberMaker.privilegedAccessMethodForFieldSet(aspectType, getSignature(), shortSyntax);
                        if (ResolvedType.matches(ret, member))
                                return getSignature();
                } else {
index 7990566f2e221231dc21092e6c21dd8ea7154b74..065c11b6fe1b68e7afa159aca7376cd4cc2290af 100644 (file)
@@ -135,6 +135,11 @@ public class ReferenceType extends ResolvedType {
                return delegate.isClass();
        }
 
+       @Override
+       public int getCompilerVersion() {
+               return delegate.getCompilerVersion();
+       }
+
        @Override
        public boolean isGenericType() {
                return !isParameterizedType() && !isRawType() && delegate.isGeneric();
index d16e0b364a0ad12bd3b37aab2bcb8a6d87642b2d..1e5c092559f5425dbe85847e3380c05fff5010ae 100644 (file)
@@ -14,6 +14,7 @@ package org.aspectj.weaver;
 
 import java.util.Collection;
 
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 import org.aspectj.weaver.patterns.Declare;
 import org.aspectj.weaver.patterns.PerClause;
 
@@ -122,4 +123,12 @@ public interface ReferenceTypeDelegate {
         */
        public boolean isCacheable();
 
+       /**
+        * If known, return the compiler/weaver version used to build this delegate. Default is the most recent level as specified in
+        * {@link WeaverVersionInfo}.
+        * 
+        * @return the major version
+        */
+       public int getCompilerVersion();
+
 }
\ No newline at end of file
index 4672f7bd7bc87d250fbf94abb4cd99a8dc47c088..0b7f27c082f59cf63913db90f83a20146121550e 100644 (file)
@@ -32,6 +32,7 @@ import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.Message;
 import org.aspectj.bridge.MessageUtil;
 import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 import org.aspectj.weaver.Iterators.Getter;
 import org.aspectj.weaver.patterns.Declare;
 import org.aspectj.weaver.patterns.PerClause;
@@ -1672,7 +1673,12 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                return munger;
        }
 
-       public void addInterTypeMunger(ConcreteTypeMunger munger) {
+       /**
+        * Add an intertype munger to this type. isDuringCompilation tells us if we should be checking for an error scenario where two
+        * ITD fields are trying to use the same name. When this happens during compilation one of them is altered to get mangled name
+        * but when it happens during weaving it is too late and we need to put out an error asking them to recompile.
+        */
+       public void addInterTypeMunger(ConcreteTypeMunger munger, boolean isDuringCompilation) {
                ResolvedMember sig = munger.getSignature();
                bits = (bits & ~MungersAnalyzed); // clear the bit - as the mungers have changed
                if (sig == null || munger.getMunger() == null || munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) {
@@ -1706,6 +1712,44 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                        if (clashesWithExistingMember(munger, Arrays.asList(getDeclaredFields()).iterator())) {
                                return;
                        }
+                       // Cannot cope with two version '2' style mungers for the same field on the same type
+                       // Must error and request the user recompile at least one aspect with the
+                       // -Xset:itdStyle=1 option
+                       if (!isDuringCompilation) {
+                               ResolvedTypeMunger thisRealMunger = munger.getMunger();
+                               if (thisRealMunger instanceof NewFieldTypeMunger) {
+                                       NewFieldTypeMunger newFieldTypeMunger = (NewFieldTypeMunger) thisRealMunger;
+                                       if (newFieldTypeMunger.version == NewFieldTypeMunger.VersionTwo) {
+                                               String thisRealMungerSignatureName = newFieldTypeMunger.getSignature().getName();
+                                               for (ConcreteTypeMunger typeMunger : interTypeMungers) {
+                                                       if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
+                                                               if (typeMunger.getSignature().getKind() == Member.FIELD) {
+                                                                       NewFieldTypeMunger existing = (NewFieldTypeMunger) typeMunger.getMunger();
+                                                                       if (existing.getSignature().getName().equals(thisRealMungerSignatureName)
+                                                                                       && existing.version == NewFieldTypeMunger.VersionTwo
+                                                                                       // this check ensures no problem for a clash with an ITD on an interface
+                                                                                       && existing.getSignature().getDeclaringType().equals(
+                                                                                                       newFieldTypeMunger.getSignature().getDeclaringType())) {
+
+                                                                               // report error on the aspect
+                                                                               StringBuffer sb = new StringBuffer();
+                                                                               sb
+                                                                                               .append("Cannot handle two aspects both attempting to use new style ITDs for the same named field ");
+                                                                               sb
+                                                                                               .append("on the same target type.  Please recompile at least one aspect with '-Xset:itdVersion=1'.");
+                                                                               sb.append(" Aspects involved: " + munger.getAspectType().getName() + " and "
+                                                                                               + typeMunger.getAspectType().getName() + ".");
+                                                                               sb.append(" Field is named '" + existing.getSignature().getName() + "'");
+                                                                               getWorld().getMessageHandler().handleMessage(
+                                                                                               new Message(sb.toString(), getSourceLocation(), true));
+                                                                               return;
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
                } else {
                        if (clashesWithExistingMember(munger, Arrays.asList(getDeclaredMethods()).iterator())) {
                                return;
@@ -2181,8 +2225,8 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                public ResolvedType next() {
                        ResolvedType next = delegate.next();
                        // BUG should check for generics and erase?
-//                     if (!visited.contains(next)) {
-//                             visited.add(next);
+                       // if (!visited.contains(next)) {
+                       // visited.add(next);
                        if (visited.add(next)) {
                                toPersue.add(next); // pushes on interfaces already visited?
                        }
@@ -2690,4 +2734,12 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                return (bits & TypeHierarchyCompleteBit) != 0;
        }
 
+       /**
+        * return the weaver version used to build this type - defaults to the most recent version unless discovered otherwise.
+        * 
+        * @return the (major) version, {@link WeaverVersionInfo}
+        */
+       public int getCompilerVersion() {
+               return WeaverVersionInfo.getCurrentWeaverMajorVersion();
+       }
 }
index 20a5bbe29431fe6af317c8fcd231f05ca57d7c49..1c2cd4ca2f9c81b338589d28f3a04b375c0f3b7c 100644 (file)
@@ -36,6 +36,7 @@ import org.aspectj.util.TypeSafeEnum;
  * is the thing that is used on the eclipse side and serialized into a ConcreteTypeMunger.
  */
 public abstract class ResolvedTypeMunger {
+
        protected Kind kind;
        protected ResolvedMember signature;
 
index 16bf0c59bc8026be6414592161f8c8d59826ffef..cb2a497a8aebfc06cccec413b44d425fad4d265f 100644 (file)
@@ -33,6 +33,7 @@ import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeakClassLoaderReference;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 import org.aspectj.weaver.patterns.PerClause;
 
 /**
@@ -404,4 +405,8 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
        public boolean copySourceContext() {
                return true;
        }
+
+       public int getCompilerVersion() {
+               return WeaverVersionInfo.getCurrentWeaverMajorVersion();
+       }
 }