]> source.dussan.org Git - aspectj.git/commitdiff
big refactoring
authoraclement <aclement>
Fri, 9 May 2008 16:02:03 +0000 (16:02 +0000)
committeraclement <aclement>
Fri, 9 May 2008 16:02:03 +0000 (16:02 +0000)
111 files changed:
weaver/rewrite.txt [new file with mode: 0644]
weaver/src/org/aspectj/weaver/AdviceKind.java
weaver/src/org/aspectj/weaver/AjAttribute.java
weaver/src/org/aspectj/weaver/AjcMemberMaker.java
weaver/src/org/aspectj/weaver/AnnotatedElement.java
weaver/src/org/aspectj/weaver/AnnotationAJ.java
weaver/src/org/aspectj/weaver/AnnotationX.java
weaver/src/org/aspectj/weaver/ArrayReferenceType.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/AsmRelationshipProvider.java
weaver/src/org/aspectj/weaver/BetaException.java [deleted file]
weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java
weaver/src/org/aspectj/weaver/CrosscuttingMembers.java
weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java
weaver/src/org/aspectj/weaver/CustomMungerFactory.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/JoinPointSignature.java
weaver/src/org/aspectj/weaver/Lint.java
weaver/src/org/aspectj/weaver/Member.java
weaver/src/org/aspectj/weaver/MemberImpl.java
weaver/src/org/aspectj/weaver/MemberKind.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/NameMangler.java
weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java
weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java
weaver/src/org/aspectj/weaver/ReferenceType.java
weaver/src/org/aspectj/weaver/ReferenceTypeDelegate.java
weaver/src/org/aspectj/weaver/ResolvedMember.java
weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java
weaver/src/org/aspectj/weaver/ResolvedType.java
weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java
weaver/src/org/aspectj/weaver/Shadow.java
weaver/src/org/aspectj/weaver/ShadowMunger.java
weaver/src/org/aspectj/weaver/TypeFactory.java
weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java
weaver/src/org/aspectj/weaver/UnresolvedType.java
weaver/src/org/aspectj/weaver/WeaverMessages.java
weaver/src/org/aspectj/weaver/WeaverMetrics.java [deleted file]
weaver/src/org/aspectj/weaver/WeaverStateInfo.java
weaver/src/org/aspectj/weaver/World.java
weaver/src/org/aspectj/weaver/XlintDefault.properties
weaver/src/org/aspectj/weaver/ast/Not.java
weaver/src/org/aspectj/weaver/ast/Var.java
weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java
weaver/src/org/aspectj/weaver/bcel/BcelAccessForInlineMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
weaver/src/org/aspectj/weaver/bcel/BcelAttributes.java
weaver/src/org/aspectj/weaver/bcel/BcelCflowCounterFieldAdder.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelField.java
weaver/src/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelWorld.java
weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java [deleted file]
weaver/src/org/aspectj/weaver/bcel/LazyClassGen.java
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
weaver/src/org/aspectj/weaver/bcel/UnwovenClassFile.java
weaver/src/org/aspectj/weaver/bcel/UnwovenClassFileWithThirdPartyManagedBytecode.java
weaver/src/org/aspectj/weaver/bcel/Utility.java
weaver/src/org/aspectj/weaver/bcel/ZipFileWeaver.java [deleted file]
weaver/src/org/aspectj/weaver/loadtime/IWeavingContext.java
weaver/src/org/aspectj/weaver/ltw/LTWWorld.java
weaver/src/org/aspectj/weaver/ltw/LTWeaver.java [deleted file]
weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/AnyAnnotationTypePattern.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java
weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java
weaver/src/org/aspectj/weaver/patterns/BindingAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java
weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java
weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java
weaver/src/org/aspectj/weaver/patterns/PatternParser.java
weaver/src/org/aspectj/weaver/patterns/PointcutRewriter.java
weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java
weaver/src/org/aspectj/weaver/patterns/TypePattern.java
weaver/src/org/aspectj/weaver/patterns/TypePatternList.java
weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java
weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
weaver/src/org/aspectj/weaver/raw types.txt [deleted file]
weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java
weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java
weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java
weaver/src/org/aspectj/weaver/tools/CommonsTraceFactory.java
weaver/src/org/aspectj/weaver/tools/FuzzyBoolean.java
weaver/src/org/aspectj/weaver/tools/PointcutParser.java
weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java
weaver/src/org/aspectj/weaver/tools/package.html [deleted file]
weaver/src/org/aspectj/weaver/weaver-messages.properties
weaver/testsrc/org/aspectj/weaver/MemberTestCase.java
weaver/testsrc/org/aspectj/weaver/TestUtils.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java
weaver/testsrc/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java
weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java
weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java
weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java
weaver/testsrc/org/aspectj/weaver/bcel/ZipFileWeaver.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java [new file with mode: 0644]
weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/VisitorTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java
weaver/testsrc/org/aspectj/weaver/tools/PointcutDesignatorHandlerTests.java

diff --git a/weaver/rewrite.txt b/weaver/rewrite.txt
new file mode 100644 (file)
index 0000000..dc3c8af
--- /dev/null
@@ -0,0 +1,87 @@
+Rewritten...
+
+[bcel] hundreds of classes removed, one class now represents groups of instructions rather than one class per instruction
+[bcel] verifier packaged separately purely for use by AspectJ tests, not delivered in aspectj packages now
+[weaver] optimized KindedAnnotationAccessVar - renamed to AnnotationAccessVar
+[weaver] simplified member/resolvedmember hierarchy - still more to do, trying to remove need for casts, we should *know* what we
+         are dealing with at each point
+
+todo:
+
+[weaver] 
+[bcel] remove notion of Gens entirely (LineNumberGen/LocalVariableGen) and switch fully to lighter way tags
+[weaver] activate 'assertGoodBody()' code through command line option to catch bugs in the field
+[weaver] is reweavable turned off when LTW?
+
+measure performance - lot of hash table things used to keep types lightweight unless they need the extra data - might be a better way?
+OPTIMIZE task tag marks places noticed on the way through where we could do better
+
+hierarchies to attack:
+ASTNode
+UnresolvedType (messy...)
+Member
+
+
+28th April
+Looking at LazyMethodGen.pack()  - 12% of the cpu usage for what we are testing.  pack() is quite tricky to make better, wonder if we 
+can differentiate amongst targeters to speed things up?  Also instructionHandle has 'attributes' - for no good reason that I can see
+
+Removed static in BranchHandle...
+
+
+Performance analysis, following: http://java.sun.com/developer/technicalArticles/Programming/perfanal/
+
+
+Reveals of     5415 ticks (weaving rt.jar), we spend 25% of the time in WeaverAdapter.removeFromMap() !
+- changed that code to a CharOpt comparison
+- further changed to null 'lastReturnedResult' when it is finished with, should reduce ongoing calls
+- want to removeFromMap() quickly if we can.  we can't usually because we have rebuilt the char array because
+  post weave we build a new UnwovenClassFile() - I've changed the code to copy across the charname which
+  means we can do remove() rather than searching all keys because the char array is the same one as what was
+  used for the key when it was put in.
+  
+  knocks 25seconds (was 1 minute, now 35s) off the weave time
+
+--- Deliverable sizes: aspectjweaver.jar
+
+1.6.0 = 1,907,848 bytes:1094 classes
+26Apr = 1,718,083:893
+26Apr = 1,618,024:849 (verifier removed from delivered package)
+27Apr = 1,612,996:848
+
+
+----------------
+Finally have a loadtime weaving test
+
+see - d:\e312\eclipse\plugins
+ltwToolsProto.bat
+
+of the 20seconds it takes for 1925 classes, 1.81% is:
+
+org.aspectj.weaver.tools.WeavingAdaptor.weaveClass: 57.5% (1142 inclusive / 0 exclusive)
+org.aspectj.weaver.tools.WeavingAdaptor.getWovenBytes: 49.14% (976 inclusive / 0 exclusive)
+org.aspectj.weaver.bcel.BcelWeaver.weave: 48.94% (972 inclusive / 11 exclusive)
+org.aspectj.weaver.bcel.BcelWeaver.weaveAndNotify: 45.37% (901 inclusive / 0 exclusive)
+org.aspectj.weaver.bcel.BcelWeaver.getClassFilesFor: 22% (437 inclusive / 0 exclusive)
+org.aspectj.weaver.bcel.LazyClassGen.getJavaClassBytesIncludingReweavable: 22% (437 inclusive / 0 exclusive)
+org.aspectj.weaver.bcel.LazyClassGen.writeBack: 17.88% (355 inclusive / 4 exclusive)
+org.aspectj.weaver.bcel.LazyMethodGen.getMethod: 17.42% (346 inclusive / 0 exclusive)
+org.aspectj.weaver.bcel.LazyMethodGen.pack: 13.09% (260 inclusive / 3 exclusive)
+org.aspectj.weaver.bcel.LazyMethodGen.newPackBody: 8.36% (166 inclusive / 81 exclusive)
+org.aspectj.apache.bcel.generic.InstructionList.delete: 1.31% (26 inclusive / 1 exclusive)
+
+
+29Apr
+now the extra bytecode parse in UnwovenClassFile - can we get rid of it by using the ctor that supplies a classname?
+
+
+2may
+looked at the analysis and getSourceLocation() was being called a lot - wasn't sure why given I didn't use tjp in the advice - turns
+out a dummy xrefhandler is added in LTWWorld, and so all the guards to avoid doing anything if there is no xrefhandler are worthless.
+fixed.
+
+ noticed ClassParser ctor messing about remembering if the source is a zip and wrapping a baos in a bufferedinputstream - added new
+ ctor to avoid that and removed the zip nonsense
+2May = 1,588,317:841 but fails tests, buggerit
+
index dd2ebd174bfd45fa6e8ca46aa1c64c6ddea0fe4e..0c10bf77314507ac711d44eac017dd2969d2b131 100644 (file)
@@ -10,7 +10,6 @@
  *     PARC     initial implementation 
  * ******************************************************************/
 
-
 package org.aspectj.weaver;
 
 import java.io.IOException;
@@ -18,15 +17,17 @@ import java.io.IOException;
 import org.aspectj.util.TypeSafeEnum;
 
 /**
- * The 5 kinds of advice in AspectJ.
+ * The five kinds of advice in AspectJ.
  * 
  * @author Erik Hilsdale
  * @author Jim Hugunin
  */
 public class AdviceKind extends TypeSafeEnum {
+       
        private int precedence;
        private boolean isAfter;
        private boolean isCflow;
+       
     public AdviceKind(String name, int key, int precedence, boolean isAfter, boolean isCflow) {
        super(name, key);
        this.precedence = precedence;
@@ -114,4 +115,4 @@ public class AdviceKind extends TypeSafeEnum {
                return this == PerThisEntry || this == PerTargetEntry;
        }
 
-}
+}
\ No newline at end of file
index dd3fd932f99a32d6f1b58adfa7d4696f3f67e0ef..aa0f84244d62b9be07f525297fede9f699cc40f3 100644 (file)
@@ -215,10 +215,16 @@ public abstract class AjAttribute {
                public static short WEAVER_VERSION_MAJOR_AJ150M4 = 3; 
                public static short WEAVER_VERSION_MAJOR_AJ150 = 2;
                public static short WEAVER_VERSION_MINOR_AJ150 = 0;
+
+               // These are the weaver major/minor numbers for AspectJ 1.6.0
+               public static short WEAVER_VERSION_MAJOR_AJ160M2 = 5;
+               public static short WEAVER_VERSION_MAJOR_AJ160 = 4;
+               public static short WEAVER_VERSION_MINOR_AJ160 = 0;
+
                
                // These are the weaver major/minor versions for *this* weaver
-               private static short CURRENT_VERSION_MAJOR      = WEAVER_VERSION_MAJOR_AJ150M4;
-               private static short CURRENT_VERSION_MINOR      = WEAVER_VERSION_MINOR_AJ150;
+               private static short CURRENT_VERSION_MAJOR      = WEAVER_VERSION_MAJOR_AJ160M2;
+               private static short CURRENT_VERSION_MINOR      = WEAVER_VERSION_MINOR_AJ160;
                
                public static final WeaverVersionInfo UNKNOWN = 
                        new WeaverVersionInfo(WEAVER_VERSION_MAJOR_UNKNOWN,WEAVER_VERSION_MINOR_UNKNOWN);
index 8ca2c511b7939f9509b6ad1acbb7b6a677ad5ac5..cd1eb769b06c206c20b10d8806aa7d18ade37c52 100644 (file)
@@ -252,9 +252,7 @@ public class AjcMemberMaker {
 
        
        public static ResolvedMember perSingletonAspectOfMethod(UnresolvedType declaringType) {
-               return new ResolvedMemberImpl(Member.METHOD,
-                       declaringType, PUBLIC_STATIC, "aspectOf", 
-                       "()" + declaringType.getSignature());           
+               return new ResolvedMemberImpl(Member.METHOD, declaringType, PUBLIC_STATIC, "aspectOf", "()" + declaringType.getSignature());
        }
        
        public static ResolvedMember perSingletonHasAspectMethod(UnresolvedType declaringType) {
index 9c2c54aa4b83e22223923f51fb365edc1740673b..bb65e36f696b8490ea4ade865c2d0790bb657a62 100644 (file)
@@ -16,5 +16,6 @@ public interface AnnotatedElement {
        boolean hasAnnotation(UnresolvedType ofType);
        
        ResolvedType[] getAnnotationTypes();
-       // SomeType getAnnotation(UnresolvedType ofType);
+       
+       AnnotationX getAnnotationOfType(UnresolvedType ofType);
 }
index 58fce499205969468321c5157c125e2281388d84..ceb11cf258f21216b88271f37d306a7e0e361a81 100644 (file)
@@ -95,4 +95,27 @@ public class AnnotationAJ {
                sb.append("]");
                return sb.toString();
        }
+
+       public boolean hasNamedValue(String n) {
+               if (nvPairs==null) return false;
+               for (int i=0;i<nvPairs.size();i++) {
+                       AnnotationNameValuePair pair = (AnnotationNameValuePair)nvPairs.get(i);
+                       if (pair.getName().equals(n)) return true;
+               }
+               return false;
+       }
+
+       /**
+     * Return true if the annotation has a value with the specified name (n) and value (v)
+     */
+       public boolean hasNameValuePair(String n, String v) {
+               if (nvPairs==null) return false;
+               for (int i=0;i<nvPairs.size();i++) {
+                       AnnotationNameValuePair pair = (AnnotationNameValuePair)nvPairs.get(i);
+                       if (pair.getName().equals(n)) {
+                               if (pair.getValue().stringify().equals(v)) return true;
+                       }
+               }
+               return false;
+       }
 }
index 4e3263d41408a2f5eb0ad017d64a1f0251351a98..5374d5d4a46ea3aa3fff9a2f6ffef5f9a7db6ddb 100644 (file)
@@ -24,7 +24,7 @@ import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;
 
 /**
  * AnnotationX instances are holders for an annotation from either Bcel or
- * ASM.  We have this holder so that types about the bcel weaver package 
+ * eclipse.  We have this holder so that types about the bcel weaver package 
  * can work with something not bytecode toolkit specific.
  */
 public class AnnotationX {
@@ -32,9 +32,9 @@ public class AnnotationX {
   public static final AnnotationX[] NONE = new AnnotationX[0];
   
   private AnnotationGen theRealBcelAnnotation;
-  private AnnotationAJ theRealASMAnnotation;
+  private AnnotationAJ theRealEclipseAnnotation; // OPTIMIZE push out into compiler, not ever used if purely binary weaving ?
   private int mode = -1;
-  private final static int MODE_ASM = 1;
+  private final static int MODE_ECLIPSE = 1;
   private final static int  MODE_BCEL = 2;
   
   private ResolvedType signature = null;
@@ -51,9 +51,9 @@ public class AnnotationX {
   }
   
   public AnnotationX(AnnotationAJ a,World world) {
-               theRealASMAnnotation = a;
-               signature = UnresolvedType.forSignature(theRealASMAnnotation.getTypeSignature()).resolve(world);
-               mode= MODE_ASM;
+               theRealEclipseAnnotation = a;
+               signature = UnresolvedType.forSignature(theRealEclipseAnnotation.getTypeSignature()).resolve(world);
+               mode= MODE_ECLIPSE;
   }
 
   public AnnotationGen getBcelAnnotation() {
@@ -66,18 +66,18 @@ public class AnnotationX {
   
   public String toString() {
          if (mode==MODE_BCEL) return theRealBcelAnnotation.toString();
-         else                             return theRealASMAnnotation.toString();
+         else                             return theRealEclipseAnnotation.toString();
   }
 
 
   public String getTypeName() {
        if (mode==MODE_BCEL) return theRealBcelAnnotation.getTypeName();
-       else                             return Utility.signatureToString(theRealASMAnnotation.getTypeSignature());
+       else                             return Utility.signatureToString(theRealEclipseAnnotation.getTypeSignature());
   }
 
   public String getTypeSignature() {
          if (mode==MODE_BCEL) return theRealBcelAnnotation.getTypeSignature();
-               else                             return theRealASMAnnotation.getTypeSignature();
+               else                             return theRealEclipseAnnotation.getTypeSignature();
   }
 
   
@@ -176,7 +176,7 @@ public class AnnotationX {
                        supportedTargets.add(ev.getEnumValueString());
                }
          } else {
-                 List values = theRealASMAnnotation.getNameValuePairs();
+                 List values = theRealEclipseAnnotation.getNameValuePairs();
                  AnnotationNameValuePair nvp = (AnnotationNameValuePair)values.get(0);
                  ArrayAnnotationValue aav = (ArrayAnnotationValue)nvp.getValue();
                  AnnotationValue[] avs = aav.getValues();
@@ -203,7 +203,17 @@ public class AnnotationX {
 
   public void print(StringBuffer sb) {
          if (mode==MODE_BCEL) sb.append(theRealBcelAnnotation.toString());
-         else                 sb.append(theRealASMAnnotation.stringify());
+         else                 sb.append(theRealEclipseAnnotation.stringify());
+  }
+
+  public boolean hasNameValuePair(String n, String v) {
+         if (mode==MODE_BCEL) return theRealBcelAnnotation.hasNameValuePair(n,v);
+         else                 return theRealEclipseAnnotation.hasNameValuePair(n,v);
+  }
+
+  public boolean hasNamedValue(String n) {
+         if (mode==MODE_BCEL) return theRealBcelAnnotation.hasNamedValue(n);
+         else                 return theRealEclipseAnnotation.hasNamedValue(n);
   }
 
 }
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/ArrayReferenceType.java b/weaver/src/org/aspectj/weaver/ArrayReferenceType.java
new file mode 100644 (file)
index 0000000..76e9ba1
--- /dev/null
@@ -0,0 +1,186 @@
+/* *******************************************************************
+ * Copyright (c) 2008 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Represents a resolved array type
+ *
+ * @author Andy Clement 
+ */
+public class ArrayReferenceType extends ReferenceType {
+
+       private ResolvedType componentType;
+
+
+    public ArrayReferenceType(String sig, String erasureSig, World world, ResolvedType componentType) {
+        super(sig, erasureSig, world);
+        this.componentType = componentType;
+    }
+
+    // These methods are from the original implementation when Array was a ResolvedType and not a ReferenceType
+    
+    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();
+    }
+
+
+    // Methods overridden from ReferenceType follow
+
+    public TypeVariable[] getTypeVariables() {
+        if (this.typeVariables == null && componentType.getTypeVariables() != null) {
+            this.typeVariables = componentType.getTypeVariables();
+            for (int i = 0; i < this.typeVariables.length; i++) {
+                this.typeVariables[i].resolve(world);
+            }
+        }
+        return this.typeVariables;
+    }
+
+    public boolean isAnnotation() {
+        return false;
+    }
+
+    public boolean isAnonymous() {
+        return false;
+    }
+
+    public boolean isAnnotationStyleAspect() {
+        return false;
+    }
+
+       public boolean isAspect() {
+        return false;
+    }
+
+    public boolean isPrimitiveType() {
+        return typeKind == TypeKind.PRIMITIVE;
+    }
+
+    public boolean isSimpleType() {
+        return typeKind == TypeKind.SIMPLE;
+    }
+
+    public boolean isRawType() {
+        return typeKind == TypeKind.RAW;
+    }
+
+    public boolean isGenericType() {
+        return typeKind == TypeKind.GENERIC;
+    }
+
+    public boolean isParameterizedType() {
+        return typeKind == TypeKind.PARAMETERIZED;
+    }
+
+    public boolean isTypeVariableReference() {
+        return typeKind == TypeKind.TYPE_VARIABLE;
+    }
+
+    public boolean isGenericWildcard() {
+        return typeKind == TypeKind.WILDCARD;
+    }
+    
+       public boolean isEnum() {
+        return false;
+    }
+
+       public boolean isNested() {
+        return false;
+    }
+
+    public boolean isClass() {
+        return false;
+    }
+
+    public boolean canAnnotationTargetType() {
+        return false;
+    }
+       
+       public AnnotationTargetKind[] getAnnotationTargetKinds() {
+        return null;
+    }
+
+    public boolean isAnnotationWithRuntimeRetention() {
+        return false;
+    }
+}
index d90cb565a4ca93651a7fb87aac4e3a8a0e643ba5..e2bd4d09d064855cce09bc754090c6268386d81f 100644 (file)
@@ -16,6 +16,7 @@ package org.aspectj.weaver;
 import java.util.Iterator;
 import java.util.List;
 
+import org.aspectj.apache.bcel.classfile.Field;
 import org.aspectj.apache.bcel.classfile.Method;
 import org.aspectj.apache.bcel.classfile.Utility;
 import org.aspectj.apache.bcel.generic.Type;
@@ -430,7 +431,7 @@ public class AsmRelationshipProvider {
      * the fields' type in order to locate it.  Currently just fails silently if any of the lookup code
      * doesn't find anything...
      */
-       public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename,String fieldName) {
+       public void addDeclareAnnotationRelationship(ISourceLocation sourceLocation, String typename,Field field) {
            if (!AsmManager.isCreatingModel()) return;
            
            String pkg  = null;
@@ -444,7 +445,7 @@ public class AsmRelationshipProvider {
         IProgramElement typeElem = AsmManager.getDefault().getHierarchy().findElementForType(pkg,type);
         if (typeElem == null) return;
         
-        IProgramElement fieldElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem,IProgramElement.Kind.FIELD,fieldName);
+        IProgramElement fieldElem = AsmManager.getDefault().getHierarchy().findElementForSignature(typeElem,IProgramElement.Kind.FIELD,field.getName());
         if (fieldElem== null) return;
 
                String targetHandle = fieldElem.getHandleIdentifier();
diff --git a/weaver/src/org/aspectj/weaver/BetaException.java b/weaver/src/org/aspectj/weaver/BetaException.java
deleted file mode 100644 (file)
index f34b06e..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * 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://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     PARC     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.weaver;
-
-/**
- * Exception to use inside the bcweaver.
- */
-public class BetaException extends RuntimeException {
-
-    public BetaException() {
-        super();
-    }
-
-    public BetaException(String s) {
-        super(s);
-    }
-
-}
index abb85f65aeb4c52e7288dfa9f5caf3d17416bc9c..65a485e00d900441b3f6b13ec6bb6ba75ed7e838 100644 (file)
@@ -13,6 +13,8 @@
 
 package org.aspectj.weaver;
 
+import java.util.Map;
+
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.util.PartialOrder;
 
@@ -123,4 +125,6 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab
                if (munger==null) return false;
                return munger.isLateMunger();
        }
+
+       public abstract ConcreteTypeMunger parameterizeWith(Map parameterizationMap, World world);
 }
index 3ff7d75aa5bbd9f551dc9834b2cafc6574f744db..783bacbb5d7d00b128b936ace4ae7837df6ec1b4 100644 (file)
@@ -14,8 +14,10 @@ package org.aspectj.weaver;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.aspectj.weaver.bcel.BcelAdvice;
@@ -71,6 +73,10 @@ public class CrosscuttingMembers {
                this.shouldConcretizeIfNeeded = shouldConcretizeIfNeeded;
        }
        
+
+       private Hashtable cflowFields = new Hashtable();
+       private Hashtable cflowBelowFields = new Hashtable();
+       
 //     public void addConcreteShadowMungers(Collection c) {
 //             shadowMungers.addAll(c);
 //     }
@@ -502,4 +508,17 @@ public class CrosscuttingMembers {
                return declareAnnotationsOnMethods;
        }
 
+       public Map getCflowBelowFields() {
+               return cflowBelowFields;
+       }
+
+       public Map getCflowFields() {
+               return cflowFields;
+       }
+       
+       public void clearCaches() {
+               cflowFields.clear();
+               cflowBelowFields.clear();
+       }
+
 }
index 55d46b64263454a33e1e5f320b25bbeb33255aab..a57bbf0ac070ab2a11f5efd144da09e452842ab3 100644 (file)
@@ -78,13 +78,10 @@ public class CrosscuttingMembersSet {
                if (xcut == null) {
                        members.put(aspectType, aspectType.collectCrosscuttingMembers(inWeavingPhase));
                        clearCaches();
-                       CflowPointcut.clearCaches(aspectType);
                        change = true;
                } else {
                        if (xcut.replaceWith(aspectType.collectCrosscuttingMembers(inWeavingPhase),inWeavingPhase)) {
                                clearCaches();
-
-                               CflowPointcut.clearCaches(aspectType);
                                change = true;
                        } else {
                                if (!AsmManager.getDefault().getHandleProvider().dependsOnLocation()
diff --git a/weaver/src/org/aspectj/weaver/CustomMungerFactory.java b/weaver/src/org/aspectj/weaver/CustomMungerFactory.java
new file mode 100644 (file)
index 0000000..3ff37a4
--- /dev/null
@@ -0,0 +1,58 @@
+/* *******************************************************************
+ * Copyright (c) 2007 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Linton Ye https://bugs.eclipse.org/bugs/show_bug.cgi?id=193065
+ * ******************************************************************/
+
+package org.aspectj.weaver;
+
+import java.util.Collection;
+
+/**
+ * <p>
+ * This interface is introduced to support tools like PointcutDoctor.
+ * </p>
+ * <p>
+ * A CustomMungerFactory is used to create ShadowMungers and/or
+ * ConcreteTypeMungers so that an extender can extract extra information during
+ * the weaving process.
+ * </p>
+ * <p>
+ * A CustomMungerFactory is assigned to a weaver through its AjCompiler in
+ * extenders' code, and gets invoked by the weaver right before the weaving
+ * starts. The custom shadow/type mungers being created will be added into the
+ * shadow/type munger list in the weaver and participate the weaving process.
+ * For example, the match method of each custom shadow munger will be called
+ * against each shadow.
+ * </p>
+ * @author lintonye
+ * 
+ */
+public interface CustomMungerFactory {
+
+       /**
+        * @param aspectType
+        * @return a Collection&lt;ShadowMunger&gt; of custom shadow mungers for the
+        *         given aspect
+        */
+       public Collection/* ShadowMunger */createCustomShadowMungers(
+                       ResolvedType aspectType);
+
+       /**
+        * @param aspectType
+        * @return a Collection&lt;ConcreteTypeMunger&gt; of custom type mungers for the
+        *         given aspect
+        */
+       public Collection/* ConcreteTypeMunger */createCustomTypeMungers(
+                       ResolvedType aspectType);
+       
+       public Collection/* ShadowMunger */getAllCreatedCustomShadowMungers();
+
+       public Collection/* ConcreteTypeMunger */getAllCreatedCustomTypeMungers();
+}
index cb495c3b75b387df8165cbbbba23d566e5d94c68..f8757081a45720ff49e3e084574041e7be5b37c9 100644 (file)
@@ -16,6 +16,7 @@ import java.io.IOException;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute;
@@ -90,6 +91,10 @@ public class JoinPointSignature implements ResolvedMember {
        public ResolvedType[] getAnnotationTypes() {
                return realMember.getAnnotationTypes();
        }
+       
+       public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
+               return realMember.getAnnotationOfType(ofType);
+       }
 
        public void setAnnotationTypes(UnresolvedType[] annotationtypes) {
                realMember.setAnnotationTypes(annotationtypes);
@@ -235,15 +240,7 @@ public class JoinPointSignature implements ResolvedMember {
                return realMember.resolve(world);
        }
 
-       public int compareTo(Object other) {
-               return realMember.compareTo(other);
-       }
-
-       public String toLongString() {
-               return realMember.toLongString();
-       }
-
-       public Kind getKind() {
+       public MemberKind getKind() {
                return realMember.getKind();
        }
 
@@ -262,6 +259,14 @@ public class JoinPointSignature implements ResolvedMember {
        public UnresolvedType[] getParameterTypes() {
                return realMember.getParameterTypes();
        }
+       
+       public AnnotationX[][] getParameterAnnotations() {
+               return realMember.getParameterAnnotations();
+       }
+       
+       public ResolvedType[][] getParameterAnnotationTypes() {
+               return realMember.getParameterAnnotationTypes();
+       }
 
        public String getSignature() {
                return realMember.getSignature();
@@ -279,18 +284,6 @@ public class JoinPointSignature implements ResolvedMember {
                return realMember.isCompatibleWith(am);
        }
 
-       public boolean isProtected(World world) {
-               return realMember.isProtected(world);
-       }
-
-       public boolean isStatic(World world) {
-               return realMember.isStatic(world);
-       }
-
-       public boolean isStrict(World world) {
-               return realMember.isStrict(world);
-       }
-
        public boolean isStatic() {
                return realMember.isStatic();
        }
@@ -373,7 +366,7 @@ public class JoinPointSignature implements ResolvedMember {
           realMember.resetName(newName);
    }   
 
-       public void resetKind(Kind newKind) {
+       public void resetKind(MemberKind newKind) {
                realMember.resetKind(newKind);
        }
        
@@ -407,7 +400,11 @@ public class JoinPointSignature implements ResolvedMember {
 
        public void evictWeavingState() { realMember.evictWeavingState(); }
 
-       public Member slimline() {
-               return this;
+       public ResolvedMember parameterizedWith(Map m, World w) {
+               return realMember.parameterizedWith(m,w);
+       }
+
+       public String getAnnotationDefaultValue() {
+               return realMember.getAnnotationDefaultValue();
        }
 }
index 1dcf127d7cbcb2cb7d6530397df4bd33a8255b8d..178995159d048475df07f95825e1f57f9be5f1c3 100644 (file)
@@ -128,6 +128,9 @@ public class Lint {
        public final Kind advisingSynchronizedMethods = new Kind("advisingSynchronizedMethods",
                        "advice matching the synchronized method shadow ''{0}'' will be executed outside the lock rather than inside (compiler limitation)");
 
+       public final Kind mustWeaveXmlDefinedAspects = new Kind("mustWeaveXmlDefinedAspects",
+                       "XML Defined aspects must be woven in cases where cflow pointcuts are involved. Currently the include/exclude patterns exclude ''{0}''");
+       
        private static Trace trace = TraceFactory.getTraceFactory().getTrace(Lint.class);
        
     public Lint(World world) {
index b6db208ec75effd675fcb3e4b3a9a09fbe17ae0d..55222ef260d15ad7aa7f6a946f4554e2ade01d09 100644 (file)
  * ******************************************************************/
 package org.aspectj.weaver;
 
-import java.io.DataInputStream;
-import java.io.IOException;
 import java.util.Collection;
 import java.util.Iterator;
 
-import org.aspectj.util.TypeSafeEnum;
 
 public interface Member {
 
-    public static class Kind extends TypeSafeEnum {
-        public Kind(String name, int key) { super(name, key); }
-        
-        public static Kind read(DataInputStream s) throws IOException {
-            int key = s.readByte();
-            switch(key) {
-                case 1: return METHOD;
-                case 2: return FIELD;
-                case 3: return CONSTRUCTOR;
-                case 4: return STATIC_INITIALIZATION;
-                case 5: return POINTCUT;
-                case 6: return ADVICE;
-                case 7: return HANDLER;
-                case 8: return MONITORENTER;
-                case 9: return MONITOREXIT;
-            }
-            throw new BCException("weird kind " + key);
-        }
-    }
-
-       public static final Member[] NONE = new Member[0];
-       public static final Kind METHOD = new Kind("METHOD", 1);
-       public static final Kind FIELD = new Kind("FIELD", 2);
-       public static final Kind CONSTRUCTOR = new Kind("CONSTRUCTOR", 3);
-       public static final Kind STATIC_INITIALIZATION = new Kind("STATIC_INITIALIZATION", 4);
-       public static final Kind POINTCUT = new Kind("POINTCUT", 5);
-       public static final Kind ADVICE = new Kind("ADVICE", 6);
-       public static final Kind HANDLER = new Kind("HANDLER", 7);
-       public static final Kind MONITORENTER = new Kind("MONITORENTER", 8);
-       public static final Kind MONITOREXIT = new Kind("MONITOREXIT", 9);
-
-
+    public static final Member[]   NONE                  = new Member[0];
+       public static final MemberKind METHOD                = new MemberKind("METHOD", 1);
+       public static final MemberKind FIELD                 = new MemberKind("FIELD", 2);
+       public static final MemberKind CONSTRUCTOR           = new MemberKind("CONSTRUCTOR", 3);
+       public static final MemberKind STATIC_INITIALIZATION = new MemberKind("STATIC_INITIALIZATION", 4);
+       public static final MemberKind POINTCUT              = new MemberKind("POINTCUT", 5);
+       public static final MemberKind ADVICE                = new MemberKind("ADVICE", 6);
+       public static final MemberKind HANDLER               = new MemberKind("HANDLER", 7);
+       public static final MemberKind MONITORENTER          = new MemberKind("MONITORENTER", 8);
+       public static final MemberKind MONITOREXIT           = new MemberKind("MONITOREXIT", 9);
+
+       public static final AnnotationX[][] NO_PARAMETER_ANNOTATIONXS = new AnnotationX[][]{};
+       public static final ResolvedType[][] NO_PARAMETER_ANNOTATION_TYPES = new ResolvedType[][]{};
+
+       public MemberKind getKind();
+       
        public ResolvedMember resolve(World world);
 
-       public int compareTo(Object other);
-
-       public String toLongString();
-
-       public Kind getKind();
+       public String getName();
 
        public UnresolvedType getDeclaringType();
 
-       public UnresolvedType getReturnType();
-       
+    public AnnotationX[] getAnnotations();
+       public UnresolvedType getReturnType();  
+       public UnresolvedType getType(); 
        public UnresolvedType getGenericReturnType();
-       public UnresolvedType[] getGenericParameterTypes();
-
-       public UnresolvedType getType();
-
-       public String getName();
 
+       public String[] getParameterNames(World world);
        public UnresolvedType[] getParameterTypes();
-
+       public UnresolvedType[] getGenericParameterTypes();
+       
        /**
         * Return full signature, including return type, e.g. "()LFastCar;" for a signature without the return type,
-        * use getParameterSignature() - it is importnant to choose the right one in the face of covariance.
+        * use getParameterSignature() - it is important to choose the right one in the face of covariance.
         */
        public String getSignature();
        
@@ -102,52 +77,25 @@ public interface Member {
 
        public UnresolvedType[] getExceptions(World world);
 
-       public boolean isProtected(World world);
-
-       public boolean isStatic(World world);
-
-       public boolean isStrict(World world);
-
        public boolean isStatic();
 
        public boolean isInterface();
 
        public boolean isPrivate();
 
-       /**
-        * Returns true iff the member is generic (NOT parameterized)
-        * For example, a method declared in a generic type
-        */
-       public boolean canBeParameterized();
-
        public int getCallsiteModifiers();
 
        public String getExtractableName();
 
-       /**
-        * If you want a sensible answer, resolve the member and call
-        * hasAnnotation() on the ResolvedMember.
-        */
-       public boolean hasAnnotation(UnresolvedType ofType);
-
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
-        */
-       public ResolvedType[] getAnnotationTypes();
-
-       public AnnotationX[] getAnnotations();
+//     public AnnotationX[] getAnnotations();
 
        public Collection/*ResolvedType*/getDeclaringTypes(World world);
 
-       // ---- reflective thisJoinPoint stuff
+       // ---- reflective thisJoinPoint related methods
        public String getSignatureMakerName();
 
        public String getSignatureType();
 
        public String getSignatureString(World world);
 
-       public String[] getParameterNames(World world);
-
-       public Member slimline();
-
 }
\ No newline at end of file
index e4ab17f71aa282730823a16852feee5dd98b86c0..fef5dd1930b146ca19052f466dc051ce8a41c379 100644 (file)
@@ -21,19 +21,26 @@ import java.util.Iterator;
 import java.util.List;
 
 
-public class MemberImpl implements Comparable, AnnotatedElement,Member {
-    
-    protected Kind kind;
-    protected int modifiers; 
-    protected UnresolvedType declaringType;
+public class MemberImpl implements Comparable, Member {
+
+    protected MemberKind kind;
     protected String name;
+
+    protected UnresolvedType declaringType;
+    protected int modifiers; 
     protected UnresolvedType returnType;
     protected UnresolvedType[] parameterTypes;
     private final String signature;
     private String paramSignature;
+    
+    // OPTIMIZE move out of the member!
     private boolean reportedCantFindDeclaringType = false;
     private boolean reportedUnresolvableMember = false;
 
+
+    public AnnotationX[] getAnnotations() {
+       throw new IllegalStateException("Cannot answer getAnnotations() for MemberImpl "+this.toString());
+    }
     
     /**
      * All the signatures that a join point with this member as its signature has.
@@ -43,7 +50,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
     private JoinPointSignatureIterator joinPointSignatures = null;
 
     public MemberImpl(
-        Kind kind, 
+        MemberKind kind, 
         UnresolvedType declaringType,
         int modifiers,
         String name,
@@ -53,6 +60,9 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
         this.declaringType = declaringType;
         this.modifiers = modifiers;
         this.name = name;
+        if (kind!=STATIC_INITIALIZATION && name!=null && name.equals("<clinit>")) {
+               throw new RuntimeException("!");
+        }
         this.signature = signature;
         if (kind == FIELD) {
             this.returnType = UnresolvedType.forSignature(signature);
@@ -68,7 +78,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
     }
 
     public  MemberImpl(
-        Kind kind, 
+        MemberKind kind, 
         UnresolvedType declaringType, 
         int modifiers,
         UnresolvedType returnType, 
@@ -78,7 +88,11 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
         super();
         this.kind = kind;
         this.declaringType = declaringType;
-        this.modifiers = modifiers;
+        this.modifiers = modifiers;      
+        if (name!=null && name.equals("<clinit>") && kind!=STATIC_INITIALIZATION) {
+               throw new RuntimeException("!");
+               }
+
         this.returnType = returnType;
         this.name = name;
         this.parameterTypes = parameterTypes;
@@ -232,13 +246,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
 
 
     private static MemberImpl field(String declaring, int mods, UnresolvedType ty, String name) {
-        return new MemberImpl(
-            FIELD,
-            UnresolvedType.forName(declaring),
-            mods,
-            ty,
-            name,
-            UnresolvedType.NONE);
+        return new MemberImpl(FIELD, UnresolvedType.forName(declaring), mods, ty, name, UnresolvedType.NONE);
     }
     
     public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
@@ -270,107 +278,6 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
                        "(" + catchType.getSignature() + ")V");
        }
     
-    // ---- parsing methods
-    
-    /** Takes a string in this form:
-     * 
-     * <blockquote><pre>
-     * static? TypeName TypeName.Id
-     * </pre></blockquote>
-     * Pretty much just for testing, and as such should perhaps be moved.
-     */
-    
-    public static MemberImpl fieldFromString(String str) {
-        str = str.trim();
-        final int len = str.length();
-        int i = 0;
-        int mods = 0;
-        if (str.startsWith("static", i)) {
-            mods = Modifier.STATIC;
-            i += 6;
-            while (Character.isWhitespace(str.charAt(i))) i++;
-        }
-        int start = i;
-        while (! Character.isWhitespace(str.charAt(i))) i++;
-        UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i));
-
-        start = i;
-        i = str.lastIndexOf('.');
-        UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
-        start = ++i;
-        String name = str.substring(start, len).trim();
-        return new MemberImpl(
-            FIELD,
-            declaringTy,
-            mods,
-            retTy,
-            name,
-            UnresolvedType.NONE);
-    }
-
-    /** Takes a string in this form:
-     * 
-     * <blockquote><pre>
-     * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
-     * </pre></blockquote>
-     * Pretty much just for testing, and as such should perhaps be moved.
-     */
-    
-    public static Member methodFromString(String str) {
-        str = str.trim();
-        // final int len = str.length();
-        int i = 0;
-
-        int mods = 0;
-        if (str.startsWith("static", i)) {
-            mods = Modifier.STATIC;
-            i += 6;
-        } else if (str.startsWith("interface", i)) {
-            mods = Modifier.INTERFACE;
-            i += 9;
-        } else if (str.startsWith("private", i)) {
-            mods = Modifier.PRIVATE;
-            i += 7;
-        }            
-        while (Character.isWhitespace(str.charAt(i))) i++;
-        
-        int start = i;
-        while (! Character.isWhitespace(str.charAt(i))) i++;
-        UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i));
-
-        start = i;
-        i = str.indexOf('(', i);
-        i = str.lastIndexOf('.', i);
-        UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
-        
-        start = ++i;
-        i = str.indexOf('(', i);
-        String name = str.substring(start, i).trim();
-        start = ++i;
-        i = str.indexOf(')', i);
-    
-        String[] paramTypeNames = parseIds(str.substring(start, i).trim());
-
-        return method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames));
-    }
-
-    private static String[] parseIds(String str) {
-        if (str.length() == 0) return ZERO_STRINGS;
-        List l = new ArrayList();
-        int start = 0;
-        while (true) {
-            int i = str.indexOf(',', start);
-            if (i == -1) {
-                l.add(str.substring(start).trim());
-                break;
-            }
-            l.add(str.substring(start, i).trim());
-            start = i+1;
-        }
-        return (String[]) l.toArray(new String[l.size()]);
-    }
-
-    private static final String[] ZERO_STRINGS = new String[0];
 
     // ---- things we know without resolution
     
@@ -433,62 +340,32 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
        return buf.toString();
     }
     
+    // Overridden by subclasses - a method can be advice
+    public MemberKind getKind() { 
+       return kind; 
+    }
     
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#toLongString()
-        */
-    public String toLongString() {
-        StringBuffer buf = new StringBuffer();
-        buf.append(kind);
-        buf.append(' ');
-        if (modifiers != 0) {
-            buf.append(Modifier.toString(modifiers));
-            buf.append(' ');
-        }
-        buf.append(toString());
-        buf.append(" <");
-        buf.append(signature);
-        buf.append(" >");
-        return buf.toString();
-    }        
-
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getKind()
-        */
-    public Kind getKind() { return kind; }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getDeclaringType()
-        */
     public UnresolvedType getDeclaringType() { return declaringType; }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getReturnType()
-        */
+    
     public UnresolvedType getReturnType() { return returnType; }
     
     public UnresolvedType getGenericReturnType() { return getReturnType(); }
     public UnresolvedType[] getGenericParameterTypes() { return getParameterTypes(); }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getType()
-        */
-    public UnresolvedType getType() { return returnType; }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getName()
-        */
-    public String getName() { return name; }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getParameterTypes()
-        */
+
+    public UnresolvedType getType() { 
+       return returnType; 
+    }
+    
+    public String getName() { 
+       return name; 
+    }
+
     public UnresolvedType[]  getParameterTypes() { return parameterTypes; }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getSignature()
-        */
+    
     public String getSignature() { return signature; }
        
     public int getArity() { return parameterTypes.length; }
   
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getParameterSignature()
-        */
     public String getParameterSignature() {
        if (paramSignature != null) return paramSignature;
        StringBuffer sb = new StringBuffer();
@@ -535,9 +412,6 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
                return resolved.getModifiers();
     }
     
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getExceptions(org.aspectj.weaver.World)
-        */
     public UnresolvedType[] getExceptions(World world) {
        ResolvedMember resolved = resolve(world);
        if (resolved == null) {
@@ -546,57 +420,23 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
                }
                return resolved.getExceptions();
     }
-    
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#isProtected(org.aspectj.weaver.World)
-        */
-    public final boolean isProtected(World world) {
-        return Modifier.isProtected(resolve(world).getModifiers());
-    }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#isStatic(org.aspectj.weaver.World)
-        */
-    public final boolean isStatic(World world) {
-        return Modifier.isStatic(resolve(world).getModifiers());
-    }
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#isStrict(org.aspectj.weaver.World)
-        */
-    public final boolean isStrict(World world) {
-        return Modifier.isStrict(resolve(world).getModifiers());
-    }
-    
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#isStatic()
-        */
+        
     public final boolean isStatic() {
         return Modifier.isStatic(modifiers);
     }    
     
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#isInterface()
-        */
     public final boolean isInterface() {
-        return Modifier.isInterface(modifiers);  // this is kinda weird
+        return Modifier.isInterface(modifiers);
     }    
     
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#isPrivate()
-        */
     public final boolean isPrivate() {
         return Modifier.isPrivate(modifiers);
     }    
     
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#canBeParameterized()
-        */
     public boolean canBeParameterized() {
        return false;
     }
 
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getCallsiteModifiers()
-        */
        public final int getCallsiteModifiers() {
                return modifiers & ~ Modifier.INTERFACE;
        }
@@ -605,46 +445,19 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
                return modifiers;
        }
 
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getExtractableName()
-        */
     public final String getExtractableName() {
-       if (name.equals("<init>")) return "init$";
-       else if (name.equals("<clinit>")) return "clinit$";
+       if (kind==CONSTRUCTOR/*name.equals("<init>")*/) return "init$";
+       else if (kind==STATIC_INITIALIZATION/*name.equals("<clinit>")*/) return "clinit$";
        else return name;
     }
-
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#hasAnnotation(org.aspectj.weaver.UnresolvedType)
-        */
-       public boolean hasAnnotation(UnresolvedType ofType) {
-               throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
-       }
-       
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
-        */
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getAnnotationTypes()
-        */
-       public ResolvedType[] getAnnotationTypes() {
-               throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
-       }
-       
-       /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getAnnotations()
-        */
-       public AnnotationX[] getAnnotations() {
-               throw new UnsupportedOperationException("You should resolve this member '"+this+"' and call getAnnotations() on the result...");
-       }
+    
+//     public AnnotationX[] getAnnotations() {
+//             throw new UnsupportedOperationException("You should resolve this member '"+this+"' and call getAnnotations() on the result...");
+//     }
 
        // ---- fields 'n' stuff
 
 
-    
-    /* (non-Javadoc)
-        * @see org.aspectj.weaver.Member#getDeclaringTypes(org.aspectj.weaver.World)
-        */
        public Collection/*ResolvedType*/ getDeclaringTypes(World world) {
                ResolvedType myType = getDeclaringType().resolve(world);
                Collection ret = new HashSet();
@@ -701,9 +514,9 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
         * @see org.aspectj.weaver.Member#getSignatureMakerName()
         */
     public String getSignatureMakerName() {
-       if (getName().equals("<clinit>")) return "makeInitializerSig";
+//     if (getName().equals("<clinit>")) return "makeInitializerSig";
        
-       Kind kind = getKind();
+       MemberKind kind = getKind();
        if (kind == METHOD) {
                return "makeMethodSig";
        } else if (kind == CONSTRUCTOR) {
@@ -732,8 +545,8 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
         * @see org.aspectj.weaver.Member#getSignatureType()
         */
        public String getSignatureType() {
-       Kind kind = getKind();
-       if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
+       MemberKind kind = getKind();
+//     if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
        
        if (kind == METHOD) {
                return "org.aspectj.lang.reflect.MethodSignature";
@@ -761,8 +574,8 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
         */
        public String getSignatureString(World world) {
                if (getName().equals("<clinit>")) return getStaticInitializationSignatureString(world);
-               
-       Kind kind = getKind();
+//             
+       MemberKind kind = getKind();
        if (kind == METHOD) {
                return getMethodSignatureString(world);
        } else if (kind == CONSTRUCTOR) {
@@ -902,7 +715,7 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
     }
 
        protected String makeString(int i) {
-               return Integer.toString(i, 16);  //??? expensive
+               return Integer.toString(i, 16);
        }
 
 
@@ -982,9 +795,5 @@ public class MemberImpl implements Comparable, AnnotatedElement,Member {
                }
     }
 
-       public Member slimline() {
-               return this;
-       }
-
 }
    
diff --git a/weaver/src/org/aspectj/weaver/MemberKind.java b/weaver/src/org/aspectj/weaver/MemberKind.java
new file mode 100644 (file)
index 0000000..6cd28e7
--- /dev/null
@@ -0,0 +1,37 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     PARC     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.aspectj.util.TypeSafeEnum;
+
+public class MemberKind extends TypeSafeEnum {
+    public MemberKind(String name, int key) { super(name, key); }
+    
+    public static MemberKind read(DataInputStream s) throws IOException {
+        int key = s.readByte();
+        switch(key) {
+            case 1: return Member.METHOD;
+            case 2: return Member.FIELD;
+            case 3: return Member.CONSTRUCTOR;
+            case 4: return Member.STATIC_INITIALIZATION;
+            case 5: return Member.POINTCUT;
+            case 6: return Member.ADVICE;
+            case 7: return Member.HANDLER;
+            case 8: return Member.MONITORENTER;
+            case 9: return Member.MONITOREXIT;
+        }
+        throw new BCException("weird kind " + key);
+    }
+}
\ No newline at end of file
index 47531910abc18d3ddafabf948642247a615f6b53..f89b83651d0278b815afeefd1b1f49261d4428ab 100644 (file)
@@ -104,7 +104,7 @@ public class NameMangler {
        }
        
     public static String itdAtDeclareParentsField(UnresolvedType aspectType, UnresolvedType itdType) {
-        return makeName(aspectType.getNameAsIdentifier(), itdType.getNameAsIdentifier());
+        return makeName("instance",aspectType.getNameAsIdentifier(), itdType.getNameAsIdentifier());
     }
 
        public static String privilegedAccessMethodForMethod(String name, UnresolvedType objectType, UnresolvedType aspectType) {
@@ -358,15 +358,14 @@ public class NameMangler {
                        return enclosingType.getName() + "$AjcClosure"  + index;
        }
 
-       public static String aroundCallbackMethodName(
-               Member shadowSig,
-               LazyClassGen enclosingType) 
-       {
-               String ret =
-                       shadowSig.getExtractableName()
-                               + "_aroundBody"
-                               + enclosingType.getNewGeneratedNameTag();
-               return ret;
+       public static String aroundCallbackMethodName(Member shadowSig, LazyClassGen enclosingType) {
+               StringBuffer ret = new StringBuffer();
+               ret.append(shadowSig.getExtractableName()).append("_aroundBody").append(enclosingType.getNewGeneratedNameTag());
+//             String ret =
+//                     shadowSig.getExtractableName()
+//                             + "_aroundBody"
+//                             + enclosingType.getNewGeneratedNameTag();
+               return ret.toString();
        }
 
        public static String proceedMethodName(String adviceMethodName) {
index 6a0974965ece1ad38938bae1c9f0d5056c1d341d..19ed670ab60c406bd346fafbf014000069dba5da 100644 (file)
@@ -16,6 +16,7 @@ package org.aspectj.weaver;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.aspectj.bridge.ISourceLocation;
@@ -94,6 +95,14 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger {
            return nftm;
        }
 
+       public ResolvedTypeMunger parameterizeWith(Map m, World w) {
+               ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m,w);
+               NewFieldTypeMunger nftm = new NewFieldTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
+               nftm.setDeclaredSignature(getSignature());
+               nftm.setSourceLocation(getSourceLocation());
+               return nftm;
+       }
+
     public boolean equals(Object other) {
         if (! (other instanceof NewFieldTypeMunger)) return false;
         NewFieldTypeMunger o = (NewFieldTypeMunger) other;
index 05b6112ce7f943764098d83a57b0c2edcebc2552..9b13f780eb57e5caa7671c8f854794b80af766ba 100644 (file)
@@ -16,11 +16,14 @@ package org.aspectj.weaver;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.aspectj.bridge.ISourceLocation;
 
 public class NewMethodTypeMunger extends ResolvedTypeMunger {
+
+
        public NewMethodTypeMunger(
                ResolvedMember signature,
                Set superMethodsCalled,
@@ -128,5 +131,13 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger {
         result = 37*result + ((typeVariableAliases == null) ? 0 : typeVariableAliases.hashCode());
         return result;
     }
-       
+
+       public ResolvedTypeMunger parameterizeWith(Map m, World w) {
+               ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m,w);
+               NewMethodTypeMunger nmtm = new NewMethodTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases);
+               nmtm.setDeclaredSignature(getSignature());
+               nmtm.setSourceLocation(getSourceLocation());
+               return nmtm;
+       }
+
 }
index 31313cad8fc394dc3f69c3da77770f8267bf78f0..7852a4d866f25af9bc3c20e929cc044a02a1f034 100644 (file)
@@ -65,6 +65,7 @@ public class ReferenceType extends ResolvedType {
        ResolvedMember[] parameterizedPointcuts = null;
        ResolvedType[] parameterizedInterfaces = null;
        Collection parameterizedDeclares = null;
+       Collection parameterizedTypeMungers = null;
        
        //??? should set delegate before any use
     public ReferenceType(String signature, World world) {
@@ -127,11 +128,11 @@ public class ReferenceType extends ResolvedType {
                typeKind=TypeKind.GENERIC;
        }
         
-    public final boolean isClass() {
+    public boolean isClass() {
        return delegate.isClass();
     }
     
-    public final boolean isGenericType() {
+    public boolean isGenericType() {
        return !isParameterizedType() && !isRawType() && delegate.isGeneric();
     }
 
@@ -147,6 +148,7 @@ public class ReferenceType extends ResolvedType {
     public void addAnnotation(AnnotationX annotationX) {
        delegate.addAnnotation(annotationX);
     }
+    
     public boolean hasAnnotation(UnresolvedType ofType) {
        return delegate.hasAnnotation(ofType);
     }
@@ -200,7 +202,7 @@ public class ReferenceType extends ResolvedType {
     }
       
     // true iff the statement "this = (ThisType) other" would compile
-    public final boolean isCoerceableFrom(ResolvedType o) {
+    public boolean isCoerceableFrom(ResolvedType o) {
         ResolvedType other = o.resolve(world);
 
         if (this.isAssignableFrom(other) || other.isAssignableFrom(this)) {
@@ -272,12 +274,12 @@ public class ReferenceType extends ResolvedType {
        return false;
     }
     
-    public final boolean isAssignableFrom(ResolvedType other) {
+    public boolean isAssignableFrom(ResolvedType other) {
        return isAssignableFrom(other,false);
     }
     
     // true iff the statement "this = other" would compile.
-    public final boolean isAssignableFrom(ResolvedType other,boolean allowMissing) {
+    public boolean isAssignableFrom(ResolvedType other,boolean allowMissing) {
                if (other.isPrimitiveType()) {
                if (!world.isInJava5Mode()) return false;
                if (ResolvedType.validBoxing.contains(this.getSignature()+other.getSignature())) return true;
@@ -596,7 +598,28 @@ public class ReferenceType extends ResolvedType {
                return declares;
        }
        
-       protected Collection getTypeMungers() { return delegate.getTypeMungers(); }
+       protected Collection getTypeMungers() { 
+               return delegate.getTypeMungers();
+       }
+               // GENERICITDFIX
+////           Map parameterizationMap = getAjMemberParameterizationMap();
+//             
+//     //      if (parameterizedTypeMungers != null) return parameterizedTypeMungers;
+//             Collection ret = null;
+//             if (ajMembersNeedParameterization()) {
+//                     Collection genericDeclares = delegate.getTypeMungers(); 
+//                     parameterizedTypeMungers = new ArrayList();
+//                     Map parameterizationMap = getAjMemberParameterizationMap();
+//                     for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) {
+//                             ConcreteTypeMunger munger = (ConcreteTypeMunger)iter.next();
+//                             parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,world));
+//                     }
+//                     ret = parameterizedTypeMungers;
+//             } else {
+//                     ret = delegate.getTypeMungers(); 
+//             }
+//             return ret;
+//     }
        
        protected Collection getPrivilegedAccesses() { return delegate.getPrivilegedAccesses(); }
 
index e0853f1e52f093e2d6628f85329b116d99e4c70a..0f21b25be8aaeb701ab220273450801b901e46fe 100644 (file)
@@ -17,8 +17,8 @@ import java.util.Collection;
 import org.aspectj.weaver.patterns.PerClause;
 
 /**
- * Abstraction over a type.  Abstract implementation provided by 
- * AbstractReferenceTypeDelegate.
+ * Abstraction over a type - a reference type is Object and a descendant of Object, other types (int/etc) are
+ * considered primitive types.  Abstract implementation provided by AbstractReferenceTypeDelegate.
  */
 public interface ReferenceTypeDelegate {
        
index 1664f1a18e7cd174c79edf25c6b75e0614f1caf4..ae23bd8bdf8daa8582a23a471cced4f2b59bc721 100644 (file)
@@ -16,6 +16,7 @@ package org.aspectj.weaver;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 
 import org.aspectj.bridge.ISourceLocation;
 
@@ -33,6 +34,19 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
 
        public ShadowMunger getAssociatedShadowMunger();
 
+       public AnnotationX[][] getParameterAnnotations();
+       public ResolvedType[][] getParameterAnnotationTypes();
+       
+       public String getAnnotationDefaultValue();
+       
+       public AnnotationX[] getAnnotations();
+       
+       /**
+        * Returns true iff the member is generic (NOT parameterized)
+        * For example, a method declared in a generic type
+        */
+       public boolean canBeParameterized();
+       
        // ??? true or false?
        public boolean isAjSynthetic();
 
@@ -154,9 +168,11 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe
        public boolean matches(ResolvedMember aCandidateMatch);
        
        public void resetName(String newName);
-       public void resetKind(Kind newKind);
+       public void resetKind(MemberKind newKind);
     public void resetModifiers(int newModifiers);
     public void resetReturnTypeToObjectArray();
     
        public void evictWeavingState();
+
+       public ResolvedMember parameterizedWith(Map m, World w);
 }
\ No newline at end of file
index 8c72c371a21eb401d9bb6bc9646fdd5f47002c8c..a643fbebdc56e6887b0b6f92762dab70fe9809a6 100644 (file)
@@ -40,7 +40,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
        public static boolean showParameterNames = true;
 
     private String[] parameterNames = null;
-    protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE;
+    protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE; // OPTIMIZE unpack on demand
 //     private boolean isAjSynthetic = false;    
        protected int start, end;
        protected ISourceContext sourceContext = null;
@@ -67,6 +67,8 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
   //   protected ResolvedMember backingGenericMember = null;
         
     protected Set annotationTypes = null;
+    protected ResolvedType[][] parameterAnnotationTypes = null;
+    
        // Some members are 'created' to represent other things (for example ITDs).  These
        // members have their annotations stored elsewhere, and this flag indicates that is
        // the case.  It is up to the caller to work out where that is!
@@ -89,7 +91,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
     
     //XXX deprecate this in favor of the constructor below
        public ResolvedMemberImpl(
-               Kind kind,
+               MemberKind kind,
                UnresolvedType declaringType,
                int modifiers,
                UnresolvedType returnType,
@@ -102,7 +104,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
     
     
        public ResolvedMemberImpl(
-               Kind kind,
+               MemberKind kind,
                UnresolvedType declaringType,
                int modifiers,
                UnresolvedType returnType,
@@ -115,7 +117,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
        }
     
        public ResolvedMemberImpl(
-                       Kind kind,
+                       MemberKind kind,
                        UnresolvedType declaringType,
                        int modifiers,
                        UnresolvedType returnType,
@@ -133,7 +135,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
                }
        
        public ResolvedMemberImpl(
-               Kind kind,
+               MemberKind kind,
                UnresolvedType declaringType,
                int modifiers,
                String name,
@@ -339,11 +341,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
        if (annotationTypes == null) return null;
                return (ResolvedType[])annotationTypes.toArray(new ResolvedType[]{});
     }
+
+    public AnnotationX getAnnotationOfType(UnresolvedType ofType) { 
+               throw new UnsupportedOperationException("You should resolve this member and call getAnnotationOfType() on the result...");
+    }
     
     public AnnotationX[] getAnnotations() {
        if ((bits&HAS_BACKING_GENERIC_MEMBER)!=0 && metaInfo.backingGenericMember!=null) return metaInfo.backingGenericMember.getAnnotations();
 //     if (backingGenericMember != null) return backingGenericMember.getAnnotations();
-       return super.getAnnotations();
+//     return super.getAnnotations();
+       throw new IllegalStateException("Unable to answer getAnnotations() for "+this.toString());
     }
     
        public void setAnnotationTypes(UnresolvedType[] annotationtypes) {
@@ -354,6 +361,16 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
                }
        }
        
+    public ResolvedType[][] getParameterAnnotationTypes() {
+       if (parameterAnnotationTypes == null) return null;
+               return parameterAnnotationTypes;
+    }
+    
+    public AnnotationX[][] getParameterAnnotations() {
+       if (hasBackingGenericMember()) return getBackingGenericMember().getParameterAnnotations();
+       throw new IllegalStateException("Only a resolvedmember with backing generic member can answer this.  Member="+toString());
+    }
+       
        public void addAnnotation(AnnotationX annotation) {
            // FIXME asc only allows for annotation types, not instances - should it?
                if (annotationTypes == null) annotationTypes = new HashSet();
@@ -441,7 +458,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
     
     public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) throws IOException {
        
-       ResolvedMemberImpl m = new ResolvedMemberImpl(Kind.read(s), UnresolvedType.read(s), s.readInt(), 
+       ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(), 
                        s.readUTF(), s.readUTF());
                m.checkedExceptions = UnresolvedType.readArray(s);
                
@@ -704,6 +721,68 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
                return ret;
        }
                
+
+       /**
+        * Replace occurrences of type variables in the signature with values contained in the map.  The map is of the form A=String,B=Integer and
+        * so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {}
+        */
+       public ResolvedMember parameterizedWith(Map m, World w) {
+//             if (//isParameterized &&  <-- might need this bit...
+//                             !getDeclaringType().isGenericType()) {
+//                     throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+"  kind("+getDeclaringType().typeKind+")");
+//             }
+        declaringType = declaringType.resolve(w);
+        if (declaringType.isRawType()) declaringType = ((ResolvedType)declaringType).getGenericType();
+               TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
+//             if (isParameterized && (typeVariables.length != typeParameters.length)) {
+//                     throw new IllegalStateException("Wrong number of type parameters supplied");
+//             }
+//             Map typeMap = new HashMap();
+//             boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0;
+//             if (typeVariables!=null) {
+//                     // If no 'replacements' were supplied in the typeParameters array then collapse
+//                     // type variables to their first bound.
+//                     for (int i = 0; i < typeVariables.length; i++) {
+//                             UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]);
+//                             typeMap.put(typeVariables[i].getName(),ut);
+//                     }
+//             }
+//             // For ITDs on generic types that use type variables from the target type, the aliases
+//             // record the alternative names used throughout the ITD expression that must map to
+//             // the same value as the type variables real name.
+//             if (aliases!=null) {
+//                     int posn = 0;
+//                     for (Iterator iter = aliases.iterator(); iter.hasNext();) {
+//                             String typeVariableAlias = (String) iter.next();
+//                             typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn]));
+//                             posn++;
+//                     }
+//             }
+               
+               UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),m,true,w);
+               UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];           
+               UnresolvedType[] genericParameterTypes = getGenericParameterTypes(); 
+               for (int i = 0; i < parameterizedParameterTypes.length; i++) {
+                       parameterizedParameterTypes[i] = 
+                               parameterize(genericParameterTypes[i], m,true,w);
+               }
+               ResolvedMemberImpl ret = new ResolvedMemberImpl(
+                                       getKind(),
+                                       declaringType,
+                                       getModifiers(),
+                                       parameterizedReturnType,
+                                       getName(),
+                                       parameterizedParameterTypes,
+                                       getExceptions(),
+                                       this
+                               );
+               ret.setTypeVariables(getTypeVariables());
+               ret.setSourceContext(getSourceContext());
+               ret.setPosition(getStart(),getEnd());
+               ret.setParameterNames(getParameterNames());
+               return ret;
+       }
+               
        public void setTypeVariables(TypeVariable[] tvars) {
                typeVariables = tvars;
        }
@@ -713,6 +792,10 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
        }
        
        protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) {
+               return parameterize(aType,typeVariableMap,inParameterizedType,null);
+       }
+       
+       protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType,World w) {
                if (aType instanceof TypeVariableReference) {
                        String variableName = ((TypeVariableReference)aType).getTypeVariable().getName();
                        if (!typeVariableMap.containsKey(variableName)) {
@@ -721,7 +804,15 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
                        return (UnresolvedType) typeVariableMap.get(variableName);
                } else if (aType.isParameterizedType()) {
                        if (inParameterizedType) {
-                               if (aType instanceof UnresolvedType) aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld());
+//                             if (!(getDeclaringType() instanceof ResolvedType)) {
+//                                     int stop = 1;
+//                             }
+                               if (aType instanceof UnresolvedType) {
+                                       if (w!=null) aType = aType.resolve(w);
+                                       else {
+                                               aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld());
+                                       }
+                               }
                                return aType.parameterize(typeVariableMap);
                        } else {
                                return aType.getRawType();
@@ -806,7 +897,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
       * using this method - this is safe.
       */
        public void resetName(String newName) {this.name = newName;}
-       public void resetKind(Kind newKind)   {this.kind=newKind;  }
+       public void resetKind(MemberKind newKind)   {this.kind=newKind;  }
     public void resetModifiers(int newModifiers) {this.modifiers=newModifiers;}
 
        public void resetReturnTypeToObjectArray() {
@@ -854,7 +945,7 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
                StringBuffer sig = new StringBuffer();
                UnresolvedType[] myParameterTypes = getGenericParameterTypes();
                for (int i = 0; i < myParameterTypes.length; i++) {
-                       appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig);
+                       appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig, new HashSet());
                }
                myParameterSignatureWithBoundsRemoved = sig.toString();
                return myParameterSignatureWithBoundsRemoved;
@@ -878,14 +969,21 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
        
        // does NOT produce a meaningful java signature, but does give a unique string suitable for
        // comparison.
-       private void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer) {
+       public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer, Set alreadyUsedTypeVars) {
                if (aType.isTypeVariableReference()) {
-                       toBuffer.append("T;");
+                       // pr204505
+                   if (alreadyUsedTypeVars.contains(aType)) {
+                toBuffer.append("...");
+            } else {
+                alreadyUsedTypeVars.add(aType);
+                appendSigWithTypeVarBoundsRemoved(aType.getUpperBound(), toBuffer, alreadyUsedTypeVars);
+            }
+//                     toBuffer.append("T;");
                } else if (aType.isParameterizedType()) {
                        toBuffer.append(aType.getRawType().getSignature());
                        toBuffer.append("<");
                        for (int i = 0; i < aType.getTypeParameters().length; i++) {
-                               appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer);
+                               appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer, alreadyUsedTypeVars);
                        }
                        toBuffer.append(">;");
                } else {
@@ -982,5 +1080,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno
        }
 
        public void evictWeavingState() { }
+
+    public String getAnnotationDefaultValue() { 
+               throw new UnsupportedOperationException("You should resolve this member and call getAnnotationDefaultValue() on the result...");
+    }
 }
    
index 598b403f1a91b17baea2615bc45d8198f12a7a16..15acc1a1bfd6ecf1718dedfbfbc86f6a228bc618 100644 (file)
@@ -39,6 +39,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
        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;
        
@@ -113,6 +116,10 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
        return EMPTY_RESOLVED_TYPE_ARRAY;
     }
     
+    public AnnotationX getAnnotationOfType(UnresolvedType ofType) { 
+       return null;
+    }
+    
     public final UnresolvedType getSuperclass(World world) {
         return getSuperclass();
     }
@@ -286,7 +293,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
             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) {
+                if (munger.getMunger()!=null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent 
+                               && ((NewParentTypeMunger)munger.getMunger()).getNewParent().equals(iface) // pr171953
+                               ) {
                     shouldSkip = true;
                     break;
                 }
@@ -506,7 +515,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                crosscuttingMembers = new CrosscuttingMembers(this,shouldConcretizeIfNeeded);
                crosscuttingMembers.setPerClause(getPerClause());
                crosscuttingMembers.addShadowMungers(collectShadowMungers());
-               crosscuttingMembers.addTypeMungers(getTypeMungers());
+               // GENERICITDFIX
+//             crosscuttingMembers.addTypeMungers(collectTypeMungers());
+        crosscuttingMembers.addTypeMungers(getTypeMungers());
         //FIXME AV - skip but needed ?? or  ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers());
                crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
                crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
@@ -516,6 +527,41 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                return crosscuttingMembers;
        }
        
+       public final Collection collectTypeMungers() {
+               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()) {
+                       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();
+                                       ret.add(dec);
+                               }
+               }
+               }
+               
+               return ret;
+    }
+       
        public final Collection collectDeclares(boolean includeAdviceLike) {
                if (! this.isAspect() ) return Collections.EMPTY_LIST;
                
@@ -802,7 +848,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     // ---- types
     public static ResolvedType makeArray(ResolvedType type, int dim) {
        if (dim == 0) return type;
-       ResolvedType array = new Array("[" + type.getSignature(),"["+type.getErasureSignature(),type.getWorld(),type);
+       ResolvedType array = new ArrayReferenceType("[" + type.getSignature(),"["+type.getErasureSignature(),type.getWorld(),type);
        return makeArray(array,dim-1);
     }
     
@@ -1159,6 +1205,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
     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);
                }
         
@@ -1478,6 +1527,22 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
        //??? 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
+//                    }
                while (existingMembers.hasNext()) {
                        
                        ResolvedMember existingMember = (ResolvedMember)existingMembers.next();
@@ -1506,12 +1571,34 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                                          // 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)
-                                                 getWorld().getMessageHandler().handleMessage(
-                                                       MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
-                                                                       existingMember),
-                                                       munger.getSourceLocation())
-                                                 );
+                                         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())
+                                                         );
+                                                 }
+                                         }
                                        }
                                } else if (isDuplicateMemberWithinTargetType(existingMember,this,sig)) {
                                        getWorld().getMessageHandler().handleMessage(
@@ -2042,7 +2129,7 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
                        }
                        
                        for (int i = 0; i < typeParameters.length; i++) {
-                               UnresolvedType aType = (ResolvedType)typeParameters[i];
+                               ResolvedType aType = (ResolvedType)typeParameters[i];
                                if (aType.isTypeVariableReference()  && 
                                // assume the worst - if its definetly not a type declared one, it could be anything
                                                ((TypeVariableReference)aType).getTypeVariable().getDeclaringElementKind()!=TypeVariable.TYPE) {
index 594e31030a04fb077ab04d2b75cb3fcc0f37de16..f3c631399b36e4adeaf8f2a7ff84fe6734b2e4d6 100644 (file)
@@ -26,6 +26,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.aspectj.bridge.ISourceLocation;
@@ -68,6 +69,17 @@ public abstract class ResolvedTypeMunger {
                        if (declaringType.isRawType()) throw new IllegalStateException("Use generic type, not raw type");
                        if (declaringType.isParameterizedType()) throw new IllegalStateException("Use generic type, not parameterized type");
                }
+//             boolean aChangeOccurred = false;
+//             
+//             UnresolvedType rt = signature.getReturnType();
+//             if (rt.isParameterizedType() || rt.isGenericType()) {rt = rt.getRawType();aChangeOccurred=true;}
+//             UnresolvedType[] pt = signature.getParameterTypes();
+//             for (int i = 0; i < pt.length; i++) {
+//                     if (pt[i].isParameterizedType() || pt[i].isGenericType()) { pt[i] = pt[i].getRawType();aChangeOccurred=true;}
+//             }
+//             if (aChangeOccurred) {
+//                     this.signature = new ResolvedMemberImpl(signature.getKind(),signature.getDeclaringType(),signature.getModifiers(),rt,signature.getName(),pt,signature.getExceptions());
+//             }
        }
        
        public void setSourceLocation(ISourceLocation isl) {
@@ -424,5 +436,9 @@ public abstract class ResolvedTypeMunger {
        public boolean existsToSupportShadowMunging() {
                return false;
        }
+
+       public ResolvedTypeMunger parameterizeWith(Map m, World w) {
+               throw new BCException("Dont call parameterizeWith() on a type munger of this kind: "+this.getClass());
+       }
        
 }
index 1add44522c0e6e6a687b98aeb7e2ad48b1b2b36e..2726b82ebace3433c1dbfe3cdebf875b2a67328d 100644 (file)
@@ -44,7 +44,7 @@ import org.aspectj.weaver.bcel.BcelAdvice;
 public abstract class Shadow {
 
        // every Shadow has a unique id, doesn't matter if it wraps...
-       private static int nextShadowID = 100;  // easier to spot than zero.
+       private static int nextShadowID = 100;  // easier to spot than zero. // OPTIMIZE is this a bug? static?
        
        private final Kind kind; 
     private final Member signature;
@@ -187,6 +187,18 @@ public abstract class Shadow {
         return getSignature()
             .getParameterTypes().length;
     }
+    
+    /**
+     * Return name of the argument at position 'i' at this shadow.  This does not
+     * make sense for all shadows - but can be useful in the case of, for example,
+     * method-execution.
+     * @return null if it cannot be determined
+     */
+    public String getArgName(int i,World w) {
+       String [] names = getSignature().getParameterNames(w);
+       if (names==null || i>=names.length) return null;
+       return names[i];
+    }
        
        public abstract UnresolvedType getEnclosingType();      
 
@@ -732,7 +744,29 @@ public abstract class Shadow {
     }
     
     public String toResolvedString(World world) {
-       return getKind() + "(" + world.resolve(getSignature()).toGenericString() + ")";
+       StringBuffer sb = new StringBuffer();
+       sb.append(getKind());
+       sb.append("(");
+       Member m = getSignature();
+       if (m==null) {
+               sb.append("<<missing signature>>");
+       } else {
+               ResolvedMember rm = world.resolve(m);
+               if (rm==null) {
+                       sb.append("<<unresolvableMember:").append(m).append(">>");
+               } else {
+                       String genString = rm.toGenericString();
+                       if (genString==null) {
+                               sb.append("<<unableToGetGenericStringFor:").append(rm).append(">>");
+                       } else {
+                               sb.append(genString);
+                       }
+                       
+               }
+       }
+       sb.append(")");
+       return sb.toString();
+       // was: return getKind() + "(" + world.resolve(getSignature()).toGenericString() + ")";
     }
 
     /**
index bffb9f45dcedf3e8a7250c72c72dec31307c9f80..b173d340b0cf3a842bad05ade5833f1ac0ad8b99 100644 (file)
@@ -10,7 +10,6 @@
  *     PARC     initial implementation 
  * ******************************************************************/
 
-
 package org.aspectj.weaver;
 
 import java.io.File;
@@ -42,10 +41,9 @@ import org.aspectj.weaver.patterns.Pointcut;
  *     which may modify state.  
  * Then implement is called. 
  */
-
 public abstract class ShadowMunger implements PartialOrder.PartialComparable, IHasPosition {
-       protected Pointcut pointcut;
-       
+
+       protected Pointcut pointcut;    
        // these three fields hold the source location of this munger
        protected int start, end;
        protected ISourceContext sourceContext;
@@ -62,6 +60,7 @@ public abstract class ShadowMunger implements PartialOrder.PartialComparable, IH
                this.end = end;
                this.sourceContext = sourceContext;
        }
+
        
        public abstract ShadowMunger concretize(ResolvedType fromType, World world, PerClause clause);  
 
index 3168f9ca36494bb85085d835be1cabdc19e61a86..699f07de7efbd899b1b8ba26807f3b5b440c5998 100644 (file)
@@ -102,8 +102,8 @@ public class TypeFactory {
                        // (see pr122458) It is possible for a parameterized type to have *no* type parameters visible in its signature.
                        // This happens for an inner type of a parameterized type which simply inherits the type parameters
                        // of its parent.  In this case it is parameterized but theres no < in the signature.
-                       
                        int startOfParams = signature.indexOf('<');
+                       
                        if (startOfParams==-1) {
                                // Should be an inner type of a parameterized type - could assert there is a '$' in the signature....
                                String signatureErasure = "L" + signature.substring(1);
@@ -123,7 +123,7 @@ public class TypeFactory {
                                // the type parameters of interest are only those that apply to the 'last type' in the signature
                                // if the signature is 'PMyInterface<String>$MyOtherType;' then there are none...
                                String lastType = null;
-                               int nestedTypePosition = signature.indexOf("$");
+                               int nestedTypePosition = signature.indexOf("$", endOfParams); // don't look for $ INSIDE the parameters
                                if (nestedTypePosition!=-1) lastType = signature.substring(nestedTypePosition+1);
                                else                        lastType = new String(signature);
                                startOfParams = lastType.indexOf("<");
@@ -132,7 +132,6 @@ public class TypeFactory {
                                if (startOfParams!=-1) {
                                  typeParams = createTypeParams(lastType.substring(startOfParams +1, endOfParams));
                                }
-                               
                                return new UnresolvedType(signature,signatureErasure,typeParams);
                        }
                        // can't replace above with convertSigToType - leads to stackoverflow
index 4f6e8234b27397e990d920b20b14ab7b12a0ca55..e81574f2cf00491667f269137911880540fa5f4c 100644 (file)
@@ -70,7 +70,7 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T
 
        public UnresolvedType parameterize(Map typeBindings) {
                UnresolvedType ut = (UnresolvedType) typeBindings.get(getName());
-               if (ut!=null) return ut;
+               if (ut!=null) return world.resolve(ut);
                return this;
        }
        
index ea913c60be16a4040e8cbddebe64e3bcdee88baa..951294536ee161fdff2e30ba5d956337e51ad01b 100644 (file)
@@ -26,7 +26,7 @@ import org.aspectj.weaver.tools.Traceable;
 
 /**
  * A UnresolvedType represents a type to the weaver. It has a basic signature that knows 
- * nothing about type variables, type parameters, etc.. TypeXs are resolved in some World
+ * nothing about type variables, type parameters, etc.. UnresolvedTypes are resolved in some World
  * (a repository of types). When a UnresolvedType is resolved it turns into a 
  * ResolvedType which may be a primitive type, an array type or a ReferenceType. 
  * ReferenceTypes may refer to simple, generic, parameterized or type-variable
@@ -121,8 +121,8 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
     // this doesn't belong here and will get moved to ResolvedType later in the refactoring
        public static final String MISSING_NAME = "@missing@";
 
-    
-
+       // OPTIMIZE I dont think you can ask something unresolved what kind of type it is, how can it always know?  Push down into resolvedtype
+       // that will force references to resolvedtypes to be correct rather than relying on unresolvedtypes to answer questions
     protected TypeKind typeKind = TypeKind.SIMPLE; // what kind of type am I?
 
        /**
@@ -217,6 +217,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
      * that are type variable references are replaced by their matching type variable
      * binding.
      */
+    // OPTIMIZE methods like this just allow callers to be lazy and not ensure they are working with the right (resolved) subtype
     public UnresolvedType parameterize(Map typeBindings) {
        throw new UnsupportedOperationException("unable to parameterize unresolved type: " + signature);
     }
@@ -308,6 +309,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
      * @param      name   the java language type name in question.
      * @return     a type object representing that java language type.
      */
+    // OPTIMIZE change users of this to use forSignature, especially for simple cases
     public static UnresolvedType forName(String name) {
         return forSignature(nameToSignature(name));
     }
@@ -464,7 +466,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
 
     /**
      * Returns the name of this type in java language form (e.g. java.lang.Thread or boolean[]).
-     * This produces a more esthetically pleasing string than {@link java.lang.Class#getName()}.
+     * This produces a more aesthetically pleasing string than {@link java.lang.Class#getName()}.
      *
      * @return  the java language name of this type.
      */
@@ -664,7 +666,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
 
     // ---- helpers
     
-    public static String signatureToName(String signature) {
+    private static String signatureToName(String signature) {
         switch (signature.charAt(0)) {
             case 'B': return "byte";
             case 'C': return "char";
@@ -856,7 +858,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
        }
        
        public UnresolvedType[] getTypeParameters() {
-               return typeParameters == null ? new UnresolvedType[0] : typeParameters;
+               return typeParameters == null ? UnresolvedType.NONE : typeParameters;
        }
        
        /**
@@ -905,6 +907,7 @@ public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
         * from a generic method/ctor rather than a type variable from a generic type.  
         * Only subclasses know the answer...
         */
+       // OPTIMIZE don't allow this to be called, the caller must have a resolved entity
        public boolean isParameterizedWithAMemberTypeVariable() {
                throw new RuntimeException("I dont know - you should ask a resolved version of me: "+this);
        }
index d58251c70e9e08c6a3a01adde4ac84d496fe44d9..00b2e1f019b7c7dc59ffe9e843b741c3ef7086c3 100644 (file)
@@ -146,6 +146,10 @@ public class WeaverMessages {
        public static final String INCORRECT_TARGET_FOR_DECLARE_ANNOTATION = "incorrectTargetForDeclareAnnotation";
        public static final String NO_MATCH_BECAUSE_SOURCE_RETENTION = "noMatchBecauseSourceRetention";
        
+       // Annotation Value messages
+       public static final String INVALID_ANNOTATION_VALUE = "invalidAnnotationValue";
+       public static final String UNKNOWN_ANNOTATION_VALUE = "unknownAnnotationValue";
+       
        // < Java5 messages
        public static final String ATANNOTATION_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "atannotationNeedsJava5";
        public static final String ATWITHIN_ONLY_SUPPORTED_AT_JAVA5_LEVEL = "atwithinNeedsJava5";
diff --git a/weaver/src/org/aspectj/weaver/WeaverMetrics.java b/weaver/src/org/aspectj/weaver/WeaverMetrics.java
deleted file mode 100644 (file)
index ca4df91..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2004 IBM Corporation and others.
- * 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://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Andy Clement         initial implementation
- * ******************************************************************/
-package org.aspectj.weaver;
-
-import org.aspectj.util.FuzzyBoolean;
-
-
-/**
- * Records stats about the weaver.  Information like 'how many types are dismissed during fast match' that
- * may be useful for trying to tune pointcuts.  Not publicised.
- */
-public class WeaverMetrics {
-    
-       // Level 1 of matching is at the type level, which types can be dismissed?
-       public static int fastMatchOnTypeAttempted = 0;
-       public static int fastMatchOnTypeTrue = 0;
-       public static int fastMatchOnTypeFalse = 0;
-
-       // Level 2 of matching is fast matching on the shadows in the remaining types
-       public static int fastMatchOnShadowsAttempted = 0;
-       public static int fastMatchOnShadowsTrue = 0;
-       public static int fastMatchOnShadowsFalse = 0;
-       
-    // Level 3 of matching is slow matching on the shadows (more shadows than were fast matched on!)
-       public static int matchTrue = 0;
-       public static int matchAttempted = 0;
-
-
-       
-       public static void reset() {
-
-               fastMatchOnShadowsAttempted = 0;
-               fastMatchOnShadowsTrue = 0;
-               fastMatchOnShadowsFalse = 0;
-
-               fastMatchOnTypeAttempted = 0;
-               fastMatchOnTypeTrue = 0;
-               fastMatchOnTypeFalse = 0;
-       
-               matchTrue = 0;
-               matchAttempted = 0;
-       }       
-
-       
-       public static void dumpInfo() {
-               System.err.println("Match summary:");
-               int fastMatchOnTypeMaybe = (fastMatchOnTypeAttempted-fastMatchOnTypeTrue-fastMatchOnTypeFalse);
-               System.err.print("At the type level, we attempted #"+fastMatchOnTypeAttempted+" fast matches:");
-               System.err.println("   YES/NO/MAYBE = "+fastMatchOnTypeTrue+"/"+fastMatchOnTypeFalse+"/"+fastMatchOnTypeMaybe);
-               int fastMatchMaybe = (fastMatchOnShadowsAttempted-fastMatchOnShadowsFalse-fastMatchOnShadowsTrue);
-               System.err.print("Within those #"+(fastMatchOnTypeTrue+fastMatchOnTypeMaybe)+" possible types, ");
-               System.err.print("we fast matched on #"+fastMatchOnShadowsAttempted+" shadows:");
-               System.err.println("   YES/NO/MAYBE = "+fastMatchOnShadowsTrue+"/"+fastMatchOnShadowsFalse+"/"+fastMatchMaybe);
-               System.err.println("Shadow (non-fast) matches attempted #"+matchAttempted+" of which "+matchTrue+" successful");
-       }
-       
-
-       public static void recordFastMatchTypeResult(FuzzyBoolean fb) {
-               fastMatchOnTypeAttempted++;
-               if (fb.alwaysTrue()) fastMatchOnTypeTrue++;
-               if (fb.alwaysFalse()) fastMatchOnTypeFalse++;
-       }
-       
-       public static void recordFastMatchResult(FuzzyBoolean fb) {
-               fastMatchOnShadowsAttempted++;
-               if (fb.alwaysTrue())  fastMatchOnShadowsTrue++;
-               if (fb.alwaysFalse()) fastMatchOnShadowsFalse++;
-       }
-       
-       public static void recordMatchResult(boolean b) {
-               matchAttempted++;
-               if (b) matchTrue++;
-       }
-
-}
index 6c4dcc1df1fb7ba25d5a9d35b10e2ce13b6e6f80..f202f76cb8bca1c7e4dcdc66c6683091e53ee0db 100644 (file)
@@ -139,7 +139,7 @@ public class WeaverStateInfo {
                            readAnyReweavableData(wsi,s);
                                return wsi;
                } 
-               throw new RuntimeException("bad WeaverState.Kind: " + b);
+               throw new RuntimeException("bad WeaverState.Kind: " + b+".  File was :"+(context==null?"unknown":context.makeSourceLocation(0,0).toString()));
        }
        
        
index 0b6cfc325e51fdbd804514fcc37444b05f8e6c13..bdda663e03fe27ec4c35ede94c25a61b4505ab34 100644 (file)
@@ -17,13 +17,17 @@ package org.aspectj.weaver;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
+import java.util.AbstractMap;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.WeakHashMap;
 
 import org.aspectj.asm.IHierarchy;
 import org.aspectj.bridge.IMessageHandler;
@@ -38,9 +42,9 @@ import org.aspectj.weaver.patterns.DeclarePrecedence;
 import org.aspectj.weaver.patterns.PerClause;
 import org.aspectj.weaver.patterns.Pointcut;
 import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
+import org.aspectj.weaver.tools.PointcutDesignatorHandler;
 import org.aspectj.weaver.tools.Trace;
 import org.aspectj.weaver.tools.TraceFactory;
-import java.util.*;
 
 /**
  * A World is a collection of known types and crosscutting members.
@@ -58,6 +62,9 @@ public abstract class World implements Dump.INode {
        /** The heart of the world, a map from type signatures to resolved types */
     protected TypeMap typeMap = new TypeMap(this); // Signature to ResolvedType
 
+    /** New pointcut designators this world supports */
+    private Set pointcutDesignators;
+
     // see pr145963
     /** Should we create the hierarchy for binary classes and aspects*/
     public static boolean createInjarHierarchy = true;
@@ -111,6 +118,7 @@ public abstract class World implements Dump.INode {
        private boolean runMinimalMemory = false;
        private boolean shouldPipelineCompilation = true;
        protected boolean bcelRepositoryCaching = xsetBCEL_REPOSITORY_CACHING_DEFAULT.equalsIgnoreCase("true");
+       private boolean goforit = false; // TODO better name
        private boolean completeBinaryTypes = false;
        public boolean forDEBUG_structuralChangesCode = false;
        public boolean forDEBUG_bridgingCode = false;
@@ -265,7 +273,7 @@ public abstract class World implements Dump.INode {
         if (ty.isArray()) {
                ResolvedType componentType = resolve(ty.getComponentType(),allowMissing);
                //String brackets = signature.substring(0,signature.lastIndexOf("[")+1);
-            ret = new ResolvedType.Array(signature, "["+componentType.getErasureSignature(),
+            ret = new ArrayReferenceType(signature, "["+componentType.getErasureSignature(),
                                             this, 
                                             componentType);
         } else {
@@ -788,6 +796,8 @@ public abstract class World implements Dump.INode {
        public Properties getExtraConfiguration() {
                return extraConfiguration;
        }
+    public final static String xsetWEAVE_JAVA_PACKAGES = "weaveJavaPackages"; // default false - controls LTW
+    public final static String xsetWEAVE_JAVAX_PACKAGES = "weaveJavaxPackages"; // default false - controls LTW
        public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default false
        public final static String xsetACTIVATE_LIGHTWEIGHT_DELEGATES = "activateLightweightDelegates"; // default true
        public final static String xsetRUN_MINIMAL_MEMORY ="runMinimalMemory"; // default true
@@ -799,6 +809,7 @@ public abstract class World implements Dump.INode {
        public final static String xsetCOMPLETE_BINARY_TYPES = "completeBinaryTypes";
        public final static String xsetCOMPLETE_BINARY_TYPES_DEFAULT = "false"; 
        public final static String xsetBCEL_REPOSITORY_CACHING_DEFAULT = "true"; 
+       public final static String xsetGO_FOR_IT = "goforit"; 
        
        public boolean isInJava5Mode() {
                return behaveInJava5Way;
@@ -817,7 +828,6 @@ public abstract class World implements Dump.INode {
        public boolean isJoinpointArrayConstructionEnabled() {
                return optionalJoinpoint_ArrayConstruction;
        }
-
        public boolean isJoinpointSynchronizationEnabled() {
                return optionalJoinpoint_Synchronization;
        }
@@ -856,7 +866,7 @@ public abstract class World implements Dump.INode {
                private Map /* String -> ResolvedType */ tMap = new HashMap();
                
                // Map of types that may be ejected from the cache if we need space
-               private Map expendableMap = new SoftHashMap();
+               private Map expendableMap = Collections.synchronizedMap(new WeakHashMap());//new SoftHashMap();
                
                public static class SoftHashMap extends AbstractMap {
                          private Map map;
@@ -1020,16 +1030,32 @@ public abstract class World implements Dump.INode {
                                String key = (String) iter.next();
                                ResolvedType type = (ResolvedType)tMap.get(key);
                                if (type==null) continue;//throw new RuntimeException("Unexpected!! "+key);
-                               if (type.isAspect() ) continue;
+                               if (type.isAspect() || (type.getSuperclass()!=null && type.getSuperclass().isAspect())) continue;
                                if (type.equals(UnresolvedType.OBJECT)) continue;
                                if (type.isPrimitiveType()) continue;
                                List typeMungers = type.getInterTypeMungers();
                                if (typeMungers==null || typeMungers.size()==0) {
                                        // demote - we can recover this
                                        tMap.remove(key);
+                                       
+                                       // didnt achieve anything...
+//                                     // force the data out of memory - this may not happen if a bcel object type was loaded for
+//                                     // something not necessarily being woven as that will never go through the lifecycle states
+//                                     ReferenceTypeDelegate delly = ((ReferenceType)type).getDelegate();
+//                                     if (delly instanceof BcelObjectType) {
+//                                             ((BcelObjectType)delly).weavingCompleted();
+//                                             // that shouldnt be weavingCompleted, but it will do for now...
+//                                     }
                                        // extreme demotion if you dont use these next two lines!
-//                                     if (memoryProfiling) expendableMap.put(key,new SoftReference(type,rq));
-//                                     else                 expendableMap.put(key,new SoftReference(type));
+                                       if (policy==USE_WEAK_REFS) {
+                                           if (memoryProfiling) expendableMap.put(key,new WeakReference(type,rq));
+                                           else                 expendableMap.put(key,new WeakReference(type));
+                                       } else if (policy==USE_SOFT_REFS) {
+                                               if (memoryProfiling) expendableMap.put(key,new SoftReference(type,rq));
+                                               else                 expendableMap.put(key,new SoftReference(type));
+                                       } else {
+                                         expendableMap.put(key,type);
+                                       }
                                        count++;
                                }
                        }
@@ -1140,11 +1166,11 @@ public abstract class World implements Dump.INode {
            public int hardSize() {
                return tMap.size();
            }
-       }       
-       
+               }
+
        public void demote() {
                typeMap.demote();
-       }
+       }       
        
        /** Reference types we don't intend to weave may be ejected from
         * the cache if we need the space.
@@ -1157,7 +1183,6 @@ public abstract class World implements Dump.INode {
                                  (!type.isPrimitiveType())
                                );
        }
-       
 
        /**
         * This class is used to compute and store precedence relationships between
@@ -1290,6 +1315,10 @@ public abstract class World implements Dump.INode {
                                if (!bcelRepositoryCaching) {
                                        getMessageHandler().handleMessage(MessageUtil.info("[bcelRepositoryCaching=false] AspectJ will not use a bcel cache for class information"));
                                }
+
+                               s = p.getProperty(xsetGO_FOR_IT,"false");
+                               goforit = s.equalsIgnoreCase("true");
+                               
                                
                                s = p.getProperty(xsetPIPELINE_COMPILATION,xsetPIPELINE_COMPILATION_DEFAULT);
                                shouldPipelineCompilation = s.equalsIgnoreCase("true");
@@ -1321,6 +1350,11 @@ public abstract class World implements Dump.INode {
              ensureAdvancedConfigurationProcessed();
                  return runMinimalMemory;
            }
+
+           public boolean shouldGoForIt() {
+             ensureAdvancedConfigurationProcessed();
+                 return goforit;
+           }
            
            public boolean shouldPipelineCompilation() {
                ensureAdvancedConfigurationProcessed();
@@ -1353,4 +1387,25 @@ public abstract class World implements Dump.INode {
            public boolean isASMAround() { 
                return isASMAround;
            }
+//         
+//             public ResolvedType[] getAllTypes() {
+//                     return typeMap.getAllTypes();
+//             }
+
+        /**
+         * Register a new pointcut designator handler with the world - this can be used by any pointcut parsers attached
+         * to the world.
+         * 
+         * @param designatorHandler handler for the new pointcut
+         */
+        public void registerPointcutHandler(PointcutDesignatorHandler designatorHandler) {
+            if (pointcutDesignators == null) pointcutDesignators = new HashSet();
+            pointcutDesignators.add(designatorHandler);
+        }
+        
+        public Set getRegisteredPointcutHandlers() {
+            if (pointcutDesignators == null) return Collections.EMPTY_SET;
+            return pointcutDesignators;
+        }
+        
 }
\ No newline at end of file
index e10fa4797bbf05b480bfb37ae9be21d99458a781..6a735adb15adb24e7254adfcd1a10ed4ee4db0cc 100644 (file)
@@ -41,4 +41,5 @@ cantFindTypeAffectingJPMatch = warning
 unorderedAdviceAtShadow=ignore
 swallowedExceptionInCatchBlock=ignore
 calculatingSerialVersionUID=ignore
-advisingSynchronizedMethods=warning
\ No newline at end of file
+advisingSynchronizedMethods=warning
+mustWeaveXmlDefinedAspects=warning
\ No newline at end of file
index 1826f9c05b62c800f9b9742248b366d9e0f78dd6..d6db5727f4940a9c52f3860141a7647767d45923 100644 (file)
@@ -15,11 +15,11 @@ package org.aspectj.weaver.ast;
 
 
 public class Not extends Test {
-       Test body;
+       Test test;
 
-       public Not(Test left) {
+       public Not(Test test) {
                super();
-               this.body = left;
+               this.test = test;
        }
 
        public void accept(ITestVisitor v) {
@@ -27,17 +27,17 @@ public class Not extends Test {
        }
        
        public Test getBody() {
-               return body;
+               return test;
        }
        
        public String toString() {
-               return "!" + body;
+               return "!" + test;
        }
 
        public boolean equals(Object other) {
                if (other instanceof Not) {
                        Not o = (Not) other;
-                       return o.body.equals(body);
+                       return o.test.equals(test);
                } else {
                        return false;
                }
index 920bd01fa01c6774d1f33775b4add90776ef207e..3b2450d1652704783972242dcdfccd0ef8d0e951 100644 (file)
@@ -15,21 +15,20 @@ package org.aspectj.weaver.ast;
 
 import org.aspectj.weaver.ResolvedType;
 
-
 public class Var extends Expr {
-       ResolvedType type;
+       ResolvedType variableType;
 
-       public Var(ResolvedType type) {
+       public Var(ResolvedType variableType) {
                super();
-               this.type = type;               
+               this.variableType = variableType;               
        }
     
        public ResolvedType getType() {
-               return type;
+               return variableType;
        }
 
        public String toString() {
-               return "(Var " + type + ")";
+               return "(Var " + variableType + ")";
        }
     
     public void accept(IExprVisitor v) {
diff --git a/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java b/weaver/src/org/aspectj/weaver/bcel/AnnotationAccessVar.java
new file mode 100644 (file)
index 0000000..c58f58d
--- /dev/null
@@ -0,0 +1,160 @@
+/* *******************************************************************
+ * Copyright (c) 2005-2008 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.weaver.bcel;
+
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.generic.Instruction;
+import org.aspectj.apache.bcel.generic.InstructionConstants;
+import org.aspectj.apache.bcel.generic.InstructionFactory;
+import org.aspectj.apache.bcel.generic.InstructionList;
+import org.aspectj.apache.bcel.generic.ObjectType;
+import org.aspectj.apache.bcel.generic.Type;
+import org.aspectj.weaver.Member;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.Shadow.Kind;
+
+/**
+ * Represents access to an annotation on an element, relating to some kinded pointcut.
+ * Depending on the kind of pointcut the element might be a field or a method and the code
+ * generators in here can retrieve the annotation from the element.
+ */
+public class AnnotationAccessVar extends BcelVar {
+
+       private Kind   kind;                  // What kind of shadow are we at?
+       private UnresolvedType containingType;  // The type upon which we want to ask for 'member'
+       private Member member;                // Holds the member that has the annotations (for method/field join points)
+       
+       public AnnotationAccessVar(Kind kind, ResolvedType annotationType, UnresolvedType theTargetIsStoredHere, Member sig) {
+               super(annotationType,0);
+               this.kind = kind;
+               this.containingType = theTargetIsStoredHere; 
+               this.member = sig;
+       }
+
+       public String toString() {
+               return "AnnotationAccessVar(" + getType() +")";
+       }
+
+    public Instruction createLoad(InstructionFactory fact) {
+               throw new IllegalStateException("unimplemented");
+    }
+    public Instruction createStore(InstructionFactory fact) {
+       throw new IllegalStateException("unimplemented");
+    }
+
+    public InstructionList createCopyFrom(InstructionFactory fact, int oldSlot) {
+        throw new IllegalStateException("unimplemented");
+    }
+    
+       public void appendLoad(InstructionList il, InstructionFactory fact) {
+               il.append(createLoadInstructions(getType(), fact));
+       }
+
+       public void appendLoadAndConvert(InstructionList il, InstructionFactory fact, ResolvedType toType) {
+               il.append(createLoadInstructions(toType, fact));                                
+       }
+
+       public void insertLoad(InstructionList il, InstructionFactory fact) {
+               il.insert(createLoadInstructions(getType(), fact));
+       }
+
+       private InstructionList createLoadInstructions(ResolvedType toType, InstructionFactory fact) {
+               
+               InstructionList il = new InstructionList();
+               
+               Type jlClass = BcelWorld.makeBcelType(UnresolvedType.JAVA_LANG_CLASS);
+               Type jlString = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.String;"));
+               Type jlClassArray = BcelWorld.makeBcelType(UnresolvedType.forSignature("[Ljava.lang.Class;"));  
+               Type jlaAnnotation = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.annotation.Annotation;"));
+
+        Instruction pushConstant = fact.createConstant(new ObjectType(toType.getName()));
+        
+               if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || 
+                       kind==Shadow.PreInitialization || kind==Shadow.Initialization || 
+                       kind==Shadow.ConstructorCall || kind==Shadow.ConstructorExecution ||
+                       kind==Shadow.AdviceExecution || 
+                       // annotations for fieldset/fieldget when an ITD is involved are stored against a METHOD 
+                       ((kind==Shadow.FieldGet || kind==Shadow.FieldSet) && member.getKind()==Member.METHOD)) {
+                       
+                       Type jlrMethod = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Method;"));
+                       Type[] paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
+
+                       il.append(fact.createConstant(BcelWorld.makeBcelType(containingType)));
+       
+                       if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || kind==Shadow.AdviceExecution || 
+                         // annotations for fieldset/fieldget when an ITD is involved are stored against a METHOD 
+                         ((kind==Shadow.FieldGet || kind==Shadow.FieldSet) && member.getKind()==Member.METHOD) ||
+                         ((kind==Shadow.ConstructorCall || kind==Shadow.ConstructorExecution) && member.getKind()==Member.METHOD)) {
+
+                               il.append(fact.createConstant(member.getName()));
+                               buildArray(il,fact,jlClass,paramTypes,1);
+                               // OPTIMIZE cache result of getDeclaredMethod and getAnnotation?  Might be able to use it again if someone else needs the same annotations?
+                               il.append(fact.createInvoke("java/lang/Class","getDeclaredMethod",jlrMethod,new Type[]{jlString,jlClassArray},Constants.INVOKEVIRTUAL));
+                       il.append(pushConstant);//fact.createConstant(new ObjectType(toType.getName())));               
+                               il.append(fact.createInvoke("java/lang/reflect/Method","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+                   } else { // init/preinit/ctor-call/ctor-exec
+                               buildArray(il,fact,jlClass,paramTypes,1);
+                               Type jlrCtor = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Constructor;"));
+                               // OPTIMIZE cache result of getDeclaredConstructor and getAnnotation?  Might be able to use it again if someone else needs the same annotations?
+                               il.append(fact.createInvoke("java/lang/Class","getDeclaredConstructor",jlrCtor,new Type[]{jlClassArray},Constants.INVOKEVIRTUAL));
+                       il.append(pushConstant);
+                               il.append(fact.createInvoke("java/lang/reflect/Constructor","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+                   }
+           } else if (kind == Shadow.FieldSet || kind == Shadow.FieldGet) {
+                       Type jlrField = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Field;"));
+                       il.append(fact.createConstant(BcelWorld.makeBcelType(containingType))); // Stick the target on the stack
+                       il.append(fact.createConstant(member.getName())); // Stick what we are after on the stack
+                       il.append(fact.createInvoke("java/lang/Class","getDeclaredField",jlrField,new Type[]{jlString},Constants.INVOKEVIRTUAL));
+               il.append(pushConstant);
+               il.append(fact.createInvoke("java/lang/reflect/Field","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+           } else if (kind == Shadow.StaticInitialization || kind==Shadow.ExceptionHandler) {
+                       il.append(fact.createConstant(BcelWorld.makeBcelType(containingType)));
+               il.append(pushConstant);
+               il.append(fact.createInvoke("java/lang/Class","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
+               } else {
+                   throw new RuntimeException("Don't understand this kind "+kind);
+               }
+               il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
+               return il;
+       }
+       
+
+       private void buildArray(InstructionList il, InstructionFactory fact, Type arrayElementType, Type[] arrayEntries,int dim) {
+        il.append(fact.createConstant(Integer.valueOf(arrayEntries==null?0:arrayEntries.length)));
+        il.append(fact.createNewArray(arrayElementType,(short)dim));
+        if (arrayEntries == null) return;
+        for (int i = 0; i < arrayEntries.length; i++) {
+                       il.append(InstructionFactory.createDup(1));
+                       il.append(fact.createConstant(Integer.valueOf(i)));
+               switch (arrayEntries[i].getType()) {
+                 case Constants.T_ARRAY:
+                   il.append(fact.createConstant(new ObjectType(arrayEntries[i].getSignature())));
+                   break;
+                 case Constants.T_BOOLEAN: il.append(fact.createGetStatic("java/lang/Boolean","TYPE",arrayElementType)); break;
+                 case Constants.T_BYTE:il.append(fact.createGetStatic("java/lang/Byte","TYPE",arrayElementType)); break;
+                 case Constants.T_CHAR:il.append(fact.createGetStatic("java/lang/Character","TYPE",arrayElementType)); break;
+                 case Constants.T_INT:il.append(fact.createGetStatic("java/lang/Integer","TYPE",arrayElementType)); break;
+                 case Constants.T_LONG:il.append(fact.createGetStatic("java/lang/Long","TYPE",arrayElementType)); break;
+                 case Constants.T_DOUBLE:il.append(fact.createGetStatic("java/lang/Double","TYPE",arrayElementType)); break;
+                 case Constants.T_FLOAT:il.append(fact.createGetStatic("java/lang/Float","TYPE",arrayElementType)); break;
+                 case Constants.T_SHORT:il.append(fact.createGetStatic("java/lang/Short","TYPE",arrayElementType)); break;
+                 default:
+                   il.append(fact.createConstant(arrayEntries[i]));
+               }
+                       il.append(InstructionConstants.AASTORE);
+               }
+       }
+
+}
index 96d393126a2a00925ecd9fcf9ca9eb359f13fa1f..c66819921f6e55561344f27f6f9bf17cf5150e99 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.StringTokenizer;
 
 import org.aspectj.apache.bcel.Constants;
 import org.aspectj.apache.bcel.classfile.Attribute;
@@ -74,9 +75,7 @@ import org.aspectj.weaver.patterns.SimpleScope;
 import org.aspectj.weaver.patterns.TypePattern;
 
 /**
- * Annotation defined aspect reader.
- * <p/>
- * It reads the Java 5 annotations and turns them into AjAttributes
+ * Annotation defined aspect reader. Reads the Java 5 annotations and turns them into AjAttributes
  *
  * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
  */
@@ -85,6 +84,7 @@ public class AtAjAttributes {
     private final static List EMPTY_LIST = new ArrayList();
     private final static String[] EMPTY_STRINGS = new String[0];
     private final static String VALUE = "value";
+    private final static String ARGNAMES = "argNames";
     private final static String POINTCUT = "pointcut";
     private final static String THROWING = "throwing";
     private final static String RETURNING = "returning";
@@ -92,8 +92,6 @@ public class AtAjAttributes {
 
     /**
      * A struct that allows to add extra arguments without always breaking the API
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
      */
     private static class AjAttributeStruct {
 
@@ -124,11 +122,9 @@ public class AtAjAttributes {
      */
     private static class AjAttributeMethodStruct extends AjAttributeStruct {
 
-        /**
-         * Argument names as they appear in the SOURCE code, ordered, and lazyly populated
-         * Used to do formal binding
-         */
+       // argument names used for formal binding
         private String[] m_argumentNamesLazy = null;
+        public String unparsedArgumentNames = null; // Set only if discovered as argNames attribute of annotation
 
         final Method method;
         final BcelMethod bMethod;
@@ -141,7 +137,7 @@ public class AtAjAttributes {
 
         public String[] getArgumentNames() {
             if (m_argumentNamesLazy == null) {
-                m_argumentNamesLazy = getMethodArgumentNamesAsInSource(method);
+                m_argumentNamesLazy = getMethodArgumentNames(method,unparsedArgumentNames,this);
             }
             return m_argumentNamesLazy;
         }
@@ -149,8 +145,6 @@ public class AtAjAttributes {
 
     /**
      * A struct when we read @AJ on field
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
      */
     private static class AjAttributeFieldStruct extends AjAttributeStruct {
 
@@ -184,15 +178,19 @@ public class AtAjAttributes {
      * @return list of AjAttributes
      */
     public static List readAj5ClassAttributes(JavaClass javaClass, ReferenceType type, ISourceContext context, IMessageHandler msgHandler, boolean isCodeStyleAspect) {
-        //FIXME AV - 1.5 feature limitation, kick after implemented
-        try {
-            Constant[] cpool = javaClass.getConstantPool().getConstantPool();
-            for (int i = 0; i < cpool.length; i++) {
-                Constant constant = cpool[i];
-                if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) {
-                    if (!javaClass.getClassName().startsWith("org.aspectj.lang.annotation")) {
-                        ConstantUtf8 constantUtf8 = (ConstantUtf8) constant;
-                        if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantUtf8.getBytes())) {
+       boolean ignoreThisClass = javaClass.getClassName().charAt(0)=='o' && javaClass.getClassName().startsWith("org.aspectj.lang.annotation");
+       if (ignoreThisClass) return EMPTY_LIST;
+       boolean containsPointcut = false;
+               boolean containsAnnotationClassReference = false;
+        Constant[] cpool = javaClass.getConstantPool().getConstantPool();
+        for (int i = 0; i < cpool.length; i++) {
+            Constant constant = cpool[i];
+            if (constant != null && constant.getTag() == Constants.CONSTANT_Utf8) {
+                String constantValue = ((ConstantUtf8)constant).getBytes();
+                if (constantValue.length()>28 && constantValue.charAt(1)=='o') {
+                       if (constantValue.startsWith("Lorg/aspectj/lang/annotation")) {
+                               containsAnnotationClassReference=true;
+                               if ("Lorg/aspectj/lang/annotation/DeclareAnnotation;".equals(constantValue)) {
                             msgHandler.handleMessage(
                                     new Message(
                                             "Found @DeclareAnnotation while current release does not support it (see '" + type.getName() + "')",
@@ -202,13 +200,14 @@ public class AtAjAttributes {
                                     )
                             );
                         }
-                    }
+                        if ("Lorg/aspectj/lang/annotation/Pointcut;".equals(constantValue)) {
+                               containsPointcut=true;
+                        }
+                       }
                 }
             }
-        } catch (Throwable t) {
-            ;
         }
-
+        if (!containsAnnotationClassReference) return EMPTY_LIST;
 
         AjAttributeStruct struct = new AjAttributeStruct(type, context, msgHandler);
         Attribute[] attributes = javaClass.getAttributes();
@@ -219,7 +218,7 @@ public class AtAjAttributes {
             Attribute attribute = attributes[i];
             if (acceptAttribute(attribute)) {
                 RuntimeAnnotations rvs = (RuntimeAnnotations) attribute;
-                // we don't need to look for several attribute occurence since it cannot happen as per JSR175
+                // we don't need to look for several attribute occurrences since it cannot happen as per JSR175
                 if (!isCodeStyleAspect && !javaClass.isInterface()) {
                     hasAtAspectAnnotation = handleAspectAnnotation(rvs, struct);
                     //TODO AV - if put outside the if isCodeStyleAspect then we would enable mix style
@@ -245,11 +244,10 @@ public class AtAjAttributes {
         }
 
         // the following block will not detect @Pointcut in non @Aspect types for optimization purpose
-        if (!hasAtAspectAnnotation) {
+        if (!hasAtAspectAnnotation && !containsPointcut) {
             return EMPTY_LIST;
         }
 
-
         //FIXME AV - turn on when ajcMightHaveAspect
 //        if (hasAtAspectAnnotation && type.isInterface()) {
 //            msgHandler.handleMessage(
@@ -282,31 +280,35 @@ public class AtAjAttributes {
         // we need to gather the @AJ pointcut right now and not at method level annotation extraction time
         // in order to be able to resolve the pointcut references later on
         // we don't need to look in super class, the pointcut reference in the grammar will do it
+        
         for (int i = 0; i < javaClass.getMethods().length; i++) {
             Method method = javaClass.getMethods()[i];
             if (method.getName().startsWith(NameMangler.PREFIX)) continue;  // already dealt with by ajc...
             //FIXME alex optimize, this method struct will gets recreated for advice extraction
-            AjAttributeMethodStruct mstruct = new AjAttributeMethodStruct(method, null, type, context, msgHandler);//FIXME AVASM
+            AjAttributeMethodStruct mstruct = null;
+            boolean processedPointcut = false;
             Attribute[] mattributes = method.getAttributes();
-
             for (int j = 0; j < mattributes.length; j++) {
                 Attribute mattribute = mattributes[j];
                 if (acceptAttribute(mattribute)) {
-                    RuntimeAnnotations mrvs = (RuntimeAnnotations) mattribute;
-                    handlePointcutAnnotation(mrvs, mstruct);
+                       if (mstruct==null) mstruct = new AjAttributeMethodStruct(method, null, type, context, msgHandler);//FIXME AVASM
+                    processedPointcut = handlePointcutAnnotation((RuntimeAnnotations) mattribute, mstruct);
                     // there can only be one RuntimeVisible bytecode attribute
                     break;
                 }
             }
-            // FIXME asc should check we aren't adding multiple versions... will do once I get the tests passing again...
-            struct.ajAttributes.add(new AjAttribute.WeaverVersionInfo());
-            struct.ajAttributes.addAll(mstruct.ajAttributes);
+            if (processedPointcut) {
+                   // FIXME asc should check we aren't adding multiple versions... will do once I get the tests passing again...
+                   struct.ajAttributes.add(new AjAttribute.WeaverVersionInfo());
+                   struct.ajAttributes.addAll(mstruct.ajAttributes);
+            }
         }
 
 
         // code style declare error / warning / implements / parents are field attributes
-        for (int i = 0; i < javaClass.getFields().length; i++) {
-            Field field = javaClass.getFields()[i];
+        Field[] fs = javaClass.getFields();
+        for (int i = 0; i < fs.length; i++) {
+            Field field = fs[i];
             if (field.getName().startsWith(NameMangler.PREFIX)) continue;  // already dealt with by ajc...
             //FIXME alex optimize, this method struct will gets recreated for advice extraction
             AjAttributeFieldStruct fstruct = new AjAttributeFieldStruct(field, null, type, context, msgHandler);
@@ -742,28 +744,27 @@ public class AtAjAttributes {
                     for (int i = 0; i < methods.length; i++) {
                         ResolvedMember method = (ResolvedMember)methods[i];
                         if (method.isAbstract()) {
-                            if (defaultImplClassName == null) {
-                                // non marker interface with no default impl provided
-                                reportError("@DeclareParents: used with a non marker interface and no defaultImpl=\"...\" provided", struct);
-                                return false;
-                            }
+                        // moved to be detected at weave time if the target doesnt implement the methods
+//                            if (defaultImplClassName == null) {
+//                                // non marker interface with no default impl provided
+//                                reportError("@DeclareParents: used with a non marker interface and no defaultImpl=\"...\" provided", struct);
+//                                return false;
+//                            }
                             hasAtLeastOneMethod = true;
-
-                            struct.ajAttributes.add(
-                                    new AjAttribute.TypeMunger(
-                                            new MethodDelegateTypeMunger(
-                                                method,
-                                                struct.enclosingType,
-                                                defaultImplClassName,
-                                                typePattern
-                                            )
-                                    )
-                            );
+                            MethodDelegateTypeMunger mdtm = 
+                                new MethodDelegateTypeMunger(
+                                    method,
+                                    struct.enclosingType,
+                                    defaultImplClassName,
+                                    typePattern
+                                );
+                            mdtm.setSourceLocation(struct.enclosingType.getSourceLocation());
+                            struct.ajAttributes.add(new AjAttribute.TypeMunger(mdtm));
                         }
                     }
                     // successfull so far, we thus need a bcel type munger to have
                     // a field hosting the mixin in the target type
-                    if (hasAtLeastOneMethod) {
+                    if (hasAtLeastOneMethod && defaultImplClassName!=null) {
                         struct.ajAttributes.add(
                                 new AjAttribute.TypeMunger(
                                         new MethodDelegateTypeMunger.FieldHostTypeMunger(
@@ -802,6 +803,10 @@ public class AtAjAttributes {
             ElementNameValuePairGen beforeAdvice = getAnnotationElement(before, VALUE);
             if (beforeAdvice != null) {
                 // this/target/args binding
+               String argumentNames = getArgNamesValue(before);
+                if (argumentNames!=null) {
+                       struct.unparsedArgumentNames = argumentNames;
+                }
                 FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
                 try {
                     bindings = extractBindings(struct);
@@ -859,6 +864,10 @@ public class AtAjAttributes {
             if (afterAdvice != null) {
                 // this/target/args binding
                 FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                String argumentNames = getArgNamesValue(after);
+                if (argumentNames!=null) {
+                       struct.unparsedArgumentNames = argumentNames;
+                }
                 try {
                     bindings = extractBindings(struct);
                 } catch (UnreadableDebugInfoException unreadableDebugInfoException) {
@@ -948,7 +957,10 @@ public class AtAjAttributes {
                     }
                 }
             }
-
+            String argumentNames = getArgNamesValue(after);
+            if (argumentNames!=null) {
+               struct.unparsedArgumentNames = argumentNames;
+            }
             // this/target/args binding
             // exclude the return binding from the pointcut binding since it is an extraArg binding
             FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
@@ -1045,7 +1057,10 @@ public class AtAjAttributes {
                     }
                 }
             }
-
+            String argumentNames = getArgNamesValue(after);
+            if (argumentNames!=null) {
+               struct.unparsedArgumentNames = argumentNames;
+            }
             // this/target/args binding
             // exclude the throwned binding from the pointcut binding since it is an extraArg binding
             FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
@@ -1106,7 +1121,11 @@ public class AtAjAttributes {
         if (around != null) {
             ElementNameValuePairGen aroundAdvice = getAnnotationElement(around, VALUE);
             if (aroundAdvice != null) {
-                // this/target/args binding
+                // this/target/args binding 
+               String argumentNames = getArgNamesValue(around);
+                if (argumentNames!=null) {
+                       struct.unparsedArgumentNames = argumentNames;
+                }
                 FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
                 try {
                     bindings = extractBindings(struct);
@@ -1154,83 +1173,93 @@ public class AtAjAttributes {
      *
      * @param runtimeAnnotations
      * @param struct
+     * @return true if a pointcut was handled
      */
-    private static void handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
+    private static boolean handlePointcutAnnotation(RuntimeAnnotations runtimeAnnotations, AjAttributeMethodStruct struct) {
         AnnotationGen pointcut = getAnnotation(runtimeAnnotations, AjcMemberMaker.POINTCUT_ANNOTATION);
-        if (pointcut != null) {
-            ElementNameValuePairGen pointcutExpr = getAnnotationElement(pointcut, VALUE);
-
-            // semantic check: the method must return void, or be "public static boolean" for if() support
-            if (!(Type.VOID.equals(struct.method.getReturnType())
-                  || (Type.BOOLEAN.equals(struct.method.getReturnType()) && struct.method.isStatic() && struct.method.isPublic()))) {
-                reportWarning("Found @Pointcut on a method not returning 'void' or not 'public static boolean'", struct);
-                ;//no need to stop
-            }
+        if (pointcut==null) return false;
+        ElementNameValuePairGen pointcutExpr = getAnnotationElement(pointcut, VALUE);
 
-            // semantic check: the method must not throw anything
-            if (struct.method.getExceptionTable() != null) {
-                reportWarning("Found @Pointcut on a method throwing exception", struct);
-                ;// no need to stop
-            }
+        
+        // semantic check: the method must return void, or be "public static boolean" for if() support
+        if (!(Type.VOID.equals(struct.method.getReturnType())
+              || (Type.BOOLEAN.equals(struct.method.getReturnType()) && struct.method.isStatic() && struct.method.isPublic()))) {
+            reportWarning("Found @Pointcut on a method not returning 'void' or not 'public static boolean'", struct);
+            ;//no need to stop
+        }
 
-            // this/target/args binding
-            final IScope binding;
-            try {
+        // semantic check: the method must not throw anything
+        if (struct.method.getExceptionTable() != null) {
+            reportWarning("Found @Pointcut on a method throwing exception", struct);
+            ;// no need to stop
+        }
+
+        String argumentNames = getArgNamesValue(pointcut);
+        if (argumentNames!=null) {
+               struct.unparsedArgumentNames = argumentNames;
+        }
+        // this/target/args binding
+        final IScope binding;
+        try {
+               if (struct.method.isAbstract()) {
+                   binding = null;
+               } else {
                 binding = new BindingScope(
-                        struct.enclosingType,
-                        struct.context,
-                        extractBindings(struct)
+                    struct.enclosingType,
+                    struct.context,
+                    extractBindings(struct)
                 );
-            } catch (UnreadableDebugInfoException e) {
-                return;
-            }
+               }
+        } catch (UnreadableDebugInfoException e) {
+            return false;
+        }
 
-            UnresolvedType[] argumentTypes = new UnresolvedType[struct.method.getArgumentTypes().length];
-            for (int i = 0; i < argumentTypes.length; i++) {
-                argumentTypes[i] = UnresolvedType.forSignature(struct.method.getArgumentTypes()[i].getSignature());
-            }
+        UnresolvedType[] argumentTypes = new UnresolvedType[struct.method.getArgumentTypes().length];
+        for (int i = 0; i < argumentTypes.length; i++) {
+            argumentTypes[i] = UnresolvedType.forSignature(struct.method.getArgumentTypes()[i].getSignature());
+        }
 
-            Pointcut pc = null;
-            if (struct.method.isAbstract()) {
-                if ((pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))
-                    || pointcutExpr == null) {
-                    // abstract pointcut
-                    // leave pc = null
-                } else {
-                    reportError("Found defined @Pointcut on an abstract method", struct);
-                    return;//stop
-                }
+        Pointcut pc = null;
+        if (struct.method.isAbstract()) {
+            if ((pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))
+                || pointcutExpr == null) {
+                // abstract pointcut
+                // leave pc = null
             } else {
-               if (pointcutExpr==null || (pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))) {
-                       // the matches nothing pointcut (125475/125480) - perhaps not as cleanly supported as it could be.
-               } else {
-                  if (pointcutExpr != null) {
-                    // use a LazyResolvedPointcutDefinition so that the pointcut is resolved lazily
-                    // since for it to be resolved, we will need other pointcuts to be registered as well
-                    pc = parsePointcut(pointcutExpr.getValue().stringifyValue(), struct, true);
-                    if (pc == null) return;//parse error
-                    pc.setLocation(struct.context, -1, -1);//FIXME AVASM !! bMethod is null here..
-                  } else {
-                    reportError("Found undefined @Pointcut on a non-abstract method", struct);
-                    return;
-                  }
-               }
+                reportError("Found defined @Pointcut on an abstract method", struct);
+                return false;//stop
             }
-            // do not resolve binding now but lazily
-            struct.ajAttributes.add(
-                    new AjAttribute.PointcutDeclarationAttribute(
-                            new LazyResolvedPointcutDefinition(
-                                    struct.enclosingType,
-                                    struct.method.getModifiers(),
-                                    struct.method.getName(),
-                                    argumentTypes,
-                                    UnresolvedType.forSignature(struct.method.getReturnType().getSignature()),
-                                    pc,//can be null for abstract pointcut
-                                    binding
-                            )
-                    )
-            );
+        } else {
+               if (pointcutExpr==null || (pointcutExpr != null && isNullOrEmpty(pointcutExpr.getValue().stringifyValue()))) {
+                       // the matches nothing pointcut (125475/125480) - perhaps not as cleanly supported as it could be.
+               } else {
+              if (pointcutExpr != null) {
+                // use a LazyResolvedPointcutDefinition so that the pointcut is resolved lazily
+                // since for it to be resolved, we will need other pointcuts to be registered as well
+                pc = parsePointcut(pointcutExpr.getValue().stringifyValue(), struct, true);
+                if (pc == null) return false;//parse error
+                pc.setLocation(struct.context, -1, -1);//FIXME AVASM !! bMethod is null here..
+              } else {
+                reportError("Found undefined @Pointcut on a non-abstract method", struct);
+                return false;
+              }
+               }
         }
+        // do not resolve binding now but lazily
+        struct.ajAttributes.add(
+                new AjAttribute.PointcutDeclarationAttribute(
+                        new LazyResolvedPointcutDefinition(
+                                struct.enclosingType,
+                                struct.method.getModifiers(),
+                                struct.method.getName(),
+                                argumentTypes,
+                                UnresolvedType.forSignature(struct.method.getReturnType().getSignature()),
+                                pc,//can be null for abstract pointcut
+                                binding // can be null for abstract pointcut
+                        )
+                )
+        );
+        return true;
     }
 
     /**
@@ -1492,15 +1521,37 @@ public class AtAjAttributes {
         }
         return null;
     }
+    
+    /**
+     * Return the argNames set for an annotation or null if it is not specified.
+     */
+    private static String getArgNamesValue(AnnotationGen anno) {
+        for (Iterator iterator1 = anno.getValues().iterator(); iterator1.hasNext();) {
+                ElementNameValuePairGen element = (ElementNameValuePairGen) iterator1.next();
+             if (ARGNAMES.equals(element.getNameString())) {
+                 return element.getValue().stringifyValue();
+             }
+         }
+         return null;
+    }
+    
+    private static String lastbit(String fqname) {
+       int i = fqname.lastIndexOf(".");
+       if (i==-1) return fqname; else return fqname.substring(i+1);
+    }
 
     /**
-     * Extract the method argument names as in source from debug info
-     * returns an empty array upon inconsistency
+     * Extract the method argument names.  First we try the debug info attached
+     * to the method (the LocalVariableTable) - if we cannot find that we look
+     * to use the argNames value that may have been supplied on the associated
+     * annotation.  If that fails we just don't know and return an empty string.
      *
      * @param method
-     * @return method arg names as in source
+     * @param argNamesFromAnnotation 
+     * @param methodStruct 
+     * @return method argument names
      */
-    private static String[] getMethodArgumentNamesAsInSource(Method method) {
+    private static String[] getMethodArgumentNames(Method method, String argNamesFromAnnotation, AjAttributeMethodStruct methodStruct) {
         if (method.getArgumentTypes().length == 0) {
             return EMPTY_STRINGS;
         }
@@ -1517,6 +1568,28 @@ public class AtAjAttributes {
                     }
                 }
             }
+        } else {
+               // No debug info, do we have an annotation value we can rely on?
+               if (argNamesFromAnnotation!=null) {
+                       StringTokenizer st = new StringTokenizer(argNamesFromAnnotation," ,");
+                       List args = new ArrayList();
+                       while (st.hasMoreTokens()) { args.add(st.nextToken());}
+                       if (args.size()!=method.getArgumentTypes().length) {
+                               StringBuffer shortString = new StringBuffer().append(lastbit(method.getReturnType().toString())).append(" ").append(method.getName());
+                               if (method.getArgumentTypes().length>0) {
+                                       shortString.append("(");
+                                       for (int i =0; i<method.getArgumentTypes().length;i++) {
+                                               shortString.append(lastbit(method.getArgumentTypes()[i].toString()));
+                                               if ((i+1)<method.getArgumentTypes().length) shortString.append(",");
+                                               
+                                       }
+                                       shortString.append(")");
+                           }
+                               reportError("argNames annotation value does not specify the right number of argument names for the method '"+shortString.toString()+"'",methodStruct);
+                    return EMPTY_STRINGS;
+                       }
+                       return (String[])args.toArray(new String[]{});
+               }
         }
 
         if (arguments.size() != method.getArgumentTypes().length) {
@@ -1619,7 +1692,7 @@ public class AtAjAttributes {
 
         private Pointcut m_lazyPointcut = null;
 
-        public LazyResolvedPointcutDefinition(ResolvedType declaringType, int modifiers, String name,
+        public LazyResolvedPointcutDefinition(UnresolvedType declaringType, int modifiers, String name,
                                               UnresolvedType[] parameterTypes, UnresolvedType returnType,
                                               Pointcut pointcut, IScope binding) {
             super(declaringType, modifiers, name, parameterTypes, returnType, null);
index fbed9cd5948523ff204b3f0d2042a03ba9673322..299235176331bb0f8e89418084b2972f9085e996 100644 (file)
  *******************************************************************************/
 package org.aspectj.weaver.bcel;
 
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
 import org.aspectj.apache.bcel.generic.FieldInstruction;
 import org.aspectj.apache.bcel.generic.Instruction;
 import org.aspectj.apache.bcel.generic.InstructionConstants;
@@ -26,7 +20,6 @@ import org.aspectj.apache.bcel.generic.InstructionFactory;
 import org.aspectj.apache.bcel.generic.InstructionHandle;
 import org.aspectj.apache.bcel.generic.InstructionList;
 import org.aspectj.apache.bcel.generic.InvokeInstruction;
-import org.aspectj.apache.bcel.classfile.ConstantPool;
 import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AjcMemberMaker;
@@ -37,6 +30,13 @@ import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.UnresolvedType;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+
 /**
  * Looks for all access to method or field that are not public within the body of the around advices and replace
  * the invocations to a wrapper call so that the around advice can further be inlined.
@@ -257,11 +257,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
             // flag it synthetic, AjSynthetic
             method.makeSynthetic();
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
+                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
             );
             // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(
+                    Utility.bcelAttribute(
                             new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
                             m_aspectGen.getConstantPool()
                     )
@@ -318,11 +318,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
             // flag it synthetic, AjSynthetic
             method.makeSynthetic();
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
+                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
             );
             // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(
+                    Utility.bcelAttribute(
                             new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.MethodCall, false),
                             m_aspectGen.getConstantPool()
                     )
@@ -380,11 +380,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
             // flag it synthetic, AjSynthetic
             method.makeSynthetic();
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
+                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
             );
             // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(
+                    Utility.bcelAttribute(
                             new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldGet, false),
                             m_aspectGen.getConstantPool()
                     )
@@ -438,11 +438,11 @@ public class BcelAccessForInlineMunger extends BcelTypeMunger {
             // flag it synthetic, AjSynthetic
             method.makeSynthetic();
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
+                    Utility.bcelAttribute(new AjAttribute.AjSynthetic(), m_aspectGen.getConstantPool())
             );
             // flag the effective signature, so that we can deobfuscate the signature to apply method call pointcut
             method.addAttribute(
-                    BcelAttributes.bcelAttribute(
+                    Utility.bcelAttribute(
                             new AjAttribute.EffectiveSignatureAttribute(resolvedMember, Shadow.FieldSet, false),
                             m_aspectGen.getConstantPool()
                     )
index c3c5857fa90315214948c1c24eaaf90ebc3fdda8..f6e21bc7f6012757c479bbeb1f156b35d53164ed 100644 (file)
@@ -67,20 +67,9 @@ public class BcelAdvice extends Advice {
                Member signature,
                ResolvedType concreteAspect) 
        {
-               super(attribute, pointcut, (signature==null?null:signature.slimline()));
+               super(attribute, pointcut,shrink(attribute.getKind(),concreteAspect,signature));// (signature==null?null:signature.slimline()));
                this.concreteAspect = concreteAspect;
        }
-
-       // !!! must only be used for testing
-       public BcelAdvice(AdviceKind kind, Pointcut pointcut, Member signature,
-               int extraArgumentFlags,
-        int start, int end, ISourceContext sourceContext, ResolvedType concreteAspect)
-    {
-               this(new AjAttribute.AdviceAttribute(kind, pointcut, extraArgumentFlags, start, end, sourceContext), 
-                       pointcut, (signature==null?null:signature.slimline()), concreteAspect);
-               thrownExceptions = Collections.EMPTY_LIST;  //!!! interaction with unit tests
-       }
-       
        /**
         * We don't always need to represent the signature with a heavyweight BcelMethod object - only if its around advice
         * and inlining is active
@@ -105,6 +94,15 @@ public class BcelAdvice extends Advice {
                }
                return m;
        }
+       // !!! must only be used for testing
+       public BcelAdvice(AdviceKind kind, Pointcut pointcut, Member signature,
+               int extraArgumentFlags,
+        int start, int end, ISourceContext sourceContext, ResolvedType concreteAspect)
+    {
+               this(new AjAttribute.AdviceAttribute(kind, pointcut, extraArgumentFlags, start, end, sourceContext), 
+                       pointcut, signature, concreteAspect);
+               thrownExceptions = Collections.EMPTY_LIST;  //!!! interaction with unit tests
+       }
 
     // ---- implementations of ShadowMunger's methods
     
@@ -211,7 +209,6 @@ public class BcelAdvice extends Advice {
 
                if (concreteAspect.getWorld().isXnoInline()) return false;
        //System.err.println("isWoven? " + ((BcelObjectType)concreteAspect).getLazyClassGen().getWeaverState());
-       //      if (BcelWorld.getBcelObjectType(concreteAspect).getJavaClass()==null) return true; // been evicted... CUSTARD
        return BcelWorld.getBcelObjectType(concreteAspect).getLazyClassGen().isWoven();
     }
 
@@ -721,7 +718,7 @@ public class BcelAdvice extends Advice {
        protected void suppressLintWarnings(World inWorld) {
                if (suppressedLintKinds == null) {
                if (signature instanceof BcelMethod) {
-                       this.suppressedLintKinds = Utility.getSuppressedWarnings(signature.getAnnotations(), inWorld.getLint());
+                       this.suppressedLintKinds = Utility.getSuppressedWarnings(((BcelMethod)signature).getAnnotations(), inWorld.getLint());
                } else {
                        this.suppressedLintKinds = Collections.EMPTY_LIST;
                }
index 7aa72675951243ccbb5992bcf1eced966d39ad7a..fbd07ff71667e6f9e44473f44802c04b7aa78e54 100644 (file)
@@ -18,7 +18,6 @@ import java.util.List;
 
 import org.aspectj.apache.bcel.classfile.Attribute;
 import org.aspectj.apache.bcel.classfile.Unknown;
-import org.aspectj.apache.bcel.classfile.ConstantPool;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
@@ -28,16 +27,50 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 
 // this is a class o' static methods for reading attributes.  It's pretty much a bridge from 
 // bcel to AjAttribute.
+// OPTIMIZE move the contents of this class to bcel Utility
 class BcelAttributes {
 
        /**
         * Process an array of Bcel attributes - looking for those with the name prefix org.aspectj.weaver.  The returned 
         * list contains the AspectJ attributes identified and unpacked to 'AjAttribute' objects.
         */
-       public static List readAjAttributes(String classname,Attribute[] as, ISourceContext context,
-                                                     World w,AjAttribute.WeaverVersionInfo version) {
+//     public static List readAjAttributes(String classname,List as, ISourceContext context,
+//                                                   World w, AjAttribute.WeaverVersionInfo version) {
+//             List l = new ArrayList();
+//             
+//             // first pass, look for version
+//             List forSecondPass = new ArrayList();
+//             for (int i = as.size() - 1; i >= 0; i--) {
+//                     Attribute a = (Attribute)as.get(i);
+//                     if (a instanceof Unknown) {
+//                             Unknown u = (Unknown) a;
+//                             String name = u.getName();
+//                             if (name.charAt(0)=='o') { // 'o'rg.aspectj
+//                                     if (name.startsWith(AjAttribute.AttributePrefix)) {
+//                                             if (name.endsWith(WeaverVersionInfo.AttributeName)) {
+//                                                     version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w);
+//                                                     if (version.getMajorVersion() > WeaverVersionInfo.getCurrentWeaverMajorVersion()) {
+//                                                             throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+
+//                                                                             WeaverVersionInfo.toCurrentVersionString()+" but the class "+classname+" is version "+version.toString());
+//                                                     }
+//                         }
+//                                             forSecondPass.add(a);
+//                                     }
+//                             }
+//                     }
+//             }
+                               
+//             for (int i = forSecondPass.size()-1; i >= 0; i--) {
+//                     Unknown a = (Unknown)forSecondPass.get(i);
+//                     String name = a.getName();
+//                     AjAttribute attr = AjAttribute.read(version,name,a.getBytes(),context,w); 
+//                     if (attr!=null) l.add(attr);
+//             }
+//             return l;
+//     }
+       public static List readAjAttributes(String classname, Attribute[] as, ISourceContext context, World w, AjAttribute.WeaverVersionInfo version) {
                List l = new ArrayList();
-               
+
                // first pass, look for version
                List forSecondPass = new ArrayList();
                for (int i = as.length - 1; i >= 0; i--) {
@@ -45,37 +78,34 @@ class BcelAttributes {
                        if (a instanceof Unknown) {
                                Unknown u = (Unknown) a;
                                String name = u.getName();
-                               if (name.charAt(0)=='o') { // 'o'rg.aspectj
+                               if (name.charAt(0) == 'o') { // 'o'rg.aspectj
                                        if (name.startsWith(AjAttribute.AttributePrefix)) {
                                                if (name.endsWith(WeaverVersionInfo.AttributeName)) {
-                                                       version = (AjAttribute.WeaverVersionInfo)AjAttribute.read(version,name,u.getBytes(),context,w);
-                                                       if (version.getMajorVersion() > WeaverVersionInfo.getCurrentWeaverMajorVersion()) {
-                                                               throw new BCException("Unable to continue, this version of AspectJ supports classes built with weaver version "+
-                                                                               WeaverVersionInfo.toCurrentVersionString()+" but the class "+classname+" is version "+version.toString());
+                                                       version = (AjAttribute.WeaverVersionInfo) AjAttribute.read(version, name, u.getBytes(), context, w);
+                                                       if (version.getMajorVersion() > WeaverVersionInfo
+                                                                       .getCurrentWeaverMajorVersion()) {
+                                                               throw new BCException(
+                                                                               "Unable to continue, this version of AspectJ supports classes built with weaver version "
+                                                                                               + WeaverVersionInfo
+                                                                                                               .toCurrentVersionString()
+                                                                                               + " but the class "
+                                                                                               + classname
+                                                                                               + " is version "
+                                                                                               + version.toString());
                                                        }
-                           }
+                                               }
                                                forSecondPass.add(a);
                                        }
                                }
                        }
                }
-                               
-               for (int i = forSecondPass.size()-1; i >= 0; i--) {
-                       Unknown a = (Unknown)forSecondPass.get(i);
+
+               for (int i = forSecondPass.size() - 1; i >= 0; i--) {
+                       Unknown a = (Unknown) forSecondPass.get(i);
                        String name = a.getName();
-                       AjAttribute attr = AjAttribute.read(version,name,a.getBytes(),context,w); 
-                       if (attr!=null) l.add(attr);
+                       AjAttribute attr = AjAttribute.read(version, name, a.getBytes(), context, w);
+                       if (attr != null) l.add(attr);
                }
                return l;
        }
-
-       public static Attribute bcelAttribute(AjAttribute a, ConstantPool pool) {
-               int nameIndex = pool.addUtf8(a.getNameString());
-               byte[] bytes = a.getBytes();
-               int length = bytes.length;
-
-               return new Unknown(nameIndex, length, bytes, pool);
-
-       }
-
 }
\ No newline at end of file
index 3566da0d143b92dc92e910de7f30ed13f75951e8..d7e38e6735d78ea08e2a3998c7929f3965e20fd1 100644 (file)
@@ -88,4 +88,8 @@ public class BcelCflowCounterFieldAdder extends BcelTypeMunger {
                return true;
        }
 
+       public String toString() {
+               return "(BcelTypeMunger: CflowField "+cflowCounterField.getDeclaringType().getName()+" "+cflowCounterField.getName()+")";
+       }
+
 }
index 13cc50a7416ec81b3f44c67b1f4edaacc99b46f9..a823da0d839c91b7cf461415d1a967714c5ef115 100644 (file)
@@ -80,7 +80,6 @@ import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
-import org.aspectj.weaver.WeaverMetrics;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.patterns.DeclareAnnotation;
@@ -88,9 +87,6 @@ import org.aspectj.weaver.patterns.ExactTypePattern;
 import org.aspectj.weaver.tools.Trace;
 import org.aspectj.weaver.tools.TraceFactory;
 
-import com.sun.org.apache.bcel.internal.generic.BranchInstruction;
-import com.sun.org.apache.bcel.internal.generic.GOTO;
-import com.sun.org.apache.bcel.internal.generic.GOTO_W;
 
 class BcelClassWeaver implements IClassWeaver {
 
@@ -821,8 +817,9 @@ class BcelClassWeaver implements IClassWeaver {
                                        
                                        if (annotationsToAdd==null) annotationsToAdd = new ArrayList();
                                        AnnotationGen a = decaM.getAnnotationX().getBcelAnnotation();
-                                       AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true);
-                                       annotationsToAdd.add(ag);
+                                       //CUSTARD superfluous?
+                                       //AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPool(),true);
+                                       annotationsToAdd.add(a);
                                        
                                        mg.addAnnotation(decaM.getAnnotationX());
                                        AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod());
@@ -1002,7 +999,7 @@ class BcelClassWeaver implements IClassWeaver {
                    while (!worthRetrying.isEmpty() && modificationOccured) {
                                modificationOccured = false;
                 List forRemoval = new ArrayList();
-                for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) {
+                for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) {
                                  DeclareAnnotation decaF = (DeclareAnnotation) iter2.next();
                                  if (decaF.matches(itdIsActually,world)) {
                                        LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,fieldMunger);
@@ -1055,7 +1052,7 @@ class BcelClassWeaver implements IClassWeaver {
                    while (!worthRetrying.isEmpty() && modificationOccured) {
                                modificationOccured = false;
                 List forRemoval = new ArrayList();
-                for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) {
+                for (Iterator iter2 = worthRetrying.iterator(); iter2.hasNext();) {
                                  DeclareAnnotation decaMC = (DeclareAnnotation) iter2.next();
                                  if (decaMC.matches(unMangledInterMethod,world)) {
                                        LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,methodctorMunger);
@@ -1074,7 +1071,7 @@ class BcelClassWeaver implements IClassWeaver {
              return isChanged;
        }
        
-       private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX[] dontAddMeTwice){
+       private boolean dontAddTwice(DeclareAnnotation decaF, AnnotationX [] dontAddMeTwice){
                for (int i = 0; i < dontAddMeTwice.length; i++){
                        AnnotationX ann = dontAddMeTwice[i];
                        if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())){
@@ -1162,7 +1159,7 @@ class BcelClassWeaver implements IClassWeaver {
                                                }
                                        }
                                        
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getName());
+                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs());
                                        reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF);                
                                        isChanged = true;
                                        modificationOccured = true;
@@ -1190,7 +1187,7 @@ class BcelClassWeaver implements IClassWeaver {
                                                continue; // skip this one...
                                        }
                                        aBcelField.addAnnotation(decaF.getAnnotationX());
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getName());
+                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),aBcelField.getFieldAsIs());
                                        isChanged = true;
                                        modificationOccured = true;
                                        forRemoval.add(decaF);
@@ -1301,7 +1298,7 @@ class BcelClassWeaver implements IClassWeaver {
                                          reportedProblems.add(uniqueID);
                                          reportedProblems.add(new Integer(itdfieldsig.hashCode()*deca.hashCode()));
                                          world.getLint().elementAlreadyAnnotated.signal(
-                                               new String[]{rm.toString(),deca.getAnnotationTypeX().toString()},
+                                               new String[]{itdfieldsig.toString(),deca.getAnnotationTypeX().toString()},
                                                rm.getSourceLocation(),new ISourceLocation[]{deca.getSourceLocation()});
                                  }
                          }
@@ -1537,10 +1534,10 @@ class BcelClassWeaver implements IClassWeaver {
                                                                        // ignore
                                                                } else if (targeter instanceof LineNumberTag) {
                                                                        // ignore
-                                                               } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) {
-                                                                       // move it...
-                                                                       targeter.updateTarget(element, monitorExitBlockStart);  
-                                                               } else if (targeter instanceof BranchInstruction) {
+//                                                             } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) {
+//                                                                     // move it...
+//                                                                     targeter.updateTarget(element, monitorExitBlockStart);  
+                                                               } else if (targeter instanceof InstructionBranch) {
                                                                        // move it
                                                                        targeter.updateTarget(element, monitorExitBlockStart);
                                                                } else {
@@ -1717,10 +1714,10 @@ class BcelClassWeaver implements IClassWeaver {
                                                                // ignore
                                                        } else if (targeter instanceof LineNumberTag) {
                                                                // ignore
-                                                       } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
-                                                               // move it...
-                                                               targeter.updateTarget(element, monitorExitBlockStart);
-                                                       } else if (targeter instanceof BranchInstruction) {
+//                                                     } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
+//                                                             // move it...
+//                                                             targeter.updateTarget(element, monitorExitBlockStart);
+                                                       } else if (targeter instanceof InstructionBranch) {
                                                                // move it
                                                                targeter.updateTarget(element, monitorExitBlockStart);
                                                        } else {
@@ -1825,9 +1822,9 @@ class BcelClassWeaver implements IClassWeaver {
                                                                // ignore
                                                        } else if (targeter instanceof LineNumberTag) {
                                                                // ignore
-                                                       } else if (targeter instanceof InstructionBranch && ((InstructionBranch)targeter).isGoto()) {
-                                                               // move it...
-                                                               targeter.updateTarget(element, monitorExitBlockStart);
+//                                                     } else if (targeter instanceof GOTO || targeter instanceof GOTO_W) {
+//                                                             // move it...
+//                                                             targeter.updateTarget(element, monitorExitBlockStart);
                                                        } else if (targeter instanceof InstructionBranch) {
                                                                // move it
                                                                targeter.updateTarget(element, monitorExitBlockStart);
@@ -1900,6 +1897,8 @@ class BcelClassWeaver implements IClassWeaver {
                {
                        Instruction fresh = Utility.copyInstruction(src.getInstruction());
                        InstructionHandle dest;
+                       
+                       // OPTIMIZE optimize this stuff?
                        if (fresh.isConstantPoolInstruction()) {
                                // need to reset index to go to new constant pool.  This is totally
                                // a computation leak... we're testing this LOTS of times.  Sigh.
@@ -2605,9 +2604,14 @@ class BcelClassWeaver implements IClassWeaver {
                        // sets of synthetics aren't join points in 1.1
                        return;
                } else {
-                       match(
-                               BcelShadow.makeFieldSet(world, mg, ih, enclosingShadow),
-                               shadowAccumulator);
+                       // Fix for bug 172107 (similar the "get" fix for bug 109728)
+                       BcelShadow bs=
+                               BcelShadow.makeFieldSet(world, resolvedField, mg, ih, enclosingShadow);
+                       String cname = fi.getClassName(cpg);
+                       if (!resolvedField.getDeclaringType().getName().equals(cname)) {
+                               bs.setActualTargetType(cname);
+                       }
+                       match(bs, shadowAccumulator);
                }
        }
 
@@ -2774,14 +2778,11 @@ class BcelClassWeaver implements IClassWeaver {
                    ShadowMunger munger = (ShadowMunger)i.next();
                    ContextToken mungerMatchToken = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.MATCHING_POINTCUT, munger.getPointcut());
                    if (munger.match(shadow, world)) {
-                                       WeaverMetrics.recordMatchResult(true);// Could pass: munger
                        shadow.addMunger(munger);
                        isMatched = true;
                                    if (shadow.getKind() == Shadow.StaticInitialization) {
                                          clazz.warnOnAddedStaticInitializer(shadow,munger.getSourceLocation());
                                    }
-                   } else {
-                       WeaverMetrics.recordMatchResult(false); // Could pass: munger
                        }
                    CompilationAndWeavingContext.leavingPhase(mungerMatchToken);
                }       
index 8e01e76b95dcd56330f80d2013055ec0185b4373..5b374d683809e7e244b1a7ba445943fd910e866c 100644 (file)
@@ -10,7 +10,6 @@
  *     PARC     initial implementation 
  * ******************************************************************/
 
-
 package org.aspectj.weaver.bcel;
 
 import java.util.Collections;
@@ -36,7 +35,6 @@ import org.aspectj.weaver.World;
 import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
 
-
 final class BcelField extends ResolvedMemberImpl {
 
        private static int AccSynthetic = 0x1000;
@@ -56,7 +54,7 @@ final class BcelField extends ResolvedMemberImpl {
                super(
                        FIELD, 
                        declaringType.getResolvedTypeX(),
-                       field.getAccessFlags(),
+                       field.getModifiers(),
                        field.getName(), 
                        field.getSignature());
                this.field = field;
@@ -72,7 +70,7 @@ final class BcelField extends ResolvedMemberImpl {
         * constructed at runtime (so there is no .class file to retrieve).  
         */
        BcelField(String declaringTypeName, Field field,World world) {
-               super(FIELD,UnresolvedType.forName(declaringTypeName),field.getAccessFlags(),field.getName(),field.getSignature());
+               super(FIELD,UnresolvedType.forName(declaringTypeName),field.getModifiers(),field.getName(),field.getSignature());
                this.field = field;
                this.world = world;
                this.bcelObjectType = null;
index 082dccfdc2d0b1a68ee65046657110cc7ae97ea0..e6f8829bf924eeb2488ce4a80481bd70ae0863c9 100644 (file)
@@ -255,11 +255,13 @@ public class BcelGenericSignatureToTypeXConverter {
                
                ReferenceType rt = (ReferenceType) aTypeX;
                TypeVariable[] typeVars = rt.getTypeVariables();
-               for (int i = 0; i < typeVars.length; i++) {
-                       if (typeVars[i].getUpperBound() instanceof FTPHolder) {
-                               Signature.FormalTypeParameter key = ((FTPHolder) typeVars[i].getUpperBound()).ftpToBeSubstituted;
-                               typeVars[i].setUpperBound((UnresolvedType)typeVariableResolutions.get(key));
-                       }
+               if (typeVars != null) {
+            for (int i = 0; i < typeVars.length; i++) {
+                if (typeVars[i].getUpperBound() instanceof FTPHolder) {
+                    Signature.FormalTypeParameter key = ((FTPHolder) typeVars[i].getUpperBound()).ftpToBeSubstituted;
+                    typeVars[i].setUpperBound((UnresolvedType) typeVariableResolutions.get(key));
+                }
+            }
                }
        }
        
index bea01fba57902cdfdc545fc6d9b1063688d9307b..2b2c172223d7c81a8988de27312f1c821befe562 100644 (file)
@@ -10,7 +10,6 @@
  *     PARC     initial implementation 
  * ******************************************************************/
 
-
 package org.aspectj.weaver.bcel;
 
 import java.lang.reflect.Modifier;
@@ -19,6 +18,7 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 
+import org.aspectj.apache.bcel.classfile.AnnotationDefault;
 import org.aspectj.apache.bcel.classfile.Attribute;
 import org.aspectj.apache.bcel.classfile.ExceptionTable;
 import org.aspectj.apache.bcel.classfile.GenericSignatureParser;
@@ -31,13 +31,14 @@ import org.aspectj.apache.bcel.classfile.Method;
 import org.aspectj.apache.bcel.classfile.Signature;
 import org.aspectj.apache.bcel.classfile.Signature.TypeVariableSignature;
 import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.SourceLocation;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
-import org.aspectj.weaver.Member;
+import org.aspectj.weaver.MemberKind;
 import org.aspectj.weaver.ResolvedMemberImpl;
 import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedType;
@@ -52,15 +53,14 @@ public final class BcelMethod extends ResolvedMemberImpl {
 
        private Method method;
 //     private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
-//     private World world;
        private BcelObjectType bcelObjectType;
 
-       public Member slimline() {
-               if (!bcelObjectType.getWorld().isXnoInline()) return this;
-               ResolvedMemberImpl mi = new ResolvedMemberImpl(kind,declaringType,modifiers,returnType,name,parameterTypes);
-               mi.setParameterNames(getParameterNames());
-               return mi;
-       }
+//     public Member slimline() {
+//             if (!bcelObjectType.getWorld().isXnoInline()) return this;
+//             ResolvedMemberImpl mi = new ResolvedMemberImpl(kind,declaringType,modifiers,returnType,name,parameterTypes);
+//             mi.setParameterNames(getParameterNames());
+//             return mi;
+//     }
 
 //    private AnnotationX[] annotations = null;
 //     private UnresolvedType genericReturnType = null;
@@ -75,6 +75,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
        private static final String MAPKEY_GENERIC_PARAM_TYPES     ="genericParameterTypes";
        private static final String MAPKEY_ANNOTATIONS             ="annotations";
        private static final String MAPKEY_MD_LINE_NUMBER_ATTRIBUTE="mdLineNumberAttribute";
+    private AnnotationX[][] parameterAnnotations = null;
 
 //     private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
 //     private ShadowMunger associatedShadowMunger;
@@ -109,13 +110,12 @@ public final class BcelMethod extends ResolvedMemberImpl {
                                (method.getName().equals("<clinit>") ? STATIC_INITIALIZATION : METHOD), 
                        declaringType.getResolvedTypeX(),
                        declaringType.isInterface() 
-                               ? method.getAccessFlags() | Modifier.INTERFACE
-                               : method.getAccessFlags(),
-                       method.getName(), 
+                               ? method.getModifiers() | Modifier.INTERFACE
+                               : method.getModifiers(),
+                       method.getName(),
                        method.getSignature());
                this.method = method;
                this.sourceContext = declaringType.getResolvedTypeX().getSourceContext();
-               //this.world = declaringType.getResolvedTypeX().getWorld();
                this.bcelObjectType = declaringType;
                unpackJavaAttributes();
                unpackAjAttributes(bcelObjectType.getWorld());
@@ -152,6 +152,41 @@ public final class BcelMethod extends ResolvedMemberImpl {
                LocalVariableTable varTable = method.getLocalVariableTable();
                int len = getArity();
                if (varTable == null) {
+                       // do we have an annotation with the argNames value specified...
+                       if (hasAnnotations()) {
+                               AnnotationX[] axs = getAnnotations();
+                           for (int i = 0; i < axs.length; i++) {
+                                       AnnotationX annotationX = axs[i];
+                                       String typename = annotationX.getTypeName();
+                                       if (typename.equals("org.aspectj.lang.annotation.Pointcut") ||
+                                               typename.equals("org.aspectj.lang.annotation.Before") ||
+                                               typename.equals("org.aspectj.lang.annotation.Around") ||
+                                               typename.startsWith("org.aspectj.lang.annotation.After")) {
+                                               AnnotationGen a = annotationX.getBcelAnnotation();
+                                               if (a!=null) {
+                                                       List values = a.getValues();
+                                                       for (Iterator iterator = values.iterator(); iterator
+                                                                       .hasNext();) {
+                                                               ElementNameValuePairGen nvPair = (ElementNameValuePairGen) iterator.next();
+                                                               if (nvPair.getNameString().equals("argNames")) {
+                                                                       String argNames = nvPair.getValue().stringifyValue();
+                                                                       StringTokenizer argNameTokenizer = new StringTokenizer(argNames," ,");
+                                                                       List argsList = new ArrayList();
+                                                                       while (argNameTokenizer.hasMoreTokens()) {
+                                                                               argsList.add(argNameTokenizer.nextToken());
+                                                                       }
+                                                                       int requiredCount = getParameterTypes().length;
+                                                                       while (argsList.size()<requiredCount) {
+                                                                               argsList.add("arg"+argsList.size());
+                                                                       }
+                                                                       setParameterNames((String[])argsList.toArray(new String[]{}));
+                                                                       return;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+                       } 
                        setParameterNames(Utility.makeArgNames(len));
                } else {
                        UnresolvedType[] paramTypes = getParameterTypes();
@@ -228,6 +263,18 @@ public final class BcelMethod extends ResolvedMemberImpl {
                return null;
        }
        
+       public String getAnnotationDefaultValue() {
+               Attribute[] attrs = method.getAttributes();
+               for (int i = 0; i < attrs.length; i++) {
+                       Attribute attribute = attrs[i];                 
+                       if (attribute.getName().equals("AnnotationDefault")) {
+                               AnnotationDefault def = (AnnotationDefault)attribute;
+                               return def.getElementValue().stringifyValue();
+                       }
+               }
+               return null;
+       }
+       
        // for testing - use with the method above
        public String[] getAttributeNames(boolean onlyIncludeAjOnes) {
                Attribute[] as = method.getAttributes();
@@ -304,7 +351,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
       return ret;
     }
        
-       public Kind getKind() {
+       public MemberKind getKind() {
                if ((bitflags&HAS_ASSOCIATED_SHADOWMUNGER)!=0) {
                        return ADVICE;
                } else {
@@ -313,7 +360,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
        }
        
        public boolean hasAnnotation(UnresolvedType ofType) {
-               ensureAnnotationTypesRetrieved();
+               ensureAnnotationsRetrieved();
                for (Iterator iter = annotationTypes.iterator(); iter.hasNext();) {
                        ResolvedType aType = (ResolvedType) iter.next();
                        if (aType.equals(ofType)) return true;          
@@ -322,7 +369,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
        }
        
        public AnnotationX[] getAnnotations() {
-               ensureAnnotationTypesRetrieved();
+               ensureAnnotationsRetrieved();
                if ((bitflags&HAS_ANNOTATIONS)!=0) {
                        return (AnnotationX[])metaData.get(MAPKEY_ANNOTATIONS);
                } else {
@@ -332,14 +379,24 @@ public final class BcelMethod extends ResolvedMemberImpl {
        }
        
         public ResolvedType[] getAnnotationTypes() {
-           ensureAnnotationTypesRetrieved();
+           ensureAnnotationsRetrieved();
            ResolvedType[] ret = new ResolvedType[annotationTypes.size()];
            annotationTypes.toArray(ret);
            return ret;
      }
         
+        public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
+                ensureAnnotationsRetrieved();
+                if ((bitflags&HAS_ANNOTATIONS)==0) return null;
+                AnnotationX[] annos = (AnnotationX[])metaData.get(MAPKEY_ANNOTATIONS);
+                for (int i=0; i<annos.length; i++) {
+                        if (annos[i].getTypeName().equals(ofType.getName())) return annos[i];
+                }
+                return null;
+        }
+        
         public void addAnnotation(AnnotationX annotation) {
-           ensureAnnotationTypesRetrieved();   
+           ensureAnnotationsRetrieved();       
            if ((bitflags&HAS_ANNOTATIONS)==0) {
                        AnnotationX[] ret = new AnnotationX[1];
                        ret[0]=annotation;
@@ -365,7 +422,7 @@ public final class BcelMethod extends ResolvedMemberImpl {
                // FIXME CUSTARD
         }
         
-        private void ensureAnnotationTypesRetrieved() {
+        private void ensureAnnotationsRetrieved() {
                if (method == null) return; // must be ok, we have evicted it
                if ((bitflags&HAVE_DETERMINED_ANNOTATIONS)!=0) return;
                bitflags|=HAVE_DETERMINED_ANNOTATIONS;
@@ -387,6 +444,39 @@ public final class BcelMethod extends ResolvedMemberImpl {
 //             }
        }
         
+       private void ensureParameterAnnotationsRetrieved() {
+               if (method == null) return; // must be ok, we have evicted it
+               AnnotationGen[][] pAnns = method.getParameterAnnotations();
+               if (parameterAnnotationTypes==null || pAnns.length!=parameterAnnotationTypes.length) {
+                       if (pAnns == Method.NO_PARAMETER_ANNOTATIONS) {
+                               parameterAnnotationTypes = BcelMethod.NO_PARAMETER_ANNOTATION_TYPES;
+                               parameterAnnotations     = BcelMethod.NO_PARAMETER_ANNOTATIONXS;
+                       } else {
+                               AnnotationGen annos[][] = method.getParameterAnnotations();
+                               parameterAnnotations = new AnnotationX[annos.length][];
+                               parameterAnnotationTypes = new ResolvedType[annos.length][];
+                               for (int i=0;i<annos.length;i++) {
+                                       parameterAnnotations[i] = new AnnotationX[annos[i].length];
+                                       parameterAnnotationTypes[i] = new ResolvedType[annos[i].length];
+                                       for (int j=0;j<annos[i].length;j++) {
+                                               parameterAnnotations[i][j] = new AnnotationX(annos[i][j],bcelObjectType.getWorld());
+                                               parameterAnnotationTypes[i][j] = bcelObjectType.getWorld().resolve(UnresolvedType.forSignature(annos[i][j].getTypeSignature()));
+                                       }
+                               }
+                       }
+               }
+       }
+
+       public AnnotationX[][] getParameterAnnotations() { 
+               ensureParameterAnnotationsRetrieved();
+               return parameterAnnotations;
+       }
+       
+       public ResolvedType[][] getParameterAnnotationTypes() { 
+               ensureParameterAnnotationsRetrieved();
+               return parameterAnnotationTypes;
+       }
+        
 
         /**
          * A method can be parameterized if it has one or more generic
@@ -406,6 +496,9 @@ public final class BcelMethod extends ResolvedMemberImpl {
 //              return genericParameterTypes;
         }
         
+        /**
+      * Return the parameterized/generic return type or the normal return type if the method is not generic.
+      */
         public UnresolvedType getGenericReturnType() {
                 unpackGenericSignature();
                 if ((bitflags&HAS_GENERIC_RETPARAM_TYPES)==0) return getReturnType();
@@ -507,7 +600,8 @@ public final class BcelMethod extends ResolvedMemberImpl {
                 if (method != null) {
                         unpackGenericSignature();
                         unpackJavaAttributes();
-                        ensureAnnotationTypesRetrieved();
+                        ensureAnnotationsRetrieved();
+                        ensureParameterAnnotationsRetrieved();
                         determineParameterNames();
 //                      this.sourceContext = SourceContextImpl.UNKNOWN_SOURCE_CONTEXT;
                         method = null;
@@ -567,4 +661,4 @@ public final class BcelMethod extends ResolvedMemberImpl {
                                o.getMethod().getCode().getCodeString());
        }
 
-}
+}
\ No newline at end of file
index ee8da45f5eaba1bda08fa6968081a3fa55800ba2..6008b8e936a96b612aa224e0b842d9b26f839a1f 100644 (file)
@@ -31,6 +31,7 @@ import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
 import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
 import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
 import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
+import org.aspectj.apache.bcel.classfile.annotation.EnumElementValueGen;
 import org.aspectj.bridge.IMessageHandler;
 import org.aspectj.weaver.AbstractReferenceTypeDelegate;
 import org.aspectj.weaver.AjAttribute;
@@ -148,13 +149,10 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
 //             ((SourceContextImpl)sourceContext).setSourceFileName(javaClass.getSourceFileName());
 //        }
         setSourcefilename(javaClass.getSourceFileName());
-        
     }
     
     // repeat initialization
     public void setJavaClass(JavaClass newclass) {
-//     if (this.getResolvedTypeX().isAspect())
-//     new RuntimeException("bcot: "+this.hashCode()+" Set javaclass for aspect").printStackTrace();
        this.javaClass = newclass;
        resetState();
        initializeFromJavaclass();
@@ -166,7 +164,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
                isAnnotation        = javaClass.isAnnotation();
                isAnonymous         = javaClass.isAnonymous();
                isNested            = javaClass.isNested();    
-               modifiers           = javaClass.getAccessFlags();
+               modifiers           = javaClass.getModifiers();
                superclassName      = javaClass.getSuperclassName();
                className           = javaClass.getClassName();
                cachedGenericClassTypeSignature = null;
@@ -201,7 +199,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
         ResolvedType res =     getResolvedTypeX().getWorld().resolve(UnresolvedType.forSignature(superclassSignature));
        return res;
     }
-    
+        
     public World getWorld() {
        return getResolvedTypeX().getWorld();
     }
@@ -482,7 +480,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
     public LazyClassGen getLazyClassGen() {
        LazyClassGen ret = lazyClassGen;
        if (ret == null) {
-//             System.err.println("creating lazy class gen for: " + this);
+               //System.err.println("creating lazy class gen for: " + this);
                ret = new LazyClassGen(this);
                //ret.print(System.err);
                //System.err.println("made LCG from : " + this.getJavaClass().getSuperclassName );
@@ -583,8 +581,8 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
                                List values = ax.getBcelAnnotation().getValues();
                                for (Iterator it = values.iterator(); it.hasNext();) {
                                ElementNameValuePairGen element = (ElementNameValuePairGen) it.next();
-                               ElementValueGen v = element.getValue();
-                               retentionPolicy = v.stringifyValue();
+                               EnumElementValueGen v = (EnumElementValueGen)element.getValue();
+                               retentionPolicy = v.getEnumValueString();
                                return retentionPolicy;
                            }
                                        }
@@ -619,7 +617,7 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
                        ElementValueGen[] evs = arrayValue.getElementValuesArray();
                        if (evs!=null) {
                                for (int j = 0; j < evs.length; j++) {
-                                                       String targetKind = evs[j].stringifyValue();
+                                                       String targetKind = ((EnumElementValueGen)evs[j]).getEnumValueString();
                                                        if (targetKind.equals("ANNOTATION_TYPE")) {       targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE);
                                                        } else if (targetKind.equals("CONSTRUCTOR")) {    targetKinds.add(AnnotationTargetKind.CONSTRUCTOR);
                                                        } else if (targetKind.equals("FIELD")) {          targetKinds.add(AnnotationTargetKind.FIELD);
@@ -783,7 +781,6 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
        
        public void evictWeavingState() {
                // Can't chuck all this away 
-//             if (getResolvedTypeX().isAspect()) System.err.println("Eviction of "+getResolvedTypeX().getName());
                if (getResolvedTypeX().getWorld().couldIncrementalCompileFollow()) return;
                
                if (javaClass != null) {
@@ -805,16 +802,12 @@ public class BcelObjectType extends AbstractReferenceTypeDelegate {
                                weaverState.setReweavable(false);
                                weaverState.setUnwovenClassFileData(null);
                        }
-                       
-               for (int i = methods.length - 1; i >= 0; i--) { methods[i].evictWeavingState();}
+               for (int i = methods.length - 1; i >= 0; i--) methods[i].evictWeavingState();
                for (int i = fields.length - 1;  i >= 0; i--)  fields[i].evictWeavingState();
-//                     if (getResolvedTypeX().isAspect()) System.err.println("nulling jc for "+getResolvedTypeX().getName());
                        javaClass = null;
 //                     setSourceContext(SourceContextImpl.UNKNOWN_SOURCE_CONTEXT); // bit naughty
 //                 interfaces=null; // force reinit - may get us the right instances!
 //                 superClass=null;
-                       // if this is a class, make sure aspects are re-evicted if necessary
-//                     if (!getResolvedTypeX().isAspect()) getWorld().ensureAspectsEvicted();
                }
        }
        
index 83aac4585a106deec7ca4a415bfa7d4b478af066..6d8f6447b907dc6a0f7543ef22c73733f7a7bcd0 100644 (file)
@@ -584,7 +584,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger {
             methodGen.makeSynthetic();
         }
         methodGen.addAttribute(
-                BcelAttributes.bcelAttribute(
+                Utility.bcelAttribute(
                         new AjAttribute.AjSynthetic(),
                         methodGen.getEnclosingClass().getConstantPool()
                 )
index 13335e9e60306e60955c079bbd06f0ffc2b68bd1..00f7987f50b0a813eea237611c961641198f5531 100644 (file)
@@ -43,7 +43,9 @@ import org.aspectj.apache.bcel.generic.MULTIANEWARRAY;
 import org.aspectj.apache.bcel.generic.ObjectType;
 import org.aspectj.apache.bcel.generic.TargetLostException;
 import org.aspectj.apache.bcel.generic.Type;
+import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.bridge.MessageUtil;
 import org.aspectj.weaver.Advice;
 import org.aspectj.weaver.AdviceKind;
 import org.aspectj.weaver.AjcMemberMaker;
@@ -51,6 +53,7 @@ import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.IntMap;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.MemberImpl;
+import org.aspectj.weaver.MemberKind;
 import org.aspectj.weaver.NameMangler;
 import org.aspectj.weaver.NewConstructorTypeMunger;
 import org.aspectj.weaver.NewFieldTypeMunger;
@@ -127,7 +130,6 @@ public class BcelShadow extends Shadow {
     private ShadowRange range;    
     private final BcelWorld world;  
     private final LazyMethodGen enclosingMethod;
-//     private boolean fallsThrough;  //XXX not used anymore
        
        // SECRETAPI - for testing, this will tell us if the optimization succeeded *on the last shadow processed*
        public static boolean appliedLazyTjpOptimization;
@@ -136,24 +138,15 @@ public class BcelShadow extends Shadow {
     // from the signature (pr109728) (1.4 declaring type issue)
        private String actualInstructionTargetType; 
 
-       // ---- initialization
-       
        /**
-        *  This generates an unassociated shadow, rooted in a particular method but not rooted
+        * 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) 
-       {
+       public BcelShadow(BcelWorld world, Kind kind, Member signature, LazyMethodGen enclosingMethod, BcelShadow enclosingShadow) {
                super(kind, signature, enclosingShadow);
                this.world = world;
                this.enclosingMethod = enclosingMethod;
-//             fallsThrough = kind.argsOnStack();
        }
 
        // ---- copies all state, including Shadow's mungers...
@@ -178,8 +171,6 @@ public class BcelShadow extends Shadow {
                return world;
        }
 
-
-
        private void deleteNewAndDup() {
                final ConstantPool cpg = getEnclosingClass().getConstantPool();
                int depth = 1;
@@ -976,6 +967,7 @@ public class BcelShadow extends Shadow {
     
     public static BcelShadow makeFieldSet(
             BcelWorld world,
+            ResolvedMember field,
             LazyMethodGen enclosingMethod,
             InstructionHandle setHandle,
             BcelShadow enclosingShadow) 
@@ -985,9 +977,10 @@ public class BcelShadow extends Shadow {
             new BcelShadow(
                 world,
                 FieldSet,
-                BcelWorld.makeFieldJoinPointSignature(
-                    enclosingMethod.getEnclosingClass(),
-                    (FieldInstruction) setHandle.getInstruction()),
+                field,
+//                BcelWorld.makeFieldJoinPointSignature(
+//                    enclosingMethod.getEnclosingClass(),
+//                    (FieldInstruction) setHandle.getInstruction()),
                 enclosingMethod,
                 enclosingShadow);
         ShadowRange r = new ShadowRange(body);
@@ -1529,7 +1522,7 @@ public class BcelShadow extends Shadow {
                }
     }
     
-    protected Member getRelevantMember(Member foundMember, Member relevantMember, ResolvedType relevantType){
+    protected ResolvedMember getRelevantMember(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType){
        if (foundMember != null){
                return foundMember;
        }
@@ -1567,7 +1560,7 @@ public class BcelShadow extends Shadow {
        return foundMember;
     }
     
-    protected ResolvedType [] getAnnotations(Member foundMember, Member relevantMember, ResolvedType relevantType){
+    protected ResolvedType [] getAnnotations(ResolvedMember foundMember, Member relevantMember, ResolvedType relevantType){
        if (foundMember == null){
                // check the ITD'd dooberries
                List mungers = relevantType.resolve(world).getInterTypeMungers();
@@ -1606,27 +1599,30 @@ public class BcelShadow extends Shadow {
        // 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 (UnresolvedType).
+       // annotation type.
        
        // FIXME asc Refactor this code, there is duplication
        ResolvedType[] annotations = null;
-       Member relevantMember = getSignature();
-       ResolvedType  relevantType   = relevantMember.getDeclaringType().resolve(world);
-       if (relevantType.isRawType() || relevantType.isParameterizedType()) relevantType = relevantType.getGenericType();
+//     Member relevantMember = getSignature();
+       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) {
-            Member foundMember = findMethod2(relevantType.resolve(world).getDeclaredMethods(),getSignature());            
-            annotations = getAnnotations(foundMember, relevantMember, relevantType);
-            relevantMember = getRelevantMember(foundMember,relevantMember,relevantType);
-            relevantType = relevantMember.getDeclaringType().resolve(world);
+            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) {
-               relevantMember = findField(relevantType.getDeclaredFields(),getSignature());
+               annotationHolder = findField(relevantType.getDeclaredFields(),getSignature());
                
-                       if (relevantMember==null) {
+                       if (annotationHolder==null) {
               // check the ITD'd dooberries
                                List mungers = relevantType.resolve(world).getInterTypeMungers();
                                for (Iterator iter = mungers.iterator(); iter.hasNext();) {
@@ -1638,21 +1634,21 @@ public class BcelShadow extends Shadow {
                                          ResolvedMember rmm       = findMethod(typeMunger.getAspectType(),ajcMethod);
                                          if (fakerm.equals(getSignature())) {
                                                relevantType = typeMunger.getAspectType();
-                                               relevantMember = rmm;
+                                               annotationHolder = rmm;
                                          }
                                        }
                                }       
                        }
-               annotations = relevantMember.getAnnotationTypes();
+               annotations = ((ResolvedMember)annotationHolder).getAnnotationTypes();
                
        } else if (getKind() == Shadow.MethodExecution || getKind() == Shadow.ConstructorExecution || 
                        getKind() == Shadow.AdviceExecution) {
                //ResolvedMember rm[] = relevantType.getDeclaredMethods();
-               Member foundMember = findMethod2(relevantType.getDeclaredMethods(),getSignature());
+               ResolvedMember foundMember = findMethod2(relevantType.getDeclaredMethods(),getSignature());
                
-               annotations = getAnnotations(foundMember, relevantMember, relevantType);
-               relevantMember = foundMember;
-            relevantMember = getRelevantMember(foundMember, relevantMember,relevantType);
+               annotations = getAnnotations(foundMember, shadowSignature, relevantType);
+               annotationHolder = foundMember;
+               annotationHolder = getRelevantMember(foundMember, annotationHolder,relevantType);
             
        } else if (getKind() == Shadow.ExceptionHandler) {
                relevantType = getSignature().getParameterTypes()[0].resolve(world);
@@ -1670,7 +1666,7 @@ public class BcelShadow extends Shadow {
        
                for (int i = 0; i < annotations.length; i++) {
                        ResolvedType aTX = annotations[i];
-                       KindedAnnotationAccessVar kaav =  new KindedAnnotationAccessVar(getKind(),aTX.resolve(world),relevantType,relevantMember);
+                       AnnotationAccessVar kaav =  new AnnotationAccessVar(getKind(),aTX.resolve(world),relevantType,annotationHolder);
                kindedAnnotationVars.put(aTX,kaav);
                }
     }
@@ -1718,7 +1714,7 @@ public class BcelShadow extends Shadow {
                for (int i = 0; i < annotations.length; i++) {
                        ResolvedType ann = annotations[i];
                        Kind k = Shadow.StaticInitialization;
-                       withinAnnotationVars.put(ann,new KindedAnnotationAccessVar(k,ann,getEnclosingType(),null));
+                       withinAnnotationVars.put(ann,new AnnotationAccessVar(k,ann,getEnclosingType(),null));
                }
     }
     
@@ -1733,7 +1729,7 @@ public class BcelShadow extends Shadow {
                        Kind k = (getEnclosingMethod().getMemberView().getKind()==Member.CONSTRUCTOR?
                                          Shadow.ConstructorExecution:Shadow.MethodExecution);
                        withincodeAnnotationVars.put(ann,
-                                       new KindedAnnotationAccessVar(k,ann,getEnclosingType(),getEnclosingCodeSignature()));
+                                       new AnnotationAccessVar(k,ann,getEnclosingType(),getEnclosingCodeSignature()));
                }
     }
     
@@ -1767,36 +1763,49 @@ public class BcelShadow extends Shadow {
         * 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();           
-                       for (Iterator i = returns.iterator(); i.hasNext();) {
-                               InstructionHandle ih = (InstructionHandle) i.next();
-                               retargetReturnInstruction(munger.hasExtraParameter(), returnValueVar, gotoTarget, ih);
-                       }
-        }            
-         
-        range.append(advice);
-        range.append(retList);
+       try {
+               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);
+       } catch (RuntimeException e) {
+               StringBuffer sb = new StringBuffer();
+               sb.append("Unexpected runtime exception occurred in BcelShadow.weaveAfterReturning()\n");
+               sb.append("shadow is '"+toString()+"'\n");
+               sb.append("method is '"+enclosingMethod+"'\n");
+               sb.append("enclosing shadow is '"+enclosingShadow+"'\n");
+               sb.append("range is '"+range+"'\n");
+               sb.append("munger is '"+munger+"'\n");
+               IMessage m = MessageUtil.abort(sb.toString(), e);
+               world.getMessageHandler().handleMessage(m);
+               throw e;
+       }
     }
 
        /**
@@ -2366,7 +2375,17 @@ public class BcelShadow extends Shadow {
                        extraParamOffset += thisJoinPointVar.getType().getSize();
                }
         
-        Type[] adviceParameterTypes = adviceMethod.getArgumentTypes();
+               // 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
@@ -2500,7 +2519,7 @@ public class BcelShadow extends Shadow {
         // call to the extracted method.
 
         // inlining support for code style aspects
-        if (!munger.getConcreteAspect().isAnnotationStyleAspect()) {
+        if (!munger.getDeclaringType().isAnnotationStyleAspect()) {
             String proceedName =
                 NameMangler.proceedMethodName(munger.getSignature().getName());
 
@@ -3057,7 +3076,7 @@ public class BcelShadow extends Shadow {
         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(new Integer(bitflags)));
+               closureInstantiation.append(fact.createConstant(Integer.valueOf(bitflags)));
             closureInstantiation.append(Utility.createInvoke(
                     getFactory(),
                     getWorld(),
@@ -3428,12 +3447,12 @@ public class BcelShadow extends Shadow {
         if (targetVar != null && targetVar != thisVar) {
             UnresolvedType targetType = getTargetType();
             targetType = ensureTargetTypeIsCorrect(targetType);
-            // see pr109728 - this fixes the case when the declaring class is sometype 'X' but the getfield
+            // 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 && getActualTargetType()!=null && 
+            if ((getKind()==FieldGet || getKind()==FieldSet) && getActualTargetType()!=null && 
                !getActualTargetType().equals(targetType.getName())) {
                        targetType =  UnresolvedType.forName(getActualTargetType()).resolve(world);
                }
index dad598b1ee3425031ae1512dac117cb690ebffc4..7c4728ebc8fec3b0334b6747c0e9d67456d2ab16 100644 (file)
@@ -17,6 +17,7 @@ package org.aspectj.weaver.bcel;
 import java.lang.reflect.Modifier;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.aspectj.apache.bcel.Constants;
@@ -332,25 +333,24 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
      */
     private boolean enforceDecpRule4_compatibleReturnTypes(BcelClassWeaver weaver, ResolvedMember superMethod, LazyMethodGen subMethod) {
         boolean cont = true;
-        String superReturnTypeSig = superMethod.getReturnType().getSignature();
-          String subReturnTypeSig   = subMethod.getReturnType().getSignature();
-          superReturnTypeSig = superReturnTypeSig.replace('.','/');
-          subReturnTypeSig = subReturnTypeSig.replace('.','/');
-          if (!superReturnTypeSig.equals(subReturnTypeSig)) {
-            // Allow for covariance - wish I could test this (need Java5...)
+        String superReturnTypeSig = superMethod.getGenericReturnType().getSignature(); // eg. Pjava/util/Collection<LFoo;>
+        String subReturnTypeSig = subMethod.getGenericReturnTypeSignature();
+        superReturnTypeSig = superReturnTypeSig.replace('.', '/');
+        subReturnTypeSig = subReturnTypeSig.replace('.', '/');
+        if (!superReturnTypeSig.equals(subReturnTypeSig)) {
+            // Check for covariance
             ResolvedType subType   = weaver.getWorld().resolve(subMethod.getReturnType());
             ResolvedType superType = weaver.getWorld().resolve(superMethod.getReturnType());
             if (!superType.isAssignableFrom(subType)) {
-                ISourceLocation sloc = subMethod.getSourceLocation();
                 weaver.getWorld().getMessageHandler().handleMessage(MessageUtil.error(
-                        "The return type is incompatible with "+superMethod.getDeclaringType()+"."+superMethod.getName()+superMethod.getParameterSignature(),
-                        subMethod.getSourceLocation()));
+                        "The return type is incompatible with " + superMethod.getDeclaringType() + "." + superMethod.getName()
+                        + superMethod.getParameterSignature(), subMethod.getSourceLocation()));
 // this just might be a better error message...                      
 //                        "The return type '"+subReturnTypeSig+"' is incompatible with the overridden method "+superMethod.getDeclaringType()+"."+
 //                        superMethod.getName()+superMethod.getParameterSignature()+" which returns '"+superReturnTypeSig+"'",
                  cont=false;
             }
-          }
+        }
         return cont;
     }
     
@@ -379,11 +379,14 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
     }
    
 
+    /**
+     * Search the specified type for a particular method - do not use the return value in the comparison as it is not
+     * considered for overriding.
+     */
        private LazyMethodGen findMatchingMethod(LazyClassGen newParentTarget, ResolvedMember m) {
         LazyMethodGen found = null;
-               // Search the type for methods overriding super methods (methods that come from the new parent)
-               // Don't use the return value in the comparison as overriding doesnt
-               for (Iterator i = newParentTarget.getMethodGens().iterator(); i.hasNext() && found==null;) {
+        List methodGens = newParentTarget.getMethodGens();
+        for (Iterator i = methodGens.iterator(); i.hasNext() && found == null;) {
                    LazyMethodGen gen = (LazyMethodGen) i.next();
                    if (gen.getName().equals(m.getName()) && 
                        gen.getParameterSignature().equals(m.getParameterSignature())) {
@@ -1088,6 +1091,27 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                clazz.addMethodGen(bridgeMethod);
        }
        
+       // Unlike toString() on a member, this does not include the declaring type
+       private String stringifyMember(ResolvedMember member) {
+               StringBuffer buf = new StringBuffer();
+       buf.append(member.getReturnType().getName());
+       buf.append(' ');
+               buf.append(member.getName());
+       if (member.getKind() != Member.FIELD) {
+               buf.append("(");
+               UnresolvedType[] params = member.getParameterTypes();
+            if (params.length != 0) {
+                buf.append(params[0]);
+                       for (int i=1, len = params.length; i < len; i++) {
+                    buf.append(", ");
+                           buf.append(params[i].getName());
+                       }
+            }
+               buf.append(")");
+       }
+       return buf.toString();
+       }
+       
     private boolean mungeMethodDelegate(BcelClassWeaver weaver, MethodDelegateTypeMunger munger) {
         ResolvedMember introduced = munger.getSignature();
 
@@ -1103,6 +1127,34 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
 
         boolean shouldApply = munger.matches(weaver.getLazyClassGen().getType(), aspectType);
         if (shouldApply) {
+               
+               // If no implementation class was specified, the intention was that the types matching the pattern
+               // already implemented the interface, let's check that now!
+               if (munger.getImplClassName()==null) {
+                       boolean isOK = false;
+                       List/*LazyMethodGen*/ existingMethods = gen.getMethodGens();
+                       for (Iterator i = existingMethods.iterator(); i.hasNext() && !isOK;) {
+                           LazyMethodGen m = (LazyMethodGen) i.next();
+                           if (m.getName().equals(introduced.getName()) &&  
+                               m.getParameterSignature().equals(introduced.getParameterSignature()) &&
+                               m.getReturnType().equals(introduced.getReturnType())) {
+                               isOK = true;
+                           }
+                       }        
+                       if (!isOK) {
+                               // the class does not implement this method, they needed to supply a default impl class
+                               IMessage msg = new Message("@DeclareParents: No defaultImpl was specified but the type '"+gen.getName()+
+                                               "' does not implement the method '"+stringifyMember(introduced)+"' defined on the interface '"+introduced.getDeclaringType()+"'",
+                                               weaver.getLazyClassGen().getType().getSourceLocation(),true,new ISourceLocation[]{munger.getSourceLocation()});
+                               weaver.getWorld().getMessageHandler().handleMessage(msg);
+                               return false;
+                       }
+                       
+                       return true;
+               }
+               
+               
+               
             LazyMethodGen mg = new LazyMethodGen(
                     introduced.getModifiers() - Modifier.ABSTRACT,
                     BcelWorld.makeBcelType(introduced.getReturnType()),
@@ -1666,6 +1718,10 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                return new BcelTypeMunger(munger.parameterizedFor(target),aspectType);
        }
        
+       public ConcreteTypeMunger parameterizeWith(Map m, World w) {
+               return new BcelTypeMunger(munger.parameterizeWith(m,w),aspectType);
+       }
+       
        /**
         * Returns a list of type variable aliases used in this munger.  For example, if the
         * ITD is 'int I<A,B>.m(List<A> las,List<B> lbs) {}' then this returns a list containing
index 1596b0da61773dc506147916b00f3e231256bae9..6462842cc9fd99386cdfa728b811dd1bf13b9125 100644 (file)
@@ -64,25 +64,24 @@ import org.aspectj.weaver.AsmRelationshipProvider;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ConcreteTypeMunger;
 import org.aspectj.weaver.CrosscuttingMembersSet;
+import org.aspectj.weaver.CustomMungerFactory;
 import org.aspectj.weaver.IClassFileProvider;
 import org.aspectj.weaver.IWeaveRequestor;
 import org.aspectj.weaver.IWeaver;
 import org.aspectj.weaver.NewParentTypeMunger;
 import org.aspectj.weaver.ReferenceType;
 import org.aspectj.weaver.ReferenceTypeDelegate;
-import org.aspectj.weaver.ResolvedTypeMunger;
 import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.ResolvedTypeMunger;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
-import org.aspectj.weaver.WeaverMetrics;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.patterns.AndPointcut;
 import org.aspectj.weaver.patterns.BindingAnnotationTypePattern;
 import org.aspectj.weaver.patterns.BindingTypePattern;
-import org.aspectj.weaver.patterns.CflowPointcut;
 import org.aspectj.weaver.patterns.ConcreteCflowPointcut;
 import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.DeclareParents;
@@ -113,7 +112,6 @@ public class BcelWeaver implements IWeaver {
     public BcelWeaver(BcelWorld world) {
         super();
         if (trace.isTraceEnabled()) trace.enter("<init>",this,world);
-        WeaverMetrics.reset();
         this.world = world;
         this.xcutSet = world.getCrosscuttingMembersSet();
         if (trace.isTraceEnabled()) trace.exit("<init>");
@@ -138,6 +136,7 @@ public class BcelWeaver implements IWeaver {
        private List declareParentsList = null; // setup by prepareForWeave
 
     private ZipOutputStream zipOutputStream;
+       private CustomMungerFactory customMungerFactory;
 
        // ----
     
@@ -192,8 +191,6 @@ public class BcelWeaver implements IWeaver {
                                  wsi.getUnwovenClassFileData(wovenJavaClass.getBytes()));
                                world.storeClass(unwovenJavaClass);
                                classType.setJavaClass(unwovenJavaClass);
-                               if (world.isRunMinimalMemory() && world.isXnoInline())
-                                       classType.evictWeavingState();  // CUSTARD      
 //                             classType.setJavaClass(Utility.makeJavaClass(classType.getJavaClass().getFileName(), wsi.getUnwovenClassFileData(classType.getJavaClass().getBytes())));
                        }
                        
@@ -201,6 +198,14 @@ public class BcelWeaver implements IWeaver {
             //=> mainly for nothing for LTW - pbly for something in incremental build...
                        xcutSet.addOrReplaceAspect(type);
                if (trace.isTraceEnabled()) trace.exit("addLibraryAspect",type);
+            if (type.getSuperclass().isAspect()) {
+                // If the supertype includes ITDs and the user has not included that aspect in the aop.xml, they will
+                // not get picked up, which can give unusual behaviour! See bug 223094
+                // This change causes us to pick up the super aspect regardless of what was said in the aop.xml - giving
+                // predictable behaviour. If the user also supplied it, there will be no problem other than the second
+                // addition overriding the first
+                addLibraryAspect(type.getSuperclass().getName());
+            }
             return type;
         } else {
             // FIXME AV - better warning upon no such aspect from aop.xml
@@ -463,7 +468,6 @@ public class BcelWeaver implements IWeaver {
        if (trace.isTraceEnabled()) trace.enter("prepareForWeave",this);
        needToReweaveWorld = xcutSet.hasChangedSinceLastReset();
 
-       CflowPointcut.clearCaches();
        
        // update mungers
        for (Iterator i = addedClasses.iterator(); i.hasNext(); ) { 
@@ -490,6 +494,8 @@ public class BcelWeaver implements IWeaver {
                typeMungerList = xcutSet.getTypeMungers();
         lateTypeMungerList = xcutSet.getLateTypeMungers();
                declareParentsList = xcutSet.getDeclareParents();
+               
+               addCustomMungers();
        
                // The ordering here used to be based on a string compare on toString() for the two mungers - 
                // that breaks for the @AJ style where advice names aren't programmatically generated.  So we
@@ -521,6 +527,30 @@ public class BcelWeaver implements IWeaver {
                if (trace.isTraceEnabled()) trace.exit("prepareForWeave");
     }
     
+    private void addCustomMungers() {
+               if (customMungerFactory != null) {
+                       for (Iterator i = addedClasses.iterator(); i.hasNext();) {
+                               UnwovenClassFile jc = (UnwovenClassFile) i.next();
+                               String name = jc.getClassName();
+                               ResolvedType type = world.resolve(name);
+                               if (type.isAspect()) {
+                                       Collection/*ShadowMunger*/ shadowMungers = customMungerFactory.createCustomShadowMungers(type);
+                                       if (shadowMungers != null) {
+                                               shadowMungerList.addAll(shadowMungers);
+                                       }
+                                       Collection/*ConcreteTypeMunger*/ typeMungers = customMungerFactory
+                                                       .createCustomTypeMungers(type);
+                                       if (typeMungers != null)
+                                               typeMungerList.addAll(typeMungers);
+                               }
+                       }
+               }
+       }
+    
+    public void setCustomMungerFactory(CustomMungerFactory factory) {
+       customMungerFactory = factory;
+    }
+    
     /*
      * Rewrite all of the pointcuts in the world into their most efficient
      * form for subsequent matching. Also ensure that if pc1.equals(pc2)
@@ -833,9 +863,7 @@ public class BcelWeaver implements IWeaver {
         */
        private void raiseUnboundFormalError(String name, Pointcut userPointcut) {
                world.showMessage(IMessage.ERROR,
-                               WeaverMessages.format(WeaverMessages.UNBOUND_FORMAL,
-                                                                               name),
-                               userPointcut.getSourceContext().makeSourceLocation(userPointcut),null);
+                               WeaverMessages.format(WeaverMessages.UNBOUND_FORMAL,name),userPointcut.getSourceLocation(),null);
        }
 
 
@@ -1037,6 +1065,17 @@ public class BcelWeaver implements IWeaver {
                }
           }
 
+       // Go through the types and ensure any 'damaged' during compile time are repaired prior to weaving
+       for (Iterator i = input.getClassFileIterator(); i.hasNext(); ) {
+            UnwovenClassFile classFile = (UnwovenClassFile)i.next();
+            String className = classFile.getClassName();
+            ResolvedType theType = world.resolve(className);
+            if (theType!=null) {
+                   BcelObjectType classType = BcelWorld.getBcelObjectType(theType);
+                   if (classType!=null) classType.ensureDelegateConsistent();
+            }
+       }
+
         // special case for AtAspectJMungerOnly - see #113587
         if (input.isApplyAtAspectJMungersOnly()) {
             ContextToken atAspectJMungersOnly = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_ATASPECTJTYPE_MUNGERS_ONLY, "");
@@ -1345,6 +1384,10 @@ public class BcelWeaver implements IWeaver {
                //clazz is null if the classfile was unchanged by weaving...
                if (clazz != null) {
                        UnwovenClassFile[] newClasses = getClassFilesFor(clazz);
+                       // Copy the char[] across as it means the WeaverAdapter.removeFromMap() can be fast!
+                       if (newClasses[0].getClassName().equals(classFile.getClassName())) {
+                               newClasses[0].setClassNameAsChars(classFile.getClassNameAsChars());
+                       }
                        for (int i = 0; i < newClasses.length; i++) {
                                requestor.acceptResult(newClasses[i]);
                        }
@@ -1374,11 +1417,13 @@ public class BcelWeaver implements IWeaver {
     public UnwovenClassFile[] getClassFilesFor(LazyClassGen clazz) {
        List childClasses = clazz.getChildClasses(world);
        UnwovenClassFile[] ret = new UnwovenClassFile[1 + childClasses.size()];         
-       ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getJavaClassBytesIncludingReweavable(world));
+       // APR29
+       ret[0] = new UnwovenClassFile(clazz.getFileName(),clazz.getClassName(),clazz.getJavaClassBytesIncludingReweavable(world));
        int index = 1;
        for (Iterator iter = childClasses.iterator(); iter.hasNext();) {
                        UnwovenClassFile.ChildClass element = (UnwovenClassFile.ChildClass) iter.next();
-                       UnwovenClassFile childClass = new UnwovenClassFile(clazz.getFileName() + "$" + element.name, element.bytes);
+                       // APR29
+                       UnwovenClassFile childClass = new UnwovenClassFile(clazz.getFileName() + "$" + element.name,/*clazz.getClassName()+"$"+element.name,*/ element.bytes);
                        ret[index++] = childClass;
                }
        return ret;
@@ -1409,8 +1454,8 @@ public class BcelWeaver implements IWeaver {
                        boolean typeChanged = applyDeclareParents(decp,onType);
                        if (typeChanged) {
                                aParentChangeOccurred = true;
-                       } else { // Perhaps it would have matched if a 'dec @type' had modified the type
-                               if (!decp.getChild().isStarAnnotation()) decpToRepeat.add(decp);
+                       } else {
+                               decpToRepeat.add(decp);
                        }
                }
 
@@ -1718,7 +1763,6 @@ public class BcelWeaver implements IWeaver {
                while (iter.hasNext()) {
                        ShadowMunger munger = (ShadowMunger)iter.next();
                        FuzzyBoolean fb = munger.getPointcut().fastMatch(info);
-                       WeaverMetrics.recordFastMatchTypeResult(fb); // Could pass: munger.getPointcut().toString(),info
                        if (fb.maybeTrue()) {
                                result.add(munger);
                        }
index 3678c7cbf367888ce9d806e57600f4f8add6c687..b7b8a21152b4af749c92385dc44e64a9b34d91d7 100644 (file)
@@ -45,13 +45,13 @@ import org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository;
 import org.aspectj.apache.bcel.util.Repository;
 import org.aspectj.bridge.IMessageHandler;
 import org.aspectj.weaver.Advice;
-import org.aspectj.weaver.AdviceKind;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AnnotationOnTypeMunger;
 import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ConcreteTypeMunger;
 import org.aspectj.weaver.ICrossReferenceHandler;
+import org.aspectj.weaver.MemberKind;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.MemberImpl;
 import org.aspectj.weaver.NewParentTypeMunger;
@@ -104,8 +104,6 @@ public class BcelWorld extends World implements Repository {
                
        }
        
-
-       
        private static List getPathEntries(String s) {
                List ret = new ArrayList();
                StringTokenizer tok = new StringTokenizer(s, File.pathSeparator);
@@ -170,61 +168,6 @@ public class BcelWorld extends World implements Repository {
                classPath.addPath(name, this.getMessageHandler());
        }
 
-    /**
-     * Parse a string into advice.
-     * 
-     * <blockquote><pre>
-     * Kind ( Id , ... ) : Pointcut -> MethodSignature
-     * </pre></blockquote>
-     */
-    public Advice shadowMunger(String str, int extraFlag) {
-        str = str.trim();
-        int start = 0;
-        int i = str.indexOf('(');
-        AdviceKind kind = 
-            AdviceKind.stringToKind(str.substring(start, i));
-        start = ++i;
-        i = str.indexOf(')', i);
-        String[] ids = parseIds(str.substring(start, i).trim());
-        //start = ++i;
-        
-        
-        
-        i = str.indexOf(':', i);        
-        start = ++i;        
-        i = str.indexOf("->", i);
-        Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim());
-        Member m = MemberImpl.methodFromString(str.substring(i+2, str.length()).trim());
-
-        // now, we resolve
-        UnresolvedType[] types = m.getParameterTypes();
-        FormalBinding[] bindings = new FormalBinding[ids.length];
-        for (int j = 0, len = ids.length; j < len; j++) {
-            bindings[j] = new FormalBinding(types[j], ids[j], j, 0, 0, "fromString");
-        }
-
-        Pointcut p =
-               pointcut.resolve(new SimpleScope(this, bindings));
-
-        return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null);
-    }
-    
-    private String[] parseIds(String str) {
-        if (str.length() == 0) return ZERO_STRINGS;
-        List l = new ArrayList();
-        int start = 0;
-        while (true) {
-            int i = str.indexOf(',', start);
-            if (i == -1) {
-                l.add(str.substring(start).trim());
-                break;
-            }
-            l.add(str.substring(start, i).trim());
-            start = i+1;
-        }
-        return (String[]) l.toArray(new String[l.size()]);
-    }
-    
     // ---- various interactions with bcel
 
     public static Type makeBcelType(UnresolvedType type) {
@@ -452,7 +395,7 @@ public class BcelWorld extends World implements Repository {
        }
 
        
-       public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberImpl.Kind kind) {
+       public Member makeJoinPointSignatureFromMethod(LazyMethodGen mg, MemberKind kind) {
                Member ret = mg.getMemberView();
                if (ret == null) {
                int mods = mg.getAccessFlags();
@@ -460,7 +403,8 @@ public class BcelWorld extends World implements Repository {
                    mods |= Modifier.INTERFACE;
                }
                if (kind == null) {
-                       if (mg.getName().equals("<init>")) {
+                       //OPTIMIZE surely we can pass the kind in and not resort to string compares?
+                       if (mg.getName().equals("<init>")) {
                                kind = Member.CONSTRUCTOR;
                        } else if (mg.getName().equals("<clinit>")) {
                                kind = Member.STATIC_INITIALIZATION;
@@ -482,12 +426,10 @@ public class BcelWorld extends World implements Repository {
     }
        
        public Member makeJoinPointSignatureForMonitorEnter(LazyClassGen cg,InstructionHandle h) {
-               Instruction i = h.getInstruction();
                return MemberImpl.monitorEnter();
        }
 
        public Member makeJoinPointSignatureForMonitorExit(LazyClassGen cg,InstructionHandle h) {
-               Instruction i = h.getInstruction();
                return MemberImpl.monitorExit();
        }
        
diff --git a/weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java b/weaver/src/org/aspectj/weaver/bcel/KindedAnnotationAccessVar.java
deleted file mode 100644 (file)
index 9e55c5c..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2005 IBM
- * 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://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     Andy Clement     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.weaver.bcel;
-
-import org.aspectj.apache.bcel.Constants;
-import org.aspectj.apache.bcel.generic.Instruction;
-import org.aspectj.apache.bcel.generic.InstructionConstants;
-import org.aspectj.apache.bcel.generic.InstructionFactory;
-import org.aspectj.apache.bcel.generic.InstructionList;
-import org.aspectj.apache.bcel.generic.ObjectType;
-import org.aspectj.apache.bcel.generic.Type;
-import org.aspectj.weaver.Member;
-import org.aspectj.weaver.ResolvedType;
-import org.aspectj.weaver.Shadow;
-import org.aspectj.weaver.UnresolvedType;
-import org.aspectj.weaver.Shadow.Kind;
-
-
-/**
- * Represents access to an annotation on an element, relating to some 'kinded' pointcut.  
- * Depending on the kind of pointcut the element might be a field or a method or a ...
- */
-public class KindedAnnotationAccessVar extends BcelVar {
-
-       private Kind   kind;           // What kind of shadow are we at?
-       private UnresolvedType  containingType; // The type upon which we want to ask for 'member'
-       private Member member;         // For method call/execution and field get/set contains the member that has the annotation
-       
-       public KindedAnnotationAccessVar(Kind kind, ResolvedType type,UnresolvedType theTargetIsStoredHere,Member sig) {
-               super(type,0);
-               this.kind = kind;
-               this.containingType = theTargetIsStoredHere; 
-               this.member = sig;
-       }
-
-       public String toString() {
-               return "KindedAnnotationAccessVar(" + getType() +")";
-       }
-
-    public Instruction createLoad(InstructionFactory fact) {
-               throw new RuntimeException("unimplemented");
-    }
-    public Instruction createStore(InstructionFactory fact) {
-       throw new RuntimeException("unimplemented");
-    }
-
-    public InstructionList createCopyFrom(InstructionFactory fact, int oldSlot) {
-        throw new RuntimeException("unimplemented");
-    }
-    
-       public void appendLoad(InstructionList il, InstructionFactory fact) {
-               il.append(createLoadInstructions(getType(), fact));
-       }
-
-       // FIXME asc Refactor all this stuff - there is a lot of commonality    
-       public InstructionList createLoadInstructions(ResolvedType toType, InstructionFactory fact) {
-               
-               // FIXME asc Decide on whether we ought to build an exception handler for the NoSuchMethodException that can be thrown
-               // by getDeclaredMethod()... right now we don't but no-one seems to care...
-//             LocalVariableGen var_ex = mg.addLocalVariable("ex",Type.getType("Ljava.io.IOException;"),null,null);
-//             int var_ex_slot = var_ex.getIndex();
-//             
-//             InstructionHandle handler = il.append(new ASTORE(var_ex_slot));
-//             var_ex.setStart(handler);
-//             var_ex.setEnd(il.append(InstructionConstants.RETURN));
-//             
-//             mg.addExceptionHandler(try_start, try_end, handler,
-//                             new ObjectType("java.io.IOException"));
-               
-               
-               InstructionList il = new InstructionList();
-               Type jlClass = BcelWorld.makeBcelType(UnresolvedType.JAVA_LANG_CLASS);
-
-               Type jlString = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.String;"));
-               Type jlClassArray = BcelWorld.makeBcelType(UnresolvedType.forSignature("[Ljava.lang.Class;"));
-               
-               Type jlaAnnotation = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.annotation.Annotation;"));
-               
-               if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || 
-                       kind==Shadow.PreInitialization || kind==Shadow.Initialization || 
-                       kind==Shadow.ConstructorCall || kind==Shadow.ConstructorExecution ||
-                       kind==Shadow.AdviceExecution || 
-                       // annotations for fieldset/fieldget when an ITD is involved are stored against a METHOD 
-                       ((kind==Shadow.FieldGet || kind==Shadow.FieldSet) && member.getKind()==Member.METHOD)) { 
-                       
-                       Type jlrMethod = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Method;"));
-               
-               // Calls getClass
-                       
-               // Variant (1) Use the target directly
-                   il.append(fact.createConstant(BcelWorld.makeBcelType(containingType)));
-                               
-               // Variant (2) Ask the target for its class (could give a different answer at runtime)
-        // il.append(target.createLoad(fact));
-        // il.append(fact.createInvoke("java/lang/Object","getClass",jlClass,new Type[]{},Constants.INVOKEVIRTUAL));
-    
-           // il.append(fact.createConstant(new ObjectType(toType.getClassName())));
-       
-      
-                 if (kind==Shadow.MethodCall || kind==Shadow.MethodExecution || kind==Shadow.AdviceExecution || 
-                         // annotations for fieldset/fieldget when an ITD is involved are stored against a METHOD 
-                         ((kind==Shadow.FieldGet || kind==Shadow.FieldSet) && member.getKind()==Member.METHOD) ||
-                         ((kind==Shadow.ConstructorCall || kind==Shadow.ConstructorExecution) && member.getKind()==Member.METHOD)) {
-                       il.append(fact.createConstant(member.getName()));
-                   Type[] paramTypes = null;
-                       paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
-                       buildArray(il,fact,jlClass,paramTypes,1);
-                       // Calls getDeclaredMethod
-                       il.append(fact.createInvoke("java/lang/Class","getDeclaredMethod",jlrMethod,new Type[]{jlString,jlClassArray},Constants.INVOKEVIRTUAL));
-                       // FIXME asc perf Cache the result of getDeclaredMethod() and use it 
-               // again for other annotations on the same signature at this join point
-               // Calls getAnnotation
-               String ss = toType.getName();
-               il.append(fact.createConstant(new ObjectType(toType.getName())));               
-                       il.append(fact.createInvoke("java/lang/reflect/Method","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
-                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
-                 } else { // init/preinit/ctor-call/ctor-exec
-                       Type[] paramTypes = BcelWorld.makeBcelTypes(member.getParameterTypes());
-                       buildArray(il,fact,jlClass,paramTypes,1);
-                       Type jlrCtor = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Constructor;"));
-                       il.append(fact.createInvoke("java/lang/Class","getDeclaredConstructor",jlrCtor,new Type[]{jlClassArray},Constants.INVOKEVIRTUAL));
-               
-                       // !!! OPTIMIZATION: Cache the result of getDeclaredMethod() and use it 
-                       // again for other annotations on the same signature at this join point
-                       // Calls getAnnotation
-                       String ss = toType.getName();
-                       il.append(fact.createConstant(new ObjectType(toType.getName())));               
-                       il.append(fact.createInvoke("java/lang/reflect/Constructor","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
-                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
-                 }
-               } else if (kind == Shadow.FieldSet || kind == Shadow.FieldGet) {
-                       Type jlrField = BcelWorld.makeBcelType(UnresolvedType.forSignature("Ljava.lang.reflect.Field;"));
-                       il.append(fact.createConstant(BcelWorld.makeBcelType(containingType))); // Stick the target on the stack
-                       il.append(fact.createConstant(member.getName())); // Stick what we are after on the stack
-                       il.append(fact.createInvoke("java/lang/Class","getDeclaredField",jlrField,new Type[]{jlString},Constants.INVOKEVIRTUAL));
-                       String ss = toType.getName();
-               il.append(fact.createConstant(new ObjectType(toType.getName())));               
-                       il.append(fact.createInvoke("java/lang/reflect/Field","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
-                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
-               } else if (kind == Shadow.StaticInitialization || kind==Shadow.ExceptionHandler) {
-                       il.append(fact.createConstant(BcelWorld.makeBcelType(containingType)));
-                       String ss = toType.getName();
-               il.append(fact.createConstant(new ObjectType(toType.getName())));               
-                       il.append(fact.createInvoke("java/lang/Class","getAnnotation",jlaAnnotation,new Type[]{jlClass},Constants.INVOKEVIRTUAL));
-                       il.append(Utility.createConversion(fact,jlaAnnotation,BcelWorld.makeBcelType(toType)));
-               } else {
-                       throw new RuntimeException("Don't understand this kind "+kind);
-               }
-               return il;
-               
-       }
-       
-
-       private void buildArray(InstructionList il, InstructionFactory fact, Type arrayElementType, Type[] arrayEntries,int dim) {
-        il.append(fact.createConstant(new Integer(arrayEntries==null?0:arrayEntries.length)));
-        il.append(fact.createNewArray(arrayElementType,(short)dim));
-        if (arrayEntries == null) return;
-        for (int i = 0; i < arrayEntries.length; i++) {
-                       il.append(InstructionFactory.createDup(1));
-                       il.append(fact.createConstant(new Integer(i)));
-               switch (arrayEntries[i].getType()) {
-                 case Constants.T_ARRAY:
-                   il.append(fact.createConstant(new ObjectType(arrayEntries[i].getSignature())));
-                   break;
-                 case Constants.T_BOOLEAN: il.append(fact.createGetStatic("java/lang/Boolean","TYPE",arrayElementType)); break;
-                 case Constants.T_BYTE:il.append(fact.createGetStatic("java/lang/Byte","TYPE",arrayElementType)); break;
-                 case Constants.T_CHAR:il.append(fact.createGetStatic("java/lang/Character","TYPE",arrayElementType)); break;
-                 case Constants.T_INT:il.append(fact.createGetStatic("java/lang/Integer","TYPE",arrayElementType)); break;
-                 case Constants.T_LONG:il.append(fact.createGetStatic("java/lang/Long","TYPE",arrayElementType)); break;
-                 case Constants.T_DOUBLE:il.append(fact.createGetStatic("java/lang/Double","TYPE",arrayElementType)); break;
-                 case Constants.T_FLOAT:il.append(fact.createGetStatic("java/lang/Float","TYPE",arrayElementType)); break;
-                 case Constants.T_SHORT:il.append(fact.createGetStatic("java/lang/Short","TYPE",arrayElementType)); break;
-                 default:
-                   il.append(fact.createConstant(arrayEntries[i]));
-               }
-                       il.append(InstructionConstants.AASTORE);
-               }
-       }
-
-       public void appendLoadAndConvert(
-               InstructionList il,
-               InstructionFactory fact,
-               ResolvedType toType) {
-               il.append(createLoadInstructions(toType, fact));                                
-
-       }
-
-       public void insertLoad(InstructionList il, InstructionFactory fact) {
-               il.insert(createLoadInstructions(getType(), fact));
-       }
-
-}
index ad4728423e3b9cdb05098dc69ad8f07ea729e971..b6c4f11e586704c4dd860d27925c4762ec502eea 100644 (file)
@@ -53,7 +53,7 @@ import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.SourceLocation;
-import org.aspectj.util.CollectionUtil;
+import org.aspectj.util.LangUtil;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.Member;
@@ -481,17 +481,12 @@ public final class LazyClassGen {
         }
         
         // Add a weaver version attribute to the file being produced (if necessary...)
-        boolean hasVersionAttribute = false;        
-        Attribute[] attrs = myGen.getAttributes();
-        for (int i = 0; i < attrs.length && !hasVersionAttribute; i++) {
-                       Attribute attribute = attrs[i];
-                       if (attribute.getName().equals("org.aspectj.weaver.WeaverVersion")) hasVersionAttribute=true;
-               }        
-        if (!hasVersionAttribute)
-               myGen.addAttribute(BcelAttributes.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPool()));
+        if (!myGen.hasAttribute("org.aspectj.weaver.WeaverVersion")) {
+               myGen.addAttribute(Utility.bcelAttribute(new AjAttribute.WeaverVersionInfo(),getConstantPool()));
+        }
 
         if (myType != null && myType.getWeaverState() != null) {
-                       myGen.addAttribute(BcelAttributes.bcelAttribute(
+                       myGen.addAttribute(Utility.bcelAttribute(
                                new AjAttribute.WeaverState(myType.getWeaverState()), 
                                getConstantPool()));
        }
@@ -505,7 +500,13 @@ public final class LazyClassGen {
 
        addAjcInitializers();
 
-        calculateSourceDebugExtensionOffsets();
+               // 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430).  Will be revisited when contents
+               // of attribute are confirmed to be correct.
+       boolean sourceDebugExtensionSupportSwitchedOn = false;
+       
+       if (sourceDebugExtensionSupportSwitchedOn) {
+               calculateSourceDebugExtensionOffsets();
+       }
         
         int len = methodGens.size();
         myGen.setMethods(Method.NoMethods);
@@ -515,25 +516,26 @@ public final class LazyClassGen {
             if (isEmptyClinit(gen)) continue;
             myGen.addMethod(gen.getMethod());
         }
+        
         len = fields.size();
         myGen.setFields(Field.NoFields);
         for (int i = 0; i < len; i++) {
             BcelField gen = (BcelField) fields.get(i);
             myGen.addField(gen.getField(this.constantPoolGen));
         }
-        
-               if (inlinedFiles.size() != 0) {
-                       if (hasSourceDebugExtensionAttribute(myGen)) {
-                               world.showMessage(
-                                       IMessage.WARNING,
-                                       WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()),
-                                       null,
-                                       null);
+
+       if (sourceDebugExtensionSupportSwitchedOn) {
+                       if (inlinedFiles.size() != 0) {
+                               if (hasSourceDebugExtensionAttribute(myGen)) {
+                                       world.showMessage(
+                                               IMessage.WARNING,
+                                               WeaverMessages.format(WeaverMessages.OVERWRITE_JSR45,getFileName()),
+                                               null,
+                                               null);
+                               }
+                               // myGen.addAttribute(getSourceDebugExtensionAttribute());
                        }
-                       // 17Feb05 - ASC - Skip this for now - it crashes IBM 1.4.2 jvms (pr80430).  Will be revisited when contents
-                       // of attribute are confirmed to be correct.
-                       // myGen.addAttribute(getSourceDebugExtensionAttribute());
-               }
+       }
                
                fixupGenericSignatureAttribute();
     }
@@ -560,11 +562,7 @@ public final class LazyClassGen {
                // 2. Find the old attribute
                Signature sigAttr = null;
                if (myType!=null) { // if null, this is a type built from scratch, it won't already have a sig attribute
-                       Attribute[] as = myGen.getAttributes();
-                       for (int i = 0; i < as.length; i++) {
-                               Attribute attribute = as[i];
-                               if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute;
-                       }
+                       sigAttr = (Signature) myGen.getAttribute("Signature");
                }
                
                // 3. Do we need an attribute?
@@ -632,7 +630,7 @@ public final class LazyClassGen {
                // create an empty myGen so that we can give back a return value that doesn't upset the
                // rest of the process.
                myGen = new ClassGen(myGen.getClassName(), myGen.getSuperclassName(), 
-                       myGen.getFileName(), myGen.getAccessFlags(), myGen.getInterfaceNames());
+                       myGen.getFileName(), myGen.getModifiers(), myGen.getInterfaceNames());
                // raise an error against this compilation unit.
                getWorld().showMessage(
                                IMessage.ERROR, 
@@ -643,15 +641,16 @@ public final class LazyClassGen {
        }
 
        private static boolean hasSourceDebugExtensionAttribute(ClassGen gen) {
-               ConstantPool pool = gen.getConstantPool();
-               Attribute[] attrs = gen.getAttributes();
-               for (int i = 0; i < attrs.length; i++) {
-                       if ("SourceDebugExtension"
-                               .equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) {
-                               return true;
-                       }
-               }
-               return false;
+               return gen.hasAttribute("SourceDebugExtension");
+//             ConstantPool pool = gen.getConstantPool();
+//             Attribute[] attrs = gen.getAttributes();
+//             for (int i = 0; i < attrs.length; i++) {
+//                     if ("SourceDebugExtension"
+//                             .equals(((ConstantUtf8) pool.getConstant(attrs[i].getNameIndex())).getBytes())) {
+//                             return true;
+//                     }
+//             }
+//             return false;
        }
 
     public JavaClass getJavaClass(BcelWorld world) {
@@ -734,10 +733,10 @@ public final class LazyClassGen {
 
     public String toShortString() {
         String s =
-            org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getAccessFlags(), true);
+            org.aspectj.apache.bcel.classfile.Utility.accessToString(myGen.getModifiers(), true);
         if (s != "")
             s += " ";
-        s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getAccessFlags());
+        s += org.aspectj.apache.bcel.classfile.Utility.classOrInterface(myGen.getModifiers());
         s += " ";
         s += myGen.getClassName();
         return s;
@@ -861,7 +860,7 @@ public final class LazyClassGen {
                Type.VOID,
                "<clinit>",
                new Type[0],
-               CollectionUtil.NO_STRINGS,
+               LangUtil.NO_STRINGS,
                this);
                clinit.getBody().insert(InstructionConstants.RETURN);
         methodGens.add(clinit);
@@ -878,7 +877,7 @@ public final class LazyClassGen {
                Type.VOID,
                NameMangler.AJC_PRE_CLINIT_NAME,
                new Type[0],
-               CollectionUtil.NO_STRINGS,
+               LangUtil.NO_STRINGS,
                this);
                ajcClinit.getBody().insert(InstructionConstants.RETURN);
         methodGens.add(ajcClinit);
@@ -1258,7 +1257,8 @@ public final class LazyClassGen {
        
        private void makeSyntheticAndTransientIfNeeded(FieldGen field) {
                if (field.getName().startsWith(NameMangler.PREFIX) &&
-                       !field.getName().startsWith("ajc$interField$")) {
+                       !field.getName().startsWith("ajc$interField$") &&
+                       !field.getName().startsWith("ajc$instance$")) {
                        // it's an aj added field
                        // first do transient
                        if (!field.isStatic()) {
@@ -1284,9 +1284,9 @@ public final class LazyClassGen {
                }
        }
        
-               private boolean hasSyntheticAttribute(Attribute[] attributes) {
-               for (int i = 0; i < attributes.length; i++) {
-                       if (attributes[i].getName().equals("Synthetic")) {
+               private boolean hasSyntheticAttribute(List attributes) {
+               for (int i = 0; i < attributes.size(); i++) {
+                       if (((Attribute)attributes.get(i)).getName().equals("Synthetic")) {
                                return true;
                        }
                }
@@ -1338,7 +1338,7 @@ public final class LazyClassGen {
        
        
        public void forcePublic() {
-               myGen.setAccessFlags(Utility.makePublic(myGen.getAccessFlags()));
+               myGen.setModifiers(Utility.makePublic(myGen.getModifiers()));
        }
 
        
index 5859fa7573f5d2e8f9ba18dca1c2c6deec1958b1..3d47ddcad20135227a8d0b66aba4d87bb8ebba80 100644 (file)
@@ -39,6 +39,7 @@ import org.aspectj.apache.bcel.generic.ClassGenException;
 import org.aspectj.apache.bcel.generic.CodeExceptionGen;
 import org.aspectj.apache.bcel.generic.Instruction;
 import org.aspectj.apache.bcel.generic.InstructionBranch;
+import org.aspectj.apache.bcel.generic.InstructionComparator;
 import org.aspectj.apache.bcel.generic.InstructionHandle;
 import org.aspectj.apache.bcel.generic.InstructionList;
 import org.aspectj.apache.bcel.generic.InstructionSelect;
@@ -50,6 +51,7 @@ import org.aspectj.apache.bcel.generic.LocalVariableTag;
 import org.aspectj.apache.bcel.generic.MethodGen;
 import org.aspectj.apache.bcel.generic.ObjectType;
 import org.aspectj.apache.bcel.generic.Tag;
+import org.aspectj.apache.bcel.generic.TargetLostException;
 import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
@@ -69,6 +71,7 @@ import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 import org.aspectj.weaver.tools.Traceable;
 
 
+
 /** 
  * A LazyMethodGen should be treated as a MethodGen.  It's our way of abstracting over the 
  * low-level Method objects.  It converts through {@link MethodGen} to create
@@ -86,22 +89,25 @@ import org.aspectj.weaver.tools.Traceable;
 public final class LazyMethodGen implements Traceable {
        private static final int ACC_SYNTHETIC    = 0x1000;
        
-    private        int             accessFlags;
-    private  Type            returnType;
-    private final String          name;
+    private int              accessFlags;
+    private Type             returnType;
+    private final String     name;
     private  Type[]          argumentTypes;
     //private final String[]        argumentNames;
     private  String[]        declaredExceptions;
     private  InstructionList body; // leaving null for abstracts
-    private  Attribute[]     attributes;
+    private  List    attributes;
     private List  newAnnotations;
     private final LazyClassGen enclosingClass;   
     private BcelMethod memberView;
     private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
     int highestLineNumber = 0;
+    boolean wasNewPacked = false;
     
 
     /*
+     * We use LineNumberTags and not Gens.
+     * 
      * This option specifies whether we let the BCEL classes create LineNumberGens and LocalVariableGens
      * or if we make it create LineNumberTags and LocalVariableTags.  Up until 1.5.1 we always created
      * Gens - then on return from the MethodGen ctor we took them apart, reprocessed them all and 
@@ -114,12 +120,7 @@ public final class LazyMethodGen implements Traceable {
      * instructions it targets, it relies on the instructions targetting *it* - this reduces the amount
      * of targeter manipulation we have to do.
      * 
-     * Because this *could* go wrong - it passes all our tests, but you never know, the option:
-     * -Xset:optimizeWithTags=false
-     * will turn it *OFF*
      */
-       public static boolean avoidUseOfBcelGenObjects = true;
-       public static boolean checkedXsetOption = false;
 
        /** This is nonnull if this method is the result of an "inlining".  We currently
         * copy methods into other classes for around advice.  We add this field so
@@ -167,7 +168,7 @@ public final class LazyMethodGen implements Traceable {
         } else {
             body = null;
         }
-        this.attributes = new Attribute[0];
+        this.attributes = new ArrayList();
         this.enclosingClass = enclosingClass;
         assertGoodBody();
 
@@ -207,7 +208,7 @@ public final class LazyMethodGen implements Traceable {
         }
                this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
         
-               this.accessFlags = m.getAccessFlags();
+               this.accessFlags = m.getModifiers();
                this.name = m.getName();
 
         // @AJ advice are not inlined by default since requires further analysis
@@ -233,7 +234,7 @@ public final class LazyMethodGen implements Traceable {
         }
                //this.memberView = new BcelMethod(enclosingClass.getBcelObjectType(), m);
         this.memberView = m;
-               this.accessFlags = savedMethod.getAccessFlags();
+               this.accessFlags = savedMethod.getModifiers();
                this.name = m.getName();
 
         // @AJ advice are not inlined by default since requires further analysis
@@ -301,22 +302,15 @@ public final class LazyMethodGen implements Traceable {
     private void initialize() {
        if (returnType != null) return; 
        
-       // Check whether we need to configure the optimization
-       if (!checkedXsetOption) {
-               Properties p = enclosingClass.getWorld().getExtraConfiguration();
-               if (p!=null) {
-                       String s = p.getProperty("optimizeWithTags","true");
-                       avoidUseOfBcelGenObjects = s.equalsIgnoreCase("true");
-                       if (!avoidUseOfBcelGenObjects) 
-                               enclosingClass.getWorld().getMessageHandler().handleMessage(MessageUtil.info("[optimizeWithTags=false] Disabling optimization to use Tags rather than Gens"));
-               }
-               checkedXsetOption=true;
-        }
-       
        //System.err.println("initializing: " + getName() + ", " + enclosingClass.getName() + ", " + returnType + ", " + savedMethod);
        
-               MethodGen gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(),avoidUseOfBcelGenObjects);
-        
+               MethodGen gen = null;
+               try {
+               gen = new MethodGen(savedMethod, enclosingClass.getName(), enclosingClass.getConstantPool(),true);
+               } catch (RuntimeException t) {
+                       System.err.println(getName());
+                       throw t;
+               }
                this.returnType = gen.getReturnType();
                this.argumentTypes = gen.getArgumentTypes();
 
@@ -341,13 +335,9 @@ public final class LazyMethodGen implements Traceable {
 
             unpackHandlers(gen);
             
-                       if (avoidUseOfBcelGenObjects) {
-                               ensureAllLineNumberSetup(gen);
-                           highestLineNumber = gen.getHighestlinenumber();
-                       } else {
-                               unpackLineNumbers(gen);
-                           unpackLocals(gen);
-                       }
+                       ensureAllLineNumberSetup(gen);
+                   highestLineNumber = gen.getHighestlinenumber();
+                   
         }
         assertGoodBody();
         
@@ -411,29 +401,6 @@ public final class LazyMethodGen implements Traceable {
                }
        }
 
-    private void unpackLineNumbers(MethodGen gen) {
-        LineNumberTag lr = null;
-        for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
-            InstructionTargeter[] targeters = ih.getTargeters();
-            if (targeters != null) {
-                for (int i = targeters.length - 1; i >= 0; i--) {
-                    InstructionTargeter targeter = targeters[i];
-                    if (targeter instanceof LineNumberGen) {
-                        LineNumberGen lng = (LineNumberGen) targeter;
-                        lng.updateTarget(ih, null);
-                        int lineNumber = lng.getSourceLine();
-                        if (highestLineNumber < lineNumber) highestLineNumber = lineNumber;
-                        lr = new LineNumberTag(lineNumber);
-                    }
-                }
-            }
-            if (lr != null) {
-                ih.addTargeter(lr);
-            }
-        }
-        gen.removeLineNumbers();
-    }
-
     /**
      * On entry to this method we have a method whose instruction stream contains a few instructions 
      * that have line numbers assigned to them (LineNumberTags).  The aim is to ensure every instruction
@@ -460,33 +427,6 @@ public final class LazyMethodGen implements Traceable {
             }
         }
     }
-
-    private void unpackLocals(MethodGen gen) {
-        Set locals = new HashSet();
-        for (InstructionHandle ih = body.getStart(); ih != null; ih = ih.getNext()) {
-            InstructionTargeter[] targeters = ih.getTargeters();
-            List ends = new ArrayList(0);
-            if (targeters != null) {
-                for (int i = targeters.length - 1; i >= 0; i--) {
-                    InstructionTargeter targeter = targeters[i];
-                    if (targeter instanceof LocalVariableGen) {
-                        LocalVariableGen lng = (LocalVariableGen) targeter;
-                        LocalVariableTag lr = new LocalVariableTag(lng.getType().getSignature()/*BcelWorld.fromBcel(lng.getType())*/, lng.getName(), lng.getIndex(), lng.getStart().getPosition());
-                        if (lng.getStart() == ih) {
-                            locals.add(lr);
-                        } else {
-                            ends.add(lr);
-                        }
-                    }
-                }
-            }
-            for (Iterator i = locals.iterator(); i.hasNext(); ) {
-                ih.addTargeter((LocalVariableTag) i.next());
-            }
-            locals.removeAll(ends);
-        }
-        gen.removeLocalVariables();
-    }
            
     // ===============
     
@@ -505,7 +445,8 @@ public final class LazyMethodGen implements Traceable {
        
        try {
                        MethodGen gen = pack();
-                       return gen.getMethod();
+                       savedMethod = gen.getMethod();
+                       return savedMethod;
        } catch (ClassGenException e) {
                enclosingClass.getBcelObjectType().getResolvedTypeX().getWorld().showMessage(
                        IMessage.ERROR, 
@@ -522,6 +463,9 @@ public final class LazyMethodGen implements Traceable {
     }
     
     public void markAsChanged() {
+       if (wasNewPacked) {
+               throw new RuntimeException("Already packed method is being re-modified: "+getClassName()+" "+toShortString());
+       }
        initialize();
        savedMethod = null;
     }
@@ -529,7 +473,8 @@ public final class LazyMethodGen implements Traceable {
     // =============================
 
        public String toString() {
-               WeaverVersionInfo weaverVersion = enclosingClass.getBcelObjectType().getWeaverVersionAttribute();
+               BcelObjectType bot = enclosingClass.getBcelObjectType();
+               WeaverVersionInfo weaverVersion = (bot==null?WeaverVersionInfo.CURRENT:bot.getWeaverVersionAttribute());
                return toLongString(weaverVersion);
        }
 
@@ -611,7 +556,7 @@ public final class LazyMethodGen implements Traceable {
                if (enclosingClass != null && enclosingClass.getType() != null) {
                        context = enclosingClass.getType().getSourceContext();
                }
-               List as = BcelAttributes.readAjAttributes(getClassName(),attributes, context,null,weaverVersion);
+               List as = BcelAttributes.readAjAttributes(getClassName(), (Attribute[])attributes.toArray(new Attribute[]{}), context,null,weaverVersion);
                if (! as.isEmpty()) {
                        out.println("    " + as.get(0)); // XXX assuming exactly one attribute, munger...
                }
@@ -909,6 +854,14 @@ public final class LazyMethodGen implements Traceable {
         return name;
     }
 
+    public String getGenericReturnTypeSignature() {
+        if (memberView == null) {
+            return getReturnType().getSignature();
+        } else {
+            return memberView.getGenericReturnType().getSignature();
+        }
+    }
+    
     public Type getReturnType() {
        initialize();
         return returnType;
@@ -928,7 +881,7 @@ public final class LazyMethodGen implements Traceable {
        return body != null;
     }
 
-    public Attribute[] getAttributes() {
+    public List/*Attribute*/ getAttributes() {
         return attributes;
     }
 
@@ -966,8 +919,8 @@ public final class LazyMethodGen implements Traceable {
             gen.addException(declaredExceptions[i]);
         }
         
-        for (int i = 0, len = attributes.length; i < len; i++) {
-            gen.addAttribute(attributes[i]);
+        for (int i = 0, len = attributes.size(); i < len; i++) {
+            gen.addAttribute((Attribute)attributes.get(i));
         }
         
         if (newAnnotations!=null) { 
@@ -996,7 +949,16 @@ public final class LazyMethodGen implements Traceable {
         }
         
         if (hasBody()) {
-            packBody(gen);
+               if (this.enclosingClass.getWorld().shouldGoForIt()) {
+                   if (isAdviceMethod() || getName().equals("<clinit>")) {
+                               packBody(gen);
+                       } else {
+                               newPackBody(gen); 
+                       }
+               } else {
+                       packBody(gen);
+               }
+               // FINISH OFF CASE/SWITCH !
             gen.setMaxLocals();
             gen.setMaxStack();
         } else {
@@ -1109,6 +1071,108 @@ public final class LazyMethodGen implements Traceable {
         }
     }
     
+
+    /*
+     * Andys version
+     */
+    public void newPackBody(MethodGen gen) {
+       InstructionList theBody = getBody();
+        InstructionHandle iHandle = theBody.getStart();
+
+        int currLine = -1;
+               int lineNumberOffset = (fromFilename == null) ? 0: getEnclosingClass().getSourceDebugExtensionOffset(fromFilename);
+        Map localVariables = new HashMap();
+        LinkedList exceptionList = new LinkedList();   
+        Set forDeletion = new HashSet();
+        Set branchInstructions = new HashSet();
+        // OPTIMIZE sort out in here: getRange()/insertHandler() and type of exceptionList
+        while (iHandle != null) {
+               Instruction inst = iHandle.getInstruction();
+               InstructionHandle nextInst = iHandle.getNext();
+               // OPTIMIZE remove this instructionhandle as it now points to nowhere?
+               if (inst == Range.RANGEINSTRUCTION) {
+                       Range r = Range.getRange(iHandle);
+                       if (r instanceof ExceptionRange) {
+                           ExceptionRange er = (ExceptionRange) r;
+                           if (er.getStart() == iHandle) {
+                               if (!er.isEmpty()){
+                                       // order is important, insert handlers in order of start
+                                       insertHandler(er, exceptionList);                     
+                               }
+                           }
+                       } 
+                       forDeletion.add(iHandle);
+               } else {
+                       if (inst instanceof InstructionBranch) {
+                               branchInstructions.add(iHandle);
+                       }
+
+              InstructionTargeter[] targeters = iHandle.getTargeters();
+              if (targeters != null) {
+                  for (int k = targeters.length - 1; k >= 0; k--) {
+                      InstructionTargeter targeter = targeters[k];
+                      if (targeter instanceof LineNumberTag) {
+                          int line = ((LineNumberTag)targeter).getLineNumber();
+                          if (line != currLine) {
+                              gen.addLineNumber(iHandle, line + lineNumberOffset);
+                              currLine = line;
+                          }
+                      } else if (targeter instanceof LocalVariableTag) {
+                          LocalVariableTag lvt = (LocalVariableTag) targeter;
+                          LVPosition p = (LVPosition)localVariables.get(lvt);
+                          // If we don't know about it, create a new position and store
+                          // If we do know about it - update its end position
+                          if (p==null) {
+                               LVPosition newp = new LVPosition();
+                               newp.start=newp.end=iHandle;
+                               localVariables.put(lvt,newp);
+                          } else {
+                               p.end = iHandle;
+                          }
+                      }
+                  }
+              }
+               }
+               iHandle = iHandle.getNext();
+        }
+        for (Iterator iterator = branchInstructions.iterator(); iterator.hasNext();) {
+                       BranchHandle iBranch = (BranchHandle) iterator.next();
+                       handleBranchInstruction(iBranch,forDeletion);
+               }
+       // now add exception handlers
+        for (Iterator iter = exceptionList.iterator(); iter.hasNext();) {
+            ExceptionRange r = (ExceptionRange) iter.next();
+            if (r.isEmpty()) continue;
+            gen.addExceptionHandler(
+                jumpForward(r.getRealStart(),forDeletion), 
+                jumpForward(r.getRealEnd(),forDeletion),
+                jumpForward(r.getHandler(),forDeletion),
+                (r.getCatchType() == null)
+                ? null 
+                : (ObjectType) BcelWorld.makeBcelType(r.getCatchType()));
+        }
+        
+        for (Iterator iterator = forDeletion.iterator(); iterator.hasNext();) {
+               try {
+                               theBody.delete((InstructionHandle)iterator.next());
+                       } catch (TargetLostException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+        }
+        gen.setInstructionList(theBody);
+        addLocalVariables(gen,localVariables);
+        
+        // JAVAC adds line number tables (with just one entry) to generated accessor methods - this
+        // keeps some tools that rely on finding at least some form of linenumbertable happy.
+        // Let's check if we have one - if we don't then let's add one.
+        // TODO Could be made conditional on whether line debug info is being produced
+        if (gen.getLineNumbers().length==0) { 
+               gen.addLineNumber(gen.getInstructionList().getStart(),1);
+        }
+        wasNewPacked = true;
+    }
+    
     private void addLocalVariables(MethodGen gen, Map localVariables) {
                // now add local variables
         gen.removeLocalVariables();
@@ -1166,28 +1230,59 @@ public final class LazyMethodGen implements Traceable {
                InstructionBranch newBranchInstruction = (InstructionBranch) newInstruction;
            InstructionHandle oldTarget = oldBranchInstruction.getTarget(); // old target
    
-//                             try {
            // New target is in hash map
            newBranchInstruction.setTarget(remap(oldTarget, map));
-//                             } catch (NullPointerException e) {
-//                                     print();
-//                                     System.out.println("Was trying to remap " + bi);
-//                                     System.out.println("who's target was supposedly " + itarget);
-//                                     throw e;
-//                             }
    
-                   if (oldBranchInstruction instanceof InstructionSelect) { 
-                       // Either LOOKUPSWITCH or TABLESWITCH
-                       InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets();
-                       InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets();
+           if (oldBranchInstruction instanceof InstructionSelect) { 
+               // Either LOOKUPSWITCH or TABLESWITCH
+               InstructionHandle[] oldTargets = ((InstructionSelect) oldBranchInstruction).getTargets();
+               InstructionHandle[] newTargets = ((InstructionSelect) newBranchInstruction).getTargets();
    
-                       for (int k = oldTargets.length - 1; k >= 0; k--) { 
-                           // Update all targets
+               for (int k = oldTargets.length - 1; k >= 0; k--) { 
+                   // Update all targets
                    newTargets[k] = remap(oldTargets[k], map);
                    newTargets[k].addTargeter(newBranchInstruction);
                }
            }
        }
+       
+       private InstructionHandle jumpForward(InstructionHandle t,Set handlesForDeletion) {
+               
+               InstructionHandle target = t;
+                 if (handlesForDeletion.contains(target)) {
+                       do {
+                               target = target.getNext();
+                       } while (handlesForDeletion.contains(target));
+                   }
+                 return target;
+       }
+       
+       private void handleBranchInstruction(BranchHandle branchHandle, Set handlesForDeletion) {
+               InstructionBranch branchInstruction = (InstructionBranch) branchHandle.getInstruction();
+           InstructionHandle target = branchInstruction.getTarget(); // old target
+   
+           if (handlesForDeletion.contains(target)) {
+               do {
+                       target = target.getNext();
+               } while (handlesForDeletion.contains(target));
+               branchInstruction.setTarget(target);
+           }
+   
+           if (branchInstruction instanceof InstructionSelect) { 
+               // Either LOOKUPSWITCH or TABLESWITCH
+               InstructionHandle[] targets = ((InstructionSelect)branchInstruction).getTargets();
+               for (int k = targets.length - 1; k >= 0; k--) { 
+                       InstructionHandle oneTarget = targets[k];
+                       if (handlesForDeletion.contains(oneTarget)) {
+                       do {
+                               oneTarget = oneTarget.getNext();
+                       } while (handlesForDeletion.contains(oneTarget));
+                       branchInstruction.setTarget(oneTarget);
+                       oneTarget.addTargeter(branchInstruction);
+                   }
+               }
+           }
+       }
 
        private void handleRangeInstruction(InstructionHandle ih, LinkedList exnList) {
                // we're a range instruction
@@ -1251,6 +1346,13 @@ public final class LazyMethodGen implements Traceable {
 //                     curr = next;
 //     }
 //     }
+   
+   private static InstructionHandle fNext(InstructionHandle ih) {
+          while (true) {
+                  if (ih.getInstruction()==Range.RANGEINSTRUCTION) ih = ih.getNext();
+                  else return ih;
+          }
+   }
 
     private static InstructionHandle remap(InstructionHandle ih, Map map) {
         while (true) {
@@ -1513,6 +1615,7 @@ public final class LazyMethodGen implements Traceable {
     // ----
     
     boolean isAdviceMethod() {
+       if (memberView==null) return false;
        return memberView.getAssociatedShadowMunger() != null;
     }
     
@@ -1576,10 +1679,11 @@ public final class LazyMethodGen implements Traceable {
      * @param attr
      */
     public void addAttribute(Attribute attr) {
-        Attribute[] newAttributes = new Attribute[attributes.length + 1];
-        System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
-        newAttributes[attributes.length] = attr;
-        attributes = newAttributes;
+       attributes.add(attr);
+//        Attribute[] newAttributes = new Attribute[attributes.length + 1];
+//        System.arraycopy(attributes, 0, newAttributes, 0, attributes.length);
+//        newAttributes[attributes.length] = attr;
+//        attributes = newAttributes;
     }
 
        public String toTraceString() {
index 09e5f48c390e66bfba7b3fbbe1d1a95bf57d62a1..697124151319b3ecc01036323e0f43f96081a4dc 100644 (file)
@@ -27,6 +27,7 @@ import org.aspectj.util.FileUtil;
 
 public class UnwovenClassFile {
        protected String filename;
+       protected char[] charfilename;
        protected byte[] bytes;
 //     protected JavaClass javaClass = null;
        //protected byte[] writtenBytes = null;
@@ -149,9 +150,15 @@ public class UnwovenClassFile {
                return true;
        }
 
+       public char[] getClassNameAsChars() {
+               if (charfilename==null) {
+                       charfilename = getClassName().replace('.', '/').toCharArray();
+               }
+               return charfilename;
+       }
        
        public String getClassName() {
-               if (className == null) className = getJavaClass().getClassName();
+               if (className == null) className = getJavaClass().getClassName(); // OPTIMIZE quicker way to determine name??? surely?
                return className;
        }
        
@@ -184,6 +191,7 @@ public class UnwovenClassFile {
        }
 
        // record
+       // OPTIMIZE why is the 'short name' used here (the bit after the dollar) - seems we mess about a lot trimming it off only to put it back on!
        public static class ChildClass {
                public final String name;
                public final byte[] bytes;
@@ -206,6 +214,10 @@ public class UnwovenClassFile {
                        return "(ChildClass " + name + ")";
                }
        }
+
+       public void setClassNameAsChars(char[] classNameAsChars) {
+               this.charfilename = classNameAsChars;
+       }
 }
 
 
index 869a10073bc780335bebefcc821dd7bd22e9c843..c90872a526273d2ceaffb81f3ea89940d837297a 100644 (file)
@@ -29,9 +29,11 @@ public class UnwovenClassFileWithThirdPartyManagedBytecode
                byte[] getBytes();
        }
        
-       public UnwovenClassFileWithThirdPartyManagedBytecode(String filename,
+       // OPTIMIZE make classname an input char[]
+       public UnwovenClassFileWithThirdPartyManagedBytecode(String filename,String classname,
                        IByteCodeProvider provider) {
-               super(filename,null);
+               // APR29
+               super(filename,classname,null);
                this.provider = provider;
        }
        
index 1f0db781bbc3065cae39f7eb7fc331bef578a7f4..766f7013468d2ca562a38726bc5aea3960e18dae 100644 (file)
@@ -24,9 +24,12 @@ import java.util.Hashtable;
 import java.util.List;
 
 import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.Attribute;
 import org.aspectj.apache.bcel.classfile.ClassParser;
+import org.aspectj.apache.bcel.classfile.ConstantPool;
 import org.aspectj.apache.bcel.classfile.JavaClass;
 import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.classfile.Unknown;
 import org.aspectj.apache.bcel.classfile.annotation.ArrayElementValueGen;
 import org.aspectj.apache.bcel.classfile.annotation.ElementNameValuePairGen;
 import org.aspectj.apache.bcel.classfile.annotation.ElementValueGen;
@@ -52,6 +55,7 @@ import org.aspectj.apache.bcel.generic.SwitchBuilder;
 import org.aspectj.apache.bcel.generic.TargetLostException;
 import org.aspectj.apache.bcel.generic.Type;
 import org.aspectj.bridge.ISourceLocation;
+import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.Lint;
@@ -205,12 +209,8 @@ public class Utility {
             kind = Constants.INVOKEVIRTUAL;
         }
 
-        return fact.createInvoke(
-            declaringClass.getClassName(),
-            newMethod.getName(),
-            Type.getReturnType(newMethod.getSignature()),
-            Type.getArgumentTypes(newMethod.getSignature()),
-            kind);
+        String sig = newMethod.getSignature();
+        return fact.createInvoke(declaringClass.getClassName(),newMethod.getName(),sig,kind);
        }
        
        public static byte[] stringToUTF(String s) {
@@ -541,37 +541,6 @@ public class Utility {
                }               
        }
        
-    public static String arrayToString(int[] a) {
-        int len = a.length;
-        if (len == 0) return "[]";
-        StringBuffer buf = new StringBuffer("[");
-        buf.append(a[0]);
-        for (int i = 1; i < len; i++) {
-            buf.append(", ");
-            buf.append(a[i]);
-        }
-        buf.append("]");
-        return buf.toString();
-    }
-
-       /**
-        * replace an instruction handle with another instruction, in this case, a branch instruction.
-        * 
-        * @param ih the instruction handle to replace.
-        * @param branchInstruction the branch instruction to replace ih with
-        * @param enclosingMethod where to find ih's instruction list.
-        */
-    public static void replaceInstruction(
-        InstructionHandle ih,
-        InstructionBranch branchInstruction,
-        LazyMethodGen enclosingMethod) 
-    {
-        
-        InstructionList il = enclosingMethod.getBody();
-        InstructionHandle fresh = il.append(ih, branchInstruction);
-               deleteInstruction(ih, fresh, enclosingMethod);
-    }
-    
     public static void replaceInstruction(
        InstructionHandle ih,
        InstructionList replacementInstructions,
@@ -704,15 +673,14 @@ public class Utility {
        
        // assumes that there is no already extant source line tag.  Otherwise we'll have to be better.
        public static void setSourceLine(InstructionHandle ih, int lineNumber) {
+               // OPTIMIZE LineNumberTag instances for the same line could be shared throughout a method...
                ih.addTargeter(new LineNumberTag(lineNumber));
        }
 
        public static int makePublic(int i) {
                return i & ~(Modifier.PROTECTED | Modifier.PRIVATE) | Modifier.PUBLIC;
        }
-       public static int makePrivate(int i) {
-               return i & ~(Modifier.PROTECTED | Modifier.PUBLIC) | Modifier.PRIVATE;
-       }
+
        public static BcelVar[] pushAndReturnArrayOfVars(
                ResolvedType[] proceedParamTypes,
                InstructionList il,
@@ -806,25 +774,33 @@ public class Utility {
      }
     
      // not yet used...
-        public static boolean isSimple(Method method) {
-               if (method.getCode()==null) return true;
-               if (method.getCode().getCode().length>10) return false;
-               InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
-               InstructionHandle InstrHandle = instrucs.getStart();
-               while (InstrHandle != null) {                  
-                 Instruction Instr = InstrHandle.getInstruction();
-                 int opCode = Instr.opcode;
-                 // if current instruction is a branch instruction, see if it's a backward branch.
-                 // if it is return immediately (can't be trivial)
-                 if (Instr instanceof InstructionBranch) {
-                       //  InstructionBranch BI = (InstructionBranch) Instr;
-                     if (Instr.getIndex() < 0) return false;
-                 } else if (Instr instanceof InvokeInstruction) {
-                         // if current instruction is an invocation, indicate that it can't be trivial
-                     return false;
-                 }
-                 InstrHandle = InstrHandle.getNext();
-               }
-               return true;
-        }
+//      public static boolean isSimple(Method method) {
+//             if (method.getCode()==null) return true;
+//             if (method.getCode().getCode().length>10) return false;
+//             InstructionList instrucs = new InstructionList(method.getCode().getCode()); // expensive!
+//             InstructionHandle InstrHandle = instrucs.getStart();
+//             while (InstrHandle != null) {                  
+//               Instruction Instr = InstrHandle.getInstruction();
+//               int opCode = Instr.opcode;
+//               // if current instruction is a branch instruction, see if it's a backward branch.
+//               // if it is return immediately (can't be trivial)
+//               if (Instr instanceof InstructionBranch) {
+//                     //  InstructionBranch BI = (InstructionBranch) Instr;
+//                   if (Instr.getIndex() < 0) return false;
+//               } else if (Instr instanceof InvokeInstruction) {
+//                       // if current instruction is an invocation, indicate that it can't be trivial
+//                   return false;
+//               }
+//               InstrHandle = InstrHandle.getNext();
+//             }
+//             return true;
+//      }
+
+       public static Attribute bcelAttribute(AjAttribute a, ConstantPool pool) {
+               int nameIndex = pool.addUtf8(a.getNameString());
+               byte[] bytes = a.getBytes();
+               int length = bytes.length;
+       
+               return new Unknown(nameIndex, length, bytes, pool);
+       }
 }
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/bcel/ZipFileWeaver.java b/weaver/src/org/aspectj/weaver/bcel/ZipFileWeaver.java
deleted file mode 100644 (file)
index 3be5ae3..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * 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://www.eclipse.org/legal/epl-v10.html 
- *  
- * Contributors: 
- *     PARC     initial implementation 
- * ******************************************************************/
-
-
-package org.aspectj.weaver.bcel;
-
-import java.io.File;
-import java.io.IOException;
-
-
-//XXX delete very soon
-public class ZipFileWeaver {
-       File inFile;
-       public ZipFileWeaver(File inFile) {
-               super();
-               this.inFile = inFile;
-       }
-
-       public void weave(BcelWeaver weaver, File outFile) throws IOException {
-               int count = 0;
-               long startTime = System.currentTimeMillis();
-               weaver.addJarFile(inFile, new File("."),false);
-               weaver.weave(outFile);
-               long stopTime = System.currentTimeMillis();
-               
-               
-               System.out.println("handled " + count + " entries, in " + 
-                               (stopTime-startTime)/1000. + " seconds");
-       }
-}
index 4e4dfc2b77441dbea3c8ab2562e88ee39bf3276b..2ff58dcd0961cf031a56e044c3329a430c0797be 100644 (file)
@@ -14,6 +14,9 @@ package org.aspectj.weaver.loadtime;
 import java.io.IOException;
 import java.net.URL;
 import java.util.Enumeration;
+import java.util.List;
+
+import org.aspectj.weaver.tools.WeavingAdaptor;
 
 /**
  * This class adds support to AspectJ for an OSGi environment
@@ -73,4 +76,14 @@ public interface IWeavingContext {
         */
        public boolean isLocallyDefined(String classname);
 
+       /**
+        * Allow custom parsing of aop.xml or alternative mechanism for providing 
+        * Definitions
+        * 
+        * @param loader
+        * @param adaptor
+        * @return List containing 0 or more Definition instances
+        */
+    public List getDefinitions(final ClassLoader loader, WeavingAdaptor adaptor);
+
 }
index d5d13cc38da588805a14de891e4bb36f0f97ebe2..06fe2684896ad98a734f996db25d492dca101f86 100644 (file)
@@ -258,6 +258,8 @@ public class LTWWorld extends BcelWorld implements IReflectionWorld {
                visitor.visitObject(loader.getParent());
                super.accept(visitor);
        }
-
+        public boolean shouldGoForIt() {
+                return true; // Zooooooooooom
+        }
     
 }
diff --git a/weaver/src/org/aspectj/weaver/ltw/LTWeaver.java b/weaver/src/org/aspectj/weaver/ltw/LTWeaver.java
deleted file mode 100644 (file)
index b69cb67..0000000
+++ /dev/null
@@ -1,22 +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: 
- *   Adrian Colyer                     Initial implementation
- * ******************************************************************/
-package org.aspectj.weaver.ltw;
-
-import org.aspectj.weaver.IWeaver;
-
-/**
- * @author adrian
- *
- */
-public class LTWeaver implements IWeaver {
-
-}
index f55f36d71def05f51bd3442c5b528ce22fb5fa15..c9525445faa738a8f1e9ac957bc65accb08f0ae9 100644 (file)
@@ -18,7 +18,8 @@ import org.aspectj.weaver.AnnotatedElement;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
-
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
+import org.aspectj.weaver.ResolvedType;
 /**
  * @author colyer
  *
@@ -39,6 +40,10 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
        public FuzzyBoolean matches(AnnotatedElement annotated) {
                return left.matches(annotated).and(right.matches(annotated));
        }
+       
+       public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations ) {
+               return left.matches(annotated,parameterAnnotations).and(right.matches(annotated,parameterAnnotations));
+       }
 
        public void resolve(World world) {
                left.resolve(world);
@@ -60,6 +65,7 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
                AnnotationTypePattern newRight = right.parameterizeWith(typeVariableMap,w);
                AndAnnotationTypePattern ret = new AndAnnotationTypePattern(newLeft,newRight);
                ret.copyLocationFrom(this);
+               if (this.isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
                return ret;
        }
        
@@ -68,6 +74,9 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
                                AnnotationTypePattern.read(s,context),
                                AnnotationTypePattern.read(s,context));
                p.readLocation(context,s);
+               if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
+                       if (s.readBoolean()) p.setForParameterAnnotationMatch();                        
+               }
                return p;               
        }
        
@@ -76,18 +85,20 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
                left.write(s);
                right.write(s);
                writeLocation(s);
+               s.writeBoolean(isForParameterAnnotationMatch());
        }
        
        public boolean equals(Object obj) {
                if (!(obj instanceof AndAnnotationTypePattern)) return false;
                AndAnnotationTypePattern other = (AndAnnotationTypePattern) obj;
-               return (left.equals(other.left) && right.equals(other.right));
+               return (left.equals(other.left) && right.equals(other.right) && left.isForParameterAnnotationMatch()==right.isForParameterAnnotationMatch());
        }
        
        public int hashCode() {
                int result = 17;
                result = result*37 + left.hashCode();
                result = result*37 + right.hashCode();
+               result = result*37 + (isForParameterAnnotationMatch()?0:1);
                return result;          
        }
        
@@ -108,4 +119,9 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern {
                right.traverse(visitor,ret);
                return ret;
        }
+
+       public void setForParameterAnnotationMatch() {
+               left.setForParameterAnnotationMatch();
+               right.setForParameterAnnotationMatch();
+       }
 }
index 78a2b10425649f30c13da50c3dc8b7ec66e7b690..8284407ea5c4bd1ddb47d59f00524372c51009e3 100644 (file)
@@ -18,6 +18,7 @@ import org.aspectj.weaver.AnnotatedElement;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
+import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
 
@@ -25,6 +26,8 @@ public abstract class AnnotationTypePattern extends PatternNode {
 
        public static final AnnotationTypePattern ANY = new AnyAnnotationTypePattern();
        public static final AnnotationTypePattern ELLIPSIS = new EllipsisAnnotationTypePattern();
+       public static final AnnotationTypePattern[] NONE = new AnnotationTypePattern[0];
+       private boolean isForParameterAnnotationMatch;
        
        /**
         * TODO: write, read, equals & hashcode both in annotation hierarachy and
@@ -35,6 +38,7 @@ public abstract class AnnotationTypePattern extends PatternNode {
        }
        
        public abstract FuzzyBoolean matches(AnnotatedElement annotated);
+       public abstract FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations);
        
        public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
                return FuzzyBoolean.MAYBE;
@@ -84,44 +88,22 @@ public abstract class AnnotationTypePattern extends PatternNode {
                throw new BCException("unknown TypePattern kind: " + key);
        }
 
-}
-
-class AnyAnnotationTypePattern extends AnnotationTypePattern {
-
-    public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
-        return FuzzyBoolean.YES;
-    }
-    
-       public FuzzyBoolean matches(AnnotatedElement annotated) {
-               return FuzzyBoolean.YES;
-       }
-
-       public void write(DataOutputStream s) throws IOException {
-               s.writeByte(AnnotationTypePattern.ANY_KEY);
-       }
-       
-       public void resolve(World world) {
-       }
-       
-       public String toString() { return "@ANY"; }
+       public void setForParameterAnnotationMatch() { isForParameterAnnotationMatch = true; }
+       public boolean isForParameterAnnotationMatch() { return isForParameterAnnotationMatch; }
 
-    public Object accept(PatternNodeVisitor visitor, Object data) {
-        return visitor.visit(this, data);
-    }
-    
-    public boolean isAny() { return true; }
-    
-    public AnnotationTypePattern parameterizeWith(Map arg0,World w) {
-       return this;
-    }
 }
 
+
 class EllipsisAnnotationTypePattern extends AnnotationTypePattern {
 
        public FuzzyBoolean matches(AnnotatedElement annotated) {
                return FuzzyBoolean.NO;
        }
 
+       public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
+               return FuzzyBoolean.NO;
+       }
+
        public void write(DataOutputStream s) throws IOException {
                s.writeByte(AnnotationTypePattern.ELLIPSIS_KEY);
        }
diff --git a/weaver/src/org/aspectj/weaver/patterns/AnyAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AnyAnnotationTypePattern.java
new file mode 100644 (file)
index 0000000..4a2f30a
--- /dev/null
@@ -0,0 +1,55 @@
+/* *******************************************************************
+ * Copyright (c) 2008 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors
+ * Andy Clement - extracted from AnnotationTypePattern
+ * ******************************************************************/
+ package org.aspectj.weaver.patterns;
+
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Map;
+
+import org.aspectj.util.FuzzyBoolean;
+import org.aspectj.weaver.AnnotatedElement;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.ResolvedType;
+
+public class AnyAnnotationTypePattern extends AnnotationTypePattern {
+
+    public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
+        return FuzzyBoolean.YES;
+    }
+    
+       public FuzzyBoolean matches(AnnotatedElement annotated) {
+               return FuzzyBoolean.YES;
+       }
+       
+       public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
+               return FuzzyBoolean.YES;
+       }
+
+       public void write(DataOutputStream s) throws IOException {
+               s.writeByte(AnnotationTypePattern.ANY_KEY);
+       }
+       
+       public void resolve(World world) {
+       }
+       
+       public String toString() { return "@ANY"; }
+
+    public Object accept(PatternNodeVisitor visitor, Object data) {
+        return visitor.visit(this, data);
+    }
+    
+    public boolean isAny() { return true; }
+    
+    public AnnotationTypePattern parameterizeWith(Map arg0,World w) {
+       return this;
+    }
+}
\ No newline at end of file
index 67cfc41ef9800a671bc255fa218a03fe14660baf..68d2d62f1165be46077074a017818f822b43debe 100644 (file)
@@ -23,7 +23,7 @@ import java.util.Map;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.util.FuzzyBoolean;
-import org.aspectj.weaver.BetaException;
+import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
 import org.aspectj.weaver.ResolvedType;
@@ -293,7 +293,7 @@ public class ArgsPointcut extends NameBindingPointcut {
                        }
                        return findResidueNoEllipsis(shadow, state, patternsWithoutEllipsis);
                } else {
-                       throw new BetaException("unimplemented");
+                       throw new BCException("unimplemented");
                }
        }
        
index 7b84c9c44ec0a48be6408ce0ade253a490f93dc0..392b6f933c5061628201fe69bc39f207eba0445a 100644 (file)
@@ -106,6 +106,7 @@ public class BasicTokenSource implements ITokenSource {
                                case '@':
                                case '<':
                                case '>':
+                               case '=':
                                case    '?':
                                    tokens.add(BasicToken.makeOperator(makeString(ch), i-1, i-1));
                                    continue;
index adecd08dfbff36424ea5eca1972a08e6e084d41d..feff42b0d64b58840837dad9d4fdf50c01ea4524 100644 (file)
@@ -33,7 +33,7 @@ public class BindingAnnotationTypePattern extends ExactAnnotationTypePattern imp
         * @param annotationType
         */
        public BindingAnnotationTypePattern(UnresolvedType annotationType, int index) {
-               super(annotationType);
+               super(annotationType,null);
                this.formalIndex = index;
        }
                
@@ -105,7 +105,7 @@ public class BindingAnnotationTypePattern extends ExactAnnotationTypePattern imp
        
        public AnnotationTypePattern remapAdviceFormals(IntMap bindings) {                      
                if (!bindings.hasKey(formalIndex)) {
-                       return new ExactAnnotationTypePattern(annotationType);
+                       return new ExactAnnotationTypePattern(annotationType,null);
                } else {
                        int newFormalIndex = bindings.get(formalIndex);
                        return new BindingAnnotationTypePattern(annotationType, newFormalIndex);
index 1229cd473ed2c654b994d68f7ca3b6d4472c2fc9..887b5ac00658af0df5fc62e30d9bb5fa1c1673ea 100644 (file)
@@ -50,8 +50,6 @@ public class CflowPointcut extends Pointcut {
        boolean isBelow;// Is this cflowbelow?
        private int[] freeVars;
        
-       private static Hashtable cflowFields = new Hashtable();
-       private static Hashtable cflowBelowFields = new Hashtable();
        
        /**
         * Used to indicate that we're in the context of a cflow when concretizing if's
@@ -217,7 +215,7 @@ public class CflowPointcut extends Pointcut {
                if (freeVars==null || freeVars.length == 0) { // No state, so don't use a stack, use a counter.
                  ResolvedMember localCflowField = null;
 
-                 Object field = getCflowfield(concreteEntry,concreteAspect,"counter");
+                 Object field = getCflowfield(xcut, concreteEntry, concreteAspect, "counter");
                  
                  // Check if we have already got a counter for this cflow pointcut
                  if (field != null) {
@@ -236,7 +234,7 @@ public class CflowPointcut extends Pointcut {
                        concreteAspect.crosscuttingMembers.addConcreteShadowMunger(
                    Advice.makeCflowEntry(world,concreteEntry,isBelow,localCflowField,freeVars==null?0:freeVars.length,innerCflowEntries,inAspect));
            
-                       putCflowfield(concreteEntry,concreteAspect,localCflowField,"counter"); // Remember it
+                       putCflowfield(xcut,concreteEntry,concreteAspect,localCflowField,"counter"); // Remember it
              }
                    
                  Pointcut ret = new ConcreteCflowPointcut(localCflowField, null,true);
@@ -276,7 +274,7 @@ public class CflowPointcut extends Pointcut {
                                slots.add(slot);
                        }
                        ResolvedMember localCflowField = null;
-                       Object field = getCflowfield(concreteEntry,concreteAspect,"stack");
+                       Object field = getCflowfield(xcut,concreteEntry,concreteAspect,"stack");
                        if (field != null) {
                                localCflowField = (ResolvedMember)field;
                        } else {
@@ -295,7 +293,7 @@ public class CflowPointcut extends Pointcut {
                        
                          concreteAspect.crosscuttingMembers.addTypeMunger(
                                world.makeCflowStackFieldAdder(localCflowField));
-                         putCflowfield(concreteEntry,concreteAspect,localCflowField,"stack");
+                         putCflowfield(xcut,concreteEntry,concreteAspect,localCflowField,"stack");
                    }
                        Pointcut ret = new ConcreteCflowPointcut(localCflowField, slots,false);
                        ret.copyLocationFrom(this);
@@ -304,10 +302,6 @@ public class CflowPointcut extends Pointcut {
                
        }
        
-       public static void clearCaches() {
-               cflowFields.clear();
-               cflowBelowFields.clear();
-       }
        
        private String getKey(Pointcut p,ResolvedType a,String stackOrCounter) {
          StringBuffer sb = new StringBuffer();
@@ -319,22 +313,22 @@ public class CflowPointcut extends Pointcut {
          return sb.toString();
        }
        
-       private Object getCflowfield(Pointcut pcutkey, ResolvedType concreteAspect,String stackOrCounter) {
+       private Object getCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey, ResolvedType concreteAspect,String stackOrCounter) {
                String key = getKey(pcutkey,concreteAspect,stackOrCounter);
                Object o =null;
-               if (isBelow) o = cflowBelowFields.get(key);
-               else         o = cflowFields.get(key);
+               if (isBelow) o = xcut.getCflowBelowFields().get(key);
+               else         o = xcut.getCflowFields().get(key);
                //System.err.println("Retrieving for key "+key+" returning "+o);
                return o;
        }
        
-       private void putCflowfield(Pointcut pcutkey,ResolvedType concreteAspect,Object o,String stackOrCounter) {
+       private void putCflowfield(CrosscuttingMembers xcut, Pointcut pcutkey,ResolvedType concreteAspect,Object o,String stackOrCounter) {
                String key = getKey(pcutkey,concreteAspect,stackOrCounter);
                //System.err.println("Storing cflow field for key"+key);
                if (isBelow) {
-                       cflowBelowFields.put(key,o);
+                       xcut.getCflowBelowFields().put(key,o);
                } else {
-                       cflowFields.put(key,o);
+                       xcut.getCflowFields().put(key,o);
                }
        }
 
@@ -342,23 +336,4 @@ public class CflowPointcut extends Pointcut {
         return visitor.visit(this, data);
        }
 
-       public static void clearCaches(ResolvedType aspectType) {
-               //System.err.println("Wiping entries starting "+aspectType.getName());
-               String key = aspectType.getName()+"::";
-               wipeKeys(key,cflowFields);
-               wipeKeys(key,cflowBelowFields);
-       }
-       
-       private static void wipeKeys(String keyPrefix,Hashtable ht) {
-               Enumeration keys = ht.keys();
-               List forRemoval = new ArrayList();
-               while (keys.hasMoreElements()) {
-                       String s = (String)keys.nextElement();
-                       if (s.startsWith(keyPrefix)) forRemoval.add(s);
-               }
-               for (Iterator iter = forRemoval.iterator(); iter.hasNext();) {
-                       String element = (String) iter.next();
-                       ht.remove(element);
-               }
-       }
 }
index 9f2a98a49f708819a705f17d64d893dfd3af9449..c00c4a73f00dc5c71a288db1a6a6a012cdc52829 100644 (file)
@@ -11,21 +11,27 @@ package org.aspectj.weaver.patterns;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.MessageUtil;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.AnnotatedElement;
+import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.ReferenceType;
+import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.TypeVariableReference;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 
 /**
  * Matches an annotation of a given type
@@ -36,11 +42,21 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
        protected String formalName;
        protected boolean resolved = false;
        private boolean bindingPattern = false;
+       private Map annotationValues;
        
        /**
+        * @param annotationValues 
         * 
         */
-       public ExactAnnotationTypePattern(UnresolvedType annotationType) {
+       // OPTIMIZE is annotationtype really unresolved???? surely it is resolved by now...
+       public ExactAnnotationTypePattern(UnresolvedType annotationType, Map annotationValues) {
+               this.annotationType = annotationType;
+               this.annotationValues = annotationValues;
+               this.resolved = (annotationType instanceof ResolvedType);
+       }
+       
+       // Used when deserializing, values will be added
+       private ExactAnnotationTypePattern(UnresolvedType annotationType) {
                this.annotationType = annotationType;
                this.resolved = (annotationType instanceof ResolvedType);
        }
@@ -60,9 +76,13 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
     public UnresolvedType getAnnotationType() {
         return annotationType;
     }
+    
+    public Map getAnnotationValues() {
+       return annotationValues;
+    }
 
        public FuzzyBoolean fastMatches(AnnotatedElement annotated) {
-               if (annotated.hasAnnotation(annotationType)) {
+               if (annotated.hasAnnotation(annotationType) && annotationValues == null) {
                        return FuzzyBoolean.YES;
                } else {
                        // could be inherited, but we don't know that until we are 
@@ -72,30 +92,116 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
        }
        
        public FuzzyBoolean matches(AnnotatedElement annotated) {
-               boolean checkSupers = false;
-               if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
-                       if (annotated instanceof ResolvedType) {
-                               checkSupers = true;
-                       }
-               }
-               
-               if (annotated.hasAnnotation(annotationType)) {
-                       if (annotationType instanceof ReferenceType) {
-                               ReferenceType rt = (ReferenceType)annotationType;
-                               if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) {
-                                       rt.getWorld().getMessageHandler().handleMessage(
-                                         MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation()));
-                                       return FuzzyBoolean.NO;
+               return matches(annotated,null);
+       }
+       
+       public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
+               if (!isForParameterAnnotationMatch()) {
+                       boolean checkSupers = false;
+                       if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
+                               if (annotated instanceof ResolvedType) {
+                                       checkSupers = true;
                                }
                        }
-                       return FuzzyBoolean.YES;
-               } else if (checkSupers) {
-                       ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
-                       while (toMatchAgainst != null) {
-                               if (toMatchAgainst.hasAnnotation(annotationType)) return FuzzyBoolean.YES;
-                               toMatchAgainst = toMatchAgainst.getSuperclass();
+                       
+                       if (annotated.hasAnnotation(annotationType)) {
+                               if (annotationType instanceof ReferenceType) {
+                                       ReferenceType rt = (ReferenceType)annotationType;
+                                       if (rt.getRetentionPolicy()!=null && rt.getRetentionPolicy().equals("SOURCE")) {
+                                               rt.getWorld().getMessageHandler().handleMessage(
+                                                 MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,annotationType,annotated),getSourceLocation()));
+                                               return FuzzyBoolean.NO;
+                                       }
+                               }
+                               
+                               
+                               // Are we also matching annotation values?
+                               if (annotationValues!=null) {
+                                       AnnotationX theAnnotation = annotated.getAnnotationOfType(annotationType);
+                                       
+                                       // Check each one
+                                       Set keys = annotationValues.keySet();
+                                       for (Iterator keyIter = keys.iterator(); keyIter.hasNext();) {
+                                               String k = (String) keyIter.next();
+                                               String v = (String)annotationValues.get(k);
+                                               if (theAnnotation.hasNamedValue(k)) {
+                                                       // Simple case, value is 'name=value' and the annotation specified the same thing
+                                                       if (!theAnnotation.hasNameValuePair(k,v)) {
+                                                               return FuzzyBoolean.NO;
+                                                       }       
+                                               } else {
+                                                       // Complex case, look at the default value
+                                                       ResolvedMember[] ms = ((ResolvedType)annotationType).getDeclaredMethods();
+                                                       boolean foundMatch = false;
+                                                       for (int i=0; i<ms.length && !foundMatch;i++) {
+                                                               if (ms[i].isAbstract() && ms[i].getParameterTypes().length==0 && ms[i].getName().equals(k)) {
+                                                                       // we might be onto something
+                                                                       String s= ms[i].getAnnotationDefaultValue();
+                                                                       if (s!=null && s.equals(v)) foundMatch=true;;
+                                                               }
+                                                       }
+                                                       if (!foundMatch)
+                                                       return FuzzyBoolean.NO;
+                                               }
+                                       }
+                               }
+                               return FuzzyBoolean.YES;
+                       } else if (checkSupers) {
+                               ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
+                               while (toMatchAgainst != null) {
+                                       if (toMatchAgainst.hasAnnotation(annotationType)) {
+                                               // Are we also matching annotation values?
+                                               if (annotationValues!=null) {
+                                                       AnnotationX theAnnotation = toMatchAgainst.getAnnotationOfType(annotationType);
+                                                       
+                                                       // Check each one
+                                                       Set keys = annotationValues.keySet();
+                                                       for (Iterator keyIter = keys.iterator(); keyIter.hasNext();) {
+                                                               String k = (String) keyIter.next();
+                                                               String v = (String)annotationValues.get(k);
+                                                               if (theAnnotation.hasNamedValue(k)) {
+                                                                       // Simple case, value is 'name=value' and the annotation specified the same thing
+                                                                       if (!theAnnotation.hasNameValuePair(k,v)) {
+                                                                               return FuzzyBoolean.NO;
+                                                                       }       
+                                                               } else {
+                                                                       // Complex case, look at the default value
+                                                                       ResolvedMember[] ms = ((ResolvedType)annotationType).getDeclaredMethods();
+                                                                       boolean foundMatch = false;
+                                                                       for (int i=0; i<ms.length && !foundMatch;i++) {
+                                                                               if (ms[i].isAbstract() && ms[i].getParameterTypes().length==0 && ms[i].getName().equals(k)) {
+                                                                                       // we might be onto something
+                                                                                       String s= ms[i].getAnnotationDefaultValue();
+                                                                                       if (s!=null && s.equals(v)) foundMatch=true;;
+                                                                               }
+                                                                       }
+                                                                       if (!foundMatch)
+                                                                       return FuzzyBoolean.NO;
+                                                               }
+                                                       }
+                                               }
+                                               return FuzzyBoolean.YES;
+                                       }
+                                       toMatchAgainst = toMatchAgainst.getSuperclass();
+                               }
+                       } 
+               } else {
+                       // check parameter annotations
+                       if (parameterAnnotations==null) return FuzzyBoolean.NO;
+                       for (int i = 0; i < parameterAnnotations.length; i++) {
+                               if (annotationType.equals(parameterAnnotations[i])) {
+                                       // Are we also matching annotation values?
+                                       if (annotationValues!=null) {
+                                               parameterAnnotations[i].getWorld().getMessageHandler().handleMessage(
+                                                               MessageUtil.error("Compiler limitation: annotation value matching for parameter annotations not yet supported"));
+                                               return FuzzyBoolean.NO;
+                                       }
+                                       return FuzzyBoolean.YES;
+                               }
                        }
-               } 
+               }
+               
+               
                return FuzzyBoolean.NO;
        }
        
@@ -113,7 +219,9 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
 
        
        public void resolve(World world) {
-               if (!resolved) annotationType = annotationType.resolve(world);
+               if (!resolved) {
+                       annotationType = annotationType.resolve(world);
+               }
                resolved = true;
        }
 
@@ -144,6 +252,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
                                binding.copyLocationFrom(this);
                                bindings.register(binding, scope);
                                binding.resolveBinding(scope.getWorld());
+                               if (isForParameterAnnotationMatch()) binding.setForParameterAnnotationMatch();
                                
                                return binding;
                        } 
@@ -179,10 +288,11 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
                } else if (annotationType.isParameterizedType()) {
                        newAnnotationType = annotationType.parameterize(typeVariableMap);
                }
-               ExactAnnotationTypePattern ret = new ExactAnnotationTypePattern(newAnnotationType);
+               ExactAnnotationTypePattern ret = new ExactAnnotationTypePattern(newAnnotationType,annotationValues);
                ret.formalName = formalName;
                ret.bindingPattern = bindingPattern;
                ret.copyLocationFrom(this);
+               if (isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
                return ret;
        }
        
@@ -219,10 +329,22 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
                        annotationType.write(s);
                }
                writeLocation(s);
+               s.writeBoolean(isForParameterAnnotationMatch());
+               if (annotationValues==null) {
+                       s.writeInt(0);
+               } else {
+                       s.writeInt(annotationValues.size());
+                       Set key = annotationValues.keySet();
+                       for (Iterator keys = key.iterator(); keys.hasNext();) {
+                               String k = (String) keys.next();
+                               s.writeUTF(k);
+                               s.writeUTF((String)annotationValues.get(k));
+                       }
+               }
        }
 
        public static AnnotationTypePattern read(VersionedDataInputStream s,ISourceContext context) throws IOException {
-               AnnotationTypePattern ret;
+               ExactAnnotationTypePattern ret;
                byte version = s.readByte();
                if (version > VERSION) {
                        throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
@@ -234,6 +356,21 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
                        ret = new ExactAnnotationTypePattern(UnresolvedType.read(s));                   
                }
                ret.readLocation(context,s);
+               if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160) {
+                       if (s.readBoolean()) ret.setForParameterAnnotationMatch();
+               }
+               if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) {
+                       int annotationValueCount = s.readInt();
+                       if (annotationValueCount>0) {
+                               Map aValues = new HashMap();
+                               for (int i=0;i<annotationValueCount;i++) {
+                                       String key = s.readUTF();
+                                       String val = s.readUTF();
+                                       aValues.put(key,val);
+                               }
+                               ret.annotationValues = aValues;
+                       }
+               }
                return ret;
        }
        
@@ -243,14 +380,14 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern {
        public boolean equals(Object obj) {
                if (!(obj instanceof ExactAnnotationTypePattern)) return false;
                ExactAnnotationTypePattern other = (ExactAnnotationTypePattern) obj;
-               return (other.annotationType.equals(annotationType));
+               return (other.annotationType.equals(annotationType)) && isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch();
        }
        
        /* (non-Javadoc)
         * @see java.lang.Object#hashCode()
         */
        public int hashCode() {
-               return annotationType.hashCode();
+               return annotationType.hashCode()*37+(isForParameterAnnotationMatch()?0:1);
        }
        
        public String toString() {
index 39c3877a01b1d04f985300e3d82a9af1657dad4f..859e8316fe2005b58ac1bc460b2dee2299f16bd0 100644 (file)
@@ -106,7 +106,12 @@ public class ExactTypePattern extends TypePattern {
                        typeMatch = matchesTypeVariable((TypeVariableReferenceType)matchType);
                }
                annotationPattern.resolve(matchType.getWorld());
-               boolean annMatch = this.annotationPattern.matches(matchType).alwaysTrue();
+               boolean annMatch = false;
+        if (matchType.temporaryAnnotationTypes!=null) {
+            annMatch = annotationPattern.matches(matchType,matchType.temporaryAnnotationTypes).alwaysTrue();
+        } else {
+            annMatch = annotationPattern.matches(matchType).alwaysTrue();
+        }
                return (typeMatch && annMatch);
        }
        
@@ -125,7 +130,12 @@ public class ExactTypePattern extends TypePattern {
                        typeMatch = matchesTypeVariable((TypeVariableReferenceType)matchType);
                }
                annotationPattern.resolve(matchType.getWorld());
-               boolean annMatch = this.annotationPattern.matches(annotatedType).alwaysTrue();
+        boolean annMatch = false;
+        if (annotatedType.temporaryAnnotationTypes!=null) {
+            annMatch = annotationPattern.matches(annotatedType,annotatedType.temporaryAnnotationTypes).alwaysTrue();
+        } else {
+            annMatch = annotationPattern.matches(annotatedType).alwaysTrue();
+        }
                return (typeMatch && annMatch);         
        }
        
@@ -134,6 +144,7 @@ public class ExactTypePattern extends TypePattern {
        // true if (matchType instanceof this.type)
        public FuzzyBoolean matchesInstanceof(ResolvedType matchType) {
                // in our world, Object is assignable from anything
+               annotationPattern.resolve(matchType.getWorld());
                if (type.equals(ResolvedType.OBJECT)) 
                    return FuzzyBoolean.YES.and(annotationPattern.matches(matchType));
                
index cd8cb342065bacaf00a1c02daf9ca3f6c41e4cd6..61a461e01d32793125dc24bc6019ae43e0f84b9b 100644 (file)
@@ -16,8 +16,10 @@ import java.util.Map;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.AnnotatedElement;
 import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 
 public class NotAnnotationTypePattern extends AnnotationTypePattern {
 
@@ -35,6 +37,9 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
                return negatedPattern.matches(annotated).not();
        }
        
+       public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
+               return negatedPattern.matches(annotated,parameterAnnotations).not();
+       }
        /* (non-Javadoc)
         * @see org.aspectj.weaver.patterns.AnnotationTypePattern#resolve(org.aspectj.weaver.World)
         */
@@ -56,6 +61,7 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
                AnnotationTypePattern newNegatedPattern = negatedPattern.parameterizeWith(typeVariableMap,w);
                NotAnnotationTypePattern ret = new NotAnnotationTypePattern(newNegatedPattern);
                ret.copyLocationFrom(this);
+               if (this.isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
                return ret;
        }
        
@@ -66,22 +72,27 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
                s.writeByte(AnnotationTypePattern.NOT);
                negatedPattern.write(s);
                writeLocation(s);
+               s.writeBoolean(isForParameterAnnotationMatch());
        }
 
        public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
                AnnotationTypePattern ret = new NotAnnotationTypePattern(AnnotationTypePattern.read(s,context));
                ret.readLocation(context,s);
+               if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
+                       if (s.readBoolean()) ret.setForParameterAnnotationMatch();
+               }
                return ret;
        }
        
        public boolean equals(Object obj) {
                if (!(obj instanceof NotAnnotationTypePattern)) return false;
                NotAnnotationTypePattern other = (NotAnnotationTypePattern) obj;
-               return other.negatedPattern.equals(negatedPattern);
+               return other.negatedPattern.equals(negatedPattern) && other.isForParameterAnnotationMatch()==isForParameterAnnotationMatch();
        }
 
        public int hashCode() {
                int result = 17 + 37*negatedPattern.hashCode();
+               result = 37*result +(isForParameterAnnotationMatch()?0:1);
                return result;
        }
        
@@ -102,4 +113,8 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern {
                negatedPattern.traverse(visitor,ret);
                return ret;
        }
+
+       public void setForParameterAnnotationMatch() {
+               negatedPattern.setForParameterAnnotationMatch();
+       }
 }
index fe95053c4517f23f670778802762c36b3ac50de4..d36dfdf76900befcce8834b7524850d467a749d6 100644 (file)
@@ -16,8 +16,10 @@ import java.util.Map;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.AnnotatedElement;
 import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 
 public class OrAnnotationTypePattern extends AnnotationTypePattern {
 
@@ -33,6 +35,10 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
        public FuzzyBoolean matches(AnnotatedElement annotated) {
                return left.matches(annotated).or(right.matches(annotated));
        }
+
+       public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations ) {
+               return left.matches(annotated,parameterAnnotations).or(right.matches(annotated,parameterAnnotations));
+       }
        
        public void resolve(World world) {
                left.resolve(world);
@@ -54,6 +60,7 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
                AnnotationTypePattern newRight = right.parameterizeWith(typeVariableMap,w);
                OrAnnotationTypePattern ret = new OrAnnotationTypePattern(newLeft,newRight);
                ret.copyLocationFrom(this);
+               if (isForParameterAnnotationMatch()) ret.setForParameterAnnotationMatch();
                return ret;
        }
 
@@ -73,6 +80,9 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
                                AnnotationTypePattern.read(s,context),
                                AnnotationTypePattern.read(s,context));
                p.readLocation(context,s);
+               if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
+                       if (s.readBoolean()) p.setForParameterAnnotationMatch();
+               }
                return p;               
        }
        
@@ -81,18 +91,20 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
                left.write(s);
                right.write(s);
                writeLocation(s);
+               s.writeBoolean(isForParameterAnnotationMatch());
        }
        
        public boolean equals(Object obj) {
                if (!(obj instanceof OrAnnotationTypePattern)) return false;
                OrAnnotationTypePattern other = (OrAnnotationTypePattern) obj;
-               return (left.equals(other.left) && right.equals(other.right));
+               return (left.equals(other.left) && right.equals(other.right)) && isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch();
        }
        
        public int hashCode() {
                int result = 17;
                result = result*37 + left.hashCode();
                result = result*37 + right.hashCode();
+               result = result*37 + (isForParameterAnnotationMatch()?0:1);
                return result;          
        }
        
@@ -103,4 +115,9 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern {
        public AnnotationTypePattern getLeft() { return left; }
        public AnnotationTypePattern getRight() { return right; }
 
+       public void setForParameterAnnotationMatch() {
+               left.setForParameterAnnotationMatch();
+               right.setForParameterAnnotationMatch();
+       }
+
 }
index 74105dcb022370cb50ed65297abdef9c9494dc7e..3fedd718ead39a01fa8c89a7e5884130288e0a66 100644 (file)
@@ -12,7 +12,6 @@
  *******************************************************************************/
 package org.aspectj.weaver.patterns;
 
-import org.aspectj.weaver.Member;
 
 /**
  * A Pointcut or TypePattern visitor
@@ -93,515 +92,4 @@ public interface PatternNodeVisitor {
        // Catch-all
     Object visit(PatternNode node, Object data);
 
-    /**
-     * A sample toString like visitor that helps understanding the AST tree structure organization
-     *
-     * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
-     */
-    static class DumpPointcutVisitor implements PatternNodeVisitor {
-
-        private StringBuffer sb = new StringBuffer();
-        public String get() {
-            return sb.toString();
-        }
-
-        private void append(Object o) {
-            sb.append(o.toString());
-        }
-               
-               private void append(char c) {
-                       sb.append(c);
-               }
-
-        /**
-         * This method helps maintaining the API and raises warning when PatternNode subclasses do not
-         * implement the visitor pattern
-         *
-         * @param node
-         * @param data
-         * @return
-         */
-        public Object visit(PatternNode node, Object data) {
-            System.err.println("Should implement: "  + node.getClass());
-            return null;
-        }
-
-        public Object visit(AnyTypePattern node, Object data) {
-            append('*');
-            return null;
-        }
-
-        public Object visit(NoTypePattern node, Object data) {
-            append(node.toString());//TODO no idea when this one is used
-            return null;
-        }
-
-        public Object visit(EllipsisTypePattern node, Object data) {
-            append(node.toString());
-            return null;
-        }
-
-        public Object visit(AnyWithAnnotationTypePattern node, Object data) {
-            node.annotationPattern.accept(this, data);
-            append(" *");
-            return null;
-        }
-
-        public Object visit(AnyAnnotationTypePattern node, Object data) {
-            //@ANY : ignore
-            append('*');
-            return null;
-        }
-
-        public Object visit(EllipsisAnnotationTypePattern node, Object data) {
-            append("..");
-            return null;
-        }
-
-        public Object visit(AndAnnotationTypePattern node, Object data) {
-            node.getLeft().accept(this, data);
-            append(' ');
-            node.getRight().accept(this, data);
-            return null;
-        }
-
-        public Object visit(AndPointcut node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" && ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(AndTypePattern node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" && ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(AnnotationPatternList node, Object data) {
-            AnnotationTypePattern[] annotations = node.getAnnotationPatterns();
-            for (int i = 0; i < annotations.length; i++) {
-                if (i>0) append(", ");//Note: list is ",", and is " " separated for annotations
-                annotations[i].accept(this, data);
-            }
-            return null;
-        }
-
-        public Object visit(AnnotationPointcut node, Object data) {
-            append("@annotation(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ArgsAnnotationPointcut node, Object data) {
-            append("@args(");
-            node.getArguments().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ArgsPointcut node, Object data) {
-            append("args(");
-            node.getArguments().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(BindingAnnotationTypePattern node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(BindingTypePattern node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(CflowPointcut node, Object data) {
-            append(node.isCflowBelow()?"cflowbelow(":"cflow(");
-            node.getEntry().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ExactAnnotationTypePattern node, Object data) {
-            //append('@'); // since @annotation(@someAnno) cannot be parsed anymore
-            append(node.getAnnotationType().getName());
-            return null;
-        }
-
-        public Object visit(ExactTypePattern node, Object data) {
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append('(');
-                node.getAnnotationPattern().accept(this, data);
-                append(' ');
-            }
-
-            String typeString = node.getType().toString();
-            if (node.isVarArgs()) typeString = typeString.substring(0, typeString.lastIndexOf('['));//TODO AV - ugly
-            append(typeString);
-            if (node.isIncludeSubtypes()) append('+');
-            if (node.isVarArgs()) append("...");
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append(')');
-            }
-            return null;
-        }
-
-        public Object visit(KindedPointcut node, Object data) {
-            append(node.getKind().getSimpleName());
-            append('(');
-            node.getSignature().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ModifiersPattern node, Object data) {
-            append(node.toString());//note: node takes care of forbidden mods
-            return null;
-        }
-
-        public Object visit(NamePattern node, Object data) {
-            append(node.toString());
-            return null;
-        }
-
-        public Object visit(NotAnnotationTypePattern node, Object data) {
-            append("!");
-            node.getNegatedPattern().accept(this, data);
-            return null;
-        }
-
-        public Object visit(NotPointcut node, Object data) {
-            append("!(");
-            node.getNegatedPointcut().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(NotTypePattern node, Object data) {
-            append("!(");
-            node.getNegatedPattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(OrAnnotationTypePattern node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" || ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(OrPointcut node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" || ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(OrTypePattern node, Object data) {
-            append('(');
-            node.getLeft().accept(this, data);
-            append(" || ");
-            node.getRight().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ReferencePointcut node, Object data) {
-            append(node.toString());
-            return null;
-        }
-
-        public Object visit(SignaturePattern node, Object data) {
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                node.getAnnotationPattern().accept(this, data);
-                append(' ');
-            }
-
-            if (node.getModifiers() != ModifiersPattern.ANY) {
-                node.getModifiers().accept(this, data);
-                append(' ');
-            }
-
-            if (node.getKind() == Member.STATIC_INITIALIZATION) {
-                node.getDeclaringType().accept(this, data);
-            } else if (node.getKind() == Member.HANDLER) {
-                append("handler(");
-                node.getParameterTypes().get(0).accept(this, data);//Note: we know we have 1 child
-                append(')');
-            } else {
-                if (!(node.getKind() == Member.CONSTRUCTOR)) {
-                    node.getReturnType().accept(this, data);
-                    append(' ');
-                }
-                if (node.getDeclaringType() != TypePattern.ANY) {
-                    node.getDeclaringType().accept(this, data);
-                    append('.');
-                }
-                if (node.getKind() == Member.CONSTRUCTOR) {
-                    append("new");
-                } else {
-                    node.getName().accept(this, data);
-                }
-                if (node.getKind() == Member.METHOD || node.getKind() == Member.CONSTRUCTOR) {
-                    append('(');
-                    node.getParameterTypes().accept(this, data);
-                    append(')');
-                }
-                if (node.getThrowsPattern() != null) {
-                    append(' ');
-                    node.getThrowsPattern().accept(this, data);
-                }
-            }
-            return null;
-        }
-
-        public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
-            append(node.isThis() ? "@this(" : "@target(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(ThisOrTargetPointcut node, Object data) {
-            append(node.isThis() ? "this(" : "target(");
-            node.getType().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        // Note: a visitor instance is not thread safe so should not be shared
-        private boolean inThrowsForbidden = false;
-
-        public Object visit(ThrowsPattern node, Object data) {
-            if (node == ThrowsPattern.ANY) return null;
-
-            append("throws ");
-            node.getRequired().accept(this, data);
-            if (node.getForbidden().size() > 0) {
-                // a hack since throws !(A, B) cannot be parsed
-                try {
-                    inThrowsForbidden = true;
-                    node.getForbidden().accept(this, data);
-                } finally {
-                    inThrowsForbidden = false;
-                }
-            }
-            return null;
-        }
-
-        public Object visit(TypePatternList node, Object data) {
-            if (node.getTypePatterns().length == 0) return null;
-
-            TypePattern[] typePatterns = node.getTypePatterns();
-            for (int i = 0; i < typePatterns.length; i++) {
-                TypePattern typePattern = typePatterns[i];
-                if (i > 0) append(", ");
-                if (inThrowsForbidden) append('!');
-                typePattern.accept(this, data);
-            }
-            return null;
-        }
-
-        public Object visit(WildAnnotationTypePattern node, Object data) {
-            append("@(");
-            node.getTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WildTypePattern node, Object data) {
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append('(');
-                node.getAnnotationPattern().accept(this, data);
-                append(' ');
-            }
-            NamePattern[] namePatterns = node.getNamePatterns();
-            for (int i=0; i < namePatterns.length; i++) {
-                if (namePatterns[i] == null) {
-                    append('.');//FIXME mh, error prone, can't we have a nullNamePattern ?
-                } else {
-                    if (i > 0) append('.');
-                    namePatterns[i].accept(this, data);
-                }
-            }
-            if (node.isIncludeSubtypes()) append('+');
-            if (node.isVarArgs()) append("...");
-            if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
-                append(')');
-            }
-            return null;
-        }
-
-        public Object visit(WithinAnnotationPointcut node, Object data) {
-            append("@within(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WithinCodeAnnotationPointcut node, Object data) {
-            append("@withincode(");
-            node.getAnnotationTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WithinPointcut node, Object data) {
-            append("within(");
-            node.getTypePattern().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(WithincodePointcut node, Object data) {
-            append("withincode(");
-            node.getSignature().accept(this, data);
-            append(')');
-            return null;
-        }
-
-        public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
-            append("");//TODO shouldn't that be a "false" ?
-            return null;
-        }
-
-
-        //-------------- perX
-
-        public Object visit(PerCflow node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerFromSuper node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerObject node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerSingleton node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(PerTypeWithin node, Object data) {
-            append(node);
-            return null;
-        }
-
-        // ------------- declare X
-
-        public Object visit(DeclareAnnotation node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclareErrorOrWarning node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclareParents node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclarePrecedence node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(DeclareSoft node, Object data) {
-            append(node);
-            return null;
-        }
-
-        // ----------- misc
-
-        public Object visit(ConcreteCflowPointcut node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(HandlerPointcut node, Object data) {
-            append(node);
-            return null;
-        }
-
-        public Object visit(IfPointcut node, Object data) {
-            append(node);
-            return null;
-        }
-               
-               public Object visit(TypeVariablePattern node, Object data) {
-                       append(node);
-                       return null;
-               }
-               
-               public Object visit(TypeVariablePatternList node, Object data) {
-                       append(node);
-                       return null;
-               }
-
-               public Object visit(HasMemberTypePattern node, Object data) {
-                       append(node);
-                       return null;
-               }
-
-        public static void check(String s) {
-            check(Pointcut.fromString(s), false);
-        }
-
-        public static void check(PatternNode pc, boolean isTypePattern) {
-            DumpPointcutVisitor v1 = new DumpPointcutVisitor();
-            pc.accept(v1, null);
-
-            DumpPointcutVisitor v2 = new DumpPointcutVisitor();
-            final PatternNode pc2;
-            if (isTypePattern) {
-                pc2 = new PatternParser(v1.get()).parseTypePattern();
-            } else {
-                pc2 = Pointcut.fromString(v1.get());
-            }
-            pc2.accept(v2, null);
-
-            // at second parsing, the String form stay stable when parsed and parsed again
-            if (! v1.get().equals(v2.get())) {
-                throw new ParserException("Unstable back parsing for '"+pc+"', got '" + v1.get() + "' and '" + v2.get() + "'", null);
-            }
-        }
-
-        public static void main(String args[]) throws Throwable {
-            String[] s = new String[]{
-                //"@args(Foo, Goo, *, .., Moo)",
-                //"execution(* *())",
-                //"call(* *(int, Integer...))",
-                //"staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
-                   "(if(true) && set(int BaseApp.i))"
-
-            };
-            for (int i = 0; i < s.length; i++) {
-                check(s[i]);
-            }
-        }
-
-    }
-
 }
index 29326a572c7aa532d14ce2b97beee85d552b9fb0..fe445f4c5a8ec6e0715c490c1342f3979cd93210 100644 (file)
@@ -17,11 +17,14 @@ package org.aspectj.weaver.patterns;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.MemberKind;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.UnresolvedType;
@@ -42,6 +45,8 @@ public class PatternParser {
        /** extension handlers used in weaver tools API only */
        private Set pointcutDesignatorHandlers = Collections.EMPTY_SET;
        private ReflectionWorld world;
+       
+       private AnnotationTypePattern[] parameterAnnotationTypePatterns;
 
        /**
         * Constructor for PatternParser.
@@ -213,7 +218,7 @@ public class PatternParser {
                 */
                eat(":");
                allowHasTypePatterns = true;
-               TypePattern p = parseTypePattern(false);
+               TypePattern p = parseTypePattern(false,false);
                allowHasTypePatterns = false;
                IToken t = tokenSource.next();
                if (!(t.getString().equals("extends") || t.getString().equals("implements"))) {
@@ -336,7 +341,7 @@ public class PatternParser {
                                        AnnotationTypePattern.ANY));
                } else  if (kind.equals("handler")) {
                        eat("(");
-                       TypePattern typePat = parseTypePattern(false);
+                       TypePattern typePat = parseTypePattern(false,false);
                        eat(")");
                        p = new HandlerPointcut(typePat);
                } else  if (kind.equals("lock") || kind.equals("unlock")) {
@@ -348,7 +353,7 @@ public class PatternParser {
                        p = new KindedPointcut(Shadow.Initialization, sig);
                } else  if (kind.equals("staticinitialization")) {
                        eat("(");
-                       TypePattern typePat = parseTypePattern(false);
+                       TypePattern typePat = parseTypePattern(false,false);
                        eat(")");
                        p = new KindedPointcut(Shadow.StaticInitialization,
                                        new SignaturePattern(Member.STATIC_INITIALIZATION, ModifiersPattern.ANY, 
@@ -522,7 +527,7 @@ public class PatternParser {
         */
        private Pointcut parseArgsPointcut() {
                //parseIdentifier();
-               TypePatternList arguments = parseArgumentsPattern();
+               TypePatternList arguments = parseArgumentsPattern(false);
                return new ArgsPointcut(arguments);
        }
        
@@ -553,7 +558,7 @@ public class PatternParser {
                        throw new ParserException("(",tokenSource.peek(-1));
                }
 
-               TypePatternList arguments = parseArgumentsPattern();
+               TypePatternList arguments = parseArgumentsPattern(false);
                return new ReferencePointcut(onType, simpleName, arguments);
        }
        
@@ -652,41 +657,62 @@ public class PatternParser {
        }
        
        public TypePattern parseTypePattern() {
-               return parseTypePattern(false);
+               return parseTypePattern(false,false);
        }
        
-       public TypePattern parseTypePattern(boolean insideTypeParameters) {
-               TypePattern p = parseAtomicTypePattern(insideTypeParameters); 
+       public TypePattern parseTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) {
+               TypePattern p = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible); 
                if (maybeEat("&&")) {
-                       p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters));
+                       p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters,parameterAnnotationsPossible));
                }  
                
                if (maybeEat("||")) {
-                       p = new OrTypePattern(p, parseTypePattern(insideTypeParameters));
+                       p = new OrTypePattern(p, parseTypePattern(insideTypeParameters,parameterAnnotationsPossible));
                }               
                return p;
        }
        
-       private TypePattern parseNotOrTypePattern(boolean insideTypeParameters) {
-               TypePattern p = parseAtomicTypePattern(insideTypeParameters);
+       private TypePattern parseNotOrTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) {
+               TypePattern p = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible);
                if (maybeEat("&&")) {                   
-                       p = new AndTypePattern(p, parseTypePattern(insideTypeParameters));
+                       p = new AndTypePattern(p, parseTypePattern(insideTypeParameters,parameterAnnotationsPossible));
                } 
                return p;               
        }
        
-       private TypePattern parseAtomicTypePattern(boolean insideTypeParameters) {
-               AnnotationTypePattern ap = maybeParseAnnotationPattern();
+       
+       // Need to differentiate in here between two kinds of annotation pattern - depending on where the ( is
+       
+       private TypePattern parseAtomicTypePattern(boolean insideTypeParameters,boolean parameterAnnotationsPossible) {
+               AnnotationTypePattern ap = maybeParseAnnotationPattern(); // might be parameter annotation pattern or type annotation pattern
                if (maybeEat("!")) {
                        //int startPos = tokenSource.peek(-1).getStart();
                        //??? we lose source location for true start of !type
-                       TypePattern p = new NotTypePattern(parseAtomicTypePattern(insideTypeParameters));
-                       p = setAnnotationPatternForTypePattern(p,ap);
+                       
+                       // An annotation, if processed, is outside of the Not - so here we have to build
+                       // an And pattern containing the annotation and the not as left and right children
+                       // *unless* the annotation pattern was just 'Any' then we can skip building the 
+                       // And and just return the Not directly (pr228980)
+                   TypePattern p = null;
+            TypePattern tp = parseAtomicTypePattern(insideTypeParameters,parameterAnnotationsPossible);
+                   if (!(ap instanceof AnyAnnotationTypePattern)) {
+                       p = new NotTypePattern(tp);
+                       p = new AndTypePattern(setAnnotationPatternForTypePattern(TypePattern.ANY,ap,false),p);
+                   } else {
+                       p = new NotTypePattern(tp);
+                   }
                        return p;                       
                }
                if (maybeEat("(")) {
-                       TypePattern p = parseTypePattern(insideTypeParameters);
-                       p = setAnnotationPatternForTypePattern(p,ap);
+                       TypePattern p = parseTypePattern(insideTypeParameters,false);
+                       if ((p instanceof NotTypePattern) && !(ap instanceof AnyAnnotationTypePattern)) {
+                           // dont set the annotation on it, we don't want the annotation to be 
+                           // considered as part of the not, it is outside the not (pr228980)
+                           TypePattern tp = setAnnotationPatternForTypePattern(TypePattern.ANY, ap, parameterAnnotationsPossible);
+                           p = new AndTypePattern(tp,p);
+                       } else {
+                       p = setAnnotationPatternForTypePattern(p,ap,parameterAnnotationsPossible);
+                       }
                        eat(")");
                        boolean isVarArgs = maybeEat("...");
                        if (isVarArgs) p.setIsVarArgs(isVarArgs);
@@ -697,13 +723,15 @@ public class PatternParser {
                int startPos = tokenSource.peek().getStart();
            TypePattern p = parseSingleTypePattern(insideTypeParameters);
            int endPos = tokenSource.peek(-1).getEnd();
-           p = setAnnotationPatternForTypePattern(p,ap);
+           p = setAnnotationPatternForTypePattern(p,ap,false);
            p.setLocation(sourceContext, startPos, endPos);
            return p;
        }
        
-       private TypePattern setAnnotationPatternForTypePattern(TypePattern t, AnnotationTypePattern ap) {
+
+       private TypePattern setAnnotationPatternForTypePattern(TypePattern t, AnnotationTypePattern ap,boolean parameterAnnotationsPattern) {
                TypePattern ret = t;
+               if (parameterAnnotationsPattern) ap.setForParameterAnnotationMatch();
                if (ap != AnnotationTypePattern.ANY) {
                        if (t == TypePattern.ANY) {
                                ret = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0,false,null);
@@ -730,8 +758,10 @@ public class PatternParser {
                return ret;
        }
 
+       // PVAL cope with annotation values at other places in this code
        public AnnotationTypePattern maybeParseSingleAnnotationPattern() {
                AnnotationTypePattern ret = null;
+               Map values = null;
                // LALR(2) - fix by making "!@" a single token
                int startIndex = tokenSource.getIndex();
                if (maybeEat("!")) {
@@ -743,7 +773,13 @@ public class PatternParser {
                                        return ret;
                                } else {
                                        TypePattern p = parseSingleTypePattern();
-                                       ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));
+                                       if (maybeEatAdjacent("(")) {
+                                               values = parseAnnotationValues();
+                                               eat(")");
+                                               ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p,values));
+                                       } else {
+                                               ret = new NotAnnotationTypePattern(new WildAnnotationTypePattern(p));                                           
+                                       }
                                        return ret;
                                }
                        } else {
@@ -759,7 +795,13 @@ public class PatternParser {
                                return ret;
                        } else {
                                TypePattern p = parseSingleTypePattern();
-                               ret = new WildAnnotationTypePattern(p);
+                               if (maybeEatAdjacent("(")) {
+                                       values = parseAnnotationValues();
+                                       eat(")");
+                                       ret = new WildAnnotationTypePattern(p,values);
+                               } else {
+                                       ret = new WildAnnotationTypePattern(p);
+                               }
                                return ret;
                        }
                } else {
@@ -768,6 +810,35 @@ public class PatternParser {
                }               
        }
        
+       // Parse annotation values.  In an expression in @A(a=b,c=d) this method will be 
+       // parsing the a=b,c=d.)
+       public Map/*String,String*/ parseAnnotationValues() {
+               Map values = new HashMap();
+               boolean seenDefaultValue = false;
+               do {
+                       String possibleKeyString = parseAnnotationNameValuePattern();
+                       if (possibleKeyString==null) {
+                               throw new ParserException("expecting simple literal ",tokenSource.peek(-1));
+                       }
+                       // did they specify just a single entry 'v'  or a keyvalue pair 'k=v'
+                       if (maybeEat("=")) { 
+                               // it was a key!
+                               String valueString = parseAnnotationNameValuePattern();
+                               if (valueString==null) {
+                                       throw new ParserException("expecting simple literal ",tokenSource.peek(-1));
+                               }
+                               values.put(possibleKeyString,valueString);
+                       } else {
+                               if (seenDefaultValue) {
+                                       throw new ParserException("cannot specify two default values",tokenSource.peek(-1));
+                               }
+                               seenDefaultValue = true;
+                               values.put("value",possibleKeyString);
+                       }
+               } while (maybeEat(",")); // keep going whilst there are ','
+               return values;
+       }
+       
        public TypePattern parseSingleTypePattern() {
                return parseSingleTypePattern(false);
        }
@@ -836,11 +907,11 @@ public class PatternParser {
                TypePattern[] additionalInterfaceBounds = new TypePattern[0];
                TypePattern lowerBound = null;
                if (maybeEatIdentifier("extends")) {
-                       upperBound = parseTypePattern(false);
+                       upperBound = parseTypePattern(false,false);
                        additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds();
                }
                if (maybeEatIdentifier("super")) {
-                       lowerBound = parseTypePattern(false);
+                       lowerBound = parseTypePattern(false,false);
                }
                int endPos = tokenSource.peek(-1).getEnd();
                return new WildTypePattern(names,false,0,endPos,false,null,upperBound,additionalInterfaceBounds,lowerBound);
@@ -903,7 +974,7 @@ public class PatternParser {
                        annotationName.append(parseIdentifier());
                }
                UnresolvedType type = UnresolvedType.forName(annotationName.toString());
-               p = new ExactAnnotationTypePattern(type);
+               p = new ExactAnnotationTypePattern(type,null);
                return p;
        }
 
@@ -1018,6 +1089,36 @@ public class PatternParser {
                return names;
        }
        
+       // supported form 'a.b.c.d' or just 'a'
+       public String parseAnnotationNameValuePattern() {
+               StringBuffer buf = new StringBuffer();
+               IToken tok;
+               int startPos = tokenSource.peek().getStart();
+               boolean dotOK = false;
+               int depth = 0;
+               while (true) {
+                       tok = tokenSource.peek();
+                       // keep going until we hit ')' or '=' or ','
+                       if (tok.getString()==")" && depth==0) break;
+                       if (tok.getString()=="=" && depth==0) break;
+                       if (tok.getString()=="," && depth==0) break;
+                       
+                       // keep track of nested brackets
+                       if (tok.getString()=="(") depth++;
+                       if (tok.getString()==")") depth--;
+                       if (tok.getString()=="{") depth++;
+                       if (tok.getString()=="}") depth--;
+
+                       if (tok.getString()=="." && !dotOK) {
+                               throw new ParserException("dot not expected",tok);
+                       }
+                       buf.append(tok.getString());
+                       tokenSource.next();
+                       dotOK=true;
+               }
+               if (buf.length()==0) return null;
+               else                 return buf.toString();
+       }
        
        
        public NamePattern parseNamePattern() {
@@ -1098,19 +1199,21 @@ public class PatternParser {
                }
        }
        
-       public TypePatternList parseArgumentsPattern() {
+       public TypePatternList parseArgumentsPattern(boolean parameterAnnotationsPossible) {
                List patterns = new ArrayList();
                eat("(");
+               
+               // ()
                if (maybeEat(")")) {
                        return new TypePatternList();
                }
                
                do {
-                       if (maybeEat(".")) {
+                       if (maybeEat(".")) { // ..
                                eat(".");
                                patterns.add(TypePattern.ELLIPSIS);
-                       } else {
-                               patterns.add(parseTypePattern());
+                       } else { 
+                               patterns.add(parseTypePattern(false,parameterAnnotationsPossible));
                        }
                } while (maybeEat(","));
                eat(")");
@@ -1162,11 +1265,11 @@ public class PatternParser {
                int startPos = tokenSource.peek().getStart();
                AnnotationTypePattern annotationPattern = maybeParseAnnotationPattern();
                ModifiersPattern modifiers = parseModifiersPattern();
-               TypePattern returnType = parseTypePattern(false);
+               TypePattern returnType = parseTypePattern(false,false);
                
                TypePattern declaringType;
                NamePattern name = null;
-               Member.Kind kind;
+               MemberKind kind;
                // here we can check for 'new'
                if (maybeEatNew(returnType)) {
                        kind = Member.CONSTRUCTOR;
@@ -1180,7 +1283,7 @@ public class PatternParser {
                } else {
                        kind = Member.METHOD;
                        IToken nameToken = tokenSource.peek();
-                       declaringType = parseTypePattern(false);
+                       declaringType = parseTypePattern(false,false);
                        if (maybeEat(".")) {
                                nameToken = tokenSource.peek();
                            name = parseNamePattern();
@@ -1201,8 +1304,8 @@ public class PatternParser {
                }
                }
                
-               TypePatternList parameterTypes = parseArgumentsPattern();
-               
+               TypePatternList parameterTypes = parseArgumentsPattern(true);
+
                ThrowsPattern throwsPattern = parseOptionalThrowsPattern();
                SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, name, parameterTypes, throwsPattern, annotationPattern);
            int endPos = tokenSource.peek(-1).getEnd();
@@ -1304,7 +1407,7 @@ public class PatternParser {
                if (!maybeEat("<")) return null;
                List typePats = new ArrayList();
                do {
-                       TypePattern tp = parseTypePattern(true);
+                       TypePattern tp = parseTypePattern(true,false);
                        typePats.add(tp);
                } while(maybeEat(","));
                eat(">");
@@ -1430,6 +1533,17 @@ public class PatternParser {
                }
        }
        
+       public boolean maybeEatAdjacent(String token) {
+               IToken next = tokenSource.peek();
+               if (next.getString() == token) {
+                       if (isAdjacent(tokenSource.peek(-1),next)) {
+                               tokenSource.next();
+                               return true;
+                       }
+               }               
+               return false;
+       }
+       
        public boolean maybeEat(String token) {
                IToken next = tokenSource.peek();
                if (next.getString() == token) {
index b5ce1cf513150c110cbd6c2661343bf925075080..4b480bd4f04df5437c34751feab41f8052c2751a 100644 (file)
@@ -168,8 +168,6 @@ public class PointcutRewriter {
        
        // A && (B || C) => (A && B) || (A && C)
        // (A || B) && C => (A && C) || (B && C)
-       // is this next one optimal??
-       // (A || B) && (C || D) =>  (¬A && B && Â¬C && D) || (B && C) || (A && Â¬C && D) || (A && Â¬B && C)
        private Pointcut pullUpDisjunctions(Pointcut pc) {
                if (isNot(pc)) {
                        NotPointcut npc = (NotPointcut)pc;
index b31287e77ce24d5e4fe75b516fbee5c917af7c3c..ee184615617d49bb36be3b08a7ecf002080d6016 100644 (file)
@@ -32,9 +32,11 @@ import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AjcMemberMaker;
 import org.aspectj.weaver.AnnotationTargetKind;
+import org.aspectj.weaver.ConcreteTypeMunger;
 import org.aspectj.weaver.Constants;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.JoinPointSignature;
+import org.aspectj.weaver.MemberKind;
 import org.aspectj.weaver.Member;
 import org.aspectj.weaver.NameMangler;
 import org.aspectj.weaver.NewFieldTypeMunger;
@@ -43,11 +45,10 @@ import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
-import org.aspectj.weaver.bcel.BcelTypeMunger;
 
 
 public class SignaturePattern extends PatternNode {
-       private Member.Kind kind;
+       private MemberKind kind;
        private ModifiersPattern modifiers;
        private TypePattern returnType;
     private TypePattern declaringType;
@@ -57,7 +58,7 @@ public class SignaturePattern extends PatternNode {
     private AnnotationTypePattern annotationPattern;
     private transient int hashcode = -1;
        
-       public SignaturePattern(Member.Kind kind, ModifiersPattern modifiers,
+       public SignaturePattern(MemberKind kind, ModifiersPattern modifiers,
                                 TypePattern returnType, TypePattern declaringType,
                                 NamePattern name, TypePatternList parameterTypes,
                                 ThrowsPattern throwsPattern,
@@ -84,7 +85,7 @@ public class SignaturePattern extends PatternNode {
                }
                if (parameterTypes != null) {
                        parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false);
-                       checkForIncorrectTargetKind(parameterTypes,scope,false);
+                       checkForIncorrectTargetKind(parameterTypes,scope,false,true);
                }
                if (throwsPattern != null) {
                        throwsPattern = throwsPattern.resolveBindings(scope, bindings);
@@ -100,11 +101,15 @@ public class SignaturePattern extends PatternNode {
                hashcode =-1;
        return this;
     }
+    private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) {
+       checkForIncorrectTargetKind(patternNode, scope, targetsOtherThanTypeAllowed, false);
+       
+    }
     
     // bug 115252 - adding an xlint warning if the annnotation target type is 
     // wrong. This logic, or similar, may have to be applied elsewhere in the case
     // of pointcuts which don't go through SignaturePattern.resolveBindings(..)
-    private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) {
+    private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
        // return if we're not in java5 mode, if the unmatchedTargetKind Xlint
        // warning has been turned off, or if the patternNode is *
        if (!scope.getWorld().isInJava5Mode()
@@ -125,7 +130,7 @@ public class SignaturePattern extends PatternNode {
                                reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,false);
                        }
                } else {
-                       TypePatternVisitor visitor = new TypePatternVisitor(scope,targetsOtherThanTypeAllowed);
+                       TypePatternVisitor visitor = new TypePatternVisitor(scope,targetsOtherThanTypeAllowed,parameterTargettingAnnotationsAllowed);
                        patternNode.traverse(visitor,null);
                        if (visitor.containedIncorrectTargetKind()) {
                                Set keys = visitor.getIncorrectTargetKinds().keySet();                          
@@ -171,14 +176,17 @@ public class SignaturePattern extends PatternNode {
        private IScope scope;
        private Map incorrectTargetKinds /* PatternNode -> AnnotationTargetKind[] */ = new HashMap();
        private boolean targetsOtherThanTypeAllowed;
+               private boolean parameterTargettingAnnotationsAllowed;
 
        /**
         * @param requiredTarget - the signature pattern Kind
         * @param scope
+        * @param parameterTargettingAnnotationsAllowed 
         */
-       public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed) {
+       public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
                this.scope = scope;
                this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed;
+               this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed;
        }
        
        public Object visit(WildAnnotationTypePattern node, Object data) {
@@ -196,7 +204,9 @@ public class SignaturePattern extends PatternNode {
                                if (targetKinds == null) return data;
                                List incorrectTargets = new ArrayList();
                                for (int i = 0; i < targetKinds.length; i++) {
-                                       if (targetKinds[i].getName().equals(kind.getName())) {
+                                       if (targetKinds[i].getName().equals(kind.getName()) ||
+                                                       (targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())
+                                                       ) {
                                                return data;
                                        }
                                        incorrectTargets.add(targetKinds[i]);
@@ -207,13 +217,20 @@ public class SignaturePattern extends PatternNode {
                        } else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
                                AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
                                if (targetKinds == null) return data;
+                               // exception here is if parameter annotations are allowed
+                               if (parameterTargettingAnnotationsAllowed) {
+                                       for (int i = 0; i < targetKinds.length; i++) {
+                                               AnnotationTargetKind annotationTargetKind = targetKinds[i];
+                                               if (annotationTargetKind.getName().equals("PARAMETER")  && node.isForParameterAnnotationMatch()) return data;
+                                       }
+                               }
                                incorrectTargetKinds.put(node,targetKinds);
                        }
                return data;
        }
        
        public Object visit(ExactTypePattern node, Object data) {
-               ExactAnnotationTypePattern eatp =  new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()));
+               ExactAnnotationTypePattern eatp =  new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()),null);
                eatp.accept(this,data);         
                return data;
        }
@@ -382,9 +399,11 @@ public class SignaturePattern extends PatternNode {
                }
                if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) return FuzzyBoolean.NO;
                ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes());
-               if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC).alwaysTrue()) {
+               ResolvedType[][] parameterAnnotationTypes = aMethod.getParameterAnnotationTypes();
+               if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;
+               if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
                        // It could still be a match based on the generic sig parameter types of a parameterized type
-                       if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) {
+                       if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()),TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
                                return FuzzyBoolean.MAYBE;
                                // It could STILL be a match based on the erasure of the parameter types??
                                // to be determined via test cases...
@@ -398,6 +417,8 @@ public class SignaturePattern extends PatternNode {
                return FuzzyBoolean.YES;
        }
        
+
+
        /**
         * match on declaring type, parameter types, throws types
         */
@@ -406,7 +427,12 @@ public class SignaturePattern extends PatternNode {
 
                if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length)) return FuzzyBoolean.NO;
                ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes());
-               if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC).alwaysTrue()) {
+               
+               ResolvedType[][] parameterAnnotationTypes = aConstructor.getParameterAnnotationTypes();
+
+               if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;
+
+               if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
                        // It could still be a match based on the generic sig parameter types of a parameterized type
                        if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) {
                                return FuzzyBoolean.MAYBE;
@@ -474,7 +500,7 @@ public class SignaturePattern extends PatternNode {
            ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include supers with getInterTypeMungersIncludingSupers?
            List mungers = member.getDeclaringType().resolve(world).getInterTypeMungers(); 
                for (Iterator iter = mungers.iterator(); iter.hasNext();) {
-               BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
+               ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next();
                        if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
                          ResolvedMember fakerm = typeMunger.getSignature();
                          ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm,typeMunger.getAspectType());
@@ -571,7 +597,7 @@ public class SignaturePattern extends PatternNode {
     public NamePattern getName() { return name; }
     public TypePattern getDeclaringType() { return declaringType; }
     
-    public Member.Kind getKind() {
+    public MemberKind getKind() {
        return kind;
     }
     
@@ -657,7 +683,7 @@ public class SignaturePattern extends PatternNode {
        }
 
        public static SignaturePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
-               Member.Kind kind = Member.Kind.read(s);
+               MemberKind kind = MemberKind.read(s);
                ModifiersPattern modifiers = ModifiersPattern.read(s);
                TypePattern returnType = TypePattern.read(s, context);
                TypePattern declaringType = TypePattern.read(s, context);
index 49eb0c314ebbfa86ef58774ec219a3ba7b05a730..ddd8e598e9ee8b5607d684ebbee246e7fd765518 100644 (file)
@@ -158,7 +158,11 @@ public abstract class TypePattern extends PatternNode {
                if (type.isTypeVariableReference()) {
                        typesIterator = ((TypeVariableReference)type).getTypeVariable().getFirstBound().resolve(type.getWorld()).getDirectSupertypes();
                } else {
-                       typesIterator = type.getDirectSupertypes();
+            // pr223605
+            if (type.isRawType()) {
+                type = type.getGenericType();
+            }
+            typesIterator = type.getDirectSupertypes();
                }
                
                // FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh
@@ -467,9 +471,16 @@ class AnyWithAnnotationTypePattern extends TypePattern {
 
        protected boolean matchesExactly(ResolvedType type) {
                annotationPattern.resolve(type.getWorld());
-               return annotationPattern.matches(type).alwaysTrue();
+               boolean b = false;
+               if (type.temporaryAnnotationTypes!=null) {
+                       b = annotationPattern.matches(type,type.temporaryAnnotationTypes).alwaysTrue();
+               } else {
+                       b = annotationPattern.matches(type).alwaysTrue();
+               }
+               return b;
        }
        
+       
        protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
                annotationPattern.resolve(type.getWorld());
                return annotationPattern.matches(annotatedType).alwaysTrue();           
index aec01ed74ae6bca81bc1e82023ff2ab54ff0ee50..d2b51d7d9c12e76607530aca8be48eb6a32e2035 100644 (file)
@@ -87,6 +87,9 @@ public class TypePatternList extends PatternNode {
                return (size() -ellipsisCount) <= numParams;
        }
     }
+    public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind) {
+       return matches(types,kind,null);
+    }
     
     //XXX shares much code with WildTypePattern and with NamePattern
     /**
@@ -99,7 +102,7 @@ public class TypePatternList extends PatternNode {
      * 
      * This method will never return FuzzyBoolean.NEVER
      */ 
-    public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind) {
+    public FuzzyBoolean matches(ResolvedType[] types, TypePattern.MatchKind kind, ResolvedType[][] parameterAnnotations) {
        int nameLength = types.length;
                int patternLength = typePatterns.length;
                
@@ -110,7 +113,16 @@ public class TypePatternList extends PatternNode {
                        if (nameLength != patternLength) return FuzzyBoolean.NO;
                        FuzzyBoolean finalReturn = FuzzyBoolean.YES;
                        while (patternIndex < patternLength) {
-                               FuzzyBoolean ret = typePatterns[patternIndex++].matches(types[nameIndex++], kind);
+                               ResolvedType t = types[nameIndex];
+                               FuzzyBoolean ret = null;
+                               try {
+                                 if (parameterAnnotations!=null) t.temporaryAnnotationTypes = parameterAnnotations[nameIndex];
+                             ret = typePatterns[patternIndex].matches(t,kind);
+                               } finally {
+                                       t.temporaryAnnotationTypes=null;
+                               }
+                               patternIndex++;
+                               nameIndex++;
                                if (ret == FuzzyBoolean.NO) return ret;
                                if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
                        }
@@ -123,7 +135,15 @@ public class TypePatternList extends PatternNode {
                                if (p == TypePattern.ELLIPSIS) {
                                        nameIndex = nameLength - (patternLength-patternIndex);
                                } else {
-                                       FuzzyBoolean ret = p.matches(types[nameIndex++], kind);
+                                       ResolvedType t = types[nameIndex];
+                                       FuzzyBoolean ret = null;
+                                       try {
+                                               if (parameterAnnotations!=null) t.temporaryAnnotationTypes = parameterAnnotations[nameIndex];
+                                           ret = p.matches(t, kind);
+                                       } finally {
+                                               t.temporaryAnnotationTypes=null;
+                                       }
+                                       nameIndex++;
                                    if (ret == FuzzyBoolean.NO) return ret;
                                    if (ret == FuzzyBoolean.MAYBE) finalReturn = ret;
                                }
index 35c18bc3dd5808db847eb081c3838c6c1029aa72..0bbfa1e079f10cddfb9dbc1785d33ce7b67e0089 100644 (file)
@@ -11,7 +11,10 @@ package org.aspectj.weaver.patterns;
 
 import java.io.DataOutputStream;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.MessageUtil;
@@ -19,10 +22,12 @@ import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.AnnotatedElement;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.World;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
 
 /**
  * @author colyer
@@ -34,6 +39,7 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
 
        private TypePattern typePattern;
        private boolean resolved = false;
+       Map annotationValues;
        
        /**
         * 
@@ -43,26 +49,189 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
                this.typePattern = typePattern;
                this.setLocation(typePattern.getSourceContext(), typePattern.start, typePattern.end);
        }
+       
+       public WildAnnotationTypePattern(TypePattern typePattern, Map annotationValues) {
+               super();
+               this.typePattern = typePattern;
+               this.annotationValues = annotationValues;
+               // PVAL make the location be from start of type pattern to end of values
+               this.setLocation(typePattern.getSourceContext(), typePattern.start, typePattern.end);           
+       }
 
     public TypePattern getTypePattern() {
         return typePattern;
     }
-
+    
        /* (non-Javadoc)
         * @see org.aspectj.weaver.patterns.AnnotationTypePattern#matches(org.aspectj.weaver.AnnotatedElement)
         */
        public FuzzyBoolean matches(AnnotatedElement annotated) {
+               return matches(annotated,null);
+       }
+
+       /**
+        * Resolve any annotation values specified, checking they are all well formed (valid names, valid values)
+        * @param annotationType the annotation type for which the values have been specified
+        * @param scope the scope within which to resolve type references (eg. Color.GREEN)
+        */
+       protected void resolveAnnotationValues(ResolvedType annotationType, IScope scope) {
+               if (annotationValues == null) return;
+               // Check any values specified are OK:
+               // - the value names are for valid annotation fields
+               // - the specified values are of the correct type
+               // - for enums, check the specified values can be resolved in the specified scope
+               Set keys = annotationValues.keySet();
+               ResolvedMember[] ms = annotationType.getDeclaredMethods();
+               for (Iterator kIter = keys.iterator(); kIter.hasNext();) {
+                       String k = (String) kIter.next();
+                       String v = (String) annotationValues.get(k);
+                       boolean validKey = false;
+                       for (int i = 0; i < ms.length; i++) {
+                               ResolvedMember resolvedMember = ms[i];
+                               if (resolvedMember.getName().equals(k) && resolvedMember.isAbstract()) {
+                                       validKey = true;
+                                       ResolvedType t = resolvedMember.getReturnType().resolve(scope.getWorld());
+                                       if (t.isEnum()) {
+                                               // value must be an enum reference X.Y
+                                               int pos = v.lastIndexOf(".");
+                                               if (pos == -1) {
+                                                       IMessage m = MessageUtil.error(
+                                                                       WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"enum"),
+                                                                       getSourceLocation());
+                                                       scope.getWorld().getMessageHandler().handleMessage(m);                                                  
+                                               } else {
+                                                       String typename = v.substring(0,pos);
+                                                       ResolvedType rt = scope.lookupType(typename, this).resolve(scope.getWorld());
+                                                       v = rt.getSignature()+v.substring(pos+1); // from 'Color.RED' to 'Lp/Color;RED'
+                                                       annotationValues.put(k,v);
+                                               }
+                                       } else if (t.isPrimitiveType()) {
+                                               if (t.getSignature()=="I") {
+                                                  try {
+                                                          int value = Integer.parseInt(v);
+                                                          annotationValues.put(k,Integer.toString(value));
+                                                  } catch (NumberFormatException nfe) {
+                                                          IMessage m = MessageUtil.error(
+                                                                               WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"int"),
+                                                                               getSourceLocation());
+                                                               scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                  }
+                                               } else if (t.getSignature()=="F") {
+                                                          try {
+                                                                  float value = Float.parseFloat(v);
+                                                                  annotationValues.put(k,Float.toString(value));
+                                                          } catch (NumberFormatException nfe) {
+                                                                  IMessage m = MessageUtil.error(
+                                                                                       WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"float"),
+                                                                                       getSourceLocation());
+                                                                       scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                          }    
+
+                                               } else if (t.getSignature()=="Z") {
+                                                       if (v.equalsIgnoreCase("true") || v.equalsIgnoreCase("false")) {
+                                                               // is it ok !
+                                                       } else {
+                                                                  IMessage m = MessageUtil.error(
+                                                                                       WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"boolean"),
+                                                                                       getSourceLocation());
+                                                                       scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                  }    
+                                               } else if (t.getSignature()=="S") {
+                                                                  try {
+                                                                          short value = Short.parseShort(v);
+                                                                          annotationValues.put(k,Short.toString(value));
+                                                                  } catch (NumberFormatException nfe) {
+                                                                          IMessage m = MessageUtil.error(
+                                                                                               WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"short"),
+                                                                                               getSourceLocation());
+                                                                               scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                                  }
+                                               } else if (t.getSignature()=="J") {
+                                                          try {
+                                                                  long value = Long.parseLong(v);
+                                                                  annotationValues.put(k,Long.toString(value));
+                                                          } catch (NumberFormatException nfe) {
+                                                                  IMessage m = MessageUtil.error(
+                                                                                       WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"long"),
+                                                                                       getSourceLocation());
+                                                                       scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                          }
+                                               } else if (t.getSignature()=="D") {
+                                                          try {
+                                                                  double value = Double.parseDouble(v);
+                                                                  annotationValues.put(k,Double.toString(value));
+                                                          } catch (NumberFormatException nfe) {
+                                                                  IMessage m = MessageUtil.error(
+                                                                                       WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"double"),
+                                                                                       getSourceLocation());
+                                                                       scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                          }
+                                               } else if (t.getSignature()=="B") {
+                                                          try {
+                                                                  byte value = Byte.parseByte(v);
+                                                                  annotationValues.put(k,Byte.toString(value));
+                                                          } catch (NumberFormatException nfe) {
+                                                                  IMessage m = MessageUtil.error(
+                                                                                       WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"byte"),
+                                                                                       getSourceLocation());
+                                                                       scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                          }
+                                               } else if (t.getSignature()=="C") {
+                                                       if (v.length()!=3) {  // '?'
+                                                                 IMessage m = MessageUtil.error(
+                                                                                       WeaverMessages.format(WeaverMessages.INVALID_ANNOTATION_VALUE,v,"char"),
+                                                                                       getSourceLocation());
+                                                                       scope.getWorld().getMessageHandler().handleMessage(m);  
+                                                       } else {
+                                                               annotationValues.put(k,v.substring(1,2));
+                                                       }
+                                               } else {
+                                                       throw new RuntimeException("Not implemented for "+t);
+                                               }
+                                       } else if (t.equals(ResolvedType.JAVA_LANG_STRING)) {
+                                               // nothing to do, it will be OK
+                                       } else {
+                                               throw new RuntimeException("Compiler limitation: annotation value support not implemented for type "+t);
+                                       }
+                               }
+                       }
+                       if (!validKey) {
+                               IMessage m = MessageUtil.error(
+                                               WeaverMessages.format(WeaverMessages.UNKNOWN_ANNOTATION_VALUE,annotationType,k),
+                                               getSourceLocation());
+                               scope.getWorld().getMessageHandler().handleMessage(m);  
+                       }
+               }
+       }
+
+
+
+
+       public FuzzyBoolean matches(AnnotatedElement annotated,ResolvedType[] parameterAnnotations) {
                if (!resolved) {
                        throw new IllegalStateException("Can't match on an unresolved annotation type pattern");
                }
-               // matches if the type of any of the annotations on the AnnotatedElement is
-               // matched by the typePattern.
-               ResolvedType[] annTypes = annotated.getAnnotationTypes();
-
-               if (annTypes!=null && annTypes.length!=0) {
-                       for (int i = 0; i < annTypes.length; i++) {
-                               if (typePattern.matches(annTypes[i],TypePattern.STATIC).alwaysTrue()) {
-                                       return FuzzyBoolean.YES;
+               if (annotationValues!=null) {
+                       // PVAL improve this restriction, would allow '*(value=Color.RED)'
+                       throw new IllegalStateException("Cannot use annotationvalues with a wild annotation pattern");
+               }
+               if (isForParameterAnnotationMatch()) {
+                       if (parameterAnnotations!=null && parameterAnnotations.length!=0) {
+                               for (int i = 0; i < parameterAnnotations.length; i++) {
+                                       if (typePattern.matches(parameterAnnotations[i],TypePattern.STATIC).alwaysTrue()) {
+                                               return FuzzyBoolean.YES;
+                                       }
+                               }
+                       }
+               } else {
+                       // matches if the type of any of the annotations on the AnnotatedElement is
+                       // matched by the typePattern.
+                       ResolvedType[] annTypes = annotated.getAnnotationTypes();
+                       if (annTypes!=null && annTypes.length!=0) {
+                               for (int i = 0; i < annTypes.length; i++) {
+                                       if (typePattern.matches(annTypes[i],TypePattern.STATIC).alwaysTrue()) {
+                                               return FuzzyBoolean.YES;
+                                       }
                                }
                        }
                }
@@ -100,8 +269,11 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
                                scope.getWorld().getMessageHandler().handleMessage(m);
                                resolved = false;
                        }
-               ExactAnnotationTypePattern eatp =  new ExactAnnotationTypePattern(et.getExactType().resolve(scope.getWorld()));
+                       ResolvedType annotationType = et.getExactType().resolve(scope.getWorld());
+               resolveAnnotationValues(annotationType,scope);
+               ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(annotationType,annotationValues);
                eatp.copyLocationFrom(this);
+           if (isForParameterAnnotationMatch()) eatp.setForParameterAnnotationMatch();
                return eatp;
        } else {
                return this;
@@ -124,10 +296,23 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
                s.writeByte(VERSION);
                typePattern.write(s);
                writeLocation(s);
+               s.writeBoolean(isForParameterAnnotationMatch());
+               // PVAL
+               if (annotationValues==null) {
+                       s.writeInt(0);
+               } else {
+                       s.writeInt(annotationValues.size());
+                       Set key = annotationValues.keySet();
+                       for (Iterator keys = key.iterator(); keys.hasNext();) {
+                               String k = (String) keys.next();
+                               s.writeUTF(k);
+                               s.writeUTF((String)annotationValues.get(k));
+                       }
+               }
        }
 
        public static AnnotationTypePattern read(VersionedDataInputStream s,ISourceContext context) throws IOException {
-               AnnotationTypePattern ret;
+               WildAnnotationTypePattern ret;
                byte version = s.readByte();
                if (version > VERSION) {
                        throw new BCException("ExactAnnotationTypePattern was written by a newer version of AspectJ");
@@ -135,6 +320,21 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
                TypePattern t = TypePattern.read(s,context);
                ret = new WildAnnotationTypePattern(t);
                ret.readLocation(context,s);
+               if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MINOR_AJ160) {
+                       if (s.readBoolean()) ret.setForParameterAnnotationMatch();
+               }
+               if (s.getMajorVersion()>=WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ160M2) {
+                       int annotationValueCount = s.readInt();
+                       if (annotationValueCount>0) {
+                               Map aValues = new HashMap();
+                               for (int i=0;i<annotationValueCount;i++) {
+                                       String key = s.readUTF();
+                                       String val = s.readUTF();
+                                       aValues.put(key,val);
+                               }
+                               ret.annotationValues = aValues;
+                       }
+               }
                return ret;             
        }
 
@@ -144,14 +344,14 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
        public boolean equals(Object obj) {
                if (!(obj instanceof WildAnnotationTypePattern)) return false;
                WildAnnotationTypePattern other = (WildAnnotationTypePattern) obj;
-               return other.typePattern.equals(typePattern);
+               return other.typePattern.equals(typePattern) && this.isForParameterAnnotationMatch()==other.isForParameterAnnotationMatch();
        }
        
        /* (non-Javadoc)
         * @see java.lang.Object#hashCode()
         */
        public int hashCode() {
-               return 17 + 37*typePattern.hashCode();
+               return (17 + 37*typePattern.hashCode())*37+(isForParameterAnnotationMatch()?0:1);
        }
        
        /* (non-Javadoc)
index 69a67ba4b2f4eadae6c667a620532cd6d65ab875..bb11d1156ffbc0827a3c95a97ffabaabc2fccb8d 100644 (file)
@@ -236,8 +236,8 @@ public class WildTypePattern extends TypePattern {
                
                return matchesExactlyByName(targetTypeName,type.isAnonymous(),type.isNested()) &&
                        matchesParameters(type,STATIC) &&
-                       matchesBounds(type,STATIC) &&
-                      annotationPattern.matches(annotatedType).alwaysTrue();
+                       matchesBounds(type,STATIC) && 
+                      annotationPattern.matches(annotatedType,type.temporaryAnnotationTypes).alwaysTrue();
        }
        
        
@@ -644,7 +644,7 @@ public class WildTypePattern extends TypePattern {
                  if (dim == 0 && !isVarArgs && upperBound == null && lowerBound == null && (additionalInterfaceBounds == null || additionalInterfaceBounds.length==0)) { // pr72531
                        return TypePattern.ANY;  //??? loses source location
                  } 
-               } else {
+               } else if (!isVarArgs){
                annotationPattern = annotationPattern.resolveBindings(scope,bindings,allowBinding);
                        AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern);                         
                        ret.setLocation(sourceContext,start,end);
diff --git a/weaver/src/org/aspectj/weaver/raw types.txt b/weaver/src/org/aspectj/weaver/raw types.txt
deleted file mode 100644 (file)
index 7cd2dcc..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-
-Current situation with respect to raw types...
-
-* We can create an unresolved type (typeKind = SIMPLE) by 
-   UnresolvedType.forSignature or forName
-   
-* We can create an unresolved type (typeKind = RAW) by calling 
-   UnresolvedType.forRawTypeName
-   
-   This method is called by...
-    
-   BcelWorld.addSourceObjectType when types in jar files or on the classpath are added to
-   the weaver for processing. If the JavaClass is determined to be generic then a raw
-   UnresolvedType is built and a ReferenceType constructed from that. A BcelObjectType is
-   built using the Resolved raw type (and when it's generic signature is unpacked later that will
-   be swapped out for the generic type). Then a generic type is created, the delegates of
-   the generic and raw types are set to point to the BcelObjectType, and the generic type
-   of the raw type is set to point to the generic type. The raw type is explicitly added into
-   the typeMap.
-   
-   EclipseFactory.addSourceTypeBinding when adding a binding for a generic type during 
-   completeTypeBindings. This is put into the world by calling world.lookupOrCreateName. 
-   Then a generic type is created and the raw type's generic type is set to refer to it.
-   
-   EclipseFactory.fromBinding when processing a RawTypeBinding. A later call to resolve
-   is responsible for adding this to the type map.
-   
-* World.resolve processing works as follows:
-
-   in resolveObjectType, if the typeKind of the UnresolvedType is neither parameterized
-   nor generic, then a new ReferenceType is created using the rawTypeSignature of the
-   unresolved type. Then the delegate is created, and if this turns out to be generic then a 
-   generic type is also built and set as the generic type of the reference type (but nothing
-   sets the type of the reference type to raw???).
-   
-   in resolveTheGenericType the rawTypeSignature is looked up in the typeMap.  If it
-   is not found, then a new UnresolvedType is created forSignature, resolved (see above),
-   and put in the type map. The generic type is then created and set as the generic type
-   of the raw type. 
-   
index 07d7e7cacb7d5663679a4ab61f27b60a339f1ffa..bdc3539aff1c778c5ed69f942945b57530362d70 100644 (file)
@@ -14,7 +14,9 @@ package org.aspectj.weaver.reflect;
 import java.lang.reflect.Member;
 import java.util.Set;
 
+import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.World;
 
 /**
@@ -30,8 +32,13 @@ public interface AnnotationFinder {
        Object getAnnotation(ResolvedType annotationType, Object onObject);
        
        Object getAnnotationFromMember(ResolvedType annotationType, Member aMember);
+       public AnnotationX getAnnotationOfType(UnresolvedType ofType,Member onMember);
        
+       public String getAnnotationDefaultValue(Member onMember);
+               
        Object getAnnotationFromClass(ResolvedType annotationType, Class aClass);
        
        Set/*ResolvedType*/ getAnnotations(Member onMember);
+       
+       ResolvedType[][] getParameterAnnotationTypes(Member onMember);
 }
index 9a500a17359c98fb9421e00059fddd0cad924f78..01c16ef8209183b74ba755b81ffa8b23cc91b430 100644 (file)
@@ -215,11 +215,12 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
        public ResolvedMember[] getDeclaredFields() {
                if (fields == null) {
                        Field[] reflectFields = this.myClass.getDeclaredFields();
-                       this.fields = new ResolvedMember[reflectFields.length];
+                       ResolvedMember[] rFields = new ResolvedMember[reflectFields.length];
                        for (int i = 0; i < reflectFields.length; i++) {
-                               this.fields[i] = 
+                               rFields[i] = 
                                        ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectFields[i], world);
                        }
+                       this.fields = rFields;
                }
                return fields;
        }
@@ -230,11 +231,12 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
        public ResolvedType[] getDeclaredInterfaces() {
                if (interfaces == null) {
                        Class[] reflectInterfaces = this.myClass.getInterfaces();
-                       this.interfaces = new ResolvedType[reflectInterfaces.length];
+                       ResolvedType[] rInterfaces = new ResolvedType[reflectInterfaces.length];
                        for (int i = 0; i < reflectInterfaces.length; i++) {
-                               this.interfaces[i] = ReflectionBasedReferenceTypeDelegateFactory
+                               rInterfaces[i] = ReflectionBasedReferenceTypeDelegateFactory
                                        .resolveTypeInWorld(reflectInterfaces[i],world);
                        }
+                       this.interfaces = rInterfaces;
                }
                return interfaces;
        }
@@ -246,15 +248,16 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega
                if (methods == null) {
                        Method[] reflectMethods = this.myClass.getDeclaredMethods();
                        Constructor[] reflectCons = this.myClass.getDeclaredConstructors();
-                       this.methods = new ResolvedMember[reflectMethods.length + reflectCons.length];
+                       ResolvedMember[] rMethods = new ResolvedMember[reflectMethods.length + reflectCons.length];
                        for (int i = 0; i < reflectMethods.length; i++) {
-                               this.methods[i] = 
+                               rMethods[i] = 
                                        ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectMethods[i], world);
                        }
                        for (int i = 0; i < reflectCons.length; i++) {
-                               this.methods[i + reflectMethods.length] = 
+                               rMethods[i + reflectMethods.length] = 
                                        ReflectionBasedReferenceTypeDelegateFactory.createResolvedMember(reflectCons[i], world);
                        }
+                       this.methods = rMethods;
                }
                return methods;
        }
index 86aab45998c97068d61750fb53b0c6e1a0dae843..71b203826458135822f0e604de6cda20c8c3e2f9 100644 (file)
 package org.aspectj.weaver.reflect;
 
 import java.lang.reflect.Member;
+import java.util.Iterator;
 
+import org.aspectj.weaver.AnnotationX;
+import org.aspectj.weaver.MemberKind;
 import org.aspectj.weaver.ResolvedMember;
 import org.aspectj.weaver.ResolvedMemberImpl;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.UnresolvedType;
 
+
 /**
  * Subtype of ResolvedMemberImpl used in reflection world.
  * Knows how to get annotations from a java.lang.reflect.Member
@@ -39,7 +43,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
         * @param name
         * @param parameterTypes
         */
-       public ReflectionBasedResolvedMemberImpl(Kind kind,
+       public ReflectionBasedResolvedMemberImpl(MemberKind kind,
                        UnresolvedType declaringType, int modifiers,
                        UnresolvedType returnType, String name,
                        UnresolvedType[] parameterTypes,
@@ -57,7 +61,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
         * @param parameterTypes
         * @param checkedExceptions
         */
-       public ReflectionBasedResolvedMemberImpl(Kind kind,
+       public ReflectionBasedResolvedMemberImpl(MemberKind kind,
                        UnresolvedType declaringType, int modifiers,
                        UnresolvedType returnType, String name,
                        UnresolvedType[] parameterTypes, UnresolvedType[] checkedExceptions,
@@ -77,7 +81,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
         * @param checkedExceptions
         * @param backingGenericMember
         */
-       public ReflectionBasedResolvedMemberImpl(Kind kind,
+       public ReflectionBasedResolvedMemberImpl(MemberKind kind,
                        UnresolvedType declaringType, int modifiers,
                        UnresolvedType returnType, String name,
                        UnresolvedType[] parameterTypes,
@@ -96,7 +100,7 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
         * @param name
         * @param signature
         */
-       public ReflectionBasedResolvedMemberImpl(Kind kind,
+       public ReflectionBasedResolvedMemberImpl(MemberKind kind,
                        UnresolvedType declaringType, int modifiers, String name,
                        String signature, Member reflectMember) {
                super(kind, declaringType, modifiers, name, signature);
@@ -169,6 +173,30 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
                return super.getAnnotationTypes();
        }
        
+       public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
+               unpackAnnotations();
+               if (annotationFinder==null) return null;
+               for (Iterator iterator = annotationTypes.iterator(); iterator.hasNext();) {
+                       ResolvedType type = (ResolvedType) iterator.next();
+                       if (type.getSignature().equals(ofType.getSignature())) {
+                               return annotationFinder.getAnnotationOfType(ofType, reflectMember);
+                       }
+               }
+               return null;
+       }
+
+       public String getAnnotationDefaultValue() {
+               if (annotationFinder==null) return null;
+               return annotationFinder.getAnnotationDefaultValue(reflectMember);
+       }
+
+       public ResolvedType[][] getParameterAnnotationTypes() {
+       if (parameterAnnotationTypes==null && annotationFinder!=null) {
+               parameterAnnotationTypes = annotationFinder.getParameterAnnotationTypes(reflectMember);
+       }
+       return parameterAnnotationTypes;
+    }
+       
        private void unpackAnnotations() {
                if (annotationTypes == null && annotationFinder != null) {
                        annotationTypes = annotationFinder.getAnnotations(reflectMember);
index 296b1fdc4508e826b799a7a3f68f5fbd8a88f795..8f9f91e98f1139df66ec9b266addb0acb7ae212d 100644 (file)
@@ -11,7 +11,7 @@
 package org.aspectj.weaver.tools;
 
 import org.apache.commons.logging.LogFactory;
-
+//OPTIMIZE move out of main weaver for now?
 public class CommonsTraceFactory extends TraceFactory {
 
        private LogFactory logFactory = LogFactory.getFactory();
index 059688c5b9c1ed31c0a33256ddcc245227d53333..4325c72faaeb9f9db1fddf30f5ae3981bb13f5c4 100644 (file)
@@ -12,7 +12,8 @@
 
 package org.aspectj.weaver.tools;
 
-/** This class implements a boolean that includes a "maybe"
+/** 
+ * This class implements a boolean that includes a "maybe"
  */
 public class FuzzyBoolean {
        
index 60aafe619656ca0b3b531c84496c9e525bbbb8b4..3d22f7aae4ab77647dcead6c590d138d246c244b 100644 (file)
@@ -260,6 +260,7 @@ public class PointcutParser {
      */
     public void registerPointcutDesignatorHandler(PointcutDesignatorHandler designatorHandler) {
        this.pointcutDesignators.add(designatorHandler);
+       if (world != null) world.registerPointcutHandler(designatorHandler);
     }
     
     /**
index d532b8d94280cfabb01817b88b9150c4ce26bdf3..724946455ec5316592126b4e348e42240048b3ca 100644 (file)
@@ -26,6 +26,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.StringTokenizer;
 
@@ -46,12 +47,14 @@ import org.aspectj.util.LangUtil;
 import org.aspectj.weaver.IClassFileProvider;
 import org.aspectj.weaver.IWeaveRequestor;
 import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.BcelObjectType;
 import org.aspectj.weaver.bcel.BcelWeaver;
 import org.aspectj.weaver.bcel.BcelWorld;
 import org.aspectj.weaver.bcel.UnwovenClassFile;
 import org.aspectj.weaver.bcel.Utility;
 
+// OPTIMIZE add guards for all the debug/info/etc
 /**
  * This adaptor allows the AspectJ compiler to be embedded in an existing
  * system to facilitate load-time weaving. It provides an interface for a
@@ -86,6 +89,12 @@ public class WeavingAdaptor implements IMessageContext {
        protected Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */
        protected BcelObjectType delegateForCurrentClass; // lazily initialized, should be used to prevent parsing bytecode multiple times
 
+       private int weavingSpecialTypes = 0;
+       private static final int INITIALIZED       = 0x1;
+       private static final int WEAVE_JAVA_PACKAGE = 0x2;
+       private static final int WEAVE_JAVAX_PACKAGE= 0x4;
+       
+       
        private static Trace trace = TraceFactory.getTraceFactory().getTrace(WeavingAdaptor.class);
 
        protected WeavingAdaptor () {
@@ -128,7 +137,7 @@ public class WeavingAdaptor implements IMessageContext {
                                URL[] urls = ((URLClassLoader)loader).getURLs();
                                list.addAll(0,FileUtil.makeClasspath(urls));
                        }
-                       else {
+                       else {          
                                warn("cannot determine classpath"); 
                        }
                }
@@ -157,7 +166,6 @@ public class WeavingAdaptor implements IMessageContext {
        private void init(List classPath, List aspectPath) {
                abortOnError = true;
                createMessageHandler();
-               
                info("using classpath: " + classPath); 
                info("using aspectpath: " + aspectPath); 
                
@@ -227,7 +235,7 @@ public class WeavingAdaptor implements IMessageContext {
                        weaver.addLibraryJarFile(libFile);
                }
                catch (IOException ex) {
-                       warn("bad library: '" + libFile + "'");
+               warn("bad library: '" + libFile + "'");
                }
        }
 
@@ -235,10 +243,11 @@ public class WeavingAdaptor implements IMessageContext {
         * Weave a class using aspects previously supplied to the adaptor.
         * @param name the name of the class
         * @param bytes the class bytes
+        * @param mustWeave if true then this class *must* get woven (used for concrete aspects generated from XML)
         * @return the woven bytes
      * @exception IOException weave failed
         */
-       public byte[] weaveClass (String name, byte[] bytes) throws IOException {
+       public byte[] weaveClass (String name, byte[] bytes,boolean mustWeave) throws IOException {
                if (trace.isTraceEnabled()) trace.enter("weaveClass",this,new Object[] {name, bytes});
 
                if (!enabled) {
@@ -259,6 +268,11 @@ public class WeavingAdaptor implements IMessageContext {
                                        debug("weaving '" + name + "'");
                                        bytes = getWovenBytes(name, bytes);
                                } else if (shouldWeaveAnnotationStyleAspect(name, bytes)) {
+                                       if (mustWeave) {
+                                               if (bcelWorld.getLint().mustWeaveXmlDefinedAspects.isEnabled()) {
+                                                       bcelWorld.getLint().mustWeaveXmlDefinedAspects.signal(name,null);
+                                               }
+                                       }
                            // an @AspectJ aspect needs to be at least munged by the aspectOf munger
                            debug("weaving '" + name + "'");
                            bytes = getAtAspectJAspectBytes(name, bytes);
@@ -294,10 +308,25 @@ public class WeavingAdaptor implements IMessageContext {
     }
 
        private boolean shouldWeaveName (String name) {
+               if ((weavingSpecialTypes&INITIALIZED)==0) {
+                       weavingSpecialTypes|=INITIALIZED;
+                       // initialize it
+                       Properties p = weaver.getWorld().getExtraConfiguration();
+                       if (p!=null) {
+                               boolean b = p.getProperty(World.xsetWEAVE_JAVA_PACKAGES,"false").equalsIgnoreCase("true");
+                               if (b) {
+                                       weavingSpecialTypes|=WEAVE_JAVA_PACKAGE;
+                               }
+                               b = p.getProperty(World.xsetWEAVE_JAVAX_PACKAGES,"false").equalsIgnoreCase("true");
+                               if (b) {
+                                       weavingSpecialTypes|=WEAVE_JAVAX_PACKAGE;
+                               }
+                       }
+               }
                boolean should =
-                      !((name.startsWith("org.aspectj.")
-                || name.startsWith("java.")
-                || name.startsWith("javax."))
+                      !(name.startsWith("org.aspectj.")
+                || (name.startsWith("java.") && (weavingSpecialTypes&WEAVE_JAVA_PACKAGE)==0)
+                || (name.startsWith("javax.") && (weavingSpecialTypes&WEAVE_JAVAX_PACKAGE)==0)
                 //|| name.startsWith("$Proxy")//JDK proxies//FIXME AV is that 1.3 proxy ? fe. ataspect.$Proxy0 is a java5 proxy...
                 || name.startsWith("sun.reflect."));//JDK reflect
                return should;
@@ -319,25 +348,9 @@ public class WeavingAdaptor implements IMessageContext {
        }
                return (delegateForCurrentClass.isAnnotationStyleAspect());
        }
-
-//     private boolean asmCheckAnnotationStyleAspect(byte[] bytes) {
-//             IsAtAspectAnnotationVisitor detector = new IsAtAspectAnnotationVisitor();
-//
-//             ClassReader cr = new ClassReader(bytes);
-//         try {
-//             cr.accept(detector, true);//, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES);
-//         } catch (Exception spe) {
-//             // if anything goes wrong, e.g., an NPE, then assume it's NOT an @AspectJ aspect...
-//             System.err.println("Unexpected problem parsing bytes to discover @Aspect annotation");
-//             spe.printStackTrace();
-//             return false;
-//         }
-//         
-//         return detector.isAspect();
-//     }
        
     protected void ensureDelegateInitialized(String name,byte[] bytes) {
-       if (delegateForCurrentClass==null)
+       if (delegateForCurrentClass==null) // OPTIMIZE better job here?
          delegateForCurrentClass =  ((BcelWorld)weaver.getWorld()).addSourceObjectType(Utility.makeJavaClass(name, bytes));
        }
 
@@ -396,10 +409,10 @@ public class WeavingAdaptor implements IMessageContext {
                                info("adding aspect library: '" + aspectLibrary + "'");
                                weaver.addLibraryJarFile(aspectLibrary);
                        } catch (IOException ex) {
-                               error("exception adding aspect library: '" + ex + "'");
+                       error("exception adding aspect library: '" + ex + "'");
                        }
                } else {
-                       error("bad aspect library: '" + aspectLibrary + "'");
+               error("bad aspect library: '" + aspectLibrary + "'");
                }
        }
        
@@ -470,7 +483,7 @@ public class WeavingAdaptor implements IMessageContext {
                    os.close();
            }
            catch (IOException ex) {
-               warn("unable to dump class " + name + " in directory " + dirName,ex);
+               warn("unable to dump class " + name + " in directory " + dirName,ex);
            }
        }
 
@@ -649,7 +662,7 @@ public class WeavingAdaptor implements IMessageContext {
        private class WeavingClassFileProvider implements IClassFileProvider {
 
                private UnwovenClassFile unwovenClass;
-               private List unwovenClasses = new ArrayList(); /* List<UnovenClassFile> */
+               private List unwovenClasses = new ArrayList(); /* List<UnwovenClassFile> */
                private UnwovenClassFile wovenClass;
         private boolean isApplyAtAspectJMungersOnly = false;
 
diff --git a/weaver/src/org/aspectj/weaver/tools/package.html b/weaver/src/org/aspectj/weaver/tools/package.html
deleted file mode 100644 (file)
index f8d3044..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<html>
-<body>
-Provides a set of interfaces for third-parties wishing to integrate
-AspectJ weaving capabilities into their environments.
-</body>
-</html>
index af5ab65d2f71bd7beb64da7c5ffcce81154ffa63..77c9b003190e01f0235e0d05f56fc9e645ea7e6d 100644 (file)
@@ -157,6 +157,10 @@ referenceToNonAnnotationType=Type referred to is not an annotation type: {0}
 bindingNonRuntimeRetentionAnnotation=Annotation type {0} does not have runtime retention
 noMatchBecauseSourceRetention=Failing match because annotation ''{0}'' on type ''{1}'' has SOURCE retention.  Matching allowed when RetentionPolicy is CLASS or RUNTIME
 
+# Annotation value
+invalidAnnotationValue=Invalid annotation value ''{0}'', expected {1} value
+unknownAnnotationValue=The annotation ''{0}'' does not define a value named ''{1}''
+
 # Generics
 cantDecpMultipleParameterizations=Cannot declare parent {0} onto type {1} since it already has {2} in its hierarchy
 noParameterizedTypePatternInHandler=a parameterized type pattern may not be used in a handler pointcut expression
index 4a9336abde1d1927724cc8981d00b6ccbece9bd3..e2efebe254ab4cb1e4df288f5d0db7d98f6470f7 100644 (file)
@@ -29,10 +29,10 @@ public class MemberTestCase extends TestCase {
     }
 
     public void testMethodConstruction() {
-        Member s = MemberImpl.methodFromString("void Foo.goo(int)");
+        Member s = TestUtils.methodFromString("void Foo.goo(int)");
         Member t = MemberImpl.method(UnresolvedType.forName("Foo"), 0, "goo", "(I)V");
-        Member u = MemberImpl.methodFromString("void Foo1.goo(int)");
-        Member v = MemberImpl.methodFromString("int Foo.goo(int)");
+        Member u = TestUtils.methodFromString("void Foo1.goo(int)");
+        Member v = TestUtils.methodFromString("int Foo.goo(int)");
 
         TestUtil.assertCommutativeEquals(s, s, true);
         TestUtil.assertCommutativeEquals(t, t, true);
@@ -45,10 +45,10 @@ public class MemberTestCase extends TestCase {
         TestUtil.assertCommutativeEquals(t, v, false);
         TestUtil.assertCommutativeEquals(u, v, false);
 
-        s = MemberImpl.fieldFromString("int Foo.goo");
+        s = TestUtils.fieldFromString("int Foo.goo");
         t = MemberImpl.field("Foo", 0, "goo", "I");
-        u = MemberImpl.fieldFromString("int Foo.goo1");
-        v = MemberImpl.fieldFromString("long Foo.goo");
+        u = TestUtils.fieldFromString("int Foo.goo1");
+        v = TestUtils.fieldFromString("long Foo.goo");
 
         TestUtil.assertCommutativeEquals(s, s, true);
         TestUtil.assertCommutativeEquals(t, t, true);
@@ -64,7 +64,7 @@ public class MemberTestCase extends TestCase {
 
 
     public void testMethodContents() {
-        Member m = MemberImpl.methodFromString("void Foo.goo(int)");
+        Member m = TestUtils.methodFromString("void Foo.goo(int)");
         kindTest(m, Member.METHOD);
         declaringTypeTest(m, "Foo");
         nameTest(m, "goo");
@@ -75,7 +75,7 @@ public class MemberTestCase extends TestCase {
         isConstructorTest(m, false);
         isStaticTest(m, false);
 
-        m = MemberImpl.methodFromString("interface java.lang.Object java.util.Iterator.next()");
+        m = TestUtils.methodFromString("interface java.lang.Object java.util.Iterator.next()");
         kindTest(m, Member.METHOD);
         declaringTypeTest(m, "java.util.Iterator");
         nameTest(m, "next");
@@ -86,7 +86,7 @@ public class MemberTestCase extends TestCase {
         isConstructorTest(m, false);
         isStaticTest(m, false);
 
-        m = MemberImpl.methodFromString("void Foo.<init>(int, java.lang.Object)");
+        m = TestUtils.methodFromString("void Foo.<init>(int, java.lang.Object)");
         kindTest(m, Member.CONSTRUCTOR);
         declaringTypeTest(m, "Foo");
         nameTest(m, "<init>");
@@ -97,7 +97,7 @@ public class MemberTestCase extends TestCase {
         isConstructorTest(m, true);
         isStaticTest(m, false);
 
-        m = MemberImpl.methodFromString("private double Foo.sqrt(double)");
+        m = TestUtils.methodFromString("private double Foo.sqrt(double)");
         kindTest(m, Member.METHOD);
         declaringTypeTest(m, "Foo");
         nameTest(m, "sqrt");
@@ -108,7 +108,7 @@ public class MemberTestCase extends TestCase {
         isConstructorTest(m, false);
         isStaticTest(m, false);
 
-        m = MemberImpl.methodFromString("static int java.lang.Math.max(int, int)");
+        m = TestUtils.methodFromString("static int java.lang.Math.max(int, int)");
         kindTest(m, Member.METHOD);
         declaringTypeTest(m, "java.lang.Math");
         nameTest(m, "max");
@@ -121,7 +121,7 @@ public class MemberTestCase extends TestCase {
     }
 
     public void testFieldContents() {
-        Member m = MemberImpl.fieldFromString("int Foo.goo");
+        Member m = TestUtils.fieldFromString("int Foo.goo");
         kindTest(m, Member.FIELD);
         declaringTypeTest(m, "Foo");
         nameTest(m, "goo");
@@ -132,7 +132,7 @@ public class MemberTestCase extends TestCase {
         isConstructorTest(m, false);
         isStaticTest(m, false);
 
-        m = MemberImpl.fieldFromString("static java.util.Iterator goo.Bar.i");
+        m = TestUtils.fieldFromString("static java.util.Iterator goo.Bar.i");
         kindTest(m, Member.FIELD);
         declaringTypeTest(m, "goo.Bar");
         nameTest(m, "i");
@@ -168,7 +168,7 @@ public class MemberTestCase extends TestCase {
     private void declaringTypeTest(Member m, String declaringName) {
         assertEquals(m + " declared in", UnresolvedType.forName(declaringName), m.getDeclaringType());
     }
-    private void kindTest(Member m, MemberImpl.Kind kind) {
+    private void kindTest(Member m, MemberKind kind) {
         assertEquals(m + " kind", kind, m.getKind());
     }   
    
diff --git a/weaver/testsrc/org/aspectj/weaver/TestUtils.java b/weaver/testsrc/org/aspectj/weaver/TestUtils.java
new file mode 100644 (file)
index 0000000..48bbe5b
--- /dev/null
@@ -0,0 +1,162 @@
+/* *******************************************************************
+ * Copyright (c) 2008 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.weaver.bcel.BcelAdvice;
+import org.aspectj.weaver.patterns.FormalBinding;
+import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.patterns.SimpleScope;
+
+
+public class TestUtils {
+    private static final String[] ZERO_STRINGS = new String[0];
+
+    /**
+     * Build a member from a string representation:
+     * <blockquote><pre>
+     * static? TypeName TypeName.Id
+     * </pre></blockquote>
+     */
+    public static MemberImpl fieldFromString(String str) {
+        str = str.trim();
+        final int len = str.length();
+        int i = 0;
+        int mods = 0;
+        if (str.startsWith("static", i)) {
+            mods = Modifier.STATIC;
+            i += 6;
+            while (Character.isWhitespace(str.charAt(i))) i++;
+        }
+        int start = i;
+        while (! Character.isWhitespace(str.charAt(i))) i++;
+        UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i));
+
+        start = i;
+        i = str.lastIndexOf('.');
+        UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
+        start = ++i;
+        String name = str.substring(start, len).trim();
+        return new MemberImpl(
+            Member.FIELD,
+            declaringTy,
+            mods,
+            retTy,
+            name,
+            UnresolvedType.NONE);
+    }
+
+    /**
+     * Build a member from a string representation:
+     * <blockquote><pre>
+     * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
+     * </pre></blockquote>
+     */
+    
+    public static Member methodFromString(String str) {
+        str = str.trim();
+        // final int len = str.length();
+        int i = 0;
+
+        int mods = 0;
+        if (str.startsWith("static", i)) {
+            mods = Modifier.STATIC;
+            i += 6;
+        } else if (str.startsWith("interface", i)) {
+            mods = Modifier.INTERFACE;
+            i += 9;
+        } else if (str.startsWith("private", i)) {
+            mods = Modifier.PRIVATE;
+            i += 7;
+        }            
+        while (Character.isWhitespace(str.charAt(i))) i++;
+        
+        int start = i;
+        while (! Character.isWhitespace(str.charAt(i))) i++;
+        UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i));
+
+        start = i;
+        i = str.indexOf('(', i);
+        i = str.lastIndexOf('.', i);
+        UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
+        
+        start = ++i;
+        i = str.indexOf('(', i);
+        String name = str.substring(start, i).trim();
+        start = ++i;
+        i = str.indexOf(')', i);
+    
+        String[] paramTypeNames = parseIds(str.substring(start, i).trim());
+
+        return MemberImpl.method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames));
+    }
+
+    private static String[] parseIds(String str) {
+        if (str.length() == 0) return ZERO_STRINGS;
+        List l = new ArrayList();
+        int start = 0;
+        while (true) {
+            int i = str.indexOf(',', start);
+            if (i == -1) {
+                l.add(str.substring(start).trim());
+                break;
+            }
+            l.add(str.substring(start, i).trim());
+            start = i+1;
+        }
+        return (String[]) l.toArray(new String[l.size()]);
+    }
+
+    /**
+     * Moved from BcelWorld to here
+     * 
+     * Parse a string into advice.
+     * 
+     * <blockquote><pre>
+     * Kind ( Id , ... ) : Pointcut -> MethodSignature
+     * </pre></blockquote>
+     */
+    public static Advice shadowMunger(World w,String str, int extraFlag) {
+        str = str.trim();
+        int start = 0;
+        int i = str.indexOf('(');
+        AdviceKind kind = 
+            AdviceKind.stringToKind(str.substring(start, i));
+        start = ++i;
+        i = str.indexOf(')', i);
+        String[] ids = parseIds(str.substring(start, i).trim());
+        //start = ++i;
+        
+        
+        
+        i = str.indexOf(':', i);        
+        start = ++i;        
+        i = str.indexOf("->", i);
+        Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim());
+        Member m = TestUtils.methodFromString(str.substring(i+2, str.length()).trim());
+
+        // now, we resolve
+        UnresolvedType[] types = m.getParameterTypes();
+        FormalBinding[] bindings = new FormalBinding[ids.length];
+        for (int j = 0, len = ids.length; j < len; j++) {
+            bindings[j] = new FormalBinding(types[j], ids[j], j, 0, 0, "fromString");
+        }
+
+        Pointcut p =
+               pointcut.resolve(new SimpleScope(w, bindings));
+
+        return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null);
+    }
+}
index 5505c092ae416b8811d8eabf0fe8e3c163e0a6da..231df0c756b4bf73d650c068b0eede2af80ea56a 100644 (file)
@@ -122,6 +122,29 @@ public class TypeXTestCase extends TestCase {
                }
        }
        
+       public void testTypeFactoryForParameterizedTypes() {
+               if (LangUtil.is15VMOrGreater()) { // no funny types pre 1.5             
+                       UnresolvedType enumOfSimpleType = 
+                               TypeFactory.createTypeFromSignature("Pjava/lang/Enum<Ljava/lang/String;>;"); 
+                       assertEquals(1, enumOfSimpleType.getTypeParameters().length);
+                       
+                       UnresolvedType enumOfNestedType = 
+                               TypeFactory.createTypeFromSignature("Pjava/lang/Enum<Ljavax/jws/soap/SOAPBinding$ParameterStyle;>;"); 
+                       assertEquals(1, enumOfNestedType.getTypeParameters().length);
+
+                       // is this signature right?
+                       UnresolvedType nestedTypeOfParameterized = 
+                               TypeFactory.createTypeFromSignature("PMyInterface<Ljava/lang/String;>$MyOtherType;"); 
+                       assertEquals(0, nestedTypeOfParameterized.getTypeParameters().length);
+                       
+                       // how about this one? is this valid?
+                       UnresolvedType doublyNestedTypeSignatures = 
+                               TypeFactory.createTypeFromSignature("PMyInterface<Ljava/lang/String;Ljava/lang/String;>$MyOtherType<Ljava/lang/Object;>;"); 
+                       assertEquals(1, doublyNestedTypeSignatures.getTypeParameters().length);
+                       
+               }
+       }
+       
        private void checkTX(UnresolvedType tx,boolean shouldBeParameterized,int numberOfTypeParameters) {
                assertTrue("Expected parameterization flag to be "+shouldBeParameterized,tx.isParameterizedType()==shouldBeParameterized);
                if (numberOfTypeParameters==0) {
index 9a822b78ec93dc6f19f6ee80172f60e53d1dce54..8e2a540426ddeb3a8fd5a69be98ec8d1f69d0a8c 100644 (file)
@@ -33,7 +33,7 @@ public class AfterThrowingWeaveTestCase extends WeaveTestCase {
         BcelWorld world = new BcelWorld();
         
         ShadowMunger myMunger = 
-            world.shadowMunger("afterThrowing(): get(* *.out) -> static void Aspect.ajc_afterThrowing_field_get(java.lang.Throwable)",
+            TestUtils.shadowMunger(world,"afterThrowing(): get(* *.out) -> static void Aspect.ajc_afterThrowing_field_get(java.lang.Throwable)",
                         Advice.ExtraArgument);
         ShadowMunger cm = myMunger.concretize(ResolvedType.MISSING, world, null);
 
index 3d6f540d879a2e263aa0fa0609d93d52cd1227b1..c2ab22991613300a31140b65f8b67fc643c5f921 100644 (file)
@@ -19,6 +19,7 @@ import java.util.Arrays;
 import org.aspectj.weaver.Advice;
 import org.aspectj.weaver.AdviceKind;
 import org.aspectj.weaver.MemberImpl;
+import org.aspectj.weaver.TestUtils;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.UnresolvedType;
 
@@ -46,7 +47,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
        BcelAdvice munger = new BcelAdvice(
                AdviceKind.stringToKind("before"),
                makePointcutAll(), 
-               MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
+               TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
                Advice.ThisJoinPointStaticPart, -1, -1, null, null);
        
         weaveTest("HelloWorld", "StaticTjpBeforeHelloWorld", munger);
@@ -57,7 +58,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
        BcelAdvice munger = new BcelAdvice(
                AdviceKind.stringToKind("before"),
                makePointcutAll(), 
-               MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
+               TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"),
                Advice.ThisEnclosingJoinPointStaticPart, -1, -1, null, null);
        
         weaveTest("HelloWorld", "StaticEnclosingTjpBeforeHelloWorld", munger);
@@ -68,7 +69,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
        BcelAdvice munger = new BcelAdvice(
                AdviceKind.stringToKind("before"),
                makePointcutAll(), 
-               MemberImpl.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint)"),
+               TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint)"),
                Advice.ThisJoinPoint, -1, -1, null, null);
        
         weaveTest("HelloWorld", "TjpBeforeHelloWorld", munger);
@@ -78,7 +79,7 @@ public class TjpWeaveTestCase extends WeaveTestCase {
        BcelAdvice munger = new BcelAdvice(
                AdviceKind.stringToKind("around"),
                makePointcutAll(), 
-               MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
+               TestUtils.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
                Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, null);
        
         weaveTest("HelloWorld", "TjpAroundHelloWorld", munger);
@@ -90,14 +91,14 @@ public class TjpWeaveTestCase extends WeaveTestCase {
        BcelAdvice munger1 = new BcelAdvice(
                AdviceKind.stringToKind("around"),
                makePointcutAll(), 
-               MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
+               TestUtils.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
                Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, 
                rtx);
        
        BcelAdvice munger2 = new BcelAdvice(
                AdviceKind.stringToKind("around"),
                makePointcutAll(), 
-               MemberImpl.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
+               TestUtils.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"),
                Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, 
                rtx);
        
index 8bbbdbe0d122ad123be49b96e2c622636468b9b5..05ff1257ecaecc0993cba0e18d63320f67666d0a 100644 (file)
@@ -189,7 +189,7 @@ public abstract class WeaveTestCase extends TestCase {
 
     protected ShadowMunger makeConcreteAdvice(String mungerString, int extraArgFlag, PerClause perClause) {
         Advice myMunger = 
-            world.shadowMunger(mungerString, extraArgFlag);
+               TestUtils.shadowMunger(world,mungerString, extraArgFlag);
             
 //        PerSingleton s = new PerSingleton();
 //        s.concretize(world.resolve("Aspect"));
index 253768b5891dfc10b5335bb2925c90287f7f6e9e..ccfcee9543a88ec34fd3371d40431daa0658f17c 100644 (file)
@@ -38,7 +38,7 @@ public class WorldTestCase extends AbstractWorldTestCase {
         ResolvedType trace = world.resolve(UnresolvedType.forName("Trace"),true);
         assertTrue("Couldnt find type Trace",!trace.isMissing());
         fieldsTest(trace, Member.NONE);
-        /*Member constr = */MemberImpl.methodFromString("void Trace.<init>()"); 
+        /*Member constr = */TestUtils.methodFromString("void Trace.<init>()"); 
         //XXX need attribute fix - 
         //methodsTest(trace, new Member[] { constr });
 
@@ -58,13 +58,13 @@ public class WorldTestCase extends AbstractWorldTestCase {
         
         mungersTest(trace, 
             new ShadowMunger[] {
-                               world.shadowMunger("before(foo): traced(foo) -> void Trace.ajc_before_4(java.lang.Object))",
+                       TestUtils.shadowMunger(world,"before(foo): traced(foo) -> void Trace.ajc_before_4(java.lang.Object))",
                                                0),
-                               world.shadowMunger("afterReturning(foo): traced(foo) -> void Trace.ajc_afterreturning_3(java.lang.Object, java.lang.Object))",
+                                               TestUtils.shadowMunger(world,"afterReturning(foo): traced(foo) -> void Trace.ajc_afterreturning_3(java.lang.Object, java.lang.Object))",
                                                Advice.ExtraArgument),
-                               world.shadowMunger("around(): execution(* doit(..)) -> java.lang.Object Trace.ajc_around_2(org.aspectj.runtime.internal.AroundClosure))",
+                                               TestUtils.shadowMunger(world,"around(): execution(* doit(..)) -> java.lang.Object Trace.ajc_around_2(org.aspectj.runtime.internal.AroundClosure))",
                                                Advice.ExtraArgument),
-                               world.shadowMunger("around(foo): traced(foo) -> java.lang.Object Trace.ajc_around_1(java.lang.Object, org.aspectj.runtime.internal.AroundClosure))",
+                                               TestUtils.shadowMunger(world,"around(foo): traced(foo) -> java.lang.Object Trace.ajc_around_1(java.lang.Object, org.aspectj.runtime.internal.AroundClosure))",
                                                Advice.ExtraArgument),
             });
         
diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/ZipFileWeaver.java b/weaver/testsrc/org/aspectj/weaver/bcel/ZipFileWeaver.java
new file mode 100644 (file)
index 0000000..3be5ae3
--- /dev/null
@@ -0,0 +1,39 @@
+/* *******************************************************************
+ * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * 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://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     PARC     initial implementation 
+ * ******************************************************************/
+
+
+package org.aspectj.weaver.bcel;
+
+import java.io.File;
+import java.io.IOException;
+
+
+//XXX delete very soon
+public class ZipFileWeaver {
+       File inFile;
+       public ZipFileWeaver(File inFile) {
+               super();
+               this.inFile = inFile;
+       }
+
+       public void weave(BcelWeaver weaver, File outFile) throws IOException {
+               int count = 0;
+               long startTime = System.currentTimeMillis();
+               weaver.addJarFile(inFile, new File("."),false);
+               weaver.weave(outFile);
+               long stopTime = System.currentTimeMillis();
+               
+               
+               System.out.println("handled " + count + " entries, in " + 
+                               (stopTime-startTime)/1000. + " seconds");
+       }
+}
index 1ff60c342d22d5ffbeb72265827045217f1380de..3bf23d698cd2bdbc470bbfbd73fd148cec8db147 100644 (file)
@@ -12,6 +12,7 @@ package org.aspectj.weaver.patterns;
 import org.aspectj.bridge.AbortException;
 import org.aspectj.util.LangUtil;
 import org.aspectj.weaver.AnnotatedElement;
+import org.aspectj.weaver.AnnotationX;
 import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.BcweaverTests;
 import org.aspectj.weaver.UnresolvedType;
@@ -86,7 +87,7 @@ public class AnnotationPatternTestCase extends TestCase {
                AndAnnotationTypePattern atp = (AndAnnotationTypePattern) ap;
                NotAnnotationTypePattern notBoo = (NotAnnotationTypePattern) atp.getRight();
                ExactAnnotationTypePattern boo = (ExactAnnotationTypePattern) notBoo.getNegatedPattern();
-               WildAnnotationTypePattern fooOrGoo = (WildAnnotationTypePattern) atp.getLeft();
+               AnnotationTypePattern fooOrGoo = (AnnotationTypePattern) atp.getLeft();
                assertEquals("@((Foo || Goo)) !@Boo",ap.toString());
        }
        
@@ -354,6 +355,11 @@ public class AnnotationPatternTestCase extends TestCase {
                        // TODO Auto-generated method stub
                        return null;
                }
+
+               public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
+                       // TODO Auto-generated method stub
+                       return null;
+               }
                
        }
 }
diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java b/weaver/testsrc/org/aspectj/weaver/patterns/DumpPointcutVisitor.java
new file mode 100644 (file)
index 0000000..3c47c20
--- /dev/null
@@ -0,0 +1,525 @@
+/* *******************************************************************
+ * Copyright (c) 2007-2008 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://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Alexandre Vasseur    
+ * ******************************************************************/
+package org.aspectj.weaver.patterns;
+
+import org.aspectj.weaver.Member;
+
+/**
+ * A sample toString like visitor that helps understanding the AST tree structure organization
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class DumpPointcutVisitor implements PatternNodeVisitor {
+
+    private StringBuffer sb = new StringBuffer();
+    public String get() {
+        return sb.toString();
+    }
+
+    private void append(Object o) {
+        sb.append(o.toString());
+    }
+       
+       private void append(char c) {
+               sb.append(c);
+       }
+
+    /**
+     * This method helps maintaining the API and raises warning when PatternNode subclasses do not
+     * implement the visitor pattern
+     *
+     * @param node
+     * @param data
+     * @return
+     */
+    public Object visit(PatternNode node, Object data) {
+        System.err.println("Should implement: "  + node.getClass());
+        return null;
+    }
+
+    public Object visit(AnyTypePattern node, Object data) {
+        append('*');
+        return null;
+    }
+
+    public Object visit(NoTypePattern node, Object data) {
+        append(node.toString());//TODO no idea when this one is used
+        return null;
+    }
+
+    public Object visit(EllipsisTypePattern node, Object data) {
+        append(node.toString());
+        return null;
+    }
+
+    public Object visit(AnyWithAnnotationTypePattern node, Object data) {
+        node.annotationPattern.accept(this, data);
+        append(" *");
+        return null;
+    }
+
+    public Object visit(AnyAnnotationTypePattern node, Object data) {
+        //@ANY : ignore
+        append('*');
+        return null;
+    }
+
+    public Object visit(EllipsisAnnotationTypePattern node, Object data) {
+        append("..");
+        return null;
+    }
+
+    public Object visit(AndAnnotationTypePattern node, Object data) {
+        node.getLeft().accept(this, data);
+        append(' ');
+        node.getRight().accept(this, data);
+        return null;
+    }
+
+    public Object visit(AndPointcut node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" && ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(AndTypePattern node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" && ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(AnnotationPatternList node, Object data) {
+        AnnotationTypePattern[] annotations = node.getAnnotationPatterns();
+        for (int i = 0; i < annotations.length; i++) {
+            if (i>0) append(", ");//Note: list is ",", and is " " separated for annotations
+            annotations[i].accept(this, data);
+        }
+        return null;
+    }
+
+    public Object visit(AnnotationPointcut node, Object data) {
+        append("@annotation(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ArgsAnnotationPointcut node, Object data) {
+        append("@args(");
+        node.getArguments().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ArgsPointcut node, Object data) {
+        append("args(");
+        node.getArguments().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(BindingAnnotationTypePattern node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(BindingTypePattern node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(CflowPointcut node, Object data) {
+        append(node.isCflowBelow()?"cflowbelow(":"cflow(");
+        node.getEntry().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ExactAnnotationTypePattern node, Object data) {
+        //append('@'); // since @annotation(@someAnno) cannot be parsed anymore
+        append(node.getAnnotationType().getName());
+        return null;
+    }
+
+    public Object visit(ExactTypePattern node, Object data) {
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append('(');
+            node.getAnnotationPattern().accept(this, data);
+            append(' ');
+        }
+
+        String typeString = node.getType().toString();
+        if (node.isVarArgs()) typeString = typeString.substring(0, typeString.lastIndexOf('['));//TODO AV - ugly
+        append(typeString);
+        if (node.isIncludeSubtypes()) append('+');
+        if (node.isVarArgs()) append("...");
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append(')');
+        }
+        return null;
+    }
+
+    public Object visit(KindedPointcut node, Object data) {
+        append(node.getKind().getSimpleName());
+        append('(');
+        node.getSignature().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ModifiersPattern node, Object data) {
+        append(node.toString());//note: node takes care of forbidden mods
+        return null;
+    }
+
+    public Object visit(NamePattern node, Object data) {
+        append(node.toString());
+        return null;
+    }
+
+    public Object visit(NotAnnotationTypePattern node, Object data) {
+        append("!");
+        node.getNegatedPattern().accept(this, data);
+        return null;
+    }
+
+    public Object visit(NotPointcut node, Object data) {
+        append("!(");
+        node.getNegatedPointcut().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(NotTypePattern node, Object data) {
+        append("!(");
+        node.getNegatedPattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(OrAnnotationTypePattern node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" || ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(OrPointcut node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" || ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(OrTypePattern node, Object data) {
+        append('(');
+        node.getLeft().accept(this, data);
+        append(" || ");
+        node.getRight().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ReferencePointcut node, Object data) {
+        append(node.toString());
+        return null;
+    }
+
+    public Object visit(SignaturePattern node, Object data) {
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            node.getAnnotationPattern().accept(this, data);
+            append(' ');
+        }
+
+        if (node.getModifiers() != ModifiersPattern.ANY) {
+            node.getModifiers().accept(this, data);
+            append(' ');
+        }
+
+        if (node.getKind() == Member.STATIC_INITIALIZATION) {
+            node.getDeclaringType().accept(this, data);
+        } else if (node.getKind() == Member.HANDLER) {
+            append("handler(");
+            node.getParameterTypes().get(0).accept(this, data);//Note: we know we have 1 child
+            append(')');
+        } else {
+            if (!(node.getKind() == Member.CONSTRUCTOR)) {
+                node.getReturnType().accept(this, data);
+                append(' ');
+            }
+            if (node.getDeclaringType() != TypePattern.ANY) {
+                node.getDeclaringType().accept(this, data);
+                append('.');
+            }
+            if (node.getKind() == Member.CONSTRUCTOR) {
+                append("new");
+            } else {
+                node.getName().accept(this, data);
+            }
+            if (node.getKind() == Member.METHOD || node.getKind() == Member.CONSTRUCTOR) {
+                append('(');
+                node.getParameterTypes().accept(this, data);
+                append(')');
+            }
+            if (node.getThrowsPattern() != null) {
+                append(' ');
+                node.getThrowsPattern().accept(this, data);
+            }
+        }
+        return null;
+    }
+
+    public Object visit(ThisOrTargetAnnotationPointcut node, Object data) {
+        append(node.isThis() ? "@this(" : "@target(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(ThisOrTargetPointcut node, Object data) {
+        append(node.isThis() ? "this(" : "target(");
+        node.getType().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    // Note: a visitor instance is not thread safe so should not be shared
+    private boolean inThrowsForbidden = false;
+
+    public Object visit(ThrowsPattern node, Object data) {
+        if (node == ThrowsPattern.ANY) return null;
+
+        append("throws ");
+        node.getRequired().accept(this, data);
+        if (node.getForbidden().size() > 0) {
+            // a hack since throws !(A, B) cannot be parsed
+            try {
+                inThrowsForbidden = true;
+                node.getForbidden().accept(this, data);
+            } finally {
+                inThrowsForbidden = false;
+            }
+        }
+        return null;
+    }
+
+    public Object visit(TypePatternList node, Object data) {
+        if (node.getTypePatterns().length == 0) return null;
+
+        TypePattern[] typePatterns = node.getTypePatterns();
+        for (int i = 0; i < typePatterns.length; i++) {
+            TypePattern typePattern = typePatterns[i];
+            if (i > 0) append(", ");
+            if (inThrowsForbidden) append('!');
+            typePattern.accept(this, data);
+        }
+        return null;
+    }
+
+    public Object visit(WildAnnotationTypePattern node, Object data) {
+        append("@(");
+        node.getTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WildTypePattern node, Object data) {
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append('(');
+            node.getAnnotationPattern().accept(this, data);
+            append(' ');
+        }
+        NamePattern[] namePatterns = node.getNamePatterns();
+        for (int i=0; i < namePatterns.length; i++) {
+            if (namePatterns[i] == null) {
+                append('.');//FIXME mh, error prone, can't we have a nullNamePattern ?
+            } else {
+                if (i > 0) append('.');
+                namePatterns[i].accept(this, data);
+            }
+        }
+        if (node.isIncludeSubtypes()) append('+');
+        if (node.isVarArgs()) append("...");
+        if (node.getAnnotationPattern() != AnnotationTypePattern.ANY) {
+            append(')');
+        }
+        return null;
+    }
+
+    public Object visit(WithinAnnotationPointcut node, Object data) {
+        append("@within(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WithinCodeAnnotationPointcut node, Object data) {
+        append("@withincode(");
+        node.getAnnotationTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WithinPointcut node, Object data) {
+        append("within(");
+        node.getTypePattern().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(WithincodePointcut node, Object data) {
+        append("withincode(");
+        node.getSignature().accept(this, data);
+        append(')');
+        return null;
+    }
+
+    public Object visit(Pointcut.MatchesNothingPointcut node, Object data) {
+        append("");//TODO shouldn't that be a "false" ?
+        return null;
+    }
+
+
+    //-------------- perX
+
+    public Object visit(PerCflow node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerFromSuper node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerObject node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerSingleton node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(PerTypeWithin node, Object data) {
+        append(node);
+        return null;
+    }
+
+    // ------------- declare X
+
+    public Object visit(DeclareAnnotation node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclareErrorOrWarning node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclareParents node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclarePrecedence node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(DeclareSoft node, Object data) {
+        append(node);
+        return null;
+    }
+
+    // ----------- misc
+
+    public Object visit(ConcreteCflowPointcut node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(HandlerPointcut node, Object data) {
+        append(node);
+        return null;
+    }
+
+    public Object visit(IfPointcut node, Object data) {
+        append(node);
+        return null;
+    }
+       
+       public Object visit(TypeVariablePattern node, Object data) {
+               append(node);
+               return null;
+       }
+       
+       public Object visit(TypeVariablePatternList node, Object data) {
+               append(node);
+               return null;
+       }
+
+       public Object visit(HasMemberTypePattern node, Object data) {
+               append(node);
+               return null;
+       }
+
+    public static void check(String s) {
+        check(Pointcut.fromString(s), false);
+    }
+
+    public static void check(PatternNode pc, boolean isTypePattern) {
+        DumpPointcutVisitor v1 = new DumpPointcutVisitor();
+        pc.accept(v1, null);
+
+        DumpPointcutVisitor v2 = new DumpPointcutVisitor();
+        final PatternNode pc2;
+        if (isTypePattern) {
+            pc2 = new PatternParser(v1.get()).parseTypePattern();
+        } else {
+            pc2 = Pointcut.fromString(v1.get());
+        }
+        pc2.accept(v2, null);
+
+        // at second parsing, the String form stay stable when parsed and parsed again
+        if (! v1.get().equals(v2.get())) {
+            throw new ParserException("Unstable back parsing for '"+pc+"', got '" + v1.get() + "' and '" + v2.get() + "'", null);
+        }
+    }
+
+    public static void main(String args[]) throws Throwable {
+        String[] s = new String[]{
+            //"@args(Foo, Goo, *, .., Moo)",
+            //"execution(* *())",
+            //"call(* *(int, Integer...))",
+            //"staticinitialization(@(Foo) @(Boo) @(Goo) Moo)",
+               "(if(true) && set(int BaseApp.i))"
+
+        };
+        for (int i = 0; i < s.length; i++) {
+            check(s[i]);
+        }
+    }
+
+}
\ No newline at end of file
index 08584fd00078e4f388549c874337b4d251a0c027..4f3e63a17195c04d50111280e61661c855c29f10 100644 (file)
 
 package org.aspectj.weaver.patterns;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import junit.framework.TestCase;
 
 import org.aspectj.weaver.BcweaverTests;
@@ -301,20 +308,20 @@ public class ParserTestCase extends TestCase {
        
        public void testParseAnythingTypeVariable() {
                PatternParser parser = new PatternParser("?");
-               WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true);
+               WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false);
                assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName());
        }
 
        public void testParseAnythingExtendsTypeVariable() {
                PatternParser parser = new PatternParser("? extends Number");
-               WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true);
+               WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false);
                assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName());
                assertEquals("upper Bound of Number",new PatternParser("Number").parseTypePattern(),tp.getUpperBound());
        }
        
        public void testParseAnythingSuperTypeVariable() {
                PatternParser parser = new PatternParser("? super Number+");
-               WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true);
+               WildTypePattern tp = (WildTypePattern) parser.parseTypePattern(true,false);
                assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName());
                assertEquals("lower Bound of Number+",new PatternParser("Number+").parseTypePattern(),tp.getLowerBound());
        }
@@ -335,7 +342,7 @@ public class ParserTestCase extends TestCase {
        public void testParameterizedTypePatternsAny() {
                try {
                        PatternParser parser = new PatternParser("*<T,S extends Number>");
-                       WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(false);
+                       WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(false,false);
        //              TypePatternList tvs = wtp.getTypeParameters();
        //              assertEquals("2 type parameters",2,tvs.getTypePatterns().length);
        //              assertEquals("T",new PatternParser("T").parseTypePattern(),tvs.getTypePatterns()[0]);
@@ -609,7 +616,7 @@ public class ParserTestCase extends TestCase {
        public void testTypeParamList() {
                PatternParser parser = new PatternParser("Bar<T,S extends T, R extends S>");
                try {
-                       TypePattern tp = parser.parseTypePattern(false);
+                       TypePattern tp = parser.parseTypePattern(false,false);
 //                     TypePattern[] tps = tp.getTypeParameters().getTypePatterns();
 //                     assertEquals("3 type patterns",3,tps.length);
 //                     assertEquals("T",tps[0].toString());
@@ -674,6 +681,99 @@ public class ParserTestCase extends TestCase {
                        assertEquals("(",pEx.getMessage());
                }               
        }
+       
+       public void testIntAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(ival=5) * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","ival=5",getValueString(pc));
+       }
+       
+       private String getValueString(Pointcut pc) {
+               if (!(pc instanceof KindedPointcut)) fail("Expected KindedPointcut but was "+pc.getClass());
+               KindedPointcut kpc = (KindedPointcut)pc;
+               AnnotationTypePattern atp = kpc.getSignature().getAnnotationPattern();
+               if (!(atp instanceof WildAnnotationTypePattern)) fail("Expected WildAnnotationTypePattern but was "+atp.getClass());
+               WildAnnotationTypePattern watp = (WildAnnotationTypePattern)atp;
+               Map m = watp.annotationValues;
+               Set keys = m.keySet();
+               List orderedKeys = new ArrayList();
+               orderedKeys.addAll(keys);
+               Collections.sort(orderedKeys);
+               StringBuffer sb = new StringBuffer();
+               for (Iterator iterator = orderedKeys.iterator(); iterator.hasNext();) {
+                       String object = (String) iterator.next();
+                       sb.append(object).append("=").append(m.get(object));
+                       if (iterator.hasNext()) sb.append(",");
+               }
+               return sb.toString();
+       }
+
+       public void testByteAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(bval=5) * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","bval=5",getValueString(pc));
+       }
+
+       public void testCharAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(cval='5') * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","cval='5'",getValueString(pc));
+       }
+       
+       public void testLongAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(jval=123123) * *(..))");
+               Pointcut pc = parser.parsePointcut();           
+               assertEquals("Expected annotation value not found","jval=123123",getValueString(pc));
+       }
+
+       public void testDoubleAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(dval=123.3) * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","dval=123.3",getValueString(pc));
+       }
+
+       public void testBooleanAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(zval=true) * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","zval=true",getValueString(pc));
+       }
+
+       public void testShortAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(sval=43) * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","sval=43",getValueString(pc));
+       }
+       
+       public void testEnumAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(enumval=Color.GREEN) * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","enumval=Color.GREEN",getValueString(pc));
+       }
+
+       public void testStringAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(strval=\"abc\") * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               // notice quotes stripped...
+               assertEquals("Expected annotation value not found","strval=abc",getValueString(pc));
+       }
+
+       public void testClassAnnotationVal() {
+               PatternParser parser = new PatternParser("execution(@ComplexAnnotation(classval=String.class) * *(..))");
+               Pointcut pc = parser.parsePointcut();
+               assertEquals("Expected annotation value not found","classval=String.class",getValueString(pc));
+       }
+
+       // failing as {1 is treated as a single token and so we don't realise the , is within the curlies
+//     public void testArrayAnnotationVal() {
+//             PatternParser parser = new PatternParser("execution(@ComplexAnnotation(arrayval={1,2,3}) * *(..))");
+//             Pointcut pc = parser.parsePointcut();
+//             assertEquals("Expected annotation value not found","arrayval={1,2,3}",getValueString(pc));
+//     }
+
+       
+       
+       
+       // ---
 
        
        public TestScope makeSimpleScope() {
index 336d86f6248a8f294ce808113ed6c60d8310e13a..b355cdc2cf1e1d28d2f9382521c0fcc6bd2ba644 100644 (file)
@@ -33,9 +33,9 @@ public class SignaturePatternTestCase extends TestCase {
        BcelWorld world = new BcelWorld();
 
        public void testThrowsMatch() throws IOException {
-               Member onlyDerivedOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.onlyDerived()");
-               Member mOnBase = MemberImpl.methodFromString("void fluffy.Base.m()");
-               Member mOnDerived = MemberImpl.methodFromString("void fluffy.Derived.m()");
+               Member onlyDerivedOnDerived = TestUtils.methodFromString("static void fluffy.Derived.onlyDerived()");
+               Member mOnBase = TestUtils.methodFromString("void fluffy.Base.m()");
+               Member mOnDerived = TestUtils.methodFromString("void fluffy.Derived.m()");
                
                checkMatch(makeMethodPat("* fluffy.Base.*(..) throws java.lang.CloneNotSupportedException"),
                                        new Member[] { mOnBase },
@@ -66,9 +66,9 @@ public class SignaturePatternTestCase extends TestCase {
        }
 
        public void testInstanceMethodMatch() throws IOException {
-               Member objectToString = MemberImpl.methodFromString("java.lang.String java.lang.Object.toString()");
-               Member integerToString = MemberImpl.methodFromString("java.lang.String java.lang.Integer.toString()");
-               Member integerIntValue = MemberImpl.methodFromString("int java.lang.Integer.intValue()");
+               Member objectToString = TestUtils.methodFromString("java.lang.String java.lang.Object.toString()");
+               Member integerToString = TestUtils.methodFromString("java.lang.String java.lang.Integer.toString()");
+               Member integerIntValue = TestUtils.methodFromString("int java.lang.Integer.intValue()");
                //Member objectToString = Member.methodFromString("java.lang.String java.lang.Object.toString()");
                
                checkMatch(makeMethodPat("* java.lang.Object.*(..)"),
@@ -82,11 +82,11 @@ public class SignaturePatternTestCase extends TestCase {
 
        
        public void testStaticMethodMatch() throws IOException {
-               Member onlyBaseOnBase = MemberImpl.methodFromString("static void fluffy.Base.onlyBase()");
-               Member onlyBaseOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.onlyBase()");
-               Member onlyDerivedOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.onlyDerived()");
-               Member bothOnBase = MemberImpl.methodFromString("static void fluffy.Base.both()");
-               Member bothOnDerived = MemberImpl.methodFromString("static void fluffy.Derived.both()");
+               Member onlyBaseOnBase = TestUtils.methodFromString("static void fluffy.Base.onlyBase()");
+               Member onlyBaseOnDerived = TestUtils.methodFromString("static void fluffy.Derived.onlyBase()");
+               Member onlyDerivedOnDerived = TestUtils.methodFromString("static void fluffy.Derived.onlyDerived()");
+               Member bothOnBase = TestUtils.methodFromString("static void fluffy.Base.both()");
+               Member bothOnDerived = TestUtils.methodFromString("static void fluffy.Derived.both()");
                
                checkMatch(makeMethodPat("* fluffy.Base.*(..)"),
                                        new Member[] { onlyBaseOnBase, onlyBaseOnDerived, bothOnBase },
@@ -98,11 +98,11 @@ public class SignaturePatternTestCase extends TestCase {
        }
        
        public void testFieldMatch() throws IOException {
-               Member onlyBaseOnBase = MemberImpl.fieldFromString("int fluffy.Base.onlyBase");
-               Member onlyBaseOnDerived = MemberImpl.fieldFromString("int fluffy.Derived.onlyBase");
-               Member onlyDerivedOnDerived = MemberImpl.fieldFromString("int fluffy.Derived.onlyDerived");
-               Member bothOnBase = MemberImpl.fieldFromString("int fluffy.Base.both");
-               Member bothOnDerived = MemberImpl.fieldFromString("int fluffy.Derived.both");
+               Member onlyBaseOnBase = TestUtils.fieldFromString("int fluffy.Base.onlyBase");
+               Member onlyBaseOnDerived = TestUtils.fieldFromString("int fluffy.Derived.onlyBase");
+               Member onlyDerivedOnDerived = TestUtils.fieldFromString("int fluffy.Derived.onlyDerived");
+               Member bothOnBase = TestUtils.fieldFromString("int fluffy.Base.both");
+               Member bothOnDerived = TestUtils.fieldFromString("int fluffy.Derived.both");
                
                checkMatch(makeFieldPat("* fluffy.Base.*"),
                                        new Member[] { onlyBaseOnBase, onlyBaseOnDerived, bothOnBase },
@@ -114,9 +114,9 @@ public class SignaturePatternTestCase extends TestCase {
        }
        
        public void testConstructorMatch() throws IOException {
-               Member onBase = MemberImpl.methodFromString("void fluffy.Base.<init>()");
-               Member onDerived = MemberImpl.methodFromString("void fluffy.Derived.<init>()");
-               Member onBaseWithInt = MemberImpl.methodFromString("void fluffy.Base.<init>(int)");
+               Member onBase = TestUtils.methodFromString("void fluffy.Base.<init>()");
+               Member onDerived = TestUtils.methodFromString("void fluffy.Derived.<init>()");
+               Member onBaseWithInt = TestUtils.methodFromString("void fluffy.Base.<init>(int)");
 
                
                checkMatch(makeMethodPat("fluffy.Base.new(..)"),
index 4b1f2c7376e91aee630b1e583594cbd0348c24d1..5f8021169dfb9793fcfbc77faaede13bc87ed235 100644 (file)
@@ -99,7 +99,7 @@ public class TypePatternListTestCase extends TestCase {
        }
 
        private TypePatternList makeArgumentsPattern(String pattern) {
-               return new PatternParser(pattern).parseArgumentsPattern();
+               return new PatternParser(pattern).parseArgumentsPattern(false);
        }
 
        private void checkStaticMatch(String pattern, String[] names, 
@@ -121,7 +121,7 @@ public class TypePatternListTestCase extends TestCase {
        }
        
        private TestScope makeTestScope() {
-               TestScope scope = new TestScope(CollectionUtil.NO_STRINGS, CollectionUtil.NO_STRINGS, world);
+               TestScope scope = new TestScope(LangUtil.NO_STRINGS, LangUtil.NO_STRINGS, world);
                return scope;
        }
            
index 12218df8b8237c3236715b759105e4173a739688..16ee14054d04300bea5c18a9fc741cd982670788 100644 (file)
@@ -50,7 +50,7 @@ public class VisitorTestCase extends TestCase {
         for (Iterator iterator = pointcuts.iterator(); iterator.hasNext();) {
             String pointcut = (String) iterator.next();
             try  {
-                PatternNodeVisitor.DumpPointcutVisitor.check(pointcut);
+                DumpPointcutVisitor.check(pointcut);
             } catch (Throwable t) {
                 t.printStackTrace();
                 fail("Failed on '"+pointcut+"': " +t.toString());
@@ -66,7 +66,7 @@ public class VisitorTestCase extends TestCase {
             String tp = (String) iterator.next();
             try  {
                 TypePattern p = new PatternParser(tp).parseTypePattern();
-                PatternNodeVisitor.DumpPointcutVisitor.check(p, true);
+                DumpPointcutVisitor.check(p, true);
             } catch (Throwable t) {
                 fail("Failed on '"+tp+"': " +t.toString());
             }
index d2063b73b3453ee00b8e77138e2bb885ba1ad275..55f2a38c88a687af6322dbc2fc43f4b95f572595 100644 (file)
@@ -23,6 +23,7 @@ import junit.framework.TestCase;
 import org.aspectj.util.FuzzyBoolean;
 import org.aspectj.weaver.IntMap;
 import org.aspectj.weaver.MemberImpl;
+import org.aspectj.weaver.TestUtils;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.TestShadow;
 import org.aspectj.weaver.UnresolvedType;
@@ -41,7 +42,7 @@ public class WithinTestCase extends TestCase {
        public void testMatch() throws IOException {
                Shadow getOutFromArrayList = new TestShadow(
                        Shadow.FieldGet, 
-                       MemberImpl.fieldFromString("java.io.PrintStream java.lang.System.out"),
+                       TestUtils.fieldFromString("java.io.PrintStream java.lang.System.out"),
                        UnresolvedType.forName("java.util.ArrayList"),
                        world);
 
@@ -57,7 +58,7 @@ public class WithinTestCase extends TestCase {
                
                Shadow getOutFromEntry = new TestShadow(
                        Shadow.FieldGet, 
-                       MemberImpl.fieldFromString("java.io.PrintStream java.lang.System.out"),
+                       TestUtils.fieldFromString("java.io.PrintStream java.lang.System.out"),
                        UnresolvedType.forName("java.util.Map$Entry"),
                        world);
                        
index 23acf58a57707aacae42601b4e961789dbeac67a..690f64d32af2191f1b5030fa01714142c5f6e220 100644 (file)
  * ******************************************************************/
 package org.aspectj.weaver.tools;
 
-import org.aspectj.util.LangUtil;
-
 import junit.framework.TestCase;
 
+import org.aspectj.util.LangUtil;
+
 /**
- * @author Adrian
- *
+ * @author Adrian Colyer
+ * 
  */
 public class PointcutDesignatorHandlerTests extends TestCase {
 
@@ -60,9 +60,64 @@ public class PointcutDesignatorHandlerTests extends TestCase {
                assertEquals("service.*",beanHandler.getExpressionLastAskedToParse());
        }
        
-       public void testParseWithHandlerAndMultipleSegments() { 
-               if (needToSkip) return;
-               PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
+    
+       /*
+     * Bug 205907 - the registered pointcut designator does not also get registered with the
+     * InternalUseOnlyPointcutParser inside the Java15ReflectionBasedReferenceTypeDelegate code. First test checks
+     * parsing is OK
+     */
+    public void testParsingBeanInReferencePointcut01() throws Exception {
+        if (needToSkip) return;
+        PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
+        BeanDesignatorHandler beanHandler = new BeanDesignatorHandler();
+        parser.registerPointcutDesignatorHandler(beanHandler);
+        // The pointcut in CounterAspect look as follows:
+        //
+        // @Pointcut("execution(* setAge(..)) && bean(testBean1)")
+        // public void testBean1SetAge() { }
+
+        // This should be found and resolved
+        PointcutExpression pc = parser.parsePointcutExpression("CounterAspect.testBean1SetAge()");
+
+    }
+
+    /*
+     * Bug 205907 - the registered pointcut designator does not also get registered with the
+     * InternalUseOnlyPointcutParser inside the Java15ReflectionBasedReferenceTypeDelegate code. This test checks the
+     * actual matching.
+     */
+    public void testParsingBeanInReferencePointcut02() throws Exception {
+        if (needToSkip) return;
+        PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
+        BeanDesignatorHandler beanHandler = new BeanDesignatorHandler();
+        parser.registerPointcutDesignatorHandler(beanHandler);
+        // The pointcut in CounterAspect look as follows:
+        //
+        // @Pointcut("execution(* toString(..)) && bean(testBean1)")
+        // public void testBean1toString() { }
+        
+        // This should be found and resolved
+        PointcutExpression pc = parser.parsePointcutExpression("CounterAspect.testBean1toString()");
+
+        DefaultMatchingContext context = new DefaultMatchingContext();
+        context.addContextBinding("beanName", "testBean1");
+        pc.setMatchingContext(context);
+        ShadowMatch sm = pc.matchesMethodExecution(Object.class.getMethod("toString", new Class[0]));
+        assertTrue(sm.alwaysMatches());
+        
+        sm = pc.matchesMethodExecution(Object.class.getMethod("hashCode", new Class[0]));
+        assertTrue(sm.neverMatches());
+        
+        context = new DefaultMatchingContext();
+        context.addContextBinding("beanName", "testBean2");
+        pc.setMatchingContext(context);
+        sm = pc.matchesMethodExecution(Object.class.getMethod("toString", new Class[0]));
+        assertTrue(sm.neverMatches());
+    }
+
+    public void testParseWithHandlerAndMultipleSegments() {
+        if (needToSkip) return;
+        PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution();
                BeanDesignatorHandler beanHandler = new BeanDesignatorHandler();
                parser.registerPointcutDesignatorHandler(beanHandler);
                parser.parsePointcutExpression("bean(org.xyz.someapp..*)");
@@ -192,4 +247,4 @@ public class PointcutDesignatorHandlerTests extends TestCase {
                        return this.beanNamePattern.equals(matchContext.getBinding("beanName"));
                }
        }               
-}
\ No newline at end of file
+}