]> source.dussan.org Git - aspectj.git/commitdiff
265695: inherited anno matching
authoraclement <aclement>
Fri, 20 Feb 2009 20:57:59 +0000 (20:57 +0000)
committeraclement <aclement>
Fri, 20 Feb 2009 20:57:59 +0000 (20:57 +0000)
org.aspectj.matcher/src/org/aspectj/weaver/patterns/SignaturePattern.java

index 0643b480ced9ff66beb87364e684501692f3de86..80ee4474c123dad074d22635399950b67144d78b 100644 (file)
@@ -10,7 +10,6 @@
  *     PARC     initial implementation 
  * ******************************************************************/
 
-
 package org.aspectj.weaver.patterns;
 
 import java.io.DataOutputStream;
@@ -25,7 +24,7 @@ import java.util.Set;
 
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.util.FuzzyBoolean;
-import org.aspectj.weaver.AjAttribute; 
+import org.aspectj.weaver.AjAttribute;
 import org.aspectj.weaver.AjcMemberMaker;
 import org.aspectj.weaver.AnnotationTargetKind;
 import org.aspectj.weaver.ConcreteTypeMunger;
@@ -40,23 +39,19 @@ import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.VersionedDataInputStream;
 import org.aspectj.weaver.World;
 
-
 public class SignaturePattern extends PatternNode {
        private MemberKind kind;
        private ModifiersPattern modifiers;
        private TypePattern returnType;
-    private TypePattern declaringType;
+       private TypePattern declaringType;
        private NamePattern name;
-    private TypePatternList parameterTypes;
-    private ThrowsPattern throwsPattern;
-    private AnnotationTypePattern annotationPattern;
-    private transient int hashcode = -1;
-       
-       public SignaturePattern(MemberKind kind, ModifiersPattern modifiers,
-                                TypePattern returnType, TypePattern declaringType,
-                                NamePattern name, TypePatternList parameterTypes,
-                                ThrowsPattern throwsPattern,
-                                                        AnnotationTypePattern annotationPattern) {
+       private TypePatternList parameterTypes;
+       private ThrowsPattern throwsPattern;
+       private AnnotationTypePattern annotationPattern;
+       private transient int hashcode = -1;
+
+       public SignaturePattern(MemberKind kind, ModifiersPattern modifiers, TypePattern returnType, TypePattern declaringType,
+                       NamePattern name, TypePatternList parameterTypes, ThrowsPattern throwsPattern, AnnotationTypePattern annotationPattern) {
                this.kind = kind;
                this.modifiers = modifiers;
                this.returnType = returnType;
@@ -66,84 +61,84 @@ public class SignaturePattern extends PatternNode {
                this.throwsPattern = throwsPattern;
                this.annotationPattern = annotationPattern;
        }
-       
-       
-    public SignaturePattern resolveBindings(IScope scope, Bindings bindings) { 
+
+       public SignaturePattern resolveBindings(IScope scope, Bindings bindings) {
                if (returnType != null) {
                        returnType = returnType.resolveBindings(scope, bindings, false, false);
-                       checkForIncorrectTargetKind(returnType,scope,false);
-               } 
+                       checkForIncorrectTargetKind(returnType, scope, false);
+               }
                if (declaringType != null) {
                        declaringType = declaringType.resolveBindings(scope, bindings, false, false);
-                       checkForIncorrectTargetKind(declaringType,scope,false);
+                       checkForIncorrectTargetKind(declaringType, scope, false);
                }
                if (parameterTypes != null) {
                        parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false);
-                       checkForIncorrectTargetKind(parameterTypes,scope,false,true);
+                       checkForIncorrectTargetKind(parameterTypes, scope, false, true);
                }
                if (throwsPattern != null) {
                        throwsPattern = throwsPattern.resolveBindings(scope, bindings);
-                       if (throwsPattern.getForbidden().getTypePatterns().length > 0 
+                       if (throwsPattern.getForbidden().getTypePatterns().length > 0
                                        || throwsPattern.getRequired().getTypePatterns().length > 0) {
-                               checkForIncorrectTargetKind(throwsPattern,scope,false);                         
+                               checkForIncorrectTargetKind(throwsPattern, scope, false);
                        }
                }
                if (annotationPattern != null) {
-                       annotationPattern = annotationPattern.resolveBindings(scope,bindings,false);
-                       checkForIncorrectTargetKind(annotationPattern,scope,true);
-               }
-               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, 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()
-                       || scope.getWorld().getLint().unmatchedTargetKind == null
-                       || (patternNode instanceof AnyTypePattern)) {
+                       annotationPattern = annotationPattern.resolveBindings(scope, bindings, false);
+                       checkForIncorrectTargetKind(annotationPattern, scope, true);
+               }
+               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,
+                       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() || scope.getWorld().getLint().unmatchedTargetKind == null
+                               || (patternNode instanceof AnyTypePattern)) {
                        return;
                }
                if (patternNode instanceof ExactAnnotationTypePattern) {
-                       ResolvedType resolvedType = ((ExactAnnotationTypePattern)patternNode).getAnnotationType().resolve(scope.getWorld());
+                       ResolvedType resolvedType = ((ExactAnnotationTypePattern) patternNode).getAnnotationType().resolve(scope.getWorld());
                        if (targetsOtherThanTypeAllowed) {
                                AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
-                               if (targetKinds == null) return;
-                               reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,true);
+                               if (targetKinds == null)
+                                       return;
+                               reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, true);
                        } else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
                                // everything is incorrect since we've already checked whether we have the TYPE target annotation
                                AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
-                               if (targetKinds == null) return;
-                               reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,false);
+                               if (targetKinds == null)
+                                       return;
+                               reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, false);
                        }
                } else {
-                       TypePatternVisitor visitor = new TypePatternVisitor(scope,targetsOtherThanTypeAllowed,parameterTargettingAnnotationsAllowed);
-                       patternNode.traverse(visitor,null);
+                       TypePatternVisitor visitor = new TypePatternVisitor(scope, targetsOtherThanTypeAllowed,
+                                       parameterTargettingAnnotationsAllowed);
+                       patternNode.traverse(visitor, null);
                        if (visitor.containedIncorrectTargetKind()) {
-                               Set keys = visitor.getIncorrectTargetKinds().keySet();                          
+                               Set keys = visitor.getIncorrectTargetKinds().keySet();
                                for (Iterator iter = keys.iterator(); iter.hasNext();) {
-                                       PatternNode node = (PatternNode)iter.next();
-                                       AnnotationTargetKind[] targetKinds =  (AnnotationTargetKind[]) visitor.getIncorrectTargetKinds().get(node);
-                                       reportUnmatchedTargetKindMessage(targetKinds,node,scope,false);
+                                       PatternNode node = (PatternNode) iter.next();
+                                       AnnotationTargetKind[] targetKinds = (AnnotationTargetKind[]) visitor.getIncorrectTargetKinds().get(node);
+                                       reportUnmatchedTargetKindMessage(targetKinds, node, scope, false);
                                }
                        }
                }
-    }
-    
-    private void reportUnmatchedTargetKindMessage(
-               AnnotationTargetKind[] annotationTargetKinds,  
-               PatternNode node,
-               IScope scope,
-               boolean checkMatchesMemberKindName) {
-       StringBuffer targetNames = new StringBuffer("{");
-       for (int i = 0; i < annotationTargetKinds.length; i++) {
+       }
+
+       private void reportUnmatchedTargetKindMessage(AnnotationTargetKind[] annotationTargetKinds, PatternNode node, IScope scope,
+                       boolean checkMatchesMemberKindName) {
+               StringBuffer targetNames = new StringBuffer("{");
+               for (int i = 0; i < annotationTargetKinds.length; i++) {
                        AnnotationTargetKind targetKind = annotationTargetKinds[i];
                        if (checkMatchesMemberKindName && kind.getName().equals(targetKind.getName())) {
                                return;
@@ -154,112 +149,112 @@ public class SignaturePattern extends PatternNode {
                                targetNames.append("ElementType." + targetKind.getName() + "}");
                        }
                }
-               scope.getWorld().getLint().unmatchedTargetKind.signal(new String[] {node.toString(),targetNames.toString()}, getSourceLocation(), new ISourceLocation[0]);
-    }
-    
-    /**
-     * Class which visits the nodes in the TypePattern tree until an
-     * ExactTypePattern is found. Once this is found it creates a new
-     * ExactAnnotationTypePattern and checks whether the targetKind
-     * (created via the @Target annotation) matches ElementType.TYPE if
-     * this is the only target kind which is allowed, or matches the
-     * signature pattern kind if there is no restriction.
-     */
-    private class TypePatternVisitor extends AbstractPatternNodeVisitor {
-
-       private IScope scope;
-       private Map incorrectTargetKinds /* PatternNode -> AnnotationTargetKind[] */ = new HashMap();
-       private boolean targetsOtherThanTypeAllowed;
+               scope.getWorld().getLint().unmatchedTargetKind.signal(new String[] { node.toString(), targetNames.toString() },
+                               getSourceLocation(), new ISourceLocation[0]);
+       }
+
+       /**
+        * Class which visits the nodes in the TypePattern tree until an ExactTypePattern is found. Once this is found it creates a new
+        * ExactAnnotationTypePattern and checks whether the targetKind (created via the @Target annotation) matches ElementType.TYPE if
+        * this is the only target kind which is allowed, or matches the signature pattern kind if there is no restriction.
+        */
+       private class TypePatternVisitor extends AbstractPatternNodeVisitor {
+
+               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, boolean parameterTargettingAnnotationsAllowed) {
-               this.scope = scope;
-               this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed;
-               this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed;
-       }
-       
-       public Object visit(WildAnnotationTypePattern node, Object data) {
-               node.getTypePattern().accept(this,data);
-               return node;
-       }
-       
-       /**
-        * Do the ExactAnnotationTypePatterns have the incorrect target?
-        */
-       public Object visit(ExactAnnotationTypePattern node, Object data) {
-               ResolvedType resolvedType = node.getAnnotationType().resolve(scope.getWorld());
+               /**
+                * @param requiredTarget - the signature pattern Kind
+                * @param scope
+                * @param parameterTargettingAnnotationsAllowed
+                */
+               public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
+                       this.scope = scope;
+                       this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed;
+                       this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed;
+               }
+
+               public Object visit(WildAnnotationTypePattern node, Object data) {
+                       node.getTypePattern().accept(this, data);
+                       return node;
+               }
+
+               /**
+                * Do the ExactAnnotationTypePatterns have the incorrect target?
+                */
+               public Object visit(ExactAnnotationTypePattern node, Object data) {
+                       ResolvedType resolvedType = node.getAnnotationType().resolve(scope.getWorld());
                        if (targetsOtherThanTypeAllowed) {
                                AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
-                               if (targetKinds == null) return data;
+                               if (targetKinds == null)
+                                       return data;
                                List incorrectTargets = new ArrayList();
                                for (int i = 0; i < targetKinds.length; i++) {
-                                       if (targetKinds[i].getName().equals(kind.getName()) ||
-                                                       (targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())
-                                                       ) {
+                                       if (targetKinds[i].getName().equals(kind.getName())
+                                                       || (targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())) {
                                                return data;
                                        }
                                        incorrectTargets.add(targetKinds[i]);
                                }
-                               if (incorrectTargets.isEmpty()) return data;
+                               if (incorrectTargets.isEmpty())
+                                       return data;
                                AnnotationTargetKind[] kinds = new AnnotationTargetKind[incorrectTargets.size()];
-                               incorrectTargetKinds.put(node,(AnnotationTargetKind[]) incorrectTargets.toArray(kinds));        
+                               incorrectTargetKinds.put(node, (AnnotationTargetKind[]) incorrectTargets.toArray(kinds));
                        } else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
                                AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
-                               if (targetKinds == null) return data;
+                               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;
+                                               if (annotationTargetKind.getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())
+                                                       return data;
                                        }
                                }
-                               incorrectTargetKinds.put(node,targetKinds);
+                               incorrectTargetKinds.put(node, targetKinds);
                        }
-               return data;
-       }
-       
-       public Object visit(ExactTypePattern node, Object data) {
-               ExactAnnotationTypePattern eatp =  new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()),null);
-               eatp.accept(this,data);         
-               return data;
-       }
-       
-       public Object visit(AndTypePattern node, Object data) {
-               node.getLeft().accept(this,data);
-               node.getRight().accept(this,data);
-               return node;
-       }
-
-       public Object visit(OrTypePattern node, Object data) {
-               node.getLeft().accept(this,data);
-               node.getRight().accept(this,data);
-               return node;
-       }
-
-       public Object visit(AnyWithAnnotationTypePattern node, Object data) {
-               node.getAnnotationPattern().accept(this,data);
-               return node;
-       }
-       
-       public boolean containedIncorrectTargetKind() {
-               return (incorrectTargetKinds.size() != 0);
-       }
-       
-       public Map getIncorrectTargetKinds() {
-               return incorrectTargetKinds;
-       }
-    }
-    
-    
+                       return data;
+               }
+
+               public Object visit(ExactTypePattern node, Object data) {
+                       ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()), null);
+                       eatp.accept(this, data);
+                       return data;
+               }
+
+               public Object visit(AndTypePattern node, Object data) {
+                       node.getLeft().accept(this, data);
+                       node.getRight().accept(this, data);
+                       return node;
+               }
+
+               public Object visit(OrTypePattern node, Object data) {
+                       node.getLeft().accept(this, data);
+                       node.getRight().accept(this, data);
+                       return node;
+               }
+
+               public Object visit(AnyWithAnnotationTypePattern node, Object data) {
+                       node.getAnnotationPattern().accept(this, data);
+                       return node;
+               }
+
+               public boolean containedIncorrectTargetKind() {
+                       return (incorrectTargetKinds.size() != 0);
+               }
+
+               public Map getIncorrectTargetKinds() {
+                       return incorrectTargetKinds;
+               }
+       }
+
        public void postRead(ResolvedType enclosingType) {
                if (returnType != null) {
                        returnType.postRead(enclosingType);
-               } 
+               }
                if (declaringType != null) {
                        declaringType.postRead(enclosingType);
                }
@@ -267,103 +262,127 @@ public class SignaturePattern extends PatternNode {
                        parameterTypes.postRead(enclosingType);
                }
        }
-       
+
        /**
-        * return a copy of this signature pattern in which every type variable reference
-        * is replaced by the corresponding entry in the map.
+        * return a copy of this signature pattern in which every type variable reference is replaced by the corresponding entry in the
+        * map.
         */
-       public SignaturePattern parameterizeWith(Map typeVariableMap,World w) {
-               SignaturePattern ret = new SignaturePattern(
-                                               kind,
-                                               modifiers,
-                                               returnType.parameterizeWith(typeVariableMap,w),
-                                               declaringType.parameterizeWith(typeVariableMap,w),
-                                               name,
-                                               parameterTypes.parameterizeWith(typeVariableMap,w),
-                                               throwsPattern.parameterizeWith(typeVariableMap,w),
-                                               annotationPattern.parameterizeWith(typeVariableMap,w));
+       public SignaturePattern parameterizeWith(Map typeVariableMap, World w) {
+               SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType.parameterizeWith(typeVariableMap, w), declaringType
+                               .parameterizeWith(typeVariableMap, w), name, parameterTypes.parameterizeWith(typeVariableMap, w), throwsPattern
+                               .parameterizeWith(typeVariableMap, w), annotationPattern.parameterizeWith(typeVariableMap, w));
                ret.copyLocationFrom(this);
                return ret;
        }
-       
+
        public boolean matches(Member joinPointSignature, World world, boolean allowBridgeMethods) {
                // fail (or succeed!) fast tests...
-               if (joinPointSignature == null) return false;
-               if (kind != joinPointSignature.getKind()) return false;
-               if (kind == Member.ADVICE) return true;
-               
+               if (joinPointSignature == null)
+                       return false;
+               if (kind != joinPointSignature.getKind())
+                       return false;
+               if (kind == Member.ADVICE)
+                       return true;
+
                // do the hard work then...
                boolean subjectMatch = true;
+               boolean wantsAnnotationMatch = wantToMatchAnnotationPattern();
                Iterator candidateMatches = joinPointSignature.getJoinPointSignatures(world);
-               while(candidateMatches.hasNext()) {
+               while (candidateMatches.hasNext()) {
                        JoinPointSignature aSig = (JoinPointSignature) candidateMatches.next();
-                       FuzzyBoolean matchResult = matchesExactly(aSig,world,allowBridgeMethods,subjectMatch); 
+                       // System.out.println(aSig);
+                       FuzzyBoolean matchResult = matchesExactly(aSig, world, allowBridgeMethods, subjectMatch);
                        if (matchResult.alwaysTrue()) {
                                return true;
                        } else if (matchResult.alwaysFalse()) {
                                return false;
                        }
                        // if we got a "MAYBE" it's worth looking at the other signatures
+                       // The first signature is the subject signature - and against it we must match modifiers/annotations/throws
+                       // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
                        subjectMatch = false;
+                       // Early exit
+                       if (wantsAnnotationMatch) {
+                               return false;
+                       }
                }
                return false;
        }
-       
+
        // Does this pattern match this exact signature (no declaring type mucking about
        // or chasing up the hierarchy)
        // return YES if it does, NO if it doesn't and no ancester member could match either,
        // and MAYBE if it doesn't but an ancester member could.
-       private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods,boolean subjectMatch) {
+       private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods, boolean subjectMatch) {
                // Java5 introduces bridge methods, we match a call to them but nothing else...
                if (aMember.isBridgeMethod() && !allowBridgeMethods) {
                        return FuzzyBoolean.MAYBE;
                }
-                       
-               // modifiers match on the *subject*
+
+               // Only the subject is checked for modifiers
+               // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
                if (subjectMatch && !modifiers.matches(aMember.getModifiers())) {
                        return FuzzyBoolean.NO;
-//                     if (aMember.isPrivate()) return FuzzyBoolean.NO;
-//                     else return FuzzyBoolean.MAYBE;
                }
-               
-               
+
                FuzzyBoolean matchesIgnoringAnnotations = FuzzyBoolean.YES;
                if (kind == Member.STATIC_INITIALIZATION) {
                        matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld);
                } else if (kind == Member.FIELD) {
-                       matchesIgnoringAnnotations = matchesExactlyField(aMember,inAWorld);
+                       matchesIgnoringAnnotations = matchesExactlyField(aMember, inAWorld);
                } else if (kind == Member.METHOD) {
-                       matchesIgnoringAnnotations = matchesExactlyMethod(aMember,inAWorld, subjectMatch);
+                       matchesIgnoringAnnotations = matchesExactlyMethod(aMember, inAWorld, subjectMatch);
                } else if (kind == Member.CONSTRUCTOR) {
                        matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld);
                }
-               if (matchesIgnoringAnnotations.alwaysFalse()) return FuzzyBoolean.NO;
-               
-               // why did Adrian put this comment in:
-               // annotations match on the *subject* 
-               // surely you never want execution(@Something * *(..)) to match something just because
-               // it is a secondary join point signature for a join point and doesn't have the annotation?
-               // pr239441
-               if (matchesIgnoringAnnotations.alwaysTrue()) {
-                       return matchesAnnotations(aMember,inAWorld);
+               if (matchesIgnoringAnnotations.alwaysFalse()) {
+                       return FuzzyBoolean.NO;
+               }
+
+               // Only the subject is checked for annotations (239441/119749)
+               // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
+               if (subjectMatch) {
+                       // The annotations must match if specified
+                       if (!matchesAnnotations(aMember, inAWorld).alwaysTrue()) {
+                               return FuzzyBoolean.NO;
+                       } else {
+                               return matchesIgnoringAnnotations;
+                       }
                } else {
-                       return matchesIgnoringAnnotations;
+                       // Unless they specified any annotation then it is a failure
+                       if (annotationPattern instanceof AnyAnnotationTypePattern) {
+                               return matchesIgnoringAnnotations;
+                       } else {
+                               return FuzzyBoolean.NO;
+                       }
                }
-               
+
+               // if (subjectMatch && !matchesAnnotations(aMember, inAWorld).alwaysTrue()) {
+               // return FuzzyBoolean.NO;
+               // } else {
+               //                      
+               // return matchesIgnoringAnnotations;
+               // }
+
        }
-       
+
+       private boolean wantToMatchAnnotationPattern() {
+               return !(annotationPattern instanceof AnyAnnotationTypePattern);
+       }
+
        /**
         * Matches on declaring type
         */
-       private FuzzyBoolean matchesExactlyStaticInitialization(JoinPointSignature aMember,World world) {
+       private FuzzyBoolean matchesExactlyStaticInitialization(JoinPointSignature aMember, World world) {
                return FuzzyBoolean.fromBoolean(declaringType.matchesStatically(aMember.getDeclaringType().resolve(world)));
        }
-       
+
        /**
         * Matches on name, declaring type, field type
         */
        private FuzzyBoolean matchesExactlyField(JoinPointSignature aField, World world) {
-               if (!name.matches(aField.getName())) return FuzzyBoolean.NO;
+               if (!name.matches(aField.getName()))
+                       return FuzzyBoolean.NO;
                ResolvedType fieldDeclaringType = aField.getDeclaringType().resolve(world);
                if (!declaringType.matchesStatically(fieldDeclaringType)) {
                        return FuzzyBoolean.MAYBE;
@@ -378,16 +397,19 @@ public class SignaturePattern extends PatternNode {
                // passed all the guards...
                return FuzzyBoolean.YES;
        }
-       
+
        /**
         * Matches on name, declaring type, return type, parameter types, throws types
         */
        private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world, boolean subjectMatch) {
-               if (!name.matches(aMethod.getName())) return FuzzyBoolean.NO;
+               if (!name.matches(aMethod.getName()))
+                       return FuzzyBoolean.NO;
                // Check the throws pattern
-               if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world)) return FuzzyBoolean.NO;
-               
-               if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) return FuzzyBoolean.MAYBE;
+               if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world))
+                       return FuzzyBoolean.NO;
+
+               if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world)))
+                       return FuzzyBoolean.MAYBE;
                if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) {
                        // looking bad, but there might be parameterization to consider...
                        if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) {
@@ -395,276 +417,297 @@ public class SignaturePattern extends PatternNode {
                                return FuzzyBoolean.MAYBE;
                        }
                }
-               if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) return FuzzyBoolean.NO;
+               if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length))
+                       return FuzzyBoolean.NO;
                ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes());
                ResolvedType[][] parameterAnnotationTypes = aMethod.getParameterAnnotationTypes();
-               if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;
-               if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
+               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,parameterAnnotationTypes).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...
                        }
                }
-               
+
                // check that varargs specifications match
-               if (!matchesVarArgs(aMethod,world)) return FuzzyBoolean.MAYBE;
-               
+               if (!matchesVarArgs(aMethod, world))
+                       return FuzzyBoolean.MAYBE;
+
                // passed all the guards..
                return FuzzyBoolean.YES;
        }
-       
-
 
        /**
         * match on declaring type, parameter types, throws types
         */
        private FuzzyBoolean matchesExactlyConstructor(JoinPointSignature aConstructor, World world) {
-               if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world))) return FuzzyBoolean.NO;
+               if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world)))
+                       return FuzzyBoolean.NO;
 
-               if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length)) return FuzzyBoolean.NO;
+               if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length))
+                       return FuzzyBoolean.NO;
                ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes());
-               
+
                ResolvedType[][] parameterAnnotationTypes = aConstructor.getParameterAnnotationTypes();
 
-               if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;
+               if (parameterAnnotationTypes == null || parameterAnnotationTypes.length == 0)
+                       parameterAnnotationTypes = null;
 
-               if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
+               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()) {
+                       if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()), TypePattern.STATIC).alwaysTrue()) {
                                return FuzzyBoolean.MAYBE;
                                // It could STILL be a match based on the erasure of the parameter types??
                                // to be determined via test cases...
                        }
                }
-               
+
                // check that varargs specifications match
-               if (!matchesVarArgs(aConstructor,world)) return FuzzyBoolean.NO;
-               
+               if (!matchesVarArgs(aConstructor, world))
+                       return FuzzyBoolean.NO;
+
                // Check the throws pattern
-               if (!throwsPattern.matches(aConstructor.getExceptions(), world)) return FuzzyBoolean.NO;
-               
+               if (!throwsPattern.matches(aConstructor.getExceptions(), world))
+                       return FuzzyBoolean.NO;
+
                // passed all the guards..
-               return FuzzyBoolean.YES;                
+               return FuzzyBoolean.YES;
        }
-       
+
        /**
-        * We've matched against this method or constructor so far, but without considering
-        * varargs (which has been matched as a simple array thus far). Now we do the additional
-        * checks to see if the parties agree on whether the last parameter is varargs or a 
-        * straight array. 
+        * We've matched against this method or constructor so far, but without considering varargs (which has been matched as a simple
+        * array thus far). Now we do the additional checks to see if the parties agree on whether the last parameter is varargs or a
+        * straight array.
         */
        private boolean matchesVarArgs(JoinPointSignature aMethodOrConstructor, World inAWorld) {
-               if (parameterTypes.size() == 0) return true;
-               
-               TypePattern lastPattern = parameterTypes.get(parameterTypes.size()-1);
-               boolean canMatchVarArgsSignature = lastPattern.isStar() || 
-                                                   lastPattern.isVarArgs() ||
-                                                   (lastPattern == TypePattern.ELLIPSIS);
-               
+               if (parameterTypes.size() == 0)
+                       return true;
+
+               TypePattern lastPattern = parameterTypes.get(parameterTypes.size() - 1);
+               boolean canMatchVarArgsSignature = lastPattern.isStar() || lastPattern.isVarArgs() || (lastPattern == TypePattern.ELLIPSIS);
+
                if (aMethodOrConstructor.isVarargsMethod()) {
                        // we have at least one parameter in the pattern list, and the method has a varargs signature
                        if (!canMatchVarArgsSignature) {
                                // XXX - Ideally the shadow would be included in the msg but we don't know it...
-                               inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(),getSourceLocation());
+                               inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(), getSourceLocation());
                                return false;
                        }
                } else {
                        // the method ends with an array type, check that we don't *require* a varargs
-                       if (lastPattern.isVarArgs()) return false;
+                       if (lastPattern.isVarArgs())
+                               return false;
                }
 
                return true;
        }
-               
-       private FuzzyBoolean matchesAnnotations(ResolvedMember member,World world) {
-         if (member == null) {
-            //                 world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
+
+       private FuzzyBoolean matchesAnnotations(ResolvedMember member, World world) {
+               if (member == null) {
+                       // world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
                        return FuzzyBoolean.NO;
-         }
-         annotationPattern.resolve(world);
-        
-         // optimization before we go digging around for annotations on ITDs
-         if (annotationPattern instanceof AnyAnnotationTypePattern) return FuzzyBoolean.YES;
-         
-         // fake members represent ITD'd fields - for their annotations we should go and look up the
-         // relevant member in the original aspect
-         if (member.isAnnotatedElsewhere() && member.getKind()==Member.FIELD) {
-           // FIXME asc duplicate of code in AnnotationPointcut.matchInternal()?  same fixmes apply here.
-//         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();) {
-               ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next();
-                       if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
-                         ResolvedMember fakerm = typeMunger.getSignature();
-                         ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm,typeMunger.getAspectType());
-                         ResolvedMember rmm       = findMethod(typeMunger.getAspectType(),ajcMethod);
-                         if (fakerm.equals(member)) {
-                               member = rmm;
-                         }
+               }
+               annotationPattern.resolve(world);
+
+               // optimization before we go digging around for annotations on ITDs
+               if (annotationPattern instanceof AnyAnnotationTypePattern) {
+                       return FuzzyBoolean.YES;
+               }
+
+               // fake members represent ITD'd fields - for their annotations we should go and look up the
+               // relevant member in the original aspect
+               if (member.isAnnotatedElsewhere() && member.getKind() == Member.FIELD) {
+                       // FIXME asc duplicate of code in AnnotationPointcut.matchInternal()? same fixmes apply here.
+                       // 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();) {
+                               ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next();
+                               if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
+                                       ResolvedMember fakerm = typeMunger.getSignature();
+                                       ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm, typeMunger.getAspectType());
+                                       ResolvedMember rmm = findMethod(typeMunger.getAspectType(), ajcMethod);
+                                       if (fakerm.equals(member)) {
+                                               member = rmm;
+                                       }
+                               }
                        }
                }
-         }
-         
-         if (annotationPattern.matches(member).alwaysTrue()) {
-                 return FuzzyBoolean.YES;
-         } else {
-                 return FuzzyBoolean.NO;  // do NOT look at ancestor members...
-         }
+
+               if (annotationPattern.matches(member).alwaysTrue()) {
+                       return FuzzyBoolean.YES;
+               } else {
+                       // do NOT look at ancestor members... only the subject can have an annotation match
+                       // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
+                       return FuzzyBoolean.NO;
+               }
        }
-       
+
        private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) {
-              ResolvedMember decMethods[] = aspectType.getDeclaredMethods();
-              for (int i = 0; i < decMethods.length; i++) {
+               ResolvedMember decMethods[] = aspectType.getDeclaredMethods();
+               for (int i = 0; i < decMethods.length; i++) {
                        ResolvedMember member = decMethods[i];
-                       if (member.equals(ajcMethod)) return member;
-          }
-                       return null;
+                       if (member.equals(ajcMethod))
+                               return member;
+               }
+               return null;
        }
-       
-       public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world,TypePattern returnTypePattern,ResolvedType sigReturn) {
-               
+
+       public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world,
+                       TypePattern returnTypePattern, ResolvedType sigReturn) {
+
                ResolvedType onType = shadowDeclaringType.resolve(world);
-                       
+
                // fastmatch
-               if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn)) 
+               if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn))
                        return true;
-                       
+
                Collection declaringTypes = member.getDeclaringTypes(world);
-               
+
                boolean checkReturnType = true;
-               // XXX Possible enhancement?  Doesn't seem to speed things up
-               //      if (returnTypePattern.isStar()) {
-               //              if (returnTypePattern instanceof WildTypePattern) {
-               //                      if (((WildTypePattern)returnTypePattern).getDimensions()==0) checkReturnType = false;
-               //              }
-               //      }
-                       
+               // XXX Possible enhancement? Doesn't seem to speed things up
+               // if (returnTypePattern.isStar()) {
+               // if (returnTypePattern instanceof WildTypePattern) {
+               // if (((WildTypePattern)returnTypePattern).getDimensions()==0) checkReturnType = false;
+               // }
+               // }
+
                // Sometimes that list includes types that don't explicitly declare the member we are after -
                // they are on the list because their supertype is on the list, that's why we use
                // lookupMethod rather than lookupMemberNoSupers()
-               for (Iterator i = declaringTypes.iterator(); i.hasNext(); ) {
-                       ResolvedType type = (ResolvedType)i.next();
+               for (Iterator i = declaringTypes.iterator(); i.hasNext();) {
+                       ResolvedType type = (ResolvedType) i.next();
                        if (declaringType.matchesStatically(type)) {
-                         if (!checkReturnType) return true;
-                         ResolvedMember rm = type.lookupMethod(member);
-                         if (rm==null)  rm = type.lookupMethodInITDs(member); // It must be in here, or we have *real* problems
-                         if (rm==null) continue; // might be currently looking at the generic type and we need to continue searching in case we hit a parameterized version of this same type...
-                         UnresolvedType returnTypeX = rm.getReturnType();
-                         ResolvedType returnType = returnTypeX.resolve(world);
-                         if (returnTypePattern.matchesStatically(returnType)) return true;
+                               if (!checkReturnType)
+                                       return true;
+                               ResolvedMember rm = type.lookupMethod(member);
+                               if (rm == null)
+                                       rm = type.lookupMethodInITDs(member); // It must be in here, or we have *real* problems
+                               if (rm == null)
+                                       continue; // might be currently looking at the generic type and we need to continue searching in case we hit a
+                               // parameterized version of this same type...
+                               UnresolvedType returnTypeX = rm.getReturnType();
+                               ResolvedType returnType = returnTypeX.resolve(world);
+                               if (returnTypePattern.matchesStatically(returnType))
+                                       return true;
                        }
                }
                return false;
        }
-       
-//     private Collection getDeclaringTypes(Signature sig) {
-//             List l = new ArrayList();
-//             Class onType = sig.getDeclaringType();
-//             String memberName = sig.getName();
-//             if (sig instanceof FieldSignature) {
-//                     Class fieldType = ((FieldSignature)sig).getFieldType();
-//                     Class superType = onType;
-//                     while(superType != null) {
-//                             try {
-//                                     Field f =  (superType.getDeclaredField(memberName));
-//                                     if (f.getType() == fieldType) {
-//                                             l.add(superType);
-//                                     }
-//                             } catch (NoSuchFieldException nsf) {}
-//                             superType = superType.getSuperclass();
-//                     }
-//             } else if (sig instanceof MethodSignature) {
-//                     Class[] paramTypes = ((MethodSignature)sig).getParameterTypes();
-//                     Class superType = onType;
-//                     while(superType != null) {
-//                             try {
-//                                     superType.getDeclaredMethod(memberName,paramTypes);
-//                                     l.add(superType);
-//                             } catch (NoSuchMethodException nsm) {}
-//                             superType = superType.getSuperclass();
-//                     }
-//             }
-//             return l;
-//     }
-       
-    public NamePattern getName() { return name; }
-    public TypePattern getDeclaringType() { return declaringType; }
-    
-    public MemberKind getKind() {
-       return kind;
-    }
-    
-    public String toString() {
-       StringBuffer buf = new StringBuffer();
-       
-       if (annotationPattern != AnnotationTypePattern.ANY) {
+
+       // private Collection getDeclaringTypes(Signature sig) {
+       // List l = new ArrayList();
+       // Class onType = sig.getDeclaringType();
+       // String memberName = sig.getName();
+       // if (sig instanceof FieldSignature) {
+       // Class fieldType = ((FieldSignature)sig).getFieldType();
+       // Class superType = onType;
+       // while(superType != null) {
+       // try {
+       // Field f = (superType.getDeclaredField(memberName));
+       // if (f.getType() == fieldType) {
+       // l.add(superType);
+       // }
+       // } catch (NoSuchFieldException nsf) {}
+       // superType = superType.getSuperclass();
+       // }
+       // } else if (sig instanceof MethodSignature) {
+       // Class[] paramTypes = ((MethodSignature)sig).getParameterTypes();
+       // Class superType = onType;
+       // while(superType != null) {
+       // try {
+       // superType.getDeclaredMethod(memberName,paramTypes);
+       // l.add(superType);
+       // } catch (NoSuchMethodException nsm) {}
+       // superType = superType.getSuperclass();
+       // }
+       // }
+       // return l;
+       // }
+
+       public NamePattern getName() {
+               return name;
+       }
+
+       public TypePattern getDeclaringType() {
+               return declaringType;
+       }
+
+       public MemberKind getKind() {
+               return kind;
+       }
+
+       public String toString() {
+               StringBuffer buf = new StringBuffer();
+
+               if (annotationPattern != AnnotationTypePattern.ANY) {
                        buf.append(annotationPattern.toString());
                        buf.append(' ');
-       }
-       
-       if (modifiers != ModifiersPattern.ANY) {
-               buf.append(modifiers.toString());
-               buf.append(' ');
-       }
-       
-       if (kind == Member.STATIC_INITIALIZATION) {
-               buf.append(declaringType.toString());
-               buf.append(".<clinit>()");//FIXME AV - bad, cannot be parsed again
-       } else if (kind == Member.HANDLER) {
-               buf.append("handler(");
-               buf.append(parameterTypes.get(0));
-               buf.append(")");
-       } else {
-               if (!(kind == Member.CONSTRUCTOR)) {
-                       buf.append(returnType.toString());
-                   buf.append(' ');
-               }
-               if (declaringType != TypePattern.ANY) {
-                       buf.append(declaringType.toString());
-                       buf.append('.');
-               }
-               if (kind == Member.CONSTRUCTOR) {
-                       buf.append("new");
-               } else {
-                   buf.append(name.toString());
-               }
-               if (kind == Member.METHOD || kind == Member.CONSTRUCTOR) {
-                       buf.append(parameterTypes.toString());
-               }
-            //FIXME AV - throws is not printed here, weird
-       }
-       return buf.toString();
-    }
-    
-    public boolean equals(Object other) {
-       if (!(other instanceof SignaturePattern)) return false;
-       SignaturePattern o = (SignaturePattern)other;
-       return o.kind.equals(this.kind)
-               && o.modifiers.equals(this.modifiers)
-               && o.returnType.equals(this.returnType)
-               && o.declaringType.equals(this.declaringType)
-               && o.name.equals(this.name)
-               && o.parameterTypes.equals(this.parameterTypes)
-                       && o.throwsPattern.equals(this.throwsPattern)
-                       && o.annotationPattern.equals(this.annotationPattern);
-    }
-    public int hashCode() {
-       if (hashcode==-1) {
-          hashcode = 17;
-          hashcode = 37*hashcode + kind.hashCode();
-          hashcode = 37*hashcode + modifiers.hashCode();
-          hashcode = 37*hashcode + returnType.hashCode();
-          hashcode = 37*hashcode + declaringType.hashCode();
-          hashcode = 37*hashcode + name.hashCode();
-          hashcode = 37*hashcode + parameterTypes.hashCode();
-          hashcode = 37*hashcode + throwsPattern.hashCode();
-          hashcode = 37*hashcode + annotationPattern.hashCode();
-       }
-        return hashcode;
-    }
-    
+               }
+
+               if (modifiers != ModifiersPattern.ANY) {
+                       buf.append(modifiers.toString());
+                       buf.append(' ');
+               }
+
+               if (kind == Member.STATIC_INITIALIZATION) {
+                       buf.append(declaringType.toString());
+                       buf.append(".<clinit>()");// FIXME AV - bad, cannot be parsed again
+               } else if (kind == Member.HANDLER) {
+                       buf.append("handler(");
+                       buf.append(parameterTypes.get(0));
+                       buf.append(")");
+               } else {
+                       if (!(kind == Member.CONSTRUCTOR)) {
+                               buf.append(returnType.toString());
+                               buf.append(' ');
+                       }
+                       if (declaringType != TypePattern.ANY) {
+                               buf.append(declaringType.toString());
+                               buf.append('.');
+                       }
+                       if (kind == Member.CONSTRUCTOR) {
+                               buf.append("new");
+                       } else {
+                               buf.append(name.toString());
+                       }
+                       if (kind == Member.METHOD || kind == Member.CONSTRUCTOR) {
+                               buf.append(parameterTypes.toString());
+                       }
+                       // FIXME AV - throws is not printed here, weird
+               }
+               return buf.toString();
+       }
+
+       public boolean equals(Object other) {
+               if (!(other instanceof SignaturePattern))
+                       return false;
+               SignaturePattern o = (SignaturePattern) other;
+               return o.kind.equals(this.kind) && o.modifiers.equals(this.modifiers) && o.returnType.equals(this.returnType)
+                               && o.declaringType.equals(this.declaringType) && o.name.equals(this.name)
+                               && o.parameterTypes.equals(this.parameterTypes) && o.throwsPattern.equals(this.throwsPattern)
+                               && o.annotationPattern.equals(this.annotationPattern);
+       }
+
+       public int hashCode() {
+               if (hashcode == -1) {
+                       hashcode = 17;
+                       hashcode = 37 * hashcode + kind.hashCode();
+                       hashcode = 37 * hashcode + modifiers.hashCode();
+                       hashcode = 37 * hashcode + returnType.hashCode();
+                       hashcode = 37 * hashcode + declaringType.hashCode();
+                       hashcode = 37 * hashcode + name.hashCode();
+                       hashcode = 37 * hashcode + parameterTypes.hashCode();
+                       hashcode = 37 * hashcode + throwsPattern.hashCode();
+                       hashcode = 37 * hashcode + annotationPattern.hashCode();
+               }
+               return hashcode;
+       }
+
        public void write(DataOutputStream s) throws IOException {
                kind.write(s);
                modifiers.write(s);
@@ -685,15 +728,15 @@ public class SignaturePattern extends PatternNode {
                NamePattern name = NamePattern.read(s);
                TypePatternList parameterTypes = TypePatternList.read(s, context);
                ThrowsPattern throwsPattern = ThrowsPattern.read(s, context);
-               
+
                AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY;
-               
-               if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
-                 annotationPattern = AnnotationTypePattern.read(s,context);
+
+               if (s.getMajorVersion() >= AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
+                       annotationPattern = AnnotationTypePattern.read(s, context);
                }
 
-               SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType,
-                                       name, parameterTypes, throwsPattern,annotationPattern);
+               SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, name, parameterTypes,
+                               throwsPattern, annotationPattern);
                ret.readLocation(context, s);
                return ret;
        }
@@ -725,30 +768,28 @@ public class SignaturePattern extends PatternNode {
        public ThrowsPattern getThrowsPattern() {
                return throwsPattern;
        }
-       
+
        /**
-        * return true if last argument in params is an Object[] but the modifiers say this method
-        * was declared with varargs (Object...).  We shouldn't be matching if this is the case.
+        * return true if last argument in params is an Object[] but the modifiers say this method was declared with varargs
+        * (Object...). We shouldn't be matching if this is the case.
         */
-//     private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) {
-//             if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) {
-//                     // we have at least one parameter in the pattern list, and the method has a varargs signature
-//                     TypePattern lastPattern = params.get(params.size()-1);
-//                     if (lastPattern.isArray() && !lastPattern.isVarArgs) return true;
-//             }
-//         return false;
-//     }
-       
+       // private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) {
+       // if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) {
+       // // we have at least one parameter in the pattern list, and the method has a varargs signature
+       // TypePattern lastPattern = params.get(params.size()-1);
+       // if (lastPattern.isArray() && !lastPattern.isVarArgs) return true;
+       // }
+       // return false;
+       // }
        public AnnotationTypePattern getAnnotationPattern() {
                return annotationPattern;
        }
 
-
        public boolean isStarAnnotation() {
                return annotationPattern == AnnotationTypePattern.ANY;
        }
 
-    public Object accept(PatternNodeVisitor visitor, Object data) {
-        return visitor.visit(this, data);
-    }
+       public Object accept(PatternNodeVisitor visitor, Object data) {
+               return visitor.visit(this, data);
+       }
 }