diff options
author | acolyer <acolyer> | 2004-06-09 15:44:29 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2004-06-09 15:44:29 +0000 |
commit | 0ffb7cb8f5b01873495f1d419e4f59c13816325c (patch) | |
tree | 09fbb7ca8a9c18b2129d572b0d7f8f8e8fa10d34 | |
parent | a410567f2d9da6df3cfa51af84a6f7bc5a9c0418 (diff) | |
download | aspectj-0ffb7cb8f5b01873495f1d419e4f59c13816325c.tar.gz aspectj-0ffb7cb8f5b01873495f1d419e4f59c13816325c.zip |
ensure args() handles boxed primitives correctly when doing
runtime matching (against JoinPoint)
5 files changed, 132 insertions, 7 deletions
diff --git a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java index efc1219c0..0af3ececc 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ArgsPointcut.java @@ -16,11 +16,14 @@ package org.aspectj.weaver.patterns; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.Collection; +import java.util.Iterator; import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.reflect.CodeSignature; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.BetaException; import org.aspectj.weaver.ISourceContext; @@ -55,7 +58,37 @@ public class ArgsPointcut extends NameBindingPointcut { } public FuzzyBoolean match(JoinPoint jp, JoinPoint.StaticPart jpsp) { - return arguments.matches(jp.getArgs(),TypePattern.DYNAMIC); + FuzzyBoolean ret = arguments.matches(jp.getArgs(),TypePattern.DYNAMIC); + // this may have given a false match (e.g. args(int) may have matched a call to doIt(Integer x)) due to boxing + // check for this... + if (ret == FuzzyBoolean.YES) { + // are the sigs compatible too... + CodeSignature sig = (CodeSignature)jp.getSignature(); + Class[] pTypes = sig.getParameterTypes(); + Collection tps = arguments.getExactTypes(); + int sigIndex = 0; + for (Iterator iter = tps.iterator(); iter.hasNext();) { + TypeX tp = (TypeX) iter.next(); + Class lookForClass = getPossiblyBoxed(tp); + if (lookForClass != null) { + boolean foundMatchInSig = false; + while (sigIndex < pTypes.length && !foundMatchInSig) { + if (pTypes[sigIndex++] == lookForClass) foundMatchInSig = true; + } + if (!foundMatchInSig) { + ret = FuzzyBoolean.NO; + break; + } + } + } + } + return ret; + } + + private Class getPossiblyBoxed(TypeX tp) { + Class ret = (Class) ExactTypePattern.primitiveTypesMap.get(tp.getName()); + if (ret == null) ret = (Class) ExactTypePattern.boxedPrimitivesMap.get(tp.getName()); + return ret; } public void write(DataOutputStream s) throws IOException { diff --git a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java index 99ecf9012..3aa3400ca 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/ExactTypePattern.java @@ -16,6 +16,9 @@ package org.aspectj.weaver.patterns; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.BCException; @@ -26,6 +29,41 @@ import org.aspectj.weaver.TypeX; public class ExactTypePattern extends TypePattern { protected TypeX type; + public static final Map primitiveTypesMap; + public static final Map boxedPrimitivesMap; + private static final Map boxedTypesMap; + + static { + primitiveTypesMap = new HashMap(); + primitiveTypesMap.put("int",int.class); + primitiveTypesMap.put("short",short.class); + primitiveTypesMap.put("long",long.class); + primitiveTypesMap.put("byte",byte.class); + primitiveTypesMap.put("char",char.class); + primitiveTypesMap.put("float",float.class); + primitiveTypesMap.put("double",double.class); + + boxedPrimitivesMap = new HashMap(); + boxedPrimitivesMap.put("java.lang.Integer",Integer.class); + boxedPrimitivesMap.put("java.lang.Short",Short.class); + boxedPrimitivesMap.put("java.lang.Long",Long.class); + boxedPrimitivesMap.put("java.lang.Byte",Byte.class); + boxedPrimitivesMap.put("java.lang.Character",Character.class); + boxedPrimitivesMap.put("java.lang.Float",Float.class); + boxedPrimitivesMap.put("java.lang.Double",Double.class); + + + boxedTypesMap = new HashMap(); + boxedTypesMap.put("int",Integer.class); + boxedTypesMap.put("short",Short.class); + boxedTypesMap.put("long",Long.class); + boxedTypesMap.put("byte",Byte.class); + boxedTypesMap.put("char",Character.class); + boxedTypesMap.put("float",Float.class); + boxedTypesMap.put("double",Double.class); + + } + public ExactTypePattern(TypeX type, boolean includeSubtypes) { super(includeSubtypes); this.type = type; @@ -50,7 +88,7 @@ public class ExactTypePattern extends TypePattern { public boolean matchesExactly(Class matchType) { try { - Class toMatchAgainst = Class.forName(type.getName()); + Class toMatchAgainst = getClassFor(type.getName()); return matchType == toMatchAgainst; } catch (ClassNotFoundException cnfEx) { return false; @@ -61,13 +99,29 @@ public class ExactTypePattern extends TypePattern { if (matchType.equals(Object.class)) return FuzzyBoolean.YES; try { - Class toMatchAgainst = Class.forName(type.getName()); - return toMatchAgainst.isAssignableFrom(matchType) ? FuzzyBoolean.YES : FuzzyBoolean.NO; + String typeName = type.getName(); + Class toMatchAgainst = getClassFor(typeName); + FuzzyBoolean ret = FuzzyBoolean.fromBoolean(toMatchAgainst.isAssignableFrom(matchType)); + if (ret == FuzzyBoolean.NO) { + if (boxedTypesMap.containsKey(typeName)) { + // try again with 'boxed' alternative + toMatchAgainst = (Class) boxedTypesMap.get(typeName); + ret = FuzzyBoolean.fromBoolean(toMatchAgainst.isAssignableFrom(matchType)); + } + } + return ret; } catch (ClassNotFoundException cnfEx) { return FuzzyBoolean.NO; } } + private Class getClassFor(String typeName) throws ClassNotFoundException { + Class ret = null; + ret = (Class) primitiveTypesMap.get(typeName); + if (ret == null) ret = Class.forName(typeName); + return ret; + } + public boolean equals(Object other) { if (!(other instanceof ExactTypePattern)) return false; ExactTypePattern o = (ExactTypePattern)other; diff --git a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java index ad6b88fb4..ecb29ea5c 100644 --- a/weaver/src/org/aspectj/weaver/patterns/TypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/TypePattern.java @@ -97,11 +97,23 @@ public abstract class TypePattern extends PatternNode { } } + /** + * This variant is only called by the args and handler pcds when doing runtime + * matching. We need to handle primitive types correctly in this case (an Integer + * should match an int,...). + */ public final FuzzyBoolean matches(Object o, MatchKind kind) { - if (kind == STATIC) { + if (kind == STATIC) { // handler pcd return FuzzyBoolean.fromBoolean(matchesStatically(o.getClass())); - } else if (kind == DYNAMIC) { - return FuzzyBoolean.fromBoolean(matchesSubtypes(o.getClass())); + } else if (kind == DYNAMIC) { // args pcd +// Class clazz = o.getClass(); +// FuzzyBoolean ret = FuzzyBoolean.fromBoolean(matchesSubtypes(clazz)); +// if (ret == FuzzyBoolean.NO) { +// // try primitive type instead +// if (clazz == Integer.class) ret = FuzzyBoolean.fromBoolean(matchesExactly(int.class)); +// } +// return ret; + return matchesInstanceof(o.getClass()); } else { throw new IllegalArgumentException("kind must be DYNAMIC or STATIC"); } diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java index 92c27f05e..36004cfc5 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ArgsTestCase.java @@ -69,6 +69,30 @@ public class ArgsTestCase extends TestCase { } + public void testMatchJPWithPrimitiveTypes() { + try { + Factory f = new Factory("ArgsTestCase.java",ArgsTestCase.A.class); + + Pointcut oneInt = new PatternParser("args(int)").parsePointcut().resolve(); + Pointcut oneInteger = new PatternParser("args(Integer)").parsePointcut().resolve(); + + JoinPoint.StaticPart oneIntjp = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {int.class},new String[] {"i"},new Class[] {},null) ,1); + JoinPoint.StaticPart oneIntegerjp = f.makeSJP(JoinPoint.METHOD_EXECUTION,f.makeMethodSig(0,"aMethod",A.class,new Class[] {Integer.class},new String[] {"i"},new Class[] {},null),1); + + JoinPoint oneIntArg = Factory.makeJP(oneIntjp,new A(),new A(),new Integer(3)); + JoinPoint oneIntegerArg = Factory.makeJP(oneIntegerjp,new A(), new A(), new Integer(7)); + + checkMatches(oneInt,oneIntArg,null,FuzzyBoolean.YES); + checkMatches(oneInt,oneIntegerArg,null,FuzzyBoolean.NO); + checkMatches(oneInteger,oneIntArg,null,FuzzyBoolean.NO); + checkMatches(oneInteger,oneIntegerArg,null,FuzzyBoolean.YES); + + } catch( Exception ex) { + fail("Unexpected exception " + ex); + } + + } + private void checkMatches(Pointcut p, JoinPoint jp, JoinPoint.StaticPart jpsp, FuzzyBoolean expected) { assertEquals(expected,p.match(jp,jpsp)); } diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java index 0da791619..d344f89f7 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/KindedTestCase.java @@ -49,6 +49,7 @@ public class KindedTestCase extends TestCase { JoinPoint.StaticPart execonsjp2 = f.makeSJP(JoinPoint.CONSTRUCTOR_EXECUTION,f.makeConstructorSig(0,String.class,new Class[] {String.class},new String[]{"s"},new Class[0]),1); JoinPoint.StaticPart initjp1 = f.makeSJP(JoinPoint.INITIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[0],new String[0],new Class[0]),1); JoinPoint.StaticPart initjp2 = f.makeSJP(JoinPoint.PREINTIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[]{int.class, int.class},new String[]{"a","b"},new Class[0]),1); + JoinPoint.StaticPart initjp3 = f.makeSJP(JoinPoint.PREINTIALIZATION,f.makeConstructorSig(0,Hello.class,new Class[]{Integer.class, Integer.class},new String[]{"a","b"},new Class[0]),1); JoinPoint.StaticPart sinitjp1 = f.makeSJP(JoinPoint.STATICINITIALIZATION,f.makeInitializerSig(Modifier.STATIC,Hello.class),1); JoinPoint.StaticPart sinitjp2 = f.makeSJP(JoinPoint.STATICINITIALIZATION,f.makeInitializerSig(Modifier.STATIC,String.class),1); JoinPoint.StaticPart getjp1 = f.makeSJP(JoinPoint.FIELD_GET,f.makeFieldSig(0,"x",Hello.class,int.class),1); @@ -71,6 +72,7 @@ public class KindedTestCase extends TestCase { checkMatches(initpc,initjp2,FuzzyBoolean.NO); checkMatches(preinitpc,initjp1,FuzzyBoolean.NO); checkMatches(preinitpc,initjp2,FuzzyBoolean.YES); + checkMatches(preinitpc,initjp3,FuzzyBoolean.NO); checkMatches(staticinitpc,sinitjp1,FuzzyBoolean.YES); checkMatches(staticinitpc,sinitjp2,FuzzyBoolean.NO); checkMatches(getpc,getjp1,FuzzyBoolean.YES); |