From a4a4da472ba4482e67eda77e130166226ca00a09 Mon Sep 17 00:00:00 2001 From: acolyer Date: Thu, 9 Jun 2005 14:44:30 +0000 Subject: [PATCH] first batch of updates for generics :- largely parsing plus storage of type variable patterns, plus a few tweaks to visitor pattern --- .../aspectj/weaver/bcel/AtAjAttributes.java | 30 +- .../tools/PointcutExpressionImpl.java | 64 +++ .../patterns/AbstractPatternNodeVisitor.java | 407 ++++++++++++++++++ .../patterns/AndAnnotationTypePattern.java | 9 +- .../aspectj/weaver/patterns/AndPointcut.java | 13 +- .../weaver/patterns/AndTypePattern.java | 9 +- .../patterns/AnnotationPatternList.java | 10 +- .../weaver/patterns/AnnotationPointcut.java | 7 +- .../patterns/AnnotationTypePattern.java | 4 +- .../patterns/ArgsAnnotationPointcut.java | 6 +- .../aspectj/weaver/patterns/ArgsPointcut.java | 6 +- .../weaver/patterns/BasicTokenSource.java | 8 + .../weaver/patterns/CflowPointcut.java | 20 +- .../patterns/ConcreteCflowPointcut.java | 6 +- .../weaver/patterns/DeclareAnnotation.java | 4 + .../patterns/DeclareErrorOrWarning.java | 5 +- .../weaver/patterns/DeclareParents.java | 25 +- .../weaver/patterns/DeclarePrecedence.java | 4 + .../aspectj/weaver/patterns/DeclareSoft.java | 4 + .../patterns/ExactAnnotationTypePattern.java | 2 +- .../weaver/patterns/ExactTypePattern.java | 4 +- .../weaver/patterns/HandlerPointcut.java | 6 +- .../patterns/IdentityPointcutVisitor.java | 10 +- .../aspectj/weaver/patterns/IfPointcut.java | 6 +- .../weaver/patterns/KindedPointcut.java | 7 +- .../weaver/patterns/ModifiersPattern.java | 2 +- .../aspectj/weaver/patterns/NamePattern.java | 2 +- .../patterns/NotAnnotationTypePattern.java | 8 +- .../aspectj/weaver/patterns/NotPointcut.java | 12 +- .../weaver/patterns/NotTypePattern.java | 9 +- .../patterns/OrAnnotationTypePattern.java | 11 + .../aspectj/weaver/patterns/OrPointcut.java | 13 +- .../weaver/patterns/OrTypePattern.java | 10 +- .../aspectj/weaver/patterns/PatternNode.java | 8 +- ...utVisitor.java => PatternNodeVisitor.java} | 158 +++---- .../weaver/patterns/PatternParser.java | 265 ++++++++---- .../org/aspectj/weaver/patterns/PerCflow.java | 8 + .../aspectj/weaver/patterns/PerFromSuper.java | 8 + .../aspectj/weaver/patterns/PerObject.java | 8 + .../aspectj/weaver/patterns/PerSingleton.java | 8 + .../weaver/patterns/PerTypeWithin.java | 8 + .../org/aspectj/weaver/patterns/Pointcut.java | 20 +- .../weaver/patterns/ReferencePointcut.java | 6 +- .../patterns/ScopeWithTypeVariables.java | 118 +++++ .../weaver/patterns/SignaturePattern.java | 6 +- .../ThisOrTargetAnnotationPointcut.java | 6 +- .../weaver/patterns/ThisOrTargetPointcut.java | 6 +- .../weaver/patterns/ThrowsPattern.java | 2 +- .../aspectj/weaver/patterns/TypePattern.java | 32 +- .../weaver/patterns/TypePatternList.java | 12 +- .../aspectj/weaver/patterns/TypeVariable.java | 216 ++++++++++ .../patterns/TypeVariablePatternList.java | 81 ++++ .../patterns/WildAnnotationTypePattern.java | 2 +- .../weaver/patterns/WildTypePattern.java | 46 +- .../patterns/WithinAnnotationPointcut.java | 7 +- .../WithinCodeAnnotationPointcut.java | 6 +- .../weaver/patterns/WithinPointcut.java | 6 +- .../weaver/patterns/WithincodePointcut.java | 7 +- .../weaver/tools/PointcutExpression.java | 13 + .../weaver/tools/PointcutPrimitive.java | 44 ++ .../weaver/tools/PointcutPrimitives.java | 43 -- ...UnsupportedPointcutPrimitiveException.java | 43 ++ weaver/testdata/dummyAspect.jar | Bin 861 -> 910 bytes weaver/testdata/ltw-acaspects.jar | Bin 2485 -> 2568 bytes weaver/testdata/ltw-aspects.jar | Bin 1508 -> 1592 bytes weaver/testdata/ltw-classes.jar | Bin 1486 -> 1486 bytes weaver/testdata/ltw-deaspects.jar | Bin 1131 -> 1249 bytes weaver/testdata/ltw-dwaspects.jar | Bin 1136 -> 1250 bytes weaver/testdata/ltw-itdaspects.jar | Bin 5469 -> 5815 bytes weaver/testdata/ltw-peraspects.jar | Bin 1916 -> 1922 bytes weaver/testdata/ltw-woven.jar | Bin 2735 -> 2819 bytes weaver/testdata/megatrace.jar | Bin 5890 -> 5584 bytes weaver/testdata/megatrace0easy.jar | Bin 3712 -> 3966 bytes weaver/testdata/megatrace0hard.jar | Bin 3615 -> 3836 bytes weaver/testdata/megatraceNoweave.jar | Bin 3234 -> 3320 bytes weaver/testdata/tracing.jar | Bin 2706 -> 2861 bytes .../weaver/patterns/ParserTestCase.java | 151 +++++++ .../weaver/patterns/PointcutTestCase.java | 8 + .../weaver/patterns/VisitorTestCase.java | 4 +- .../weaver/tools/PointcutExpressionTest.java | 14 + 80 files changed, 1818 insertions(+), 295 deletions(-) create mode 100644 weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java rename weaver/src/org/aspectj/weaver/patterns/{PointcutVisitor.java => PatternNodeVisitor.java} (94%) create mode 100644 weaver/src/org/aspectj/weaver/patterns/ScopeWithTypeVariables.java create mode 100644 weaver/src/org/aspectj/weaver/patterns/TypeVariable.java create mode 100644 weaver/src/org/aspectj/weaver/patterns/TypeVariablePatternList.java create mode 100644 weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java delete mode 100644 weaver/src/org/aspectj/weaver/tools/PointcutPrimitives.java create mode 100644 weaver/src/org/aspectj/weaver/tools/UnsupportedPointcutPrimitiveException.java diff --git a/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java b/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java index a310f0838..f3a8cf88f 100644 --- a/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java +++ b/weaver/src/org/aspectj/weaver/bcel/AtAjAttributes.java @@ -11,6 +11,12 @@ *******************************************************************************/ package org.aspectj.weaver.bcel; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.Field; import org.aspectj.apache.bcel.classfile.JavaClass; @@ -24,46 +30,38 @@ import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations; import org.aspectj.apache.bcel.generic.Type; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.IMessageHandler; -import org.aspectj.bridge.Message; import org.aspectj.bridge.ISourceLocation; -import org.aspectj.bridge.SourceLocation; +import org.aspectj.bridge.Message; import org.aspectj.weaver.Advice; import org.aspectj.weaver.AdviceKind; import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.AjcMemberMaker; +import org.aspectj.weaver.IHasPosition; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.NameMangler; import org.aspectj.weaver.ResolvedPointcutDefinition; import org.aspectj.weaver.ResolvedTypeX; import org.aspectj.weaver.TypeX; -import org.aspectj.weaver.IHasPosition; +import org.aspectj.weaver.patterns.AndPointcut; import org.aspectj.weaver.patterns.DeclareErrorOrWarning; import org.aspectj.weaver.patterns.DeclarePrecedence; import org.aspectj.weaver.patterns.FormalBinding; import org.aspectj.weaver.patterns.IScope; +import org.aspectj.weaver.patterns.IdentityPointcutVisitor; +import org.aspectj.weaver.patterns.IfPointcut; +import org.aspectj.weaver.patterns.NotPointcut; +import org.aspectj.weaver.patterns.OrPointcut; import org.aspectj.weaver.patterns.ParserException; import org.aspectj.weaver.patterns.PatternParser; import org.aspectj.weaver.patterns.PerCflow; import org.aspectj.weaver.patterns.PerClause; +import org.aspectj.weaver.patterns.PerFromSuper; import org.aspectj.weaver.patterns.PerObject; import org.aspectj.weaver.patterns.PerSingleton; import org.aspectj.weaver.patterns.PerTypeWithin; import org.aspectj.weaver.patterns.Pointcut; import org.aspectj.weaver.patterns.SimpleScope; import org.aspectj.weaver.patterns.TypePattern; -import org.aspectj.weaver.patterns.PerFromSuper; -import org.aspectj.weaver.patterns.PointcutVisitor; -import org.aspectj.weaver.patterns.IdentityPointcutVisitor; -import org.aspectj.weaver.patterns.IfPointcut; -import org.aspectj.weaver.patterns.AndPointcut; -import org.aspectj.weaver.patterns.NotPointcut; -import org.aspectj.weaver.patterns.OrPointcut; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.Iterator; -import java.util.List; /** * Annotation defined aspect reader. diff --git a/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java b/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java index 046cf5a61..8757cae3f 100644 --- a/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java +++ b/weaver/src/org/aspectj/weaver/internal/tools/PointcutExpressionImpl.java @@ -15,7 +15,17 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; +import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor; +import org.aspectj.weaver.patterns.ArgsAnnotationPointcut; +import org.aspectj.weaver.patterns.ArgsPointcut; +import org.aspectj.weaver.patterns.CflowPointcut; +import org.aspectj.weaver.patterns.FastMatchInfo; +import org.aspectj.weaver.patterns.IfPointcut; +import org.aspectj.weaver.patterns.NotAnnotationTypePattern; +import org.aspectj.weaver.patterns.NotPointcut; import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut; +import org.aspectj.weaver.patterns.ThisOrTargetPointcut; import org.aspectj.weaver.tools.FuzzyBoolean; import org.aspectj.weaver.tools.PointcutExpression; @@ -31,6 +41,16 @@ public class PointcutExpressionImpl implements PointcutExpression { this.pointcut = pointcut; this.expression = expression; } + + public boolean couldMatchJoinPointsInType(Class aClass) { + return pointcut.fastMatch(aClass).maybeTrue(); + } + + public boolean mayNeedDynamicTest() { + HasPossibleDynamicContentVisitor visitor = new HasPossibleDynamicContentVisitor(); + pointcut.traverse(visitor, null); + return visitor.hasDynamicContent(); + } /* (non-Javadoc) * @see org.aspectj.weaver.tools.PointcutExpression#matchesMethodCall(java.lang.reflect.Method, java.lang.Class, java.lang.Class, java.lang.reflect.Member) @@ -193,6 +213,50 @@ public class PointcutExpressionImpl implements PointcutExpression { throw new IllegalArgumentException("Cant match FuzzyBoolean " + fb); } + private static class HasPossibleDynamicContentVisitor extends AbstractPatternNodeVisitor { + private boolean hasDynamicContent = false; + + public boolean hasDynamicContent() { return hasDynamicContent; } + + public Object visit(ArgsAnnotationPointcut node, Object data) { + hasDynamicContent = true; + return null; + } + + public Object visit(ArgsPointcut node, Object data) { + hasDynamicContent = true; + return null; + } + + public Object visit(CflowPointcut node, Object data) { + hasDynamicContent = true; + return null; + } + + public Object visit(IfPointcut node, Object data) { + hasDynamicContent = true; + return null; + } + + public Object visit(NotAnnotationTypePattern node, Object data) { + return node.getNegatedPattern().accept(this, data); + } + + public Object visit(NotPointcut node, Object data) { + return node.getNegatedPointcut().accept(this, data); + } + + public Object visit(ThisOrTargetAnnotationPointcut node, Object data) { + hasDynamicContent = true; + return null; + } + + public Object visit(ThisOrTargetPointcut node, Object data) { + hasDynamicContent = true; + return null; + } + } + public static class Handler implements Member { private Class decClass; diff --git a/weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java b/weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java new file mode 100644 index 000000000..11c4ea60c --- /dev/null +++ b/weaver/src/org/aspectj/weaver/patterns/AbstractPatternNodeVisitor.java @@ -0,0 +1,407 @@ +/* ******************************************************************* + * 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.patterns; + +import org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut; + +/** + * @author colyer + * + */ +public abstract class AbstractPatternNodeVisitor implements PatternNodeVisitor { + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyTypePattern, java.lang.Object) + */ + public Object visit(AnyTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NoTypePattern, java.lang.Object) + */ + public Object visit(NoTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.EllipsisTypePattern, java.lang.Object) + */ + public Object visit(EllipsisTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyWithAnnotationTypePattern, java.lang.Object) + */ + public Object visit(AnyWithAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnyAnnotationTypePattern, java.lang.Object) + */ + public Object visit(AnyAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.EllipsisAnnotationTypePattern, java.lang.Object) + */ + public Object visit(EllipsisAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndAnnotationTypePattern, java.lang.Object) + */ + public Object visit(AndAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndPointcut, java.lang.Object) + */ + public Object visit(AndPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AndTypePattern, java.lang.Object) + */ + public Object visit(AndTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnnotationPatternList, java.lang.Object) + */ + public Object visit(AnnotationPatternList node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.AnnotationPointcut, java.lang.Object) + */ + public Object visit(AnnotationPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ArgsAnnotationPointcut, java.lang.Object) + */ + public Object visit(ArgsAnnotationPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ArgsPointcut, java.lang.Object) + */ + public Object visit(ArgsPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.BindingAnnotationTypePattern, java.lang.Object) + */ + public Object visit(BindingAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.BindingTypePattern, java.lang.Object) + */ + public Object visit(BindingTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.CflowPointcut, java.lang.Object) + */ + public Object visit(CflowPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ConcreteCflowPointcut, java.lang.Object) + */ + public Object visit(ConcreteCflowPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareAnnotation, java.lang.Object) + */ + public Object visit(DeclareAnnotation node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareErrorOrWarning, java.lang.Object) + */ + public Object visit(DeclareErrorOrWarning node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareParents, java.lang.Object) + */ + public Object visit(DeclareParents node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclarePrecedence, java.lang.Object) + */ + public Object visit(DeclarePrecedence node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.DeclareSoft, java.lang.Object) + */ + public Object visit(DeclareSoft node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ExactAnnotationTypePattern, java.lang.Object) + */ + public Object visit(ExactAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ExactTypePattern, java.lang.Object) + */ + public Object visit(ExactTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.HandlerPointcut, java.lang.Object) + */ + public Object visit(HandlerPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.IfPointcut, java.lang.Object) + */ + public Object visit(IfPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.KindedPointcut, java.lang.Object) + */ + public Object visit(KindedPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ModifiersPattern, java.lang.Object) + */ + public Object visit(ModifiersPattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NamePattern, java.lang.Object) + */ + public Object visit(NamePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotAnnotationTypePattern, java.lang.Object) + */ + public Object visit(NotAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotPointcut, java.lang.Object) + */ + public Object visit(NotPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.NotTypePattern, java.lang.Object) + */ + public Object visit(NotTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrAnnotationTypePattern, java.lang.Object) + */ + public Object visit(OrAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrPointcut, java.lang.Object) + */ + public Object visit(OrPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.OrTypePattern, java.lang.Object) + */ + public Object visit(OrTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerCflow, java.lang.Object) + */ + public Object visit(PerCflow node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerFromSuper, java.lang.Object) + */ + public Object visit(PerFromSuper node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerObject, java.lang.Object) + */ + public Object visit(PerObject node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerSingleton, java.lang.Object) + */ + public Object visit(PerSingleton node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PerTypeWithin, java.lang.Object) + */ + public Object visit(PerTypeWithin node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.PatternNode, java.lang.Object) + */ + public Object visit(PatternNode node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ReferencePointcut, java.lang.Object) + */ + public Object visit(ReferencePointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.SignaturePattern, java.lang.Object) + */ + public Object visit(SignaturePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThisOrTargetAnnotationPointcut, java.lang.Object) + */ + public Object visit(ThisOrTargetAnnotationPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThisOrTargetPointcut, java.lang.Object) + */ + public Object visit(ThisOrTargetPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.ThrowsPattern, java.lang.Object) + */ + public Object visit(ThrowsPattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.TypePatternList, java.lang.Object) + */ + public Object visit(TypePatternList node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WildAnnotationTypePattern, java.lang.Object) + */ + public Object visit(WildAnnotationTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WildTypePattern, java.lang.Object) + */ + public Object visit(WildTypePattern node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinAnnotationPointcut, java.lang.Object) + */ + public Object visit(WithinAnnotationPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinCodeAnnotationPointcut, java.lang.Object) + */ + public Object visit(WithinCodeAnnotationPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithinPointcut, java.lang.Object) + */ + public Object visit(WithinPointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.WithincodePointcut, java.lang.Object) + */ + public Object visit(WithincodePointcut node, Object data) { + return node; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.PointcutVisitor#visit(org.aspectj.weaver.patterns.Pointcut.MatchesNothingPointcut, java.lang.Object) + */ + public Object visit(MatchesNothingPointcut node, Object data) { + return node; + } + + public Object visit(TypeVariable node, Object data) { + return node; + } + + public Object visit(TypeVariablePatternList node, Object data) { + return node; + } +} diff --git a/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java index 077840632..4635051b2 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/AndAnnotationTypePattern.java @@ -89,7 +89,14 @@ public class AndAnnotationTypePattern extends AnnotationTypePattern { public AnnotationTypePattern getLeft() { return left; } public AnnotationTypePattern getRight() { return right; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + left.traverse(visitor,ret); + right.traverse(visitor,ret); + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java b/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java index a688e66b9..e389d5a25 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/AndPointcut.java @@ -51,6 +51,10 @@ public class AndPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return left.fastMatch(type).and(right.fastMatch(type)); } + + public FuzzyBoolean fastMatch(Class targetType) { + return left.fastMatch(targetType).and(right.fastMatch(targetType)); + } protected FuzzyBoolean matchInternal(Shadow shadow) { FuzzyBoolean leftMatch = left.match(shadow); @@ -146,7 +150,14 @@ public class AndPointcut extends Pointcut { return right; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + left.traverse(visitor,ret); + right.traverse(visitor,ret); + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java index cf547c235..bc150b1d3 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/AndTypePattern.java @@ -169,8 +169,15 @@ public class AndTypePattern extends TypePattern { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + left.traverse(visitor, ret); + right.traverse(visitor, ret); + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/AnnotationPatternList.java b/weaver/src/org/aspectj/weaver/patterns/AnnotationPatternList.java index 75dbb73a8..d9cbd07d6 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AnnotationPatternList.java +++ b/weaver/src/org/aspectj/weaver/patterns/AnnotationPatternList.java @@ -177,8 +177,16 @@ public class AnnotationPatternList extends PatternNode { writeLocation(s); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor, data); + for (int i = 0; i < typePatterns.length; i++) { + typePatterns[i].traverse(visitor,ret); + } + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java index 586056a24..17a6da36f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/AnnotationPointcut.java @@ -92,6 +92,11 @@ public class AnnotationPointcut extends NameBindingPointcut { return FuzzyBoolean.MAYBE; } } + + public FuzzyBoolean fastMatch(Class targetType) { + // TODO AMC + return FuzzyBoolean.MAYBE; + } /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) @@ -266,7 +271,7 @@ public class AnnotationPointcut extends NameBindingPointcut { return buf.toString(); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } diff --git a/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java index 831c6f8c4..c814ba0df 100644 --- a/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/AnnotationTypePattern.java @@ -100,7 +100,7 @@ class AnyAnnotationTypePattern extends AnnotationTypePattern { public String toString() { return "@ANY"; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } @@ -121,7 +121,7 @@ class EllipsisAnnotationTypePattern extends AnnotationTypePattern { public String toString() { return ".."; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } diff --git a/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java index f60f64446..de271b5f5 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ArgsAnnotationPointcut.java @@ -63,6 +63,10 @@ public class ArgsAnnotationPointcut extends NameBindingPointcut { public FuzzyBoolean fastMatch(FastMatchInfo info) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) @@ -221,7 +225,7 @@ public class ArgsAnnotationPointcut extends NameBindingPointcut { return buf.toString(); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java index eebacd084..5001fd06c 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java @@ -69,6 +69,10 @@ public class ArgsPointcut extends NameBindingPointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } protected FuzzyBoolean matchInternal(Shadow shadow) { FuzzyBoolean ret = @@ -308,7 +312,7 @@ public class ArgsPointcut extends NameBindingPointcut { return "args" + arguments.toString() + ""; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java b/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java index a11413539..1ae2c38fe 100644 --- a/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java +++ b/weaver/src/org/aspectj/weaver/patterns/BasicTokenSource.java @@ -104,6 +104,9 @@ public class BasicTokenSource implements ITokenSource { case '!': case ':': case '@': + case '<': + case '>': + case '?': tokens.add(BasicToken.makeOperator(makeString(ch), i-1, i-1)); continue; case '.': @@ -123,6 +126,11 @@ public class BasicTokenSource implements ITokenSource { } continue; case '&': + if ((i+1) <= chars.length && chars[i] != '&') { + tokens.add(BasicToken.makeOperator(makeString(ch),i-1,i-1)); + continue; + } + // fall-through case '|': if (i == chars.length) { throw new BCException("bad " + ch); diff --git a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java index 4c1c13d7b..13ed1b6f6 100644 --- a/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/CflowPointcut.java @@ -44,7 +44,7 @@ import org.aspectj.weaver.ast.Test; public class CflowPointcut extends Pointcut { private Pointcut entry; // The pointcut inside the cflow() that represents the 'entry' point - private boolean isBelow;// Is this cflowbelow? + boolean isBelow;// Is this cflowbelow? private int[] freeVars; private static Hashtable cflowFields = new Hashtable(); @@ -68,9 +68,12 @@ public class CflowPointcut extends Pointcut { this.pointcutKind = CFLOW; } - public boolean isBelow() { - return isBelow; - } + /** + * @return Returns true is this is a cflowbelow pointcut + */ + public boolean isCflowBelow() { + return isBelow; + } public Set couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS; @@ -84,6 +87,10 @@ public class CflowPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } protected FuzzyBoolean matchInternal(Shadow shadow) { //??? this is not maximally efficient @@ -312,8 +319,7 @@ public class CflowPointcut extends Pointcut { } } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); - } - + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java index 360b6456f..f704d7305 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ConcreteCflowPointcut.java @@ -51,6 +51,10 @@ public class ConcreteCflowPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } protected FuzzyBoolean matchInternal(Shadow shadow) { //??? this is not maximally efficient @@ -140,7 +144,7 @@ public class ConcreteCflowPointcut extends Pointcut { throw new RuntimeException("unimplemented"); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java b/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java index 55db910a7..a3913f735 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareAnnotation.java @@ -99,6 +99,10 @@ public class DeclareAnnotation extends Declare { return ret.toString(); } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public void resolve(IScope scope) { if (typePattern != null) { typePattern = typePattern.resolveBindings(scope,Bindings.NONE,false,false); diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareErrorOrWarning.java b/weaver/src/org/aspectj/weaver/patterns/DeclareErrorOrWarning.java index a3bebe50c..a053ae8e1 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareErrorOrWarning.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareErrorOrWarning.java @@ -58,7 +58,10 @@ public class DeclareErrorOrWarning extends Declare { return result; } - + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public void write(DataOutputStream s) throws IOException { s.writeByte(Declare.ERROR_OR_WARNING); s.writeBoolean(isError); diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java b/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java index 3607afe7d..ef228d43d 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareParents.java @@ -20,6 +20,7 @@ import java.util.Collections; import java.util.List; import org.aspectj.bridge.IMessage; +import org.aspectj.weaver.AjAttribute; import org.aspectj.weaver.ISourceContext; import org.aspectj.weaver.ResolvedTypeX; import org.aspectj.weaver.TypeX; @@ -31,6 +32,7 @@ public class DeclareParents extends Declare { private TypePattern child; private TypePatternList parents; private boolean isWildChild = false; + private TypeVariablePatternList typeVariablesInScope = TypeVariablePatternList.EMPTY; // AspectJ 5 extension for generic types public DeclareParents(TypePattern child, List parents) { @@ -43,6 +45,14 @@ public class DeclareParents extends Declare { if (child instanceof WildTypePattern) isWildChild = true; } + public TypeVariablePatternList getTypeParameters() { + return this.typeVariablesInScope; + } + + public void setTypeParameters(TypeVariablePatternList typeParameters) { + this.typeVariablesInScope = typeParameters; + } + public boolean match(ResolvedTypeX typeX) { if (!child.matchesStatically(typeX)) return false; if (typeX.getWorld().getLint().typeNotExposedToWeaver.isEnabled() && @@ -54,6 +64,10 @@ public class DeclareParents extends Declare { return true; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("declare parents: "); @@ -83,11 +97,15 @@ public class DeclareParents extends Declare { s.writeByte(Declare.PARENTS); child.write(s); parents.write(s); + typeVariablesInScope.write(s); // change to binary form in AJ 5 writeLocation(s); } public static Declare read(VersionedDataInputStream s, ISourceContext context) throws IOException { - Declare ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context)); + DeclareParents ret = new DeclareParents(TypePattern.read(s, context), TypePatternList.read(s, context)); + if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) { + ret.setTypeParameters(TypeVariablePatternList.read(s,context)); + } ret.readLocation(context, s); return ret; } @@ -106,8 +124,9 @@ public class DeclareParents extends Declare { } public void resolve(IScope scope) { - child = child.resolveBindings(scope, Bindings.NONE, false, false); - parents = parents.resolveBindings(scope, Bindings.NONE, false, true); + ScopeWithTypeVariables resolutionScope = new ScopeWithTypeVariables(typeVariablesInScope,scope); + child = child.resolveBindings(resolutionScope, Bindings.NONE, false, false); + parents = parents.resolveBindings(resolutionScope, Bindings.NONE, false, true); // Could assert this ... // for (int i=0; i < parents.size(); i++) { diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclarePrecedence.java b/weaver/src/org/aspectj/weaver/patterns/DeclarePrecedence.java index 0bc548c8c..2dd5fb83d 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclarePrecedence.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclarePrecedence.java @@ -35,6 +35,10 @@ public class DeclarePrecedence extends Declare { this.patterns = patterns; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("declare precedence: "); diff --git a/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java b/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java index a7bb8fade..9ed15111f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java +++ b/weaver/src/org/aspectj/weaver/patterns/DeclareSoft.java @@ -32,6 +32,10 @@ public class DeclareSoft extends Declare { this.pointcut = pointcut; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public String toString() { StringBuffer buf = new StringBuffer(); buf.append("declare soft: "); diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java index 8e980203e..a93cab6bb 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ExactAnnotationTypePattern.java @@ -226,7 +226,7 @@ public class ExactAnnotationTypePattern extends AnnotationTypePattern { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java index eb3cececa..5703251a8 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java @@ -208,6 +208,7 @@ public class ExactTypePattern extends TypePattern { out.writeBoolean(includeSubtypes); out.writeBoolean(isVarArgs); annotationPattern.write(out); + typeParameters.write(out); writeLocation(out); } @@ -224,6 +225,7 @@ public class ExactTypePattern extends TypePattern { if (version > EXACT_VERSION) throw new BCException("ExactTypePattern was written by a more recent version of AspectJ"); TypePattern ret = new ExactTypePattern(TypeX.read(s), s.readBoolean(), s.readBoolean()); ret.setAnnotationTypePattern(AnnotationTypePattern.read(s,context)); + ret.setTypeParameters(TypePatternList.read(s,context)); ret.readLocation(context, s); return ret; } @@ -262,7 +264,7 @@ public class ExactTypePattern extends TypePattern { throw new IllegalStateException("trying to re-resolve"); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } diff --git a/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java b/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java index 8cc32353c..9f8752ad1 100644 --- a/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/HandlerPointcut.java @@ -58,6 +58,10 @@ public class HandlerPointcut extends Pointcut { return FuzzyBoolean.MAYBE; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } + protected FuzzyBoolean matchInternal(Shadow shadow) { if (shadow.getKind() != Shadow.ExceptionHandler) return FuzzyBoolean.NO; @@ -157,7 +161,7 @@ public class HandlerPointcut extends Pointcut { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java b/weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java index a05fe013f..90a302d1b 100644 --- a/weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java +++ b/weaver/src/org/aspectj/weaver/patterns/IdentityPointcutVisitor.java @@ -14,7 +14,7 @@ package org.aspectj.weaver.patterns; /** * @author Alexandre Vasseur */ -public class IdentityPointcutVisitor implements PointcutVisitor { +public class IdentityPointcutVisitor implements PatternNodeVisitor { public Object visit(AnyTypePattern node, Object data) { return node; @@ -231,4 +231,12 @@ public class IdentityPointcutVisitor implements PointcutVisitor { public Object visit(Pointcut.MatchesNothingPointcut node, Object data) { return node; } + + public Object visit(TypeVariable node, Object data) { + return node; + } + + public Object visit(TypeVariablePatternList node, Object data) { + return node; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java index 9aa1246f2..d6cf9fa84 100644 --- a/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/IfPointcut.java @@ -79,6 +79,10 @@ public class IfPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } protected FuzzyBoolean matchInternal(Shadow shadow) { //??? this is not maximally efficient @@ -383,7 +387,7 @@ public class IfPointcut extends Pointcut { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } diff --git a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java index 8951931f6..f6c4ef835 100644 --- a/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/KindedPointcut.java @@ -98,6 +98,11 @@ public class KindedPointcut extends Pointcut { return FuzzyBoolean.MAYBE; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.fromBoolean(signature.couldMatch(targetType)); + } + + protected FuzzyBoolean matchInternal(Shadow shadow) { if (shadow.getKind() != kind) return FuzzyBoolean.NO; @@ -314,7 +319,7 @@ public class KindedPointcut extends Pointcut { return kind; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ModifiersPattern.java b/weaver/src/org/aspectj/weaver/patterns/ModifiersPattern.java index a3f5eedce..f1543af1e 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ModifiersPattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ModifiersPattern.java @@ -93,7 +93,7 @@ public class ModifiersPattern extends PatternNode { return flag.intValue(); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/NamePattern.java b/weaver/src/org/aspectj/weaver/patterns/NamePattern.java index a2879b1ea..45f4b154a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/NamePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/NamePattern.java @@ -158,7 +158,7 @@ public class NamePattern extends PatternNode { return starCount == 1 && pattern.length == 1; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java index 37acaa16b..5e0293158 100644 --- a/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/NotAnnotationTypePattern.java @@ -84,7 +84,13 @@ public class NotAnnotationTypePattern extends AnnotationTypePattern { return negatedPattern; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + negatedPattern.traverse(visitor,ret); + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java index 47baa7acf..f042f0f82 100644 --- a/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/NotPointcut.java @@ -49,6 +49,10 @@ public class NotPointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return body.fastMatch(type).not(); } + + public FuzzyBoolean fastMatch(Class targetType) { + return body.fastMatch(targetType).not(); + } protected FuzzyBoolean matchInternal(Shadow shadow) { return body.match(shadow).not(); @@ -133,8 +137,14 @@ public class NotPointcut extends Pointcut { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + this.body.traverse(visitor,ret); + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java index e8dba6cb2..7affe0aa3 100644 --- a/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/NotTypePattern.java @@ -150,7 +150,14 @@ public class NotTypePattern extends TypePattern { return 17 + 37 * negatedPattern.hashCode(); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + negatedPattern.traverse(visitor, ret); + return ret; + } + } diff --git a/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java index 6bdf616e4..562fafe00 100644 --- a/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/OrAnnotationTypePattern.java @@ -48,6 +48,17 @@ public class OrAnnotationTypePattern extends AnnotationTypePattern { return this; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + left.traverse(visitor,ret); + right.traverse(visitor,ret); + return ret; + } + public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException { AnnotationTypePattern p = new OrAnnotationTypePattern( AnnotationTypePattern.read(s,context), diff --git a/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java b/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java index 12abd441b..13317fe38 100644 --- a/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/OrPointcut.java @@ -50,6 +50,10 @@ public class OrPointcut extends Pointcut { return left.fastMatch(type).or(right.fastMatch(type)); } + public FuzzyBoolean fastMatch(Class targetType) { + return left.fastMatch(targetType).or(right.fastMatch(targetType)); + } + protected FuzzyBoolean matchInternal(Shadow shadow) { FuzzyBoolean leftMatch = left.match(shadow); if (leftMatch.alwaysTrue()) return leftMatch; @@ -148,7 +152,14 @@ public class OrPointcut extends Pointcut { return right; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + left.traverse(visitor, ret); + right.traverse(visitor,ret); + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java index 16fe35872..3355ea508 100644 --- a/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/OrTypePattern.java @@ -176,7 +176,15 @@ public class OrTypePattern extends TypePattern { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + left.traverse(visitor, ret); + right.traverse(visitor, ret); + return ret; + } + } diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternNode.java b/weaver/src/org/aspectj/weaver/patterns/PatternNode.java index 817064123..518446a04 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PatternNode.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternNode.java @@ -81,7 +81,9 @@ public abstract class PatternNode implements IHasSourceLocation { this.sourceContext = context; } - public Object accept(PointcutVisitor visitor, Object data) { - return visitor.visit(this, data); - } + public abstract Object accept(PatternNodeVisitor visitor, Object data); + + public Object traverse(PatternNodeVisitor visitor, Object data) { + return accept(visitor,data); + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java b/weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java similarity index 94% rename from weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java rename to weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java index 1abf102ff..87a61a694 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PointcutVisitor.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternNodeVisitor.java @@ -8,6 +8,7 @@ * * Contributors: * Alexandre Vasseur initial implementation + * Adrian Colyer refactoring for traversal and grouping by kind *******************************************************************************/ package org.aspectj.weaver.patterns; @@ -18,122 +19,85 @@ import org.aspectj.weaver.Member; * * @author Alexandre Vasseur */ -public interface PointcutVisitor { - - Object visit(AnyTypePattern node, Object data); - - Object visit(NoTypePattern node, Object data); - - Object visit(EllipsisTypePattern node, Object data); - - Object visit(AnyWithAnnotationTypePattern node, Object data); +public interface PatternNodeVisitor { + // Annotation type patterns + Object visit(AndAnnotationTypePattern node, Object data); Object visit(AnyAnnotationTypePattern node, Object data); - Object visit(EllipsisAnnotationTypePattern node, Object data); - - Object visit(AndAnnotationTypePattern node, Object data); - - Object visit(AndPointcut node, Object data); - - Object visit(AndTypePattern node, Object data); - - Object visit(AnnotationPatternList node, Object data); - - Object visit(AnnotationPointcut node, Object data); - - Object visit(ArgsAnnotationPointcut node, Object data); - - Object visit(ArgsPointcut node, Object data); - + Object visit(ExactAnnotationTypePattern node, Object data); Object visit(BindingAnnotationTypePattern node, Object data); + Object visit(NotAnnotationTypePattern node, Object data); + Object visit(OrAnnotationTypePattern node, Object data); + Object visit(WildAnnotationTypePattern node, Object data); + Object visit(AnnotationPatternList node, Object data); + // Regular type patterns + Object visit(AndTypePattern node, Object data); + Object visit(AnyTypePattern node, Object data); + Object visit(AnyWithAnnotationTypePattern node, Object data); + Object visit(EllipsisTypePattern node, Object data); + Object visit(ExactTypePattern node, Object data); Object visit(BindingTypePattern node, Object data); + Object visit(NotTypePattern node, Object data); + Object visit(NoTypePattern node, Object data); + Object visit(OrTypePattern node, Object data); + Object visit(WildTypePattern node, Object data); + Object visit(TypePatternList node, Object data); + // Pointcuts + Object visit(AndPointcut node, Object data); Object visit(CflowPointcut node, Object data); - Object visit(ConcreteCflowPointcut node, Object data); - - Object visit(DeclareAnnotation node, Object data); - - Object visit(DeclareErrorOrWarning node, Object data); - - Object visit(DeclareParents node, Object data); - - Object visit(DeclarePrecedence node, Object data); - - Object visit(DeclareSoft node, Object data); - - Object visit(ExactAnnotationTypePattern node, Object data); - - Object visit(ExactTypePattern node, Object data); - Object visit(HandlerPointcut node, Object data); - Object visit(IfPointcut node, Object data); - Object visit(KindedPointcut node, Object data); - - Object visit(ModifiersPattern node, Object data); - - Object visit(NamePattern node, Object data); - - Object visit(NotAnnotationTypePattern node, Object data); - + Object visit(Pointcut.MatchesNothingPointcut node, Object data); + Object visit(AnnotationPointcut node, Object data); + Object visit(ArgsAnnotationPointcut node, Object data); + Object visit(ArgsPointcut node, Object data); + Object visit(ThisOrTargetAnnotationPointcut node, Object data); + Object visit(ThisOrTargetPointcut node, Object data); + Object visit(WithinAnnotationPointcut node, Object data); + Object visit(WithinCodeAnnotationPointcut node, Object data); Object visit(NotPointcut node, Object data); - - Object visit(NotTypePattern node, Object data); - - Object visit(OrAnnotationTypePattern node, Object data); - Object visit(OrPointcut node, Object data); + Object visit(ReferencePointcut node, Object data); + Object visit(WithinPointcut node, Object data); + Object visit(WithincodePointcut node, Object data); - Object visit(OrTypePattern node, Object data); - + // Per-clauses Object visit(PerCflow node, Object data); - Object visit(PerFromSuper node, Object data); - Object visit(PerObject node, Object data); - Object visit(PerSingleton node, Object data); - Object visit(PerTypeWithin node, Object data); - Object visit(PatternNode node, Object data); - - Object visit(ReferencePointcut node, Object data); + + // Declares + Object visit(DeclareAnnotation node, Object data); + Object visit(DeclareErrorOrWarning node, Object data); + Object visit(DeclareParents node, Object data); + Object visit(DeclarePrecedence node, Object data); + Object visit(DeclareSoft node, Object data); + // Miscellaneous patterns + Object visit(ModifiersPattern node, Object data); + Object visit(NamePattern node, Object data); Object visit(SignaturePattern node, Object data); - - Object visit(ThisOrTargetAnnotationPointcut node, Object data); - - Object visit(ThisOrTargetPointcut node, Object data); - Object visit(ThrowsPattern node, Object data); + Object visit(TypeVariable node, Object data); + Object visit(TypeVariablePatternList node,Object data); - Object visit(TypePatternList node, Object data); - - Object visit(WildAnnotationTypePattern node, Object data); - - Object visit(WildTypePattern node, Object data); - - Object visit(WithinAnnotationPointcut node, Object data); - - Object visit(WithinCodeAnnotationPointcut node, Object data); - - Object visit(WithinPointcut node, Object data); - - Object visit(WithincodePointcut node, Object data); - - Object visit(Pointcut.MatchesNothingPointcut node, Object data); + // Catch-all + Object visit(PatternNode node, Object data); /** * A sample toString like visitor that helps understanding the AST tree structure organization * * @author Alexandre Vasseur */ - static class DumpPointcutVisitor implements PointcutVisitor { + static class DumpPointcutVisitor implements PatternNodeVisitor { private StringBuffer sb = new StringBuffer(); public String get() { @@ -259,7 +223,7 @@ public interface PointcutVisitor { } public Object visit(CflowPointcut node, Object data) { - append(node.isBelow()?"cflowbelow(":"cflow("); + append(node.isCflowBelow()?"cflowbelow(":"cflow("); node.getEntry().accept(this, data); append(')'); return null; @@ -584,6 +548,16 @@ public interface PointcutVisitor { append(node); return null; } + + public Object visit(TypeVariable node, Object data) { + append(node); + return null; + } + + public Object visit(TypeVariablePatternList node, Object data) { + append(node); + return null; + } public static void check(String s) { check(Pointcut.fromString(s), false); @@ -610,13 +584,11 @@ public interface PointcutVisitor { 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)", -// "staticinitialization(!@(Immutable) *)" -// "execution(* *()) && if()", - "(if(true) && set(int BaseApp.i))" + //"@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++) { diff --git a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java index d63484e0f..deb98242f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PatternParser.java +++ b/weaver/src/org/aspectj/weaver/patterns/PatternParser.java @@ -179,7 +179,8 @@ public class PatternParser { } private Declare parseParents() { - TypePattern p = parseTypePattern(); + TypeVariablePatternList typeParameters = maybeParseTypeVariableList(); + TypePattern p = parseTypePattern(false,false); IToken t = tokenSource.next(); if (!(t.getString().equals("extends") || t.getString().equals("implements"))) { throw new ParserException("extends or implements", t); @@ -192,7 +193,11 @@ public class PatternParser { //XXX somewhere in the chain we need to enforce that we have only ExactTypePatterns - return new DeclareParents(p, l); + DeclareParents decp = new DeclareParents(p, l); + if (typeParameters != null) { + decp.setTypeParameters(typeParameters); + } + return decp; } private Declare parseSoft() { @@ -269,26 +274,28 @@ public class PatternParser { } String kind = parseIdentifier(); + IToken possibleTypeVariableToken = tokenSource.peek(); + TypeVariablePatternList typeVariables = maybeParseSimpleTypeVariableList(); tokenSource.setIndex(start); if (kind.equals("execution") || kind.equals("call") || kind.equals("get") || kind.equals("set")) { - return parseKindedPointcut(); + p = parseKindedPointcut(); } else if (kind.equals("args")) { - return parseArgsPointcut(); + p = parseArgsPointcut(); } else if (kind.equals("this") || kind.equals("target")) { - return parseThisOrTargetPointcut(); + p = parseThisOrTargetPointcut(); } else if (kind.equals("within")) { - return parseWithinPointcut(); + p = parseWithinPointcut(); } else if (kind.equals("withincode")) { - return parseWithinCodePointcut(); + p = parseWithinCodePointcut(); } else if (kind.equals("cflow")) { - return parseCflowPointcut(false); + p = parseCflowPointcut(false); } else if (kind.equals("cflowbelow")) { - return parseCflowPointcut(true); + p = parseCflowPointcut(true); } else if (kind.equals("adviceexecution")) { parseIdentifier(); eat("("); eat(")"); - return new KindedPointcut(Shadow.AdviceExecution, + p = new KindedPointcut(Shadow.AdviceExecution, new SignaturePattern(Member.ADVICE, ModifiersPattern.ANY, TypePattern.ANY, TypePattern.ANY, NamePattern.ANY, TypePatternList.ANY, @@ -296,57 +303,50 @@ public class PatternParser { AnnotationTypePattern.ANY)); } else if (kind.equals("handler")) { parseIdentifier(); eat("("); - TypePattern typePat = parseTypePattern(); + TypePattern typePat = parseTypePattern(false,true); eat(")"); - return new HandlerPointcut(typePat); + p = new HandlerPointcut(typePat); } else if (kind.equals("initialization")) { parseIdentifier(); eat("("); SignaturePattern sig = parseConstructorSignaturePattern(); eat(")"); - return new KindedPointcut(Shadow.Initialization, sig); + p = new KindedPointcut(Shadow.Initialization, sig); } else if (kind.equals("staticinitialization")) { parseIdentifier(); eat("("); - TypePattern typePat = parseTypePattern(); + TypePattern typePat = parseTypePattern(false,true); eat(")"); - return new KindedPointcut(Shadow.StaticInitialization, + p = new KindedPointcut(Shadow.StaticInitialization, new SignaturePattern(Member.STATIC_INITIALIZATION, ModifiersPattern.ANY, TypePattern.ANY, typePat, NamePattern.ANY, TypePatternList.EMPTY, ThrowsPattern.ANY,AnnotationTypePattern.ANY)); - } else if (kind.equals("preinitialization")) { + } else if (kind.equals("preinitialization")) { parseIdentifier(); eat("("); SignaturePattern sig = parseConstructorSignaturePattern(); eat(")"); - return new KindedPointcut(Shadow.PreInitialization, sig); - } else if (kind.equals("if")) { - //@style support - parseIdentifier(); - eat("("); - if (maybeEat("true")) { - eat(")"); - return new IfPointcut.IfTruePointcut(); - } else if (maybeEat("false")) { - eat(")"); - return new IfPointcut.IfFalsePointcut(); - } else { - //TODO AV - true/false stuff needed ? What are the token here ? - eat(")"); - // build a readable pointcut as an hint (toString() dumps raw token array into an horrible thing) - StringBuffer sb = new StringBuffer(); - int currentIndex = tokenSource.getIndex(); - try { - tokenSource.setIndex(0); - for (int i = 0; !IToken.EOF.equals(tokenSource.peek(i)); i++) { - if (i > 0) sb.append(' '); - sb.append(tokenSource.peek(i).getString()); - } - } finally { - tokenSource.setIndex(currentIndex); - } - return new IfPointcut(sb.toString()); - } - } else { - return parseReferencePointcut(); + p = new KindedPointcut(Shadow.PreInitialization, sig); + } else if (kind.equals("if")) { + // @style support allows if(), if(true), if(false) + parseIdentifier(); + eat("("); + if (maybeEatIdentifier("true")) { + eat(")"); + p = new IfPointcut.IfTruePointcut(); + } else if (maybeEatIdentifier("false")) { + eat(")"); + p = new IfPointcut.IfFalsePointcut(); + } else { + eat(")"); + // TODO - Alex has some token stuff going on here to get a readable name in place of ""... + p = new IfPointcut(""); + } } + else { + p = parseReferencePointcut(); + if (typeVariables != null) + throw new ParserException("type variable specification not allowed for reference pointcuts",possibleTypeVariableToken); + } + if (typeVariables != null) p.setTypeVariables(typeVariables); + return p; } public Pointcut parseAnnotationPointcut() { @@ -538,36 +538,40 @@ public class PatternParser { } public TypePattern parseTypePattern() { - TypePattern p = parseAtomicTypePattern(); + return parseTypePattern(false,false); + } + + public TypePattern parseTypePattern(boolean insideTypeParameters, boolean allowTypeVariableDeclarations) { + TypePattern p = parseAtomicTypePattern(insideTypeParameters,allowTypeVariableDeclarations); if (maybeEat("&&")) { - p = new AndTypePattern(p, parseNotOrTypePattern()); + p = new AndTypePattern(p, parseNotOrTypePattern(insideTypeParameters,allowTypeVariableDeclarations)); } if (maybeEat("||")) { - p = new OrTypePattern(p, parseTypePattern()); + p = new OrTypePattern(p, parseTypePattern(insideTypeParameters,allowTypeVariableDeclarations)); } return p; } - private TypePattern parseNotOrTypePattern() { - TypePattern p = parseAtomicTypePattern(); + private TypePattern parseNotOrTypePattern(boolean insideTypeParameters,boolean allowTypeVariableDeclarations) { + TypePattern p = parseAtomicTypePattern(insideTypeParameters,allowTypeVariableDeclarations); if (maybeEat("&&")) { - p = new AndTypePattern(p, parseTypePattern()); + p = new AndTypePattern(p, parseTypePattern(insideTypeParameters,allowTypeVariableDeclarations)); } return p; } - private TypePattern parseAtomicTypePattern() { + private TypePattern parseAtomicTypePattern(boolean insideTypeParameters, boolean allowTypeVariableDeclarations) { AnnotationTypePattern ap = maybeParseAnnotationPattern(); if (maybeEat("!")) { //int startPos = tokenSource.peek(-1).getStart(); //??? we lose source location for true start of !type - TypePattern p = new NotTypePattern(parseAtomicTypePattern()); + TypePattern p = new NotTypePattern(parseAtomicTypePattern(insideTypeParameters,allowTypeVariableDeclarations)); p = setAnnotationPatternForTypePattern(p,ap); return p; } if (maybeEat("(")) { - TypePattern p = parseTypePattern(); + TypePattern p = parseTypePattern(insideTypeParameters,allowTypeVariableDeclarations); p = setAnnotationPatternForTypePattern(p,ap); eat(")"); boolean isVarArgs = maybeEat("..."); @@ -575,7 +579,7 @@ public class PatternParser { return p; } int startPos = tokenSource.peek().getStart(); - TypePattern p = parseSingleTypePattern(); + TypePattern p = parseSingleTypePattern(insideTypeParameters,allowTypeVariableDeclarations); int endPos = tokenSource.peek(-1).getEnd(); p = setAnnotationPatternForTypePattern(p,ap); p.setLocation(sourceContext, startPos, endPos); @@ -586,7 +590,7 @@ public class PatternParser { TypePattern ret = t; if (ap != AnnotationTypePattern.ANY) { if (t == TypePattern.ANY) { - ret = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0,false); + ret = new WildTypePattern(new NamePattern[] {NamePattern.ANY},false,0,false,null); } if (t.annotationPattern == AnnotationTypePattern.ANY) { ret.setAnnotationTypePattern(ap); @@ -649,17 +653,27 @@ public class PatternParser { } public TypePattern parseSingleTypePattern() { + return parseSingleTypePattern(false, false); + } + + public TypePattern parseSingleTypePattern(boolean insideTypeParameters, boolean allowTypeVariableDeclarations) { + if (insideTypeParameters && maybeEat("?")) return parseGenericsWildcardTypePattern(); + List names = parseDottedNamePattern(); -// new ArrayList(); -// NamePattern p1 = parseNamePattern(); -// names.add(p1); -// while (maybeEat(".")) { -// if (maybeEat(".")) { -// names.add(NamePattern.ELLIPSIS); -// } -// NamePattern p2 = parseNamePattern(); -// names.add(p2); -// } + + TypePattern upperBound = null; + TypePattern[] additionalInterfaceBounds = new TypePattern[0]; + TypePattern lowerBound = null; + if ((names.size() == 1) && allowTypeVariableDeclarations) { + if (maybeEatIdentifier("extends")) { + upperBound = parseTypePattern(false,false); + additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds(); + } + if (maybeEatIdentifier("super")) { + lowerBound = parseTypePattern(false,false); + } + } + int dim = 0; while (maybeEat("[")) { eat("]"); @@ -669,10 +683,14 @@ public class PatternParser { boolean isVarArgs = maybeEat("..."); boolean includeSubtypes = maybeEat("+"); + + TypePatternList typeParameters = maybeParseTypeParameterList(allowTypeVariableDeclarations); int endPos = tokenSource.peek(-1).getEnd(); //??? what about the source location of any's???? - if (names.size() == 1 && ((NamePattern)names.get(0)).isAny() && dim == 0 && !isVarArgs) return TypePattern.ANY; + if (names.size() == 1 && ((NamePattern)names.get(0)).isAny() && + dim == 0 && !isVarArgs && typeParameters == null && upperBound == null && + lowerBound == null) return TypePattern.ANY; // Notice we increase the dimensions if varargs is set. this is to allow type matching to // succeed later: The actual signature at runtime of a method declared varargs is an array type of @@ -680,10 +698,26 @@ public class PatternParser { // pattern 'Integer...' we create a WildTypePattern 'Integer[]' with varargs set. If this matches // during shadow matching, we confirm that the varargs flags match up before calling it a successful // match. - return new WildTypePattern(names, includeSubtypes, dim+(isVarArgs?1:0), endPos,isVarArgs); + return new WildTypePattern(names, includeSubtypes, dim+(isVarArgs?1:0), endPos,isVarArgs,typeParameters, + upperBound,additionalInterfaceBounds,lowerBound); } - + public TypePattern parseGenericsWildcardTypePattern() { + List names = new ArrayList(); + names.add(new NamePattern("?")); + TypePattern upperBound = null; + TypePattern[] additionalInterfaceBounds = new TypePattern[0]; + TypePattern lowerBound = null; + if (maybeEatIdentifier("extends")) { + upperBound = parseTypePattern(false,false); + additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds(); + } + if (maybeEatIdentifier("super")) { + lowerBound = parseTypePattern(false,false); + } + int endPos = tokenSource.peek(-1).getEnd(); + return new WildTypePattern(names,false,0,endPos,false,null,upperBound,additionalInterfaceBounds,lowerBound); + } // private AnnotationTypePattern completeAnnotationPattern(AnnotationTypePattern p) { // if (maybeEat("&&")) { @@ -797,9 +831,9 @@ public class PatternParser { if (previous != null) { if (!isAdjacent(previous, tok)) break; } - if ("*".equals(tok.getString()) || (tok.isIdentifier() && !"...".equals(tok.getString()))) { + if (tok.getString() == "*" || (tok.isIdentifier() && tok.getString()!="...")) { buf.append(tok.getString()); - } else if ("...".equals(tok.getString())) { + } else if (tok.getString()=="...") { break; } else if (tok.getLiteralKind() != null) { //System.err.println("literal kind: " + tok.getString()); @@ -869,7 +903,7 @@ public class PatternParser { if (previous != null) { if (!isAdjacent(previous, tok)) break; } - if (tok.getString().equals("*") || tok.isIdentifier()) { + if (tok.getString() == "*" || tok.isIdentifier()) { buf.append(tok.getString()); } else if (tok.getLiteralKind() != null) { //System.err.println("literal kind: " + tok.getString()); @@ -1067,6 +1101,9 @@ public class PatternParser { public SignaturePattern parseFieldSignaturePattern() { int startPos = tokenSource.peek().getStart(); + + // TypePatternList followMe = TypePatternList.ANY; + AnnotationTypePattern annotationPattern = maybeParseAnnotationPattern(); ModifiersPattern modifiers = parseModifiersPattern(); TypePattern returnType = parseTypePattern(); @@ -1100,6 +1137,82 @@ public class PatternParser { return null; } } + + /** + * Parse type variable declarations for a generic method or at the start of a signature pointcut to identify + * type variable names in a generic type. + * @param includeParameterizedTypes + * @return + */ + public TypeVariablePatternList maybeParseTypeVariableList() { + if (!maybeEat("<")) return null; + List typeVars = new ArrayList(); + TypeVariable t = parseTypeVariable(); + typeVars.add(t); + while (maybeEat(",")) { + TypeVariable nextT = parseTypeVariable(); + typeVars.add(nextT); + } + eat(">"); + TypeVariable[] tvs = new TypeVariable[typeVars.size()]; + typeVars.toArray(tvs); + return new TypeVariablePatternList(tvs); + } + + // of the form execution - allows identifiers only + public TypeVariablePatternList maybeParseSimpleTypeVariableList() { + if (!maybeEat("<")) return null; + List typeVars = new ArrayList(); + do { + String typeVarName = parseIdentifier(); + TypeVariable tv = new TypeVariable(typeVarName); + typeVars.add(tv); + } while (maybeEat(",")); + eat(">"); + TypeVariable[] tvs = new TypeVariable[typeVars.size()]; + typeVars.toArray(tvs); + return new TypeVariablePatternList(tvs); + } + + public TypePatternList maybeParseTypeParameterList(boolean allowTypeVariables) { + if (!maybeEat("<")) return null; + List typePats = new ArrayList(); + do { + TypePattern tp = parseTypePattern(true,allowTypeVariables); + typePats.add(tp); + } while(maybeEat(",")); + eat(">"); + TypePattern[] tps = new TypePattern[typePats.size()]; + typePats.toArray(tps); + return new TypePatternList(tps); + } + + public TypeVariable parseTypeVariable() { + TypePattern upperBound = null; + TypePattern[] additionalInterfaceBounds = null; + TypePattern lowerBound = null; + String typeVariableName = null; + if (typeVariableName == null) typeVariableName = parseIdentifier(); + if (maybeEatIdentifier("extends")) { + upperBound = parseTypePattern(); + additionalInterfaceBounds = maybeParseAdditionalInterfaceBounds(); + } else if (maybeEatIdentifier("super")) { + lowerBound = parseTypePattern(); + } + return new TypeVariable(typeVariableName,upperBound,additionalInterfaceBounds,lowerBound); + } + + private TypePattern[] maybeParseAdditionalInterfaceBounds() { + List boundsList = new ArrayList(); + while (maybeEat("&")) { + TypePattern tp = parseTypePattern(); + boundsList.add(tp); + } + if (boundsList.size() == 0) return null; + TypePattern[] ret = new TypePattern[boundsList.size()]; + boundsList.toArray(ret); + return ret; + } public String parsePossibleStringSequence(boolean shouldEnd) { StringBuffer result = new StringBuffer(); @@ -1130,7 +1243,7 @@ public class PatternParser { public String parseStringLiteral() { IToken token = tokenSource.next(); String literalKind = token.getLiteralKind(); - if (literalKind.equals("string")) { + if (literalKind == "string") { return token.getString(); } @@ -1169,7 +1282,7 @@ public class PatternParser { public boolean maybeEat(String token) { IToken next = tokenSource.peek(); - if (next.getString().equals(token)) { + if (next.getString() == token) { tokenSource.next(); return true; } else { @@ -1189,7 +1302,7 @@ public class PatternParser { public boolean peek(String token) { IToken next = tokenSource.peek(); - return next.getString().equals(token); + return next.getString() == token; } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java index b61223ccf..c66d3e43a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java @@ -49,6 +49,10 @@ public class PerCflow extends PerClause { // ----- + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public Set couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS; } @@ -57,6 +61,10 @@ public class PerCflow extends PerClause { return FuzzyBoolean.MAYBE; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } + protected FuzzyBoolean matchInternal(Shadow shadow) { return FuzzyBoolean.YES; } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java index 63131f5ad..6b963df1a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java @@ -33,6 +33,10 @@ public class PerFromSuper extends PerClause { this.kind = kind; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public Set couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS; } @@ -41,6 +45,10 @@ public class PerFromSuper extends PerClause { throw new RuntimeException("unimplemented"); } + public FuzzyBoolean fastMatch(Class targetType) { + throw new RuntimeException("unimplemented"); + } + protected FuzzyBoolean matchInternal(Shadow shadow) { throw new RuntimeException("unimplemented"); } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerObject.java b/weaver/src/org/aspectj/weaver/patterns/PerObject.java index a9294e853..b3494cd85 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerObject.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerObject.java @@ -52,6 +52,10 @@ public class PerObject extends PerClause { this.isThis = isThis; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public Set couldMatchKinds() { return isThis ? thisKindSet : targetKindSet; } @@ -61,6 +65,10 @@ public class PerObject extends PerClause { return FuzzyBoolean.MAYBE; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } + protected FuzzyBoolean matchInternal(Shadow shadow) { //System.err.println("matches " + this + " ? " + shadow + ", " + shadow.hasTarget()); diff --git a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java index 5b3b9f954..6554e4157 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java @@ -32,6 +32,10 @@ public class PerSingleton extends PerClause { public PerSingleton() { } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public Set couldMatchKinds() { return Shadow.ALL_SHADOW_KINDS; } @@ -40,6 +44,10 @@ public class PerSingleton extends PerClause { return FuzzyBoolean.YES; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.YES; + } + protected FuzzyBoolean matchInternal(Shadow shadow) { return FuzzyBoolean.YES; } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java index bd8873e27..b3c6cdd92 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java @@ -54,6 +54,10 @@ public class PerTypeWithin extends PerClause { this.typePattern = p; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public Set couldMatchKinds() { return kindSet; } @@ -66,6 +70,10 @@ public class PerTypeWithin extends PerClause { return FuzzyBoolean.MAYBE; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } + protected FuzzyBoolean matchInternal(Shadow shadow) { ResolvedTypeX enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true); diff --git a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java index 886d1af9d..402c4ad47 100644 --- a/weaver/src/org/aspectj/weaver/patterns/Pointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/Pointcut.java @@ -104,6 +104,7 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression protected int lastMatchedShadowId; private FuzzyBoolean lastMatchedShadowResult; private Test lastMatchedShadowResidue; + private TypeVariablePatternList typeVariables = TypeVariablePatternList.EMPTY; /** * Constructor for Pattern. @@ -118,12 +119,25 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression * Could I match any shadows in the code defined within this type? */ public abstract FuzzyBoolean fastMatch(FastMatchInfo info); + + /** + * Could I match any shadows defined in this type? + */ + public abstract FuzzyBoolean fastMatch(Class targetType); /** * The set of ShadowKinds that this Pointcut could possibly match */ public abstract /*Enum*/Set/**/ couldMatchKinds(); + public TypeVariablePatternList getTypeVariables() { + return typeVariables; + } + + public void setTypeVariables(TypeVariablePatternList typeVars) { + this.typeVariables = typeVars; + } + /** * Do I really match this shadow? * XXX implementors need to handle state @@ -366,6 +380,10 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression return FuzzyBoolean.NO; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.NO; + } + protected FuzzyBoolean matchInternal(Shadow shadow) { return FuzzyBoolean.NO; } @@ -413,7 +431,7 @@ public abstract class Pointcut extends PatternNode implements PointcutExpression public String toString() { return ""; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java index 1b18cced8..1dab1b0ba 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java @@ -69,6 +69,10 @@ public class ReferencePointcut extends Pointcut { return FuzzyBoolean.MAYBE; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } + /** * Do I really match this shadow? */ @@ -312,7 +316,7 @@ public class ReferencePointcut extends Pointcut { return result; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ScopeWithTypeVariables.java b/weaver/src/org/aspectj/weaver/patterns/ScopeWithTypeVariables.java new file mode 100644 index 000000000..dcab3ba4f --- /dev/null +++ b/weaver/src/org/aspectj/weaver/patterns/ScopeWithTypeVariables.java @@ -0,0 +1,118 @@ +/* ******************************************************************* + * 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.patterns; + +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.weaver.IHasPosition; +import org.aspectj.weaver.ResolvedTypeX; +import org.aspectj.weaver.TypeX; +import org.aspectj.weaver.World; + +/** + * A scope that also considers type variables when looking up a type. + * + */ +public class ScopeWithTypeVariables implements IScope { + + private IScope delegateScope; + private TypeVariablePatternList typeVariables; + + public ScopeWithTypeVariables(TypeVariablePatternList typeVars, IScope delegate) { + this.delegateScope = delegate; + this.typeVariables = typeVars; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#lookupType(java.lang.String, org.aspectj.weaver.IHasPosition) + */ + public TypeX lookupType(String name, IHasPosition location) { + TypeVariable typeVariableMatch = typeVariables.lookupTypeVariable(name); + if (typeVariableMatch != null) { + return typeVariableMatch.resolvedType(); + } else { + return delegateScope.lookupType(name, location); + } + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#getWorld() + */ + public World getWorld() { + return delegateScope.getWorld(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#getEnclosingType() + */ + public ResolvedTypeX getEnclosingType() { + return delegateScope.getEnclosingType(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#getMessageHandler() + */ + public IMessageHandler getMessageHandler() { + return delegateScope.getMessageHandler(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#lookupFormal(java.lang.String) + */ + public FormalBinding lookupFormal(String name) { + return delegateScope.lookupFormal(name); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#getFormal(int) + */ + public FormalBinding getFormal(int i) { + return delegateScope.getFormal(i); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#getFormalCount() + */ + public int getFormalCount() { + return delegateScope.getFormalCount(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#getImportedPrefixes() + */ + public String[] getImportedPrefixes() { + return delegateScope.getImportedPrefixes(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#getImportedNames() + */ + public String[] getImportedNames() { + return delegateScope.getImportedNames(); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#message(org.aspectj.bridge.IMessage.Kind, org.aspectj.weaver.IHasPosition, java.lang.String) + */ + public void message(Kind kind, IHasPosition location, String message) { + delegateScope.message(kind, location, message); + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.patterns.IScope#message(org.aspectj.bridge.IMessage.Kind, org.aspectj.weaver.IHasPosition, org.aspectj.weaver.IHasPosition, java.lang.String) + */ + public void message(Kind kind, IHasPosition location1, + IHasPosition location2, String message) { + delegateScope.message(kind,location1,location2,message); + } + +} diff --git a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java index 0cdd94dec..012d7c99a 100644 --- a/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/SignaturePattern.java @@ -353,6 +353,10 @@ public class SignaturePattern extends PatternNode { return false; } + public boolean couldMatch(Class declaringClass) { + return declaringTypeMatch(declaringClass); + } + public boolean matches(Class declaringClass, java.lang.reflect.Member member) { if (kind == Member.ADVICE) return true; if (kind == Member.POINTCUT) return false; @@ -625,7 +629,7 @@ public class SignaturePattern extends PatternNode { return annotationPattern == AnnotationTypePattern.ANY; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java index be281ffc4..da45228ea 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetAnnotationPointcut.java @@ -83,6 +83,10 @@ public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut { public FuzzyBoolean fastMatch(FastMatchInfo info) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) @@ -271,7 +275,7 @@ public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut { return buf.toString(); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java index 2a2d6786b..958c9d8ba 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ThisOrTargetPointcut.java @@ -84,6 +84,10 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } private boolean couldMatch(Shadow shadow) { return isThis ? shadow.hasThis() : shadow.hasTarget(); @@ -232,7 +236,7 @@ public class ThisOrTargetPointcut extends NameBindingPointcut { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java b/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java index 9977c3c5e..db3981040 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ThrowsPattern.java @@ -152,7 +152,7 @@ public class ThrowsPattern extends PatternNode { //XXXwriteLocation(s); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java index e541b3946..a99f05ed8 100644 --- a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java @@ -54,10 +54,16 @@ public abstract class TypePattern extends PatternNode { protected boolean includeSubtypes; protected boolean isVarArgs = false; protected AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY; + protected TypePatternList typeParameters = TypePatternList.EMPTY; - protected TypePattern(boolean includeSubtypes,boolean isVarArgs) { + protected TypePattern(boolean includeSubtypes,boolean isVarArgs,TypePatternList typeParams) { this.includeSubtypes = includeSubtypes; this.isVarArgs = isVarArgs; + this.typeParameters = (typeParams == null ? TypePatternList.EMPTY : typeParams); + } + + protected TypePattern(boolean includeSubtypes, boolean isVarArgs) { + this(includeSubtypes,isVarArgs,null); } public AnnotationTypePattern getAnnotationPattern() { @@ -84,6 +90,14 @@ public abstract class TypePattern extends PatternNode { this.annotationPattern = annPatt; } + public void setTypeParameters(TypePatternList typeParams) { + this.typeParameters = typeParams; + } + + public TypePatternList getTypeParameters() { + return this.typeParameters; + } + public void setIsVarArgs(boolean isVarArgs) { this.isVarArgs = isVarArgs; } @@ -335,7 +349,7 @@ class EllipsisTypePattern extends TypePattern { * @param includeSubtypes */ public EllipsisTypePattern() { - super(false,false); + super(false,false,new TypePatternList()); } /* (non-Javadoc) @@ -398,7 +412,7 @@ class EllipsisTypePattern extends TypePattern { return 17 * 37; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } @@ -412,7 +426,7 @@ class AnyTypePattern extends TypePattern { * @param includeSubtypes */ public AnyTypePattern() { - super(false,false); + super(false,false,new TypePatternList()); } /* (non-Javadoc) @@ -488,7 +502,7 @@ class AnyTypePattern extends TypePattern { return 37; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } @@ -504,6 +518,10 @@ class AnyWithAnnotationTypePattern extends TypePattern { annotationPattern = atp; } + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + protected boolean couldEverMatchSameTypesAs(TypePattern other) { return true; } @@ -571,7 +589,7 @@ class AnyWithAnnotationTypePattern extends TypePattern { class NoTypePattern extends TypePattern { public NoTypePattern() { - super(false,false); + super(false,false,new TypePatternList()); } @@ -654,7 +672,7 @@ class NoTypePattern extends TypePattern { return 17 * 37 * 37; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java index 67327aa3d..33bdca150 100644 --- a/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java +++ b/weaver/src/org/aspectj/weaver/patterns/TypePatternList.java @@ -34,7 +34,7 @@ public class TypePatternList extends PatternNode { new TypePatternList(new TypePattern[] {}); public static final TypePatternList ANY = - new TypePatternList(new TypePattern[] {TypePattern.ELLIPSIS}); + new TypePatternList(new TypePattern[] {new EllipsisTypePattern()}); //can't use TypePattern.ELLIPSIS because of circular static dependency that introduces public TypePatternList() { typePatterns = new TypePattern[0]; @@ -503,7 +503,15 @@ public class TypePatternList extends PatternNode { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + for (int i = 0; i < typePatterns.length; i++) { + typePatterns[i].traverse(visitor,ret); + } + return ret; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/TypeVariable.java b/weaver/src/org/aspectj/weaver/patterns/TypeVariable.java new file mode 100644 index 000000000..8c667f010 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/patterns/TypeVariable.java @@ -0,0 +1,216 @@ +/* ******************************************************************* + * 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.patterns; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.weaver.ISourceContext; +import org.aspectj.weaver.ResolvedTypeX; +import org.aspectj.weaver.TypeX; +import org.aspectj.weaver.VersionedDataInputStream; + +/** + * @author colyer + * Represents a type variable as declared as part of a type declaration, parameter declaration, + * or type parameter specification. + *

For example:

+ *
    + *
  • <T> T genericMethod(T t) {...}
  • + *
  • static <T extends Foo> T staticGenericMethod(T t) {...}
  • + *
  • Foo<T extends Bar & IGoo> + *
+ */ +public class TypeVariable extends PatternNode { + + private static final String anything = "?"; + + private String name; // eg. "T" + private TypePattern upperBound; // default is object unless of the form T extends Bar + private TypePattern[] interfaceBounds; // additional upper bounds (must be interfaces) arising from + // declarations of the form T extends Bar & IGoo, IDoo + private TypePattern lowerBound; // only set if type variable is of the form T super Bar + private ResolvedTypeX resolvedType; // only set if resolved + + /** + * Create a named type variable with upper bound Object and no lower bounds. + * Use this constructor for the simple "T" case + */ + public TypeVariable(String variableName) { + this.name = variableName; + this.upperBound = new ExactTypePattern(TypeX.OBJECT,false,false); + this.lowerBound = null; + this.interfaceBounds = null; + } + + /** + * Create a named type variable with the given upper bound and no lower bounds + * Use this constructor for the T extends Foo case + * @param variableName + * @param upperBound + */ + public TypeVariable(String variableName, TypePattern upperBound) { + this.name = variableName; + this.upperBound = upperBound; + this.lowerBound = null; + this.interfaceBounds = null; + } + + public TypeVariable(String variableName, TypePattern upperLimit, TypePattern[] interfaceBounds, TypePattern lowerBound) { + this.name = variableName; + this.upperBound = upperLimit; + if (upperBound == null) upperBound = new ExactTypePattern(TypeX.OBJECT,false,false); + this.interfaceBounds = interfaceBounds; + this.lowerBound = lowerBound; + } + + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + + public String getName() { + return name; + } + + public boolean isAnythingPattern() { + return name.equals(anything); + } + + public TypePattern getRawTypePattern() { + return upperBound; + } + + public TypePattern getUpperBound() { + return upperBound; + } + + public boolean hasLowerBound() { return (lowerBound != null); } + + public TypePattern getLowerBound() { + return lowerBound; + } + + public boolean hasAdditionalInterfaceBounds() { + return (interfaceBounds != null); + } + + public TypePattern[] getAdditionalInterfaceBounds() { + if (interfaceBounds != null) { + return interfaceBounds; + } else { + return new TypePattern[0]; + } + } + + public ResolvedTypeX resolvedType() { + throw new UnsupportedOperationException("Haven't implement ResolvedTypeX for TypeVariables yet..."); + //return this.resolvedType; + } + + public boolean equals(Object obj) { + if (!(obj instanceof TypeVariable)) return false; + TypeVariable other = (TypeVariable) obj; + if (!name.equals(other.name)) return false; + if (!upperBound.equals(other.upperBound)) return false; + if (lowerBound != null) { + if (other.lowerBound == null) return false; + if (!lowerBound.equals(other.lowerBound)) return false; + } else { + if (other.lowerBound != null) return false; + } + if (interfaceBounds != null) { + if (other.interfaceBounds == null) return false; + if (interfaceBounds.length != other.interfaceBounds.length) return false; + for (int i = 0; i < interfaceBounds.length; i++) { + if (!interfaceBounds[i].equals(other.interfaceBounds[i])) return false; + } + } else { + if (other.interfaceBounds != null) return false; + } + return true; + } + + public int hashCode() { + int hashCode = 17 + (37 * name.hashCode()); + hashCode = hashCode * 37 + upperBound.hashCode(); + if (lowerBound != null) hashCode = hashCode * 37 + lowerBound.hashCode(); + if (interfaceBounds != null) { + for (int i = 0; i < interfaceBounds.length; i++) { + hashCode = 37*hashCode + interfaceBounds[i].hashCode(); + } + } + return hashCode; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(name); + sb.append(getExtendsClause()); + if (interfaceBounds != null) { + sb.append(" & "); + for (int i = 0; i < interfaceBounds.length; i++) { + sb.append(interfaceBounds[i].toString()); + if (i < interfaceBounds.length) sb.append(","); + } + } + if (lowerBound != null) { + sb.append(" super "); + sb.append(lowerBound.toString()); + } + return sb.toString(); + } + + private String getExtendsClause() { + if (upperBound instanceof ExactTypePattern) { + ExactTypePattern bound = (ExactTypePattern) upperBound; + if (bound.type == TypeX.OBJECT) return ""; + } + return " extends " + upperBound.toString(); + } + + public void write(DataOutputStream s) throws IOException { + s.writeUTF(name); + upperBound.write(s); + if (interfaceBounds == null) { + s.writeInt(0); + } else { + s.writeInt(interfaceBounds.length); + for (int i = 0; i < interfaceBounds.length; i++) { + interfaceBounds[i].write(s); + } + } + s.writeBoolean(hasLowerBound()); + if (hasLowerBound()) lowerBound.write(s); + writeLocation(s); + } + + public static TypeVariable read(VersionedDataInputStream s, ISourceContext context) throws IOException { + TypeVariable tv = null; + String name = s.readUTF(); + TypePattern upperBound = TypePattern.read(s, context); + TypePattern[] additionalInterfaceBounds = null; + int numInterfaceBounds = s.readInt(); + if (numInterfaceBounds > 0) { + additionalInterfaceBounds = new TypePattern[numInterfaceBounds]; + for (int i = 0; i < additionalInterfaceBounds.length; i++) { + additionalInterfaceBounds[i] = TypePattern.read(s, context); + } + } + boolean hasLowerBound = s.readBoolean(); + TypePattern lowerBound = null; + if (hasLowerBound) lowerBound = TypePattern.read(s,context); + tv = new TypeVariable(name,upperBound,additionalInterfaceBounds,lowerBound); + tv.readLocation(context, s); + return tv; + } + +} diff --git a/weaver/src/org/aspectj/weaver/patterns/TypeVariablePatternList.java b/weaver/src/org/aspectj/weaver/patterns/TypeVariablePatternList.java new file mode 100644 index 000000000..1107d4e81 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/patterns/TypeVariablePatternList.java @@ -0,0 +1,81 @@ +/* ******************************************************************* + * 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.patterns; + +import java.io.DataOutputStream; +import java.io.IOException; + +import org.aspectj.weaver.ISourceContext; +import org.aspectj.weaver.VersionedDataInputStream; + +/** + * @author colyer + * A list of type variable specifications, eg. <T,S> + */ +public class TypeVariablePatternList extends PatternNode { + + public static final TypeVariablePatternList EMPTY = new TypeVariablePatternList(new TypeVariable[0]); + + private TypeVariable[] patterns; + + public TypeVariablePatternList(TypeVariable[] typeVars) { + this.patterns = typeVars; + } + + public TypeVariable[] getTypeVariablePatterns() { + return this.patterns; + } + + public TypeVariable lookupTypeVariable(String name) { + for (int i = 0; i < patterns.length; i++) { + if (patterns[i].getName().equals(name)) { + return patterns[i]; + } + } + return null; + } + + public void write(DataOutputStream s) throws IOException { + s.writeInt(patterns.length); + for (int i = 0; i < patterns.length; i++) { + patterns[i].write(s); + } + writeLocation(s); + } + + public static TypeVariablePatternList read(VersionedDataInputStream s, ISourceContext context) throws IOException { + TypeVariablePatternList ret = EMPTY; + int length = s.readInt(); + if (length > 0) { + TypeVariable[] patterns = new TypeVariable[length]; + for (int i = 0; i < patterns.length; i++) { + patterns[i] = TypeVariable.read(s,context); + } + ret = new TypeVariablePatternList(patterns); + } + ret.readLocation(context, s); // redundant but safe to read location for EMPTY + return ret; + } + + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + + public Object traverse(PatternNodeVisitor visitor, Object data) { + Object ret = accept(visitor,data); + for (int i = 0; i < patterns.length; i++) { + patterns[i].traverse(visitor,ret); + } + return ret; + } + +} diff --git a/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java index c75924b1d..124e4508f 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java @@ -142,7 +142,7 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern { return "@(" + typePattern.toString() + ")"; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java index 2e5b98f5d..31df81d09 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java @@ -38,9 +38,16 @@ public class WildTypePattern extends TypePattern { String[] importedPrefixes; String[] knownMatches; int dim; - - WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs) { - super(includeSubtypes,isVarArgs); + + // these next three are set if the type pattern is constrained by extends or super clauses, in which case the + // namePatterns must have length 1 + // TODO AMC: read/write/resolve of these fields + TypePattern upperBound; // extends Foo + TypePattern[] additionalInterfaceBounds; // extends Foo & A,B,C + TypePattern lowerBound; // super Foo + + WildTypePattern(NamePattern[] namePatterns, boolean includeSubtypes, int dim, boolean isVarArgs, TypePatternList typeParams) { + super(includeSubtypes,isVarArgs,typeParams); this.namePatterns = namePatterns; this.dim = dim; ellipsisCount = 0; @@ -51,7 +58,7 @@ public class WildTypePattern extends TypePattern { } public WildTypePattern(List names, boolean includeSubtypes, int dim) { - this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim,false); + this((NamePattern[])names.toArray(new NamePattern[names.size()]), includeSubtypes, dim,false,TypePatternList.EMPTY); } @@ -65,10 +72,31 @@ public class WildTypePattern extends TypePattern { this.end = endPos; this.isVarArgs = isVarArg; } - + + public WildTypePattern( + List names, + boolean includeSubtypes, + int dim, + int endPos, + boolean isVarArg, + TypePatternList typeParams, + TypePattern upperBound, + TypePattern[] additionalInterfaceBounds, + TypePattern lowerBound) { + this((NamePattern[])names.toArray(new NamePattern[names.size()]),includeSubtypes,dim,isVarArg,typeParams); + this.end = endPos; + this.upperBound = upperBound; + this.lowerBound = lowerBound; + this.additionalInterfaceBounds = additionalInterfaceBounds; + } + public NamePattern[] getNamePatterns() { return namePatterns; } + + public TypePattern getUpperBound() { return upperBound; } + public TypePattern getLowerBound() { return lowerBound; } + public TypePattern[] getAdditionalIntefaceBounds() { return additionalInterfaceBounds; } // called by parser after parsing a type pattern, must bump dim as well as setting flag public void setIsVarArgs(boolean isVarArgs) { @@ -638,6 +666,7 @@ public class WildTypePattern extends TypePattern { s.writeBoolean(includeSubtypes); s.writeInt(dim); s.writeBoolean(isVarArgs); + typeParameters.write(s); // ! change from M2 //??? storing this information with every type pattern is wasteful of .class // file size. Storing it on enclosing types would be more efficient FileUtil.writeStringArray(knownMatches, s); @@ -667,7 +696,8 @@ public class WildTypePattern extends TypePattern { boolean includeSubtypes = s.readBoolean(); int dim = s.readInt(); boolean varArg = s.readBoolean(); - WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, varArg); + TypePatternList typeParams = TypePatternList.read(s, context); + WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, varArg,typeParams); ret.knownMatches = FileUtil.readStringArray(s); ret.importedPrefixes = FileUtil.readStringArray(s); ret.readLocation(context, s); @@ -683,14 +713,14 @@ public class WildTypePattern extends TypePattern { } boolean includeSubtypes = s.readBoolean(); int dim = s.readInt(); - WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, false); + WildTypePattern ret = new WildTypePattern(namePatterns, includeSubtypes, dim, false,null); ret.knownMatches = FileUtil.readStringArray(s); ret.importedPrefixes = FileUtil.readStringArray(s); ret.readLocation(context, s); return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java index a00734b1d..e66e9c676 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinAnnotationPointcut.java @@ -72,6 +72,11 @@ public class WithinAnnotationPointcut extends NameBindingPointcut { return annotationTypePattern.fastMatches(info.getType()); } + public FuzzyBoolean fastMatch(Class targetType) { + // TODO AMC + return FuzzyBoolean.MAYBE; + } + /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) */ @@ -209,7 +214,7 @@ public class WithinAnnotationPointcut extends NameBindingPointcut { return buf.toString(); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java index b1eae06cc..8ee9fdd64 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinCodeAnnotationPointcut.java @@ -79,6 +79,10 @@ public class WithinCodeAnnotationPointcut extends NameBindingPointcut { return FuzzyBoolean.MAYBE; } + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } + /* (non-Javadoc) * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow) */ @@ -216,7 +220,7 @@ public class WithinCodeAnnotationPointcut extends NameBindingPointcut { return buf.toString(); } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java index 142c97825..18c58a5d6 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithinPointcut.java @@ -64,6 +64,10 @@ public class WithinPointcut extends Pointcut { } return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } protected FuzzyBoolean matchInternal(Shadow shadow) { ResolvedTypeX enclosingType = shadow.getIWorld().resolve(shadow.getEnclosingType(),true); @@ -174,7 +178,7 @@ public class WithinPointcut extends Pointcut { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java index 04d0230b9..e3f64f9de 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/WithincodePointcut.java @@ -60,6 +60,11 @@ public class WithincodePointcut extends Pointcut { public FuzzyBoolean fastMatch(FastMatchInfo type) { return FuzzyBoolean.MAYBE; } + + public FuzzyBoolean fastMatch(Class targetType) { + return FuzzyBoolean.MAYBE; + } + protected FuzzyBoolean matchInternal(Shadow shadow) { //This will not match code in local or anonymous classes as if @@ -139,7 +144,7 @@ public class WithincodePointcut extends Pointcut { return ret; } - public Object accept(PointcutVisitor visitor, Object data) { + public Object accept(PatternNodeVisitor visitor, Object data) { return visitor.visit(this, data); } } diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java b/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java index 2da27a246..2f3a09e4a 100644 --- a/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java +++ b/weaver/src/org/aspectj/weaver/tools/PointcutExpression.java @@ -22,6 +22,19 @@ import java.lang.reflect.Method; */ public interface PointcutExpression { + /** + * Determine whether or not this pointcut could ever match a join point in the given class. + * @param aClass the candidate class + * @return true iff this pointcut may match a join point within(aClass), and false otherwise + */ + boolean couldMatchJoinPointsInType(Class aClass); + + /** + * Returns true iff this pointcut contains any expression that might necessitate a dynamic test + * at some join point (e.g. args) + */ + boolean mayNeedDynamicTest(); + /** * Determine whether or not this pointcut matches a method call to the given method. * @param aMethod the method being called diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java b/weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java new file mode 100644 index 000000000..cd357e743 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/tools/PointcutPrimitive.java @@ -0,0 +1,44 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * ******************************************************************/ + +package org.aspectj.weaver.tools; + +import org.aspectj.util.TypeSafeEnum; + +/** + * An enumeration of the different kinds of pointcut primitives + * supported by AspectJ. + */ +public class PointcutPrimitive extends TypeSafeEnum { + + public static final PointcutPrimitive CALL = new PointcutPrimitive("call",1); + public static final PointcutPrimitive EXECUTION = new PointcutPrimitive("execution",2); + public static final PointcutPrimitive GET = new PointcutPrimitive("get",3); + public static final PointcutPrimitive SET = new PointcutPrimitive("set",4); + public static final PointcutPrimitive INITIALIZATION = new PointcutPrimitive("initialization",5); + public static final PointcutPrimitive PRE_INITIALIZATION = new PointcutPrimitive("preinitialization",6); + public static final PointcutPrimitive STATIC_INITIALIZATION = new PointcutPrimitive("staticinitialization",7); + public static final PointcutPrimitive HANDLER = new PointcutPrimitive("handler",8); + public static final PointcutPrimitive ADVICE_EXECUTION = new PointcutPrimitive("adviceexecution",9); + public static final PointcutPrimitive WITHIN = new PointcutPrimitive("within",10); + public static final PointcutPrimitive WITHIN_CODE = new PointcutPrimitive("withincode",11); + public static final PointcutPrimitive CFLOW = new PointcutPrimitive("cflow",12); + public static final PointcutPrimitive CFLOW_BELOW = new PointcutPrimitive("cflowbelow",13); + public static final PointcutPrimitive IF = new PointcutPrimitive("if",14); + public static final PointcutPrimitive THIS = new PointcutPrimitive("this",15); + public static final PointcutPrimitive TARGET = new PointcutPrimitive("target",16); + public static final PointcutPrimitive ARGS = new PointcutPrimitive("args",17); + public static final PointcutPrimitive REFERENCE = new PointcutPrimitive("reference pointcut",18); + + private PointcutPrimitive(String name, int key) { + super(name, key); + } + +} diff --git a/weaver/src/org/aspectj/weaver/tools/PointcutPrimitives.java b/weaver/src/org/aspectj/weaver/tools/PointcutPrimitives.java deleted file mode 100644 index d6c13e186..000000000 --- a/weaver/src/org/aspectj/weaver/tools/PointcutPrimitives.java +++ /dev/null @@ -1,43 +0,0 @@ -/* ******************************************************************* - * Copyright (c) 2004 IBM Corporation. - * All rights reserved. - * This program and the accompanying materials are made available - * under the terms of the Common Public License v1.0 - * which accompanies this distribution and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * ******************************************************************/ - -package org.aspectj.weaver.tools; - -import org.aspectj.util.TypeSafeEnum; - -/** - * An enumeration of the different kinds of pointcut primitives - * supported by AspectJ. - */ -public class PointcutPrimitives extends TypeSafeEnum { - - public static final PointcutPrimitives CALL = new PointcutPrimitives("call",1); - public static final PointcutPrimitives EXECUTION = new PointcutPrimitives("execution",2); - public static final PointcutPrimitives GET = new PointcutPrimitives("get",3); - public static final PointcutPrimitives SET = new PointcutPrimitives("set",4); - public static final PointcutPrimitives INITIALIZATION = new PointcutPrimitives("initialization",5); - public static final PointcutPrimitives PRE_INITIALIZATION = new PointcutPrimitives("preinitialization",6); - public static final PointcutPrimitives STATIC_INITIALIZATION = new PointcutPrimitives("staticinitialization",7); - public static final PointcutPrimitives HANDLER = new PointcutPrimitives("handler",8); - public static final PointcutPrimitives ADVICE_EXECUTION = new PointcutPrimitives("adviceexecution",9); - public static final PointcutPrimitives WITHIN = new PointcutPrimitives("within",10); - public static final PointcutPrimitives WITHIN_CODE = new PointcutPrimitives("withincode",11); - public static final PointcutPrimitives CFLOW = new PointcutPrimitives("cflow",12); - public static final PointcutPrimitives CFLOW_BELOW = new PointcutPrimitives("cflowbelow",13); - public static final PointcutPrimitives IF = new PointcutPrimitives("if",14); - public static final PointcutPrimitives THIS = new PointcutPrimitives("this",15); - public static final PointcutPrimitives TARGET = new PointcutPrimitives("target",16); - public static final PointcutPrimitives ARGS = new PointcutPrimitives("args",17); - - private PointcutPrimitives(String name, int key) { - super(name, key); - } - -} diff --git a/weaver/src/org/aspectj/weaver/tools/UnsupportedPointcutPrimitiveException.java b/weaver/src/org/aspectj/weaver/tools/UnsupportedPointcutPrimitiveException.java new file mode 100644 index 000000000..49f6555f6 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/tools/UnsupportedPointcutPrimitiveException.java @@ -0,0 +1,43 @@ +/* ******************************************************************* + * 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.tools; + +/** + * @author colyer + * + */ +public class UnsupportedPointcutPrimitiveException extends RuntimeException { + + private static final long serialVersionUID = 3258689888517043251L; + + private PointcutPrimitive unsupportedPrimitive; + private String pointcutExpression; + + public UnsupportedPointcutPrimitiveException(String pcExpression, PointcutPrimitive primitive) { + super("Pointcut expression " + pcExpression + " contains unsupported pointcut primitive '" + + primitive.getName() + "'"); + this.pointcutExpression = pcExpression; + this.unsupportedPrimitive = primitive; + } + + /** + * @return Returns the unsupportedPrimitive. + */ + public PointcutPrimitive getUnsupportedPrimitive() { + return unsupportedPrimitive; + } + + public String getInvalidPointcutExpression() { + return pointcutExpression; + } + +} diff --git a/weaver/testdata/dummyAspect.jar b/weaver/testdata/dummyAspect.jar index af35626c6a6515f6c0ec9e451213b930ac954d13..8095fddf44927b6f85f2680aaafde67359522034 100644 GIT binary patch delta 659 zcmV;E0&M-=295^}P)h>@6aWYS2mq*E$&n3w1E^iek&GgL?Nd!}(?AfNt=+UuTN+vl z1SFJ7DGD4MHK-gYLaGw=lma4scNZbD+E z$$<+Jf|X`x=fi$)KiFws3l+w3O%0kYQV#8^;xH9vKE8f zV?XrO69!g)p0hqo-nwKc5l4s-> z?|*@n&!)Ue^V%>;ew}=tEN3#h`3h`+1qF(Z*fJGV#07f5tXYR>AR#78evAgK1F}>X zPR!zeD$TYrO=;h-Agl?U>m~ssI(lrv7EzfH(>uCm`nRbYpf>g3=;v%gbr#bK+@SAP z*qG)`3O_+wf8;i#NctG6xWq%R)Iz2Fup7HV1_O-T<3VZM;GRWN|1EY$ci~~`X0L|# zJmm;_^sd5Kd0cTfj>Mij{kY7=0Cve^&6CS?MFW1z>&L8Xk%D;o_Ib zi~mLbmx=s$1e%rOWwHKofo4TG5i1*um5sz||1$#p2~bN12=&}$iZucN0Br{V08mQ- t0u%rg00;mG0H|HblhFc04yawpGWFbLiZucN0Br}8A_FxB^8x?>006+RGpqmr delta 610 zcmV-o0-gPi2i*n@P)h>@6aWYS2mlgGYLN|m0}@MWk&GgLbyCf4(?AfOt=+UuTbdRM z6eN^N0finMHK-gYLaGw=lma4=K1u0mh&f^Mbb$o(@}Yg4jkK29=jl8tGRI zoaWO31Ggi8L)?I6s8qp)RR&wVD8<+LC_wd|2MIFR=}Ezp0auanCqY+VL>Yt4UWxUX z!9I^gBfyVRVWX6395&j|pB=RWY%|zx_GXnG8!3BI4Lxq_WA7940+n|X7Lg!2Z%*zE z^@R+(C=#x?j$}GjPTk>^Fw*~HVo>eNTnRjlOdqv>l1k4MGk7wG>#dAZEplCATOioF z4C-@o*SsB>YP?!da&FB4Rc09;EiCD4uF>6xC7PO9OTf$!XmP-L){1 zj;soQ;+o32YXdNmW7ZDbCMi>4rlUKyewV5N+A|N1e$J*+=P7N%J^F5q-N?L8?l&kp zFZ`|)`3O^;)p;7$`>1u44l`fKWQ@u`8`p0N{7WUx-!gwPix3OHJQ^N{+7tBXeT|t8 zx#oVR#Gya?xNKtpj|uMx9|)fbUkG1e&)$_MxsnG2#{u{UP)i30aRC^P1Ofm6-va;u wP)h*<6aW+e2mlBG5=&~60s})15=&|_aRC^P1Ofm6-vg6V12qQ10ssI20D>F=i2wiq diff --git a/weaver/testdata/ltw-acaspects.jar b/weaver/testdata/ltw-acaspects.jar index 7ee6e98889ebadde0da78cd2dc015b2d03726d70..ed55e51bc5afeefc1ab482b55a16f128cb619e24 100644 GIT binary patch delta 1535 zcmY+EdpOez7{{mOGPh)NEtR|FPAC$FD3@l=6sx%WXq$*! zirFgW)-fxsGsTQzDX|o}bkfm3=c)Jm$M<>P=lwq4|30lyB1{SC1Ktb+$!&;nVt}la z3Er^cCa^Iu7nG0$L&LHY(@GQWD8yqL|EPi0H)e$k^oS^|8HQ9!*o46pY~x0W5z#uQ zD$1FJgDz!6>xCOGT_jC}nTLYv)D5G|h3FMaezHVSn3z_FR=tfk-e(&pPFUoEr)nWB>HsepP)@riHnJ!sz>A62@sm-_qSS=++)?Ew zak`<3B1Qo{KM*Wp4p}-yl!V`isDfrcPrc`e$e4#akjCr|{ngy~+HB#$4jY}C?{e;D zwpKkVyz}bTNy8bPuHvP4FqD;IOIV~lBtAwz-q!sncqe5hY~*<334Ftux%;1t)dIAD zW#4&UyeLSr72mC!;7F)HoW7k$PTz-fa;*=~Mr{pI#8Vw0Td%20ewmfuwTQF+m{e}nzHHdd!EmY2$d_ODk@4cqgQL$5MA z7gccf5nQZBCU)hOHEukpoNK?58U*wQ^RzW;yR%SJ?JrAc@%)|=PU^*N=(NzHZB1*?=g`;ehPJ3mFHp!|p>6Ob}92F>h9IljHW(Pt1}* z*BR3-_MQxbUDC1vV)P~LQ|Lec^?PIDKH3?L2^^y%QE7H@)?B*FHPpWbb6&6{!e$w2EfA2ygu;bd<4959w0a~x$CzRbR zyh;BylA=%_EhEuo(cspU4+eJ&J}GS_&;eJ2@&W^Bp3e-HU)yHlsk?Qwr72``$NnQc zjhQ(_F5BoGEq56IBw`6Hv$l49Vm;}(=So7ZETkiguA*)e`~4i*)pLx&`c^i$n>~JM zhN?AYyQecBpvt~=UXUH>vEsLXlls~c*74yho8)u`6CSK{s|(vBhlj^oVsC@&tMgWt zi|y2~ciQ4q?EESm8>uGs=X7L=UzFycO1MsXYul_)@0Q`P`+^sd$B`)zP4;IMT7Gb4 zzj|Jp67hPWD-mg|S&sK)oy~I0nKbyO6lW|TAx@m)08j}nvnh%jxVUDk{#n-N zEpRiq-RQX1B3|&pR309?xY_VUvU+}~BlFpVL1eXvs7-W(J62vVv#j4=*BL)>_x)Mlm-GM6T$OJ*-Y#*J4hClqqMHWxv%AzP%F-lqwVbw5E4=&w{v zC`&C#GcUyoDU28is%AcguxiE5_?+@3oSK-(=5imjui86^#NyGh%pb3~X+q2_JLWwG zhfAOb@2^UP1NT`C>U81BAFZRaAx<+QQQVKDQCxL9Yu&3&Ad*7*$jZ&sTyS=j27#*7 zK%n1X+f=9xR+8ET1O1QR;&D0mog4hM`8A^s`gMTfM_?^8q|a|Tn}XVkbD~WkQ13>M c=CALd@6yF?knJ#OnV(nihMsM>9^~itAK_ogPyhe` delta 1451 zcmY*Zc{~#e0G^zik+-d4EV**!{;6d~46)VBIq5kfa-ZoH%W{N=ggKhr=E&81vAI%? z+)P7`60w*2NN?U8(bGTg*ZaOdzTfx#zVF{J0Y-<45OBPFFo4hzVK|>O5fbl_)PV%x zyuv@{$%^DsdtVz#JMlJr`j&(T{Q_Y@13Y<5fx2MX3$uA~|5lK318XpeZ$fLdT%;(J`&ajIgGCO{2qWC7i=BZ*gE=+Cs%TiUa>i&P9=YD?DkCQg4)Ajo2 z)u(}uVZ6ftqu-CwRVQhzes`Rvi6C!KWQS|YO*~4J%aAGB`sNoVydE38GKUM`D*1ZA z9QOygRmAOpcVV5yugngN93kfIOC76sOEC1cL$i`#8n9a}X-~&#a*F95!-e#^RtU$4 zmtj%zMV>d}+2D`1-z<0U9G8guZmAD$t$f7zYHJDY>_ab5%sQW&T4Ef$$V{LNe!T{l zO&W$pr-#fv%&`kA3SN#<&ay?ZQaKGiec0fxOyTGb*WNX!2&s~cr<@+O%5f5{*>$>2 zoT)|oK58}-+E;aHSF(pcj_EPXz)nB2wzjPINwe=h8^mhc@3pZo#xyKc$S=1qT(dZn zB1+FSD0IzPA&owL+i;4U*=sM$Zp2dGZ{V!<>d`%p0h2+twUUi-#~#+T#SqG!3%Fx( zGzCvsYh_^K0AnRD2Gu(F6@;0uTm>0!emNuNGfP)04X~(FX;@En8Yc|JM4cQqwyXeK z>re7)*Jzafaiyk3CAMN&42jn=TfRCjfN2FKtlC^FuiD$B*^uMZn^?tO^Nv(xjUkXdKcjTHoeGWbs3ohrhq^|p!6DE=aLx&BYHIfIv1CWuQL_~iWV z?271-;C9&|VSzm^l(k?;m)@!}v2^2b^V}SSM)tN;(h?gn5nO(%UE^W-QbAuX96r;w z#qx6D0P&h+@OCaK+Q$D$ZOg%(gxaQ>#_AM8aG+Z(ArbYcLFvK$rL*58UX*pLvg}3l zuBMj-NR?7VU&hqMl8E~z1Mp4n8mGMvvSkYC7}l)>ripe}L2x9L;;WY$4x;F~=mi6_ z`y!n>Q?mrarP=+P<_2AKYCh$0+H~8a#oHWqRx$a!S|qdq{${_E)P80yFu{~4S0w_8 z+e`FHMV1Z!PEKS{MW&s5GU)f(cY%6OY@u;)CR_ z70t2hMbsqdj!v=4FN%&SYcoU_$bD1JMOG*LP{zP^*X?=^?)JW-{nwJu7Q@x*Aff>8 zG?^}tXpD748%=R?Pt0WpR)hU``Z;hbVJ)SJxKYT!=k>aN)vUpse2sopVjGgjBj5aIS zu?(zjBzO+_2{=I^?dYWDMLqz40|JNv2soZ&Fu;FbNznpgew-zx1t>{L2f`>TK#;@# z8rnb20Ve@JgT@O0T(Kn@g#?BL+{E|=hK7ZBsJr{!2n{9R_yvA6d5`$^NQZ@fxPJk+ CC!@ds diff --git a/weaver/testdata/ltw-aspects.jar b/weaver/testdata/ltw-aspects.jar index f09ee3db18ba44477f94a256ddd026c00d67eb0c..2e1e86fb1fdc6c7af66288016516cfd7e6c6ed02 100644 GIT binary patch delta 1351 zcmV-N1-Sa;3%CpoP)h>@6aWYS2mq;F$&n3w1FBugk&GaJ?N-}UTSXZEZ2}~Olu~F* zQ43T<%gqETUP`bEq1cvi(I5!s<#4jViHCFIIU8D@e9#wPoUt>`IQ<9op)(4d0WC9j ze9@Wy5x)9gsNe1hxsaed))_MMWxuog-7mY}v%jAF0w9VsLt}DbY23|mT?D`wTC&=f z7Be+#JvO(0npL}ghVxohj~JFArZmIMJ3OJ~UCwYJS)yLpaO`{9s>$OFmn3@-yUdbq43n7AD3apmPaVx_xSWfDdQ@pQ=+fzwq^fx0-`!U&Dx`ef_YEDq|FXz?%$#oZK+2Fm6cK-oj{5c1Uw&;sbb_ z!mVX8Mto*jbpm2pzCriA&#*{ z3fDPhu)D^&XH&wq1ivq8lPsxakvp!kpjNOw5}7WJE97k*-M>DBeg{tm(E{>Nz9Q9FKrqHHCsP4Rd;Ox|M!&RBu7zJDL>J4)4gDahNz zC8eyAxdSiI`XYTzGCFPWS{}?_U9C{ReS#-{7k-5QKyV=4dMFXRME~+Ds0{jqa6hd* zyLkBkk>%E_`{*0o!>g^aJzU?z8+(Wkw2u9Z2_Ke926uZ*1%oA)z@##{2e&YPMO4y> zW<}LV#>0$5PkhghWb*NS&haTXI$ z9shdfSN7EV$bVgo%GCh zcab2Sb8LBiy6Hk2W%yRQysNZqMnrXbpVNZ7BBKc{?K=8!y8O;i1y4DDSN#RLg@Flz zRf2B_z9o1{DWP<+9)doCL98gdWrjYc+WoW5b2<3Ov%`^T<#c2^9hpu?rqhw>bYwc& z$aLayXGA@a$B#R{iizd$A^nfB=O|0%2=p9|J+%g!lZ`_Ehq0&rbnJN^$DV%xP)i30 zXNA^M;{*Tz5fT6ZP)h*}0u%rg00;mG0I6NclUfBs4ys+rGG~R>QsV>w01*@6aWYS2mljHYLN|m0~1SXk&GaJjaA!I8&w$podie-DW&O! zq83sOZMc{~#Y+iRAr#vZE*b>Eyezv1*tqP*-4j}#e9#wPoUt>`IQ|3r&>4l!fR-8i zrZfIg>UYkDTuAD;GvA(X&-s1#?>qa~-_L#rkV1i>Gqe(a}lVd4`KE zjE8W6;e5`t`C@r@le;T&lOdLKbj@1TTvL8mHan(&l<6ogOXY32LgvMe=`jpQ^P7Cj zae1QZZel#KHO6n>8k?A4m`wVimxXDibEYRUImg{jYYJKPoqFJy_A-%3+`J5@oGg@mut;lerMFc7bdRf$s#tWvaV(VHfC9b(g2Ddp?Fy7+a z_bKbxf#-Zh z7#cmo>#_6^ZXMyRBV#*fVG;#abKw7u;j9sRW1+WF6Ia&gXmVMPI6vzpXfQk!g_4#5Ix6OeokAz&=FGx14_|{_^3g=Uzr3Vg#82U zZBK$v8YCj}|I{Ecp!SJBL16tD`KOpaXb=fuMR6ZvRpqk&zo;au1!&HHI}0j*+5_@m zM{@VLWjSk(YZ)1-8Tg#&3$S5-u(n!-nmGw|h`uD^L|+A8T<&j(z9ssa=y3)A7;7?L ztg88wO3{IJqMzVqCkwNVUf$)l@Zy?n#PeJTx+J`U?pXWWEiCNEtAIkub>yY#6)MAH z@V!F)ENMkUq;&c#7X@y;aj|2b!BMATiP)h*<6aW+e2mlBG6H987t_4F5 c6H96`>@y;aj|2b!BMFoL1v3Uq1poj50J)QIi2wiq diff --git a/weaver/testdata/ltw-classes.jar b/weaver/testdata/ltw-classes.jar index 1dfcc034bfe5a60f2dfe4c3ba8ddcf47ee8690eb..014510d57abc4f6f031cbc3a13ef0fef5bc618e2 100644 GIT binary patch delta 62 zcmX@deU6(qz?+#xgn@6aWYS2mq>G$&n3w1FBugk&GsP?N!Zh6Gs&PjXz??xDXOj z2yGKnzMMeqBK1T7DK*fd2B_pH5oi&b><;l-n;mO*oDYsY^uV9Np+$m21BX;aYHzK? z-_t9FH?vD@CyUx+g<|P>XWzcx?|se8d-cz6zXPb@0>h#Cg{7;)4Y(55l#;3d#xT<6 zYrG!taHW2Kd$}!KT|k!M2yeTm{Lt6exgT_uXz*?%7{=#&)(b5q*ZFcFW*Lqd^NvtW zKU@ifmf?*s(mZqta(I51S28bNasxwtg&|v=US!BMq(`;~EsczH!+tKKj8X|1d{jmr zL&LN>#4wf;LIH~ zYTSEqsP~0jzfU!*NwrerQHKiCuB{8cCRFXF&@Ji3IdSdFu;-XzG6gW#Zf=IUCA9BS z^6|&p4=9!D^q%UJQ9#k8I>~UBxatX4obfF=XJ5aT-O#(X;fjv&UqGd3dO1_=>rYcF z>c(t;YR9G*P5LKGIDu0P!z~`gw6-62P06V$rKapES6uhwQVzyh<86jBDY>_9DR`X{v0FQIQ<8ye%T?)Soj&79e__-dZ0wMe%FEF(=04ZSFu4X7U;8DswVevz&_OKB$YeUFq%t0s9Z$%KuC8+{$){x;%@*|rY zB==D0(Eis!2$t)8+q)ttz9Hcxmr0hX%fK9C#XjeKxE!yvyVKMekl z!{9AYO9u$H@)Vwc0{{R$3;+O7O928D02BZS00;o8UCEQ%149m~UCA=G@)Vwc0{{R$ P43jJbIR-)m00000XTsOp delta 874 zcmV-w1C{*Y3F`@6aWYS2mlmIYLN|m0~AYYk&GsPbyQnV6G0UIrWaajRpg?e z0#y{s#WubQnqU<*;w335!K@F%cBI=ZJI(Bri%-S}e~1riq7MQO7)|s|6MvL?X4(MN zb(6Dm=Ir;K+nm{-zdnBjP(YF4%evsq+n9^m(vWe6(5@u1+D& z(9i4cB`@%Q^aA(%rV=II3B17d8do5UMa=FK-9BCbZ{fkwV&Jd7fc{pv5+{mFz<~Z?`vPGpOF)az#UXGDu-0 zZH{3of26f#t*DW+kjF}PAhRi9@nxuC(Ss9MeZiZGyYxWaPyhZx{)E;_vtR+sYUefwV@3Izy z95`SW+sx$DKF;jeQ2oYH%ZNc6>?paLQaDS0sBBvV05K7w~L;A zjC~{1M@#Fsu0ixmxZFV>v5tWZVZS4p_z?fl!N{0<(!m(DcGABfwz7}$Jq+)3P*Rw% zS{{?MzKFP`mfy85bWK)?8Mi4UW9FI>^sexIxh$1moi)yYdn8YhYS7?nKLAVoZa=_( zznUT3A>ky~NmemM?|H`3M?xOb@SNl&hW?)8cCfrDp>Fe?HvMA<%o*Cg##ZT?b4$9- zbrI+=$AfCFEVQNz7CNr$IP)h*<6aW+e2mlBG6iaH8Q3OK{6iaF{N3G$M3IhNDw*`};1UUxG0{{R3092Zt ANdN!< diff --git a/weaver/testdata/ltw-dwaspects.jar b/weaver/testdata/ltw-dwaspects.jar index 791213a885a25dbd611cd4ce8e82d6532500b9e7..7ca214cf3bc8256d45db5e06611690fab1bd02c9 100644 GIT binary patch delta 990 zcmV<410nqI2;vD1P)h>@6aWYS2mq>G$&n3w1FBugk&GyR?Nv)}6h{#LdLLeU*?{qb zXRw#|+Q2SIIRz^bSwJ9`hqRV0&`4H$rt!{dJiY4awQ&wP<`Cs)M9Kw4SvWWfQgTZq zepEtr&#(_X2#yGOq?+leuJ5brs_w4W|NZ$FfGVyr9BwSH-V|=Ym00B}^uvt;7{g?n zZ}D2d!;RX1!}Ydsbpct18Qyl!`Ju0Gb3f=RQRm%AFw8av*2^s=xA}S?t}`4n<{hD$ z#2N@K!@FUmdFT>ky0OPE0mhfyz|eogkgY7NFy!jeBkO~fNJhGDr%NcISVRV2l#s{R z1dR?6Wl9hQ9A-Gw@I&#SySXmZvQaWjHKfaf6|Q`L^PeckmaOX%W(|1`N65Wy`4Q#F zxcA~<*M!_&qr6q6+NkoVL#b(3w*}u4s(N4Omh|FPaqY`+;Fw`91#qL?+zE9{Xy2v9 z$CD4AQbH>WDfua(fN`_fIfjeGR!i98H9wFy?C*E78+x~%xuRntD4;xU>bY1Ms!>xb z!6DjZQ+AarZu=&0GkYSf@;1YTl=VK6eyH89 z9!e3zi4?^&x{_Ol{XWZkFLB{pelt_9^GLz@BgE}G3o zqvNIy^c|!31Zf!#(BEbHGWwSOz`dd6F?|g{-2a+Fga_^By+*QoN0vr1klTFsg zR_XT_d|&_CxhdW5rU-RZ=Al<^3ayEMAaYz8>mhZV6u{ck%mLLT2Pve|!0Tpf$V;8Eq4veQU_?w}ww6w>7*0 zP)i30(%2!UeFFdhSquOGP)h*<6aW+e2mlBGs$I#G-UCAps$I!4(%2!UeFFdhSqzge M1Um*n1ONa40P!^50RR91 delta 875 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 delta 5130 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 H@c-dIP}Q>W delta 1448 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 a$ueh!)>7jH000pZlXeO-1}O>v0002V8kM5} delta 1283 zcmV+e1^oJh7OxczP)h>@6aWYS2mljHYLN|m0~1SXv5bcV0~1SXlNJRae~ne!QyWzn z|D6O#2q~rMg`yTx4Q;rXK*dW5Rv{GI5-u79!MrTH2iUmm#@!QIo_x?3U!1Ws&N%)9 z`p_AL&VZH~`=&GgQR;WjhFnPMxHI3LZ_oLC_wPIV*Wb^62arO6p)m<^ZtJ))AcuKdV+B*!vD58i&5Wu-8 z+R@QT+TY5@u{FkT-x`~kV3+&Z8sCe0OFnK$90A)b<%<`+cV{@E$)W!8pDNZ=&4=h zK{AX%Qku-26{4tQ7H>w7K#~%xl}g+;7)I-%emiA`nxuV`o~okdamprtK_a};&` zp!K(Exnh3b7CW32L=i$*j@1LQ*JN(d@%79&W!t#>NarQlgdyY@hFesq<)z?v$YKNw zSfWd3NArB0e`@eI>*$JZP0{A0o@eah;-Vqx(02h`i2->y!DXwS(TB zv`hCSeT~w}XpR1g?jI4JAAX9S1GN(*WQ@3rO2*$|fASuyNTw^2?Ze0DJy51DNk#r9 zt}0`V!hLv&)|csPmeFa4Kk{I~=5B?0j)|WAQ+bI0ndn4@^@C*a3ccl5SUL0=@j+S# z5Ao^=66>)W#~2zt!t1g05pEsfts`VcVpG3iCV;h?!*O4z;;`hhm{l$h;x6V0C4=Zz zs7`WTe~xq)aUb9wo!wV5()@^W1?WA*{GaGK!NPiM>JUB0Sbk1hzt9m=1_Mgbhxn*L zykD6FB82?|?QKtjPZ}g5^8eHzF`)K|KS5yq82P7|KWGpMVMTEtV^!s{{=cXss|9Gz ze>)2*f7%1`Uq^EHxMewOj%yhisTug3=nJr6f3UV%g_=1Db%?$s;zVBsUtI2Qh`uHI zn&@!_{}^jBU#zP6lS%R+$}8Z$E$!s z$#vwV=@lx&WAME~{VZukL!@;2D;EU!grNzo;JNyEq5h^&ZBCU|Qw6$vff=GrqVI^l zHz#^dg`gs_L82j|QEVu`WnDg%<3R27FHlPd2<$T=jE@8W03!(i08mQ-0u%rg00;mG t0251UlQ;@P0~1SXlYR<54iigiGVC)VjE@8W03!*L$_g_E)d>Iq002FNb7%kn diff --git a/weaver/testdata/megatrace.jar b/weaver/testdata/megatrace.jar index 23a58710dec2d2192c533be6267fc6070cdb07fb..8735641c59b60d6fc48d3231d3cfd83181346eb6 100644 GIT binary patch delta 4503 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 diff --git a/weaver/testdata/megatrace0easy.jar b/weaver/testdata/megatrace0easy.jar index 4c025a67f45995cc281d4f0cacd71ba0d39936b8..11deb555cd7c6c2f050e11ffea447b6f498e2e0f 100644 GIT binary patch delta 3041 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 diff --git a/weaver/testdata/megatrace0hard.jar b/weaver/testdata/megatrace0hard.jar index 15f34d5d3f6a0d75877d10bcacbb9b5242dd2a15..84f4a7b1ee50384ba0a048b52c1a3ce3b74d0bd3 100644 GIT binary patch delta 2899 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 Dd3Na& delta 2451 zcmYk8c|6mPAIDkb+CoOik>ozZ9A8%%Y8cgu7?qLx9Epri&Z6A8R>+lHi8cz4}A?Iula6vhE|CF$;Uls&+;BUJx z1ynjxgO6H4f4?%vye0-Rn&nC}JL-Ly!pv*w0#w zM>EuvGKCnyv#(M}avJ8Tx2$r{tvMD9?GIMKWWu#}j`&)O+$Kd^+ zn@2f(>vXuB0+5Sx+R4wFS}U)s;@h*@fi}l49lX6%S|~*u5?a(-B2~5(=Um%Y&RZrQ z&p`rLZ6*&MSssT4HTd|8jtUK_UFZS4}~*Q{C9*52B`%ChqvrVUz6dIZPaL)HR%ufL~y z`IDZHh)n_9t`j%78j^*|4eL9Ofgtc`{Fws&89F|~_%CPE!_Bw+zy?e@ScMe&t)l||QXVlyMu8T}AjHe9G z8{Jy)(s5|?o}SQ+n1Nd7dIMkt?VW0&#P`{Ne(YEM5}8fxY^Q%>*0m+mfepu)n4&2; zSBxQ(mm;=t5F!zIK@8L=YnjS#RXa{}#)xkW&6G|YjX;bE-?tI)O@97dG8$Z!bEo7n zA^)Tz^+KGhp>-xckohRTY+w${^%ZVxvnAY*-O2jNzYXD+qIPotG#bZlaS0V`*BzS zZZ~p#27P{-6u_lhu%%kF(draJmrvX89O;;{RW6jyHX<(PQp9q+^sl~_E~FTU|1@c0 zN}?Z|K{`)3A!Dj=`SOzmw-QIGJ`8dg>uBI~#RgZJ@b<~4 zWTjC4*zhsG;v`@ASu2}su?>#pu4OjQe@AHH8$|rD^GF!LeDdjbe1#rd3a1wlo4)9= z7j5{VYd!gD#srz`$V2HHA zgYL}Du}lN}rupe>f^8+o*Uwe9=Kgp(eA`{-rmJ**0yQsyEi$*5_iTlSq~)0#qoK45 zYKjo;gc7!0MZ9+m{(sn{B>OKxd?w^N^z+k{gJM6gk1*GgAywzVEwb+Rm7GGr@ zv)vzbr%R>Nw2=5+g~d4z=Jv}H)kyz|&pJylP5T28qPu6ea+1^udBs<-ijC@oVZ4i& z&yJ}d0o8A0+u+1Z=uPo|*TC;O!2S%qQQI`U${+=GMLj;dXYUf08gx^6qaG7YpbaTx z0q>cFYGtCl4W5>oUY{X~PO}%43`x&a8VKQ<6CjC@P^1#5aSB;@#Dd| znhFg*AiUJS-EA9Lvd-!Fps(rJr{g~mbb#ZWEe~&!*wt6BxHvc*_&NUU|G}OP$A1L* zGb5vNzHtixF_+K|=rcmU#ik~RK^A=Z6-OA&_MpT`1s4B@8h9$0J2|>$#4T^{=i5c-)ZL=sj6L=@wy7^T zlraf%-S6oar-gmBlP^{%iXV(3t3>uxIT1eusGa`;te(;a*X#c<(}K0XKu^}GMZLU< z$K=g*oDAl>wDD`^3GEHA#Dm{G)Xu867V^w148tofnZPjtxO;NWd75^%>h>Mi`0?YEu-{uL9dMn^9fLOF=7`xpD@6pF5x8&` z0Tuzeo<(z#0}oLBU7jjgwBJ(OQtwl07yuDzvYo~GQN#%eZmvg>AM5pppPbY5aZeG+2J+r}rEd1R$-H2q1>?4H8+d2?r5s&+2 zW0k9T_s6jmM^Cg7reAmO(LH`;d*p?5& z=x4?XB3_;6Y^PVuNJ>_zF7?7fA>OceAS+2yFOCFvZM!xzYAJA~@_EBpkOHEudopA> zUV-7l&)!PQ0?GuLS95Uwj2-LVWmZu$=Fd-uon9W$?TShzv0oO6+;;$E=2t!Jr04gx zPHdGrKd2ZpdwEBnB8;Ch&c} zyx7We*+5Ey*x`kq`?&&Zyd>vy0lrZ#O(1(j8Y|Hg6|3B$#Z^;H-R*y3!Y==_|aK+?E%p;2I4DWbtVj zp4(}~sq;*Nfva11#o*{7aggZhke{zt(@x{vzgI#pdt` L96Lzj`|JD<1`d+B diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java index 3ca01ffc0..2b80740c7 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java @@ -17,10 +17,13 @@ import junit.framework.TestCase; import org.aspectj.weaver.BcweaverTests; import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.TypeX; import org.aspectj.weaver.World; import org.aspectj.weaver.bcel.BcelShadow; import org.aspectj.weaver.bcel.BcelWorld; +import sun.reflect.generics.tree.TypeVariableSignature; + /** * @author hugunin * @@ -229,6 +232,154 @@ public class ParserTestCase extends TestCase { assertEquals("@args(Foo, Goo, ANY, .., Moo)",p.toString()); } + public void testParseSimpleTypeVariable() { + PatternParser parser = new PatternParser("T"); + TypeVariable tv = parser.parseTypeVariable(); + TypeVariable expected = new TypeVariable("T"); + assertEquals("Expected simple type variable T",expected,tv); + } + + public void testParseExtendingTypeVariable() { + PatternParser parser = new PatternParser("T extends Number"); + TypeVariable tv = parser.parseTypeVariable(); + TypeVariable expected = new TypeVariable("T",new PatternParser("Number").parseTypePattern()); + assertEquals("Expected type variable T extends Number",expected,tv); + } + + public void testParseExtendingTypeVariableWithPattern() { + PatternParser parser = new PatternParser("T extends Number+"); + TypeVariable tv = parser.parseTypeVariable(); + TypeVariable expected = new TypeVariable("T",new PatternParser("Number+").parseTypePattern()); + assertEquals("Expected type variable T extends Number+",expected,tv); + } + + public void testParseExtendingTypeVariableWithInterface() { + PatternParser parser = new PatternParser("T extends Number & Comparable"); + TypeVariable tv = parser.parseTypeVariable(); + TypeVariable expected = new TypeVariable("T",new PatternParser("Number").parseTypePattern(), + new TypePattern[] {new PatternParser("Comparable").parseTypePattern()},null); + assertEquals("Expected type variable T extends Number",expected,tv); + } + + public void testParseExtendingTypeVariableWithInterfaceList() { + PatternParser parser = new PatternParser("T extends Number & Comparable & Cloneable"); + TypeVariable tv = parser.parseTypeVariable(); + TypeVariable expected = new TypeVariable("T",new PatternParser("Number").parseTypePattern(), + new TypePattern[] {new PatternParser("Comparable").parseTypePattern(), + new PatternParser("Cloneable").parseTypePattern()},null); + assertEquals("Expected type variable T extends Number",expected,tv); + } + + public void testParseTypeParameterList() { + PatternParser parser = new PatternParser(""); + TypeVariablePatternList list = parser.maybeParseTypeVariableList(); + TypeVariable[] patterns = list.getTypeVariablePatterns(); + TypeVariable expected = new TypeVariable("T"); + assertEquals("Expected simple type variable T",expected,patterns[0]); + assertEquals("One pattern in list",1,patterns.length); + } + + public void testParseTypeParameterListWithSeveralTypeParameters() { + PatternParser parser = new PatternParser(""); + TypeVariablePatternList list = parser.maybeParseTypeVariableList(); + TypeVariable[] patterns = list.getTypeVariablePatterns(); + TypeVariable expected0 = new TypeVariable("T"); + assertEquals("Expected simple type variable T",expected0,patterns[0]); + TypeVariable expected1 = new TypeVariable("S",new PatternParser("Number").parseTypePattern()); + assertEquals("Expected type variable S extends Number",expected1,patterns[1]); + TypeVariable expected2 = new TypeVariable("R"); + assertEquals("Expected simple type variable R",expected2,patterns[2]); + + assertEquals("3 patterns in list",3,patterns.length); + } + + + public void testParseAllowedSuperInTypeVariable() { + PatternParser parser = new PatternParser("T super Number+"); + TypeVariable tv = parser.parseTypeVariable(); + TypeVariable expected = new TypeVariable("T",new ExactTypePattern(TypeX.OBJECT,false,false),null,new PatternParser("Number+").parseTypePattern()); + assertEquals("Expected type variable T super Number+",expected,tv); + } + + public void testParseAnythingTypeVariable() { + PatternParser parser = new PatternParser("?"); + 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,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,false); + assertEquals("Expected type variable ?","?",tp.maybeGetSimpleName()); + assertEquals("lower Bound of Number+",new PatternParser("Number+").parseTypePattern(),tp.getLowerBound()); + } + + public void testParseDeclareParentsWithTypeParameterList() { + PatternParser parser = new PatternParser("declare parents : Foo implements IveGoneMad"); + DeclareParents decp = (DeclareParents) parser.parseDeclare(); + TypeVariablePatternList tvp = decp.getTypeParameters(); + assertEquals("one type parameter",1,tvp.getTypeVariablePatterns().length); + assertEquals("expecting T","T",tvp.getTypeVariablePatterns()[0].getName()); + } + + public void testParameterizedTypePatternsAny() { + PatternParser parser = new PatternParser("*"); + WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(false,true); + TypePatternList tvs = wtp.getTypeParameters(); + assertEquals("2 type parameters",2,tvs.getTypePatterns().length); + assertEquals("T",new PatternParser("T").parseTypePattern(),tvs.getTypePatterns()[0]); + assertEquals("S extends Number",new PatternParser("S extends Number").parseTypePattern(false,true),tvs.getTypePatterns()[1]); + } + + public void testParameterizedTypePatternsSimple() { + PatternParser parser = new PatternParser("List"); + WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(); + TypePatternList tvs = wtp.getTypeParameters(); + assertEquals("1 type parameter",1,tvs.getTypePatterns().length); + assertEquals("String",new PatternParser("String").parseTypePattern(),tvs.getTypePatterns()[0]); + assertEquals("List",wtp.getNamePatterns()[0].toString()); + } + + public void testNestedParameterizedTypePatterns() { + PatternParser parser = new PatternParser("List>>"); + WildTypePattern wtp = (WildTypePattern) parser.parseTypePattern(); + TypePatternList typeParameters = wtp.getTypeParameters(); + WildTypePattern expected = (WildTypePattern) typeParameters.getTypePatterns()[0]; + assertEquals("expecting a List", "List",expected.maybeGetSimpleName()); + typeParameters = expected.getTypeParameters(); + expected = (WildTypePattern) typeParameters.getTypePatterns()[0]; + assertEquals("expecting a List", "List",expected.maybeGetSimpleName()); + typeParameters = expected.getTypeParameters(); + expected = (WildTypePattern) typeParameters.getTypePatterns()[0]; + assertEquals("expecting a String", "String",expected.maybeGetSimpleName()); + } + + public void testSimpleTypeVariableList() { + PatternParser parser = new PatternParser(""); + TypeVariablePatternList tl = parser.maybeParseSimpleTypeVariableList(); + TypeVariable[] patterns = tl.getTypeVariablePatterns(); + assertEquals("3 patterns",3,patterns.length); + assertEquals("T",new TypeVariable("T"),patterns[0]); + assertEquals("S",new TypeVariable("S"),patterns[1]); + assertEquals("V",new TypeVariable("V"),patterns[2]); + } + + public void testSimpleTypeVariableListError() { + PatternParser parser = new PatternParser(""); + try { + TypeVariablePatternList tl = parser.maybeParseSimpleTypeVariableList(); + } catch (ParserException ex) { + assertEquals("Expecting >",">",ex.getMessage()); + } + } + public TestScope makeSimpleScope() { TestScope s = new TestScope(new String[] {"int", "java.lang.String"}, new String[] {"a", "b"}, world); s.setImportedPrefixes(new String[]{"p."}); diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java index 039bf89d5..857c82171 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/PointcutTestCase.java @@ -31,6 +31,10 @@ public class PointcutTestCase extends TestCase { public void testMatchJP() { Pointcut p = new Pointcut() { + public Object accept(PatternNodeVisitor visitor, Object data) { + return visitor.visit(this,data); + } + public Set couldMatchKinds() { return null; } @@ -38,6 +42,10 @@ public class PointcutTestCase extends TestCase { public FuzzyBoolean fastMatch(FastMatchInfo info) { return null; } + + public FuzzyBoolean fastMatch(Class targetClass) { + return null; + } protected FuzzyBoolean matchInternal(Shadow shadow) { return null; diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/VisitorTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/VisitorTestCase.java index b3a2a73bf..12218df8b 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/VisitorTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/VisitorTestCase.java @@ -50,7 +50,7 @@ public class VisitorTestCase extends TestCase { for (Iterator iterator = pointcuts.iterator(); iterator.hasNext();) { String pointcut = (String) iterator.next(); try { - PointcutVisitor.DumpPointcutVisitor.check(pointcut); + PatternNodeVisitor.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(); - PointcutVisitor.DumpPointcutVisitor.check(p, true); + PatternNodeVisitor.DumpPointcutVisitor.check(p, true); } catch (Throwable t) { fail("Failed on '"+tp+"': " +t.toString()); } diff --git a/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java b/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java index 411716b95..6e3e3d35e 100644 --- a/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java +++ b/weaver/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java @@ -468,6 +468,20 @@ public class PointcutExpressionTest extends TestCase { PointcutExpression ex = p.parsePointcutExpression("staticinitialization(*..A+)"); assertEquals("staticinitialization(*..A+)",ex.getPointcutExpression()); } + + public void testCouldMatchJoinPointsInType() { + PointcutExpression ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..))"); + assertFalse("Could never match String",ex.couldMatchJoinPointsInType(String.class)); + assertTrue("Will always match B",ex.couldMatchJoinPointsInType(B.class)); + assertFalse("Does not match A",ex.couldMatchJoinPointsInType(A.class)); + } + + public void testMayNeedDynamicTest() { + PointcutExpression ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..))"); + assertFalse("No dynamic test needed",ex.mayNeedDynamicTest()); + ex = p.parsePointcutExpression("execution(* org.aspectj.weaver.tools.PointcutExpressionTest.B.*(..)) && args(X)"); + assertTrue("Dynamic test needed",ex.mayNeedDynamicTest()); + } protected void setUp() throws Exception { super.setUp(); -- 2.39.5