From d3da67c03dc7d19782d60d82fdf8fc7c7895280e Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Fri, 25 Jan 2019 15:14:30 -0800 Subject: mavenizing weaver - wip --- weaver/src/test/java/$Proxy1.java | 28 + weaver/src/test/java/CounterAspect.java | 52 ++ weaver/src/test/java/GenericService.java | 17 + weaver/src/test/java/MA.java | 15 + weaver/src/test/java/MB.java | 15 + weaver/src/test/java/MC.java | 15 + weaver/src/test/java/MD.java | 15 + weaver/src/test/java/MessageService.java | 13 + weaver/src/test/java/fluffy/Aspect.java | 29 + weaver/src/test/java/fluffy/Base.java | 18 + weaver/src/test/java/fluffy/Derived.java | 20 + ...lectionWorldAdvancedPointcutExpressionTest.java | 30 + .../java/org/aspectj/weaver/AbstractTraceTest.java | 153 ++++ .../java/org/aspectj/weaver/AllWeaver5Tests.java | 40 + .../org/aspectj/weaver/BcweaverModule15Test.java | 41 + .../weaver/BoundedReferenceTypeTestCase.java | 106 +++ .../aspectj/weaver/CommonReferenceTypeTests.java | 91 +++ .../aspectj/weaver/CommonsTraceFactoryTest.java | 26 + .../java/org/aspectj/weaver/CommonsTraceTest.java | 35 + .../aspectj/weaver/DefaultTraceFactoryTest.java | 30 + .../java/org/aspectj/weaver/DefaultTraceTest.java | 38 + .../test/java/org/aspectj/weaver/DumpTestCase.java | 147 ++++ .../aspectj/weaver/GenericSignatureParserTest.java | 63 ++ ...a5ReflectionBasedReferenceTypeDelegateTest.java | 154 ++++ .../org/aspectj/weaver/Jdk14TraceFactoryTest.java | 30 + .../java/org/aspectj/weaver/Jdk14TraceTest.java | 34 + .../weaver/JoinPointSignatureIteratorTest.java | 107 +++ .../test/java/org/aspectj/weaver/LocaleTest.java | 53 ++ .../test/java/org/aspectj/weaver/Member15Test.java | 155 ++++ .../java/org/aspectj/weaver/Member15TestCase.java | 81 ++ .../java/org/aspectj/weaver/MemberTestCase.java | 183 +++++ .../weaver/ParameterizedReferenceTypeTestCase.java | 84 ++ .../org/aspectj/weaver/ReferenceTypeTestCase.java | 854 +++++++++++++++++++++ .../weaver/ResolvedMemberSignatures15TestCase.java | 281 +++++++ .../test/java/org/aspectj/weaver/TestShadow.java | 131 ++++ .../java/org/aspectj/weaver/TraceFactoryTest.java | 31 + .../weaver/TypeVariableReferenceTypeTestCase.java | 81 ++ .../org/aspectj/weaver/TypeVariableTestCase.java | 110 +++ .../java/org/aspectj/weaver/TypeXTestCase.java | 219 ++++++ .../org/aspectj/weaver/Weaver5ModuleTests.java | 37 + .../org/aspectj/weaver/WeaverMessagesTestCase.java | 47 ++ .../java/org/aspectj/weaver/WeaverTestCase.java | 50 ++ .../weaver/bcel/AfterReturningWeaveTestCase.java | 58 ++ .../weaver/bcel/AfterThrowingWeaveTestCase.java | 45 ++ .../aspectj/weaver/bcel/AfterWeaveTestCase.java | 31 + .../org/aspectj/weaver/bcel/ArgsWeaveTestCase.java | 119 +++ .../weaver/bcel/AroundArgsWeaveTestCase.java | 41 + .../aspectj/weaver/bcel/AroundWeaveTestCase.java | 100 +++ .../bcel/BcelGenericSignatureToTypeXTestCase.java | 68 ++ .../org/aspectj/weaver/bcel/BcelTestUtils.java | 65 ++ .../weaver/bcel/BcelWorldReferenceTypeTest.java | 23 + .../aspectj/weaver/bcel/BeforeWeaveTestCase.java | 31 + .../org/aspectj/weaver/bcel/CheckerTestCase.java | 48 ++ .../weaver/bcel/ClassLoaderRepositoryTest.java | 213 +++++ .../org/aspectj/weaver/bcel/FieldSetTestCase.java | 34 + .../weaver/bcel/HierarchyDependsTestCase.java | 63 ++ .../org/aspectj/weaver/bcel/IdWeaveTestCase.java | 101 +++ .../org/aspectj/weaver/bcel/JImageTestCase.java | 139 ++++ .../org/aspectj/weaver/bcel/MegaZipTestCase.java | 107 +++ .../weaver/bcel/MoveInstructionsWeaveTestCase.java | 81 ++ .../weaver/bcel/NonstaticWeaveTestCase.java | 83 ++ .../aspectj/weaver/bcel/PatternWeaveTestCase.java | 122 +++ .../weaver/bcel/PointcutResidueTestCase.java | 189 +++++ .../org/aspectj/weaver/bcel/TjpWeaveTestCase.java | 99 +++ .../aspectj/weaver/bcel/TraceJarWeaveTestCase.java | 40 + .../org/aspectj/weaver/bcel/UtilityTestCase.java | 52 ++ .../aspectj/weaver/bcel/WeaveOrderTestCase.java | 149 ++++ .../org/aspectj/weaver/bcel/WeaveTestCase.java | 318 ++++++++ .../org/aspectj/weaver/bcel/WorldTestCase.java | 163 ++++ .../org/aspectj/weaver/bcel/ZipFileWeaver.java | 39 + .../java/org/aspectj/weaver/bcel/ZipTestCase.java | 121 +++ .../AnnotationPatternMatchingTestCase.java | 252 ++++++ .../weaver/patterns/AnnotationPatternTestCase.java | 382 +++++++++ .../weaver/patterns/ConcretizationTestCase.java | 116 +++ .../WildTypePatternResolutionTestCase.java | 422 ++++++++++ .../weaver/patterns/bcel/BcelAndOrNotTestCase.java | 24 + .../weaver/patterns/bcel/BcelBindingTestCase.java | 24 + .../bcel/BcelModifiersPatternTestCase.java | 24 + .../weaver/patterns/bcel/BcelParserTestCase.java | 25 + .../bcel/BcelSignaturePatternTestCase.java | 24 + .../patterns/bcel/BcelTypePatternListTestCase.java | 23 + .../patterns/bcel/BcelTypePatternTestCase.java | 24 + .../weaver/patterns/bcel/BcelWithinTestCase.java | 23 + .../ReflectionBasedReferenceTypeDelegateTest.java | 316 ++++++++ .../reflect/ReflectionWorldReferenceTypeTest.java | 27 + .../weaver/reflect/ReflectionWorldTest.java | 290 +++++++ .../weaver/tools/Java15PointcutExpressionTest.java | 746 ++++++++++++++++++ .../tools/PointcutDesignatorHandlerTest.java | 251 ++++++ .../weaver/tools/PointcutExpressionTest.java | 596 ++++++++++++++ .../aspectj/weaver/tools/PointcutParserTest.java | 391 ++++++++++ .../weaver/tools/ReadingAttributesTest.java | 66 ++ .../weaver/tools/TypePatternMatcherTest.java | 55 ++ .../cache/AbstractCacheBackingTestSupport.java | 379 +++++++++ .../AsynchronousFileCacheBackingTestSupport.java | 193 +++++ .../tools/cache/DefaultCacheKeyResolverTest.java | 95 +++ .../tools/cache/DefaultFileCacheBackingTest.java | 179 +++++ .../tools/cache/FlatFileCacheBackingTest.java | 147 ++++ .../weaver/tools/cache/SimpleClassCacheTest.java | 71 ++ .../weaver/tools/cache/WeavedClassCacheTest.java | 152 ++++ .../tools/cache/ZippedFileCacheBackingTest.java | 154 ++++ weaver/src/test/java/reflect/tests/C.java | 33 + weaver/src/test/java/test/A.java | 27 + weaver/src/test/java/test/A1.java | 20 + weaver/src/test/java/test/A1AnnotatedType.java | 17 + weaver/src/test/java/test/A2.java | 20 + weaver/src/test/java/test/A2AnnotatedType.java | 17 + weaver/src/test/java/test/A3.java | 19 + weaver/src/test/java/test/AnnoValues.java | 20 + weaver/src/test/java/test/Color.java | 14 + 109 files changed, 12159 insertions(+) create mode 100644 weaver/src/test/java/$Proxy1.java create mode 100644 weaver/src/test/java/CounterAspect.java create mode 100644 weaver/src/test/java/GenericService.java create mode 100644 weaver/src/test/java/MA.java create mode 100644 weaver/src/test/java/MB.java create mode 100644 weaver/src/test/java/MC.java create mode 100644 weaver/src/test/java/MD.java create mode 100644 weaver/src/test/java/MessageService.java create mode 100644 weaver/src/test/java/fluffy/Aspect.java create mode 100644 weaver/src/test/java/fluffy/Base.java create mode 100644 weaver/src/test/java/fluffy/Derived.java create mode 100644 weaver/src/test/java/org/aspectj/matcher/tools/ReflectionWorldAdvancedPointcutExpressionTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/AbstractTraceTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/AllWeaver5Tests.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/BcweaverModule15Test.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/BoundedReferenceTypeTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/CommonReferenceTypeTests.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/CommonsTraceFactoryTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/CommonsTraceTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/DefaultTraceFactoryTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/DefaultTraceTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/DumpTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/GenericSignatureParserTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/Java5ReflectionBasedReferenceTypeDelegateTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/Jdk14TraceFactoryTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/Jdk14TraceTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/JoinPointSignatureIteratorTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/LocaleTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/Member15Test.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/Member15TestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/MemberTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/ReferenceTypeTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/ResolvedMemberSignatures15TestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/TestShadow.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/TraceFactoryTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/TypeVariableTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/TypeXTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/Weaver5ModuleTests.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/WeaverMessagesTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/WeaverTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/AfterReturningWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/AfterWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/AroundArgsWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/AroundWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/BcelTestUtils.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/BcelWorldReferenceTypeTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/BeforeWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/CheckerTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/ClassLoaderRepositoryTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/FieldSetTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/IdWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/JImageTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/MegaZipTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/PatternWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/PointcutResidueTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/TjpWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/TraceJarWeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/UtilityTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/WeaveOrderTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/WeaveTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/WorldTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/ZipFileWeaver.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/bcel/ZipTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/ConcretizationTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/WildTypePatternResolutionTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelAndOrNotTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelBindingTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelModifiersPatternTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelParserTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelSignaturePatternTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternListTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelWithinTestCase.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldReferenceTypeTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/PointcutDesignatorHandlerTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/PointcutExpressionTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/PointcutParserTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/ReadingAttributesTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/TypePatternMatcherTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/AbstractCacheBackingTestSupport.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/AsynchronousFileCacheBackingTestSupport.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultCacheKeyResolverTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultFileCacheBackingTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/FlatFileCacheBackingTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/SimpleClassCacheTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/WeavedClassCacheTest.java create mode 100644 weaver/src/test/java/org/aspectj/weaver/tools/cache/ZippedFileCacheBackingTest.java create mode 100644 weaver/src/test/java/reflect/tests/C.java create mode 100644 weaver/src/test/java/test/A.java create mode 100644 weaver/src/test/java/test/A1.java create mode 100644 weaver/src/test/java/test/A1AnnotatedType.java create mode 100644 weaver/src/test/java/test/A2.java create mode 100644 weaver/src/test/java/test/A2AnnotatedType.java create mode 100644 weaver/src/test/java/test/A3.java create mode 100644 weaver/src/test/java/test/AnnoValues.java create mode 100644 weaver/src/test/java/test/Color.java (limited to 'weaver/src/test') diff --git a/weaver/src/test/java/$Proxy1.java b/weaver/src/test/java/$Proxy1.java new file mode 100644 index 000000000..51cae8b05 --- /dev/null +++ b/weaver/src/test/java/$Proxy1.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2009 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; + +public class $Proxy1 extends Proxy implements MessageService { + + protected $Proxy1(InvocationHandler arg0) { + super(arg0); + } + + public Object get1(Long t) { + return null; + } + + public Object get2(Serializable s) { + return null; + } +} diff --git a/weaver/src/test/java/CounterAspect.java b/weaver/src/test/java/CounterAspect.java new file mode 100644 index 000000000..1ca126d02 --- /dev/null +++ b/weaver/src/test/java/CounterAspect.java @@ -0,0 +1,52 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; + +/** + * Created to enable PointcutDesignatorHandlerTests.testParsingBeanInReferencePointcut01 and 02 to run + * + * @author Andy Clement + */ +@Aspect +public class CounterAspect { + + int count; + + @Before("execution(* set*(..)) && bean(testBean1)") + public void increment1ForAnonymousPointcut() { + count++; + } + + @Pointcut("execution(* toString(..)) && bean(testBean1)") + public void testBean1toString() { + } + + @Pointcut("execution(* setAge(..)) && bean(testBean1)") + public void testBean1SetAge() { + } + + @Pointcut("execution(* setAge(..)) && bean(testBean2)") + public void testBean2SetAge() { + } + + @Before("testBean1SetAge()") + public void increment1() { + count++; + } + + @Before("testBean2SetAge()") + public void increment2() { + count++; + } +} \ No newline at end of file diff --git a/weaver/src/test/java/GenericService.java b/weaver/src/test/java/GenericService.java new file mode 100644 index 000000000..87f5c0419 --- /dev/null +++ b/weaver/src/test/java/GenericService.java @@ -0,0 +1,17 @@ +/******************************************************************************* + * Copyright (c) 2009 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +import java.io.Serializable; + +public interface GenericService { + Object get1(T t); + + Object get2(Serializable s); +} diff --git a/weaver/src/test/java/MA.java b/weaver/src/test/java/MA.java new file mode 100644 index 000000000..270882586 --- /dev/null +++ b/weaver/src/test/java/MA.java @@ -0,0 +1,15 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ + +public @interface MA { + +} diff --git a/weaver/src/test/java/MB.java b/weaver/src/test/java/MB.java new file mode 100644 index 000000000..3ff3eede4 --- /dev/null +++ b/weaver/src/test/java/MB.java @@ -0,0 +1,15 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ + +public @interface MB { + +} diff --git a/weaver/src/test/java/MC.java b/weaver/src/test/java/MC.java new file mode 100644 index 000000000..d48133baf --- /dev/null +++ b/weaver/src/test/java/MC.java @@ -0,0 +1,15 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ + +public @interface MC { + +} diff --git a/weaver/src/test/java/MD.java b/weaver/src/test/java/MD.java new file mode 100644 index 000000000..47a61cba0 --- /dev/null +++ b/weaver/src/test/java/MD.java @@ -0,0 +1,15 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ + +public @interface MD { + +} diff --git a/weaver/src/test/java/MessageService.java b/weaver/src/test/java/MessageService.java new file mode 100644 index 000000000..160aecc21 --- /dev/null +++ b/weaver/src/test/java/MessageService.java @@ -0,0 +1,13 @@ +/******************************************************************************* + * Copyright (c) 2009 Contributors + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +public interface MessageService extends GenericService { + +} diff --git a/weaver/src/test/java/fluffy/Aspect.java b/weaver/src/test/java/fluffy/Aspect.java new file mode 100644 index 000000000..401ce9ba8 --- /dev/null +++ b/weaver/src/test/java/fluffy/Aspect.java @@ -0,0 +1,29 @@ +package fluffy; +import org.aspectj.runtime.internal.AroundClosure; + +public class Aspect { + + public static void ignoreMe() {} + + public static void before_method_call() { + System.out.println("before"); + } + + public static void afterReturning_method_call() { + System.out.println("afterReturning"); + } + + public static void afterThrowing_method_execution(Throwable t) { + System.out.println("afterThrowing " + t); + t.printStackTrace(); + } + + public static Object aroundFun(AroundClosure c) { + System.out.println("around"); + try { + return c.run(new Object[0]); + } catch (Throwable t) { + return null; + } + } +} diff --git a/weaver/src/test/java/fluffy/Base.java b/weaver/src/test/java/fluffy/Base.java new file mode 100644 index 000000000..4cdb1f772 --- /dev/null +++ b/weaver/src/test/java/fluffy/Base.java @@ -0,0 +1,18 @@ +package fluffy; + +public class Base { + + public static void onlyBase() {} + public static void both() {} + + public void onlyBaseNonStatic() {} + public void bothNonStatic() {} + + public int onlyBase; + public int both; + + public Base() {} + public Base(int i) {} + + public void m() throws CloneNotSupportedException {} +} diff --git a/weaver/src/test/java/fluffy/Derived.java b/weaver/src/test/java/fluffy/Derived.java new file mode 100644 index 000000000..ad0842c18 --- /dev/null +++ b/weaver/src/test/java/fluffy/Derived.java @@ -0,0 +1,20 @@ +package fluffy; + +import java.io.IOException; + +public class Derived extends Base { + + public static void onlyDerived() throws IOException, CloneNotSupportedException {} + public static void both() {} + + public void onlyDerivedNonStatic() {} + public void bothNonStatic() {} + + public int onlyDerived; + public int both; + + public Derived() {} + + public void m() {} + +} diff --git a/weaver/src/test/java/org/aspectj/matcher/tools/ReflectionWorldAdvancedPointcutExpressionTest.java b/weaver/src/test/java/org/aspectj/matcher/tools/ReflectionWorldAdvancedPointcutExpressionTest.java new file mode 100644 index 000000000..9e16e65fb --- /dev/null +++ b/weaver/src/test/java/org/aspectj/matcher/tools/ReflectionWorldAdvancedPointcutExpressionTest.java @@ -0,0 +1,30 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.matcher.tools; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.reflect.ReflectionWorld; + +/** + * Run all the pointcut parsing/matching tests against a ReflectionWorld. + * + * @author Andy Clement + */ +public class ReflectionWorldAdvancedPointcutExpressionTest extends CommonAdvancedPointcutExpressionTests { + + protected World getWorld() { + World w = new ReflectionWorld(false, getClass().getClassLoader()); + w.setBehaveInJava5Way(true); + return w; + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/AbstractTraceTest.java b/weaver/src/test/java/org/aspectj/weaver/AbstractTraceTest.java new file mode 100644 index 000000000..334690b62 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/AbstractTraceTest.java @@ -0,0 +1,153 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import java.util.ArrayList; + +import junit.framework.TestCase; + +import org.aspectj.weaver.tools.AbstractTrace; +import org.aspectj.weaver.tools.DefaultTrace; +import org.aspectj.weaver.tools.Traceable; + +public abstract class AbstractTraceTest extends TestCase { + + protected AbstractTrace trace; + + public void testIsTraceEnabled() { + DefaultTrace trace = new DefaultTrace(getClass()); + assertFalse(trace.isTraceEnabled()); + } + + public void testEnterWithThisAndArgs() { + trace.enter("testEnterWithThisAndArgs",this,new Object[] { "arg1", "arg2" }); + } + + public void testEnterWithThisAndArray() { + Object arg1 = new String[] { "s1", "s2" }; + Object arg2 = new char[] { 'a', 'b', 'c' }; + trace.enter(getName(),this,new Object[] { arg1, arg2 }); + } + + public void testEnterWithThisAndCollection() { + Object arg1 = new ArrayList(); + trace.enter(getName(),this,new Object[] { arg1 }); + } + + public void testEnterWithThisAndTraceable () { + Object arg1 = new Traceable() { + + public String toTraceString() { + return getClass().getName() + "[Traceable]"; + } + + }; + trace.enter(getName(),this,new Object[] { arg1 }); + } + + public void testEnterWithThisAndToStringException () { + Object arg1 = new Object() { + + public String toString() { + throw new RuntimeException("toString() can throw an Exception"); + } + + }; + trace.enter(getName(),this,new Object[] { arg1 }); + } + + public void testEnterWithThisAndHashCodeException () { + Object arg1 = new Object() { + + public int hashCode() { + throw new RuntimeException("hashCode can throw an Exception"); + } + + }; + trace.enter(getName(),this,new Object[] { arg1 }); + } + + public void testEnterWithThisAndClassLoader () { + Object arg1 = new ClassLoader() { + + public String toString() { + throw new Error("Don't call ClassLoader.toString()"); + } + + }; + trace.enter(getName(),this,new Object[] { arg1 }); + } + + public void testEnterWithThis() { + trace.enter("testEnterWithThis",this); + } + + public void testEnter() { + trace.enter("testEnter"); + } + + public void testExitWithReturn() { + trace.exit("testExitWithReturn","ret"); + } + + public void testExitWithThrowable() { + trace.exit("testExitWithThrowable",new RuntimeException()); + } + + public void testExit() { + trace.exit("testExit"); + } + + public void testEvent() { + trace.event("testEvent"); + } + + public void testEventWithThisAndArgs() { + trace.event("testEventWithThisAndArgs",this,new Object[] { "arg1", "arg2" }); + } + + public void testEventWithThisAndArg() { + trace.event("testEventWithThisAndArg",this,"arg1"); + } + + public void testDebug() { + trace.debug("debug"); + } + + public void testInfo() { + trace.info("information"); + } + + public void testWarn() { + trace.warn("warning"); + } + + public void testWarnWithException() { + trace.warn("warning",new RuntimeException("warning")); + } + + public void testError() { + trace.error("error"); + } + + public void testErrorWithException() { + trace.error("error",new RuntimeException("error")); + } + + public void testFatal() { + trace.fatal("fatal"); + } + + public void testFatalWithException() { + trace.fatal("fatal",new RuntimeException("fatal")); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/AllWeaver5Tests.java b/weaver/src/test/java/org/aspectj/weaver/AllWeaver5Tests.java new file mode 100644 index 000000000..6ce2e0354 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/AllWeaver5Tests.java @@ -0,0 +1,40 @@ +///* ******************************************************************* +// * Copyright (c) 2005-2006 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 +// * Matthew Webster Move from default package +// * ******************************************************************/ +//package org.aspectj.weaver; +// +//import junit.framework.Test; +//import junit.framework.TestSuite; +// +//import org.aspectj.weaver.reflect.ReflectionWorldReferenceTypeTest; +//import org.aspectj.weaver.reflect.ReflectionWorldSpecificTest; +//import org.aspectj.weaver.tools.PointcutExpressionTest; +// +//public class AllWeaver5Tests { +// +// public static Test suite() { +// TestSuite suite = new TestSuite(AllWeaver5Tests.class.getName()); +// // $JUnit-BEGIN$ +// suite.addTest(AllTracing5Tests.suite()); +// suite.addTest(BcweaverModule15Test.suite()); +// suite.addTestSuite(ReflectionWorldReferenceTypeTest.class); +// suite.addTestSuite(PointcutExpressionTest.class); +// suite.addTestSuite(JoinPointSignatureIteratorTest.class); +// // gives incompatible class version error... +// // suite.addTestSuite(ReflectionWorldAdvancedPointcutExpressionTests.class +// // ); +// suite.addTestSuite(ReflectionWorldSpecificTest.class); +// // $JUnit-END$ +// return suite; +// } +// +//} diff --git a/weaver/src/test/java/org/aspectj/weaver/BcweaverModule15Test.java b/weaver/src/test/java/org/aspectj/weaver/BcweaverModule15Test.java new file mode 100644 index 000000000..8455315ff --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/BcweaverModule15Test.java @@ -0,0 +1,41 @@ +//package org.aspectj.weaver; +// +///* ******************************************************************* +// * 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 +// * ******************************************************************/ +//import junit.framework.Test; +//import junit.framework.TestCase; +//import junit.framework.TestSuite; +// +//import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXTestCase; +//import org.aspectj.weaver.bcel.BcelWorldReferenceTypeTest; +//import org.aspectj.weaver.patterns.WildTypePatternResolutionTestCase; +//import org.aspectj.weaver.tools.Java15PointcutExpressionTest; +// +//public class BcweaverModule15Test extends TestCase { +// public static Test suite() { +// TestSuite suite = new TestSuite(BcweaverModule15Test.class.getName()); +// suite.addTestSuite(BcelGenericSignatureToTypeXTestCase.class); +// suite.addTestSuite(BoundedReferenceTypeTestCase.class); +// suite.addTest(Java15PointcutExpressionTest.suite()); +// suite.addTestSuite(Member15Test.class); +// suite.addTestSuite(BcelWorldReferenceTypeTest.class); +// suite.addTest(Java5ReflectionBasedReferenceTypeDelegateTest.suite()); +// suite.addTestSuite(TypeVariableTestCase.class); +// suite.addTestSuite(TypeVariableReferenceTypeTestCase.class); +// suite.addTestSuite(WildTypePatternResolutionTestCase.class); +// return suite; +// } +// +// public BcweaverModule15Test(String name) { +// super(name); +// } +//} diff --git a/weaver/src/test/java/org/aspectj/weaver/BoundedReferenceTypeTestCase.java b/weaver/src/test/java/org/aspectj/weaver/BoundedReferenceTypeTestCase.java new file mode 100644 index 000000000..403b2ecb1 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/BoundedReferenceTypeTestCase.java @@ -0,0 +1,106 @@ +/* ******************************************************************* + * 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; + +import junit.framework.TestCase; + +import org.aspectj.weaver.bcel.BcelWorld; + +public class BoundedReferenceTypeTestCase extends TestCase { + + ReferenceType javaLangClass; + ReferenceType javaLangObject; + BoundedReferenceType extendsClass; + BoundedReferenceType superClass; + BoundedReferenceType extendsWithExtras; + + public void testSignature() { + String extendsSig = extendsClass.getSignature(); + assertEquals("+Ljava/lang/Class;", extendsSig); + assertEquals("-Ljava/lang/Class;", superClass.getSignature()); + } + + public void testExtendsBounds() { + assertFalse("has no lower bound", extendsClass.hasLowerBound()); + assertNull("no lower bound", extendsClass.getLowerBound()); + assertEquals(javaLangClass, extendsClass.getUpperBound()); + assertEquals("no interface bounds", 0, extendsClass.getAdditionalBounds().length); + } + + public void testSuperBounds() { + assertTrue("has lower bound", superClass.hasLowerBound()); + assertEquals(javaLangClass, superClass.getLowerBound()); + assertEquals("Ljava/lang/Object;", superClass.getUpperBound().getSignature()); + assertEquals("no interface bounds", 0, superClass.getAdditionalBounds().length); + } + + public void testIsExtends() { + assertTrue(extendsClass.kind == BoundedReferenceType.EXTENDS); + assertFalse(superClass.kind == BoundedReferenceType.EXTENDS); + } + + public void testIsSuper() { + assertTrue(superClass.kind == BoundedReferenceType.SUPER); + assertFalse(extendsClass.kind == BoundedReferenceType.SUPER); + } + + public void testGetDeclaredInterfacesNoAdditions() { + ResolvedType[] rt1 = extendsClass.getDeclaredInterfaces(); + ResolvedType[] rt2 = javaLangClass.getDeclaredInterfaces(); + assertEquals("same length", rt1.length, rt2.length); + for (int i = 0; i < rt2.length; i++) { + assertEquals("same methods", rt1[i], rt2[i]); + } + } + + public void testGetDeclaredInterfacesWithInterfaceBounds() { + ResolvedType[] rt1 = extendsWithExtras.getDeclaredInterfaces(); + ResolvedType[] rt2 = javaLangClass.getDeclaredInterfaces(); + assertEquals("one extra interface", rt1.length, rt2.length + 1); + for (int i = 0; i < rt2.length; i++) { + assertEquals("same methods", rt1[i], rt2[i]); + } + assertEquals("Ljava/util/List;", rt1[rt1.length - 1].getSignature()); + } + + // all other methods in signature are delegated to upper bound... + // representative test + public void testGetDeclaredMethodsExtends() { + ResolvedMember[] rm1 = extendsClass.getDeclaredMethods(); + ResolvedMember[] rm2 = javaLangClass.getDeclaredMethods(); + assertEquals("same length", rm1.length, rm2.length); + for (int i = 0; i < rm2.length; i++) { + assertEquals("same methods", rm1[i], rm2[i]); + } + } + + public void testGetDeclaredMethodsSuper() { + ResolvedMember[] rm1 = superClass.getDeclaredMethods(); + ResolvedMember[] rm2 = javaLangObject.getDeclaredMethods(); + assertEquals("same length", rm1.length, rm2.length); + for (int i = 0; i < rm2.length; i++) { + assertEquals("same methods", rm1[i], rm2[i]); + } + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + BcelWorld world = new BcelWorld(); + javaLangClass = (ReferenceType) world.resolve(UnresolvedType.forName("java/lang/Class")); + javaLangObject = (ReferenceType) world.resolve(UnresolvedType.OBJECT); + extendsClass = new BoundedReferenceType(javaLangClass, true, world); + superClass = new BoundedReferenceType(javaLangClass, false, world); + extendsWithExtras = new BoundedReferenceType(javaLangClass, true, world, new ReferenceType[] { (ReferenceType) world + .resolve(UnresolvedType.forName("java/util/List")) }); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/CommonReferenceTypeTests.java b/weaver/src/test/java/org/aspectj/weaver/CommonReferenceTypeTests.java new file mode 100644 index 000000000..8d683e8af --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/CommonReferenceTypeTests.java @@ -0,0 +1,91 @@ +/* ******************************************************************* + * 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; + +import junit.framework.TestCase; + +// test cases for Adrian's additions to ReferenceType +// XXX - couldn't find any unit test cases for the rest of the ReferenceType class +public abstract class CommonReferenceTypeTests extends TestCase { + + private World world; + + public abstract World getWorld(); + + public void setUp() { + world = getWorld(); + } + + public void testUnresolvedTypeSignatureProcessing() { + world.setBehaveInJava5Way(true); + UnresolvedType ut = null; + ut = UnresolvedType.forName("java.util.List>[]").resolve(world); + ut = UnresolvedType.forSignature("[Pjava/util/List;>;").resolve(world); + assertEquals("Signatures not equal ", "[Pjava/util/List;>;", ut.getSignature()); + assertEquals("Names not equal ", "java.util.List>[]", ut.getName()); + } + + public void testArrays() { + world.setBehaveInJava5Way(true); + UnresolvedType ut = null; + ut = UnresolvedType.forName("[Ljava.lang.String;"); + assertEquals("[Ljava/lang/String;",ut.getSignature()); + UnresolvedType reified = UnresolvedType.forSignature(ut.getSignature()); + ResolvedType rt = world.resolve(reified); + assertEquals("[Ljava/lang/String;",rt.getSignature()); + assertEquals("java.lang.String[]",rt.getName()); + assertFalse(rt.isMissing()); + + ut = UnresolvedType.forName("[[[[Ljava.lang.String;"); + assertEquals("[[[[Ljava/lang/String;",ut.getSignature()); + reified = UnresolvedType.forSignature(ut.getSignature()); + rt = world.resolve(reified); + assertEquals("[[[[Ljava/lang/String;",rt.getSignature()); + assertEquals("java.lang.String[][][][]",rt.getName()); + assertTrue(rt.isArray()); + assertTrue(rt.getComponentType().isArray()); + assertFalse(rt.isMissing()); + } + + public void testIsRawTrue() { + world.setBehaveInJava5Way(true); + UnresolvedType javaLangClass = UnresolvedType.forName("java.lang.Class"); + ResolvedType rtx = world.resolve(javaLangClass); + assertTrue("Resolves to reference type", (rtx instanceof ReferenceType)); + ReferenceType rt = (ReferenceType) rtx; + assertTrue("java.lang.Class is raw", rt.isRawType()); + } + + public void testIsRawFalse() { + world.setBehaveInJava5Way(true); + UnresolvedType javaLangObject = UnresolvedType.forName("java.lang.Object"); + ResolvedType rtx = world.resolve(javaLangObject); + assertTrue("Resolves to reference type", (rtx instanceof ReferenceType)); + ReferenceType rt = (ReferenceType) rtx; + assertFalse("java.lang.Object is not raw", rt.isRawType()); + } + + public void testIsGenericTrue() { + world.setBehaveInJava5Way(true); + UnresolvedType javaLangClass = UnresolvedType.forName("java.lang.Class"); + ResolvedType rtx = world.resolve(javaLangClass); + assertTrue("java.lang.Class has underpinning generic type", rtx.getGenericType().isGenericType()); + } + + public void testIsGenericFalse() { + world.setBehaveInJava5Way(true); + UnresolvedType javaLangObject = UnresolvedType.forName("java.lang.Object"); + ResolvedType rtx = world.resolve(javaLangObject); + assertFalse(rtx.isGenericType()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/CommonsTraceFactoryTest.java b/weaver/src/test/java/org/aspectj/weaver/CommonsTraceFactoryTest.java new file mode 100644 index 000000000..ecdaf63de --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/CommonsTraceFactoryTest.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import junit.framework.TestCase; + +import org.aspectj.weaver.tools.CommonsTraceFactory; +import org.aspectj.weaver.tools.Trace; + +public class CommonsTraceFactoryTest extends TestCase { + + public void testGetTraceFactory() { + CommonsTraceFactory factory = new CommonsTraceFactory(); + Trace trace = factory.getTrace(getClass()); + assertFalse("Tracing should be disbled by default",trace.isTraceEnabled()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/CommonsTraceTest.java b/weaver/src/test/java/org/aspectj/weaver/CommonsTraceTest.java new file mode 100644 index 000000000..ac6a8cec3 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/CommonsTraceTest.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import org.aspectj.weaver.tools.CommonsTrace; + +public class CommonsTraceTest extends AbstractTraceTest { + + protected void setUp() throws Exception { + super.setUp(); + trace = new CommonsTrace(getClass()); + trace.setTraceEnabled(true); + } + + public void testCommonsTrace() { +// CommonsTrace trace = + new CommonsTrace(getClass()); + } + + public void testSetTraceEnabled() { + CommonsTrace trace = new CommonsTrace(getClass()); + trace.setTraceEnabled(true); + /* XXX Need to find out how to turn tracing on */ +// assertTrue(trace.isTraceEnabled()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/DefaultTraceFactoryTest.java b/weaver/src/test/java/org/aspectj/weaver/DefaultTraceFactoryTest.java new file mode 100644 index 000000000..16d14bfb6 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/DefaultTraceFactoryTest.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import org.aspectj.weaver.tools.DefaultTraceFactory; +import org.aspectj.weaver.tools.Trace; + +import junit.framework.TestCase; + +public class DefaultTraceFactoryTest extends TestCase { + + public void testGetTrace() { + DefaultTraceFactory factory = new DefaultTraceFactory(); + Trace trace = factory.getTrace(getClass()); + assertFalse("Tracing should be disbled by default",trace.isTraceEnabled()); + } + +// public void testIsEnabled() { +// fail("Not yet implemented"); +// } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/DefaultTraceTest.java b/weaver/src/test/java/org/aspectj/weaver/DefaultTraceTest.java new file mode 100644 index 000000000..a8313c4fb --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/DefaultTraceTest.java @@ -0,0 +1,38 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import org.aspectj.weaver.tools.DefaultTrace; + +public class DefaultTraceTest extends AbstractTraceTest { + + protected void setUp() throws Exception { + super.setUp(); + trace = new DefaultTrace(getClass()); + trace.setTraceEnabled(true); + } + + public void testDefaultTrace() { +// DefaultTrace trace = + new DefaultTrace(getClass()); + } + + public void testSetTraceEnabled() { + DefaultTrace trace = new DefaultTrace(getClass()); + trace.setTraceEnabled(true); + assertTrue(trace.isTraceEnabled()); + } + + public void testSetPrintStream () { + DefaultTrace trace = new DefaultTrace(getClass()); + trace.setPrintStream(System.out); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/DumpTestCase.java b/weaver/src/test/java/org/aspectj/weaver/DumpTestCase.java new file mode 100644 index 000000000..affd39c2c --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/DumpTestCase.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster + *******************************************************************************/ +package org.aspectj.weaver; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import junit.framework.TestCase; + +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHolder; +import org.aspectj.bridge.Message; +import org.aspectj.bridge.MessageHandler; + +/** + * @author websterm + * + * Test Dump facility. Ensure it can be configured and files contain expected contents. Testcase + * returns Dump configuration to orginal state. + */ +public class DumpTestCase extends TestCase { + + private File dumpFile; + private IMessage.Kind savedDumpCondition; + + public DumpTestCase(String name) { + super(name); + } + + protected void setUp() throws Exception { + super.setUp(); + + dumpFile = null; + savedDumpCondition = Dump.getDumpOnExit(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + + if (dumpFile != null && dumpFile.exists()) { + boolean deleted = dumpFile.delete(); + assertTrue("Dump file '" + dumpFile.getPath() + "' could not be deleted",deleted); + } + Dump.setDumpOnExit(savedDumpCondition); + } + + public void testSetDumpOnException () { + Dump.setDumpOnException(true); + assertTrue("DumpOnException should be true",Dump.getDumpOnException()); + } + + public void testSetDumpOnExit () { + assertTrue("Should be able to set condition 'error'",Dump.setDumpOnExit("error")); + assertTrue("Should be able to set condition 'warning'",Dump.setDumpOnExit("warning")); + assertFalse("Should not be able to set condition 'junk'",Dump.setDumpOnExit("junk")); + } + + public void testDump () { + String fileName = Dump.dump("testDump()"); + dumpFile = new File(fileName); + assertTrue("Dump file '" + fileName + "' should exist",dumpFile.exists()); + } + + public void testDumpWithException () { + String message = "testDumpWithException()"; + String fileName = recursiveCall(message,100); + dumpFile = new File(fileName); + assertContents(dumpFile,"Exception Information",message); + } + + public void testDumpOnExit () { + Dump.setDumpOnExit("abort"); + Dump.saveMessageHolder(null); + String fileName = Dump.dumpOnExit(); + dumpFile = new File(fileName); + assertTrue("Dump file '" + fileName + "' should exist",dumpFile.exists()); + } + + public void testDumpOnExitExcluded () { + Dump.setDumpOnExit("abort"); + IMessageHolder holder = new MessageHandler(); + Dump.saveMessageHolder(holder); + holder.handleMessage(new Message("testDumpOnExitExcluded()",IMessage.ERROR,null,null)); + String fileName = Dump.dumpOnExit(); + dumpFile = new File(fileName); + assertEquals("Dump '" + fileName + "' should be excluded",Dump.DUMP_EXCLUDED,fileName); + } + + public void testDumpOnExitIncluded () { + Dump.setDumpOnExit("error"); + IMessageHolder holder = new MessageHandler(); + Dump.saveMessageHolder(holder); + IMessage error = new Message("testDumpOnExitIncluded()",IMessage.ERROR,null,null); + holder.handleMessage(error); + String fileName = Dump.dumpOnExit(); + dumpFile = new File(fileName); + assertContents(dumpFile,"Compiler Messages",error.getMessage()); + } + + /* Ensure dump file exists and contains certain contents under a given heading */ + public static void assertContents (File dumpFile, String heading, String contents) { + assertTrue("Dump file '" + dumpFile.getPath() + "' should exist",dumpFile.exists()); + assertTrue("Dump file '" + dumpFile.getPath()+ "' should contain '" + contents + "'",fileContains(dumpFile,heading,contents)); + } + + private static boolean fileContains (File dumpFile, String heading, String contents) { + boolean result = false; + + try { + BufferedReader reader = new BufferedReader(new FileReader(dumpFile)); + String currentHeading = ""; + String record; + while ((null != (record = reader.readLine())) && (result == false)) { + if (record.startsWith("----")) currentHeading = record; + else if ((record.indexOf(contents) != -1) && currentHeading.indexOf(heading) != -1) result = true; + } + reader.close(); + } + catch (IOException ex) { + fail(ex.toString()); + } + + return result; + } + + /* Generate a big stack trace */ + private String recursiveCall (String message, int depth) { + if (depth == 0) { + Throwable th = new RuntimeException(message); + return Dump.dumpWithException(th); + } + else { + return recursiveCall(message,--depth); + } + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/GenericSignatureParserTest.java b/weaver/src/test/java/org/aspectj/weaver/GenericSignatureParserTest.java new file mode 100644 index 000000000..e5948eb40 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/GenericSignatureParserTest.java @@ -0,0 +1,63 @@ +/* ******************************************************************* + * Copyright (c) 1999-2001 Xerox Corporation, + * 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * ******************************************************************/ + package org.aspectj.weaver; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; +import org.aspectj.apache.bcel.util.SyntheticRepository; +import org.aspectj.util.GenericSignatureParser; + +/** + * @author Adrian Colyer + * @author Andy Clement + */ +public class GenericSignatureParserTest extends TestCase { + + GenericSignatureParser parser; + + protected void setUp() throws Exception { + super.setUp(); + parser = new GenericSignatureParser(); + } + + public void testClassSignatureParsingInJDK() throws Exception { + SyntheticRepository repository = SyntheticRepository.getInstance(); + String[] testClasses = new String[] { "java.lang.Comparable", "java.lang.Iterable", "java.lang.Class", "java.lang.Enum", + "java.lang.InheritableThreadLocal", "java.lang.ThreadLocal", "java.util.Collection", "java.util.Comparator", + "java.util.Enumeration", "java.util.Iterator", "java.util.List", "java.util.ListIterator", "java.util.Map", + "java.util.Map$Entry", "java.util.Queue", "java.util.Set", "java.util.SortedMap", "java.util.SortedSet" }; + for (int i = 0; i < testClasses.length; i++) { + JavaClass jc = repository.loadClass(testClasses[i]); + String sig = jc.getGenericSignature(); + parser.parseAsClassSignature(sig); + } + } + + public void testMethodSignatureParsingInJDK() throws Exception { + SyntheticRepository repository = SyntheticRepository.getInstance(); + String[] testClasses = new String[] { "java.lang.Comparable", "java.lang.Iterable", "java.lang.Class", "java.lang.Enum", + "java.lang.InheritableThreadLocal", "java.lang.ThreadLocal", "java.util.Collection", "java.util.Comparator", + "java.util.Enumeration", "java.util.Iterator", "java.util.List", "java.util.ListIterator", "java.util.Map", + "java.util.Map$Entry", "java.util.Queue", "java.util.Set", "java.util.SortedMap", "java.util.SortedSet" }; + for (int i = 0; i < testClasses.length; i++) { + JavaClass jc = repository.loadClass(testClasses[i]); + Method[] methods = jc.getMethods(); + for (int j = 0; j < methods.length; j++) { + String sig = methods[j].getGenericSignature(); + if (sig != null) + parser.parseAsMethodSignature(sig); + } + } + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/Java5ReflectionBasedReferenceTypeDelegateTest.java b/weaver/src/test/java/org/aspectj/weaver/Java5ReflectionBasedReferenceTypeDelegateTest.java new file mode 100644 index 000000000..9f6a2965e --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/Java5ReflectionBasedReferenceTypeDelegateTest.java @@ -0,0 +1,154 @@ +/* ******************************************************************* + * Copyright (c) 2005-2017 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: + * Andrew Clement Initial implementation + * ******************************************************************/ + +package org.aspectj.weaver; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Field; + +import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegateTest; + +public class Java5ReflectionBasedReferenceTypeDelegateTest extends ReflectionBasedReferenceTypeDelegateTest { + + public static Test suite() { + TestSuite suite = new TestSuite("TestJava5ReflectionBasedReferenceTypeDelegate"); + suite.addTestSuite(Java5ReflectionBasedReferenceTypeDelegateTest.class); + return suite; + } + + /** + * Let's play about with a generic type and ensure we can work with it in a reflective world. + */ + public void testResolveGeneric() { + UnresolvedType collectionType = UnresolvedType.forName("java.util.Collection"); + world.resolve(collectionType).getRawType().resolve(world); + ResolvedMember[] methods = world.resolve(collectionType).getDeclaredMethods(); + int i = -1; + for (int j=0;j 0); + TypeVariable tv = theGenericEnumType.getTypeVariables()[0]; + String expected = "TypeVar E extends java.lang.Enum"; + assertTrue("Type variable should be '" + expected + "' but is '" + tv + "'", tv.toString().equals(expected)); + } + + public void testResolveClass() { + world.resolve("java.lang.Class").getGenericType(); + } + + public void testGenericInterfaceSuperclass_ReflectionWorldResolution() { + + UnresolvedType javaUtilMap = UnresolvedType.forName("java.util.Map"); + + ReferenceType rawType = (ReferenceType) world.resolve(javaUtilMap); + assertTrue("Should be the raw type ?!? " + rawType.getTypekind(), rawType.isRawType()); + + ReferenceType genericType = (ReferenceType) rawType.getGenericType(); + assertTrue("Should be the generic type ?!? " + genericType.getTypekind(), genericType.isGenericType()); + + ResolvedType rt = rawType.getSuperclass(); + assertTrue("Superclass for Map raw type should be Object but was " + rt, rt.equals(UnresolvedType.OBJECT)); + + ResolvedType rt2 = genericType.getSuperclass(); + assertTrue("Superclass for Map generic type should be Object but was " + rt2, rt2.equals(UnresolvedType.OBJECT)); + } + + /** + * This is testing the optimization in the reflective annotation finder to verify that if you only want runtime + * annotation info then we use reflection and don't go digging through the classfile bytes. + */ + public void testAnnotationFinderClassRetention() throws Exception { + ResolvedType type = world.resolve(AnnoTesting.class.getName()); + ResolvedMember[] ms = type.getDeclaredMethods(); + int findMethod = findMethod("a", ms); + + ResolvedMember methodWithOnlyClassLevelAnnotation = ms[findMethod("a", ms)]; + ResolvedMember methodWithOnlyRuntimeLevelAnnotation = ms[findMethod("b", ms)]; + ResolvedMember methodWithClassAndRuntimeLevelAnnotations = ms[findMethod("c", ms)]; + ResolvedMember methodWithClassAndRuntimeLevelAnnotations2 = ms[findMethod("d", ms)]; + + assertTrue(methodWithOnlyClassLevelAnnotation.hasAnnotation(world.resolve(AnnoClass.class.getName()))); + assertTrue(methodWithOnlyRuntimeLevelAnnotation.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + + // This is the tricky scenario. + + // When asking about the runtime level annotations it should not go digging into bcel + assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + + Field annotationsField = ResolvedMemberImpl.class.getDeclaredField("annotationTypes"); + annotationsField.setAccessible(true); + ResolvedType[] annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations); + + // Should only be the runtime one here + assertEquals(1, annoTypes.length); + + // But when you do ask again and this time for class level, it should redo the unpack and pull both runtime and class out + assertTrue(methodWithClassAndRuntimeLevelAnnotations.hasAnnotation(world.resolve(AnnoClass.class.getName()))); + + annotationsField.setAccessible(true); + annoTypes = (ResolvedType[])annotationsField.get(methodWithClassAndRuntimeLevelAnnotations); + + // Now both should be there + assertEquals(2, annoTypes.length); + + assertTrue(methodWithClassAndRuntimeLevelAnnotations2.hasAnnotation(world.resolve(AnnoRuntime.class.getName()))); + // now ask for 'all annotations' via another route, this should reunpack and get them all + ResolvedType[] annotations = methodWithClassAndRuntimeLevelAnnotations2.getAnnotationTypes(); + assertEquals(2,annotations.length); + } + + @Retention(RetentionPolicy.CLASS) + @interface AnnoClass {} + + @Retention(RetentionPolicy.RUNTIME) + @interface AnnoRuntime {} + + class AnnoTesting { + + @AnnoClass + public void a() {} + + @AnnoRuntime + public void b() {} + + @AnnoClass @AnnoRuntime + public void c() {} + + @AnnoClass @AnnoRuntime + public void d() {} + + } + +} \ No newline at end of file diff --git a/weaver/src/test/java/org/aspectj/weaver/Jdk14TraceFactoryTest.java b/weaver/src/test/java/org/aspectj/weaver/Jdk14TraceFactoryTest.java new file mode 100644 index 000000000..cec4d6a3d --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/Jdk14TraceFactoryTest.java @@ -0,0 +1,30 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import junit.framework.TestCase; + +import org.aspectj.weaver.tools.Jdk14TraceFactory; +import org.aspectj.weaver.tools.Trace; + +public class Jdk14TraceFactoryTest extends TestCase { + + public void testJdk14TraceFactory() { + new Jdk14TraceFactory(); + } + + public void testGetTrace() { + Jdk14TraceFactory factory = new Jdk14TraceFactory(); + Trace trace = factory.getTrace(getClass()); + assertFalse("Tracing should be disbled by default",trace.isTraceEnabled()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/Jdk14TraceTest.java b/weaver/src/test/java/org/aspectj/weaver/Jdk14TraceTest.java new file mode 100644 index 000000000..0c694cc9d --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/Jdk14TraceTest.java @@ -0,0 +1,34 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import org.aspectj.weaver.tools.DefaultTrace; +import org.aspectj.weaver.tools.Jdk14Trace; + +public class Jdk14TraceTest extends AbstractTraceTest { + + protected void setUp() throws Exception { + super.setUp(); + trace = new Jdk14Trace(getClass()); + trace.setTraceEnabled(true); + } + + public void testJdk14Trace() { + new Jdk14Trace(getClass()); + } + + public void testSetTraceEnabled() { + DefaultTrace trace = new DefaultTrace(getClass()); + trace.setTraceEnabled(true); + assertTrue(trace.isTraceEnabled()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/JoinPointSignatureIteratorTest.java b/weaver/src/test/java/org/aspectj/weaver/JoinPointSignatureIteratorTest.java new file mode 100644 index 000000000..143de7333 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/JoinPointSignatureIteratorTest.java @@ -0,0 +1,107 @@ +/* ******************************************************************* + * Copyright (c) 2009 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: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import junit.framework.TestCase; + +import org.aspectj.weaver.reflect.ReflectionWorld; + +/** + * @author Andy Clement + */ +public class JoinPointSignatureIteratorTest extends TestCase { + + private World getWorld() { + return new ReflectionWorld(getClass().getClassLoader()); + } + + /** + * Checking the signatures for a dynamic proxy - which is created using erased information and so is completely generics unaware + */ + public void testPr268419() { + World w = getWorld(); + w.setBehaveInJava5Way(true); + + // The proxy class here is not generated, it is simply loaded up. $Proxy1 is in the java5-testsrc folder, but it + // obeys the rules of a generated proxy in that it extends java.lang.reflect.Proxy + ResolvedType proxy = UnresolvedType.forName("$Proxy1").resolve(w); + assertNotNull(proxy); + + // The test hierarchy here (messageservice and genericservice) contains 2 methods. One is generic + // and one is not. The aim of the test here is that the join point signatures generated for both + // should be the same because of the use of a proxy. + + List l = proxy.getMethodsWithoutIterator(false, false, false); + for (Object object : l) { + ResolvedMember rm = (ResolvedMember) object; + if (expectedResults.containsKey(rm.toString())) { + System.out.println("\nChecking: " + rm); + int i = 0; + List/* String */sigs = (List) expectedResults.get(rm.toString()); + Iterator jpsi = rm.getJoinPointSignatures(w); + while (jpsi.hasNext()) { + ResolvedMember sig = (ResolvedMember) jpsi.next(); + assertEquals(sigs.get(i).toString(), sig.toString()); + i++; + } + if (i != sigs.size()) { + fail("Expected " + sigs.size() + " signatures but got " + i); + } + } else { + if (rm.getName().equals("get1") || rm.getName().equals("get2")) { + fail("\nFound this unchecked get method " + rm); + // Iterator jpsi = rm.getJoinPointSignatures(w); + // while (jpsi.hasNext()) { + // ResolvedMember sig = (ResolvedMember) jpsi.next(); + // System.out.println(sig); + // } + } + } + } + } + + public static Map expectedResults = new HashMap(); + + static { + List sigs = new ArrayList(); + sigs.add("java.lang.Object $Proxy1.get1(java.io.Serializable)"); + sigs.add("java.lang.Object MessageService.get1(java.io.Serializable)"); + sigs.add("java.lang.Object GenericService.get1(java.io.Serializable)"); + sigs.add("java.lang.Object GenericService.get1(java.io.Serializable)"); + expectedResults.put("java.lang.Object $Proxy1.get1(java.io.Serializable)", sigs); + + sigs = new ArrayList(); + sigs.add("java.lang.Object $Proxy1.get2(java.io.Serializable)"); + sigs.add("java.lang.Object MessageService.get2(java.io.Serializable)"); + sigs.add("java.lang.Object GenericService.get2(java.io.Serializable)"); + sigs.add("java.lang.Object GenericService.get2(java.io.Serializable)"); + expectedResults.put("java.lang.Object $Proxy1.get2(java.io.Serializable)", sigs); + + sigs = new ArrayList(); + sigs.add("java.lang.Object $Proxy1.get1(java.lang.Long)"); + expectedResults.put("java.lang.Object $Proxy1.get1(java.lang.Long)", sigs); + + sigs = new ArrayList(); + sigs.add("java.lang.Object GenericService.get1(java.io.Serializable)"); + expectedResults.put("java.lang.Object GenericService.get1(java.io.Serializable)", sigs); + + sigs = new ArrayList(); + sigs.add("java.lang.Object GenericService.get2(java.io.Serializable)"); + expectedResults.put("java.lang.Object GenericService.get2(java.io.Serializable)", sigs); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/LocaleTest.java b/weaver/src/test/java/org/aspectj/weaver/LocaleTest.java new file mode 100644 index 000000000..e69a4df93 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/LocaleTest.java @@ -0,0 +1,53 @@ +/* Copyright (c) 2002 Contributors. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + */ +package org.aspectj.weaver; + +import java.io.IOException; +import java.util.Locale; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.generic.Instruction; +import org.aspectj.apache.bcel.util.ByteSequence; + +public class LocaleTest extends TestCase { + + public LocaleTest(String name) { + super(name); + } + + public void testNormalLocale() { + doBipush(); + } + + public void testTurkishLocale() { + Locale def = Locale.getDefault(); + Locale.setDefault(new Locale("tr", "")); + try { + doBipush(); + } finally { + Locale.setDefault(def); + } + } + + private static void doBipush() { + try { + Instruction.readInstruction( + new ByteSequence(new byte[] { + (byte)16, // bipush + (byte) 3 // data for bipush + })); + } catch (IOException e) { + throw new RuntimeException(e.getMessage()); + } + } +} + diff --git a/weaver/src/test/java/org/aspectj/weaver/Member15Test.java b/weaver/src/test/java/org/aspectj/weaver/Member15Test.java new file mode 100644 index 000000000..6cb0ce83f --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/Member15Test.java @@ -0,0 +1,155 @@ +/* ******************************************************************* + * 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; + +import org.aspectj.weaver.bcel.BcelWorld; + +import junit.framework.TestCase; + +/** + * @author colyer + * @author clement + */ +public class Member15Test extends TestCase { + + public void testCanBeParameterizedRegularMethod() { + BcelWorld world = new BcelWorld(); + ResolvedType javaLangClass = world.resolve(UnresolvedType.forName("java/lang/Class")); + ResolvedMember[] methods = javaLangClass.getDeclaredMethods(); + ResolvedMember getAnnotations = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("getAnnotations")) { + getAnnotations = methods[i]; + break; + } + } + if (getAnnotations != null) { // so can run on non-Java 5 +// System.out.println("got it"); + assertFalse(getAnnotations.canBeParameterized()); + } + } + + public void testCanBeParameterizedGenericMethod() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + ResolvedType javaLangClass = world.resolve(UnresolvedType.forName("java.lang.Class")); + javaLangClass = javaLangClass.getGenericType(); + if (javaLangClass == null) return; // for < 1.5 + ResolvedMember[] methods = javaLangClass.getDeclaredMethods(); + ResolvedMember asSubclass = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("asSubclass")) { + asSubclass = methods[i]; + break; + } + } + if (asSubclass != null) { // so can run on non-Java 5 +// System.out.println("got it"); + assertTrue(asSubclass.canBeParameterized()); + } + } + + public void testCanBeParameterizedMethodInGenericType() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + ResolvedType javaUtilList = world.resolve(UnresolvedType.forName("java.util.List")); + javaUtilList = javaUtilList.getGenericType(); + if (javaUtilList == null) return; // for < 1.5 + ResolvedMember[] methods = javaUtilList.getDeclaredMethods(); + ResolvedMember add = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("add")) { + add = methods[i]; + break; + } + } + if (add != null) { // so can run on non-Java 5 +// System.out.println("got it"); + assertTrue(add.canBeParameterized()); + } + } + /* + public void testGenericReferenceTypeCreation() { + UnresolvedType genericType = UnresolvedType.forGenericTypeSignature("Lorg/aspectj/weaver/MemberTestCase15$One;","Ljava/lang/Object;"); + assertEquals("Porg/aspectj/weaver/MemberTestCase15$One;",genericType.getSignature()); + assertEquals("Lorg/aspectj/weaver/MemberTestCase15$One;",genericType.getErasureSignature()); + } + + public void testMemberSignatureCreation() { + World world = new BcelWorld("../weaver5/bin/"); + //new ReflectionWorld(false, getClass().getClassLoader()); + world.setBehaveInJava5Way(true); + ResolvedType one = world.resolve("org.aspectj.weaver.MemberTestCase15$One"); + assertNotNull(one); + assertFalse(one.isMissing()); + + // Look at the methods on the parameterized type One + ResolvedMember member = findMethod("getter",one); + String erasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),true); + assertEquals("()Ljava/lang/String;",erasedSignature); + String nonErasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),false); + assertEquals("()Ljava/lang/String;",nonErasedSignature); + erasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),true); + assertEquals("()Ljava/lang/String;",erasedSignature); + nonErasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),false); + assertEquals("()Ljava/lang/String;",nonErasedSignature); + + member = findMethod("getterTwo",one); + erasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),true); + assertEquals("()Ljava/util/List;",erasedSignature); + nonErasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),false); + assertEquals("()Pjava/util/List;",nonErasedSignature); + nonErasedSignature = MemberImpl.typesToSignature(member.getGenericReturnType(),member.getGenericParameterTypes(),true); + assertEquals("()Ljava/util/List;",nonErasedSignature); + nonErasedSignature = MemberImpl.typesToSignature(member.getGenericReturnType(),member.getGenericParameterTypes(),false); + assertEquals("()Pjava/util/List;",nonErasedSignature); + + // Grab the generic type backing the parameterized type + ResolvedType oneGeneric = one.getGenericType(); + assertTrue(oneGeneric.isGenericType()); + member = findMethod("getterTwo",oneGeneric); + erasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),true); + assertEquals("()Ljava/util/List;",erasedSignature); + erasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),false); + assertEquals("()Ljava/util/List;",erasedSignature); + nonErasedSignature = MemberImpl.typesToSignature(member.getReturnType(),member.getParameterTypes(),false); + assertEquals("()Pjava/util/List;",nonErasedSignature); + nonErasedSignature = MemberImpl.typesToSignature(member.getGenericReturnType(),member.getGenericParameterTypes(),false); + assertEquals("()Ljava/util/List;",nonErasedSignature); + + + ResolvedType oneRaw = oneGeneric.getRawType(); + member = findMethod("getterTwo",oneRaw); + } + + private ResolvedMember findMethod(String name, ResolvedType type) { + ResolvedMember[] members = type.getDeclaredMethods(); + for (ResolvedMember member: members) { + if (member.getName().equals(name)) { + return member; + } + } + return null; + } + + // testcode + class One { + T t; + T getter() { + return null; + } + List getterTwo() { + return null; + } + } + */ +} diff --git a/weaver/src/test/java/org/aspectj/weaver/Member15TestCase.java b/weaver/src/test/java/org/aspectj/weaver/Member15TestCase.java new file mode 100644 index 000000000..3b37d5ba8 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/Member15TestCase.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; + +import org.aspectj.weaver.bcel.BcelWorld; + +import junit.framework.TestCase; + +/** + * @author colyer + * + */ +public class Member15TestCase extends TestCase { + + public void testCanBeParameterizedRegularMethod() { + BcelWorld world = new BcelWorld(); + ResolvedType javaLangClass = world.resolve(UnresolvedType.forName("java/lang/Class")); + ResolvedMember[] methods = javaLangClass.getDeclaredMethods(); + ResolvedMember getAnnotations = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("getAnnotations")) { + getAnnotations = methods[i]; + break; + } + } + if (getAnnotations != null) { // so can run on non-Java 5 +// System.out.println("got it"); + assertFalse(getAnnotations.canBeParameterized()); + } + } + + public void testCanBeParameterizedGenericMethod() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + ResolvedType javaLangClass = world.resolve(UnresolvedType.forName("java.lang.Class")); + javaLangClass = javaLangClass.getGenericType(); + if (javaLangClass == null) return; // for < 1.5 + ResolvedMember[] methods = javaLangClass.getDeclaredMethods(); + ResolvedMember asSubclass = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("asSubclass")) { + asSubclass = methods[i]; + break; + } + } + if (asSubclass != null) { // so can run on non-Java 5 +// System.out.println("got it"); + assertTrue(asSubclass.canBeParameterized()); + } + } + + public void testCanBeParameterizedMethodInGenericType() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + ResolvedType javaUtilList = world.resolve(UnresolvedType.forName("java.util.List")); + javaUtilList = javaUtilList.getGenericType(); + if (javaUtilList == null) return; // for < 1.5 + ResolvedMember[] methods = javaUtilList.getDeclaredMethods(); + ResolvedMember add = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("add")) { + add = methods[i]; + break; + } + } + if (add != null) { // so can run on non-Java 5 +// System.out.println("got it"); + assertTrue(add.canBeParameterized()); + } + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/MemberTestCase.java b/weaver/src/test/java/org/aspectj/weaver/MemberTestCase.java new file mode 100644 index 000000000..c4755a3db --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/MemberTestCase.java @@ -0,0 +1,183 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * Adrian Colyer, canBeParameterized tests + * ******************************************************************/ + +package org.aspectj.weaver; + +import java.lang.reflect.Modifier; + +import junit.framework.TestCase; + +import org.aspectj.testing.util.TestUtil; + +/** + * This is a test case for all the portions of Member that don't require a world. + */ +public class MemberTestCase extends TestCase { + + public MemberTestCase(String name) { + super(name); + } + + public void testMethodConstruction() { + Member s = TestUtils.methodFromString("void Foo.goo(int)"); + Member t = MemberImpl.method(UnresolvedType.forName("Foo"), 0, "goo", "(I)V"); + Member u = TestUtils.methodFromString("void Foo1.goo(int)"); + Member v = TestUtils.methodFromString("int Foo.goo(int)"); + + TestUtil.assertCommutativeEquals(s, s, true); + TestUtil.assertCommutativeEquals(t, t, true); + TestUtil.assertCommutativeEquals(u, u, true); + TestUtil.assertCommutativeEquals(v, v, true); + TestUtil.assertCommutativeEquals(s, t, true); + TestUtil.assertCommutativeEquals(s, u, false); + TestUtil.assertCommutativeEquals(s, v, false); + TestUtil.assertCommutativeEquals(t, u, false); + TestUtil.assertCommutativeEquals(t, v, false); + TestUtil.assertCommutativeEquals(u, v, false); + + s = TestUtils.fieldFromString("int Foo.goo"); + t = MemberImpl.field("Foo", 0, "goo", "I"); + u = TestUtils.fieldFromString("int Foo.goo1"); + v = TestUtils.fieldFromString("long Foo.goo"); + + TestUtil.assertCommutativeEquals(s, s, true); + TestUtil.assertCommutativeEquals(t, t, true); + TestUtil.assertCommutativeEquals(u, u, true); + TestUtil.assertCommutativeEquals(v, v, true); + TestUtil.assertCommutativeEquals(s, t, true); + TestUtil.assertCommutativeEquals(s, u, false); + TestUtil.assertCommutativeEquals(s, v, false); + TestUtil.assertCommutativeEquals(t, u, false); + TestUtil.assertCommutativeEquals(t, v, false); + TestUtil.assertCommutativeEquals(u, v, false); + } + + public void testMethodContents() { + Member m = TestUtils.methodFromString("void Foo.goo(int)"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "Foo"); + nameTest(m, "goo"); + parameterTypesTest(m, new UnresolvedType[] { UnresolvedType.INT }); + returnTypeTest(m, UnresolvedType.VOID); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = TestUtils.methodFromString("interface java.lang.Object java.util.Iterator.next()"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "java.util.Iterator"); + nameTest(m, "next"); + parameterTypesTest(m, UnresolvedType.NONE); + returnTypeTest(m, UnresolvedType.OBJECT); + isInterfaceTest(m, true); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = TestUtils.methodFromString("void Foo.(int, java.lang.Object)"); + kindTest(m, Member.CONSTRUCTOR); + declaringTypeTest(m, "Foo"); + nameTest(m, ""); + parameterTypesTest(m, new UnresolvedType[] { UnresolvedType.INT, UnresolvedType.OBJECT }); + returnTypeTest(m, UnresolvedType.VOID); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, true); + isStaticTest(m, false); + + m = TestUtils.methodFromString("private double Foo.sqrt(double)"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "Foo"); + nameTest(m, "sqrt"); + parameterTypesTest(m, new UnresolvedType[] { UnresolvedType.DOUBLE }); + returnTypeTest(m, UnresolvedType.DOUBLE); + isInterfaceTest(m, false); + isPrivateTest(m, true); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = TestUtils.methodFromString("static int java.lang.Math.max(int, int)"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "java.lang.Math"); + nameTest(m, "max"); + parameterTypesTest(m, new UnresolvedType[] { UnresolvedType.INT, UnresolvedType.INT }); + returnTypeTest(m, UnresolvedType.INT); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, true); + } + + public void testFieldContents() { + Member m = TestUtils.fieldFromString("int Foo.goo"); + kindTest(m, Member.FIELD); + declaringTypeTest(m, "Foo"); + nameTest(m, "goo"); + parameterTypesTest(m, UnresolvedType.NONE); + returnTypeTest(m, UnresolvedType.INT); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = TestUtils.fieldFromString("static java.util.Iterator goo.Bar.i"); + kindTest(m, Member.FIELD); + declaringTypeTest(m, "goo.Bar"); + nameTest(m, "i"); + parameterTypesTest(m, UnresolvedType.NONE); + returnTypeTest(m, UnresolvedType.forName("java.util.Iterator")); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, true); + } + + private void isStaticTest(Member m, boolean b) { + assertEquals(m + " is static", b, Modifier.isStatic(m.getModifiers())); + } + + private void isConstructorTest(Member m, boolean b) { + assertEquals(m + " is constructor", b, m.getKind() == Member.CONSTRUCTOR); + } + + private void isPrivateTest(Member m, boolean b) { + assertEquals(m + " is private", b, Modifier.isPrivate(m.getModifiers())); + } + + private void isInterfaceTest(Member m, boolean b) { + assertEquals(m + " is interface", b, Modifier.isInterface(m.getModifiers())); + } + + private void returnTypeTest(Member m, UnresolvedType returnType) { + assertEquals(m + " return type", returnType, m.getReturnType()); + } + + private void parameterTypesTest(Member m, UnresolvedType[] paramTypes) { + TestUtil.assertArrayEquals(m + " parameters", paramTypes, m.getParameterTypes()); + } + + private void nameTest(Member m, String name) { + assertEquals(m + " name", name, m.getName()); + } + + private void declaringTypeTest(Member m, String declaringName) { + assertEquals(m + " declared in", UnresolvedType.forName(declaringName), m.getDeclaringType()); + } + + private void kindTest(Member m, MemberKind kind) { + assertEquals(m + " kind", kind, m.getKind()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java b/weaver/src/test/java/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java new file mode 100644 index 000000000..8e04d8c53 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java @@ -0,0 +1,84 @@ +/* ******************************************************************* + * 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; + +import org.aspectj.weaver.bcel.BcelWorld; + +import junit.framework.TestCase; + +/** + * @author colyer + * For a parameterized reference type, the methods that return members + * - getDeclaredFields + * - getDeclaredMethods + * - getDeclaredInterfaces + * - getDeclaredPointcuts + * should have any type variables substituted by the given type parameter before + * being returned. + */ +public class ParameterizedReferenceTypeTestCase extends TestCase { + + BcelWorld world; + ReferenceType listOfString; + + public void testDeclaredMethodWithParameter() { + ResolvedMember[] methods = listOfString.getDeclaredMethods(); + ResolvedMember add = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("add")) { + if (methods[i].getParameterTypes().length == 1) { + add = methods[i]; + System.out.println(add); +// j8: boolean java.util.List.add(java.lang.Object) +// break; + } + } + } + UnresolvedType parameterType = add.getParameterTypes()[0]; + assertEquals("Ljava/lang/String;",parameterType.getSignature()); + + ResolvedMember get = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("get")) { + if (methods[i].getParameterTypes().length == 1) { + get = methods[i]; + break; + } + } + } + UnresolvedType returnType = get.getReturnType(); + assertEquals("Ljava/lang/String;",returnType.getSignature()); + + } + + public void testDeclaredMethodWithParameterizedReturnType() { + ResolvedMember[] methods = listOfString.getDeclaredMethods(); + ResolvedMember iterator = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("iterator")) { + iterator = methods[i]; + break; + } + } + UnresolvedType returnType = iterator.getReturnType(); + assertEquals("Pjava/util/Iterator;",returnType.getSignature()); + + } + + protected void setUp() throws Exception { + super.setUp(); + world = new BcelWorld(); + world.setBehaveInJava5Way(true); + listOfString = (ReferenceType) + TypeFactory.createTypeFromSignature("Pjava/util/List;").resolve(world); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/ReferenceTypeTestCase.java b/weaver/src/test/java/org/aspectj/weaver/ReferenceTypeTestCase.java new file mode 100644 index 000000000..5fbc530e7 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/ReferenceTypeTestCase.java @@ -0,0 +1,854 @@ +/* ******************************************************************* + * 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; + +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import junit.framework.TestCase; + +import org.aspectj.util.PartialOrder; +import org.aspectj.weaver.bcel.BcelWorld; + +// test cases for Adrian's additions to ReferenceType +// XXX - couldn't find any unit test cases for the rest of the ReferenceType class +public class ReferenceTypeTestCase extends TestCase { + + public void testIsRawTrue() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + UnresolvedType javaLangClass = UnresolvedType.forName("java.lang.Class"); + ResolvedType rtx = world.resolve(javaLangClass); + assertTrue("Resolves to reference type", (rtx instanceof ReferenceType)); + ReferenceType rt = (ReferenceType) rtx; + assertTrue("java.lang.Class is raw", rt.isRawType()); + } + + public void testIsRawFalse() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + UnresolvedType javaLangObject = UnresolvedType.forName("java.lang.Object"); + ResolvedType rtx = world.resolve(javaLangObject); + assertTrue("Resolves to reference type", (rtx instanceof ReferenceType)); + ReferenceType rt = (ReferenceType) rtx; + assertFalse("java.lang.Object is not raw", rt.isRawType()); + } + + public void testIsGenericTrue() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + UnresolvedType javaLangClass = UnresolvedType.forName("java.lang.Class"); + ResolvedType rtx = world.resolve(javaLangClass); + assertTrue("java.lang.Class has underpinning generic type", rtx.getGenericType().isGenericType()); + } + + public void testIsGenericFalse() { + BcelWorld world = new BcelWorld(); + world.setBehaveInJava5Way(true); + UnresolvedType javaLangObject = UnresolvedType.forName("java.lang.Object"); + ResolvedType rtx = world.resolve(javaLangObject); + assertFalse(rtx.isGenericType()); + } + + BcelWorld world; + + @Override + public void setUp() throws Exception { + super.setUp(); + world = new BcelWorld(); + world.setBehaveInJava5Way(true); + } + + public void testCoercion01() { + ReferenceType listOfString = (ReferenceType) world.resolve(UnresolvedType + .forSignature("Pjava/util/List;")); + ReferenceType listOfInteger = (ReferenceType) world.resolve(UnresolvedType + .forSignature("Pjava/util/List;")); + assertFalse(listOfInteger.isAssignableFrom(listOfString)); + assertFalse(listOfString.isAssignableFrom(listOfInteger)); + assertFalse(listOfInteger.isCoerceableFrom(listOfString)); + assertFalse(listOfString.isCoerceableFrom(listOfInteger)); + } + + public void testAssignable01() { + List list = new ArrayList(); + List listOfString = new ArrayList(); + List listOfSomething = new ArrayList(); + List listOfSomethingNumberish = new ArrayList(); + List listOfSomethingSuperDouble = new ArrayList(); + // interfaces too List + + ReferenceType ajList = resolve("Ljava/util/List;"); + ReferenceType ajListOfString = resolve("Pjava/util/List;"); + ReferenceType ajListOfSomething = resolve("Pjava/util/List<*>;"); + ReferenceType ajListOfSomethingNumberish = resolve("Pjava/util/List<+Ljava/lang/Number;>;"); + ReferenceType ajListOfSomethingSuperDouble = resolve("Pjava/util/List<-Ljava/lang/Double;>;"); + + // try and write the java equivalent, if it succeeds then check isAssignableFrom() is true + // if the java is only correct with a cast, check isCoerceableFrom() + list = listOfString; + assertTrue(ajList.isAssignableFrom(ajListOfString)); + list = listOfSomething; + assertTrue(ajList.isAssignableFrom(ajListOfSomething)); + list = listOfSomethingNumberish; + assertTrue(ajList.isAssignableFrom(ajListOfSomething)); + list = listOfSomethingSuperDouble; + assertTrue(ajList.isAssignableFrom(ajListOfSomethingSuperDouble)); + + listOfString = list; // unchecked conversion to List + assertFalse(ajListOfString.isAssignableFrom(ajList)); + assertTrue(ajListOfString.isCoerceableFrom(ajListOfSomething)); + // error: listOfString = listOfSomething; + assertFalse(ajListOfString.isAssignableFrom(ajListOfSomething)); + // error: listOfString = listOfSomethingNumberish; + assertFalse(ajListOfString.isAssignableFrom(ajListOfSomethingNumberish)); + // error: listOfString = listOfSomethingSuperDouble; + assertFalse(ajListOfString.isAssignableFrom(ajListOfSomethingSuperDouble)); + // error: listOfString = (List) listOfSomethingSuperDouble; + assertFalse(ajListOfString.isCoerceableFrom(ajListOfSomethingSuperDouble)); + + listOfSomething = list; + assertTrue(ajListOfSomething.isAssignableFrom(ajList)); + listOfSomething = listOfString; + assertTrue(ajListOfSomething.isAssignableFrom(ajListOfString)); + listOfSomething = listOfSomethingNumberish; + assertTrue(ajListOfSomething.isAssignableFrom(ajListOfSomething)); + listOfSomething = listOfSomethingSuperDouble; + assertTrue(ajListOfSomething.isAssignableFrom(ajListOfSomethingSuperDouble)); + + listOfSomethingNumberish = list; // unchecked conversion + assertFalse(ajListOfSomethingNumberish.isAssignableFrom(ajList)); + assertTrue(ajListOfSomethingNumberish.isCoerceableFrom(ajList)); + // error: listOfSomethingNumberish = listOfString; + assertFalse(ajListOfSomethingNumberish.isAssignableFrom(ajListOfString)); + assertFalse(ajListOfSomethingNumberish.isCoerceableFrom(ajListOfString)); + // error: listOfSomethingNumberish = listOfSomething; + assertFalse(ajListOfSomethingNumberish.isAssignableFrom(ajListOfSomething)); + listOfSomethingNumberish = (List) listOfSomething; + assertTrue(ajListOfSomethingNumberish.isCoerceableFrom(ajListOfSomething)); + // error: listOfSomethingNumberish = listOfSomethingSuperDouble; + assertFalse(ajListOfSomethingNumberish.isAssignableFrom(ajListOfSomethingSuperDouble)); + // listOfSomethingNumberish = (List) listOfSomethingSuperDouble; + // assertTrue(ajListOfSomethingNumberish.isCoerceableFrom(ajListOfSomethingSuperDouble)); + } + + class C { + void m1(List e) { + } + + void m2(List e) { + } + + void m3(List e) { + } + + void m4(List e) { + } + + void m5(List e) { + } + + void m6(List e) { + } + + void m7(List> e) { + } + + void m8(List e) { + } + + void m9(E e) { + } + } + + class A1 { + } + + class B1 extends A1 { + } + + class C1 extends B1 { + } + + class D1 extends C1 { + } + + class D2 { + void m5(List e) { + } + } + + public void testAssignable02() { + List list = new ArrayList(); + ArrayList arraylist = null; + List listOfString = new ArrayList(); + List listOfSomething = new ArrayList(); + ArrayList arrayListOfSomething = null; + List listOfNumber = null; + ArrayList arrayListOfNumber = null; + ArrayList arrayListOfSomethingNumberish = null; + List listOfSomethingNumberish = new ArrayList(); + List listOfSomethingSuperDouble = new ArrayList(); + List listOfInteger = new ArrayList(); + ArrayList arrayListOfString; + ArrayList arraylistOfInteger; + // interfaces too List + + ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfSomethingNumberish = resolve("Pjava/util/ArrayList<+Ljava/lang/Number;>;"); + ReferenceType ajList = resolve("Ljava/util/List;"); + ReferenceType ajArrayList = resolve("Ljava/util/ArrayList;"); + ReferenceType ajListOfString = resolve("Pjava/util/List;"); + ReferenceType ajListOfSomething = resolve("Pjava/util/List<*>;"); + ReferenceType ajArrayListOfSomething = resolve("Pjava/util/ArrayList<*>;"); + ReferenceType ajListOfSomethingNumberish = resolve("Pjava/util/List<+Ljava/lang/Number;>;"); + ReferenceType ajListOfSomethingSuperDouble = resolve("Pjava/util/List<-Ljava/lang/Double;>;"); + ReferenceType ajListOfInteger = resolve("Pjava/util/List;"); + ReferenceType ajListOfNumber = resolve("Pjava/util/List;"); + // Effectively, whether the advice matches is based on whether what we pass at the joinpoint could + // be bound to the specification in the args() pointcut + + // void around(): execution(* C.m1(..)) && args(List){} //: Should match (it does) + assertTrue(ajListOfInteger.isAssignableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(ArrayList){}//: Should runtime check (it does!) + ArrayList x = (ArrayList) listOfInteger; + assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfInteger)); + assertTrue(ajArrayListOfInteger.isCoerceableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(List){} // Should not match (it does not!) + // error: listOfNumber = listOfInteger; + assertFalse(ajListOfNumber.isAssignableFrom(ajListOfInteger)); + assertFalse(ajListOfNumber.isCoerceableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(ArrayList){} // Should not match (it does not) + // error: arrayListOfNumber = listOfInteger; + assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfInteger)); + assertFalse(ajArrayListOfNumber.isCoerceableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(List){} // Should match (it does) + listOfSomethingNumberish = listOfInteger; + assertTrue(ajListOfSomethingNumberish.isAssignableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(ArrayList){}// Should runtime check (it does!) + arrayListOfSomethingNumberish = (ArrayList) listOfInteger; + assertFalse(ajArrayListOfSomethingNumberish.isAssignableFrom(ajListOfInteger)); + assertTrue(ajArrayListOfSomethingNumberish.isCoerceableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(List){}// Should match (it does) + list = listOfInteger; + assertTrue(ajList.isAssignableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(ArrayList){}//: Should runtime check (it does not match!) + arraylist = (ArrayList) listOfInteger; + assertFalse(ajArrayList.isAssignableFrom(ajListOfInteger)); + assertTrue(ajArrayList.isCoerceableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(List){}// Should match (it does) + listOfSomething = listOfInteger; + assertTrue(ajListOfSomething.isAssignableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(ArrayList){}// Should runtime check (it does not match!) + arrayListOfSomething = (ArrayList) listOfInteger; + assertFalse(ajArrayListOfSomething.isAssignableFrom(ajListOfInteger)); + assertTrue(ajArrayListOfSomething.isCoerceableFrom(ajListOfInteger)); + + // void around(): execution(* C.m1(..)) && args(ArrayList){}// Should not match (it does not match!) + // error: arrayListOfString = listOfInteger; + assertFalse(ajArrayListOfString.isAssignableFrom(ajListOfInteger)); + assertFalse(ajArrayListOfString.isCoerceableFrom(ajListOfInteger)); + } + + public void testAssignable03_method_m2() { + List list = new ArrayList(); + ArrayList arraylist = null; + List listOfString = new ArrayList(); + List listOfSomething = new ArrayList(); + ArrayList arrayListOfSomething = null; + List listOfNumber = null; + ArrayList arrayListOfNumber = null; + ArrayList arrayListOfInteger = null; + ArrayList arrayListOfSomethingNumberish = null; + List listOfSomethingNumberish = new ArrayList(); + List listOfSomethingSuperDouble = new ArrayList(); + List listOfInteger = new ArrayList(); + ArrayList arrayListOfString; + ArrayList arraylistOfInteger; + // interfaces too List + + ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfSomethingNumberish = resolve("Pjava/util/ArrayList<+Ljava/lang/Number;>;"); + ReferenceType ajList = resolve("Ljava/util/List;"); + ReferenceType ajArrayList = resolve("Ljava/util/ArrayList;"); + ReferenceType ajListOfString = resolve("Pjava/util/List;"); + ReferenceType ajListOfSomething = resolve("Pjava/util/List<*>;"); + ReferenceType ajArrayListOfSomething = resolve("Pjava/util/ArrayList<*>;"); + ReferenceType ajListOfSomethingNumberish = resolve("Pjava/util/List<+Ljava/lang/Number;>;"); + ReferenceType ajListOfSomethingSuperDouble = resolve("Pjava/util/List<-Ljava/lang/Double;>;"); + ReferenceType ajListOfInteger = resolve("Pjava/util/List;"); + ReferenceType ajListOfNumber = resolve("Pjava/util/List;"); + + // void m2(List e) {} + + // comment 11 + // void around(): execution(* C.m2(..)) && args(List){} //: Should not match (but it does) ERROR + listOfInteger = (List) listOfSomethingNumberish; + assertFalse(ajListOfInteger.isAssignableFrom(ajListOfSomethingNumberish)); + assertTrue(ajListOfInteger.isCoerceableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(ArrayList){}//: Should not match (but it does!) ERROR + arrayListOfInteger = (ArrayList) listOfSomethingNumberish; + assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfSomethingNumberish)); + assertTrue(ajArrayListOfInteger.isCoerceableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(List){} //: Should not match (but it does) ERROR + listOfNumber = (List) listOfSomethingNumberish; + assertFalse(ajListOfNumber.isAssignableFrom(ajListOfSomethingNumberish)); + assertTrue(ajListOfNumber.isCoerceableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(ArrayList){}//: Should not runtime check (but it does!) ERROR + arrayListOfNumber = (ArrayList) listOfSomethingNumberish; + assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfSomethingNumberish)); + assertTrue(ajArrayListOfNumber.isCoerceableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(List){}//: Should match (it does) + listOfSomethingNumberish = listOfSomethingNumberish; + assertTrue(ajListOfSomethingNumberish.isAssignableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(ArrayList){}//: Should runtime check (it does!) + arrayListOfSomethingNumberish = (ArrayList) listOfSomethingNumberish; + assertFalse(ajArrayListOfSomethingNumberish.isAssignableFrom(ajListOfSomethingNumberish)); + assertTrue(ajArrayListOfSomethingNumberish.isCoerceableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(List){}//: Should match (it does) + list = listOfSomethingNumberish; + assertTrue(ajList.isAssignableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(ArrayList){}//: Should runtime check (it does not match!) ERROR + arraylist = (ArrayList) listOfSomethingNumberish; + assertFalse(ajArrayList.isAssignableFrom(ajListOfSomethingNumberish)); + assertTrue(ajArrayList.isCoerceableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(List){}//: Should match (it does) + listOfSomething = listOfSomethingNumberish; + assertTrue(ajListOfSomething.isAssignableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(ArrayList){}//: Should runtime check (it does!) + arrayListOfSomething = (ArrayList) listOfSomethingNumberish; + assertFalse(ajArrayListOfSomething.isAssignableFrom(ajListOfSomethingNumberish)); + assertTrue(ajArrayListOfSomething.isCoerceableFrom(ajListOfSomethingNumberish)); + + // void around(): execution(* C.m2(..)) && args(ArrayList){}//: Should not match (it does not match!) + // error: arrayListOfString = listOfSomethingNumberish; + assertFalse(ajArrayListOfString.isAssignableFrom(ajListOfSomethingNumberish)); + assertFalse(ajArrayListOfString.isCoerceableFrom(ajListOfSomethingNumberish)); + } + + public void testAssignable04_method_m3() { + List list = new ArrayList(); + ArrayList arraylist = null; + List listOfString = new ArrayList(); + List listOfSomething = new ArrayList(); + ArrayList arrayListOfSomething = null; + List listOfNumber = null; + ArrayList arrayListOfNumber = null; + ArrayList arrayListOfInteger = null; + ArrayList arrayListOfSomethingNumberish = null; + List listOfSomethingNumberish = new ArrayList(); + List listOfSomethingSuperDouble = new ArrayList(); + List listOfInteger = new ArrayList(); + ArrayList arrayList = null; + ArrayList arrayListOfString; + ArrayList arraylistOfInteger; + // interfaces too List + + ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfSomethingNumberish = resolve("Pjava/util/ArrayList<+Ljava/lang/Number;>;"); + ReferenceType ajList = resolve("Ljava/util/List;"); + ReferenceType ajArrayList = resolve("Ljava/util/ArrayList;"); + ReferenceType ajListOfString = resolve("Pjava/util/List;"); + ReferenceType ajListOfSomething = resolve("Pjava/util/List<*>;"); + ReferenceType ajArrayListOfSomething = resolve("Pjava/util/ArrayList<*>;"); + ReferenceType ajListOfSomethingNumberish = resolve("Pjava/util/List<+Ljava/lang/Number;>;"); + ReferenceType ajListOfSomethingSuperDouble = resolve("Pjava/util/List<-Ljava/lang/Double;>;"); + ReferenceType ajListOfInteger = resolve("Pjava/util/List;"); + ReferenceType ajListOfNumber = resolve("Pjava/util/List;"); + + // void m3(List e) { } + + // void around(): execution(* C.m3(..)) && args(List){} //: Should not match (it does not) + // error: listOfInteger = listOfNumber; + assertFalse(ajListOfInteger.isAssignableFrom(ajListOfNumber)); + assertFalse(ajListOfInteger.isCoerceableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(ArrayList){}//: Should not match (it does not) + // error: arrayListOfInteger = listOfNumber; + assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfNumber)); + assertFalse(ajArrayListOfInteger.isCoerceableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(List){}//: Should match (it does) + listOfNumber = listOfNumber; + assertTrue(ajListOfNumber.isAssignableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(ArrayList){}//: Should runtime match (it does) + arrayListOfNumber = (ArrayList) listOfNumber; + assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfNumber)); + assertTrue(ajArrayListOfNumber.isCoerceableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(List){}//: Should match (it does) + listOfSomethingNumberish = listOfNumber; + assertTrue(ajListOfSomethingNumberish.isAssignableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(ArrayList){}//: Should runtime check (it does!) + arrayListOfSomethingNumberish = (ArrayList) listOfNumber; + assertFalse(ajArrayListOfSomethingNumberish.isAssignableFrom(ajListOfNumber)); + assertTrue(ajArrayListOfSomethingNumberish.isCoerceableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(List){}//: Should match (it does) + list = listOfNumber; + assertTrue(ajList.isAssignableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(ArrayList){}//: Should runtime check (it does not match!) ERROR + arrayList = (ArrayList) listOfNumber; + assertFalse(ajArrayList.isAssignableFrom(ajListOfNumber)); + assertTrue(ajArrayList.isCoerceableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(List){}//: Should match (it does) + listOfSomething = listOfNumber; + assertTrue(ajListOfSomething.isAssignableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(ArrayList){}//: Should runtime check (it does!) + arrayListOfSomething = (ArrayList) listOfNumber; + assertFalse(ajArrayListOfSomething.isAssignableFrom(ajListOfNumber)); + assertTrue(ajArrayListOfSomething.isCoerceableFrom(ajListOfNumber)); + + // void around(): execution(* C.m3(..)) && args(ArrayList){}//: Should not match (it does not match!) + // error: arrayListOfString = listOfNumber; + assertFalse(ajArrayListOfString.isAssignableFrom(ajListOfNumber)); + assertFalse(ajArrayListOfString.isCoerceableFrom(ajListOfNumber)); + + } + + static class ClassA { + } + + static interface IMarker { + } + + static class ClassB implements IMarker> { + } + + static class ClassC implements IMarker { + } + + public void testAssignability_pr267559() { + ClassB cb = new ClassB(); + ClassB cb2 = new ClassB(); + + ReferenceType rcb = resolve("Lorg/aspectj/weaver/ReferenceTypeTestCase$ClassB;"); + ReferenceType rcb2 = resolve("Lorg/aspectj/weaver/ReferenceTypeTestCase$ClassB;"); + boolean b = rcb.isAssignableFrom(rcb2); + assertTrue(b); + b = rcb2.isAssignableFrom(rcb); + assertTrue(b); + + rcb = resolve("Porg/aspectj/weaver/ReferenceTypeTestCase$IMarker;>;"); + rcb2 = resolve("Lorg/aspectj/weaver/ReferenceTypeTestCase$ClassB;"); + b = rcb.isAssignableFrom(rcb2); + assertTrue(b); + } + + public void testAssignable03_method_m4() { + List list = new ArrayList(); + ArrayList arraylist = null; + List listOfString = new ArrayList(); + List listOfSomething = new ArrayList(); + ArrayList arrayListOfSomething = null; + List listOfNumber = null; + ArrayList arrayListOfNumber = null; + ArrayList arrayListOfSomethingNumberish = null; + List listOfSomethingNumberish = new ArrayList(); + List listOfSomethingSuperDouble = new ArrayList(); + List listOfInteger = new ArrayList(); + ArrayList arrayListOfString; + ArrayList arraylistOfInteger; + // interfaces too List + + ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList;"); + ReferenceType ajArrayListOfSomethingNumberish = resolve("Pjava/util/ArrayList<+Ljava/lang/Number;>;"); + ReferenceType ajList = resolve("Ljava/util/List;"); + ReferenceType ajArrayList = resolve("Ljava/util/ArrayList;"); + ReferenceType ajListOfString = resolve("Pjava/util/List;"); + ReferenceType ajListOfSomething = resolve("Pjava/util/List<*>;"); + ReferenceType ajArrayListOfSomething = resolve("Pjava/util/ArrayList<*>;"); + ReferenceType ajListOfSomethingNumberish = resolve("Pjava/util/List<+Ljava/lang/Number;>;"); + ReferenceType ajListOfSomethingSuperDouble = resolve("Pjava/util/List<-Ljava/lang/Double;>;"); + ReferenceType ajListOfInteger = resolve("Pjava/util/List;"); + ReferenceType ajListOfNumber = resolve("Pjava/util/List;"); + + // void m4(List e) {} + + // void around(): execution(* C.m4(..)) && args(List){} //: Should match with unchecked warning + listOfInteger = (List) listOfSomething; + assertFalse(ajListOfInteger.isAssignableFrom(ajListOfSomething)); + assertTrue(ajListOfInteger.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(ArrayList){} // Should match with unchecked warning + arraylistOfInteger = (ArrayList) listOfSomething; + assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfSomething)); + assertTrue(ajArrayListOfInteger.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(List){} // Should match with unchecked warning + listOfNumber = (List) listOfSomething; + assertFalse(ajListOfNumber.isAssignableFrom(ajListOfSomething)); + assertTrue(ajListOfNumber.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(ArrayList){} // Should match with unchecked warning + arrayListOfNumber = (ArrayList) listOfSomething; + assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfSomething)); + assertTrue(ajArrayListOfNumber.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(List){} // Should match with unchecked warning + listOfSomethingNumberish = (List) listOfSomething; + assertFalse(ajListOfSomethingNumberish.isAssignableFrom(ajListOfSomething)); + assertTrue(ajListOfSomethingNumberish.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(ArrayList){} // Should match with unchecked warning + arrayListOfSomethingNumberish = (ArrayList) listOfSomething; + assertFalse(ajArrayListOfSomethingNumberish.isAssignableFrom(ajListOfSomething)); + assertTrue(ajArrayListOfSomethingNumberish.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(List){} // Should match + list = listOfSomething; + assertTrue(ajList.isAssignableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(ArrayList){} // Should runtime check + arraylist = (ArrayList) listOfSomething; + assertFalse(ajArrayList.isAssignableFrom(ajListOfSomething)); + assertTrue(ajArrayList.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(List){}//: Should match + list = listOfSomething; + assertTrue(ajList.isAssignableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(ArrayList){} // Should runtime check + arrayListOfSomething = (ArrayList) listOfSomething; + assertFalse(ajArrayListOfSomething.isAssignableFrom(ajListOfSomething)); + assertTrue(ajArrayListOfSomething.isCoerceableFrom(ajListOfSomething)); + + // void around(): execution(* C.m4(..)) && args(ArrayList){} // Should match with unchecked warning + arrayListOfString = (ArrayList) listOfSomething; + assertFalse(ajArrayListOfString.isAssignableFrom(ajListOfSomething)); + assertTrue(ajArrayListOfString.isCoerceableFrom(ajListOfSomething)); + } + + // copy of the real one in BcelClassWeaver + public static class IfaceInitList implements PartialOrder.PartialComparable { + final ResolvedType onType; + List list = new ArrayList(); + + IfaceInitList(ResolvedType onType) { + this.onType = onType; + } + + public int compareTo(Object other) { + IfaceInitList o = (IfaceInitList) other; + if (onType.isAssignableFrom(o.onType)) { + return +1; + } else if (o.onType.isAssignableFrom(onType)) { + return -1; + } else { + return 0; + } + } + + public int fallbackCompareTo(Object other) { + return 0; + } + } + + public void testExpensiveAssignableChecks_309336() { + List objects = new ArrayList(); + ReferenceType rcb = resolve("Lorg/aspectj/weaver/ReferenceTypeTestCase$Foo;"); + ReferenceType i = (ReferenceType) rcb.getDeclaredInterfaces()[0]; + while (i != null && i.isInterface()) { + objects.add(Math.abs(new Random(12).nextInt(objects.size() + 1)), new IfaceInitList(i)); + ResolvedType[] rt = i.getDeclaredInterfaces(); + i = rt == null || rt.length == 0 ? null : (ReferenceType) rt[0]; + } + for (int loop = 0; loop < 10; loop++) { + // ReferenceType.r = 0; + long stime = System.nanoTime(); + for (int j = 0; j < 10; j++) { + List objects2 = new ArrayList(); + objects2.addAll(objects); + PartialOrder.sort(objects2); + } + long etime = System.nanoTime(); + System.err.println("Took " + ((etime - stime) / 1000000) + "ms: calls ");// + ReferenceType.r); + } + // could do with asserting something... basically we are just checking we didn't run out of memory doing the sorts above! + } + + public interface Operator14 { + T execute(String aArg) throws E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, RemoteException; + } + + public interface Operator13 + extends Operator14 { + } + + public interface Operator12 + extends Operator13 { + } + + public interface Operator11 + extends Operator12 { + } + + public interface Operator10 + extends Operator11 { + + } + + public interface Operator9 + extends Operator10 { + } + + public interface Operator8 + extends Operator9 { + } + + public interface Operator7 + extends Operator8 { + } + + public interface Operator6 + extends Operator7 { + + } + + public interface Operator5 + extends Operator6 { + } + + public interface Operator4 extends + Operator5 { + } + + public interface Operator3 extends + Operator4 { + } + + public interface Operator2 extends Operator3 { + + } + + public interface Operator1 extends Operator2 { + } + + public interface Operator extends Operator1 { + } + + class Foo implements Operator { + public String execute(String aArg) throws NullPointerException, RemoteException { + System.out.println("Doh!"); + return aArg; + } + } + + // public void testAssignable_method_m5() { + // List list = new ArrayList(); + // ArrayList arraylist = null; + // List listOfString = new ArrayList(); + // List listOfSomething = new ArrayList(); + // ArrayList arrayListOfSomething = null; + // List listOfNumber = null; + // ArrayList arrayListOfNumber = null; + // ArrayList arrayListOfSomethingNumberish = null; + // List listOfSomethingNumberish = new ArrayList(); + // List listOfSomethingSuperDouble = new ArrayList(); + // List listOfInteger = new ArrayList(); + // ArrayList arrayListOfString; + // ArrayList arraylistOfInteger; + // // interfaces too List + // + // ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList;"); + // ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList;"); + // ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList;"); + // ReferenceType ajArrayListOfSomethingNumberish = resolve("Pjava/util/ArrayList<+Ljava/lang/Number;>;"); + // ReferenceType ajList = resolve("Ljava/util/List;"); + // ReferenceType ajArrayList = resolve("Ljava/util/ArrayList;"); + // ReferenceType ajListOfString = resolve("Pjava/util/List;"); + // ReferenceType ajListOfSomething = resolve("Pjava/util/List<*>;"); + // ReferenceType ajArrayListOfSomething = resolve("Pjava/util/ArrayList<*>;"); + // ReferenceType ajListOfSomethingNumberish = resolve("Pjava/util/List<+Ljava/lang/Number;>;"); + // ReferenceType ajListOfSomethingSuperDouble = resolve("Pjava/util/List<-Ljava/lang/Double;>;"); + // ReferenceType ajListOfInteger = resolve("Pjava/util/List;"); + // ReferenceType ajListOfNumber = resolve("Pjava/util/List;"); + // ReferenceType ajListOfEextendsNumber = resolve("Pjava/util/List<+TE") + // + // // class C { + // // void m5(List e) { } + // // + // // void around(): execution(* C.m5(..)) && args(List){} Should not match (but it does) ERROR + // + // // void around(): execution(* C.m5(..)) && args(ArrayList){}//: Should not match (but it does!) ERROR + // // void around(): execution(* C.m5(..)) && args(List){}//: Should not match (but it does!) ERROR + // // void around(): execution(* C.m5(..)) && args(ArrayList){}//: Should not match (it does) ERROR + // // void around(): execution(* C.m5(..)) && args(List){}//: Should match (it does) + // // void around(): execution(* C.m5(..)) && args(ArrayList){}//: Should runtime check (it does!) + // // void around(): execution(* C.m5(..)) && args(List){}//: Should match (it does) + // // void around(): execution(* C.m5(..)) && args(ArrayList){}//: Should runtime check (it does not match!) ERROR + // // void around(): execution(* C.m5(..)) && args(List){}//: Should match (it does) + // // void around(): execution(* C.m5(..)) && args(ArrayList){}//: Should runtime check (it does not match!) + // // void around(): execution(* C.m5(..)) && args(ArrayList){}//: Should not match (it does not match!) + // // + // // // void around(): execution(* D2.m5(..)) && args(List){} //: Should + // // not match (but it does) ERROR + // // // void around(): execution(* D2.m5(..)) && args(ArrayList){}//: + // // Should not match (but it does!) ERROR + // // // void around(): execution(* D2.m5(..)) && args(List){}//: Should + // // not match (but it does!) ERROR + // // // void around(): execution(* D2.m5(..)) && args(ArrayList){}//: + // // Should not match (it does) ERROR + // // // void around(): execution(* D2.m5(..)) && args(List){}//: + // // Should match (it does) + // // // void around(): execution(* D2.m5(..)) && args(ArrayList){}//: Should runtime check (it does!) + // // // void around(): execution(* D2.m5(..)) && args(List){}//: + // // Should match (it does) + // // // void around(): execution(* D2.m5(..)) && args(ArrayList){}//: Should runtime check (it does!) + // // // void around(): execution(* D2.m5(..)) && args(List){}//: Should match + // // (it does) + // // // void around(): execution(* D2.m5(..)) && args(ArrayList){}//: Should + // // runtime check (it does not match!) ERROR + // // // void around(): execution(* D2.m5(..)) && args(List){}//: Should + // // match (it does) + // // // void around(): execution(* D2.m5(..)) && args(ArrayList){}//: + // // Should runtime check (it does not match!) + // // // void around(): execution(* D2.m5(..)) && args(ArrayList){}//: + // // Should not match (it does not match!) + // // + // // // void around(): execution(* C.m6(..)) && args(List){} //: + // // Should not match (but it does) ERROR + // // // void around(): execution(* C.m6(..)) && args(ArrayList){}//: + // // Should not match (but it does!) ERROR + // // // void around(): execution(* C.m6(..)) && args(List){}//: Should + // // not match (but it does!) ERROR + // // // void around(): execution(* C.m6(..)) && args(ArrayList){}//: + // // Should not match (it does) ERROR + // // // void around(): execution(* C.m6(..)) && args(List){}//: Should match (it does) + // // // void around(): execution(* C.m6(..)) && args(ArrayList){}//: Should runtime check (it does!) + // // // void around(): execution(* C.m6(..)) && args(List){}//: Should match + // // (it does) + // // // void around(): execution(* C.m6(..)) && args(ArrayList){}//: Should + // // runtime check (it does not match!) + // // // void around(): execution(* C.m6(..)) && args(List){}//: Should + // // match (it does) + // // // void around(): execution(* C.m6(..)) && args(ArrayList){}//: Should + // // runtime check (it does not match!) + // // // void around(): execution(* C.m6(..)) && args(ArrayList){}//: + // // Should not match (it does not match!) + // // + // // // void around(): execution(* C.m7(..)) && args(List>){} + // // //: Should not match (but it does) ERROR + // // // void around(): execution(* C.m7(..)) && + // // args(ArrayList>){}//: Should not match (but it does!) ERROR + // // // void around(): execution(* C.m7(..)) && args(List>){}//: + // // Should not match (but it does!) ERROR + // // // void around(): execution(* C.m7(..)) && + // // args(ArrayList>){}//: Should not match (but it does) ERROR + // // // void around(): execution(* C.m7(..)) && args(List>){}//: Should not match (but it does) ERROR + // // // void around(): execution(* C.m7(..)) && args(ArrayList< ? extends + // // List>){}//: Should not match (but it does!) ERROR + // // // void around(): execution(* C.m7(..)) && args(List< ? extends List>){}//: Should match (it does!) + // // // void around(): execution(* C.m7(..)) && args(ArrayList< ? extends + // // List>){}//: Should match (it does!) + // // // void around(): execution(* C.m7(..)) && args(List){}//: Should match + // // (it does) + // // // void around(): execution(* C.m7(..)) && args(ArrayList){}//: Should + // // runtime check (it does not match!) + // // // void around(): execution(* C.m7(..)) && args(List){}//: Should + // // match (it does) + // // // void around(): execution(* C.m7(..)) && args(ArrayList){}//: Should + // // runtime check (it does!) + // // // void around(): execution(* C.m7(..)) && + // // args(ArrayList>){}//: Should not match (it does not match!) + // // + // // // void around(): execution(* C.m8(..)) && args(List){} //: + // // Should match with unchecked conversion (it does) + // // // void around(): execution(* C.m8(..)) && args(ArrayList){}//: + // // Should runtime check with unchecked conversion (it does!) + // // // void around(): execution(* C.m8(..)) && args(List){}//: Should + // // match with unchecked conversion (it does!) + // // // void around(): execution(* C.m8(..)) && args(ArrayList){}//: + // // Should runtime check with unchecked conversion (it does) + // // // void around(): execution(* C.m8(..)) && args(List){}//: Should match with unchecked conversion (it does!) + // // // void around(): execution(* C.m8(..)) && args(ArrayList){}//: Should runtime check with unchecked conversion (it does) + // // // void around(): execution(* C.m8(..)) && args(List){}//: Should match + // // (it does) + // // // void around(): execution(* C.m8(..)) && args(ArrayList){}//: Should + // // runtime check (it does!) + // // // void around(): execution(* C.m8(..)) && args(List){}//: Should + // // match (it does) + // // // void around(): execution(* C.m8(..)) && args(ArrayList){}//: Should + // // runtime check (it does!) + // // // void around(): execution(* C.m8(..)) && args(ArrayList){}//: + // // Should not match (it does not match!) + // // + // // // void around(): execution(* C.m9(..)) && args(List){} //: + // // Should not match (but it does) ERROR + // // // void around(): execution(* C.m9(..)) && args(ArrayList){}//: + // // Should not match (it does not match!) + // // // void around(): execution(* C.m9(..)) && args(Number){}//: Should match + // // (it does!) + // // // void around(): execution(* C.m9(..)) && args(Integer){}//: Should + // // runtime check (it does) + // // // void around(): execution(* C.m9(..)) && args(List){}//: Should not match (but it does) ERROR + // // // void around(): execution(* C.m9(..)) && args(ArrayList){}//: Should not match (it does not match!) + // // // void around(): execution(* C.m9(..)) && args(List){}//: Should not + // // match (but it does) ERROR + // // // void around(): execution(* C.m9(..)) && args(ArrayList){}//: Should + // // not match (it does not match!) + // // // void around(): execution(* C.m9(..)) && args(List){}//: Should not + // // match (but it does) ERROR + // // // void around(): execution(* C.m9(..)) && args(ArrayList){}//: Should + // // not match (it does not match!) + // // // void around(): execution(* C.m9(..)) && args(String){}//: Should not + // // match (it does not match!) + // + // } + + private ReferenceType resolve(String sig) { + return (ReferenceType) world.resolve(UnresolvedType.forSignature(sig)); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/ResolvedMemberSignatures15TestCase.java b/weaver/src/test/java/org/aspectj/weaver/ResolvedMemberSignatures15TestCase.java new file mode 100644 index 000000000..04697b884 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/ResolvedMemberSignatures15TestCase.java @@ -0,0 +1,281 @@ +/* ******************************************************************* + * 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; + +import java.lang.reflect.Modifier; + +import org.aspectj.weaver.bcel.BcelWorld; + +import junit.framework.TestCase; + +public class ResolvedMemberSignatures15TestCase extends TestCase { + + World world; + UnresolvedType baseType; + UnresolvedType derivedType; + + // STATIC METHODS + + public void testBaseOnlyStaticMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyBase", UnresolvedType.NONE); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD, derivedType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyBase", UnresolvedType.NONE); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + // this looks odd but we need both because of the way calls to inherited static methods + // are rendered in bytecode when written as obj.foo(); - the bytecode says it is a call + // to obj.getClass().foo() even if the static method is defined in a super type. + assertEquals("found 2 members",2,foundMembers.length); + StringBuilder s= new StringBuilder(); + for (ResolvedMember rm: foundMembers) { + s.append(rm.toString()+" "); + } + assertEquals("Expected derived but was "+foundMembers[0]+". All="+s,"Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Expected base but was "+foundMembers[1]+". All="+s,"Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + } + + public void testBothStaticMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "both", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD,derivedType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "both", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testDerivedStaticMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyDerived", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found nothing",0,foundMembers.length); + + toFind = new MemberImpl(Member.METHOD,derivedType, + (Modifier.PUBLIC | Modifier.STATIC), + UnresolvedType.forSignature("V"), + "onlyDerived", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + // NON-STATIC METHODS + + public void testBaseOnlyMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyBaseNonStatic", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyBaseNonStatic", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + + } + + public void testBothMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + Modifier.PUBLIC, UnresolvedType.forSignature("V"), + "bothNonStatic", UnresolvedType.NONE); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, UnresolvedType.forSignature("V"), + "bothNonStatic", UnresolvedType.NONE); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + } + + public void testDerivedMethod() { + Member toFind = new MemberImpl(Member.METHOD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyDerivedNonStatic", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found nothing",0,foundMembers.length); + + toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "onlyDerivedNonStatic", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testChangingThrowsClause() { + Member toFind = new MemberImpl(Member.METHOD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "m", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + + assertEquals("throws CloneNotSupported",1,foundMembers[1].getExceptions().length); + assertEquals("doesn't throw anything",0,foundMembers[0].getExceptions().length); + } + + // CONSTRUCTORS + + public void testNoWalkUpMatchingConstructor() { + Member toFind = new MemberImpl(Member.CONSTRUCTOR,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testNoWalkUpNoMatchingConstructor() { + Member toFind = new MemberImpl(Member.CONSTRUCTOR,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("V"), + "", + new UnresolvedType[] {UnresolvedType.forSignature("I")} + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("No matches",0,foundMembers.length); + } + + // FIELDS + + public void testBaseOnlyField() { + Member toFind = new MemberImpl(Member.FIELD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyBase", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.FIELD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyBase", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 2 members",2,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + assertEquals("Lfluffy/Base;",foundMembers[1].getDeclaringType().getSignature()); + } + + public void testBothField() { + Member toFind = new MemberImpl(Member.FIELD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "both", + new UnresolvedType[0] + ); + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 member",1,foundMembers.length); + assertEquals("Lfluffy/Base;",foundMembers[0].getDeclaringType().getSignature()); + + toFind = new MemberImpl(Member.FIELD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "both", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + public void testDerivedField() { + Member toFind = new MemberImpl(Member.FIELD,baseType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyDerived", + new UnresolvedType[0] + ); + + ResolvedMember[] foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found nothing",0,foundMembers.length); + + toFind = new MemberImpl(Member.FIELD,derivedType, + Modifier.PUBLIC, + UnresolvedType.forSignature("I"), + "onlyDerived", + new UnresolvedType[0] + ); + foundMembers = ResolvedMemberImpl.getJoinPointSignatures(toFind, world); + assertEquals("found 1 members",1,foundMembers.length); + assertEquals("Lfluffy/Derived;",foundMembers[0].getDeclaringType().getSignature()); + } + + protected void setUp() throws Exception { + world = new BcelWorld(); + world.setBehaveInJava5Way(true); + baseType = UnresolvedType.forSignature("Lfluffy/Base;"); + derivedType = UnresolvedType.forSignature("Lfluffy/Derived;"); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/TestShadow.java b/weaver/src/test/java/org/aspectj/weaver/TestShadow.java new file mode 100644 index 000000000..2cdfd84bf --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/TestShadow.java @@ -0,0 +1,131 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver; + +import org.aspectj.bridge.ISourceLocation; +import org.aspectj.weaver.ast.Var; + +public class TestShadow extends Shadow { + + private final World world; + private final UnresolvedType thisType; + + public TestShadow(Kind kind, Member signature, UnresolvedType thisType, World world) { + super(kind, signature, null); + this.world = world; + this.thisType = thisType; + } + + public World getIWorld() { + return world; + } + + /** this is subtly wrong. ha ha */ + public UnresolvedType getEnclosingType() { + return thisType; + } + + public Var getThisVar() { + // we should thorw if we don't have a this + return new Var(getThisType().resolve(world)); + } + + public Var getTargetVar() { + if (!hasTarget()) + throw new RuntimeException("bad"); + return new Var(getTargetType().resolve(world)); + } + + public Var getArgVar(int i) { + return new Var(getArgType(i).resolve(world)); + } + + public Var getThisEnclosingJoinPointStaticPartVar() { + throw new RuntimeException("unimplemented"); + } + + public Var getThisJoinPointStaticPartVar() { + throw new RuntimeException("unimplemented"); + } + + public Var getThisAspectInstanceVar(ResolvedType aspectType) { + throw new RuntimeException("unimplemented"); + } + + public Var getThisJoinPointVar() { + throw new RuntimeException("unimplemented"); + } + + public ISourceLocation getSourceLocation() { + throw new RuntimeException("unimplemented"); + } + + public Member getEnclosingCodeSignature() { + throw new RuntimeException("unimplemented"); + } + + /* + * (non-Javadoc) + * + * @see org.aspectj.weaver.Shadow#getKindedAnnotationVar() + */ + public Var getKindedAnnotationVar(UnresolvedType annotationType) { + throw new RuntimeException("unimplemented"); + } + + /* + * (non-Javadoc) + * + * @see org.aspectj.weaver.Shadow#getWithinAnnotationVar() + */ + public Var getWithinAnnotationVar(UnresolvedType annotationType) { + throw new RuntimeException("unimplemented"); + } + + /* + * (non-Javadoc) + * + * @see org.aspectj.weaver.Shadow#getWithinCodeAnnotationVar() + */ + public Var getWithinCodeAnnotationVar(UnresolvedType annotationType) { + throw new RuntimeException("unimplemented"); + } + + /* + * (non-Javadoc) + * + * @see org.aspectj.weaver.Shadow#getThisAnnotationVar() + */ + public Var getThisAnnotationVar(UnresolvedType annotationType) { + throw new RuntimeException("unimplemented"); + } + + /* + * (non-Javadoc) + * + * @see org.aspectj.weaver.Shadow#getTargetAnnotationVar() + */ + public Var getTargetAnnotationVar(UnresolvedType annotationType) { + throw new RuntimeException("unimplemented"); + } + + /* + * (non-Javadoc) + * + * @see org.aspectj.weaver.Shadow#getArgAnnotationVar(int) + */ + public Var getArgAnnotationVar(int i, UnresolvedType annotationType) { + throw new RuntimeException("unimplemented"); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/TraceFactoryTest.java b/weaver/src/test/java/org/aspectj/weaver/TraceFactoryTest.java new file mode 100644 index 000000000..24ec997fe --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/TraceFactoryTest.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import org.aspectj.weaver.tools.Trace; +import org.aspectj.weaver.tools.TraceFactory; + +import junit.framework.TestCase; + +public class TraceFactoryTest extends TestCase { + + public void testGetTraceFactory() { + TraceFactory traceFactory = TraceFactory.getTraceFactory(); + assertNotNull(traceFactory); + } + + public void testGetTrace() { + TraceFactory traceFactory = TraceFactory.getTraceFactory(); + Trace trace = traceFactory.getTrace(getClass()); + assertNotNull(trace); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java b/weaver/src/test/java/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java new file mode 100644 index 000000000..367a4fc93 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.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; + +import junit.framework.TestCase; + +import org.aspectj.weaver.bcel.BcelWorld; + +/** + * @author colyer + * + */ +public class TypeVariableReferenceTypeTestCase extends TestCase { + + ReferenceType javaLangClass; + ReferenceType jlNumber; + ReferenceType javaLangObject; + BoundedReferenceType extendsClass; + BoundedReferenceType superClass; + BoundedReferenceType extendsWithExtras; + BcelWorld world; + + @Override + protected void setUp() throws Exception { + super.setUp(); + world = new BcelWorld("../bin"); + world.setBehaveInJava5Way(true); + javaLangClass = (ReferenceType) world.resolve(UnresolvedType.forName("java/lang/Class")); + jlNumber = (ReferenceType) world.resolve(UnresolvedType.forSignature("Ljava/lang/Number;")); + javaLangObject = (ReferenceType) world.resolve(UnresolvedType.OBJECT); + extendsClass = new BoundedReferenceType(javaLangClass, true, world); + superClass = new BoundedReferenceType(javaLangClass, false, world); + extendsWithExtras = new BoundedReferenceType(javaLangClass, true, world, new ReferenceType[] { (ReferenceType) world + .resolve(UnresolvedType.forName("java/util/List")) }); + } + + public void testConstructionByNameAndVariable() { + TypeVariable tv = new TypeVariable("T", javaLangClass); + TypeVariableReferenceType tvrt = new TypeVariableReferenceType(tv, world); + assertEquals("T", tvrt.getTypeVariable().getName()); + assertEquals(javaLangClass, tvrt.getTypeVariable().getUpperBound()); + } + + public void testBounds() { + // Load up the testclass from below + ResolvedType testerClass = world.resolve(Tester1.class.getName()); + ResolvedType genericTesterClass = testerClass.getGenericType(); + + // Check the declaration type variable + TypeVariable[] typevars = genericTesterClass.getTypeVariables(); + TypeVariable typevar = typevars[0]; + assertEquals(jlNumber, typevar.getUpperBound()); + assertEquals("T", typevar.getName()); + ResolvedMember member = genericTesterClass.getDeclaredMethods()[1]; + + // getParameterTypes() returning the erased parameter + UnresolvedType param = member.getParameterTypes()[0]; + assertEquals(jlNumber, param); + + // Check the type variable reference + TypeVariableReferenceType tvReference = (TypeVariableReferenceType) member.getGenericParameterTypes()[0]; + assertEquals("T", tvReference.getTypeVariableName()); + assertEquals(jlNumber, tvReference.getUpperBound()); + assertEquals(jlNumber, tvReference.getDelegate().getResolvedTypeX()); + } + + class Tester1 { + public void method(T t) { + } + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/TypeVariableTestCase.java b/weaver/src/test/java/org/aspectj/weaver/TypeVariableTestCase.java new file mode 100644 index 000000000..8ef8f70c1 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/TypeVariableTestCase.java @@ -0,0 +1,110 @@ +/* ******************************************************************* + * 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; + +import junit.framework.TestCase; + +import org.aspectj.weaver.bcel.BcelWorld; + +public class TypeVariableTestCase extends TestCase { + + private UnresolvedType javaLangNumber; + private UnresolvedType javaLangDouble; + private UnresolvedType javaUtilList; + private UnresolvedType javaIoSerializable; + private World world; + + public void testName() { + TypeVariable tv = new TypeVariable("T"); + assertEquals("T", tv.getName()); + } + + public void testDefaultBounds() { + TypeVariable tv = new TypeVariable("T"); + assertEquals("Object", UnresolvedType.OBJECT, tv.getFirstBound()); + assertNull(tv.getUpperBound()); + assertEquals("no additional bounds", 0, tv.getSuperInterfaces().length); + } + + public void testUpperBound() { + TypeVariable tv = new TypeVariable("N", javaLangNumber); + assertEquals("java.lang.Number", javaLangNumber, tv.getUpperBound()); + } + + public void testAdditionalUpperBounds() { + TypeVariable tv = new TypeVariable("E", UnresolvedType.OBJECT, new UnresolvedType[] { javaUtilList }); + assertEquals("1 additional bound", 1, tv.getSuperInterfaces().length); + assertEquals("java.util.List", javaUtilList, tv.getSuperInterfaces()[0]); + + tv = new TypeVariable("E", null, new UnresolvedType[] { javaUtilList }); + assertEquals("1 additional bound", 1, tv.getSuperInterfaces().length); + assertEquals("java.util.List", javaUtilList, tv.getSuperInterfaces()[0]); + } + + public void testResolution() { + TypeVariable tv = new TypeVariable("T", javaLangNumber, new UnresolvedType[] { javaUtilList }); + tv.resolve(world); + assertEquals("resolved number", javaLangNumber.resolve(world), tv.getUpperBound()); + assertEquals("resolved list", javaUtilList.resolve(world), tv.getSuperInterfaces()[0]); + } + + public void testBindWithoutResolve() { + TypeVariable tv = new TypeVariable("X"); + try { + tv.canBeBoundTo(null); + fail("Should throw illegal state exception"); + } catch (IllegalStateException ex) { + } + } + + public void testCanBindToUpperMatch() { + TypeVariable tv = new TypeVariable("X", javaLangNumber); + tv.resolve(world); + assertTrue(tv.canBeBoundTo(javaLangDouble.resolve(world))); + } + + public void testCanBindToUpperFail() { + TypeVariable tv = new TypeVariable("X", javaLangNumber); + tv.resolve(world); + assertFalse(tv.canBeBoundTo(UnresolvedType.OBJECT.resolve(world))); + } + + public void testCanBindToInterfaceMatch() { + TypeVariable tv = new TypeVariable("T", javaLangNumber, new UnresolvedType[] { javaIoSerializable }); + tv.resolve(world); + assertTrue(tv.canBeBoundTo(javaLangDouble.resolve(world))); + } + + public void testCanBindToInterfaceFail() { + TypeVariable tv = new TypeVariable("T", javaLangNumber, new UnresolvedType[] { javaUtilList }); + tv.resolve(world); + assertFalse(tv.canBeBoundTo(javaLangDouble.resolve(world))); + } + + // --- + + @Override + protected void setUp() throws Exception { + super.setUp(); + javaLangNumber = UnresolvedType.forSignature("Ljava/lang/Number;"); + javaLangDouble = UnresolvedType.forSignature("Ljava/lang/Double;"); + javaIoSerializable = UnresolvedType.forSignature("Ljava/io/Serializable;"); + javaUtilList = UnresolvedType.forSignature("Ljava/util/List;"); + world = new BcelWorld(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/TypeXTestCase.java b/weaver/src/test/java/org/aspectj/weaver/TypeXTestCase.java new file mode 100644 index 000000000..dc4c2e3d1 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/TypeXTestCase.java @@ -0,0 +1,219 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +import junit.framework.TestCase; + +import org.aspectj.testing.util.TestUtil; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.bcel.BcelWorld; + +/** + * This is a test case for all the portions of UnresolvedType that don't require a world. + */ +public class TypeXTestCase extends TestCase { + + public TypeXTestCase(String name) { + super(name); + } + + public void testUnresolvedTypes() { + // basic equality + String[] testNames = + new String[] {"int", "long", "int[]", "boolean[][]", + "java.lang.String", "java.lang.String[]", "void" }; + String[] testSigs = + new String[] {"I", "J", "[I", "[[Z", + "Ljava/lang/String;", "[Ljava/lang/String;", "V" }; + + String[] componentNames = + new String[] {null, null, "int", "boolean[]", + null, "java.lang.String", null }; + + int[] sizes = new int[] {1, 2, 1, 1, 1, 1, 0}; + + boolean[] isPrimitive = + new boolean[] { true, true, false, false, false, false, true }; + + nameSignatureTest(testNames, testSigs); + arrayTest(UnresolvedType.forNames(testNames), componentNames); + arrayTest(UnresolvedType.forSignatures(testSigs), componentNames); + + sizeTest(UnresolvedType.forNames(testNames), sizes); + sizeTest(UnresolvedType.forSignatures(testSigs), sizes); + + isPrimitiveTest(UnresolvedType.forSignatures(testSigs), isPrimitive); + } + + public void testNameAndSigWithInners() { + UnresolvedType t = UnresolvedType.forName("java.util.Map$Entry"); + assertEquals(t.getName(), "java.util.Map$Entry"); + assertEquals(t.getSignature(), "Ljava/util/Map$Entry;"); + assertEquals(t.getOutermostType(), UnresolvedType.forName("java.util.Map")); + assertEquals(UnresolvedType.forName("java.util.Map").getOutermostType(), UnresolvedType.forName("java.util.Map")); + } + + public void testNameAndSigWithParameters() { + UnresolvedType t = UnresolvedType.forName("java.util.List"); + assertEquals(t.getName(),"java.util.List"); + assertEquals(t.getSignature(),"Pjava/util/List;"); + t = UnresolvedType.forSignature("Pjava/util/List;"); + assertEquals(t.getName(),"java.util.List"); + assertEquals(t.getSignature(),"Pjava/util/List;"); + t = UnresolvedType.forName("java.util.Map>"); + assertEquals(t.getName(),"java.util.Map>"); + assertEquals(t.getSignature(),"Pjava/util/Map;>;"); + t = UnresolvedType.forSignature("Pjava/util/Map;>;"); + assertEquals(t.getName(),"java.util.Map>"); + assertEquals(t.getSignature(),"Pjava/util/Map;>;"); + } + + /** + * Verify UnresolvedType signature processing creates the right kind of UnresolvedType's from a signature. + * + * For example, calling UnresolvedType.dump() for + * "Ljava/util/Map;Ljava/lang/String;>;" + * results in: + * UnresolvedType: signature=Ljava/util/Map;Ljava/lang/String;>; parameterized=true #params=2 + * UnresolvedType: signature=Ljava/util/List; parameterized=true #params=1 + * UnresolvedType: signature=Ljava/lang/String; parameterized=false #params=0 + * UnresolvedType: signature=Ljava/lang/String; parameterized=false #params=0 + */ + public void testTypexGenericSignatureProcessing() { + UnresolvedType tx = null; + + tx = UnresolvedType.forSignature("Pjava/util/Set;"); + checkTX(tx,true,1); + + tx = UnresolvedType.forSignature("Pjava/util/Set;>;"); + checkTX(tx,true,1); + + tx = UnresolvedType.forSignature("Pjava/util/Map;Ljava/lang/String;>;"); + checkTX(tx,true,2); + checkTX(tx.getTypeParameters()[0],true,1); + checkTX(tx.getTypeParameters()[1],false,0); +// System.err.println(tx.dump()); + } + + public void testTypeXForParameterizedTypes() { + if (LangUtil.is15VMOrGreater()) { // no funny types pre 1.5 + World world = new BcelWorld(); + UnresolvedType stringType = UnresolvedType.forName("java/lang/String"); + ResolvedType listOfStringType = + TypeFactory.createParameterizedType( + UnresolvedType.forName("java/util/List").resolve(world), + new UnresolvedType[] {stringType}, + world); + assertEquals("1 type param",1,listOfStringType.typeParameters.length); + assertEquals(stringType,listOfStringType.typeParameters[0]); + assertTrue(listOfStringType.isParameterizedType()); + assertFalse(listOfStringType.isGenericType()); + } + } + + public void testTypeFactoryForParameterizedTypes() { + if (LangUtil.is15VMOrGreater()) { // no funny types pre 1.5 + UnresolvedType enumOfSimpleType = + TypeFactory.createTypeFromSignature("Pjava/lang/Enum;"); + assertEquals(1, enumOfSimpleType.getTypeParameters().length); + + UnresolvedType enumOfNestedType = + TypeFactory.createTypeFromSignature("Pjava/lang/Enum;"); + assertEquals(1, enumOfNestedType.getTypeParameters().length); + + // is this signature right? + UnresolvedType nestedTypeOfParameterized = + TypeFactory.createTypeFromSignature("PMyInterface$MyOtherType;"); + assertEquals(0, nestedTypeOfParameterized.getTypeParameters().length); + + // how about this one? is this valid? + UnresolvedType doublyNestedTypeSignatures = + TypeFactory.createTypeFromSignature("PMyInterface$MyOtherType;"); + assertEquals(1, doublyNestedTypeSignatures.getTypeParameters().length); + + } + } + + private void checkTX(UnresolvedType tx,boolean shouldBeParameterized,int numberOfTypeParameters) { + assertTrue("Expected parameterization flag to be "+shouldBeParameterized,tx.isParameterizedType()==shouldBeParameterized); + if (numberOfTypeParameters==0) { + UnresolvedType[] params = tx.getTypeParameters(); + assertTrue("Expected 0 type parameters but found "+params.length, params.length==0); + } else { + assertTrue("Expected #type parameters to be "+numberOfTypeParameters,tx.getTypeParameters().length==numberOfTypeParameters); + } + } + + + private void isPrimitiveTest(UnresolvedType[] types, boolean[] isPrimitives) { + for (int i = 0, len = types.length; i < len; i++) { + UnresolvedType type = types[i]; + boolean b = isPrimitives[i]; + assertEquals(type + " is primitive: ", b, type.isPrimitiveType()); + } + } + + private void sizeTest(UnresolvedType[] types, int[] sizes) { + for (int i = 0, len = types.length; i < len; i++) { + UnresolvedType type = types[i]; + int size = sizes[i]; + assertEquals("size of " + type + ": ", size, type.getSize()); + } + } + + private void arrayTest(UnresolvedType[] types, String[] components) { + for (int i = 0, len = types.length; i < len; i++) { + UnresolvedType type = types[i]; + String component = components[i]; + assertEquals(type + " is array: ", component != null, type.isArray()); + if (component != null) + assertEquals(type + " componentType: ", component, + type.getComponentType().getName()); + } + } + + private void nameSignatureTest(String[] ns, String[] ss) { + for (int i = 0, len = ns.length; i < len; i++) { + String n = ns[i]; + String s = ss[i]; + UnresolvedType tn = UnresolvedType.forName(n); + UnresolvedType ts = UnresolvedType.forSignature(s); + + assertEquals("forName(n).getName()", n, + tn.getName()); + assertEquals("forSignature(s).getSignature()", s, + ts.getSignature()); + assertEquals("forName(n).getSignature()", s, + tn.getSignature()); + assertEquals("forSignature(n).getName()", n, + ts.getName()); + + TestUtil.assertCommutativeEquals(tn, tn, true); + TestUtil.assertCommutativeEquals(ts, ts, true); + TestUtil.assertCommutativeEquals(tn, ts, true); + + for (int j = 0; j < len; j++) { + if (i == j) continue; + UnresolvedType tn1 = UnresolvedType.forName(ns[j]); + UnresolvedType ts1 = UnresolvedType.forSignature(ss[j]); + TestUtil.assertCommutativeEquals(tn, tn1, false); + TestUtil.assertCommutativeEquals(ts, tn1, false); + TestUtil.assertCommutativeEquals(tn, ts1, false); + TestUtil.assertCommutativeEquals(ts, ts1, false); + } + } + } + + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/Weaver5ModuleTests.java b/weaver/src/test/java/org/aspectj/weaver/Weaver5ModuleTests.java new file mode 100644 index 000000000..d54732b08 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/Weaver5ModuleTests.java @@ -0,0 +1,37 @@ +//package org.aspectj.weaver; +///******************************************************************************* +// * 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: (See CVS logs) +// * +// *******************************************************************************/ +// +//import junit.framework.Test; +//import junit.framework.TestCase; +//import junit.framework.TestSuite; +// +//import org.aspectj.testing.util.TestUtil; +// +///** +// */ +//public class Weaver5ModuleTests extends TestCase { +// +// public static Test suite() { +// TestSuite suite = new TestSuite(Weaver5ModuleTests.class.getName()); +// if (TestUtil.is15VMOrGreater()) { +// TestUtil.loadTestsReflectively(suite, "org.aspectj.weaver.AllWeaver5Tests", false); +// } else { +// suite.addTest(TestUtil.testNamed("all tests require 1.5")); +// } +// return suite; +// } +// public static void main(String[] args) { +// junit.textui.TestRunner.main(new String[] {Weaver5ModuleTests.class.getName()}); +// } +// +//} diff --git a/weaver/src/test/java/org/aspectj/weaver/WeaverMessagesTestCase.java b/weaver/src/test/java/org/aspectj/weaver/WeaverMessagesTestCase.java new file mode 100644 index 000000000..7326971d3 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/WeaverMessagesTestCase.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.aspectj.weaver; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.MissingResourceException; + +import junit.framework.TestCase; + +/** + * @author Adrian Colyer + */ +public class WeaverMessagesTestCase extends TestCase { + + public void testAllMessagesDefined() { + + Class wmClass = WeaverMessages.class; + Field[] fields = wmClass.getDeclaredFields(); + List fieldList = new ArrayList(); + for (int i = 0; i < fields.length; i++) { + Field f = fields[i]; + if (f.getType() == String.class) { + try { + String key = (String) f.get(null); +// String value = WeaverMessages.format(key); + assertFalse("Each key should be unique",fieldList.contains(key)); + fieldList.add(key); +// System.out.println(key + "," + value); + } catch (IllegalAccessException ex) { + } catch(MissingResourceException mrEx) { + fail("Missing resource: " + mrEx); + } + } + } + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/WeaverTestCase.java b/weaver/src/test/java/org/aspectj/weaver/WeaverTestCase.java new file mode 100644 index 000000000..152cae782 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/WeaverTestCase.java @@ -0,0 +1,50 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver; + +import java.io.File; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +import org.aspectj.util.FileUtil; + +public abstract class WeaverTestCase extends TestCase { + + public static final String TESTDATA_PATH = "../weaver/testdata"; + public static final String OUTDIR_PATH = "../weaver/out"; + + /** @return File outDir (writable) or null if unable to write */ + public static File getOutdir() { + File result = new File(OUTDIR_PATH); + if (result.mkdirs() || (result.canWrite() && result.isDirectory())) { + return result; + } + return null; + } + + /** best efforts to delete the output directory and any contents */ + public static void removeOutDir() { + File outDir = getOutdir(); + if (null != outDir) { + FileUtil.deleteContents(outDir); + outDir.delete(); + } + } + + public WeaverTestCase(String name) { + super(name); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/AfterReturningWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/AfterReturningWeaveTestCase.java new file mode 100644 index 000000000..8ccafe4de --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/AfterReturningWeaveTestCase.java @@ -0,0 +1,58 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +import org.aspectj.weaver.ShadowMunger; + +public class AfterReturningWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public AfterReturningWeaveTestCase(String name) { + super(name); + } + + public void testAfterReturning() throws IOException { + weaveTest( + getStandardTargets(), + "AfterReturning", + makeAdviceAll("afterReturning")); + } + + public void testAfterReturningParam() throws IOException { + weaveTest( + getStandardTargets(), + "AfterReturningParam", + makeAdviceField("afterReturning", "java.lang.Object")); + } + public void testAfterReturningCheckcastParam() throws IOException { + weaveTest( + getStandardTargets(), + "AfterReturningCheckcastParam", + makeAdviceField("afterReturning", "java.rmi.server.LogStream")); + } + + public void testAfterReturningConversionParam() throws IOException { + String mungerString = + "afterReturning(): call(int *.*(..)) -> " + + "static void Aspect.ajc_afterReturning_field_get(java.lang.Object)"; + ShadowMunger cm = makeConcreteAdvice(mungerString, 1); + + weaveTest("FancyHelloWorld", "AfterReturningConversionParam", cm); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java new file mode 100644 index 000000000..b0c3f04ce --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java @@ -0,0 +1,45 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +import org.aspectj.weaver.Advice; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.ShadowMunger; + +public class AfterThrowingWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public AfterThrowingWeaveTestCase(String name) { + super(name); + } + + public void testAfterThrowing() throws IOException { + weaveTest(getStandardTargets(), "AfterThrowing", makeAdviceAll("afterThrowing")); + } + + public void testAfterThrowingParam() throws IOException { + BcelWorld world = new BcelWorld(); + + ShadowMunger myMunger = BcelTestUtils.shadowMunger(world, + "afterThrowing(): get(* *.out) -> static void Aspect.ajc_afterThrowing_field_get(java.lang.Throwable)", + Advice.ExtraArgument); + ShadowMunger cm = myMunger.concretize(ResolvedType.MISSING, world, null); + + weaveTest(getStandardTargets(), "AfterThrowingParam", cm); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/AfterWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/AfterWeaveTestCase.java new file mode 100644 index 000000000..a51c69b9a --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/AfterWeaveTestCase.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.*; + +public class AfterWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public AfterWeaveTestCase(String name) { + super(name); + } + + + public void testAfter() throws IOException { + weaveTest(getStandardTargets(), "After", makeAdviceAll("after")); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java new file mode 100644 index 000000000..1108c3574 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java @@ -0,0 +1,119 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.generic.InstructionFactory; +import org.aspectj.apache.bcel.generic.InstructionHandle; +import org.aspectj.apache.bcel.generic.InstructionList; +import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.weaver.AdviceKind; +import org.aspectj.weaver.MemberImpl; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.UnresolvedType; + +/**. + */ +public class ArgsWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public ArgsWeaveTestCase(String name) { + super(name); + } + + + public void testAfterReturningArgs() throws IOException { + weaveTest("HelloWorld", "ArgsAfterReturningHelloWorld", makeArgsMunger("afterReturning")); + } + + + public void testFancyAfterReturningArgs() throws IOException { + weaveTest("FancyHelloWorld", "ArgsAfterReturningFancyHelloWorld", makeArgsMunger("afterReturning")); + } + + public void testThrowing() throws IOException { + weaveTest("HelloWorld", "ArgsAfterThrowingHelloWorld", makeArgsMunger("afterThrowing")); + } + + public void testLots() throws IOException { + List l = new ArrayList<>(); + + BcelAdvice p1 = + makeArgsMunger("before"); + + BcelAdvice p2 = + makeArgsMunger("afterThrowing"); + + BcelAdvice p3 = + makeArgsMunger("afterReturning"); + + l.add(p1); + l.add(p2); + l.add(p3); + + weaveTest("HelloWorld", "ArgsBeforeAfterHelloWorld", addLexicalOrder(l)); + } + + /* private */ InstructionList getArgsAdviceTag(BcelShadow shadow, String where) { + String methodName = + "ajc_" + where + "_" + shadow.getKind().toLegalJavaIdentifier(); + InstructionFactory fact = shadow.getFactory(); + InstructionList il = new InstructionList(); + + + il.append( + BcelRenderer.renderExpr( + fact, + new BcelWorld(), + shadow.getArgVar(0), + Type.OBJECT)); + + il.append( + fact.createInvoke( + "Aspect", + methodName, + Type.VOID, + new Type[] { Type.OBJECT }, + Constants.INVOKESTATIC)); + + return il; + } + + private BcelAdvice makeArgsMunger(final String kindx) { + ResolvedType rtx = world.resolve(UnresolvedType.forName("Aspect"),true); + assertTrue("Cant find required type Aspect",!rtx.isMissing()); + return new BcelAdvice(AdviceKind.stringToKind(kindx), makePointcutNoZeroArg(), + MemberImpl.method(UnresolvedType.forName("Aspect"), 0, "foo", "()V"), 0, -1, -1, null, + rtx) { + @Override + public void specializeOn(Shadow shadow) { + super.specializeOn(shadow); + shadow.getArgVar(0); + } + @Override + public InstructionList getAdviceInstructions(BcelShadow shadow, BcelVar extraVar, InstructionHandle fk) { + return getArgsAdviceTag(shadow, kindx); + } + }; + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/AroundArgsWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/AroundArgsWeaveTestCase.java new file mode 100644 index 000000000..4088755b5 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/AroundArgsWeaveTestCase.java @@ -0,0 +1,41 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +import org.aspectj.weaver.ShadowMunger; + +public class AroundArgsWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public AroundArgsWeaveTestCase(String name) { + super(name); + } + + public void testWeave() throws IOException + { + String label = "AroundArgs"; + ShadowMunger p = + makeConcreteAdvice( + "around(list) : " + + "(call(public * add(..)) && target(list)) -> " + + "static boolean Aspect.ajc_around0" + + "(java.util.ArrayList, org.aspectj.runtime.internal.AroundClosure)"); + weaveTest(new String[] {"DynamicHelloWorld"}, label, p); + + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/AroundWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/AroundWeaveTestCase.java new file mode 100644 index 000000000..a9d1fe9b4 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/AroundWeaveTestCase.java @@ -0,0 +1,100 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.weaver.AdviceKind; +import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; +import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.UnresolvedType; + +public class AroundWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public AroundWeaveTestCase(String name) { + super(name); + } + + public void testAround() throws IOException { + aroundTest("Around", true); + } + + public void testAroundAll() throws IOException { + aroundTest("AroundAll", false); + } + + public void testAroundAndOthers() throws IOException { + aroundTestAndOthers("AroundAndOthers", true); + } + + public void testAroundAllAndOthers() throws IOException { + aroundTestAndOthers("AroundAllAndOthers", false); + } + + + private BcelAdvice makeAroundMunger(final boolean matchOnlyPrintln) { + BcelWorld world = super.world; + final Member sig = + MemberImpl.method( + UnresolvedType.forName("Aspect"), + Modifier.STATIC, + "ajc_around", + "(Lorg/aspectj/runtime/internal/AroundClosure;)Ljava/lang/Object;"); + + return new BcelAdvice( + AdviceKind.stringToKind("around"), + matchOnlyPrintln ? makePointcutPrintln() : makePointcutAll(), + sig, 0, -1, -1, null, UnresolvedType.forName("Aspect").resolve(world)) + { + @Override + public void specializeOn(Shadow s) { + super.specializeOn(s); + ((BcelShadow) s).initializeForAroundClosure(); + } + }; + } + + private void aroundTest(String outName, final boolean matchOnlyPrintln) throws IOException { + weaveTest(getStandardTargets(), outName, makeAroundMunger(matchOnlyPrintln)); + } + + private void aroundTestAndOthers(String outName, final boolean matchOnlyPrintln) + throws IOException + { + + List l = new ArrayList<>(); + + // the afterReturning was taken out to avoid circular advice dependency + + l.addAll(makeAdviceAll("before", matchOnlyPrintln)); + //l.addAll(makeAdviceAll("afterReturning", matchOnlyPrintln)); + + l.add(makeAroundMunger(matchOnlyPrintln)); + + l.addAll(makeAdviceAll("before", matchOnlyPrintln)); + //l.addAll(makeAdviceAll("afterReturning", matchOnlyPrintln)); + + l.add(makeAroundMunger(matchOnlyPrintln)); + weaveTest(getStandardTargets(), outName, addLexicalOrder(l)); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java new file mode 100644 index 000000000..58f774840 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java @@ -0,0 +1,68 @@ +/* ******************************************************************* + * 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.bcel; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.Repository; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Signature; +import org.aspectj.util.GenericSignature; +import org.aspectj.util.GenericSignatureParser; +import org.aspectj.util.GenericSignature.ClassSignature; +import org.aspectj.weaver.UnresolvedType; + +/** + * @author colyer + * + */ +public class BcelGenericSignatureToTypeXTestCase extends TestCase { + + public final GenericSignature.ClassSignature getGenericClassTypeSignature(JavaClass jClass) { + Signature sig = jClass.getSignatureAttribute(); + if (sig != null) { + GenericSignatureParser parser = new GenericSignatureParser(); + ClassSignature classSig = parser.parseAsClassSignature(sig.getSignature()); + return classSig; + } + return null; + } + + public void testEnumFromHell() throws Exception { + BcelWorld world = new BcelWorld(); + JavaClass javaLangEnum = Repository.lookupClass("java/lang/Enum"); + GenericSignature.ClassSignature cSig = getGenericClassTypeSignature(javaLangEnum); + UnresolvedType superclass = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(cSig.superclassSignature, + cSig.formalTypeParameters, world); + assertEquals("Ljava/lang/Object;", superclass.getSignature()); + assertEquals("2 superinterfaces", 2, cSig.superInterfaceSignatures.length); + UnresolvedType comparable = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(cSig.superInterfaceSignatures[0], + cSig.formalTypeParameters, world); + assertEquals("Pjava/lang/Comparable;", comparable.getSignature()); + UnresolvedType serializable = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX( + cSig.superInterfaceSignatures[1], cSig.formalTypeParameters, world); + assertEquals("Ljava/io/Serializable;", serializable.getSignature()); + } + + public void testColonColon() throws Exception { + BcelWorld world = new BcelWorld(); + GenericSignature.ClassSignature cSig = new GenericSignatureParser() + .parseAsClassSignature("Ljava/lang/Object;Ljava/lang/Comparable;"); + UnresolvedType resolved = BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(cSig.superclassSignature, + cSig.formalTypeParameters, world); + assertEquals("Ljava/lang/Object;", resolved.getSignature()); + BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(cSig.superInterfaceSignatures[0], cSig.formalTypeParameters, + world); + + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/BcelTestUtils.java b/weaver/src/test/java/org/aspectj/weaver/bcel/BcelTestUtils.java new file mode 100644 index 000000000..bc9f47a85 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/BcelTestUtils.java @@ -0,0 +1,65 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.weaver.bcel; + +import org.aspectj.weaver.Advice; +import org.aspectj.weaver.AdviceKind; +import org.aspectj.weaver.Member; +import org.aspectj.weaver.TestUtils; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; +import org.aspectj.weaver.patterns.FormalBinding; +import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.SimpleScope; + +public class BcelTestUtils { + /** + * Moved from BcelWorld to here + * + * Parse a string into advice. + * + *
+ * + *
+	 * Kind ( Id , ... ) : Pointcut -> MethodSignature
+	 * 
+ * + *
+ */ + public static Advice shadowMunger(World w, String str, int extraFlag) { + str = str.trim(); + int start = 0; + int i = str.indexOf('('); + AdviceKind kind = AdviceKind.stringToKind(str.substring(start, i)); + start = ++i; + i = str.indexOf(')', i); + String[] ids = TestUtils.parseIds(str.substring(start, i).trim()); + // start = ++i; + + i = str.indexOf(':', i); + start = ++i; + i = str.indexOf("->", i); + Pointcut pointcut = Pointcut.fromString(str.substring(start, i).trim()); + Member m = TestUtils.methodFromString(str.substring(i + 2, str.length()).trim()); + + // now, we resolve + UnresolvedType[] types = m.getParameterTypes(); + FormalBinding[] bindings = new FormalBinding[ids.length]; + for (int j = 0, len = ids.length; j < len; j++) { + bindings[j] = new FormalBinding(types[j], ids[j], j, 0, 0); + } + + Pointcut p = pointcut.resolve(new SimpleScope(w, bindings)); + + return new BcelAdvice(kind, p, m, extraFlag, 0, 0, null, null); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/BcelWorldReferenceTypeTest.java b/weaver/src/test/java/org/aspectj/weaver/bcel/BcelWorldReferenceTypeTest.java new file mode 100644 index 000000000..0ab70023e --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/BcelWorldReferenceTypeTest.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * Copyright (c) 2002-2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ +package org.aspectj.weaver.bcel; + +import org.aspectj.weaver.CommonReferenceTypeTests; +import org.aspectj.weaver.World; + +public class BcelWorldReferenceTypeTest extends CommonReferenceTypeTests { + + public World getWorld() { + return new BcelWorld(); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/BeforeWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/BeforeWeaveTestCase.java new file mode 100644 index 000000000..a43689777 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/BeforeWeaveTestCase.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +public class BeforeWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public BeforeWeaveTestCase(String name) { + super(name); + } + + + public void testBefore() throws IOException { + weaveTest(getStandardTargets(), "Before", makeAdviceAll("before")); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/CheckerTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/CheckerTestCase.java new file mode 100644 index 000000000..b503e9593 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/CheckerTestCase.java @@ -0,0 +1,48 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +import org.aspectj.weaver.Checker; +import org.aspectj.weaver.patterns.DeclareErrorOrWarning; +import org.aspectj.bridge.*; +import org.aspectj.bridge.MessageHandler; + +public class CheckerTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public CheckerTestCase(String name) { + super(name); + } + + + public void testStaticTjp() throws IOException { + Checker checker = new Checker( + new DeclareErrorOrWarning(true, makePointcutPrintln(), "hey, we found a println")); + + MessageHandler handler = new MessageHandler(); + world.setMessageHandler(handler); + + weaveTest("HelloWorld", "IdHelloWorld", checker); + assertEquals(1, handler.numMessages(IMessage.ERROR, false)); + + handler = new MessageHandler(); + world.setMessageHandler(handler); + weaveTest("FancyHelloWorld", "IdFancyHelloWorld", checker); + assertEquals(3, handler.numMessages(IMessage.ERROR, false)); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/ClassLoaderRepositoryTest.java b/weaver/src/test/java/org/aspectj/weaver/bcel/ClassLoaderRepositoryTest.java new file mode 100644 index 000000000..1d668def2 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/ClassLoaderRepositoryTest.java @@ -0,0 +1,213 @@ +/* ******************************************************************* + * Copyright (c) 2006 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.File; +import java.lang.ref.Reference; +import java.lang.reflect.Field; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Enumeration; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.util.ClassLoaderRepository; + +/** NOT YET INCLUDED IN A FULL TEST RUN - WORK IN PROGRESS CHECKING CLASSLOADERREPOSITORY OPTIMIZATIONS */ +public class ClassLoaderRepositoryTest extends TestCase { + private File f; + private ZipFile zf; + private Enumeration entries; + private Map map; + + public void setUp() throws Exception { + f = new File("../lib/aspectj/lib/aspectjtools.jar"); + assertTrue("Couldn't find aspectjtools to test. Tried: "+f.getAbsolutePath(),f.exists()); + zf = new ZipFile(f); + entries = zf.entries(); +// ClassLoaderRepository.sharedCacheCompactFrequency = 16384; + map = getSharedMap(); + } + + public void tearDown() { + new ClassLoaderRepository((ClassLoader) null).reset(); + } + + private ClassLoaderRepository setupRepository() throws Exception { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + ClassLoader res = new URLClassLoader(new URL[]{f.toURL()},cl); + ClassLoaderRepository rep = new ClassLoaderRepository(res); + return rep; + } + + private void compareTwoRepositories() throws Exception { + ClassLoaderRepository rep1 = setupRepository(); + ClassLoaderRepository rep2 = setupRepository(); + int i = 0; + while (entries.hasMoreElements()) { + ZipEntry zfe = (ZipEntry)entries.nextElement(); + String classfileName = zfe.getName(); + if (classfileName.endsWith(".class")) { + String clazzname = classfileName.substring(0,classfileName.length()-6).replace('/','.'); + + // twice by each + rep1.loadClass(clazzname); + rep1.loadClass(clazzname); + rep2.loadClass(clazzname); + rep2.loadClass(clazzname); + i++; + } + } + System.err.println("Successfully compared "+i+" entries!!"); + System.err.println(rep1.report()); + System.err.println(rep2.report()); + } + +// private void loadOnce() throws Exception { +// ClassLoaderRepository rep = setupRepository(); +// while (entries.hasMoreElements()) { +// ZipEntry zfe = (ZipEntry) entries.nextElement(); +// String classfileName = zfe.getName(); +// if (classfileName.endsWith(".class")) { +// String clazzname = classfileName.substring(0, +// classfileName.length() - 6).replace('/', '.'); +// +// rep.loadClass(clazzname); +// } +// } +// } + + public void testMultiThreaded() throws Throwable { + ClassLoaderRepository.useSharedCache=true; +// ClassLoaderRepository.sharedCacheCompactFrequency = 200; + //loadOnce(); + TestThread threads[] = new TestThread[6]; + for (int i=0; i())", + "constructor-call(void java.lang.StringBuffer.(java.lang.String))" }); + } + + public void testId() throws IOException { + final List l = new ArrayList(); + BcelAdvice p = new BcelAdvice(null, makePointcutAll(), null, 0, -1, -1, null, null) { + public boolean implementOn(Shadow shadow) { + l.add(shadow); + return true; + } + }; + weaveTest(new String[] { "HelloWorld" }, "Id2", p); + + checkShadowSet(l, new String[] { "method-execution(void HelloWorld.main(java.lang.String[]))", + "method-call(void java.io.PrintStream.println(java.lang.String))", + "field-get(java.io.PrintStream java.lang.System.out)", "constructor-execution(void HelloWorld.())", }); + } + + // this test requires that Trace has been unzipped and placed in the correct place + // public void testTraceId() throws IOException { + // String saveClassDir = classDir; + // try { + // classDir = "testdata/dummyAspect.jar"; + // + // + // + // final List l = new ArrayList(); + // BcelAdvice p = new BcelAdvice(null, makePointcutAll(), null, 0, -1, -1, null, null) { + // public void implementOn(Shadow shadow) { + // l.add(shadow); + // } + // }; + // boolean tempRunTests = runTests; + // runTests = false; + // weaveTest(new String[] {"DummyAspect"}, "Id", p); + // runTests = tempRunTests; + // + // checkShadowSet(l, new String[] { + // "constructor-execution(void DummyAspect.())", + // // XXX waiting on parser stuff + // //"advice-execution(void DummyAspect.ajc_before_1(java.lang.Object))", + // }); + // } finally { + // classDir = saveClassDir; + // } + // } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/JImageTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/JImageTestCase.java new file mode 100644 index 000000000..6e89c675c --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/JImageTestCase.java @@ -0,0 +1,139 @@ +/* ******************************************************************* + * Copyright (c) 2017 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * ******************************************************************/ +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.net.URI; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.bcel.ClassPathManager.ClassFile; +import org.aspectj.weaver.bcel.ClassPathManager.Entry; +import org.aspectj.weaver.bcel.ClassPathManager.JImageEntry; + +import junit.framework.TestCase; + +/** + * Exercise the JImage handling in @link {@link org.aspectj.weaver.bcel.ClassPathManager}. + * + * @author Andy Clement + */ +public class JImageTestCase extends TestCase { + + ClassPathManager cpm; + + public void setUp() throws Exception { + List paths = new ArrayList<>(); + paths.add(LangUtil.getJrtFsFilePath()); + cpm = new ClassPathManager(paths,new TestMessageHandler()); + } + + public void testOnJava9() { + if (!LangUtil.is19VMOrGreater()) { + System.out.println("SKIPPING JIMAGE TESTS AS NOT ON 1.9 OR LATER"); + } + } + + public void testBasicStructureAndCapabilities() { + if (!LangUtil.is19VMOrGreater()) return; + // Should be one entry for finding JRT contents + List entries = cpm.getEntries(); + assertEquals(1,entries.size()); + assertEquals(JImageEntry.class,entries.get(0).getClass()); + + ClassFile stringClassFile = cpm.find(UnresolvedType.JL_STRING); + assertNotNull(stringClassFile); + assertEquals("java/lang/String.class",stringClassFile.getPath()); + } + + public void testBehaviour() throws Exception { + if (!LangUtil.is19VMOrGreater()) return; + JImageEntry jie = getJImageEntry(); + + Map packageCache = JImageEntry.getPackageCache(); + assertTrue(packageCache.size()>0); + // Note: seems to be about 1625 entries in it for Java9 + Path path = packageCache.get("java/lang"); + assertEquals("modules/java.base/java/lang", path.toString()); + path = packageCache.get("java/io"); + assertEquals("modules/java.base/java/io", path.toString()); + + assertNotNull(jie.find("java/lang/String")); + assertNotNull(jie.find("java/io/File")); + // TODO test the filecache, hard because difficult to simulate collection of SoftReferences + } + + + static class TestMessageHandler implements IMessageHandler { + + @Override + public boolean handleMessage(IMessage message) throws AbortException { + return false; + } + + @Override + public boolean isIgnoring(Kind kind) { + return false; + } + + @Override + public void dontIgnore(Kind kind) { + } + + @Override + public void ignore(Kind kind) { + } + + } + + // --- + + private JImageEntry getJImageEntry() { + return (JImageEntry) cpm.getEntries().get(0); + } + + public List getAllTheClasses() { + final List result = new ArrayList<>(); + URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$ + FileSystem fs = FileSystems.getFileSystem(JRT_URI); + Iterable roots = fs.getRootDirectories(); + try { + for (java.nio.file.Path path : roots) { + Files.walkFileTree(path, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + if (file.getNameCount()>3 && file.toString().endsWith(".class")) { + String withClassSuffix = file.subpath(2, file.getNameCount()).toString(); + result.add(withClassSuffix.substring(0,withClassSuffix.length()-".class".length())); + } + return FileVisitResult.CONTINUE; + } + }); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + return result; + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/MegaZipTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/MegaZipTestCase.java new file mode 100644 index 000000000..ba71761b4 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/MegaZipTestCase.java @@ -0,0 +1,107 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.weaver.AdviceKind; +import org.aspectj.weaver.WeaverTestCase; +import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; +import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.UnresolvedType; + +public class MegaZipTestCase extends WeaveTestCase { + + private File outDir; + + public MegaZipTestCase(String arg0) { + super(arg0); + } + + public void setUp() throws Exception { + super.setUp(); + outDir = WeaverTestCase.getOutdir(); + } + + public void tearDown() throws Exception { + super.tearDown(); + WeaverTestCase.removeOutDir(); + outDir = null; + } + + private BcelAdvice makeAroundMunger(final boolean matchOnlyPrintln) { + // BcelWorld world = new BcelWorld(); + final Member sig = MemberImpl.method(UnresolvedType.forName("fluffy.Aspect"), Modifier.STATIC, "aroundFun", + "(Lorg/aspectj/runtime/internal/AroundClosure;)Ljava/lang/Object;"); + + return new BcelAdvice(AdviceKind.stringToKind("around"), matchOnlyPrintln ? makePointcutPrintln() : makePointcutAll(), sig, + 0, -1, -1, null, null) { + public void specializeOn(Shadow s) { + super.specializeOn(s); + ((BcelShadow) s).initializeForAroundClosure(); + } + }; + } + + public List getShadowMungers() { + List ret = new ArrayList(); + ret.add(makeConcreteAdvice("before" + "(): call(* *.println(..)) -> static void fluffy.Aspect.before_method_call()")); + ret.add(makeConcreteAdvice("afterReturning" + + "(): call(* *.println(..)) -> static void fluffy.Aspect.afterReturning_method_call()")); + + ret.add(makeConcreteAdvice("before" + "(): execution(* *.*(..)) -> static void fluffy.Aspect.ignoreMe()")); + + ret.add(makeConcreteAdvice("afterReturning" + "(): execution(* *.*(..)) -> static void fluffy.Aspect.ignoreMe()")); + + ret.add(makeConcreteAdvice("afterThrowing" + + "(): execution(* *.*(..)) -> static void fluffy.Aspect.afterThrowing_method_execution(java.lang.Throwable)", 1)); + ret.add(makeConcreteAdvice("after" + "(): execution(* *.*(..)) -> static void fluffy.Aspect.ignoreMe()")); + + ret.add(makeAroundMunger(true)); + return ret; + } + + public void zipTest(String fileName) throws IOException { + long startTime = System.currentTimeMillis(); + File inFile = new File(WeaverTestCase.TESTDATA_PATH, fileName); + File outFile = new File(outDir, fileName); + outFile.delete(); + + world = new BcelWorld("c:/apps/java-1.3.1_04/lib/tools.jar"); + BcelWeaver weaver1 = new BcelWeaver(world); + + ZipFileWeaver weaver = new ZipFileWeaver(inFile); + + weaver1.setShadowMungers(getShadowMungers()); + + weaver.weave(weaver1, outFile); + assertTrue(outFile.lastModified() > startTime); + } + + public void testEmptyForAntJUnit() { + } + + // this is something we test every now and again. + // to try, rename as testBig and put aspectjtools.jar in testdata + public void trytestBig() throws IOException { + System.out.println("could take 80 seconds..."); + zipTest("aspectjtools.jar"); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java new file mode 100644 index 000000000..bd7c2ae65 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java @@ -0,0 +1,81 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.util.ArrayList; + +import org.aspectj.apache.bcel.generic.InstructionFactory; +import org.aspectj.weaver.NameMangler; +import org.aspectj.weaver.Shadow; + +public class MoveInstructionsWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public MoveInstructionsWeaveTestCase(String name) { + super(name); + } + + public void testHello() throws IOException { + BcelAdvice p = new BcelAdvice(null, makePointcutAll(), null, 0, -1, -1, null, null) { + public void specializeOn(Shadow s) { + super.specializeOn(s); + ((BcelShadow) s).initializeForAroundClosure(); + } + + public boolean implementOn(Shadow s) { + BcelShadow shadow = (BcelShadow) s; + LazyMethodGen newMethod = shadow.extractShadowInstructionsIntoNewMethod(NameMangler.getExtractableName(shadow + .getSignature()) + + "_extracted", 0, this.getSourceLocation(), new ArrayList(),shadow.getEnclosingClass().isInterface()); + shadow.getRange().append(shadow.makeCallToCallback(newMethod)); + + if (!shadow.isFallsThrough()) { + shadow.getRange().append(InstructionFactory.createReturn(newMethod.getReturnType())); + } + return true; + } + }; + + weaveTest("HelloWorld", "ExtractedHelloWorld", p); + } + + static int counter = 0; + + public void testFancyHello() throws IOException { + BcelAdvice p = new BcelAdvice(null, makePointcutAll(), null, 0, -1, -1, null, null) { + public void specializeOn(Shadow s) { + super.specializeOn(s); + ((BcelShadow) s).initializeForAroundClosure(); + } + + public boolean implementOn(Shadow s) { + BcelShadow shadow = (BcelShadow) s; + LazyMethodGen newMethod = + shadow.extractShadowInstructionsIntoNewMethod(NameMangler.getExtractableName(shadow + .getSignature()) + + "_extracted" + counter++, 0, this.getSourceLocation(), new ArrayList(),shadow.getEnclosingClass().isInterface()); + shadow.getRange().append(shadow.makeCallToCallback(newMethod)); + + if (!shadow.isFallsThrough()) { + shadow.getRange().append(InstructionFactory.createReturn(newMethod.getReturnType())); + } + return true; + } + }; + + weaveTest("FancyHelloWorld", "ExtractedFancyHelloWorld", p); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java new file mode 100644 index 000000000..1f67a6249 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java @@ -0,0 +1,83 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +import org.aspectj.weaver.*; +import org.aspectj.weaver.patterns.*; + +public class NonstaticWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public NonstaticWeaveTestCase(String name) { + super(name); + } + + + public void testBefore() throws IOException { + String s = "before(): get(* *.*) -> void Aspect.ajc_before()"; + PerClause per = new PerSingleton(); + per = per.concretize(world.resolve("Aspect")); + + ShadowMunger myMunger = this.makeConcreteAdvice(s, 0, per); + + weaveTest(getStandardTargets(), "NonStaticBefore", myMunger); + } + + public void testBeforeCflow() throws IOException { + String s = "before(): get(* *.*) -> void Aspect.ajc_before()"; + PerClause per = new PatternParser("percflow(execution(void main(..)))").maybeParsePerClause(); + per.resolve(new TestScope(new String[0], new String[0], world)); + + ResolvedType onAspect = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(onAspect,true); + onAspect.crosscuttingMembers = xcut; + + per = per.concretize(onAspect); + + ShadowMunger myMunger = this.makeConcreteAdvice(s, 0, per); + + xcut.addConcreteShadowMunger(myMunger); + + + weaveTest(getStandardTargets(), "CflowNonStaticBefore", xcut.getShadowMungers()); + } + + public void testBeforePerThis() throws IOException { + String s = "before(): call(* println(..)) -> void Aspect.ajc_before()"; + PerClause per = new PatternParser("pertarget(call(* println(..)))").maybeParsePerClause(); + per.resolve(new TestScope(new String[0], new String[0], world)); + + ResolvedType onAspect = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(onAspect,true); + onAspect.crosscuttingMembers = xcut; + per = per.concretize(onAspect); + + ShadowMunger myMunger = this.makeConcreteAdvice(s, 0, per); + xcut.addConcreteShadowMunger(myMunger); + +// List mungers = new ArrayList(); +// mungers.add(myMunger); +// mungers.addAll(onAspect.getExtraConcreteShadowMungers()); + + + weaveTest(getStandardTargets(), "PerThisNonStaticBefore", xcut.getShadowMungers()); + } + + + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/PatternWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/PatternWeaveTestCase.java new file mode 100644 index 000000000..2d9af5395 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/PatternWeaveTestCase.java @@ -0,0 +1,122 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.weaver.CompressingDataOutputStream; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.Shadow; +import org.aspectj.weaver.VersionedDataInputStream; +import org.aspectj.weaver.patterns.ConstantPoolSimulator; +import org.aspectj.weaver.patterns.FormalBinding; +import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.SimpleScope; + +public class PatternWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public PatternWeaveTestCase(String name) { + super(name); + } + + String[] none = new String[0]; + + // XXX this test is incompatible with optimizations made to weaver + + public void testPublic() throws IOException { + String[] publicHello = new String[] { "method-execution(void HelloWorld.main(java.lang.String[]))", }; + String[] publicFancyHello = new String[] { "method-execution(void FancyHelloWorld.main(java.lang.String[]))", + "method-execution(java.lang.String FancyHelloWorld.getName())", }; + checkPointcut("execution(public * *(..))", publicHello, publicFancyHello); + } + + // + // public void testPrintln() throws IOException { + // String[] callPrintlnHello = new String[] { + // "method-call(void java.io.PrintStream.println(java.lang.String))", + // }; + // String[] callPrintlnFancyHello = new String[] { + // "method-call(void java.io.PrintStream.println(java.lang.String))", + // "method-call(void java.io.PrintStream.println(java.lang.String))", + // "method-call(void java.io.PrintStream.println(java.lang.Object))", + // }; + // checkPointcut("call(* println(*))", callPrintlnHello, callPrintlnFancyHello); + // } + // + // public void testMumble() throws IOException { + // checkPointcut("call(* mumble(*))", none, none); + // } + // + // public void testFooBar() throws IOException { + // checkPointcut("call(FooBar *(..))", none, none); + // } + // + // public void testGetOut() throws IOException { + // String[] getOutHello = new String[] { + // "field-get(java.io.PrintStream java.lang.System.out)", + // }; + // + // checkPointcut("get(* java.lang.System.out)", getOutHello, getOutHello); + // } + // + // // private Pointcut makePointcut(String s) { + // // return new PatternParser(s).parsePointcut(); + // // } + // + private void checkPointcut(String pointcutSource, String[] expectedHelloShadows, String[] expectedFancyShadows) + throws IOException { + Pointcut sp = Pointcut.fromString(pointcutSource); + Pointcut rp = sp.resolve(new SimpleScope(world, FormalBinding.NONE)); + Pointcut cp = rp.concretize(ResolvedType.MISSING, ResolvedType.MISSING, 0); + + final List l = new ArrayList(); + BcelAdvice p = new BcelAdvice(null, cp, null, 0, -1, -1, null, null) { + public boolean implementOn(Shadow shadow) { + l.add(shadow); + return true; + } + }; + weaveTest(new String[] { "HelloWorld" }, "PatternWeave", p); + + checkShadowSet(l, expectedHelloShadows); + + l.clear(); + weaveTest(new String[] { "FancyHelloWorld" }, "PatternWeave", p); + + checkShadowSet(l, expectedFancyShadows); + + checkSerialize(rp); + } + + public void checkSerialize(Pointcut p) throws IOException { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + ConstantPoolSimulator cps = new ConstantPoolSimulator(); + CompressingDataOutputStream out = new CompressingDataOutputStream(bo, cps); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + VersionedDataInputStream in = new VersionedDataInputStream(bi, cps); + Pointcut newP = Pointcut.read(in, null); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/PointcutResidueTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/PointcutResidueTestCase.java new file mode 100644 index 000000000..7f6f5f163 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/PointcutResidueTestCase.java @@ -0,0 +1,189 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; + +import org.aspectj.weaver.AdviceKind; +import org.aspectj.weaver.CompressingDataOutputStream; +import org.aspectj.weaver.CrosscuttingMembers; +import org.aspectj.weaver.MemberImpl; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.VersionedDataInputStream; +import org.aspectj.weaver.patterns.ConstantPoolSimulator; +import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.SimpleScope; + +public class PointcutResidueTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public PointcutResidueTestCase(String name) { + super(name); + } + + String[] none = new String[0]; + + // ----- + + // ---- + + public void testArgResidue1() throws IOException { + checkMultiArgWeave("StringResidue1", + "call(* *(java.lang.Object, java.lang.Object)) && args(java.lang.String, java.lang.String)"); + } + + public void testArgResidue2() throws IOException { + checkMultiArgWeave("StringResidue2", "call(* *(java.lang.Object, java.lang.Object)) && args(.., java.lang.String)"); + } + + public void testArgResidue3() throws IOException { + checkMultiArgWeave("StringResidue3", "call(* *(java.lang.Object, java.lang.Object)) && args(java.lang.String, ..)"); + } + + // BETAX this is a beta feature. + // public void testArgResidue4() throws IOException { + // checkMultiArgWeave( + // "StringResidue4", + // "call(* *(java.lang.Object, java.lang.Object)) && args(.., java.lang.String, ..)"); + // } + + public void testMultiArgState() throws IOException { + checkWeave("StateResidue", "MultiArgHelloWorld", "call(* *(java.lang.Object, java.lang.Object)) && args(s, ..)", + new String[] { "java.lang.String" }, new String[] { "s" }); + checkWeave("StateResidue", "MultiArgHelloWorld", "call(* *(java.lang.Object, java.lang.Object)) && args(s, *)", + new String[] { "java.lang.String" }, new String[] { "s" }); + } + + public void testAdd() throws IOException { + checkDynamicWeave("AddResidue", "call(public * add(..)) && target(java.util.ArrayList)"); + checkDynamicWeave("AddResidue", "call(public * add(..)) && (target(java.util.ArrayList) || target(java.lang.String))"); + checkDynamicWeave("AddResidue", + "call(public * add(..)) && this(java.io.Serializable) && target(java.util.ArrayList) && !this(java.lang.Integer)"); + } + + public void testNot() throws IOException { + checkDynamicWeave("AddNotResidue", "call(public * add(..)) && !target(java.util.ArrayList)"); + checkDynamicWeave("AddNotResidue", "call(public * add(..)) && !(target(java.util.ArrayList) || target(java.lang.String)) "); + checkDynamicWeave("AddNotResidue", "call(public * add(..)) && target(java.lang.Object) && !target(java.util.ArrayList)"); + } + + public void testState() throws IOException { + checkWeave("AddStateResidue", "DynamicHelloWorld", "call(public * add(..)) && target(list)", + new String[] { "java.util.ArrayList" }, new String[] { "list" }); + checkWeave("AddStateResidue", "DynamicHelloWorld", "target(foo) && !target(java.lang.Integer) && call(public * add(..))", + new String[] { "java.util.ArrayList" }, new String[] { "foo" }); + checkDynamicWeave("AddResidue", "call(public * add(..)) && (target(java.util.ArrayList) || target(java.lang.String))"); + checkDynamicWeave("AddResidue", + "call(public * add(..)) && this(java.io.Serializable) && target(java.util.ArrayList) && !this(java.lang.Integer)"); + } + + public void testNoResidueArgs() throws IOException { + checkDynamicWeave("NoResidue", "call(public * add(..)) && args(java.lang.Object)"); + checkDynamicWeave("NoResidue", "call(public * add(..)) && args(*)"); + checkDynamicWeave("NoResidue", "call(public * add(..))"); + } + + // ---- cflow tests + + public void testCflowState() throws IOException { + checkWeave("CflowStateResidue", "DynamicHelloWorld", + "cflow(call(public * add(..)) && target(list)) && execution(public void main(..))", + new String[] { "java.util.ArrayList" }, new String[] { "list" }); + // checkWeave( + // "CflowStateResidue", + // "DynamicHelloWorld", + // "cflow(call(public * add(..)) && target(list)) && this(obj) && execution(public void doit(..))", + // new String[] { "java.lang.Object", "java.util.ArrayList" }, + // new String[] { "obj", "list" }); + // checkWeave( + // "AddStateResidue", + // "DynamicHelloWorld", + // "target(foo) && !target(java.lang.Integer) && call(public * add(..))", + // new String[] { "java.util.ArrayList" }, + // new String[] { "foo" }); + // checkDynamicWeave( + // "AddResidue", + // "call(public * add(..)) && (target(java.util.ArrayList) || target(java.lang.String))"); + // checkDynamicWeave( + // "AddResidue", + // "call(public * add(..)) && this(java.io.Serializable) && target(java.util.ArrayList) && !this(java.lang.Integer)"); + } + + // ---- + + private void checkDynamicWeave(String label, String pointcutSource) throws IOException { + checkWeave(label, "DynamicHelloWorld", pointcutSource, new String[0], new String[0]); + } + + private void checkMultiArgWeave(String label, String pointcutSource) throws IOException { + checkWeave(label, "MultiArgHelloWorld", pointcutSource, new String[0], new String[0]); + } + + private void checkWeave(String label, String filename, String pointcutSource, String[] formalTypes, String[] formalNames) + throws IOException { + final Pointcut sp = Pointcut.fromString(pointcutSource); + final Pointcut rp = sp.resolve(new SimpleScope(world, SimpleScope.makeFormalBindings(UnresolvedType.forNames(formalTypes), + formalNames))); + + ShadowMunger pp = new BcelAdvice(AdviceKind.Before, rp, MemberImpl.method(UnresolvedType.forName("Aspect"), + Modifier.STATIC, "ajc_before_0", + MemberImpl.typesToSignature(UnresolvedType.VOID, UnresolvedType.forNames(formalTypes), false)), 0, -1, -1, null, + null); + + ResolvedType inAspect = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(inAspect, true); + inAspect.crosscuttingMembers = xcut; + + ShadowMunger cp = pp.concretize(inAspect, world, null); + + xcut.addConcreteShadowMunger(cp); + + // System.out.println("extras: " + inAspect.getExtraConcreteShadowMungers()); + // List advice = new ArrayList(); + // advice.add(cp); + // advice.addAll(inAspect.getExtraConcreteShadowMungers()); + weaveTest(new String[] { filename }, label, xcut.getShadowMungers()); + + checkSerialize(rp); + } + + public void weaveTest(String name, String outName, ShadowMunger planner) throws IOException { + List l = new ArrayList(1); + l.add(planner); + weaveTest(name, outName, l); + } + + public void checkSerialize(Pointcut p) throws IOException { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + ConstantPoolSimulator cps = new ConstantPoolSimulator(); + CompressingDataOutputStream out = new CompressingDataOutputStream(bo, cps); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + VersionedDataInputStream in = new VersionedDataInputStream(bi, cps); + Pointcut newP = Pointcut.read(in, null); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/TjpWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/TjpWeaveTestCase.java new file mode 100644 index 000000000..b24b3f6d0 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/TjpWeaveTestCase.java @@ -0,0 +1,99 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.util.Arrays; + +import org.aspectj.weaver.Advice; +import org.aspectj.weaver.AdviceKind; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.TestUtils; +import org.aspectj.weaver.UnresolvedType; + +public class TjpWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public TjpWeaveTestCase(String name) { + super(name); + } + + public void setUp() throws Exception { + super.setUp(); + behave15 = true; + } + + public void tearDown() throws Exception { + super.tearDown(); + behave15 = false; + } + + public void testStaticTjp() throws IOException { + BcelAdvice munger = new BcelAdvice(AdviceKind.stringToKind("before"), makePointcutAll(), + TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"), + Advice.ThisJoinPointStaticPart, -1, -1, null, null); + + weaveTest("HelloWorld", "StaticTjpBeforeHelloWorld", munger); + } + + public void testEnclosingStaticTjp() throws IOException { + BcelAdvice munger = new BcelAdvice(AdviceKind.stringToKind("before"), makePointcutAll(), + TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint$StaticPart)"), + Advice.ThisEnclosingJoinPointStaticPart, -1, -1, null, null); + + weaveTest("HelloWorld", "StaticEnclosingTjpBeforeHelloWorld", munger); + } + + public void testTjp() throws IOException { + BcelAdvice munger = new BcelAdvice(AdviceKind.stringToKind("before"), makePointcutAll(), + TestUtils.methodFromString("static void Aspect.ajc_before(org.aspectj.lang.JoinPoint)"), Advice.ThisJoinPoint, -1, + -1, null, null); + + weaveTest("HelloWorld", "TjpBeforeHelloWorld", munger); + } + + public void testAroundTjp() throws IOException { + BcelAdvice munger = new BcelAdvice( + AdviceKind.stringToKind("around"), + makePointcutAll(), + TestUtils + .methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, null); + + weaveTest("HelloWorld", "TjpAroundHelloWorld", munger); + } + + public void testAround2Tjp() throws IOException { + ResolvedType rtx = world.resolve(UnresolvedType.forName("Aspect"), true); + assertTrue("Couldnt find type Aspect", !rtx.isMissing()); + BcelAdvice munger1 = new BcelAdvice( + AdviceKind.stringToKind("around"), + makePointcutAll(), + TestUtils + .methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, rtx); + + BcelAdvice munger2 = new BcelAdvice( + AdviceKind.stringToKind("around"), + makePointcutAll(), + TestUtils + .methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, rtx); + + weaveTest("HelloWorld", "TjpAround2HelloWorld", Arrays.asList(new ShadowMunger[] { munger1, munger2 })); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/TraceJarWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/TraceJarWeaveTestCase.java new file mode 100644 index 000000000..45535407b --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/TraceJarWeaveTestCase.java @@ -0,0 +1,40 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +public class TraceJarWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public TraceJarWeaveTestCase(String name) { + super(name); + } + + + public void testTraceJar() throws IOException { + world = new BcelWorld(getTraceJar()); + BcelWeaver weaver = new BcelWeaver(world); + weaver.addLibraryAspect("MyTrace"); + UnwovenClassFile classFile + = makeUnwovenClassFile(classDir, "DynamicHelloWorld", outDirPath); + + weaver.addClassFile(classFile,false); + weaver.prepareForWeave(); + + weaveTestInner(weaver, classFile, "DynamicHelloWorld", "TraceJarHello"); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/UtilityTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/UtilityTestCase.java new file mode 100644 index 000000000..8083c1532 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/UtilityTestCase.java @@ -0,0 +1,52 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; +import java.io.*; + +import junit.framework.TestCase; + +public class UtilityTestCase extends TestCase { + + public UtilityTestCase(String name) { + super(name); + } + + public void disassembleTest(String name) throws IOException { + BcelWorld world = new BcelWorld("../weaver/bin"); +// world.setFastDelegateSupport(false); + world.addPath(WeaveTestCase.classDir); + + LazyClassGen clazz = new LazyClassGen(BcelWorld.getBcelObjectType(world.resolve(name))); + clazz.print(); + System.out.println(); + } + + + public void testHelloWorld() throws IOException { + disassembleTest("Test"); + } + public void testFancyHelloWorld() throws IOException { + disassembleTest("FancyHelloWorld"); + } +// public void testSwitchy() throws IOException { +// disassembleTest("TestSwitchy"); +// } + + public static void main(String[] args) throws IOException { + BcelWorld world = new BcelWorld(); + LazyClassGen clazz = new LazyClassGen(BcelWorld.getBcelObjectType(world.resolve(args[0]))); + clazz.print(); + } +} + diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/WeaveOrderTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/WeaveOrderTestCase.java new file mode 100644 index 000000000..f22805f11 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/WeaveOrderTestCase.java @@ -0,0 +1,149 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import org.aspectj.weaver.patterns.*; +import org.aspectj.weaver.*; + +/**. + */ +public class WeaveOrderTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public WeaveOrderTestCase(String name) { + super(name); + } + + + public void testLexicalOrder() { + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.THROWABLE, 2); + + assertEquals(-1, a2.compareTo(a1)); + assertEquals(+1, a1.compareTo(a2)); + } + + public void testLexicalOrderWithAfter() { + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.After, UnresolvedType.OBJECT, UnresolvedType.THROWABLE, 2); + + assertEquals(+1, a2.compareTo(a1)); + assertEquals(-1, a1.compareTo(a2)); + + a1 = + makeConcreteAdvice(AdviceKind.After, UnresolvedType.OBJECT, UnresolvedType.OBJECT, 1); + a2 = + makeConcreteAdvice(AdviceKind.After, UnresolvedType.OBJECT, UnresolvedType.THROWABLE, 2); + + assertEquals(+1, a2.compareTo(a1)); + assertEquals(-1, a1.compareTo(a2)); + } + + public void testSubtypes() { + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.THROWABLE, UnresolvedType.OBJECT, 1); + Advice a3 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.forName("java.lang.String"), UnresolvedType.OBJECT, 1); + + assertEquals(+1, a2.compareTo(a1)); + assertEquals(-1, a1.compareTo(a2)); + + assertEquals(+1, a3.compareTo(a1)); + assertEquals(-1, a1.compareTo(a3)); + + assertEquals(0, a3.compareTo(a2)); + assertEquals(0, a2.compareTo(a3)); + } + + + public void testDominates() { + Declare dom = + new PatternParser("declare precedence: java.lang.String, java.lang.Throwable").parseDeclare(); + //??? concretize dom + ResolvedType aType = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(aType,true); + aType.crosscuttingMembers = xcut; + xcut.addDeclare(dom); + world.getCrosscuttingMembersSet().addFixedCrosscuttingMembers(aType); + + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.THROWABLE, 2); + Advice a3 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.forName("java.lang.String"), 2); + + assertEquals(-1, a2.compareTo(a1)); + assertEquals(+1, a1.compareTo(a2)); + + assertEquals(-1, a3.compareTo(a1)); + assertEquals(+1, a1.compareTo(a3)); + + + assertEquals(+1, a3.compareTo(a2)); + assertEquals(-1, a2.compareTo(a3)); + } + + public void testDominatesHarder() { + Declare dom = + new PatternParser("declare precedence: *, java.lang.String, java.lang.Throwable").parseDeclare(); + //??? concretize dom + ResolvedType aType = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(aType,true); + aType.crosscuttingMembers = xcut; + xcut.addDeclare(dom); + world.getCrosscuttingMembersSet().addFixedCrosscuttingMembers(aType); + + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.OBJECT, 2); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.THROWABLE, 1); + Advice a3 = + makeConcreteAdvice(AdviceKind.Before, UnresolvedType.OBJECT, UnresolvedType.forName("java.lang.String"), 1); + + assertEquals(-1, a2.compareTo(a1)); + assertEquals(+1, a1.compareTo(a2)); + + assertEquals(-1, a3.compareTo(a1)); + assertEquals(+1, a1.compareTo(a3)); + + + assertEquals(+1, a3.compareTo(a2)); + assertEquals(-1, a2.compareTo(a3)); + } + + + + + private Advice makeConcreteAdvice(AdviceKind kind, UnresolvedType declaringAspect, + UnresolvedType concreteAspect, int lexicalPosition) + { + Advice a1 = new BcelAdvice(kind, makeResolvedPointcut("this(*)"), + MemberImpl.method(declaringAspect, 0, "foo", "()V"), + 0, lexicalPosition, lexicalPosition, null, null); + a1 = (Advice)a1.concretize(concreteAspect.resolve(world), world, null); + return a1; + } + + + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/WeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/WeaveTestCase.java new file mode 100644 index 000000000..088a9a9d0 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/WeaveTestCase.java @@ -0,0 +1,318 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.aspectj.apache.bcel.Constants; +import org.aspectj.apache.bcel.generic.InstructionFactory; +import org.aspectj.apache.bcel.generic.InstructionList; +import org.aspectj.apache.bcel.generic.InvokeInstruction; +import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.testing.util.TestUtil; +import org.aspectj.util.FileUtil; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.Advice; +import org.aspectj.weaver.WeaverTestCase; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.patterns.FormalBinding; +import org.aspectj.weaver.patterns.PerClause; +import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.SimpleScope; + +import junit.framework.TestCase; + +public abstract class WeaveTestCase extends TestCase { + + public boolean regenerate = false; + public boolean runTests = true; + public boolean behave15 = false; + + File outDir; + String outDirPath; + + public BcelWorld world = new BcelWorld(); + { + world.addPath(classDir); + // Some of the tests in here rely on comparing output from dumping the delegates - if + // we are using ASM delegates we don't know the names of parameters (they are irrelevant...) + // and are missing from the dumping of asm delegates. This switch ensures we + // continue to use BCEL for these tests. + // world.setFastDelegateSupport(false); + } + + public WeaveTestCase(String name) { + super(name); + } + + @Override + public void setUp() throws Exception { + outDir = WeaverTestCase.getOutdir(); + outDirPath = outDir.getAbsolutePath(); + } + + @Override + public void tearDown() throws Exception { + super.tearDown(); + WeaverTestCase.removeOutDir(); + outDir = null; + outDirPath = null; + } + + public static InstructionList getAdviceTag(BcelShadow shadow, String where) { + String methodName = "ajc_" + where + "_" + shadow.getKind().toLegalJavaIdentifier(); + + InstructionFactory fact = shadow.getFactory(); + InvokeInstruction il = fact.createInvoke("Aspect", methodName, Type.VOID, new Type[] {}, Constants.INVOKESTATIC); + return new InstructionList(il); + } + + public void weaveTest(String name, String outName, ShadowMunger planner) throws IOException { + List l = new ArrayList(1); + l.add(planner); + weaveTest(name, outName, l); + } + + // static String classDir = "../weaver/bin"; + static String classDir = WeaverTestCase.TESTDATA_PATH + File.separator + "bin"; + + public void weaveTest(String name, String outName, List planners) throws IOException { + BcelWeaver weaver = new BcelWeaver(world); + try { + if (behave15) + world.setBehaveInJava5Way(true); + + UnwovenClassFile classFile = makeUnwovenClassFile(classDir, name, outDirPath); + + weaver.addClassFile(classFile, false); + weaver.setShadowMungers(planners); + weaveTestInner(weaver, classFile, name, outName); + } finally { + if (behave15) + world.setBehaveInJava5Way(false); + } + } + + protected void weaveTestInner(BcelWeaver weaver, UnwovenClassFile classFile, String name, String outName) throws IOException { + // int preErrors = currentResult.errorCount(); + BcelObjectType classType = BcelWorld.getBcelObjectType(world.resolve(classFile.getClassName())); + LazyClassGen gen = weaver.weave(classFile, classType); + if (gen == null) { + // we didn't do any weaving, but let's make a gen anyway + gen = classType.getLazyClassGen(); // new LazyClassGen(classType); + } + try { + String filenameToUse = findMostRelevantFile(outName); + checkClass(gen, outDirPath, filenameToUse); + if (runTests) { + System.out.println("*******RUNNING: " + outName + " " + name + " *******"); + TestUtil.runMain(makeClassPath(outDirPath), name); + } + } catch (Error e) { + System.err.println("Comparing to " + outName + ".txt"); + gen.print(System.err); + throw e; + } catch (RuntimeException e) { + gen.print(System.err); + throw e; + } + } + + public String findMostRelevantFile(String name) { + double version = LangUtil.getVmVersion(); + while (version > 0) { + String possibleFileName = name+"."+Double.toString(version)+".txt"; + if (new File(TESTDATA_DIR, possibleFileName).exists()) { + return possibleFileName; + } + version--; + } + // Use the standard file + return name+".txt"; + } + + public String makeClassPath(String outDir) { + return outDir + File.pathSeparator + getTraceJar() + File.pathSeparator + classDir + File.pathSeparator + + System.getProperty("java.class.path"); + } + + /** + * '/' in the name indicates the location of the class + */ + public static UnwovenClassFile makeUnwovenClassFile(String classDir, String name, String outDir) throws IOException { + File outFile = new File(outDir, name + ".class"); + if (classDir.endsWith(".jar")) { + String fname = name + ".class"; + UnwovenClassFile ret = new UnwovenClassFile(outFile.getAbsolutePath(), FileUtil.readAsByteArray(FileUtil + .getStreamFromZip(classDir, fname))); + return ret; + } else { + File inFile = new File(classDir, name + ".class"); + return new UnwovenClassFile(outFile.getAbsolutePath(), FileUtil.readAsByteArray(inFile)); + } + } + + public void checkClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException { + if (regenerate) + genClass(gen, outDir, expectedFile); + else + realCheckClass(gen, outDir, expectedFile); + } + + static final File TESTDATA_DIR = new File(WeaverTestCase.TESTDATA_PATH); + + void genClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException { + // ClassGen b = getJavaClass(outDir, className); + FileOutputStream out = new FileOutputStream(new File(TESTDATA_DIR, expectedFile)); + PrintStream ps = new PrintStream(out); + gen.print(ps); + ps.flush(); + + } + + void realCheckClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException { + TestUtil.assertMultiLineStringEquals(expectedFile/* "classes" */, + FileUtil.readAsString(new File(TESTDATA_DIR, expectedFile)), gen.toLongString()); + } + + // ---- + public ShadowMunger makeConcreteAdvice(String mungerString) { + return makeConcreteAdvice(mungerString, 0, null); + } + + public ShadowMunger makeConcreteAdvice(String mungerString, int extraArgFlag) { + return makeConcreteAdvice(mungerString, extraArgFlag, null); + } + + protected ShadowMunger makeConcreteAdvice(String mungerString, int extraArgFlag, PerClause perClause) { + Advice myMunger = BcelTestUtils.shadowMunger(world, mungerString, extraArgFlag); + + // PerSingleton s = new PerSingleton(); + // s.concretize(world.resolve("Aspect")); + // System.err.println(((KindedPointcut)myMunger.getPointcut().getPointcut()).getKind()); + Advice cm = (Advice) myMunger.concretize(myMunger.getDeclaringAspect().resolve(world), world, perClause); + return cm; + } + + public ShadowMunger makeAdviceField(String kind, String extraArgType) { + return makeConcreteAdvice(kind + "(): get(* *.*) -> static void Aspect.ajc_" + kind + "_field_get(" + extraArgType + ")", 1); + } + + public List makeAdviceAll(String kind, boolean matchOnlyPrintln) { + List ret = new ArrayList(); + if (matchOnlyPrintln) { + ret.add(makeConcreteAdvice(kind + "(): call(* *.println(..)) -> static void Aspect.ajc_" + kind + "_method_execution()")); + } else { + ret.add(makeConcreteAdvice(kind + "(): call(* *.*(..)) -> static void Aspect.ajc_" + kind + "_method_call()")); + ret.add(makeConcreteAdvice(kind + "(): call(*.new(..)) -> static void Aspect.ajc_" + kind + "_constructor_call()")); + ret.add(makeConcreteAdvice(kind + "(): execution(* *.*(..)) -> static void Aspect.ajc_" + kind + "_method_execution()")); + ret.add(makeConcreteAdvice(kind + "(): execution(*.new(..)) -> static void Aspect.ajc_" + kind + + "_constructor_execution()")); + // ret.add( + // makeConcreteMunger( + // kind + // + "(): staticinitialization(*) -> static void Aspect.ajc_" + // + kind + // + "_staticinitialization()")); + ret.add(makeConcreteAdvice(kind + "(): get(* *.*) -> static void Aspect.ajc_" + kind + "_field_get()")); + // ret.add( + // makeConcreteMunger( + // kind + "(): set(* *.*) -> static void Aspect.ajc_" + kind + "_field_set()")); + // XXX no test for advice execution, staticInitialization or (god help us) preInitialization + } + return ret; + } + + public List makeAdviceAll(final String kind) { + return makeAdviceAll(kind, false); + } + + public Pointcut makePointcutAll() { + return makeConcretePointcut("get(* *.*) || call(* *.*(..)) || execution(* *.*(..)) || call(*.new(..)) || execution(*.new(..))"); + } + + public Pointcut makePointcutNoZeroArg() { + return makeConcretePointcut("call(* *.*(*, ..)) || execution(* *.*(*, ..)) || call(*.new(*, ..)) || execution(*.new(*, ..))"); + } + + public Pointcut makePointcutPrintln() { + return makeConcretePointcut("call(* *.println(..))"); + } + + public Pointcut makeConcretePointcut(String s) { + return makeResolvedPointcut(s).concretize(null, null, 0); + } + + public Pointcut makeResolvedPointcut(String s) { + Pointcut pointcut0 = Pointcut.fromString(s); + return pointcut0.resolve(new SimpleScope(world, FormalBinding.NONE)); + } + + // ---- + + public String[] getStandardTargets() { + return new String[] { "HelloWorld", "FancyHelloWorld" }; + } + + public String getTraceJar() { + return WeaverTestCase.TESTDATA_PATH + "/tracing.jar"; + } + + // ---- + + protected void weaveTest(String[] inClassNames, String outKind, ShadowMunger patternMunger) throws IOException { + for (int i = 0; i < inClassNames.length; i++) { + String inFileName = inClassNames[i]; + weaveTest(inFileName, outKind + inFileName, patternMunger); + } + } + + protected void weaveTest(String[] inClassNames, String outKind, List patternMungers) throws IOException { + for (int i = 0; i < inClassNames.length; i++) { + String inFileName = inClassNames[i]; + weaveTest(inFileName, outKind + inFileName, patternMungers); + } + } + + protected List addLexicalOrder(List l) { + int i = 10; + for (ShadowMunger element: l) { + ((Advice)element).setLexicalPosition(i += 10); + } + return l; + } + + // XXX cut-and-paster from IdWeaveTestCase + public void checkShadowSet(List l, String[] ss) { + outer: for (int i = 0, len = ss.length; i < len; i++) { + // inner: + for (Iterator j = l.iterator(); j.hasNext();) { + BcelShadow shadow = (BcelShadow) j.next(); + String shadowString = shadow.toString(); + if (shadowString.equals(ss[i])) { + j.remove(); + continue outer; + } + } + assertTrue("didn't find " + ss[i] + " in " + l, false); + } + assertTrue("too many things in " + l, l.size() == 0); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/WorldTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/WorldTestCase.java new file mode 100644 index 000000000..65d079543 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/WorldTestCase.java @@ -0,0 +1,163 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.lang.reflect.Modifier; + +import org.aspectj.weaver.Advice; +import org.aspectj.weaver.WeaverTestCase; +import org.aspectj.weaver.CommonWorldTests; +import org.aspectj.weaver.Member; +import org.aspectj.weaver.MemberImpl; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.ShadowMunger; +import org.aspectj.weaver.TestUtils; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.World; + +/** + * This is a test case for the nameType parts of worlds. + */ +public class WorldTestCase extends CommonWorldTests { + + private final BcelWorld world = new BcelWorld(WeaverTestCase.TESTDATA_PATH + "/tracing.jar"); + + protected World getWorld() { + return world; + } + + protected boolean getSupportsAutoboxing() { + return true; + } + + // XXX fix the various XXXs before expecting this test to work + public void xtestTraceJar() { + ResolvedType trace = world.resolve(UnresolvedType.forName("Trace"), true); + assertTrue("Couldnt find type Trace", !trace.isMissing()); + fieldsTest(trace, Member.NONE); + /* Member constr = */TestUtils.methodFromString("void Trace.()"); + // XXX need attribute fix - + // methodsTest(trace, new Member[] { constr }); + + interfacesTest(trace, ResolvedType.NONE); + superclassTest(trace, UnresolvedType.OBJECT); + isInterfaceTest(trace, false); + isClassTest(trace, false); + isAspectTest(trace, true); + + pointcutsTest(trace, new Member[] { MemberImpl.pointcut(trace, "traced", "(Ljava/lang/Object;)V"), }); + + modifiersTest(trace.findPointcut("traced"), Modifier.PUBLIC | Modifier.ABSTRACT); + + mungersTest( + trace, + new ShadowMunger[] { + BcelTestUtils.shadowMunger(world, "before(foo): traced(foo) -> void Trace.ajc_before_4(java.lang.Object))", + 0), + BcelTestUtils + .shadowMunger( + world, + "afterReturning(foo): traced(foo) -> void Trace.ajc_afterreturning_3(java.lang.Object, java.lang.Object))", + Advice.ExtraArgument), + BcelTestUtils + .shadowMunger( + world, + "around(): execution(* doit(..)) -> java.lang.Object Trace.ajc_around_2(org.aspectj.runtime.internal.AroundClosure))", + Advice.ExtraArgument), + BcelTestUtils + .shadowMunger( + world, + "around(foo): traced(foo) -> java.lang.Object Trace.ajc_around_1(java.lang.Object, org.aspectj.runtime.internal.AroundClosure))", + Advice.ExtraArgument), }); + + ResolvedType myTrace = world.resolve(UnresolvedType.forName("MyTrace"), true); + assertTrue("Couldnt find type MyTrace", !myTrace.isMissing()); + + interfacesTest(myTrace, ResolvedType.NONE); + superclassTest(myTrace, trace); + isInterfaceTest(myTrace, false); + isClassTest(myTrace, false); + isAspectTest(myTrace, true); + + // XXX need attribute fix - + // fieldsTest(myTrace, Member.NONE); + + pointcutsTest(trace, new Member[] { MemberImpl.pointcut(trace, "traced", "(Ljava/lang/Object;)V"), }); + + modifiersTest(myTrace.findPointcut("traced"), Modifier.PUBLIC); + + // this tests for declared mungers + mungersTest(myTrace, ShadowMunger.NONE); + + } + + public void testIterator() { + int abstractPublic = Modifier.ABSTRACT | Modifier.PUBLIC; + ResolvedType iter = world.getCoreType(UnresolvedType.forRawTypeName("java.util.Iterator")); + + modifiersTest(iter, abstractPublic | Modifier.INTERFACE); + fieldsTest(iter, ResolvedMember.NONE); + methodsTest(iter, new Member[] { + MemberImpl.method(iter, 0, "hasNext", "()Z"), + MemberImpl.method(iter, 0, "remove", "()V"), + MemberImpl.method(iter, 0, "next", "()Ljava/lang/Object;"), + MemberImpl.method(iter, 0, "forEachRemaining", "(Ljava/util/function/Consumer;)V") +// default void forEachRemaining(Consumer action) { +// Objects.requireNonNull(action); +// while (hasNext()) +// action.accept(next()); +// } + }); + ResolvedMember remove = iter.lookupMethod(MemberImpl.method(iter, 0, "remove", "()V")); + assertNotNull("iterator doesn't have remove", remove); + modifiersTest(remove, Modifier.PUBLIC); // no longer abstract in Java8 (default instead) + exceptionsTest(remove, UnresolvedType.NONE); + + ResolvedMember clone = iter.lookupMethod(MemberImpl.method(UnresolvedType.OBJECT, 0, "clone", "()Ljava/lang/Object;")); + assertNotNull("iterator doesn't have clone", clone); + // AV: JRockit Object.clone() is not native.. corrupted test here: + // modifiersTest(clone, Modifier.PROTECTED | Modifier.NATIVE); + assertTrue("should be protected" + clone.toString(), Modifier.isProtected(clone.getModifiers())); + exceptionsTest(clone, UnresolvedType.forNames(new String[] { "java.lang.CloneNotSupportedException" })); + + interfacesTest(iter, ResolvedType.NONE); + superclassTest(iter, UnresolvedType.OBJECT); + pointcutsTest(iter, ResolvedMember.NONE); + mungersTest(iter, ShadowMunger.NONE); + isInterfaceTest(iter, true); + isClassTest(iter, false); + isAspectTest(iter, false); + } + + public void testObjectCoersion() { + assertCouldBeCoercibleFrom("java.lang.Object", "java.lang.String"); + assertCouldBeCoercibleFrom("java.lang.Integer", "java.lang.Object"); + assertCouldBeCoercibleFrom("java.io.Serializable", "java.lang.Runnable"); + assertCouldBeCoercibleFrom("java.util.Stack", "java.lang.Runnable"); + assertCouldNotBeCoercibleFrom("java.lang.Runnable", "java.lang.Integer"); + assertCouldNotBeCoercibleFrom("java.lang.Integer", "java.lang.String"); + assertCouldNotBeCoercibleFrom("java.lang.Integer", "java.lang.Runnable"); + } + + // ---- + + private void assertCouldBeCoercibleFrom(String a, String b) { + isCoerceableFromTest(world.resolve(a), world.resolve(b), true); + } + + private void assertCouldNotBeCoercibleFrom(String a, String b) { + isCoerceableFromTest(world.resolve(a), world.resolve(b), false); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/ZipFileWeaver.java b/weaver/src/test/java/org/aspectj/weaver/bcel/ZipFileWeaver.java new file mode 100644 index 000000000..3be5ae332 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/ZipFileWeaver.java @@ -0,0 +1,39 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.File; +import java.io.IOException; + + +//XXX delete very soon +public class ZipFileWeaver { + File inFile; + public ZipFileWeaver(File inFile) { + super(); + this.inFile = inFile; + } + + public void weave(BcelWeaver weaver, File outFile) throws IOException { + int count = 0; + long startTime = System.currentTimeMillis(); + weaver.addJarFile(inFile, new File("."),false); + weaver.weave(outFile); + long stopTime = System.currentTimeMillis(); + + + System.out.println("handled " + count + " entries, in " + + (stopTime-startTime)/1000. + " seconds"); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/ZipTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/ZipTestCase.java new file mode 100644 index 000000000..71f3bc926 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/bcel/ZipTestCase.java @@ -0,0 +1,121 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.bcel; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; + +import junit.framework.TestCase; + +import org.aspectj.weaver.WeaverTestCase; + +public class ZipTestCase extends TestCase { + + File outDir; + + /** + * Constructor for ZipTestCase. + * + * @param arg0 + */ + public ZipTestCase(String arg0) { + super(arg0); + } + + public void setUp() { + outDir = WeaverTestCase.getOutdir(); + } + + public void tearDown() { + WeaverTestCase.removeOutDir(); + outDir = null; + } + + public void zipTest(String fileName, String aspectjar) throws IOException { + zipTest(fileName, aspectjar, false); + } + + public void zipTest(String fileName, String aspectjar, boolean isInJar) throws IOException { + File inFile = new File(fileName); + File outFile = new File(outDir, inFile.getName()); + BcelWorld world = new BcelWorld(); + BcelWeaver weaver = new BcelWeaver(world); + + long startTime = System.currentTimeMillis(); + // ensure that a fast cpu doesn't complete file write within 1000ms of start + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + weaver.addJarFile(inFile, new File("."), false); + + if (aspectjar != null) { + if (isInJar) { + weaver.addJarFile(new File(aspectjar), new File("."), false); + } else { + weaver.addLibraryJarFile(new File(aspectjar)); + world.addPath(new File(aspectjar).toString()); + } + } + weaver.addLibraryJarFile(new File(WeaverTestCase.TESTDATA_PATH + "/Regex.jar")); // ??? + world.addPath(new File(WeaverTestCase.TESTDATA_PATH + "/Regex.jar").getPath()); + + Collection woven = weaver.weave(outFile); + long stopTime = System.currentTimeMillis(); + + System.out.println("handled " + woven.size() + " entries, in " + (stopTime - startTime) / 1000. + " seconds"); + // last mod times on linux (at least) are only accurate to the second. + // with fast disks and a fast cpu the following test can fail if the write completes less than + // 1000 milliseconds after the start of the test, hence the 1000ms delay added above. + assertTrue(outFile.lastModified() > startTime); + } + + public void testSmall() throws IOException { + zipTest(WeaverTestCase.TESTDATA_PATH + "/Regex.jar", null); + } + + public void testSmallWithAspects() throws IOException { + System.out.println("could take 4 seconds..."); + zipTest(WeaverTestCase.TESTDATA_PATH + "/Regex.jar", WeaverTestCase.TESTDATA_PATH + "/megatrace.jar"); + } + + public void testSmallWithAspectsNoWeave() throws IOException { + System.out.println("could take 4 seconds..."); + zipTest(WeaverTestCase.TESTDATA_PATH + "/Regex.jar", WeaverTestCase.TESTDATA_PATH + "/megatraceNoweave.jar", true); + } + + public void testBig() throws IOException { + System.out.println("could take 4 seconds..."); + zipTest("../lib/bcel/bcel.jar", null); + } + + public void testBigWithEasyNoTrace() throws IOException { + System.out.println("could take 4 seconds..."); + zipTest("../lib/bcel/bcel.jar", WeaverTestCase.TESTDATA_PATH + "/megatrace0easy.jar"); + } + + // this is something we test every now and again. + public void xtestBigWithHardNoTrace() throws IOException { + System.out.println("could take 24 seconds..."); + zipTest("../lib/bcel/bcel.jar", WeaverTestCase.TESTDATA_PATH + "/megatrace0hard.jar"); + } + + public void xtestBigWithAspects() throws IOException { + System.out.println("could take 40 seconds..."); + zipTest("../lib/bcel/bcel.jar", WeaverTestCase.TESTDATA_PATH + "/megatrace.jar"); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java new file mode 100644 index 000000000..753e7a6b0 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java @@ -0,0 +1,252 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement initial implementation + * ******************************************************************/ +package org.aspectj.weaver.patterns; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.WeaverTestCase; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.bcel.BcelWorld; + +/* + * Sample types that this program uses are: + + import p.SimpleAnnotation; + + @SimpleAnnotation(id=2) + public class AnnotatedClass { + + @SimpleAnnotation(id=3) + public void m1() { } + + @SimpleAnnotation(id=4) + int i; + } + + * with SimpleAnnotation defined as: + + package p; + import java.lang.annotation.*; + + @Retention(RetentionPolicy.RUNTIME) + public @interface SimpleAnnotation { + int id(); + String fruit() default "bananas"; + } + + *NOTE NOTE NOTE NOTE NOTE NOTE NOTE* + If you need to rebuild the test data code, run 'ant -f build-15.xml' in the + testdata directory. + + */ +public class AnnotationPatternMatchingTestCase extends TestCase { + + private BcelWorld world; + private AnnotationTypePattern fooTP, simpleAnnotationTP; + + private ResolvedType loadType(String name) { + if (world == null) { + world = new BcelWorld(WeaverTestCase.TESTDATA_PATH + "/testcode.jar"); + world.setBehaveInJava5Way(true); + } + return world.resolve(name); + } + + private void initAnnotationTypePatterns() { + PatternParser p = new PatternParser("@Foo"); + fooTP = p.maybeParseAnnotationPattern(); + fooTP = fooTP.resolveBindings(makeSimpleScope(), new Bindings(3), true); + + p = new PatternParser("@p.SimpleAnnotation"); + simpleAnnotationTP = p.maybeParseAnnotationPattern(); + simpleAnnotationTP = simpleAnnotationTP.resolveBindings(makeSimpleScope(), new Bindings(3), true); + } + + public void testAnnotationPatternMatchingOnTypes() { + if (LangUtil.is15VMOrGreater()) { + ResolvedType rtx = loadType("AnnotatedClass"); + initAnnotationTypePatterns(); + + // One should match + assertTrue("@Foo should not match on the AnnotatedClass", fooTP.matches(rtx).alwaysFalse()); + assertTrue("@SimpleAnnotation should match on the AnnotatedClass", simpleAnnotationTP.matches(rtx).alwaysTrue()); + } + + } + + static class MyMessageHandler implements IMessageHandler { + public List messages = new ArrayList(); + + public boolean handleMessage(IMessage message) throws AbortException { + messages.add(message); + return false; + } + + public boolean isIgnoring(Kind kind) { + return false; + } + + public void dontIgnore(IMessage.Kind kind) { + } + + public void ignore(Kind kind) { + } + } + + public void testReferenceToNonAnnotationType() { + // ResolvedType rtx = + loadType("AnnotatedClass"); // inits the world + PatternParser p = new PatternParser("@java.lang.String"); + + MyMessageHandler mh = new MyMessageHandler(); + world.setMessageHandler(mh); + AnnotationTypePattern atp = p.maybeParseAnnotationPattern(); + atp = atp.resolveBindings(makeSimpleScope(), new Bindings(3), true); + + assertTrue("Expected 1 error message but got " + mh.messages.size(), mh.messages.size() == 1); + + String expected = "Type referred to is not an annotation type"; + String msg = ((IMessage) mh.messages.get(0)).toString(); + assertTrue("Expected: " + expected + " but got " + msg, msg.indexOf(expected) != -1); + } + + public void testReferenceViaFormalToNonAnnotationType() { + // ResolvedType rtx = + loadType("AnnotatedClass"); // inits the world + PatternParser p = new PatternParser("a"); + + MyMessageHandler mh = new MyMessageHandler(); + world.setMessageHandler(mh); + AnnotationTypePattern atp = p.parseAnnotationNameOrVarTypePattern(); + atp = atp.resolveBindings(makeSimpleScope(), new Bindings(3), true); + + assertTrue("Expected 3 error messages but got " + mh.messages.size(), mh.messages.size() == 3); + + String expected = "Type referred to is not an annotation type"; + String msg = ((IMessage) mh.messages.get(0)).toString(); + assertTrue("Expected: " + expected + " but got " + msg, msg.indexOf(expected) != -1); + + // expected = "Binding not supported in @pcds (1.5.0 M1 limitation): null"; + // msg = ((IMessage)mh.messages.get(1)).toString(); + // assertTrue("Expected: "+expected+" but got "+msg,msg.indexOf(expected)!=-1); + } + + public TestScope makeSimpleScope() { + return new TestScope(new String[] { "int", "java.lang.String" }, new String[] { "a", "b" }, world); + } + + public void testUnresolvedAnnotationTypes() { + ResolvedType rtx = loadType("AnnotatedClass"); + + PatternParser p = new PatternParser("@Foo"); + AnnotationTypePattern fooTP = p.maybeParseAnnotationPattern(); + try { + fooTP.matches(rtx); + fail("Should have failed with illegal state exception, fooTP is not resolved"); + } catch (IllegalStateException ise) { + // Correct! + } + } + + public void testAnnotationPatternMatchingOnMethods() { + if (LangUtil.is15VMOrGreater()) { + ResolvedType rtx = loadType("AnnotatedClass"); + ResolvedMember aMethod = rtx.getDeclaredMethods()[1]; + + assertTrue("Haven't got the right method, I'm looking for 'm1()': " + aMethod.getName(), aMethod.getName().equals("m1")); + + initAnnotationTypePatterns(); + + // One should match + assertTrue("@Foo should not match on the AnnotatedClass.m1() method", fooTP.matches(aMethod).alwaysFalse()); + assertTrue("@SimpleAnnotation should match on the AnnotatedClass.m1() method", simpleAnnotationTP.matches(aMethod) + .alwaysTrue()); + } + } + + public void testAnnotationPatternMatchingOnFields() { + if (LangUtil.is15VMOrGreater()) { + ResolvedType rtx = loadType("AnnotatedClass"); + ResolvedMember aField = rtx.getDeclaredFields()[0]; + + assertTrue("Haven't got the right field, I'm looking for 'i'" + aField.getName(), aField.getName().equals("i")); + + initAnnotationTypePatterns(); + + // One should match + assertTrue("@Foo should not match on the AnnotatedClass.i field", fooTP.matches(aField).alwaysFalse()); + assertTrue("@SimpleAnnotation should match on the AnnotatedClass.i field", simpleAnnotationTP.matches(aField) + .alwaysTrue()); + } + + } + + public void testAnnotationTypeResolutionOnTypes() { + ResolvedType rtx = loadType("AnnotatedClass"); + ResolvedType[] types = rtx.getAnnotationTypes(); + assertTrue("Did not expect null", types != null); + assertTrue("Expected 1 entry but got " + types.length, types.length == 1); + assertTrue("Should be 'p.SimpleAnnotation' but is " + types[0], types[0].equals(world.resolve("p.SimpleAnnotation"))); + } + + public void testAnnotationTypeResolutionOnMethods() { + ResolvedType rtx = loadType("AnnotatedClass"); + + ResolvedMember aMethod = rtx.getDeclaredMethods()[1]; + assertTrue("Haven't got the right method, I'm looking for 'm1()': " + aMethod.getName(), aMethod.getName().equals("m1")); + + ResolvedType[] types = aMethod.getAnnotationTypes(); + assertTrue("Did not expect null", types != null); + assertTrue("Expected 1 entry but got " + types.length, types.length == 1); + assertTrue("Should be 'p.SimpleAnnotation' but is " + types[0], types[0].equals(world.resolve("p.SimpleAnnotation"))); + } + + public void testAnnotationTypeResolutionOnFields() { + ResolvedType rtx = loadType("AnnotatedClass"); + + ResolvedMember aField = rtx.getDeclaredFields()[0]; + + assertTrue("Haven't got the right field, I'm looking for 'i'" + aField.getName(), aField.getName().equals("i")); + + ResolvedType[] types = aField.getAnnotationTypes(); + assertTrue("Did not expect null", types != null); + assertTrue("Expected 1 entry but got " + types.length, types.length == 1); + assertTrue("Should be 'p.SimpleAnnotation' but is " + types[0], types[0].equals(world.resolve("p.SimpleAnnotation"))); + } + + public void testWildPatternMatchingOnTypes() { + + ResolvedType rtx = loadType("AnnotatedClass"); + initAnnotationTypePatterns(); + + // Let's create something wild + PatternParser p = new PatternParser("@(Foo || Boo)"); + AnnotationTypePattern ap = p.maybeParseAnnotationPattern(); + ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true); + assertTrue("shouldnt match the type AnnotatedClass", ap.matches(rtx).alwaysFalse()); + + p = new PatternParser("@(p.SimpleAnnotation || Boo)"); + ap = p.maybeParseAnnotationPattern(); + ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true); + assertTrue("should match the type AnnotatedClass", ap.matches(rtx).alwaysTrue()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java new file mode 100644 index 000000000..899b40b8e --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java @@ -0,0 +1,382 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * ******************************************************************/ +package org.aspectj.weaver.patterns; + +import junit.framework.TestCase; + +import org.aspectj.bridge.AbortException; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.AnnotatedElement; +import org.aspectj.weaver.AnnotationAJ; +import org.aspectj.weaver.WeaverTestCase; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.bcel.BcelWorld; + +public class AnnotationPatternTestCase extends TestCase { + + public void testParseSimpleAnnotationPattern() { + PatternParser p = new PatternParser("@Foo"); + AnnotationTypePattern foo = p.maybeParseAnnotationPattern(); + foo = foo.resolveBindings(makeSimpleScope(), new Bindings(3), true); + assertTrue("ExactAnnotationTypePattern", foo instanceof ExactAnnotationTypePattern); + assertEquals("Foo", UnresolvedType.forSignature("LFoo;"), ((ExactAnnotationTypePattern) foo).annotationType); + } + + public void testParseAndAnnotationPattern() { + PatternParser p = new PatternParser("@Foo @Goo"); + AnnotationTypePattern fooAndGoo = p.maybeParseAnnotationPattern(); + assertTrue("AndAnnotationTypePattern", fooAndGoo instanceof AndAnnotationTypePattern); + assertEquals("@(Foo) @(Goo)", fooAndGoo.toString()); + fooAndGoo = fooAndGoo.resolveBindings(makeSimpleScope(), new Bindings(3), true); + assertEquals("@Foo @Goo", fooAndGoo.toString()); + AnnotationTypePattern left = ((AndAnnotationTypePattern) fooAndGoo).getLeft(); + AnnotationTypePattern right = ((AndAnnotationTypePattern) fooAndGoo).getRight(); + assertEquals("Foo", UnresolvedType.forSignature("LFoo;"), ((ExactAnnotationTypePattern) left).annotationType); + assertEquals("Goo", UnresolvedType.forSignature("LGoo;"), ((ExactAnnotationTypePattern) right).annotationType); + } + + // + // public void testParseOrAnnotationPattern() { + // PatternParser p = new PatternParser("@Foo || @Goo"); + // AnnotationTypePattern fooOrGoo = p.parseAnnotationTypePattern(); + // assertTrue("OrAnnotationTypePattern",fooOrGoo instanceof + // OrAnnotationTypePattern); + // assertEquals("(@Foo || @Goo)",fooOrGoo.toString()); + // AnnotationTypePattern left = + // ((OrAnnotationTypePattern)fooOrGoo).getLeft(); + // AnnotationTypePattern right = + // ((OrAnnotationTypePattern)fooOrGoo).getRight(); + // assertEquals("Foo",UnresolvedType.forName("Foo"),(( + // ExactAnnotationTypePattern)left).annotationType); + // assertEquals("Goo",UnresolvedType.forName("Goo"),(( + // ExactAnnotationTypePattern)right).annotationType); + // } + // + public void testParseNotAnnotationPattern() { + PatternParser p = new PatternParser("!@Foo"); + AnnotationTypePattern notFoo = p.maybeParseAnnotationPattern(); + assertTrue("NotAnnotationTypePattern", notFoo instanceof NotAnnotationTypePattern); + notFoo = notFoo.resolveBindings(makeSimpleScope(), new Bindings(3), true); + assertEquals("!@Foo", notFoo.toString()); + AnnotationTypePattern body = ((NotAnnotationTypePattern) notFoo).getNegatedPattern(); + assertEquals("Foo", UnresolvedType.forName("Foo"), ((ExactAnnotationTypePattern) body).annotationType); + } + + public void testParseBracketedAnnotationPattern() { + PatternParser p = new PatternParser("(@Foo)"); + AnnotationTypePattern foo = p.maybeParseAnnotationPattern(); + // cannot start with ( so, we get ANY + assertEquals("ANY", AnnotationTypePattern.ANY, foo); + } + + public void testParseFQAnnPattern() { + PatternParser p = new PatternParser("@org.aspectj.Foo"); + AnnotationTypePattern foo = p.maybeParseAnnotationPattern(); + assertEquals("@(org.aspectj.Foo)", foo.toString()); + } + + public void testParseComboPattern() { + // PatternParser p = new PatternParser("!((@Foo || @Goo) && !@Boo)"); + PatternParser p = new PatternParser("@(Foo || Goo)!@Boo"); + AnnotationTypePattern ap = p.maybeParseAnnotationPattern(); + ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true); + AndAnnotationTypePattern atp = (AndAnnotationTypePattern) ap; + NotAnnotationTypePattern notBoo = (NotAnnotationTypePattern) atp.getRight(); + // ExactAnnotationTypePattern boo = (ExactAnnotationTypePattern) + notBoo.getNegatedPattern(); + // AnnotationTypePattern fooOrGoo = (AnnotationTypePattern) + atp.getLeft(); + assertEquals("@((Foo || Goo)) !@Boo", ap.toString()); + } + + // public void testParseAndOrPattern() { + // PatternParser p = new PatternParser("@Foo && @Boo || @Goo"); + // AnnotationTypePattern andOr = p.parseAnnotationTypePattern(); + // assertTrue("Should be or pattern",andOr instanceof + // OrAnnotationTypePattern); + // } + // + public void testParseBadPattern() { + PatternParser p = new PatternParser("@@Foo"); + try { + p.maybeParseAnnotationPattern(); + fail("ParserException expected"); + } catch (ParserException pEx) { + assertEquals("name pattern", pEx.getMessage()); + } + } + + public void testParseBadPattern2() { + PatternParser p = new PatternParser("Foo"); + AnnotationTypePattern bad = p.maybeParseAnnotationPattern(); + assertEquals("ANY", AnnotationTypePattern.ANY, bad); + } + + public void testParseNameOrVarAnnotationPattern() { + PatternParser p = new PatternParser("Foo"); + AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern(); + assertTrue("ExactAnnotationTypePattern expected", foo != null); + assertEquals("Foo", UnresolvedType.forName("Foo"), ((ExactAnnotationTypePattern) foo).annotationType); + } + + public void testParseNameOrVarAnnotationPatternWithNot() { + PatternParser p = new PatternParser("!@Foo"); + try { + // AnnotationTypePattern bad = + p.parseAnnotationNameOrVarTypePattern(); + fail("ParserException expected"); + } catch (ParserException pEx) { + assertEquals("identifier", pEx.getMessage()); + } + } + + public void testParseNameOrVarAnnotationPatternWithOr() { + PatternParser p = new PatternParser("Foo || Boo"); + AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern(); + // rest of pattern not consumed... + assertTrue("ExactAnnotationTypePattern", foo instanceof ExactAnnotationTypePattern); + assertEquals("Foo", UnresolvedType.forName("Foo"), ((ExactAnnotationTypePattern) foo).annotationType); + } + + public void testParseNameOrVarAnnotationWithBinding() { + PatternParser p = new PatternParser("foo"); + AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern(); + assertTrue("ExactAnnotationTypePattern", foo instanceof ExactAnnotationTypePattern); + assertEquals("@foo", ((ExactAnnotationTypePattern) foo).toString()); + } + + public void testParseNameOrVarAnnotationPatternWithAnd() { + PatternParser p = new PatternParser("Foo Boo"); + AnnotationTypePattern foo = p.parseAnnotationNameOrVarTypePattern(); + // rest of pattern not consumed... + assertEquals("@Foo", foo.toString()); + } + + public void testMaybeParseAnnotationPattern() { + PatternParser p = new PatternParser("@Foo"); + AnnotationTypePattern a = p.maybeParseAnnotationPattern(); + assertNotNull("Should find annotation pattern", a); + p = new PatternParser("Foo && Boo"); + a = p.maybeParseAnnotationPattern(); + assertEquals("Should be ANY pattern for a non-match", AnnotationTypePattern.ANY, a); + } + + public void testParseTypePatternsWithAnnotations() { + PatternParser p = new PatternParser("@Foo *"); + TypePattern t = p.parseTypePattern(); + assertTrue("AnyWithAnnotationTypePattern", t instanceof AnyWithAnnotationTypePattern); + AnnotationTypePattern atp = t.annotationPattern; + assertEquals("@(Foo)", atp.toString()); + assertEquals("(@(Foo) *)", t.toString()); + } + + public void testParseTypePatternsWithAnnotationsComplex() { + PatternParser p = new PatternParser("(@(Foo || Boo) (Foo || Boo))"); + TypePattern t = p.parseTypePattern(); + assertTrue("OrTypePattern", t instanceof OrTypePattern); + assertEquals("((@((Foo || Boo)) Foo) || (@((Foo || Boo)) Boo))", t.toString()); + } + + public void testNotSyntax() { + PatternParser p = new PatternParser("!@Foo (Foo || Boo))"); + TypePattern t = p.parseTypePattern(); + assertTrue("OrTypePattern", t instanceof OrTypePattern); + assertEquals("((!@(Foo) Foo) || (!@(Foo) Boo))", t.toString()); + } + + public void testParseMethodOrConstructorSigNoAP() { + PatternParser p = new PatternParser("* *.*(..)"); + SignaturePattern s = p.parseMethodOrConstructorSignaturePattern(); + assertEquals("Any annotation", AnnotationTypePattern.ANY, s.getAnnotationPattern()); + assertEquals("Any return", "*", s.getReturnType().toString()); + assertEquals("Any dec type", "*", s.getDeclaringType().toString()); + assertEquals("Any name", "*", s.getName().toString()); + assertEquals("* *.*(..)", s.toString()); + } + + public void testParseMethodOrConstructorSigSimpleAP() { + PatternParser p = new PatternParser("@Foo * *.*(..)"); + SignaturePattern s = p.parseMethodOrConstructorSignaturePattern(); + assertEquals("@(Foo) annotation", "@(Foo)", s.getAnnotationPattern().toString()); + assertEquals("Any return", "*", s.getReturnType().toString()); + assertEquals("Any dec type", "*", s.getDeclaringType().toString()); + assertEquals("Any name", "*", s.getName().toString()); + assertEquals("@(Foo) * *.*(..)", s.toString()); + } + + public void testParseMethodOrConstructorSigComplexAP() { + PatternParser p = new PatternParser("!@(Foo || Goo) * *.*(..)"); + SignaturePattern s = p.parseMethodOrConstructorSignaturePattern(); + assertEquals("complex annotation", "!@((Foo || Goo))", s.getAnnotationPattern().toString()); + assertEquals("Any return", "*", s.getReturnType().toString()); + assertEquals("Any dec type", "*", s.getDeclaringType().toString()); + assertEquals("Any name", "*", s.getName().toString()); + assertEquals("!@((Foo || Goo)) * *.*(..)", s.toString()); + } + + public void testParseMethodFieldSigNoAP() { + PatternParser p = new PatternParser("* *.*"); + SignaturePattern s = p.parseFieldSignaturePattern(); + assertEquals("Any annotation", AnnotationTypePattern.ANY, s.getAnnotationPattern()); + assertEquals("Any field type", "*", s.getReturnType().toString()); + assertEquals("Any dec type", "*", s.getDeclaringType().toString()); + assertEquals("Any name", "*", s.getName().toString()); + assertEquals("* *.*", s.toString()); + } + + public void testParseFieldSigSimpleAP() { + PatternParser p = new PatternParser("@Foo * *.*"); + SignaturePattern s = p.parseFieldSignaturePattern(); + assertEquals("@Foo annotation", "@(Foo)", s.getAnnotationPattern().toString()); + assertEquals("Any field type", "*", s.getReturnType().toString()); + assertEquals("Any dec type", "*", s.getDeclaringType().toString()); + assertEquals("Any name", "*", s.getName().toString()); + assertEquals("@(Foo) * *.*", s.toString()); + } + + public void testParseFieldSigComplexAP() { + PatternParser p = new PatternParser("!@(Foo || Goo) * *.*"); + SignaturePattern s = p.parseFieldSignaturePattern(); + assertEquals("complex annotation", "!@((Foo || Goo))", s.getAnnotationPattern().toString()); + assertEquals("Any field type", "*", s.getReturnType().toString()); + assertEquals("Any dec type", "*", s.getDeclaringType().toString()); + assertEquals("Any name", "*", s.getName().toString()); + assertEquals("!@((Foo || Goo)) * *.*", s.toString()); + } + + public void testExactAnnotationPatternMatching() { + if (LangUtil.is15VMOrGreater()) { + PatternParser p = new PatternParser("@Foo"); + AnnotationTypePattern ap = p.maybeParseAnnotationPattern(); + ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true); + AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] { "Foo" }); + assertTrue("matches element with Foo", ap.matches(ae).alwaysTrue()); + AnnotatedElementImpl ae2 = new AnnotatedElementImpl(new String[] { "Boo" }); + assertTrue("does not match element with Boo", ap.matches(ae2).alwaysFalse()); + } + } + + public void testBindingAnnotationPatternMatching() { + if (LangUtil.is15VMOrGreater()) { + PatternParser p = new PatternParser("foo"); + AnnotationTypePattern ap = p.parseAnnotationNameOrVarTypePattern(); + try { + ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true); + } catch (AbortException abEx) { + assertEquals("Binding not supported in @pcds (1.5.0 M1 limitation): null", abEx.getMessage()); + } + // uncomment these next lines once binding is supported + // AnnotatedElementImpl ae = new AnnotatedElementImpl(new + // String[]{"Foo"}); + // assertTrue("matches element with Foo",ap.matches(ae).alwaysTrue()) + // ; + // AnnotatedElementImpl ae2 = new AnnotatedElementImpl(new + // String[]{"Boo"}); + // assertTrue("does not match element with Boo",ap.matches(ae2). + // alwaysFalse()); + } + } + + public void testAndAnnotationPatternMatching() { + if (LangUtil.is15VMOrGreater()) { + PatternParser p = new PatternParser("@Foo @Boo"); + AnnotationTypePattern ap = p.maybeParseAnnotationPattern(); + ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true); + AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] { "Foo", "Boo" }); + assertTrue("matches foo and boo", ap.matches(ae).alwaysTrue()); + ae = new AnnotatedElementImpl(new String[] { "Foo" }); + assertTrue("does not match foo", ap.matches(ae).alwaysFalse()); + ae = new AnnotatedElementImpl(new String[] { "Boo" }); + assertTrue("does not match boo", ap.matches(ae).alwaysFalse()); + ae = new AnnotatedElementImpl(new String[] { "Goo" }); + assertTrue("does not match goo", ap.matches(ae).alwaysFalse()); + } + } + + // + // public void testOrAnnotationPatternMatching() { + // PatternParser p = new PatternParser("@Foo || @Boo"); + // AnnotationTypePattern ap = p.parseAnnotationTypePattern(); + // ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true); + // AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] + // {"Foo","Boo"}); + // assertTrue("matches foo and boo",ap.matches(ae).alwaysTrue()); + // ae = new AnnotatedElementImpl(new String[] {"Foo"}); + // assertTrue("matches foo",ap.matches(ae).alwaysTrue()); + // ae = new AnnotatedElementImpl(new String[] {"Boo"}); + // assertTrue("matches boo",ap.matches(ae).alwaysTrue()); + // ae = new AnnotatedElementImpl(new String[] {"Goo"}); + // assertTrue("does not match goo",ap.matches(ae).alwaysFalse()); + // } + // + public void testNotAnnotationPatternMatching() { + if (LangUtil.is15VMOrGreater()) { + PatternParser p = new PatternParser("!@Foo"); + AnnotationTypePattern ap = p.maybeParseAnnotationPattern(); + ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true); + AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] { "Foo", "Boo" }); + assertTrue("does not match foo and boo", ap.matches(ae).alwaysFalse()); + ae = new AnnotatedElementImpl(new String[] { "Boo" }); + assertTrue("matches boo", ap.matches(ae).alwaysTrue()); + } + } + + public void testAnyAnnotationPatternMatching() { + AnnotatedElementImpl ae = new AnnotatedElementImpl(new String[] { "Foo", "Boo" }); + assertTrue("always matches", AnnotationTypePattern.ANY.matches(ae).alwaysTrue()); + ae = new AnnotatedElementImpl(new String[] {}); + assertTrue("always matches", AnnotationTypePattern.ANY.matches(ae).alwaysTrue()); + } + + public TestScope makeSimpleScope() { + BcelWorld bWorld = new BcelWorld(WeaverTestCase.TESTDATA_PATH + "/testcode.jar"); // testcode contains Foo/Boo/Goo/etc + bWorld.setBehaveInJava5Way(true); + return new TestScope(new String[] { "int", "java.lang.String", "Foo", "Boo", "Goo" }, new String[] { "a", "b", "foo", + "boo", "goo" }, bWorld); + } + + // put test cases for AnnotationPatternList matching in separate test + // class... + + static class AnnotatedElementImpl implements AnnotatedElement { + + private String[] annotationTypes; + + public AnnotatedElementImpl(String[] annotationTypes) { + this.annotationTypes = annotationTypes; + } + + public boolean hasAnnotation(UnresolvedType ofType) { + for (int i = 0; i < annotationTypes.length; i++) { + if (annotationTypes[i].equals(ofType.getName())) { + return true; + } + } + return false; + } + + /* + * (non-Javadoc) + * + * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes() + */ + public ResolvedType[] getAnnotationTypes() { + // TODO Auto-generated method stub + return null; + } + + public AnnotationAJ getAnnotationOfType(UnresolvedType ofType) { + // TODO Auto-generated method stub + return null; + } + + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/ConcretizationTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/ConcretizationTestCase.java new file mode 100644 index 000000000..8c3fd0d9c --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/ConcretizationTestCase.java @@ -0,0 +1,116 @@ +/* ******************************************************************* + * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC). + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * PARC initial implementation + * ******************************************************************/ + +package org.aspectj.weaver.patterns; + +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.bcel.WeaveTestCase; + +public class ConcretizationTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public ConcretizationTestCase(String name) { + super(name); + } + + public void testNothingForAntJUnit() { + } + + // String[] none = new String[0]; + + /* + * XXX temporarily skipping public void testCflowResidual() throws IOException { + * + * BcelAdvice a = (BcelAdvice) makeConcreteTestAdviceEntryPart(); + * + * TestShadow shadow = new TestShadow(Shadow.MethodCall, Member.methodFromString("int Aspect.i(int x)"), UnresolvedType.OBJECT, + * world); + * + * ExposedState state = new ExposedState(1); + * + * a.specializeOn(shadow); + * + * //System.err.println(shadow); //System.err.println(a); + * + * //System.err.println(a.exposedState); + * + * + * } + * + * + * + * public Advice makeConcreteTestAdviceEntryPart() throws IOException { // XXX copied from below, refactor later + * + * + * // returns the advice for the entry part of cflow(foo(a)) Pointcut in = createResolvedPointcut( + * "cflow(foo(a)) && (args(b) && !cflow(foo(int)))", new String[] { "b", "a" }, new String[] { "float", "int" }); + * + * ResolvedPointcutDefinition ref = new ResolvedPointcutDefinition( UnresolvedType.forName("Aspect"), 0, "foo", new + * UnresolvedType[] { UnresolvedType.INT }, createResolvedPointcut( "args(refA)", new String[] { "refA" }, new String[] { "int" + * })); BcelObjectType target = (BcelObjectType) world.resolve("Aspect"); + * + * // now munge this to get the pointcut in it + * + * target.addPointcutDefinition(ref); CrosscuttingMembers xcut = new CrosscuttingMembers(target); target.crosscuttingMembers = + * xcut; + * + * Advice adviceMember = new BcelAdvice( AdviceKind.Before, in, Member.method(UnresolvedType.forName("FOO"), 0, "garadf", + * "(FI)V"), 0, 0, 0, null, null); // The pointcut to concretize + * + * // this returns the actual advice, but we don't care about it now. in.concretize(target, 2, adviceMember); + * + * List c = (List)xcut.getCflowEntries(); //target.getExtraConcreteShadowMungers(); + * + * return (Advice) c.get(0); } + * + * public void XtestCflow() throws IOException { Pointcut in = + * createResolvedPointcut("cflow(foo(a)) && (args(b) && !cflow(foo(int)))", new String[] {"b", "a"}, new String[] {"float", + * "int"} ); + * + * ResolvedPointcutDefinition ref = new ResolvedPointcutDefinition(UnresolvedType.forName("Aspect"), 0, "foo", new + * UnresolvedType[] { UnresolvedType.INT }, createResolvedPointcut("args(refA)", new String[] {"refA"}, new String[] {"int"})); + * + * List expectedSlots = new ArrayList(); expectedSlots.add(new ConcreteCflowPointcut.Slot(1, UnresolvedType.INT, 0)); + * + * checkConcr(in, ref, expectedSlots); } + * + * public void checkConcr( Pointcut in, ResolvedPointcutDefinition referredTo, List expectedSlots) throws IOException { + * + * BcelObjectType target = (BcelObjectType)world.resolve("Aspect"); + * + * // now munge this to get the pointcut in it + * + * target.addPointcutDefinition(referredTo); + * + * + * Advice adviceMember = new BcelAdvice(AdviceKind.Before, in, Member.method(UnresolvedType.forName("FOO"), 0, "garadf", + * "(FI)V"), 0, 0, 0, null, null); + * + * // The pointcut to concretize AndPointcut ap = (AndPointcut)in.concretize(target, 2, adviceMember); + * + * + * ConcreteCflowPointcut conc = (ConcreteCflowPointcut)ap.left; + * + * List slots = conc.slots; TestUtil.assertSetEquals(expectedSlots, slots); + * + * } + */ + + public Pointcut createResolvedPointcut(String pointcutSource, String[] formalNames, String[] formalTypes) { + final Pointcut sp = Pointcut.fromString(pointcutSource); + final Pointcut rp = sp.resolve(new SimpleScope(world, SimpleScope.makeFormalBindings(UnresolvedType.forNames(formalTypes), + formalNames))); + return rp; + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/WildTypePatternResolutionTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/WildTypePatternResolutionTestCase.java new file mode 100644 index 000000000..5eda5d577 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/WildTypePatternResolutionTestCase.java @@ -0,0 +1,422 @@ +/* ******************************************************************* + * 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Adrian Colyer initial implementation + * ******************************************************************/ +package org.aspectj.weaver.patterns; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import junit.framework.TestCase; + +import org.aspectj.weaver.BoundedReferenceType; +import org.aspectj.weaver.CompressingDataOutputStream; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.TypeFactory; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.VersionedDataInputStream; +import org.aspectj.weaver.World; +import org.aspectj.weaver.AjAttribute.WeaverVersionInfo; +import org.aspectj.weaver.bcel.BcelWorld; + +// TODO write test cases for instanceof matching + +public class WildTypePatternResolutionTestCase extends TestCase { + + private World world; + private Bindings bindings; + private SimpleScope scope; + private ResolvedType javaUtilList; + private ResolvedType javaLangString; + private ResolvedType javaUtilListOfString; + private ResolvedType javaUtilListOfDouble; + private ResolvedType javaUtilListOfSomething; + + /** + * Foo where Foo exists and is generic Parser creates WildTypePattern namePatterns={Foo} resolveBindings resolves Foo to RT(Foo + * - raw) return ExactTypePattern(LFoo;) + */ + public void testSimpleFoo() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to exact type", rtp instanceof ExactTypePattern); + UnresolvedType exactType = rtp.getExactType(); + assertTrue(exactType.isRawType()); + assertEquals("Ljava/util/List;", exactType.getSignature()); + + ResolvedType rt = exactType.resolve(world); + assertEquals("Ljava/util/List;", rt.getSignature()); + assertTrue(rt.isRawType()); + + ExactTypePattern etp = (ExactTypePattern) writeAndRead(rtp); + exactType = etp.getExactType(); + + assertEquals("Ljava/util/List;", exactType.getSignature()); + + rt = exactType.resolve(world); + assertEquals("Ljava/util/List;", rt.getSignature()); + assertTrue(rt.isRawType()); + + assertTrue("matches List", etp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertTrue("matches generic List", etp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertTrue("matches parameterized list", etp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertTrue("does not match String", etp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + } + + /** + * Foo where Foo exists and String meets the bounds Parser creates WildTypePattern namePatterns = {Foo}, + * typeParameters=WTP{String} resolveBindings resolves typeParameters to ExactTypePattern(String) resolves Foo to RT(Foo) + * returns ExactTypePattern(PFoo; - parameterized) + */ + public void testParameterized() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to exact type", rtp instanceof ExactTypePattern); + UnresolvedType exactType = rtp.getExactType(); + assertTrue(exactType.isParameterizedType()); + assertEquals("Pjava/util/List;", exactType.getSignature()); + + ResolvedType rt = exactType.resolve(world); + assertEquals("Pjava/util/List;", rt.getSignature()); + assertTrue(rt.isParameterizedType()); + + ExactTypePattern etp = (ExactTypePattern) writeAndRead(rtp); + exactType = etp.getExactType(); + + assertEquals("Pjava/util/List;", rt.getSignature()); + assertTrue(rt.isParameterizedType()); + + rt = exactType.resolve(world); + assertEquals("Pjava/util/List;", rt.getSignature()); + assertTrue(rt.isParameterizedType()); + + assertFalse("does not match List", etp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", etp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertTrue("matches parameterized list", etp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", etp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", etp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + + } + + /** + * Foo where Foo exists and takes one bound Parser creates WildTypePattern namePatterns = {Foo}, typeParameters=WTP{Str*} + * resolveBindings resolves typeParameters to WTP{Str*} resolves Foo to RT(Foo) returns WildTypePattern(name = Foo, + * typeParameters = WTP{Str*} isGeneric=false) + */ + public void testParameterizedWildCard() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to WildTypePattern", rtp instanceof WildTypePattern); + assertTrue("one type parameter", rtp.typeParameters.size() == 1); + assertTrue("missing", ResolvedType.isMissing(rtp.getExactType())); + + WildTypePattern wtp = (WildTypePattern) writeAndRead(rtp); + assertTrue("one type parameter", wtp.typeParameters.size() == 1); + assertTrue("missing", ResolvedType.isMissing(wtp.getExactType())); + assertEquals("Str*", wtp.getTypeParameters().getTypePatterns()[0].toString()); + + assertFalse("does not match List", wtp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", wtp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertTrue("matches parameterized list", wtp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", wtp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", wtp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + } + + /** + * Fo* Parser creates WildTypePattern namePatterns = {Fo*}, typeParameters=WTP{String} resolveBindings resolves + * typeParameters to ETP{String} returns WildTypePattern(name = Fo*, typeParameters = ETP{String} isGeneric=false) + */ + public void testWildcardParameterized() { + TypePattern rtp = resolveWildTypePattern("Li*", false); + + assertTrue("resolves to WildTypePattern", rtp instanceof WildTypePattern); + assertTrue("one type parameter", rtp.typeParameters.size() == 1); + assertEquals("Ljava/lang/String;", rtp.typeParameters.getTypePatterns()[0].getExactType().getSignature()); + + WildTypePattern wtp = (WildTypePattern) writeAndRead(rtp); + assertTrue("one type parameter", wtp.typeParameters.size() == 1); + assertEquals("Ljava/lang/String;", wtp.typeParameters.getTypePatterns()[0].getExactType().getSignature()); + + assertFalse("does not match List", wtp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", wtp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertTrue("matches parameterized list", wtp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", wtp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", wtp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + } + + /** + * Foo + */ + public void testSomething() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to exact type", rtp instanceof ExactTypePattern); + UnresolvedType exactType = rtp.getExactType(); + assertTrue(exactType.isParameterizedType()); + assertEquals("Pjava/util/List<*>;", exactType.getSignature()); + + ExactTypePattern etp = (ExactTypePattern) writeAndRead(rtp); + exactType = etp.getExactType(); + assertTrue(exactType.isParameterizedType()); + assertEquals("Pjava/util/List<*>;", exactType.getSignature()); + + assertFalse("does not match List", etp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", etp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list", etp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", etp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", etp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + + assertTrue("matches list of something", etp.matches(javaUtilListOfSomething, TypePattern.STATIC).alwaysTrue()); + } + + /** + * Foo + */ + public void testSomethingExtends() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to exact type", rtp instanceof ExactTypePattern); + UnresolvedType exactType = rtp.getExactType(); + assertTrue(exactType.isParameterizedType()); + assertEquals("Pjava/util/List<+Ljava/lang/Number;>;", exactType.getSignature()); + assertTrue("got a bounded reference type", exactType.getTypeParameters()[0] instanceof BoundedReferenceType); + + ExactTypePattern etp = (ExactTypePattern) writeAndRead(rtp); + exactType = etp.getExactType(); + exactType = exactType.resolve(world); + assertTrue(exactType.isParameterizedType()); + assertEquals("Pjava/util/List<+Ljava/lang/Number;>;", exactType.getSignature()); + assertTrue("got a bounded reference type", exactType.getTypeParameters()[0] instanceof BoundedReferenceType); + + assertFalse("does not match List", etp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", etp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list", etp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", etp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", etp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + assertFalse("does not match list of something", etp.matches(javaUtilListOfSomething, TypePattern.STATIC).alwaysTrue()); + + ResolvedType listOfNumber = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Number").resolve(world) }, world); + + ResolvedType listOfDouble = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Double").resolve(world) }, world); + + assertFalse("does not match list of number", etp.matches(listOfNumber, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match list of double", etp.matches(listOfDouble, TypePattern.STATIC).alwaysTrue()); + + ResolvedType extendsNumber = TypeFactory.createTypeFromSignature("+Ljava/lang/Number;").resolve(world); + ResolvedType listOfExtendsNumber = TypeFactory.createParameterizedType(javaUtilList, + new UnresolvedType[] { extendsNumber }, world); + + assertTrue("matches list of ? extends number", etp.matches(listOfExtendsNumber, TypePattern.STATIC).alwaysTrue()); + + } + + /** + * Foo + */ + public void testSomethingExtendsPattern() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to wild type pattern", rtp instanceof WildTypePattern); + assertEquals("one type parameter", 1, rtp.getTypeParameters().size()); + TypePattern tp = rtp.getTypeParameters().getTypePatterns()[0]; + assertTrue("parameter is wild", tp instanceof WildTypePattern); + WildTypePattern tpwtp = (WildTypePattern) tp; + assertEquals("?", tpwtp.getNamePatterns()[0].maybeGetSimpleName()); + assertEquals("java.lang.Number+", tpwtp.upperBound.toString()); + + WildTypePattern wtp = (WildTypePattern) writeAndRead(rtp); + assertEquals("one type parameter", 1, wtp.getTypeParameters().size()); + tp = rtp.getTypeParameters().getTypePatterns()[0]; + assertTrue("parameter is wild", tp instanceof WildTypePattern); + tpwtp = (WildTypePattern) tp; + assertEquals("?", tpwtp.getNamePatterns()[0].maybeGetSimpleName()); + assertEquals("java.lang.Number+", tpwtp.upperBound.toString()); + + assertFalse("does not match List", wtp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", wtp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list", wtp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", wtp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", wtp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + assertFalse("does not match list of something", wtp.matches(javaUtilListOfSomething, TypePattern.STATIC).alwaysTrue()); + + ResolvedType listOfNumber = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Number").resolve(world) }, world); + + ResolvedType listOfDouble = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Double").resolve(world) }, world); + + assertFalse("does not match list of number", wtp.matches(listOfNumber, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match list of double", wtp.matches(listOfDouble, TypePattern.STATIC).alwaysTrue()); + + ResolvedType extendsNumber = TypeFactory.createTypeFromSignature("+Ljava/lang/Number;").resolve(world); + ResolvedType listOfExtendsNumber = TypeFactory.createParameterizedType(javaUtilList, + new UnresolvedType[] { extendsNumber }, world); + + assertTrue("matches list of ? extends number", wtp.matches(listOfExtendsNumber, TypePattern.STATIC).alwaysTrue()); + + ResolvedType extendsDouble = TypeFactory.createTypeFromSignature("+Ljava/lang/Double;").resolve(world); + ResolvedType listOfExtendsDouble = TypeFactory.createParameterizedType(javaUtilList, + new UnresolvedType[] { extendsDouble }, world); + + assertTrue("matches list of ? extends double", wtp.matches(listOfExtendsDouble, TypePattern.STATIC).alwaysTrue()); + + } + + /** + * Foo + */ + public void testSomethingExtendsPatternv2() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to wild type pattern", rtp instanceof WildTypePattern); + assertEquals("one type parameter", 1, rtp.getTypeParameters().size()); + TypePattern tp = rtp.getTypeParameters().getTypePatterns()[0]; + assertTrue("parameter is wild", tp instanceof WildTypePattern); + WildTypePattern tpwtp = (WildTypePattern) tp; + assertEquals("?", tpwtp.getNamePatterns()[0].maybeGetSimpleName()); + assertEquals("Num*", tpwtp.upperBound.toString()); + + WildTypePattern wtp = (WildTypePattern) writeAndRead(rtp); + assertEquals("one type parameter", 1, wtp.getTypeParameters().size()); + tp = rtp.getTypeParameters().getTypePatterns()[0]; + assertTrue("parameter is wild", tp instanceof WildTypePattern); + tpwtp = (WildTypePattern) tp; + assertEquals("?", tpwtp.getNamePatterns()[0].maybeGetSimpleName()); + assertEquals("Num*", tpwtp.upperBound.toString()); + + assertFalse("does not match List", wtp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", wtp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list", wtp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", wtp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", wtp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + assertFalse("does not match list of something", wtp.matches(javaUtilListOfSomething, TypePattern.STATIC).alwaysTrue()); + + ResolvedType listOfNumber = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Number").resolve(world) }, world); + + ResolvedType listOfDouble = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Double").resolve(world) }, world); + + assertFalse("does not match list of number", wtp.matches(listOfNumber, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match list of double", wtp.matches(listOfDouble, TypePattern.STATIC).alwaysTrue()); + + ResolvedType extendsNumber = TypeFactory.createTypeFromSignature("+Ljava/lang/Number;").resolve(world); + ResolvedType listOfExtendsNumber = TypeFactory.createParameterizedType(javaUtilList, + new UnresolvedType[] { extendsNumber }, world); + + assertTrue("matches list of ? extends number", wtp.matches(listOfExtendsNumber, TypePattern.STATIC).alwaysTrue()); + + ResolvedType extendsDouble = TypeFactory.createTypeFromSignature("+Ljava/lang/Double;").resolve(world); + ResolvedType listOfExtendsDouble = TypeFactory.createParameterizedType(javaUtilList, + new UnresolvedType[] { extendsDouble }, world); + + assertFalse("does not match list of ? extends double", wtp.matches(listOfExtendsDouble, TypePattern.STATIC).alwaysTrue()); + } + + /** + * Foo + * + */ + public void testSomethingSuper() { + TypePattern rtp = resolveWildTypePattern("List", false); + + assertTrue("resolves to exact type", rtp instanceof ExactTypePattern); + UnresolvedType exactType = rtp.getExactType(); + assertTrue(exactType.isParameterizedType()); + assertEquals("Pjava/util/List<-Ljava/lang/Double;>;", exactType.getSignature()); + assertTrue("got a bounded reference type", exactType.getTypeParameters()[0] instanceof BoundedReferenceType); + + ExactTypePattern etp = (ExactTypePattern) writeAndRead(rtp); + exactType = etp.getExactType(); + exactType = exactType.resolve(world); + assertTrue(exactType.isParameterizedType()); + assertEquals("Pjava/util/List<-Ljava/lang/Double;>;", exactType.getSignature()); + assertTrue("got a bounded reference type", exactType.getTypeParameters()[0] instanceof BoundedReferenceType); + + assertFalse("does not match List", etp.matches(javaUtilList, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match generic List", etp.matches(javaUtilList.getGenericType(), TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list", etp.matches(javaUtilListOfString, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match parameterized list of double", etp.matches(javaUtilListOfDouble, TypePattern.STATIC) + .alwaysTrue()); + assertTrue("does not match String", etp.matches(javaLangString, TypePattern.STATIC).alwaysFalse()); + assertFalse("does not match list of something", etp.matches(javaUtilListOfSomething, TypePattern.STATIC).alwaysTrue()); + + ResolvedType listOfNumber = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Number").resolve(world) }, world); + + ResolvedType listOfDouble = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Double").resolve(world) }, world); + + assertFalse("does not match list of number", etp.matches(listOfNumber, TypePattern.STATIC).alwaysTrue()); + assertFalse("does not match list of double", etp.matches(listOfDouble, TypePattern.STATIC).alwaysTrue()); + + ResolvedType superDouble = TypeFactory.createTypeFromSignature("-Ljava/lang/Double;").resolve(world); + ResolvedType listOfSuperDouble = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { superDouble }, + world); + + assertTrue("matches list of ? super double", etp.matches(listOfSuperDouble, TypePattern.STATIC).alwaysTrue()); + } + + private TypePattern resolveWildTypePattern(String source, boolean requireExact) { + WildTypePattern wtp = makeWildTypePattern(source); + return wtp.resolveBindings(scope, bindings, false, requireExact); + } + + private WildTypePattern makeWildTypePattern(String source) { + PatternParser parser = new PatternParser(source); + return (WildTypePattern) parser.parseTypePattern(); + } + + private TypePattern writeAndRead(TypePattern etp) { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ConstantPoolSimulator cps = new ConstantPoolSimulator(); + CompressingDataOutputStream dos = new CompressingDataOutputStream(baos, cps); + etp.write(dos); + dos.flush(); + dos.close(); + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + VersionedDataInputStream in = new VersionedDataInputStream(bais, cps); + in.setVersion(new WeaverVersionInfo()); + TypePattern ret = TypePattern.read(in, null); + return ret; + } catch (IOException ioEx) { + fail(ioEx + " thrown during serialization"); + } + return null; + } + + protected void setUp() throws Exception { + super.setUp(); + this.world = new BcelWorld(); + this.world.setBehaveInJava5Way(true); + this.bindings = new Bindings(0); + this.scope = new SimpleScope(world, new FormalBinding[] {}); + this.scope.setImportedPrefixes(new String[] { "java.io.", "java.util.", "java.lang." }); + this.javaLangString = UnresolvedType.forName("java.lang.String").resolve(world); + this.javaUtilList = UnresolvedType.forName("java.util.List").resolve(world); + this.javaUtilListOfString = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { javaLangString }, + world); + this.javaUtilListOfDouble = TypeFactory.createParameterizedType(javaUtilList, new UnresolvedType[] { UnresolvedType + .forName("java.lang.Double").resolve(world) }, world); + this.javaUtilListOfSomething = TypeFactory.createParameterizedType(javaUtilList, + new UnresolvedType[] { UnresolvedType.SOMETHING.resolve(world) }, world); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelAndOrNotTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelAndOrNotTestCase.java new file mode 100644 index 000000000..d72960fea --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelAndOrNotTestCase.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.AndOrNotTestCase; + +public class BcelAndOrNotTestCase extends AndOrNotTestCase { + + public World getWorld() { + return new BcelWorld(); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelBindingTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelBindingTestCase.java new file mode 100644 index 000000000..fac53dee1 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelBindingTestCase.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.BindingTestCase; + +public class BcelBindingTestCase extends BindingTestCase { + + public World getWorld() { + return new BcelWorld(); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelModifiersPatternTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelModifiersPatternTestCase.java new file mode 100644 index 000000000..06b89dc15 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelModifiersPatternTestCase.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.ModifiersPatternTestCase; + +public class BcelModifiersPatternTestCase extends ModifiersPatternTestCase { + + public World getWorld() { + return new BcelWorld(); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelParserTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelParserTestCase.java new file mode 100644 index 000000000..6dc837709 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelParserTestCase.java @@ -0,0 +1,25 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.WeaverTestCase; +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.ParserTestCase; + +public class BcelParserTestCase extends ParserTestCase { + + public World getWorld() { + return new BcelWorld(WeaverTestCase.TESTDATA_PATH + "/testcode.jar"); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelSignaturePatternTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelSignaturePatternTestCase.java new file mode 100644 index 000000000..e7f0f9890 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelSignaturePatternTestCase.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.SignaturePatternTestCase; + +public class BcelSignaturePatternTestCase extends SignaturePatternTestCase { + + public World getWorld() { + return new BcelWorld(); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternListTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternListTestCase.java new file mode 100644 index 000000000..935533d3c --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternListTestCase.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.TypePatternListTestCase; + +public class BcelTypePatternListTestCase extends TypePatternListTestCase { + + public World getWorld() { + return new BcelWorld(); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternTestCase.java new file mode 100644 index 000000000..47b2ce3af --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternTestCase.java @@ -0,0 +1,24 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.TypePatternTestCase; + +public class BcelTypePatternTestCase extends TypePatternTestCase { + + public World getWorld() { + return new BcelWorld(); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelWithinTestCase.java b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelWithinTestCase.java new file mode 100644 index 000000000..8da1c172f --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelWithinTestCase.java @@ -0,0 +1,23 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.patterns.bcel; + +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.weaver.patterns.WithinTestCase; + +public class BcelWithinTestCase extends WithinTestCase { + + public World getWorld() { + return new BcelWorld(); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java b/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java new file mode 100644 index 000000000..72c7c85f7 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java @@ -0,0 +1,316 @@ +/* ******************************************************************* + * 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.reflect; + +import java.lang.reflect.Method; +import java.util.HashSet; +import java.util.Set; + +import junit.framework.TestCase; + +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.bcel.BcelWorld; + +public abstract class ReflectionBasedReferenceTypeDelegateTest extends TestCase { + + protected ReflectionWorld world; + private ResolvedType objectType; + private ResolvedType classType; + + public void testIsAspect() { + assertFalse(objectType.isAspect()); + } + + public void testIsAnnotationStyleAspect() { + assertFalse(objectType.isAnnotationStyleAspect()); + } + + public void testIsInterface() { + assertFalse(objectType.isInterface()); + assertTrue(world.resolve("java.io.Serializable").isInterface()); + } + + public void testIsEnum() { + assertFalse(objectType.isEnum()); + } + + public void testIsAnnotation() { + assertFalse(objectType.isAnnotation()); + } + + public void testIsAnnotationWithRuntimeRetention() { + assertFalse(objectType.isAnnotationWithRuntimeRetention()); + } + + public void testIsClass() { + assertTrue(objectType.isClass()); + assertFalse(world.resolve("java.io.Serializable").isClass()); + } + + public void testIsGeneric() { + assertFalse(objectType.isGenericType()); + } + + public void testIsExposedToWeaver() { + assertFalse(objectType.isExposedToWeaver()); + } + + public void testHasAnnotation() { + assertFalse(objectType.hasAnnotation(UnresolvedType.forName("Foo"))); + } + + public void testGetAnnotations() { + assertEquals("no entries", 0, objectType.getAnnotations().length); + } + + public void testGetAnnotationTypes() { + assertEquals("no entries", 0, objectType.getAnnotationTypes().length); + } + + public void testGetTypeVariables() { + assertEquals("no entries", 0, objectType.getTypeVariables().length); + } + + public void testGetPerClause() { + assertNull(objectType.getPerClause()); + } + + public void testGetModifiers() { + assertEquals(Object.class.getModifiers(), objectType.getModifiers()); + } + + public void testGetSuperclass() { + assertTrue("Superclass of object should be null, but it is: " + objectType.getSuperclass(), + objectType.getSuperclass() == null); + assertEquals(objectType, world.resolve("java.lang.Class").getSuperclass()); + ResolvedType d = world.resolve("reflect.tests.D"); + assertEquals(world.resolve("reflect.tests.C"), d.getSuperclass()); + } + + protected int findMethod(String name, ResolvedMember[] methods) { + for (int i = 0; i < methods.length; i++) { + if (name.equals(methods[i].getName())) { + return i; + } + } + return -1; + } + + protected int findMethod(String name, int numArgs, ResolvedMember[] methods) { + for (int i = 0; i < methods.length; i++) { + if (name.equals(methods[i].getName()) && (methods[i].getParameterTypes().length == numArgs)) { + return i; + } + } + return -1; + } + + public void testGetDeclaredMethods() { + ResolvedMember[] methods = objectType.getDeclaredMethods(); + assertEquals(Object.class.getDeclaredMethods().length + Object.class.getDeclaredConstructors().length, methods.length); + + ResolvedType c = world.resolve("reflect.tests.C"); + methods = c.getDeclaredMethods(); + assertEquals(3, methods.length); + int idx = findMethod("foo", methods); + assertTrue(idx > -1); + + assertEquals(world.resolve("java.lang.String"), methods[idx].getReturnType()); + assertEquals(1, methods[idx].getParameterTypes().length); + assertEquals(objectType, methods[idx].getParameterTypes()[0]); + assertEquals(1, methods[idx].getExceptions().length); + assertEquals(world.resolve("java.lang.Exception"), methods[idx].getExceptions()[0]); + int baridx = findMethod("bar", methods); + int initidx = findMethod("", methods); + assertTrue(baridx > -1); + assertTrue(initidx > -1); + assertTrue(baridx != initidx && baridx != idx && idx <= 2 && initidx <= 2 && baridx <= 2); + + ResolvedType d = world.resolve("reflect.tests.D"); + methods = d.getDeclaredMethods(); + assertEquals(2, methods.length); + + classType = world.resolve("java.lang.Class"); + methods = classType.getDeclaredMethods(); + assertEquals(Class.class.getDeclaredMethods().length + Class.class.getDeclaredConstructors().length, methods.length); + } + + public void testGetDeclaredFields() { + ResolvedMember[] fields = objectType.getDeclaredFields(); + assertEquals(0, fields.length); + + ResolvedType c = world.resolve("reflect.tests.C"); + fields = c.getDeclaredFields(); + + assertEquals(2, fields.length); + assertEquals("f", fields[0].getName()); + assertEquals("s", fields[1].getName()); + assertEquals(UnresolvedType.INT, fields[0].getReturnType()); + assertEquals(world.resolve("java.lang.String"), fields[1].getReturnType()); + } + + public void testGetDeclaredInterfaces() { + ResolvedType[] interfaces = objectType.getDeclaredInterfaces(); + assertEquals(0, interfaces.length); + + ResolvedType d = world.resolve("reflect.tests.D"); + interfaces = d.getDeclaredInterfaces(); + assertEquals(1, interfaces.length); + assertEquals(world.resolve("java.io.Serializable"), interfaces[0]); + } + + public void testGetDeclaredPointcuts() { + ResolvedMember[] pointcuts = objectType.getDeclaredPointcuts(); + assertEquals(0, pointcuts.length); + } + + public void testSerializableSuperclass() { + ResolvedType serializableType = world.resolve("java.io.Serializable"); + ResolvedType superType = serializableType.getSuperclass(); + assertTrue("Superclass of serializable should be Object but was " + superType, superType.equals(UnresolvedType.OBJECT)); + + BcelWorld bcelworld = new BcelWorld(); + bcelworld.setBehaveInJava5Way(true); + ResolvedType bcelSupertype = bcelworld.resolve(UnresolvedType.SERIALIZABLE).getSuperclass(); + assertTrue("Should be null but is " + bcelSupertype, bcelSupertype.equals(UnresolvedType.OBJECT)); + } + + public void testSubinterfaceSuperclass() { + ResolvedType ifaceType = world.resolve("java.security.Key"); + ResolvedType superType = ifaceType.getSuperclass(); + assertTrue("Superclass should be Object but was " + superType, superType.equals(UnresolvedType.OBJECT)); + + BcelWorld bcelworld = new BcelWorld(); + bcelworld.setBehaveInJava5Way(true); + ResolvedType bcelSupertype = bcelworld.resolve("java.security.Key").getSuperclass(); + assertTrue("Should be null but is " + bcelSupertype, bcelSupertype.equals(UnresolvedType.OBJECT)); + } + + public void testVoidSuperclass() { + ResolvedType voidType = world.resolve(Void.TYPE); + ResolvedType superType = voidType.getSuperclass(); + assertNull(superType); + + BcelWorld bcelworld = new BcelWorld(); + bcelworld.setBehaveInJava5Way(true); + ResolvedType bcelSupertype = bcelworld.resolve("void").getSuperclass(); + assertTrue("Should be null but is " + bcelSupertype, bcelSupertype == null); + } + + public void testIntSuperclass() { + ResolvedType voidType = world.resolve(Integer.TYPE); + ResolvedType superType = voidType.getSuperclass(); + assertNull(superType); + + BcelWorld bcelworld = new BcelWorld(); + bcelworld.setBehaveInJava5Way(true); + ResolvedType bcelSupertype = bcelworld.resolve("int").getSuperclass(); + assertTrue("Should be null but is " + bcelSupertype, bcelSupertype == null); + } + + public void testGenericInterfaceSuperclass_BcelWorldResolution() { + BcelWorld bcelworld = new BcelWorld(); + bcelworld.setBehaveInJava5Way(true); + + UnresolvedType javaUtilMap = UnresolvedType.forName("java.util.Map"); + + ReferenceType rawType = (ReferenceType) bcelworld.resolve(javaUtilMap); + assertTrue("Should be the raw type ?!? " + rawType.getTypekind(), rawType.isRawType()); + + ReferenceType genericType = (ReferenceType) rawType.getGenericType(); + assertTrue("Should be the generic type ?!? " + genericType.getTypekind(), genericType.isGenericType()); + + ResolvedType rt = rawType.getSuperclass(); + assertTrue("Superclass for Map raw type should be Object but was " + rt, rt.equals(UnresolvedType.OBJECT)); + + ResolvedType rt2 = genericType.getSuperclass(); + assertTrue("Superclass for Map generic type should be Object but was " + rt2, rt2.equals(UnresolvedType.OBJECT)); + } + + // FIXME asc maybe. The reflection list of methods returned doesn't include (the static initializer) ... is that really + // a problem. + public void testCompareSubclassDelegates() { + + boolean barfIfClinitMissing = false; + world.setBehaveInJava5Way(true); + + BcelWorld bcelWorld = new BcelWorld(getClass().getClassLoader(), IMessageHandler.THROW, null); + bcelWorld.setBehaveInJava5Way(true); + UnresolvedType javaUtilHashMap = UnresolvedType.forName("java.util.HashMap"); + ReferenceType rawType = (ReferenceType) bcelWorld.resolve(javaUtilHashMap); + + ReferenceType rawReflectType = (ReferenceType) world.resolve(javaUtilHashMap); + ResolvedMember[] rms1 = rawType.getDelegate().getDeclaredMethods(); + ResolvedMember[] rms2 = rawReflectType.getDelegate().getDeclaredMethods(); + StringBuffer errors = new StringBuffer(); + Set one = new HashSet(); + for (int i = 0; i < rms1.length; i++) { + one.add(rms1[i].toString()); + } + Set two = new HashSet(); + for (int i = 0; i < rms2.length; i++) { + two.add(rms2[i].toString()); + } + for (int i = 0; i < rms2.length; i++) { + if (!one.contains(rms2[i].toString())) { + errors.append("Couldn't find " + rms2[i].toString() + " in the bcel set\n"); + } + } + for (int i = 0; i < rms1.length; i++) { + if (!two.contains(rms1[i].toString())) { + if (!barfIfClinitMissing && rms1[i].getName().equals("")) + continue; + errors.append("Couldn't find " + rms1[i].toString() + " in the reflection set\n"); + } + } + assertTrue("Errors:" + errors.toString(), errors.length() == 0); + + // the good old ibm vm seems to offer clinit through its reflection support (see pr145322) + if (rms1.length == rms2.length) + return; + if (barfIfClinitMissing) { + // the numbers must be exact + assertEquals(rms1.length, rms2.length); + } else { + // the numbers can be out by one in favour of bcel + if (rms1.length != (rms2.length + 1)) { + for (int i = 0; i < rms1.length; i++) { + System.err.println("bcel" + i + " is " + rms1[i]); + } + for (int i = 0; i < rms2.length; i++) { + System.err.println("refl" + i + " is " + rms2[i]); + } + } + assertTrue("Should be one extra (clinit) in BCEL case, but bcel=" + rms1.length + " reflect=" + rms2.length, + rms1.length == rms2.length + 1); + } + } + + public void testArrayArgsSig() throws Exception { + Method invokeMethod = Method.class.getMethod("invoke", new Class[] { Object.class, Object[].class }); + ResolvedMember reflectionMethod = ReflectionBasedReferenceTypeDelegateFactory.createResolvedMethod(invokeMethod, world); + String exp = "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"; + assertTrue("Expected: \n" + exp + "\n but got:\n" + reflectionMethod.getSignature(), reflectionMethod.getSignature() + .equals(exp)); + } + + // todo: array of int + + protected void setUp() throws Exception { + world = new ReflectionWorld(getClass().getClassLoader()); + objectType = world.resolve("java.lang.Object"); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldReferenceTypeTest.java b/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldReferenceTypeTest.java new file mode 100644 index 000000000..720c88289 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldReferenceTypeTest.java @@ -0,0 +1,27 @@ +/* ******************************************************************* + * Copyright (c) 2002-2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.reflect; + +import org.aspectj.weaver.CommonReferenceTypeTests; +import org.aspectj.weaver.World; + +public class ReflectionWorldReferenceTypeTest extends CommonReferenceTypeTests { + + protected boolean getSupportsAutoboxing() { + return true; + } + + public World getWorld() { + return new ReflectionWorld(false, getClass().getClassLoader()); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldTest.java b/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldTest.java new file mode 100644 index 000000000..ede4e26d1 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldTest.java @@ -0,0 +1,290 @@ +/* ******************************************************************* + * Copyright (c) 2005,2017 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 + * ******************************************************************/ +package org.aspectj.weaver.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.List; +import java.util.Map; + +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.weaver.ReferenceType; +import org.aspectj.weaver.ResolvedMember; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.UnresolvedType; +import org.aspectj.weaver.WeakClassLoaderReference; +import org.aspectj.weaver.World; +import org.aspectj.weaver.bcel.BcelWorld; + +import junit.framework.TestCase; + +/** + * @author Andy Clement + * @author Adrian Colyer + */ +public class ReflectionWorldTest extends TestCase { + + public void testDelegateCreation() { + World world = new ReflectionWorld(getClass().getClassLoader()); + ResolvedType rt = world.resolve("java.lang.Object"); + assertNotNull(rt); + assertEquals("Ljava/lang/Object;", rt.getSignature()); + } + + // Removed for now. In Spring the reflection worlds are customized by introducing new + // PCD handlers. It means more thought needs to be put into reusing worlds. + public void xtestReflectionWorldFactory() throws Exception { + ClassLoader parent = getClass().getClassLoader(); + ClassLoader cl1 = new URLClassLoader(new URL[] {}, parent); + ClassLoader cl2 = new URLClassLoader(new URL[] {}, parent); + + WeakClassLoaderReference wcl1 = new WeakClassLoaderReference(cl1); + WeakClassLoaderReference wcl2 = new WeakClassLoaderReference(cl2); + ReflectionWorld a = ReflectionWorld.getReflectionWorldFor(wcl1); + + ResolvedType stringClass1 = a.resolve(String.class); + assertNotNull(stringClass1); + + ReflectionWorld b = ReflectionWorld.getReflectionWorldFor(wcl1); + + // They should be the same because the classloader has not gone away + assertTrue(a==b); + + cl1 = null; + for (int i=0;i<100;i++) { + System.gc(); // How robust is it that this should be causing the reference to be collected? + } + b = ReflectionWorld.getReflectionWorldFor(wcl1); + + assertFalse(a==b); + + cl1 = new URLClassLoader(new URL[] {}, parent); + wcl1 = new WeakClassLoaderReference(cl1); + a = ReflectionWorld.getReflectionWorldFor(wcl1); + b = ReflectionWorld.getReflectionWorldFor(wcl2); + assertFalse(a==b); + + Field declaredField = ReflectionWorld.class.getDeclaredField("rworlds"); + declaredField.setAccessible(true); + Map worlds = (Map)declaredField.get(null); + assertEquals(2, worlds.size()); + + cl2 = null; + for (int i=0;i<100;i++) { + System.gc(); // How robust is it that this should be causing the reference to be collected? + } + ReflectionWorld.getReflectionWorldFor(wcl1); // need to call this to trigger tidyup + assertEquals(1, worlds.size()); + + cl1 = null; + for (int i=0;i<100;i++) { + System.gc(); // How robust is it that this should be causing the reference to be collected? + } + ReflectionWorld.getReflectionWorldFor(wcl1); // need to call this to trigger tidyup + assertEquals(0, worlds.size()); + + cl1 = new URLClassLoader(new URL[] {}, parent); + wcl1 = new WeakClassLoaderReference(cl1); + ReflectionWorld reflectionWorldFor = ReflectionWorld.getReflectionWorldFor(wcl1); + assertEquals(1, worlds.size()); + ReflectionWorld.cleanUpWorlds(); + assertEquals(0, worlds.size()); + } + + public void testArrayTypes() { + IReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); + String[] strArray = new String[1]; + ResolvedType rt = world.resolve(strArray.getClass()); + assertTrue(rt.isArray()); + } + + public void testPrimitiveTypes() { + IReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); + assertEquals("int", UnresolvedType.INT, world.resolve(int.class)); + assertEquals("void", UnresolvedType.VOID, world.resolve(void.class)); + } + + static class AbstractSuperClass {} + static interface InterfaceOne {} + static interface InterfaceTwo {} + static class ID {} + static abstract class AbstractTestClass extends AbstractSuperClass implements InterfaceOne, InterfaceTwo { + + } + static class TestType {} +// static class ConcreteClass extends AbstractTestClass { + static class ConcreteClass extends AbstractTestClass> { + } + + static class Bar extends ConcreteClass {} + + public void testGenerics() { + ReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); +// world.lookupOrCreateName(UnresolvedType.forName(AbstractTestClass.class.getName())); +// ResolvedType resolvedType = world.resolve(AbstractTestClass.class); + JavaLangTypeToResolvedTypeConverter converter = new JavaLangTypeToResolvedTypeConverter(world); + ResolvedType resolvedType2 = converter.fromType(ConcreteClass.class); + } + + public void xtestTypeConversions_509327() throws Exception { + ReflectionWorld rWorld = new ReflectionWorld(getClass().getClassLoader()); + JavaLangTypeToResolvedTypeConverter converter = new JavaLangTypeToResolvedTypeConverter(rWorld); + + // Check basic conversion of String to String + Method method = TestClass.class.getDeclaredMethod("m"); + Type stringType = method.getGenericReturnType(); + assertEquals("java.lang.String",stringType.getTypeName()); + ResolvedType stringResolvedType = converter.fromType(stringType); + assertEquals("java.lang.String",stringResolvedType.getName()); + + // public String m() { return ""; } + method = TestClass2.class.getDeclaredMethod("m"); + stringType = method.getGenericReturnType(); + assertEquals("java.lang.String",stringType.getTypeName()); + stringResolvedType = converter.fromType(stringType); + assertEquals("java.lang.String",stringResolvedType.getName()); + + // Verify that the conversion process creates the same thing as the bcel unpacking + + // Here the return type is a non-static inner of a generic class + // public Inner m2() { return null; } + method = TestClass2.class.getDeclaredMethod("m2"); + Type innerType = method.getGenericReturnType(); + assertEquals("org.aspectj.weaver.reflect.ReflectionWorldTest.org.aspectj.weaver.reflect.ReflectionWorldTest$TestClass2.Inner",innerType.getTypeName()); + ResolvedType rType_Inner = converter.fromType(innerType); + assertEquals("Lorg/aspectj/weaver/reflect/ReflectionWorldTest$TestClass2$Inner;",rType_Inner.getSignature()); + assertEquals(UnresolvedType.TypeKind.SIMPLE,rType_Inner.getTypekind()); + ResolvedType rType_Outer = rType_Inner.getOuterClass(); + assertEquals("Lorg/aspectj/weaver/reflect/ReflectionWorldTest$TestClass2;",rType_Outer.getSignature()); + + BcelWorld bWorld = new BcelWorld(getClass().getClassLoader(), IMessageHandler.THROW, null); + bWorld.setBehaveInJava5Way(true); + UnresolvedType javaUtilHashMap = UnresolvedType.forName("java.util.HashMap"); + ReferenceType rawType = (ReferenceType) bWorld.resolve(javaUtilHashMap); + assertNotNull(rawType); + + // Now use bcel to resolve the same m2 method, and compare the signatures of the return types + ResolvedType bResolved_TestClass2 = bWorld.resolve(UnresolvedType.forName(TestClass2.class.getName())); + assertNotNull(bResolved_TestClass2); + ResolvedMember bMethod_m2 = findMethod(bResolved_TestClass2,"m2"); + ResolvedType bType_Inner = (ResolvedType) bMethod_m2.getReturnType(); + assertEquals("Lorg/aspectj/weaver/reflect/ReflectionWorldTest$TestClass2$Inner;",bType_Inner.getSignature()); + assertEquals(UnresolvedType.TypeKind.SIMPLE,bType_Inner.getTypekind()); + ResolvedType bType_Outer = bType_Inner.getOuterClass(); + assertEquals("Lorg/aspectj/weaver/reflect/ReflectionWorldTest$TestClass2;",bType_Outer.getSignature()); + + assertEquals(bType_Inner.getSignature(),rType_Inner.getSignature()); + assertEquals(bType_Outer.getSignature(),rType_Outer.getSignature()); + } + + + public void xtestTypeConversions_509327_2() throws Exception { + ReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); + JavaLangTypeToResolvedTypeConverter converter = new JavaLangTypeToResolvedTypeConverter(world); + BcelWorld bWorld = new BcelWorld(getClass().getClassLoader(), IMessageHandler.THROW, null); + bWorld.setBehaveInJava5Way(true); + + // Slightly more advanced, now the method is returning a parameterized form of the outer + // generic class + + // public TestClass2.Inner m3() { return new TestClass2.Inner("Foo"); } + Method method = TestClass2.class.getDeclaredMethod("m3"); + Type type_ParameterizedInner = method.getGenericReturnType(); + assertEquals("org.aspectj.weaver.reflect.ReflectionWorldTest.org.aspectj.weaver.reflect.ReflectionWorldTest$TestClass2.Inner",type_ParameterizedInner.getTypeName()); + ResolvedType rType_ParameterizedInner = converter.fromType(type_ParameterizedInner); + // NOTE: DECLARED PARAMETERIZATION OF OUTER IS LOST + assertEquals("Lorg/aspectj/weaver/reflect/ReflectionWorldTest$TestClass2$Inner;",rType_ParameterizedInner.getSignature()); + + ResolvedType bResolved_TestClass2 = bWorld.resolve(UnresolvedType.forName(TestClass2.class.getName())); + assertNotNull(bResolved_TestClass2); + ResolvedMember bMethod_m3 = findMethod(bResolved_TestClass2,"m3"); + ResolvedType bType_Inner = (ResolvedType) bMethod_m3.getReturnType(); + // NOTE: DECLARED PARAMETERIZATION OF OUTER IS LOST + assertEquals("Lorg/aspectj/weaver/reflect/ReflectionWorldTest$TestClass2$Inner;",bType_Inner.getSignature()); + + assertEquals(UnresolvedType.TypeKind.SIMPLE,bType_Inner.getTypekind()); + ResolvedType bType_Outer = bType_Inner.getOuterClass(); + + // Fields seem to lose it too, although the backinggenericmember has the info +// ResolvedMember bField_f = findField(bResolved_TestClass2,"f"); +// ResolvedMember backingGenericMember = bField_f.getBackingGenericMember(); +// System.out.println(backingGenericMember); +// System.out.println(backingGenericMember.getGenericReturnType()); +// System.out.println(bField_f); +// System.out.println(bField_f.getSignature()); +// System.out.println(bField_f.getGenericReturnType()); + } + +// public void testbar() throws Exception { +// ReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); +// JavaLangTypeToResolvedTypeConverter converter = new JavaLangTypeToResolvedTypeConverter(world); +// +// // public TestClass2.Inner m3() { return new TestClass2.Inner("Foo"); } +// Method method = TestClass2.class.getDeclaredMethod("m3"); +// Type type_ParameterizedInner = method.getGenericReturnType(); +// assertEquals("org.aspectj.weaver.reflect.ReflectionWorldTest.org.aspectj.weaver.reflect.ReflectionWorldTest$TestClass2.Inner",type_ParameterizedInner.getTypeName()); +// ResolvedType rType_ParameterizedInner = converter.fromType(type_ParameterizedInner); +// System.out.println(rType_ParameterizedInner); +// System.out.println(type_ParameterizedInner.getTypeName()); +// } +// +// public void testfoo() { +// ReflectionWorld world = new ReflectionWorld(getClass().getClassLoader()); +// JavaLangTypeToResolvedTypeConverter converter = new JavaLangTypeToResolvedTypeConverter(world); +// BcelWorld bWorld = new BcelWorld(getClass().getClassLoader(), IMessageHandler.THROW, null); +// bWorld.setBehaveInJava5Way(true); +// +// +// ResolvedType bResolved_TestClass2 = bWorld.resolve(UnresolvedType.forName(TestClass2.class.getName())); +// ResolvedMember bField_f = findField(bResolved_TestClass2,"f"); +// System.out.println(bField_f); +// System.out.println(bField_f.getGenericReturnType()); +// System.out.println(bField_f.getReturnType()); +// System.out.println(bField_f.getBackingGenericMember().getGenericReturnType()); +// } + + static class TestClass { + public String m() { return ""; } + } + + static class TestClass2 { + class Inner { + T t; + Inner(T t) { + this.t = t; + } + } + public String m() { return ""; } + public Inner m2() { return null; } + public TestClass2 f; + public TestClass2.Inner m3() { return new TestClass2.Inner("Foo"); } + } + + private ResolvedMember findMethod(ResolvedType resolvedType, String methodName) { + for (ResolvedMember method: resolvedType.getDeclaredMethods()) { + if (method.getName().equals(methodName)) { + return method; + } + } + return null; + } + + private ResolvedMember findField(ResolvedType resolvedType, String fieldName) { + for (ResolvedMember field: resolvedType.getDeclaredFields()) { + if (field.getName().equals(fieldName)) { + return field; + } + } + return null; + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java new file mode 100644 index 000000000..f651a2f29 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java @@ -0,0 +1,746 @@ +/* ******************************************************************* + * 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; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.StringTokenizer; + +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.internal.tools.PointcutExpressionImpl; +import org.aspectj.weaver.patterns.AbstractPatternNodeVisitor; +import org.aspectj.weaver.patterns.AndAnnotationTypePattern; +import org.aspectj.weaver.patterns.AnnotationPatternList; +import org.aspectj.weaver.patterns.AnyAnnotationTypePattern; +import org.aspectj.weaver.patterns.BindingAnnotationTypePattern; +import org.aspectj.weaver.patterns.ExactAnnotationTypePattern; +import org.aspectj.weaver.patterns.KindedPointcut; +import org.aspectj.weaver.patterns.NotAnnotationTypePattern; +import org.aspectj.weaver.patterns.OrAnnotationTypePattern; +import org.aspectj.weaver.patterns.SignaturePattern; +import org.aspectj.weaver.patterns.TypePattern; +import org.aspectj.weaver.patterns.TypePatternList; +import org.aspectj.weaver.patterns.WildAnnotationTypePattern; + +import test.A1AnnotatedType; +import test.A2AnnotatedType; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Test parameter pointcut parsing. Extended by Andy Clement to cover parameter annotation matching. + * + */ +public class Java15PointcutExpressionTest extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite("Java15PointcutExpressionTest"); + suite.addTestSuite(Java15PointcutExpressionTest.class); + return suite; + } + + private PointcutParser parser; + private Method a; + private Method b; + private Method c; + private Method d; + + /** + * Parse some expressions and ensure we capture the parameter annotations and parameter type annotations correctly. + * Buckle up, this will get complicated ;) + */ + public void testParseParameterAnnotationExpressions() { + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + PointcutExpression pexpr = null; + + pexpr = p.parsePointcutExpression("execution(public void foo(@MA *))"); + checkParameterAnnotations(pexpr,0,null,"@MA","exact[@MA:t]"); + + pexpr = p.parsePointcutExpression("execution(public void foo(@MA (*)))"); + checkParameterAnnotations(pexpr,0,"@MA",null,"exact[@MA:p]"); + + pexpr = p.parsePointcutExpression("execution(public void foo(@MA @MB *))"); + checkParameterAnnotations(pexpr,0,null,"@MA @MB","(exact[@MA:t] and exact[@MB:t])"); + + pexpr = p.parsePointcutExpression("execution(public void foo(@MA (@MB *)))"); + checkParameterAnnotations(pexpr,0,"@MA","@MB","(exact[@MA:p] and exact[@MB:t])"); + + pexpr = p.parsePointcutExpression("execution(public void foo(@MA @MB (@MC *)))"); + checkParameterAnnotations(pexpr,0,"@MA @MB","@MC","((exact[@MA:p] and exact[@MB:p]) and exact[@MC:t])"); + + pexpr = p.parsePointcutExpression("execution(public void foo(@MA (@MB @MC @MD *)))"); + checkParameterAnnotations(pexpr,0,"@MA","@MB @MC @MD","(exact[@MA:p] and ((exact[@MB:t] and exact[@MC:t]) and exact[@MD:t]))"); + + pexpr = p.parsePointcutExpression("execution(public void foo(@(MA || MB) (@MC @MD *)))"); + checkParameterAnnotations(pexpr,0,null/*Should be MA MB */,"@MC @MD","(wild[(MA || MB)] and (exact[@MC:t] and exact[@MD:t]))"); // I dont think WildAnnotationTypePatterns work properly... + + pexpr = p.parsePointcutExpression("execution(public void foo(@MA (@MB *),(@MC *),@MD (*)))"); + checkParameterAnnotations(pexpr,0,"@MA","@MB","(exact[@MA:p] and exact[@MB:t])"); + checkParameterAnnotations(pexpr,1,null,"@MC","exact[@MC:t]"); + checkParameterAnnotations(pexpr,2,"@MD",null,"exact[@MD:p]"); + + } + + public void testMatchingAnnotationValueExpressions() throws SecurityException, NoSuchMethodException { + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + PointcutExpression pexpr = null; + ShadowMatch match = null; + + Method n = test.AnnoValues.class.getMethod("none"); + Method r = test.AnnoValues.class.getMethod("redMethod"); + Method g = test.AnnoValues.class.getMethod("greenMethod"); + Method b = test.AnnoValues.class.getMethod("blueMethod"); + Method d = test.AnnoValues.class.getMethod("defaultMethod"); + + pexpr = p.parsePointcutExpression("execution(@test.A3(test.Color.RED) public void *(..))"); + assertTrue("Should match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED + assertTrue("Should match", pexpr.matchesMethodExecution(r).alwaysMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(d).alwaysMatches()); + + pexpr = p.parsePointcutExpression("execution(@test.A3(test.Color.GREEN) public void *(..))"); + assertTrue("Should not match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED + assertTrue("Should not match", pexpr.matchesMethodExecution(r).neverMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(d).neverMatches()); + + pexpr = p.parsePointcutExpression("execution(@test.A3(test.Color.BLUE) public void *(..))"); + assertTrue("Should not match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED + assertTrue("Should not match", pexpr.matchesMethodExecution(r).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(d).neverMatches()); + + pexpr = p.parsePointcutExpression("execution(@test.A3 public void *(..))"); + assertTrue("Should match", pexpr.matchesMethodExecution(n).neverMatches()); // default value RED + assertTrue("Should match", pexpr.matchesMethodExecution(r).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(d).alwaysMatches()); + + } + + private static final Set DEFAULT_SUPPORTED_PRIMITIVES = new HashSet(); + + static { + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.ARGS); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.REFERENCE); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.THIS); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.TARGET); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.WITHIN); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ANNOTATION); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_WITHIN); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_ARGS); + DEFAULT_SUPPORTED_PRIMITIVES.add(PointcutPrimitive.AT_TARGET); + } + + public void testPerformanceOfPointcutParsing() { + String expression = "execution(public * rewards.internal.*.*Repository+.*(..))"; + long stime1 = System.currentTimeMillis(); + PointcutParser parser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingContextClassloaderForResolution(DEFAULT_SUPPORTED_PRIMITIVES); + long stime2 = System.currentTimeMillis(); + PointcutExpression pointcutExpression = parser.parsePointcutExpression(expression, null, new PointcutParameter[0]); + long etime = System.currentTimeMillis(); + System.out.println("Time to get a parser "+(stime2-stime1)+"ms"); + System.out.println("Time taken to parse expression is "+(etime-stime2)+"ms"); + } + + + public void testPerformanceOfPointcutParsingWithBean() { + String expression = "execution(public * rewards.internal.*.*Repository+.*(..))"; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + long stime = System.currentTimeMillis(); + PointcutExpression pointcutExpression = parser.parsePointcutExpression(expression, null, new PointcutParameter[0]); + long etime = System.currentTimeMillis(); + System.out.println("Time taken to parse expression is "+(etime-stime)+"ms"); + } + + private class BeanDesignatorHandler implements PointcutDesignatorHandler { + + private String askedToParse; + public boolean simulateDynamicTest = false; + + public String getDesignatorName() { + return "bean"; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.tools.PointcutDesignatorHandler#parse(java.lang.String) + */ + public ContextBasedMatcher parse(String expression) { + this.askedToParse = expression; + return null; +// return new BeanPointcutExpression(expression,this.simulateDynamicTest); + } + + public String getExpressionLastAskedToParse() { + return this.askedToParse; + } + } + + + /** + * Test matching of pointcuts against expressions. A reflection world is being used on the backend here (not a Bcel one). + */ + public void testMatchingParameterAnnotationExpressions() throws SecurityException, NoSuchMethodException { + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + PointcutExpression pexpr = null; + ShadowMatch match = null; + + Method a = test.A.class.getMethod("a",new Class[] {String.class}); // public void a(String s) {} + Method b = test.A.class.getMethod("b",new Class[] {String.class}); // public void b(@A1 String s) {} + Method c = test.A.class.getMethod("c",new Class[] {String.class}); // public void c(@A1 @A2 String s) {} +// Method d = test.A.class.getMethod("d",new Class[] {String.class,String.class});// public void d(@A1 String s,@A2 String t) {} + + Method e = test.A.class.getMethod("e",new Class[] {A1AnnotatedType.class}); // public void e(A1AnnotatedType s) {} + Method f = test.A.class.getMethod("f",new Class[] {A2AnnotatedType.class}); // public void f(A2AnnotatedType s) {} + Method g = test.A.class.getMethod("g",new Class[] {A1AnnotatedType.class}); // public void g(@A2 A1AnnotatedType s) {} + Method h = test.A.class.getMethod("h",new Class[] {A1AnnotatedType.class}); // public void h(@A1 A1AnnotatedType s) {} +// Method i = test.A.class.getMethod("i",new Class[] {A1AnnotatedType.class,String.class}); // public void i(A1AnnotatedType s,@A2 String t) {} +// Method j = test.A.class.getMethod("j",new Class[] {String.class}); // public void j(@A1 @A2 String s) {} + + pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 *))"); + assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(c).neverMatches()); + + pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 (*)))"); + assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(c).alwaysMatches()); + + pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 *))"); + assertTrue("Should match", pexpr.matchesMethodExecution(e).alwaysMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(f).neverMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(h).alwaysMatches()); + + pexpr = p.parsePointcutExpression("execution(public void *(@test.A1 (*)))"); + assertTrue("Should not match", pexpr.matchesMethodExecution(e).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(f).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(h).alwaysMatches()); + + pexpr = p.parsePointcutExpression("execution(public void *(@(test.A1 || test.A2) (*)))"); + assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(b).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(c).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(g).alwaysMatches()); + assertTrue("Should match", pexpr.matchesMethodExecution(h).alwaysMatches()); + + pexpr = p.parsePointcutExpression("execution(public void *(@(test.A1 && test.A2) (*),..))"); + assertTrue("Should not match", pexpr.matchesMethodExecution(a).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(b).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(c).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(g).neverMatches()); + assertTrue("Should not match", pexpr.matchesMethodExecution(h).neverMatches()); +// assertTrue("Should match", pexpr.matchesMethodExecution(j).alwaysMatches()); // should match but does not, broken implementation, old bug - see WildAnnotationTypePattern.match + + + + } + + private void checkParameterAnnotations(PointcutExpression pe,int parameterNumber,String expectedParameterAnnotations,String expectedParameterTypeAnnotations,String expectedNodeStructure) { + org.aspectj.weaver.patterns.Pointcut p = ((PointcutExpressionImpl)pe).getUnderlyingPointcut(); + KindedPointcut kindedP = (KindedPointcut)p; + SignaturePattern sp = kindedP.getSignature(); + TypePatternList tpl = sp.getParameterTypes(); + TypePattern[] tps = tpl.getTypePatterns(); + + // A visitor over the annotation pattern for the parameter will break it down into parameter vs parameter type annotations + MyPatternNodeVisitor mpnv = new MyPatternNodeVisitor(); + tps[parameterNumber].getAnnotationPattern().accept(mpnv,null); + + if (expectedNodeStructure==null) { + // The caller hasn't worked it out yet!! + System.out.println(mpnv.getStringRepresentation()); + } else if (!mpnv.getStringRepresentation().equals(expectedNodeStructure)) { + System.out.println(mpnv.getStringRepresentation()); + fail("Expected annotation pattern node structure for expression "+pe.getPointcutExpression()+ + " was '"+expectedNodeStructure+"' but it turned out to be '"+mpnv.getStringRepresentation()+"'"); + } + + tps[parameterNumber].getAnnotationPattern().toString(); + + // parameter type annotation checking + Set expected = new HashSet(); + expected.addAll(mpnv.getParameterTypeAnnotations()); + + StringTokenizer st = new StringTokenizer(expectedParameterTypeAnnotations==null?"":expectedParameterTypeAnnotations); + while (st.hasMoreTokens()) { + String nextToken = st.nextToken(); + if (!expected.contains(nextToken)) + fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern did not include parameter type annotation "+nextToken+". It's full set was "+mpnv.getParameterTypeAnnotations()); + expected.remove(nextToken); + } + if (expected.size()>0) { // we have excess ones! + StringBuffer excessTokens = new StringBuffer(); + for (Iterator iterator = expected.iterator(); iterator.hasNext();) { + String string = (String) iterator.next(); + excessTokens.append(string).append(" "); + } + fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern has these unexpected parameter type annotations "+excessTokens.toString()); + } + + // parameter annotation checking + expected = new HashSet(); + expected.addAll(mpnv.getParameterAnnotations()); + + st = new StringTokenizer(expectedParameterAnnotations==null?"":expectedParameterAnnotations); + while (st.hasMoreTokens()) { + String nextToken = st.nextToken(); + if (!expected.contains(nextToken)) + fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern did not include parameter annotation "+nextToken+". It's full set was "+mpnv.getParameterAnnotations()); + expected.remove(nextToken); + } + if (expected.size()>0) { // we have excess ones! + StringBuffer excessTokens = new StringBuffer(); + for (Iterator iterator = expected.iterator(); iterator.hasNext();) { + String string = (String) iterator.next(); + excessTokens.append(string).append(" "); + } + fail("In pointcut expression "+pe.getPointcutExpression()+" parameter "+parameterNumber+". The annotation type pattern has these unexpected parameter annotations "+excessTokens.toString()); + } + + } + + static class MyPatternNodeVisitor extends AbstractPatternNodeVisitor { + private StringBuffer stringRep = new StringBuffer(); + private List parameterAnnotations = new ArrayList(); + private List parameterTypeAnnotations = new ArrayList(); + + public String getStringRepresentation() { return stringRep.toString(); } + public List getParameterAnnotations() { return parameterAnnotations; } + public List getParameterTypeAnnotations() { return parameterTypeAnnotations; } + + public Object visit(AndAnnotationTypePattern node, Object data) { + stringRep.append("("); + node.getLeft().accept(this, data); + stringRep.append(" and "); + node.getRight().accept(this, data); + stringRep.append(")"); + return node; + } + public Object visit(AnyAnnotationTypePattern node, Object data) { + stringRep.append("any"); + return node; + } + public Object visit(ExactAnnotationTypePattern node, Object data) { + stringRep.append("exact["+stringify(node.getResolvedAnnotationType())+":"+(node.isForParameterAnnotationMatch()?"p":"t")+"]"); + if (node.isForParameterAnnotationMatch()) { + parameterAnnotations.add(stringify(node.getResolvedAnnotationType())); + } else { + parameterTypeAnnotations.add(stringify(node.getResolvedAnnotationType())); + } + return node; + } + private String stringify(ResolvedType resolvedAnnotationType) { + return "@"+resolvedAnnotationType.getSimpleName(); + } + + public Object visit(BindingAnnotationTypePattern node, Object data) { + stringRep.append("binding"); + + return node; + } + public Object visit(NotAnnotationTypePattern node, Object data) { + stringRep.append("not"); + return node; + } + public Object visit(OrAnnotationTypePattern node, Object data) { + stringRep.append("("); + node.getLeft().accept(this, data); + stringRep.append(" or "); + node.getRight().accept(this, data); + stringRep.append(")"); + return node; + } + public Object visit(WildAnnotationTypePattern node, Object data) { + stringRep.append("wild["); + stringRep.append(node.getTypePattern().toString()); + stringRep.append("]"); + return node; + } + public Object visit(AnnotationPatternList node, Object data) { + stringRep.append("list"); + + return node; + } + + + } + + + + public void testAtThis() { + PointcutExpression atThis = parser.parsePointcutExpression("@this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); + ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); + assertTrue("matches",jp2.matches()); + } + + public void testAtTarget() { + PointcutExpression atTarget = parser.parsePointcutExpression("@target(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atTarget.matchesMethodExecution(a); + ShadowMatch sMatch2 = atTarget.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); + assertTrue("matches",jp2.matches()); + } + + public void testAtThisWithBinding() { + PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class); + B myB = new B(); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + PointcutExpression atThis = parser.parsePointcutExpression("@this(a)",A.class,new PointcutParameter[] {param}); + ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); + ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]); + assertTrue("matches",jp2.matches()); + assertEquals(1,jp2.getParameterBindings().length); + assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + } + + public void testAtTargetWithBinding() { + PointcutParameter param = parser.createPointcutParameter("a",MyAnnotation.class); + B myB = new B(); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + PointcutExpression atThis = parser.parsePointcutExpression("@target(a)",A.class,new PointcutParameter[] {param}); + ShadowMatch sMatch1 = atThis.matchesMethodExecution(a); + ShadowMatch sMatch2 = atThis.matchesMethodExecution(b); + assertTrue("maybe matches A",sMatch1.maybeMatches()); + assertTrue("maybe matches B",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new A(), new A(), new Object[0]); + assertFalse("does not match",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(myB, myB, new Object[0]); + assertTrue("matches",jp2.matches()); + assertEquals(1,jp2.getParameterBindings().length); + assertEquals("should be myB's annotation",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + } + + public void testAtArgs() { + PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atArgs.matchesMethodExecution(a); + ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("never matches A",sMatch1.neverMatches()); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()}); + assertTrue("matches",jp2.matches()); + + atArgs = parser.parsePointcutExpression("@args(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation,org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + sMatch1 = atArgs.matchesMethodExecution(a); + sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("never matches A",sMatch1.neverMatches()); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch2.matchesJoinPoint(new A(), new A(), new Object[] {new A(), new B()}); + assertFalse("does not match",jp1.matches()); + jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()}); + assertTrue("matches",jp2.matches()); + } + + public void testAtArgs2() { + PointcutExpression atArgs = parser.parsePointcutExpression("@args(*, org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atArgs.matchesMethodExecution(c); + ShadowMatch sMatch2 = atArgs.matchesMethodExecution(d); + assertTrue("maybe matches c",sMatch1.maybeMatches()); + assertTrue("maybe matches d",sMatch2.maybeMatches()); + JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new B(), new B(), new Object[] {new A(), new B()}); + assertTrue("matches",jp1.matches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new A(),new A()}); + assertFalse("does not match",jp2.matches()); + } + + public void testAtArgsWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("a",MyAnnotation.class); + PointcutParameter p2 = parser.createPointcutParameter("b", MyAnnotation.class); + PointcutExpression atArgs = parser.parsePointcutExpression("@args(..,a)",A.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[]{new A(),new B()}); + assertTrue("matches",jp2.matches()); + assertEquals(1,jp2.getParameterBindings().length); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + + atArgs = parser.parsePointcutExpression("@args(a,b)",A.class,new PointcutParameter[] {p1,p2}); + sMatch2 = atArgs.matchesMethodExecution(c); + assertTrue("maybe matches C",sMatch2.maybeMatches()); + jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new B(),new B()}); + assertTrue("matches",jp2.matches()); + assertEquals(2,jp2.getParameterBindings().length); + assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[0].getBinding()); + assertEquals("annotation on B",bAnnotation,jp2.getParameterBindings()[1].getBinding()); + } + + public void testAtWithin() { + PointcutExpression atWithin = parser.parsePointcutExpression("@within(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a); + ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b); + assertTrue("does not match a",sMatch1.neverMatches()); + assertTrue("matches b",sMatch2.alwaysMatches()); + } + + public void testAtWithinWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); + PointcutExpression atWithin = parser.parsePointcutExpression("@within(x)",B.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch1 = atWithin.matchesMethodExecution(a); + ShadowMatch sMatch2 = atWithin.matchesMethodExecution(b); + assertTrue("does not match a",sMatch1.neverMatches()); + assertTrue("matches b",sMatch2.alwaysMatches()); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(new B(), new B(), new Object[0]); + assertTrue(jpm.matches()); + assertEquals(1,jpm.getParameterBindings().length); + MyAnnotation bAnnotation = B.class.getAnnotation(MyAnnotation.class); + assertEquals("annotation on B",bAnnotation,jpm.getParameterBindings()[0].getBinding()); + } + + public void testAtWithinCode() { + PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atWithinCode.matchesMethodCall(a,b); + ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a); + assertTrue("does not match from b",sMatch1.neverMatches()); + assertTrue("matches from a",sMatch2.alwaysMatches()); + } + + public void testAtWithinCodeWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); + PointcutExpression atWithinCode = parser.parsePointcutExpression("@withincode(x)",A.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch2 = atWithinCode.matchesMethodCall(a,a); + assertTrue("matches from a",sMatch2.alwaysMatches()); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]); + assertEquals(1,jpm.getParameterBindings().length); + MyAnnotation annOna = a.getAnnotation(MyAnnotation.class); + assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding()); + } + + public void testAtAnnotation() { + PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)"); + ShadowMatch sMatch1 = atAnnotation.matchesMethodCall(b,a); + ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a); + assertTrue("does not match call to b",sMatch1.neverMatches()); + assertTrue("matches call to a",sMatch2.alwaysMatches()); + } + + public void testAtAnnotationWithBinding() { + PointcutParameter p1 = parser.createPointcutParameter("x",MyAnnotation.class); + PointcutExpression atAnnotation = parser.parsePointcutExpression("@annotation(x)",A.class,new PointcutParameter[] {p1}); + ShadowMatch sMatch2 = atAnnotation.matchesMethodCall(a,a); + assertTrue("matches call to a",sMatch2.alwaysMatches()); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(new A(), new A(), new Object[0]); + assertTrue(jpm.matches()); + assertEquals(1,jpm.getParameterBindings().length); + MyAnnotation annOna = a.getAnnotation(MyAnnotation.class); + assertEquals("MyAnnotation on a",annOna,jpm.getParameterBindings()[0].getBinding()); + } + + public void testReferencePointcutNoParams() { + PointcutExpression pc = parser.parsePointcutExpression("foo()",C.class,new PointcutParameter[0]); + ShadowMatch sMatch1 = pc.matchesMethodCall(a,b); + ShadowMatch sMatch2 = pc.matchesMethodExecution(a); + assertTrue("no match on call",sMatch1.neverMatches()); + assertTrue("match on execution",sMatch2.alwaysMatches()); + + pc = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.C.foo()"); + sMatch1 = pc.matchesMethodCall(a,b); + sMatch2 = pc.matchesMethodExecution(a); + assertTrue("no match on call",sMatch1.neverMatches()); + assertTrue("match on execution",sMatch2.alwaysMatches()); + } + + public void testReferencePointcutParams() { + PointcutParameter p1 = parser.createPointcutParameter("x",A.class); + PointcutExpression pc = parser.parsePointcutExpression("goo(x)",C.class,new PointcutParameter[] {p1}); + + ShadowMatch sMatch1 = pc.matchesMethodCall(a,b); + ShadowMatch sMatch2 = pc.matchesMethodExecution(a); + assertTrue("no match on call",sMatch1.neverMatches()); + assertTrue("match on execution",sMatch2.maybeMatches()); + A anA = new A(); + JoinPointMatch jpm = sMatch2.matchesJoinPoint(anA, new A(), new Object[0]); + assertTrue(jpm.matches()); + assertEquals("should be bound to anA",anA,jpm.getParameterBindings()[0].getBinding()); + + } + + public void testExecutionWithClassFileRetentionAnnotation() { + PointcutExpression pc1 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation * *(..))"); + PointcutExpression pc2 = parser.parsePointcutExpression("execution(@org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyClassFileRetentionAnnotation * *(..))"); + ShadowMatch sMatch = pc1.matchesMethodExecution(a); + assertTrue("matches",sMatch.alwaysMatches()); + sMatch = pc2.matchesMethodExecution(a); + assertTrue("no match",sMatch.neverMatches()); + sMatch = pc1.matchesMethodExecution(b); + assertTrue("no match",sMatch.neverMatches()); + sMatch = pc2.matchesMethodExecution(b); + assertTrue("matches",sMatch.alwaysMatches()); + } + + public void testGenericMethodSignatures() throws Exception{ + PointcutExpression ex = parser.parsePointcutExpression("execution(* set*(java.util.List))"); + Method m = TestBean.class.getMethod("setFriends",List.class); + ShadowMatch sm = ex.matchesMethodExecution(m); + assertTrue("should match",sm.alwaysMatches()); + } + + public void testAnnotationInExecution() throws Exception { + parser.parsePointcutExpression("execution(@(org.springframework..*) * *(..))"); + } + + public void testVarArgsMatching() throws Exception { + PointcutExpression ex = parser.parsePointcutExpression("execution(* *(String...))"); + Method usesVarArgs = D.class.getMethod("varArgs",String[].class); + Method noVarArgs = D.class.getMethod("nonVarArgs", String[].class); + ShadowMatch sm1 = ex.matchesMethodExecution(usesVarArgs); + assertTrue("should match",sm1.alwaysMatches()); + ShadowMatch sm2 = ex.matchesMethodExecution(noVarArgs); + assertFalse("should not match",sm2.alwaysMatches()); + } + + public void testJavaLangMatching() throws Exception { + PointcutExpression ex = parser.parsePointcutExpression("@within(java.lang.Deprecated)"); + Method foo = GoldenOldie.class.getMethod("foo"); + ShadowMatch sm1 = ex.matchesMethodExecution(foo); + assertTrue("should match",sm1.alwaysMatches()); + } + + public void testReferencePCsInSameType() throws Exception { + PointcutExpression ex = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.c()",NamedPointcutResolution.class,new PointcutParameter[0]); + ShadowMatch sm = ex.matchesMethodExecution(a); + assertTrue("should match",sm.alwaysMatches()); + sm = ex.matchesMethodExecution(b); + assertTrue("does not match",sm.neverMatches()); + } + + public void testReferencePCsInOtherType() throws Exception { + PointcutExpression ex = parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.ExternalReferrer.d()",ExternalReferrer.class,new PointcutParameter[0]); + ShadowMatch sm = ex.matchesMethodExecution(a); + assertTrue("should match",sm.alwaysMatches()); + sm = ex.matchesMethodExecution(b); + assertTrue("does not match",sm.neverMatches()); + } + + public void testArrayTypeInArgs() throws Exception { + PointcutParameter[] params = new PointcutParameter[3]; + params[0] = parser.createPointcutParameter("d", Date.class); + params[1] = parser.createPointcutParameter("s", String.class); + params[2] = parser.createPointcutParameter("ss", String[].class); + parser.parsePointcutExpression("org.aspectj.weaver.tools.Java15PointcutExpressionTest.UsesArrays.pc(d,s,ss)",UsesArrays.class,params); + } + + protected void setUp() throws Exception { + super.setUp(); + parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + a = A.class.getMethod("a"); + b = B.class.getMethod("b"); + c = B.class.getMethod("c",new Class[] {A.class,B.class}); + d = B.class.getMethod("d",new Class[] {A.class,A.class}); + } + + @Retention(RetentionPolicy.RUNTIME) + private @interface MyAnnotation {} + + private @interface MyClassFileRetentionAnnotation {} + + private static class A { + @MyAnnotation public void a() {} + } + + @MyAnnotation + private static class B { + @MyClassFileRetentionAnnotation public void b() {} + public void c(A anA, B aB) {} + + public void d(A anA, A anotherA) {} + } + + private static class C { + + @Pointcut("execution(* *(..))") + public void foo() {} + + @Pointcut(value="execution(* *(..)) && this(x)", argNames="x") + public void goo(A x) {} + } + + private static class D { + + public void nonVarArgs(String[] strings) {}; + + public void varArgs(String... strings) {}; + + } + + static class TestBean { + public void setFriends(List friends) {} + } + + @Deprecated + static class GoldenOldie { + public void foo() {} + } + + private static class NamedPointcutResolution { + + @Pointcut("execution(* *(..))") + public void a() {} + + @Pointcut("this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.A)") + public void b() {} + + @Pointcut("a() && b()") + public void c() {} + } + + private static class ExternalReferrer { + + @Pointcut("org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.a() && " + + "org.aspectj.weaver.tools.Java15PointcutExpressionTest.NamedPointcutResolution.b())") + public void d() {} + + } + + private static class UsesArrays { + + @Pointcut("execution(* *(..)) && args(d,s,ss)") + public void pc(Date d, String s, String[] ss) {} + + } +} + + diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/PointcutDesignatorHandlerTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/PointcutDesignatorHandlerTest.java new file mode 100644 index 000000000..83d7b461d --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/PointcutDesignatorHandlerTest.java @@ -0,0 +1,251 @@ +/* ******************************************************************* + * 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; + +import junit.framework.TestCase; + +import org.aspectj.util.LangUtil; + +/** + * @author Adrian Colyer + * + */ +public class PointcutDesignatorHandlerTest extends TestCase { + + boolean needToSkip = false; + + protected void setUp() throws Exception { + super.setUp(); + needToSkip = needToSkipPointcutParserTests(); + } + + /** this condition can occur on the build machine only, and is way too complex to fix right now... */ + private boolean needToSkipPointcutParserTests() { + if (!LangUtil.is15VMOrGreater()) return false; + try { + Class.forName("org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate",false,this.getClass().getClassLoader());//ReflectionBasedReferenceTypeDelegate.class.getClassLoader()); + } catch (ClassNotFoundException cnfEx) { + return true; + } + return false; + } + + public void testParseWithoutHandler() { + if (needToSkip) return; + try { + PointcutParser + .getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution() + .parsePointcutExpression("bean(service.*"); + fail("should not be able to parse bean(service.*)"); + } catch(IllegalArgumentException ex) { + assertTrue("contains bean",ex.getMessage().indexOf("bean") != -1); + } + } + + public void testParseWithHandler() { + if (needToSkip) return; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution(); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + parser.parsePointcutExpression("bean(service.*)"); + assertEquals("service.*",beanHandler.getExpressionLastAskedToParse()); + } + + + /* + * Bug 205907 - the registered pointcut designator does not also get registered with the + * InternalUseOnlyPointcutParser inside the Java15ReflectionBasedReferenceTypeDelegate code. First test checks + * parsing is OK + */ + public void testParsingBeanInReferencePointcut01() throws Exception { + if (needToSkip) return; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution(); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + // The pointcut in CounterAspect look as follows: + // + // @Pointcut("execution(* setAge(..)) && bean(testBean1)") + // public void testBean1SetAge() { } + + // This should be found and resolved +// PointcutExpression pc = + parser.parsePointcutExpression("CounterAspect.testBean1SetAge()"); + + } + + /* + * Bug 205907 - the registered pointcut designator does not also get registered with the + * InternalUseOnlyPointcutParser inside the Java15ReflectionBasedReferenceTypeDelegate code. This test checks the + * actual matching. + */ + public void testParsingBeanInReferencePointcut02() throws Exception { + if (needToSkip) return; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution(); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + // The pointcut in CounterAspect look as follows: + // + // @Pointcut("execution(* toString(..)) && bean(testBean1)") + // public void testBean1toString() { } + + // This should be found and resolved + PointcutExpression pc = parser.parsePointcutExpression("CounterAspect.testBean1toString()"); + + DefaultMatchingContext context = new DefaultMatchingContext(); + context.addContextBinding("beanName", "testBean1"); + pc.setMatchingContext(context); + ShadowMatch sm = pc.matchesMethodExecution(Object.class.getMethod("toString", new Class[0])); + assertTrue(sm.alwaysMatches()); + + sm = pc.matchesMethodExecution(Object.class.getMethod("hashCode", new Class[0])); + assertTrue(sm.neverMatches()); + + context = new DefaultMatchingContext(); + context.addContextBinding("beanName", "testBean2"); + pc.setMatchingContext(context); + sm = pc.matchesMethodExecution(Object.class.getMethod("toString", new Class[0])); + assertTrue(sm.neverMatches()); + } + + public void testParseWithHandlerAndMultipleSegments() { + if (needToSkip) return; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution(); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + parser.parsePointcutExpression("bean(org.xyz.someapp..*)"); + assertEquals("org.xyz.someapp..*",beanHandler.getExpressionLastAskedToParse()); + } + + public void testStaticMatch() throws Exception { + if (needToSkip) return; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution(); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + PointcutExpression pc = parser.parsePointcutExpression("bean(myBean)"); + DefaultMatchingContext context = new DefaultMatchingContext(); + context.addContextBinding("beanName","myBean"); + pc.setMatchingContext(context); + ShadowMatch sm = pc.matchesMethodExecution(Object.class.getMethod("toString",new Class[0])); + assertTrue(sm.alwaysMatches()); + context.addContextBinding("beanName", "notMyBean"); + sm = pc.matchesMethodExecution(Object.class.getMethod("toString",new Class[0])); + assertTrue(sm.neverMatches()); + } + + public void testDynamicMatch() throws Exception { + if (needToSkip) return; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution(); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + beanHandler.simulateDynamicTest = true; + parser.registerPointcutDesignatorHandler(beanHandler); + PointcutExpression pc = parser.parsePointcutExpression("bean(myBean)"); + ShadowMatch sm = pc.matchesMethodExecution(Object.class.getMethod("toString",new Class[0])); + DefaultMatchingContext context = new DefaultMatchingContext(); + assertTrue(sm.maybeMatches()); + assertFalse(sm.alwaysMatches()); + assertFalse(sm.neverMatches()); + context.addContextBinding("beanName","myBean"); + sm.setMatchingContext(context); + assertTrue(sm.matchesJoinPoint(null, null, null).matches()); + context.addContextBinding("beanName", "notMyBean"); + assertFalse(sm.matchesJoinPoint(null, null, null).matches()); + } + + public void testFastMatch() { + if (needToSkip) return; + PointcutParser parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingContextClassloaderForResolution(); + BeanDesignatorHandler beanHandler = new BeanDesignatorHandler(); + parser.registerPointcutDesignatorHandler(beanHandler); + PointcutExpression pc = parser.parsePointcutExpression("bean(myBean)"); + DefaultMatchingContext context = new DefaultMatchingContext(); + context.addContextBinding("beanName","myBean"); + pc.setMatchingContext(context); + assertTrue(pc.couldMatchJoinPointsInType(String.class)); + context.addContextBinding("beanName","yourBean"); + assertFalse(pc.couldMatchJoinPointsInType(String.class)); + } + + private class BeanDesignatorHandler implements PointcutDesignatorHandler { + + private String askedToParse; + public boolean simulateDynamicTest = false; + + public String getDesignatorName() { + return "bean"; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.tools.PointcutDesignatorHandler#parse(java.lang.String) + */ + public ContextBasedMatcher parse(String expression) { + this.askedToParse = expression; + return new BeanPointcutExpression(expression,this.simulateDynamicTest); + } + + public String getExpressionLastAskedToParse() { + return this.askedToParse; + } + } + + private class BeanPointcutExpression implements ContextBasedMatcher { + + private final String beanNamePattern; + private final boolean simulateDynamicTest; + + public BeanPointcutExpression(String beanNamePattern, boolean simulateDynamicTest) { + this.beanNamePattern = beanNamePattern; + this.simulateDynamicTest = simulateDynamicTest; + } + + + public boolean couldMatchJoinPointsInType(Class aClass) { + return true; + } + + /* (non-Javadoc) + * @see org.aspectj.weaver.tools.ContextBasedMatcher#couldMatchJoinPointsInType(java.lang.Class) + */ + public boolean couldMatchJoinPointsInType(Class aClass, MatchingContext context) { + if (this.beanNamePattern.equals(context.getBinding("beanName"))) { + return true; + } else { + return false; + } + } + + + /* (non-Javadoc) + * @see org.aspectj.weaver.tools.ContextBasedMatcher#mayNeedDynamicTest() + */ + public boolean mayNeedDynamicTest() { + return this.simulateDynamicTest; + } + + + public FuzzyBoolean matchesStatically(MatchingContext matchContext) { + if (this.simulateDynamicTest) return FuzzyBoolean.MAYBE; + if (this.beanNamePattern.equals(matchContext.getBinding("beanName"))) { + return FuzzyBoolean.YES; + } else { + return FuzzyBoolean.NO; + } + } + + + /* (non-Javadoc) + * @see org.aspectj.weaver.tools.ContextBasedMatcher#matchesDynamically(org.aspectj.weaver.tools.MatchingContext) + */ + public boolean matchesDynamically(MatchingContext matchContext) { + return this.beanNamePattern.equals(matchContext.getBinding("beanName")); + } + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/PointcutExpressionTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/PointcutExpressionTest.java new file mode 100644 index 000000000..46189fd32 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/PointcutExpressionTest.java @@ -0,0 +1,596 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.aspectj.weaver.tools; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import junit.framework.TestCase; + +import org.aspectj.util.LangUtil; + +public class PointcutExpressionTest extends TestCase { + + PointcutParser p; + Constructor asCons; + Constructor bsCons; + Constructor bsStringCons; + Constructor clientCons; + Method a; + Method aa; + Method aaa; + Field x; + Field y; + Method b; + Method bsaa; + Field n; + Method foo; + Method bar; + + public void testMatchesMethodCall() { + PointcutExpression ex = p.parsePointcutExpression("call(* *..A.a*(..))"); + assertTrue("Should match call to A.a()", ex.matchesMethodCall(a, a).alwaysMatches()); + assertTrue("Should match call to A.aaa()", ex.matchesMethodCall(aaa, a).alwaysMatches()); + assertTrue("Should match call to B.aa()", ex.matchesMethodCall(bsaa, a).alwaysMatches()); + assertTrue("Should not match call to B.b()", ex.matchesMethodCall(b, a).neverMatches()); + ex = p.parsePointcutExpression("call(* *..A.a*(int))"); + assertTrue("Should match call to A.aa()", ex.matchesMethodCall(aa, a).alwaysMatches()); + assertTrue("Should not match call to A.a()", ex.matchesMethodCall(a, a).neverMatches()); + ex = p.parsePointcutExpression("call(void aaa(..)) && this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should match call to A.aaa() from Client", ex.matchesMethodCall(aaa, foo).alwaysMatches()); + ex = p.parsePointcutExpression("call(void aaa(..)) && this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Should match call to A.aaa() from B", ex.matchesMethodCall(aaa, b).alwaysMatches()); + assertTrue("May match call to A.aaa() from A", ex.matchesMethodCall(aaa, a).maybeMatches()); + assertFalse("May match call to A.aaa() from A", ex.matchesMethodCall(aaa, a).alwaysMatches()); + ex = p.parsePointcutExpression("execution(* *.*(..))"); + assertTrue("Should not match call to A.aa", ex.matchesMethodCall(aa, a).neverMatches()); + // this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should match Client", ex.matchesMethodCall(a, foo).alwaysMatches()); + assertTrue("Should not match A", ex.matchesMethodCall(a, a).neverMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Should maybe match B", ex.matchesMethodCall(bsaa, a).maybeMatches()); + assertFalse("Should maybe match B", ex.matchesMethodCall(bsaa, a).alwaysMatches()); + // target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should not match Client", ex.matchesMethodCall(a, a).neverMatches()); + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should match A", ex.matchesMethodCall(a, a).alwaysMatches()); + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Should maybe match A", ex.matchesMethodCall(aa, a).maybeMatches()); + assertFalse("Should maybe match A", ex.matchesMethodCall(aa, a).alwaysMatches()); + // test args + ex = p.parsePointcutExpression("args(..,int)"); + assertTrue("Should match A.aa", ex.matchesMethodCall(aa, a).alwaysMatches()); + assertTrue("Should match A.aaa", ex.matchesMethodCall(aaa, a).alwaysMatches()); + assertTrue("Should not match A.a", ex.matchesMethodCall(a, a).neverMatches()); + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesMethodCall(a, a).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesMethodCall(a, b).neverMatches()); + assertTrue("Matches in class A", ex.matchesMethodCall(a, A.class).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesMethodCall(a, B.class).neverMatches()); + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Should match", ex.matchesMethodCall(b, bsaa).alwaysMatches()); + assertTrue("Should not match", ex.matchesMethodCall(b, b).neverMatches()); + } + + public void testMatchesMethodExecution() { + PointcutExpression ex = p.parsePointcutExpression("execution(* *..A.aa(..))"); + assertTrue("Should match execution of A.aa", ex.matchesMethodExecution(aa).alwaysMatches()); + assertTrue("Should match execution of B.aa", ex.matchesMethodExecution(bsaa).alwaysMatches()); + assertTrue("Should not match execution of A.a", ex.matchesMethodExecution(a).neverMatches()); + ex = p.parsePointcutExpression("call(* *..A.a*(int))"); + assertTrue("Should not match execution of A.a", ex.matchesMethodExecution(a).neverMatches()); + + // test this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should match A", ex.matchesMethodExecution(a).alwaysMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesMethodExecution(a).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesMethodExecution(a).alwaysMatches()); + + // test target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should match A", ex.matchesMethodExecution(a).alwaysMatches()); + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesMethodExecution(a).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesMethodExecution(a).alwaysMatches()); + + // test args + ex = p.parsePointcutExpression("args(..,int)"); + assertTrue("Should match A.aa", ex.matchesMethodExecution(aa).alwaysMatches()); + assertTrue("Should match A.aaa", ex.matchesMethodExecution(aaa).alwaysMatches()); + assertTrue("Should not match A.a", ex.matchesMethodExecution(a).neverMatches()); + + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesMethodExecution(a).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesMethodExecution(bsaa).neverMatches()); + + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Should not match", ex.matchesMethodExecution(a).neverMatches()); + } + + public void testMatchesConstructorCall() { + PointcutExpression ex = p.parsePointcutExpression("call(new(String))"); + assertTrue("Should match A(String)", ex.matchesConstructorCall(asCons, b).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesConstructorCall(bsStringCons, b).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesConstructorCall(bsCons, foo).neverMatches()); + ex = p.parsePointcutExpression("call(*..A.new(String))"); + assertTrue("Should match A(String)", ex.matchesConstructorCall(asCons, b).alwaysMatches()); + assertTrue("Should not match B(String)", ex.matchesConstructorCall(bsStringCons, foo).neverMatches()); + // this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should match Client", ex.matchesConstructorCall(asCons, foo).alwaysMatches()); + assertTrue("Should not match A", ex.matchesConstructorCall(asCons, a).neverMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Should maybe match B", ex.matchesConstructorCall(asCons, a).maybeMatches()); + assertFalse("Should maybe match B", ex.matchesConstructorCall(asCons, a).alwaysMatches()); + // target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should not match Client", ex.matchesConstructorCall(asCons, foo).neverMatches()); + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should not match A (no target)", ex.matchesConstructorCall(asCons, a).neverMatches()); + // args + ex = p.parsePointcutExpression("args(String)"); + assertTrue("Should match A(String)", ex.matchesConstructorCall(asCons, b).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesConstructorCall(bsStringCons, foo).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesConstructorCall(bsCons, foo).neverMatches()); + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesConstructorCall(asCons, a).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesConstructorCall(asCons, b).neverMatches()); + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Should match", ex.matchesConstructorCall(bsCons, aa).alwaysMatches()); + assertTrue("Should not match", ex.matchesConstructorCall(bsCons, b).neverMatches()); + } + + public void testMatchesConstructorExecution() { + PointcutExpression ex = p.parsePointcutExpression("execution(new(String))"); + assertTrue("Should match A(String)", ex.matchesConstructorExecution(asCons).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesConstructorExecution(bsStringCons).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesConstructorExecution(bsCons).neverMatches()); + ex = p.parsePointcutExpression("execution(*..A.new(String))"); + assertTrue("Should match A(String)", ex.matchesConstructorExecution(asCons).alwaysMatches()); + assertTrue("Should not match B(String)", ex.matchesConstructorExecution(bsStringCons).neverMatches()); + + // test this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should match A", ex.matchesConstructorExecution(asCons).alwaysMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesConstructorExecution(asCons).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesConstructorExecution(asCons).alwaysMatches()); + assertTrue("Should match B", ex.matchesConstructorExecution(bsCons).alwaysMatches()); + assertTrue("Does not match client", ex.matchesConstructorExecution(clientCons).neverMatches()); + + // test target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should match A", ex.matchesConstructorExecution(asCons).alwaysMatches()); + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesConstructorExecution(asCons).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesConstructorExecution(asCons).alwaysMatches()); + assertTrue("Should match B", ex.matchesConstructorExecution(bsCons).alwaysMatches()); + assertTrue("Does not match client", ex.matchesConstructorExecution(clientCons).neverMatches()); + + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesConstructorExecution(asCons).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesConstructorExecution(bsCons).neverMatches()); + + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Does not match", ex.matchesConstructorExecution(bsCons).neverMatches()); + + // args + ex = p.parsePointcutExpression("args(String)"); + assertTrue("Should match A(String)", ex.matchesConstructorExecution(asCons).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesConstructorExecution(bsStringCons).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesConstructorExecution(bsCons).neverMatches()); + } + + public void testMatchesAdviceExecution() { + PointcutExpression ex = p.parsePointcutExpression("adviceexecution()"); + assertTrue("Should match (advice) A.a", ex.matchesAdviceExecution(a).alwaysMatches()); + // test this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should match Client", ex.matchesAdviceExecution(foo).alwaysMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesAdviceExecution(a).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesAdviceExecution(a).alwaysMatches()); + assertTrue("Does not match client", ex.matchesAdviceExecution(foo).neverMatches()); + + // test target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should match Client", ex.matchesAdviceExecution(foo).alwaysMatches()); + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesAdviceExecution(a).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesAdviceExecution(a).alwaysMatches()); + assertTrue("Does not match client", ex.matchesAdviceExecution(foo).neverMatches()); + + // test within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesAdviceExecution(a).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesAdviceExecution(b).neverMatches()); + + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Does not match", ex.matchesAdviceExecution(a).neverMatches()); + + // test args + ex = p.parsePointcutExpression("args(..,int)"); + assertTrue("Should match A.aa", ex.matchesAdviceExecution(aa).alwaysMatches()); + assertTrue("Should match A.aaa", ex.matchesAdviceExecution(aaa).alwaysMatches()); + assertTrue("Should not match A.a", ex.matchesAdviceExecution(a).neverMatches()); + } + + public void testMatchesHandler() { + PointcutExpression ex = p.parsePointcutExpression("handler(Exception)"); + assertTrue("Should match catch(Exception)", ex.matchesHandler(Exception.class, Client.class).alwaysMatches()); + assertTrue("Should not match catch(Throwable)", ex.matchesHandler(Throwable.class, Client.class).neverMatches()); + // test this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should match Client", ex.matchesHandler(Exception.class, foo).alwaysMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesHandler(Exception.class, a).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesHandler(Exception.class, a).alwaysMatches()); + assertTrue("Does not match client", ex.matchesHandler(Exception.class, foo).neverMatches()); + // target - no target for exception handlers + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("Should match Client", ex.matchesHandler(Exception.class, foo).neverMatches()); + // args + ex = p.parsePointcutExpression("args(Exception)"); + assertTrue("Should match Exception", ex.matchesHandler(Exception.class, foo).alwaysMatches()); + assertTrue("Should match RuntimeException", ex.matchesHandler(RuntimeException.class, foo).alwaysMatches()); + assertTrue("Should not match String", ex.matchesHandler(String.class, foo).neverMatches()); + assertTrue("Maybe matches Throwable", ex.matchesHandler(Throwable.class, foo).maybeMatches()); + assertFalse("Maybe matches Throwable", ex.matchesHandler(Throwable.class, foo).alwaysMatches()); + // within + ex = p.parsePointcutExpression("within(*..Client)"); + assertTrue("Matches in class Client", ex.matchesHandler(Exception.class, foo).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesHandler(Exception.class, b).neverMatches()); + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Matches within aa", ex.matchesHandler(Exception.class, aa).alwaysMatches()); + assertTrue("Does not match within b", ex.matchesHandler(Exception.class, b).neverMatches()); + } + + public void testMatchesInitialization() { + PointcutExpression ex = p.parsePointcutExpression("initialization(new(String))"); + assertTrue("Should match A(String)", ex.matchesInitialization(asCons).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesInitialization(bsStringCons).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesInitialization(bsCons).neverMatches()); + ex = p.parsePointcutExpression("initialization(*..A.new(String))"); + assertTrue("Should match A(String)", ex.matchesInitialization(asCons).alwaysMatches()); + assertTrue("Should not match B(String)", ex.matchesInitialization(bsStringCons).neverMatches()); + // test this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should match A", ex.matchesInitialization(asCons).alwaysMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesInitialization(asCons).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesInitialization(asCons).alwaysMatches()); + + // test target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("Should match A", ex.matchesInitialization(asCons).alwaysMatches()); + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("Maybe matches B", ex.matchesInitialization(asCons).maybeMatches()); + assertFalse("Maybe matches B", ex.matchesInitialization(asCons).alwaysMatches()); + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesInitialization(asCons).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesInitialization(bsCons).neverMatches()); + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Does not match", ex.matchesInitialization(bsCons).neverMatches()); + // args + ex = p.parsePointcutExpression("args(String)"); + assertTrue("Should match A(String)", ex.matchesInitialization(asCons).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesInitialization(bsStringCons).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesInitialization(bsCons).neverMatches()); + } + + public void testMatchesPreInitialization() { + PointcutExpression ex = p.parsePointcutExpression("preinitialization(new(String))"); + assertTrue("Should match A(String)", ex.matchesPreInitialization(asCons).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesPreInitialization(bsStringCons).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesPreInitialization(bsCons).neverMatches()); + ex = p.parsePointcutExpression("preinitialization(*..A.new(String))"); + assertTrue("Should match A(String)", ex.matchesPreInitialization(asCons).alwaysMatches()); + assertTrue("Should not match B(String)", ex.matchesPreInitialization(bsStringCons).neverMatches()); + // test this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("No match, no this at preinit", ex.matchesPreInitialization(asCons).neverMatches()); + + // test target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("No match, no target at preinit", ex.matchesPreInitialization(asCons).neverMatches()); + + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesPreInitialization(asCons).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesPreInitialization(bsCons).neverMatches()); + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Does not match", ex.matchesPreInitialization(bsCons).neverMatches()); + // args + ex = p.parsePointcutExpression("args(String)"); + assertTrue("Should match A(String)", ex.matchesPreInitialization(asCons).alwaysMatches()); + assertTrue("Should match B(String)", ex.matchesPreInitialization(bsStringCons).alwaysMatches()); + assertTrue("Should not match B()", ex.matchesPreInitialization(bsCons).neverMatches()); + } + + public void testMatchesStaticInitialization() { + // staticinit + PointcutExpression ex = p.parsePointcutExpression("staticinitialization(*..A+)"); + assertTrue("Matches A", ex.matchesStaticInitialization(A.class).alwaysMatches()); + assertTrue("Matches B", ex.matchesStaticInitialization(B.class).alwaysMatches()); + assertTrue("Doesn't match Client", ex.matchesStaticInitialization(Client.class).neverMatches()); + // this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("No this", ex.matchesStaticInitialization(A.class).neverMatches()); + // target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + assertTrue("No target", ex.matchesStaticInitialization(A.class).neverMatches()); + + // args + ex = p.parsePointcutExpression("args()"); + assertTrue("No args", ex.matchesStaticInitialization(A.class).alwaysMatches()); + ex = p.parsePointcutExpression("args(String)"); + assertTrue("No args", ex.matchesStaticInitialization(A.class).neverMatches()); + + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesStaticInitialization(A.class).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesStaticInitialization(B.class).neverMatches()); + + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Does not match", ex.matchesStaticInitialization(A.class).neverMatches()); + } + + public void testMatchesFieldSet() { + PointcutExpression ex = p.parsePointcutExpression("set(* *..A+.*)"); + assertTrue("matches x", ex.matchesFieldSet(x, a).alwaysMatches()); + assertTrue("matches y", ex.matchesFieldSet(y, foo).alwaysMatches()); + assertTrue("does not match n", ex.matchesFieldSet(n, foo).neverMatches()); + // this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("matches Client", ex.matchesFieldSet(x, foo).alwaysMatches()); + assertTrue("does not match A", ex.matchesFieldSet(n, a).neverMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("maybe matches A", ex.matchesFieldSet(x, a).maybeMatches()); + assertFalse("maybe matches A", ex.matchesFieldSet(x, a).alwaysMatches()); + // target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("matches B", ex.matchesFieldSet(y, foo).alwaysMatches()); + assertTrue("maybe matches A", ex.matchesFieldSet(x, foo).maybeMatches()); + assertFalse("maybe matches A", ex.matchesFieldSet(x, foo).alwaysMatches()); + // args + ex = p.parsePointcutExpression("args(int)"); + assertTrue("matches x", ex.matchesFieldSet(x, a).alwaysMatches()); + assertTrue("matches y", ex.matchesFieldSet(y, a).alwaysMatches()); + assertTrue("does not match n", ex.matchesFieldSet(n, a).neverMatches()); + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesFieldSet(x, a).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesFieldSet(x, b).neverMatches()); + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Should match", ex.matchesFieldSet(x, aa).alwaysMatches()); + assertTrue("Should not match", ex.matchesFieldSet(x, b).neverMatches()); + } + + public void testMatchesFieldGet() { + PointcutExpression ex = p.parsePointcutExpression("get(* *..A+.*)"); + assertTrue("matches x", ex.matchesFieldGet(x, a).alwaysMatches()); + assertTrue("matches y", ex.matchesFieldGet(y, foo).alwaysMatches()); + assertTrue("does not match n", ex.matchesFieldGet(n, foo).neverMatches()); + // this + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.Client)"); + assertTrue("matches Client", ex.matchesFieldGet(x, foo).alwaysMatches()); + assertTrue("does not match A", ex.matchesFieldGet(n, a).neverMatches()); + ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("maybe matches A", ex.matchesFieldGet(x, a).maybeMatches()); + assertFalse("maybe matches A", ex.matchesFieldGet(x, a).alwaysMatches()); + // target + ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertTrue("matches B", ex.matchesFieldGet(y, foo).alwaysMatches()); + assertTrue("maybe matches A", ex.matchesFieldGet(x, foo).maybeMatches()); + assertFalse("maybe matches A", ex.matchesFieldGet(x, foo).alwaysMatches()); + // args - no args at get join point + ex = p.parsePointcutExpression("args(int)"); + assertTrue("matches x", ex.matchesFieldGet(x, a).neverMatches()); + // within + ex = p.parsePointcutExpression("within(*..A)"); + assertTrue("Matches in class A", ex.matchesFieldGet(x, a).alwaysMatches()); + assertTrue("Does not match in class B", ex.matchesFieldGet(x, b).neverMatches()); + // withincode + ex = p.parsePointcutExpression("withincode(* a*(..))"); + assertTrue("Should match", ex.matchesFieldGet(x, aa).alwaysMatches()); + assertTrue("Should not match", ex.matchesFieldGet(x, b).neverMatches()); + } + + public void testArgsMatching() { + // too few args + PointcutExpression ex = p.parsePointcutExpression("args(*,*,*,*)"); + assertTrue("Too few args", ex.matchesMethodExecution(foo).neverMatches()); + assertTrue("Matching #args", ex.matchesMethodExecution(bar).alwaysMatches()); + // one too few + ellipsis + ex = p.parsePointcutExpression("args(*,*,*,..)"); + assertTrue("Matches with ellipsis", ex.matchesMethodExecution(foo).alwaysMatches()); + // exact number + ellipsis + assertTrue("Matches with ellipsis", ex.matchesMethodExecution(bar).alwaysMatches()); + assertTrue("Does not match with ellipsis", ex.matchesMethodExecution(a).neverMatches()); + // too many + ellipsis + ex = p.parsePointcutExpression("args(*,..,*)"); + assertTrue("Matches with ellipsis", ex.matchesMethodExecution(bar).alwaysMatches()); + assertTrue("Does not match with ellipsis", ex.matchesMethodExecution(a).neverMatches()); + assertTrue("Matches with ellipsis", ex.matchesMethodExecution(aaa).alwaysMatches()); + // exact match + ex = p.parsePointcutExpression("args(String,int,Number)"); + assertTrue("Matches exactly", ex.matchesMethodExecution(foo).alwaysMatches()); + // maybe match + ex = p.parsePointcutExpression("args(String,int,Double)"); + assertTrue("Matches maybe", ex.matchesMethodExecution(foo).maybeMatches()); + assertFalse("Matches maybe", ex.matchesMethodExecution(foo).alwaysMatches()); + // never match + ex = p.parsePointcutExpression("args(String,Integer,Number)"); + if (LangUtil.is15VMOrGreater()) { + assertTrue("matches", ex.matchesMethodExecution(foo).alwaysMatches()); + } else { + assertTrue("Does not match", ex.matchesMethodExecution(foo).neverMatches()); + } + } + + // public void testMatchesDynamically() { + // // everything other than this,target,args should just return true + // PointcutExpression ex = p.parsePointcutExpression("call(* *.*(..)) && execution(* *.*(..)) &&" + + // "get(* *) && set(* *) && initialization(new(..)) && preinitialization(new(..)) &&" + + // "staticinitialization(X) && adviceexecution() && within(Y) && withincode(* *.*(..)))"); + // assertTrue("Matches dynamically",ex.matchesDynamically(a,b,new Object[0])); + // // this + // ex = p.parsePointcutExpression("this(String)"); + // assertTrue("String matches",ex.matchesDynamically("",this,new Object[0])); + // assertFalse("Object doesn't match",ex.matchesDynamically(new Object(),this,new Object[0])); + // ex = p.parsePointcutExpression("this(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + // assertTrue("A matches",ex.matchesDynamically(new A(""),this,new Object[0])); + // assertTrue("B matches",ex.matchesDynamically(new B(""),this,new Object[0])); + // // target + // ex = p.parsePointcutExpression("target(String)"); + // assertTrue("String matches",ex.matchesDynamically(this,"",new Object[0])); + // assertFalse("Object doesn't match",ex.matchesDynamically(this,new Object(),new Object[0])); + // ex = p.parsePointcutExpression("target(org.aspectj.weaver.tools.PointcutExpressionTest.A)"); + // assertTrue("A matches",ex.matchesDynamically(this,new A(""),new Object[0])); + // assertTrue("B matches",ex.matchesDynamically(this,new B(""),new Object[0])); + // // args + // ex = p.parsePointcutExpression("args(*,*,*,*)"); + // assertFalse("Too few args",ex.matchesDynamically(null,null,new Object[]{a,b})); + // assertTrue("Matching #args",ex.matchesDynamically(null,null,new Object[]{a,b,aa,aaa})); + // // one too few + ellipsis + // ex = p.parsePointcutExpression("args(*,*,*,..)"); + // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b,aa,aaa})); + // // exact number + ellipsis + // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b,aa})); + // assertFalse("Does not match with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b})); + // // too many + ellipsis + // ex = p.parsePointcutExpression("args(*,..,*)"); + // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b,aa,aaa})); + // assertFalse("Does not match with ellipsis",ex.matchesDynamically(null,null,new Object[]{a})); + // assertTrue("Matches with ellipsis",ex.matchesDynamically(null,null,new Object[]{a,b})); + // // exact match + // ex = p.parsePointcutExpression("args(String,int,Number)"); + // assertTrue("Matches exactly",ex.matchesDynamically(null,null,new Object[]{"",new Integer(5),new Double(5.0)})); + // ex = p.parsePointcutExpression("args(String,Integer,Number)"); + // assertTrue("Matches exactly",ex.matchesDynamically(null,null,new Object[]{"",new Integer(5),new Double(5.0)})); + // // never match + // ex = p.parsePointcutExpression("args(String,Integer,Number)"); + // assertFalse("Does not match",ex.matchesDynamically(null,null,new Object[]{a,b,aa})); + // } + + public void testGetPointcutExpression() { + 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 maybe match String (as best we know at this point)", ex.couldMatchJoinPointsInType(String.class)); + assertTrue("Will always match B", ex.couldMatchJoinPointsInType(B.class)); + ex = p.parsePointcutExpression("within(org.aspectj.weaver.tools.PointcutExpressionTest.B)"); + assertFalse("Will never match String", ex.couldMatchJoinPointsInType(String.class)); + assertTrue("Will always match B", ex.couldMatchJoinPointsInType(B.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(org.aspectj.weaver.tools.PointcutExpressionTest.X)"); + assertTrue("Dynamic test needed", ex.mayNeedDynamicTest()); + } + + protected void setUp() throws Exception { + super.setUp(); + p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass() + .getClassLoader()); + asCons = A.class.getConstructor(new Class[] { String.class }); + bsCons = B.class.getConstructor(new Class[0]); + bsStringCons = B.class.getConstructor(new Class[] { String.class }); + a = A.class.getMethod("a", new Class[0]); + aa = A.class.getMethod("aa", new Class[] { int.class }); + aaa = A.class.getMethod("aaa", new Class[] { String.class, int.class }); + x = A.class.getDeclaredField("x"); + y = B.class.getDeclaredField("y"); + b = B.class.getMethod("b", new Class[0]); + bsaa = B.class.getMethod("aa", new Class[] { int.class }); + clientCons = Client.class.getConstructor(new Class[0]); + n = Client.class.getDeclaredField("n"); + foo = Client.class.getDeclaredMethod("foo", new Class[] { String.class, int.class, Number.class }); + bar = Client.class.getDeclaredMethod("bar", new Class[] { String.class, int.class, Integer.class, Number.class }); + } + + static class A { + public A(String s) { + } + + public void a() { + } + + public void aa(int i) { + } + + public void aaa(String s, int i) { + } + + int x; + } + + static class B extends A { + public B() { + super(""); + } + + public B(String s) { + super(s); + } + + public String b() { + return null; + } + + public void aa(int i) { + } + + int y; + } + + static class Client { + public Client() { + } + + Number n; + + public void foo(String s, int i, Number n) { + } + + public void bar(String s, int i, Integer i2, Number n) { + } + } + + static class X { + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/PointcutParserTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/PointcutParserTest.java new file mode 100644 index 000000000..4654b049d --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/PointcutParserTest.java @@ -0,0 +1,391 @@ +/* ******************************************************************* + * Copyright (c) 2004 IBM Corporation. + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * ******************************************************************/ +package org.aspectj.weaver.tools; + +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import junit.framework.Assert; +import junit.framework.TestCase; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessage.Kind; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.patterns.PatternParser; +import org.aspectj.weaver.patterns.Pointcut; +import org.aspectj.weaver.patterns.PointcutRewriter; + +/** + * Test cases for the PointcutParser class + */ +public class PointcutParserTest extends TestCase { + + private boolean needToSkip = false; + + /** this condition can occur on the build machine only, and is way too complex to fix right now... */ + private boolean needToSkipPointcutParserTests() { + if (!LangUtil.is15VMOrGreater()) { + return false; + } + try { + Class.forName("org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate", false, this.getClass() + .getClassLoader());// ReflectionBasedReferenceTypeDelegate.class.getClassLoader()); + } catch (ClassNotFoundException cnfEx) { + return true; + } + return false; + } + + protected void setUp() throws Exception { + super.setUp(); + needToSkip = needToSkipPointcutParserTests(); + } + + public void testGetAllSupportedPointcutPrimitives() { + if (needToSkip) { + return; + } + + Set s = PointcutParser.getAllSupportedPointcutPrimitives(); + assertEquals("Should be 21 elements in the set", 21, s.size()); + assertFalse("Should not contain if pcd", s.contains(PointcutPrimitive.IF)); + assertFalse("Should not contain cflow pcd", s.contains(PointcutPrimitive.CFLOW)); + assertFalse("Should not contain cflowbelow pcd", s.contains(PointcutPrimitive.CFLOW_BELOW)); + } + + public void testEmptyConstructor() { + if (needToSkip) { + return; + } + + PointcutParser parser = PointcutParser + .getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + Set s = parser.getSupportedPrimitives(); + assertEquals("Should be 21 elements in the set", 21, s.size()); + assertFalse("Should not contain if pcd", s.contains(PointcutPrimitive.IF)); + assertFalse("Should not contain cflow pcd", s.contains(PointcutPrimitive.CFLOW)); + assertFalse("Should not contain cflowbelow pcd", s.contains(PointcutPrimitive.CFLOW_BELOW)); + } + + public void testSetConstructor() { + if (needToSkip) { + return; + } + + Set p = PointcutParser.getAllSupportedPointcutPrimitives(); + PointcutParser parser = PointcutParser + .getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(p, this.getClass() + .getClassLoader()); + assertEquals("Should use the set we pass in", p, parser.getSupportedPrimitives()); + Set q = new HashSet(); + q.add(PointcutPrimitive.ARGS); + parser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(q, this + .getClass().getClassLoader()); + assertEquals("Should have only one element in set", 1, parser.getSupportedPrimitives().size()); + assertEquals("Should only have ARGS pcd", PointcutPrimitive.ARGS, parser.getSupportedPrimitives().iterator().next()); + } + + public void testParsePointcutExpression() { + if (needToSkip) { + return; + } + + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this + .getClass().getClassLoader()); + IMessageHandler current = p.setCustomMessageHandler(new IgnoreWarningsMessageHandler()); + try { + p.parsePointcutExpression("(adviceexecution() || execution(* *.*(..)) || handler(Exception) || " + + "call(Foo Bar+.*(Goo)) || get(* foo) || set(Foo+ (Goo||Moo).s*) || " + + "initialization(Foo.new(..)) || preinitialization(*.new(Foo,..)) || " + + "staticinitialization(org.xzy.abc..*)) && (this(Foo) || target(Boo) ||" + "args(A,B,C)) && !handler(X)"); + } finally { + p.setCustomMessageHandler(current); + } + try { + p.parsePointcutExpression("gobble-de-gook()"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + } + } + + public void testParseExceptionErrorMessages() { + if (needToSkip) { + return; + } + + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this + .getClass().getClassLoader()); + try { + p.parsePointcutExpression("execution(int Foo.*(..) && args(Double)"); + fail("Expected IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + assertTrue("Pointcut is not well-formed message", + ex.getMessage().startsWith("Pointcut is not well-formed: expecting ')' at character position 24")); + } + } + + public void testOperatorPrecedence_319190() throws Exception { + if (needToSkip) { + return; + } + + String s = null; + Pointcut p = null; + + s = "(execution(* A.credit(float)) || execution(* A.debit(float))) && this(acc) && args(am) || execution(* C.*(Account, float)) && args(acc, am)"; + p = new PatternParser(s).parsePointcut(); + Assert.assertEquals( + "(((execution(* A.credit(float)) || execution(* A.debit(float))) && (this(acc) && args(am))) || (execution(* C.*(Account, float)) && args(acc, am)))", + p.toString()); + + s = "(if(true) || if(false)) && this(acc) && args(am) || if(true) && args(acc, am)"; + p = new PatternParser(s).parsePointcut(); + // bugged was: ((if(true) || if(false)) && (this(acc) && (args(am) || (if(true) && args(acc, am))))) + Assert.assertEquals("(((if(true) || if(false)) && (this(acc) && args(am))) || (if(true) && args(acc, am)))", p.toString()); + p = new PointcutRewriter().rewrite(p); + Assert.assertEquals("(((this(acc) && args(am)) && if(true)) || (args(acc, am) && if(true)))", p.toString()); + + s = "if(true) && if(false) || if(true)"; + p = new PatternParser(s).parsePointcut(); + assertEquals("((if(true) && if(false)) || if(true))", p.toString()); + p = new PointcutRewriter().rewrite(p); + Assert.assertEquals("if(true)", p.toString()); + } + + public void testParseIfPCD() { + if (needToSkip) { + return; + } + + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this + .getClass().getClassLoader()); + try { + p.parsePointcutExpression("if(true)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Should not support IF", PointcutPrimitive.IF, ex.getUnsupportedPrimitive()); + } + } + + public void testParseCflowPCDs() { + if (needToSkip) { + return; + } + + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this + .getClass().getClassLoader()); + try { + p.parsePointcutExpression("cflow(this(t))"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Should not support CFLOW", PointcutPrimitive.CFLOW, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("cflowbelow(this(t))"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Should not support CFLOW_BELOW", PointcutPrimitive.CFLOW_BELOW, ex.getUnsupportedPrimitive()); + } + } + + public void testParseReferencePCDs() { + if (needToSkip) { + return; + } + + Set pcKinds = PointcutParser.getAllSupportedPointcutPrimitives(); + pcKinds.remove(PointcutPrimitive.REFERENCE); + PointcutParser p = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution( + pcKinds, this.getClass().getClassLoader()); + try { + p.parsePointcutExpression("bananas(String)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertTrue(ex.getUnsupportedPrimitive() == PointcutPrimitive.REFERENCE); + } + } + + public void testParseUnsupportedPCDs() { + if (needToSkip) { + return; + } + + Set s = new HashSet(); + PointcutParser p = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution( + s, this.getClass().getClassLoader()); + try { + p.parsePointcutExpression("args(x)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Args", PointcutPrimitive.ARGS, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("within(x)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Within", PointcutPrimitive.WITHIN, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("withincode(new(..))"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Withincode", PointcutPrimitive.WITHIN_CODE, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("handler(Exception)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("handler", PointcutPrimitive.HANDLER, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("this(X)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("this", PointcutPrimitive.THIS, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("target(X)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("target", PointcutPrimitive.TARGET, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("this(X) && target(Y)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("This", PointcutPrimitive.THIS, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("this(X) || target(Y)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("This", PointcutPrimitive.THIS, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("!this(X)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("This", PointcutPrimitive.THIS, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("call(* *.*(..))"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Call", PointcutPrimitive.CALL, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("execution(* *.*(..))"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Execution", PointcutPrimitive.EXECUTION, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("get(* *)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Get", PointcutPrimitive.GET, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("set(* *)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Set", PointcutPrimitive.SET, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("initialization(new(..))"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Initialization", PointcutPrimitive.INITIALIZATION, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("preinitialization(new(..))"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Prc-init", PointcutPrimitive.PRE_INITIALIZATION, ex.getUnsupportedPrimitive()); + } + try { + p.parsePointcutExpression("staticinitialization(T)"); + fail("Expected UnsupportedPointcutPrimitiveException"); + } catch (UnsupportedPointcutPrimitiveException ex) { + assertEquals("Staticinit", PointcutPrimitive.STATIC_INITIALIZATION, ex.getUnsupportedPrimitive()); + } + } + + public void testFormals() { + if (needToSkip) { + return; + } + + PointcutParser parser = PointcutParser + .getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + PointcutParameter param = parser.createPointcutParameter("x", String.class); + PointcutExpression pc = parser.parsePointcutExpression("args(x)", null, new PointcutParameter[] { param }); + assertEquals("args(x)", pc.getPointcutExpression()); + + try { + pc = parser.parsePointcutExpression("args(String)", null, new PointcutParameter[] { param }); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + assertTrue("formal unbound", ex.getMessage().indexOf("formal unbound") != -1); + } + + try { + pc = parser.parsePointcutExpression("args(y)"); + fail("Expecting IllegalArgumentException"); + } catch (IllegalArgumentException ex) { + assertTrue("no match for type name", ex.getMessage().indexOf("warning no match for this type name: y") != -1); + } + } + + public void testXLintConfiguration() { + if (needToSkip) { + return; + } + + PointcutParser p = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this + .getClass().getClassLoader()); + try { + p.parsePointcutExpression("this(FooBar)"); + } catch (IllegalArgumentException ex) { + assertTrue("should have xlint:invalidAbsoluteTypeName", ex.getMessage().indexOf("Xlint:invalidAbsoluteTypeName") != -1); + } + Properties props = new Properties(); + props.put("invalidAbsoluteTypeName", "ignore"); + p.setLintProperties(props); + p.parsePointcutExpression("this(FooBar)"); + } + + private static class IgnoreWarningsMessageHandler implements IMessageHandler { + + public boolean handleMessage(IMessage message) throws AbortException { + if (message.getKind() != IMessage.WARNING) { + throw new RuntimeException("unexpected message: " + message.toString()); + } + return true; + } + + public boolean isIgnoring(Kind kind) { + if (kind != IMessage.ERROR) { + return true; + } + return false; + } + + public void dontIgnore(Kind kind) { + } + + public void ignore(Kind kind) { + } + + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/ReadingAttributesTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/ReadingAttributesTest.java new file mode 100644 index 000000000..5814aa90f --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/ReadingAttributesTest.java @@ -0,0 +1,66 @@ +/* ******************************************************************* + * Copyright (c) 2009 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Andy Clement + * ******************************************************************/ +package org.aspectj.weaver.tools; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; + +import junit.framework.TestCase; + +import org.aspectj.apache.bcel.classfile.Attribute; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Unknown; +import org.aspectj.apache.bcel.util.ClassPath; +import org.aspectj.apache.bcel.util.SyntheticRepository; +import org.aspectj.weaver.VersionedDataInputStream; +import org.aspectj.weaver.WeaverStateInfo; + +public class ReadingAttributesTest extends TestCase { + + public void testSkip() {} // Review what to do about these tests + + public void xtestWeaverStateInfo() throws ClassNotFoundException, IOException { + + JavaClass jc = getClassFrom(new File("n:/temp"), "com.springsource.petclinic.domain.Visit"); + assertNotNull(jc); + Attribute[] attrs = jc.getAttributes(); + for (int i = 0; i < attrs.length; i++) { + System.out.println(attrs[i].getName()); + if (attrs[i].getName().endsWith("WeaverState")) { + Unknown u = (Unknown) attrs[i]; + VersionedDataInputStream vdis = new VersionedDataInputStream(new ByteArrayInputStream(u.getBytes()), null); + // WeaverStateInfo wsi = + WeaverStateInfo.read(vdis, null); + // System.out.println(wsi); + } + } + // Method[] meths = jc.getMethods(); + // Method oneWeWant = null; + // for (int i = 0; i < meths.length && oneWeWant == null; i++) { + // Method method = meths[i]; + // if (method.getName().equals("main")) { + // oneWeWant = meths[i]; + // } + // } + } + + public SyntheticRepository createRepos(File cpentry) { + ClassPath cp = new ClassPath(cpentry + File.pathSeparator + System.getProperty("java.class.path")); + return SyntheticRepository.getInstance(cp); + } + + protected JavaClass getClassFrom(File where, String clazzname) throws ClassNotFoundException { + SyntheticRepository repos = createRepos(where); + return repos.loadClass(clazzname); + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/TypePatternMatcherTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/TypePatternMatcherTest.java new file mode 100644 index 000000000..523ee4a83 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/TypePatternMatcherTest.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.aspectj.weaver.tools; + +import java.util.HashMap; +import java.util.Map; + +import org.aspectj.util.LangUtil; + +import junit.framework.TestCase; + +public class TypePatternMatcherTest extends TestCase { + + TypePatternMatcher tpm; + + private boolean needToSkip = false; + + /** this condition can occur on the build machine only, and is way too complex to fix right now... */ + private boolean needToSkipPointcutParserTests() { + if (!LangUtil.is15VMOrGreater()) return false; + try { + Class.forName("org.aspectj.weaver.reflect.Java15ReflectionBasedReferenceTypeDelegate",false,this.getClass().getClassLoader());//ReflectionBasedReferenceTypeDelegate.class.getClassLoader()); + } catch (ClassNotFoundException cnfEx) { + return true; + } + return false; + } + + public void testMatching() { + if (needToSkip) return; + + assertTrue("Map+ matches Map",tpm.matches(Map.class)); + assertTrue("Map+ matches HashMap",tpm.matches(HashMap.class)); + assertFalse("Map+ does not match String",tpm.matches(String.class)); + } + + protected void setUp() throws Exception { + super.setUp(); + needToSkip = needToSkipPointcutParserTests(); + if (needToSkip) return; + PointcutParser pp = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader()); + tpm = pp.parseTypePattern("java.util.Map+"); + } + + + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/AbstractCacheBackingTestSupport.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/AbstractCacheBackingTestSupport.java new file mode 100644 index 000000000..5ad69a91d --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/AbstractCacheBackingTestSupport.java @@ -0,0 +1,379 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Lyor Goldstein (vmware) add support for weaved class being re-defined + *******************************************************************************/ +package org.aspectj.weaver.tools.cache; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.io.StreamCorruptedException; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.security.CodeSource; +import java.security.ProtectionDomain; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import junit.framework.TestCase; + +import org.aspectj.util.FileUtil; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.tools.cache.AbstractIndexedFileCacheBacking.IndexEntry; + +/** + */ +public abstract class AbstractCacheBackingTestSupport extends TestCase { + public static final String JAR_FILE_SUFFIX=".jar"; + /** + * Prefix used in URL(s) that reference a resource inside a JAR + */ + public static final String JAR_URL_PREFIX="jar:"; + /** + * Separator used in URL(s) that reference a resource inside a JAR + * to denote the sub-path inside the JAR + */ + public static final char RESOURCE_SUBPATH_SEPARATOR='!'; + + private File targetFolder; + private File testTempFolder; + protected File root; + + public static final String TEMP_SUBFOLDER_NAME="temp"; + + protected AbstractCacheBackingTestSupport() { + super(); + } + + protected AbstractCacheBackingTestSupport(String name) { + super(name); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + if (root == null) { + root = createTempFile("aspectj", "testdir"); + FileUtil.deleteContents(root); + } + } + + @Override + public void tearDown() throws Exception { + if (root != null) { + FileUtil.deleteContents(root); + root = null; + } + + if (targetFolder != null) { + FileUtil.deleteContents(targetFolder); + } + + super.tearDown(); + } + + protected File ensureTempFolderExists () throws IllegalStateException { + synchronized(TEMP_SUBFOLDER_NAME) { + if (testTempFolder == null) { + File parent=detectTargetFolder(); + testTempFolder = new File(parent, TEMP_SUBFOLDER_NAME); + } + } + + return ensureFolderExists(testTempFolder); + } + + protected File detectTargetFolder () throws IllegalStateException { + synchronized(TEMP_SUBFOLDER_NAME) { + if (targetFolder == null) { + if ((targetFolder=detectTargetFolder(getClass())) == null) { + throw new IllegalStateException("Failed to detect target folder"); + } + } + } + + return targetFolder; + } + + protected File createTempFile (String prefix, String suffix) throws IOException { + File destFolder=ensureTempFolderExists(); + return File.createTempFile(prefix, suffix, destFolder); + } + + public static final File ensureFolderExists (File folder) throws IllegalStateException { + if (folder == null) { + throw new IllegalArgumentException("No folder to ensure existence"); + } + + if ((!folder.exists()) && (!folder.mkdirs())) { + throw new IllegalStateException("Failed to create " + folder.getAbsolutePath()); + } + + return folder; + } + /** + * @param anchor An anchor {@link Class} whose container we want to use + * as the starting point for the "target" folder lookup up the + * hierarchy + * @return The "target" folder - null if not found + * @see #detectTargetFolder(File) + */ + public static final File detectTargetFolder (Class anchor) { + return detectTargetFolder(getClassContainerLocationFile(anchor)); + } + + /** + * @param anchorFile An anchor {@link File) we want to use + * as the starting point for the "target" folder lookup up the + * hierarchy + * @return The "target" folder - null if not found + */ + public static final File detectTargetFolder (File anchorFile) { + for (File file=anchorFile; file != null; file=file.getParentFile()) { + if (!file.isDirectory()) { + continue; + } + + String name=file.getName(); + if ("target".equals(name) || "bin".equals(name) || "src".equals(name)) { + File parent=file.getParentFile(); + return new File(parent, "target2"); + } + } + + return null; + } + + /** + * @param clazz A {@link Class} object + * @return A {@link File} of the location of the class bytes container + * - e.g., the root folder, the containing JAR, etc.. Returns + * null if location could not be resolved + * @throws IllegalArgumentException If location is not a valid + * {@link File} location + * @see #getClassContainerLocationURI(Class) + * @see File#File(URI) + */ + public static File getClassContainerLocationFile (Class clazz) + throws IllegalArgumentException { + try { + URI uri=getClassContainerLocationURI(clazz); + return (uri == null) ? null : new File(uri); + } catch(URISyntaxException e) { + throw new IllegalArgumentException(e.getClass().getSimpleName() + ": " + e.getMessage(), e); + } + } + + /** + * @param clazz A {@link Class} object + * @return A {@link URI} to the location of the class bytes container + * - e.g., the root folder, the containing JAR, etc.. Returns + * null if location could not be resolved + * @throws URISyntaxException if location is not a valid URI + * @see #getClassContainerLocationURL(Class) + */ + public static URI getClassContainerLocationURI (Class clazz) throws URISyntaxException { + URL url=getClassContainerLocationURL(clazz); + return (url == null) ? null : url.toURI(); + } + + /** + * @param clazz A {@link Class} object + * @return A {@link URL} to the location of the class bytes container + * - e.g., the root folder, the containing JAR, etc.. Returns + * null if location could not be resolved + */ + public static URL getClassContainerLocationURL (Class clazz) { + ProtectionDomain pd=clazz.getProtectionDomain(); + CodeSource cs=(pd == null) ? null : pd.getCodeSource(); + URL url=(cs == null) ? null : cs.getLocation(); + if (url == null) { + ClassLoader cl=getDefaultClassLoader(clazz); + String className=clazz.getName().replace('.', '/') + ".class"; + if ((url=cl.getResource(className)) == null) { + return null; + } + + String srcForm=getURLSource(url); + if (LangUtil.isEmpty(srcForm)) { + return null; + } + + try { + url = new URL(srcForm); + } catch(MalformedURLException e) { + throw new IllegalArgumentException("getClassContainerLocationURL(" + clazz.getName() + ")" + + "Failed to create URL=" + srcForm + " from " + url.toExternalForm() + + ": " + e.getMessage()); + } + } + + return url; + } + /** + * @param anchor An "anchor" {@link Class} to be used in case + * no thread context loader is available + * @return A {@link ClassLoader} to be used by the caller. The loader is + * resolved in the following manner:


+ *
    + *
  • + * If a non-null loader is returned from the + * {@link Thread#getContextClassLoader()} call then use it. + *
  • + * + *
  • + * Otherwise, use the same loader that was used to load the anchor class. + *
  • + *
+ * @throws IllegalArgumentException if no anchor class provided (regardless of + * whether it is used or not) + */ + public static ClassLoader getDefaultClassLoader(Class anchor) { + if (anchor == null) { + throw new IllegalArgumentException("No anchor class provided"); + } + + Thread t=Thread.currentThread(); + ClassLoader cl=t.getContextClassLoader(); + if (cl == null) { + // No thread context class loader -> use class loader of this class. + cl = anchor.getClassLoader(); + } + + if (cl == null) { // no class loader - assume system + cl = ClassLoader.getSystemClassLoader(); + } + + return cl; + + } + public static final String getURLSource (File file) { + return getURLSource((file == null) ? null : file.toURI()); + } + + public static final String getURLSource (URI uri) { + return getURLSource((uri == null) ? null : uri.toString()); + } + + /** + * @param url The {@link URL} value - ignored if null + * @return The URL(s) source path where {@link #JAR_URL_PREFIX} and + * any sub-resource are stripped + * @see #getURLSource(String) + */ + public static final String getURLSource (URL url) { + return getURLSource((url == null) ? null : url.toExternalForm()); + } + + /** + * @param externalForm The {@link URL#toExternalForm()} string - ignored if + * null/empty + * @return The URL(s) source path where {@link #JAR_URL_PREFIX} and + * any sub-resource are stripped + */ + public static final String getURLSource (String externalForm) { + String url=externalForm; + if (LangUtil.isEmpty(url)) { + return url; + } + + url = stripJarURLPrefix(externalForm); + if (LangUtil.isEmpty(url)){ + return url; + } + + int sepPos=url.indexOf(RESOURCE_SUBPATH_SEPARATOR); + if (sepPos < 0) { + return adjustURLPathValue(url); + } else { + return adjustURLPathValue(url.substring(0, sepPos)); + } + } + + /** + * @param path A URL path value + * @return The path after stripping any trailing '/' provided the path + * is not '/' itself + */ + public static final String adjustURLPathValue(final String path) { + final int pathLen=LangUtil.isEmpty(path) ? 0 : path.length(); + if ((pathLen <= 1) || (path.charAt(pathLen - 1) != '/')) { + return path; + } + + return path.substring(0, pathLen - 1); + } + + public static final String adjustURLPathValue(URL url) { + return adjustURLPathValue((url == null) ? null : url.getPath()); + } + + public static String stripJarURLPrefix(String externalForm) { + String url=externalForm; + if (LangUtil.isEmpty(url)) { + return url; + } + + if (url.startsWith(JAR_URL_PREFIX)) { + return url.substring(JAR_URL_PREFIX.length()); + } + + return url; + } + + protected static final void writeIndex (File indexFile, IndexEntry ... entries) throws IOException { + writeIndex(indexFile, LangUtil.isEmpty(entries) ? Collections.emptyList() : Arrays.asList(entries)); + } + + protected static final void writeIndex (File indexFile, Collection entries) throws IOException { + File indexDir=indexFile.getParentFile(); + if ((!indexDir.exists()) && (!indexDir.mkdirs())) { + throw new IOException("Failed to create path to " + indexFile.getAbsolutePath()); + } + + int numEntries=LangUtil.isEmpty(entries) ? 0 : entries.size(); + IndexEntry[] entryValues=(numEntries <= 0) ? null : entries.toArray(new IndexEntry[numEntries]); + // if no entries, simply delete the index file + if (LangUtil.isEmpty(entryValues)) { + if (indexFile.exists() && (!indexFile.delete())) { + throw new StreamCorruptedException("Failed to clean up index file at " + indexFile.getAbsolutePath()); + } + + return; + } + + ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(indexFile), 4096)); + try { + oos.writeObject(entryValues); + } finally { + oos.close(); + } + } + + public static final void assertArrayEquals (String msg, byte[] expected, byte[] actual) { + int eLen=LangUtil.isEmpty(expected) ? 0 : expected.length; + int aLen=LangUtil.isEmpty(actual) ? 0 : expected.length; + assertEquals(msg + "[mismatched length]", eLen, aLen); + + for (int index=0; index < eLen; index++) { + byte eb=expected[index], ab=actual[index]; + if (eb != ab) { + fail(msg + ": Mismatched value at index=" + index + + " - " + ab + " instead of " + eb + + ": expected=" + Arrays.toString(expected) + ", actual=" + Arrays.toString(actual)); + } + } + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/AsynchronousFileCacheBackingTestSupport.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/AsynchronousFileCacheBackingTestSupport.java new file mode 100644 index 000000000..7d1b66407 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/AsynchronousFileCacheBackingTestSupport.java @@ -0,0 +1,193 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Lyor Goldstein (vmware) add support for weaved class being re-defined + *******************************************************************************/ +package org.aspectj.weaver.tools.cache; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; +import java.util.Random; +import java.util.TreeMap; + +import org.aspectj.util.FileUtil; +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.tools.cache.AbstractIndexedFileCacheBacking.IndexEntry; + +/** + */ +public abstract class AsynchronousFileCacheBackingTestSupport + extends AbstractCacheBackingTestSupport { + private File cacheDir, indexFile; + protected final byte[] bytes=new byte[Byte.MAX_VALUE]; + protected final Random random=new Random(System.nanoTime()); + + protected AsynchronousFileCacheBackingTestSupport() { + super(); + } + + protected AsynchronousFileCacheBackingTestSupport(String name) { + super(name); + } + + @Override + public void setUp () throws Exception { + super.setUp(); + cleanupCache(); + + random.nextBytes(bytes); + } + + @Override + public void tearDown () throws Exception { + cleanupCache(); + super.tearDown(); + } + + protected void cleanupCache() { + if (indexFile != null) { + if (FileUtil.deleteContents(indexFile) > 0) { + System.out.println("Deleted " + indexFile); + } + indexFile = null; + } + + if (cacheDir != null) { + if (FileUtil.deleteContents(cacheDir) > 0) { + System.out.println("Deleted " + cacheDir); + } + cacheDir = null; + } + } + + protected File getIndexFile () { + if (indexFile == null) { + File parent=getCacheDir(); + indexFile=new File(parent, AbstractIndexedFileCacheBacking.INDEX_FILE); + } + + return indexFile; + } + + protected File getCacheDir () { + if (cacheDir == null) { + File targetDir=detectTargetFolder(); + cacheDir = new File(targetDir, "dir-" + String.valueOf(Math.random())); + } + + return ensureFolderExists(cacheDir); + } + + protected abstract AsynchronousFileCacheBacking createFileBacking (File dir); + + public void testDeleteIndexFileOnEmptyIndex () throws Exception { + IndexEntry[] entries={ + createIndexEntry("weaved-empty", false, false, bytes, bytes), + createIndexEntry("generated-empty", true, false, bytes, bytes) + }; + File cacheIndex=getIndexFile(); + writeIndex(cacheIndex, entries); + assertTrue("No initial index file available: " + cacheIndex, cacheIndex.canRead()); + + AsynchronousFileCacheBacking cache=createFileBacking(getCacheDir()); + // the call should read an empty index since no data files exist + Map indexMap=cache.getIndexMap(); + assertEquals("Mismatched index size", 0, indexMap.size()); + + // no data files were created + Map bytesMap=cache.getBytesMap(); + assertEquals("Mismatched bytes size", 0, bytesMap.size()); + + writeIndex(cache.getIndexFile(), cache.getIndexEntries()); + + assertFalse("Index file still available: " + cacheIndex, cacheIndex.canRead()); + } + + protected long generateNewBytes () { + final long CRC=AbstractCacheBacking.crc(bytes); + long crc=CRC; + // 8 tries should be enough to find a non-matching CRC... + for (int index=0; (index < Byte.SIZE) && (CRC == crc) && (crc != -1L); index++) { + random.nextBytes(bytes); + crc = AbstractCacheBacking.crc(bytes); + } + assertTrue("Could not generate different CRC for " + CRC, crc != CRC); + + return crc; + } + + protected Map createDataFiles (IndexEntry ... entries) throws IOException { + return createDataFiles(LangUtil.isEmpty(entries) ? Collections.emptyList() : Arrays.asList(entries)); + } + + protected Map createDataFiles (Collection entries) throws IOException { + if (LangUtil.isEmpty(entries)) { + return Collections.emptyMap(); + } + + Map files=new TreeMap(); + for (IndexEntry entry : entries) { + File file=createDataFile(entry); + if (file != null) { + files.put(entry.key, file); + } + } + + return files; + } + + protected File createDataFile (IndexEntry entry) throws IOException { + return createDataFile(entry, entry.ignored ? null : bytes); + } + + protected File createDataFile (IndexEntry entry, byte[] dataBytes) throws IOException { + return createDataFile(entry.key, dataBytes); + } + + protected File createDataFile (String key, byte[] dataBytes) throws IOException { + if (LangUtil.isEmpty(dataBytes)) { + return null; + } + + File parent=getCacheDir(), file=new File(parent, key); + OutputStream out=new FileOutputStream(file); + try { + out.write(dataBytes); + } finally { + out.close(); + } + + return file; + } + + protected static final IndexEntry createIgnoredEntry (String key) { + return createIndexEntry(key, false, true, null, null); + } + + protected static final IndexEntry createIndexEntry (String key, boolean generated, boolean ignored, byte[] bytes, byte[] originalBytes) { + IndexEntry entry=new IndexEntry(); + entry.key = key; + entry.generated = generated; + entry.ignored = ignored; + if (ignored) { + assertFalse(key + " ignored cannot be generated", generated); + } else { + entry.crcClass = AbstractCacheBacking.crc(originalBytes); + entry.crcWeaved = AbstractCacheBacking.crc(bytes); + } + + return entry; + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultCacheKeyResolverTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultCacheKeyResolverTest.java new file mode 100644 index 000000000..139488b3c --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultCacheKeyResolverTest.java @@ -0,0 +1,95 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * John Kew (vmware) initial implementation + *******************************************************************************/ + +package org.aspectj.weaver.tools.cache; + +import junit.framework.TestCase; + +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Arrays; +import java.util.Collections; + +/** + */ +public class DefaultCacheKeyResolverTest extends TestCase { + byte[] FAKE_BYTES = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + String FAKE_CLASS = "com.example.foo.Bar"; + + DefaultCacheKeyResolver resolver = new DefaultCacheKeyResolver(); + + class BasicTestCL extends ClassLoader { + public BasicTestCL () { + super(); + } + } + + class URLTestCL extends URLClassLoader { + public URLTestCL(URL... urls) { + super(urls); + } + } + + + public void testNonURLClassLoaderScope() throws Exception { + String scope = resolver.createClassLoaderScope(new BasicTestCL(), Collections.emptyList()); + assertTrue(scope.startsWith(BasicTestCL.class.getSimpleName())); + } + + public void testCreateURLClassLoaderScope() throws Exception { + URL testURLA = new URL("http://example.com"); + URL testURLB = new URL("file:///tmp"); + URL testURLC = new URL("ftp://ftp.example.com"); + URLTestCL A = new URLTestCL(testURLA); + URLTestCL AB = new URLTestCL(testURLA, testURLB); + URLTestCL BC = new URLTestCL(testURLB, testURLC); + URLTestCL BC2 = new URLTestCL(testURLC, testURLB); + String[] a = {"one", "two", "three", "four"}; + String[] a2 = {"one", "two", "three"}; + String scopeAa = resolver.createClassLoaderScope(A, Arrays.asList(a)); + String scopeABa = resolver.createClassLoaderScope(AB, Arrays.asList(a)); + String scopeBCa = resolver.createClassLoaderScope(BC, Arrays.asList(a)); + String scopeBC2a = resolver.createClassLoaderScope(BC2, Arrays.asList(a)); + String scopeAa2 = resolver.createClassLoaderScope(A, Arrays.asList(a2)); + String scopeABa2 = resolver.createClassLoaderScope(AB, Arrays.asList(a2)); + String scopeBCa2 = resolver.createClassLoaderScope(BC, Arrays.asList(a2)); + String scopeBC2a2 = resolver.createClassLoaderScope(BC2, Arrays.asList(a2)); + + assertFalse(scopeAa.equals(scopeABa)); + assertFalse(scopeAa.equals(scopeBCa)); + assertFalse(scopeABa.equals(scopeBCa)); + assertTrue(scopeBC2a.equals(scopeBCa)); + assertFalse(scopeAa.equals(scopeAa2)); + assertFalse(scopeABa.equals(scopeABa2)); + assertFalse(scopeBCa.equals(scopeBCa2)); + assertFalse(scopeBC2a.equals(scopeBC2a2)); + + + } + + + public void testCreateGeneratedCacheKey() throws Exception { + CachedClassReference ref = resolver.generatedKey(FAKE_CLASS); + assertTrue(ref.getKey().startsWith(FAKE_CLASS)); + assertTrue(ref.getKey().matches(resolver.getGeneratedRegex())); + assertEquals(FAKE_CLASS, resolver.keyToClass(ref.getKey())); + } + + public void testCreateCacheKey() throws Exception { + // crc hashing + CachedClassReference ref = resolver.weavedKey(FAKE_CLASS, FAKE_BYTES); + assertTrue("key " + ref.getKey() + " does not match " + resolver.getWeavedRegex(), ref.getKey().matches(resolver.getWeavedRegex())); + String className = resolver.keyToClass(ref.getKey()); + assertEquals("class " + FAKE_CLASS + " != " + className, FAKE_CLASS, className); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultFileCacheBackingTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultFileCacheBackingTest.java new file mode 100644 index 000000000..2d5ec0c77 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultFileCacheBackingTest.java @@ -0,0 +1,179 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * John Kew (vmware) initial implementation + * Lyor Goldstein (vmware) add support for weaved class being re-defined + *******************************************************************************/ + +package org.aspectj.weaver.tools.cache; + +import java.io.File; +import java.util.zip.CRC32; + +import org.aspectj.util.LangUtil; +import org.aspectj.weaver.tools.cache.AbstractIndexedFileCacheBacking.IndexEntry; + +/** + */ +public class DefaultFileCacheBackingTest extends AbstractCacheBackingTestSupport { + private final byte[] FAKE_BYTES = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + private final String FAKE_CLASS = "com.example.foo.Bar"; + private final CacheKeyResolver resolver = new DefaultCacheKeyResolver(); + private final CachedClassReference fakeRef = resolver.weavedKey(FAKE_CLASS, FAKE_BYTES); + private final String fakeKey=fakeRef.getKey(); + + public DefaultFileCacheBackingTest () { + super(); + } + + public void testCreateBacking() throws Exception { + CacheBacking backing = DefaultFileCacheBacking.createBacking(root); + assertNotNull(backing); + assertTrue("Root folder not created: " + root, root.exists()); + assertTrue("Root folder not a directory: " + root, root.isDirectory()); + } + + public void testClear() { + CacheBacking backing = DefaultFileCacheBacking.createBacking(root); + backing.put(new CachedClassEntry(fakeRef, FAKE_BYTES, CachedClassEntry.EntryType.WEAVED), FAKE_BYTES); + assertNotNull(backing.get(fakeRef, FAKE_BYTES)); + backing.clear(); + assertNull(backing.get(fakeRef, FAKE_BYTES)); + } + + private CachedClassEntry createTestEntry(String key) { + return new CachedClassEntry(new CachedClassReference(key, key), FAKE_BYTES, CachedClassEntry.EntryType.WEAVED); + } + + public void testGetKeys() throws Exception { + CacheBacking backing = DefaultFileCacheBacking.createBacking(root); + backing.put(createTestEntry("apple"), FAKE_BYTES); + backing.put(createTestEntry("apply"), FAKE_BYTES); + backing.put(createTestEntry("orange"), FAKE_BYTES); + String[] matches = backing.getKeys("app.*"); + assertEquals(2, matches.length); + matches = backing.getKeys("orange"); + assertEquals(1, matches.length); + assertEquals("orange", matches[0]); + } + + public void testPut() throws Exception { + CacheBacking backing = DefaultFileCacheBacking.createBacking(root); + backing.put(new CachedClassEntry(fakeRef, FAKE_BYTES, CachedClassEntry.EntryType.WEAVED), FAKE_BYTES); + File cachedFile = new File(root, fakeKey); + assertTrue(cachedFile.exists()); + assertTrue(cachedFile.isFile()); + assertEquals(FAKE_BYTES.length, cachedFile.length()); + } + + public void testGet() throws Exception { + DefaultFileCacheBacking backing = DefaultFileCacheBacking.createBacking(root); + assertNull(backing.get(fakeRef, FAKE_BYTES)); + backing.put(new CachedClassEntry(fakeRef, FAKE_BYTES, CachedClassEntry.EntryType.WEAVED), FAKE_BYTES); + File cachedFile = new File(root, fakeKey); + assertTrue(cachedFile.isFile()); + assertEquals(FAKE_BYTES.length, cachedFile.length()); + CRC32 expectedCRC = new CRC32(); + expectedCRC.update(FAKE_BYTES); + assertTrue(indexEntryExists(backing, fakeKey, expectedCRC.getValue())); + CachedClassEntry entry = backing.get(fakeRef, FAKE_BYTES); + assertEquals(FAKE_BYTES.length, entry.getBytes().length); + } + + public void testRemove() throws Exception { + DefaultFileCacheBacking backing = DefaultFileCacheBacking.createBacking(root); + backing.put(new CachedClassEntry(fakeRef, FAKE_BYTES, CachedClassEntry.EntryType.WEAVED), FAKE_BYTES); + File cachedFile = new File(root, fakeKey); + assertTrue("Cached file not found: " + cachedFile, cachedFile.exists()); + assertTrue("Cached file not a file: " + cachedFile, cachedFile.isFile()); + CRC32 expectedCRC = new CRC32(); + expectedCRC.update(FAKE_BYTES); + assertTrue("Cached entry index not found", indexEntryExists(backing, fakeKey, expectedCRC.getValue())); + backing.remove(fakeRef); + + assertFalse("CacheFile Still exists: " + cachedFile, cachedFile.exists()); + assertFalse("Cached file is a file: " + cachedFile, cachedFile.isFile()); + assertFalse("Cached entry index not removed", indexEntryExists(backing, fakeKey, expectedCRC.getValue())); + } + + public void testMultiFile() throws Exception { + CachedClassEntry entry; + File cachedFile; + CRC32 expectedCRC = new CRC32(); + expectedCRC.update(FAKE_BYTES); + DefaultFileCacheBacking backing = DefaultFileCacheBacking.createBacking(root); + // add weaved + CachedClassReference wref = resolver.weavedKey(FAKE_CLASS + "WEAVED", FAKE_BYTES); + entry = new CachedClassEntry(wref, FAKE_BYTES, CachedClassEntry.EntryType.WEAVED); + backing.put(entry, FAKE_BYTES); + cachedFile = new File(root, wref.getKey()); + assertTrue(cachedFile.exists()); + assertTrue(cachedFile.isFile()); + assertTrue(indexEntryExists(backing, wref.getKey(), expectedCRC.getValue())); + + // add generated + CachedClassReference gref = resolver.generatedKey(FAKE_CLASS + "GENERATED"); + entry = new CachedClassEntry(gref, FAKE_BYTES, CachedClassEntry.EntryType.GENERATED); + backing.put(entry, FAKE_BYTES); + cachedFile = new File(root, gref.getKey()); + assertTrue(cachedFile.exists()); + assertTrue(cachedFile.isFile()); + assertTrue(indexEntryExists(backing, gref.getKey(), expectedCRC.getValue())); + + // add ignored + CachedClassReference iref = resolver.generatedKey(FAKE_CLASS + "IGNORED"); + entry = new CachedClassEntry(iref, FAKE_BYTES, CachedClassEntry.EntryType.IGNORED); + backing.put(entry, FAKE_BYTES); + cachedFile = new File(root, iref.getKey()); + assertFalse(cachedFile.exists()); + assertTrue(indexEntryExists(backing, iref.getKey(), expectedCRC.getValue())); + + backing.remove(wref); + backing.remove(gref); + backing.remove(iref); + } + + public void testOriginalClassBytesChanged () { + DefaultFileCacheBacking backing = DefaultFileCacheBacking.createBacking(root); + backing.put(new CachedClassEntry(fakeRef, FAKE_BYTES, CachedClassEntry.EntryType.WEAVED), FAKE_BYTES); + + CachedClassEntry entry = backing.get(fakeRef, FAKE_BYTES); + assertNotNull("No initial entry", entry); + + byte[] newBytes=new byte[FAKE_BYTES.length]; + for (int index=0; index < FAKE_BYTES.length; index++) { + newBytes[index] = (byte) (0 - FAKE_BYTES[index]); + } + + entry = backing.get(fakeRef, newBytes); + assertNull("Unexpected modified bytes entry: " + entry, entry); + + File cachedFile = new File(root, fakeKey); + assertFalse("Cache file not removed", cachedFile.exists()); + } + + private boolean indexEntryExists(AbstractIndexedFileCacheBacking cache, String key, long expectedCRC) throws Exception { + long storedCRC = 0L; + IndexEntry[] index = cache.readIndex(new File(root, AbstractIndexedFileCacheBacking.INDEX_FILE)); + if (LangUtil.isEmpty(index)) { + return false; + } + + for (IndexEntry ie : index) { + if (ie.key.equals(key)) { + storedCRC = ie.crcWeaved; + if (!ie.ignored) { + assertEquals(expectedCRC, storedCRC); + } + return true; + } + } + return false; + } +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/FlatFileCacheBackingTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/FlatFileCacheBackingTest.java new file mode 100644 index 000000000..87daff796 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/FlatFileCacheBackingTest.java @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2012 VMware, Inc. + * + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lyor Goldstein + *******************************************************************************/ + +package org.aspectj.weaver.tools.cache; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; +import java.util.TreeMap; + +import org.aspectj.weaver.tools.cache.AbstractIndexedFileCacheBacking.IndexEntry; + +/** + * @author Lyor Goldstein + */ +public class FlatFileCacheBackingTest extends AsynchronousFileCacheBackingTestSupport { + public FlatFileCacheBackingTest() { + super(); + } + + @Override + protected FlatFileCacheBacking createFileBacking(File dir) { + return new FlatFileCacheBacking(dir); + } + + public void testReadIndex() throws IOException { + IndexEntry[] entries = { createIgnoredEntry("ignored"), createIndexEntry("weaved", false, false, bytes, bytes), + createIndexEntry("generated", true, false, bytes, bytes) }; + File indexFile = getIndexFile(); + writeIndex(indexFile, entries); + Map dataFiles = createDataFiles(entries); + + File cacheDir = getCacheDir(); + AsynchronousFileCacheBacking cache = createFileBacking(cacheDir); + Map indexMap = cache.getIndexMap(); + assertEquals("Mismatched index size", entries.length, indexMap.size()); + + Map bytesMap = cache.getBytesMap(); + assertEquals("Mismatched bytes size", dataFiles.size() /* the ignored one has no file */, bytesMap.size()); + + for (IndexEntry entry : entries) { + String key = entry.key; + assertNotNull("Missing entry for key=" + key, indexMap.get(key)); + + if (entry.ignored) { + assertNull("Unexpected bytes for ignored key=" + key, bytesMap.get(key)); + } else { + assertArrayEquals("Mismatched contents for key=" + key, bytes, bytesMap.get(key)); + } + } + } + + public void testIgnoredBadCrcDataFiles() throws Exception { + IndexEntry[] entries = { createIndexEntry("weaved-goodData", false, false, bytes, bytes), + createIndexEntry("badData-weaved", false, false, bytes, bytes), + createIndexEntry("generated-goodData", true, false, bytes, bytes), + createIndexEntry("badData-generated", true, false, bytes, bytes) }; + File indexFile = getIndexFile(); + writeIndex(indexFile, entries); + + Map dataFiles = createDataFiles(entries); + long newCrc = generateNewBytes(); + assertTrue("Bad new CRC", newCrc != (-1L)); + + Map badFiles = new TreeMap(); + for (IndexEntry entry : entries) { + String key = entry.key; + if (key.startsWith("badData")) { + File file = dataFiles.get(key); + OutputStream out = new FileOutputStream(file); + try { + out.write(bytes); + } finally { + out.close(); + } + dataFiles.remove(key); + badFiles.put(key, file); + } + } + + File cacheDir = getCacheDir(); + FlatFileCacheBacking cache = createFileBacking(cacheDir); + Map indexMap = cache.getIndexMap(); + assertEquals("Mismatched index size", dataFiles.size(), indexMap.size()); + + Map bytesMap = cache.getBytesMap(); + assertEquals("Mismatched bytes size", dataFiles.size(), bytesMap.size()); + + for (Map.Entry badEntry : badFiles.entrySet()) { + String key = badEntry.getKey(); + assertFalse("Unexpectedly indexed: " + key, indexMap.containsKey(key)); + assertFalse("Unexpectedly loaded: " + key, bytesMap.containsKey(key)); + + File file = badEntry.getValue(); + assertFalse("Unexpectedly still readable: " + key, file.canRead()); + } + } + + public void testSkipMissingDataFileOnReadIndex() throws IOException { + IndexEntry[] entries = { createIndexEntry("weaved-noData", false, false, null, null), + createIndexEntry("withData-weaved", false, false, bytes, bytes), + createIndexEntry("generated-noData", true, false, null, null), + createIndexEntry("withData-generated", true, false, bytes, bytes) }; + File indexFile = getIndexFile(); + writeIndex(indexFile, entries); + + Map dataFiles = new TreeMap(); + for (IndexEntry entry : entries) { + String key = entry.key; + if (key.startsWith("withData")) { + dataFiles.put(key, createDataFile(entry, bytes)); + } + } + + File cacheDir = getCacheDir(); + FlatFileCacheBacking cache = createFileBacking(cacheDir); + Map indexMap = cache.getIndexMap(); + assertEquals("Mismatched index size", dataFiles.size(), indexMap.size()); + + Map bytesMap = cache.getBytesMap(); + assertEquals("Mismatched bytes size", dataFiles.size(), bytesMap.size()); + + for (IndexEntry entry : entries) { + String key = entry.key; + if (key.startsWith("withData")) { + assertTrue("Not indexed: " + key, indexMap.containsKey(key)); + assertTrue("Not loaded: " + key, bytesMap.containsKey(key)); + } else { + assertFalse("Unexpectedly indexed: " + key, indexMap.containsKey(key)); + assertFalse("Unexpectedly loaded: " + key, bytesMap.containsKey(key)); + } + } + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/SimpleClassCacheTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/SimpleClassCacheTest.java new file mode 100644 index 000000000..68fac6913 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/SimpleClassCacheTest.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * Abraham Nevado (lucierna) initial implementation + ********************************************************************************/ + +package org.aspectj.weaver.tools.cache; + +import java.io.File; + +import junit.framework.TestCase; + +/** + */ +public class SimpleClassCacheTest extends TestCase { + byte[] FAKE_BYTES_V1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + byte[] FAKE_BYTES_V2 = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + byte[] FAKE_WOVEN_BYTES_V1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10}; + byte[] FAKE_WOVEN_BYTES_V2 = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9,10}; + + + private SimpleCache createCache() throws Exception { + return new SimpleCache(System.getProperty("java.io.tmpdir"),true); + } + + + public void testCache() throws Exception { + String classA = "com.generated.A"; + SimpleCache cache = createCache(); + + cache.put(classA, FAKE_BYTES_V1, FAKE_WOVEN_BYTES_V1); + + + // Test the returned woven bytes are the original one + byte result[] = cache.getAndInitialize(classA, FAKE_BYTES_V1, null, null); + for(int i = 0; i < result.length; i ++){ + assertEquals("Cached version byte[" +i+"] should be equal to the original woven classe",result[i],FAKE_WOVEN_BYTES_V1[i]); + } + + // Assure the class is properly backed up in the backing folder + File f = new File (System.getProperty("java.io.tmpdir") + File.separator + "com.generated.A-1164760902"); + assertTrue("Class should be backed up to backing folder, with te CRC:1164760902 ",f.exists()); + + } + + public void testDifferentVersionCache() throws Exception { + String classA = "com.generated.A"; + SimpleCache cache = createCache(); + cache.put(classA, FAKE_BYTES_V1, FAKE_WOVEN_BYTES_V1); + cache.put(classA, FAKE_BYTES_V2, FAKE_WOVEN_BYTES_V2); + + // Test the returned woven bytes are the original one for v1 + byte result[] = cache.getAndInitialize(classA, FAKE_BYTES_V1, null, null); + for(int i = 0; i < result.length; i ++){ + assertEquals("Cached version v1 byte[" +i+"] should be equal to the original woven classe",result[i],FAKE_WOVEN_BYTES_V1[i]); + } + + // Test the returned woven bytes are the original one for v2 + result = cache.getAndInitialize(classA, FAKE_BYTES_V2, null, null); + for(int i = 0; i < result.length; i ++){ + assertEquals("Cached version v2 byte[" +i+"] should be equal to the original woven classe",result[i],FAKE_WOVEN_BYTES_V2[i]); + } + } +} \ No newline at end of file diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/WeavedClassCacheTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/WeavedClassCacheTest.java new file mode 100644 index 000000000..a02400eb8 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/WeavedClassCacheTest.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2012 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: + * John Kew (vmware) initial implementation + *******************************************************************************/ + +package org.aspectj.weaver.tools.cache; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.aspectj.bridge.AbortException; +import org.aspectj.bridge.IMessage; +import org.aspectj.bridge.IMessageHandler; +import org.aspectj.weaver.tools.GeneratedClassHandler; + +/** + */ +public class WeavedClassCacheTest extends AbstractCacheBackingTestSupport { + String FAKE_CLASS = "com.example.foo.Bar"; + byte[] FAKE_BYTES = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + + public WeavedClassCacheTest () { + super(); + } + + public class MemoryCacheBacking implements CacheBacking { + HashMap cache = new HashMap(); + + public String[] getKeys(String regex) { + Set keys = cache.keySet(); + List matches = new LinkedList(); + for (String key : keys) { + if (key.matches(regex)) { + matches.add(key); + } + } + return matches.toArray(new String[0]); + } + + public void remove(CachedClassReference ref) { + cache.remove(ref.getKey()); + } + + public void clear() { + cache.clear(); + } + + public CachedClassEntry get(CachedClassReference ref, byte[] originalBytes) { + return cache.get(ref.getKey()); + } + + public void put(CachedClassEntry entry, byte[] originalBytes) { + assertNotNull("put(" + entry + ") no original bytes", originalBytes); + cache.put(entry.getKey(), entry); + } + } + + MemoryCacheBacking memoryBacking = new MemoryCacheBacking(); + + IMessageHandler messageHandler = new IMessageHandler() { + public boolean handleMessage(IMessage message) throws AbortException { + return true; + } + + public boolean isIgnoring(IMessage.Kind kind) { + return true; + } + + public void dontIgnore(IMessage.Kind kind) { + // do nothing + } + + public void ignore(IMessage.Kind kind) { + // do nothing + } + }; + + public class TestGeneratedClassHandler implements GeneratedClassHandler { + public int accepts = 0; + public List classesISaw = new LinkedList(); + + public void acceptClass (String name, byte[] originalBytes, byte[] wovenBytes) { + accepts++; + classesISaw.add(name); + } + } + + TestGeneratedClassHandler generatedClassHandler = new TestGeneratedClassHandler(); + + CacheKeyResolver resolver = new DefaultCacheKeyResolver(); + + private WeavedClassCache createCache() throws Exception { + return new WeavedClassCache(generatedClassHandler, messageHandler, "test", memoryBacking, resolver); + } + + private void reset() throws Exception { + memoryBacking.cache.clear(); + generatedClassHandler.accepts = 0; + generatedClassHandler.classesISaw.clear(); + } + + public void testGetCachingClassHandler() throws Exception { + WeavedClassCache cache = createCache(); + GeneratedClassHandler newHandle = cache.getCachingClassHandler(); + assertTrue(generatedClassHandler != newHandle); + assertTrue(newHandle instanceof GeneratedCachedClassHandler); + } + + public void testCache() throws Exception { + reset(); + WeavedClassCache cache = createCache(); + CacheStatistics stats = cache.getStats(); + CachedClassReference ref = cache.createCacheKey(FAKE_CLASS, FAKE_BYTES); + assertNull(cache.get(ref, FAKE_BYTES)); + cache.put(ref, FAKE_BYTES, FAKE_BYTES); + assertNotNull(cache.get(ref, FAKE_BYTES)); + + assertEquals(new String(FAKE_BYTES), new String(cache.get(ref, FAKE_BYTES).getBytes())); + + ref = cache.createGeneratedCacheKey(FAKE_CLASS); + assertNull(cache.get(ref, FAKE_BYTES)); + cache.put(ref, FAKE_BYTES, FAKE_BYTES); + assertNotNull(cache.get(ref, FAKE_BYTES)); + assertEquals(new String(FAKE_BYTES), new String(cache.get(ref, FAKE_BYTES).getBytes())); + + assertEquals(4, stats.getHits()); + assertEquals(2, stats.getMisses()); + + + } + + public void testRemove() throws Exception { + reset(); + WeavedClassCache cache = createCache(); + CachedClassReference ref = cache.createCacheKey(FAKE_CLASS, FAKE_BYTES); + assertNull(cache.get(ref, FAKE_BYTES)); + cache.put(ref, FAKE_BYTES, FAKE_BYTES); + assertNotNull(cache.get(ref, FAKE_BYTES)); + cache.remove(ref); + assertNull(cache.get(ref, FAKE_BYTES)); + } + +} diff --git a/weaver/src/test/java/org/aspectj/weaver/tools/cache/ZippedFileCacheBackingTest.java b/weaver/src/test/java/org/aspectj/weaver/tools/cache/ZippedFileCacheBackingTest.java new file mode 100644 index 000000000..4c41c1807 --- /dev/null +++ b/weaver/src/test/java/org/aspectj/weaver/tools/cache/ZippedFileCacheBackingTest.java @@ -0,0 +1,154 @@ +/** + * Copyright (c) 2012 VMware, Inc. + * + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Lyor Goldstein + */ + +package org.aspectj.weaver.tools.cache; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import org.aspectj.util.FileUtil; +import org.aspectj.weaver.tools.cache.AbstractIndexedFileCacheBacking.IndexEntry; + +/** + * + */ +public class ZippedFileCacheBackingTest extends AsynchronousFileCacheBackingTestSupport { + private File zipTestFile; + + public ZippedFileCacheBackingTest() { + super(); + } + + public void testReadIndex () throws Exception { + IndexEntry[] entries={ + createIgnoredEntry("ignored"), + createIndexEntry("weaved", false, false, bytes, bytes), + createIndexEntry("generated", true, false, bytes, bytes) + }; + File indexFile=getIndexFile(); + writeIndex(indexFile, entries); + + Map entriesMap=new TreeMap(); + for (IndexEntry ie : entries) { + if (ie.ignored) { + continue; + } + + entriesMap.put(ie.key, bytes); + } + + File zipFile=getZipFile(); + ZippedFileCacheBacking.writeZipClassBytes(zipFile, entriesMap); + + File cacheDir=getCacheDir(); + AsynchronousFileCacheBacking cache=createFileBacking(cacheDir); + Map indexMap=cache.getIndexMap(); + assertEquals("Mismatched index size", entries.length, indexMap.size()); + + Map bytesMap=cache.getBytesMap(); + assertEquals("Mismatched bytes size", entriesMap.size() /* the ignored one has no file */, bytesMap.size()); + + for (IndexEntry entry : entries) { + String key=entry.key; + assertNotNull("Missing entry for key=" + key, indexMap.get(key)); + + if (entry.ignored) { + assertNull("Unexpected bytes for ignored key=" + key, bytesMap.get(key)); + } else { + assertArrayEquals("Mismatched contents for key=" + key, bytes, bytesMap.get(key)); + } + } + } + + public void testReadWriteZipClassBytes () throws IOException { + Map entriesMap=new TreeMap(); + for (int index=0; index < Byte.SIZE; index++) { + String name="classBytes#" + index; + random.nextBytes(bytes); + entriesMap.put(name, bytes); + } + + File zipFile=getZipFile(); + ZippedFileCacheBacking.writeZipClassBytes(zipFile, entriesMap); + + Map bytesMap=ZippedFileCacheBacking.readZipClassBytes(zipFile); + assertEquals("Mismatched recovered entries size", entriesMap.size(), bytesMap.size()); + for (Map.Entry bytesEntry : entriesMap.entrySet()) { + String key=bytesEntry.getKey(); + byte[] expected=bytesEntry.getValue(), actual=bytesMap.get(key); + assertArrayEquals("Mismatched data for " + key, expected, actual); + } + } + + public void testReadClassBytes () throws IOException { + IndexEntry[] entries={ + createIgnoredEntry("ignoredReadClassBytes"), + createIndexEntry("weavedReadClassBytes", false, false, bytes, bytes), + createIndexEntry("generatedReadClassBytes", true, false, bytes, bytes) + }; + File indexFile=getIndexFile(); + writeIndex(indexFile, entries); + + long newCrc=generateNewBytes(); + assertTrue("Bad new CRC", newCrc != (-1L)); + + Map entriesMap=new TreeMap(); + for (IndexEntry ie : entries) { + if (ie.ignored) { + continue; + } + + entriesMap.put(ie.key, bytes); + } + + File zipFile=getZipFile(); + ZippedFileCacheBacking.writeZipClassBytes(zipFile, entriesMap); + + File cacheDir=getCacheDir(); + AsynchronousFileCacheBacking cache=createFileBacking(cacheDir); + Map indexMap=cache.getIndexMap(); + assertEquals("Mismatched index size", 1 /* only the ignored entry */, indexMap.size()); + + Map bytesMap=cache.getBytesMap(); + assertEquals("Non empty data bytes", 0, bytesMap.size()); + assertFalse("Zip file not deleted: " + zipFile, zipFile.canRead()); + } + + protected File getZipFile () { + if (zipTestFile == null) { + File cacheDir=getCacheDir(); + zipTestFile = new File(cacheDir, ZippedFileCacheBacking.ZIP_FILE); + } + + return zipTestFile; + } + + @Override + protected void cleanupCache() { + if (zipTestFile != null) { + if (FileUtil.deleteContents(zipTestFile) > 0) { + System.out.println("Deleted " + zipTestFile); + } + zipTestFile = null; + } + + super.cleanupCache(); + } + + @Override + protected ZippedFileCacheBacking createFileBacking(File dir) { + return new ZippedFileCacheBacking(dir); + } +} \ No newline at end of file diff --git a/weaver/src/test/java/reflect/tests/C.java b/weaver/src/test/java/reflect/tests/C.java new file mode 100644 index 000000000..f52043b5a --- /dev/null +++ b/weaver/src/test/java/reflect/tests/C.java @@ -0,0 +1,33 @@ +/* ******************************************************************* + * 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 reflect.tests; + +/** + * @author colyer + * Part of the testdata for the org.aspectj.weaver.reflect tests + */ +public class C { + + public String foo(Object a) throws Exception { + return null; + } + + private void bar() {} + + public int f; + private String s; +} + +class D extends C implements java.io.Serializable { + public int getNumberOfThingies() { return 0; } + private Object o; +} \ No newline at end of file diff --git a/weaver/src/test/java/test/A.java b/weaver/src/test/java/test/A.java new file mode 100644 index 000000000..12959cd51 --- /dev/null +++ b/weaver/src/test/java/test/A.java @@ -0,0 +1,27 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ +package test; + +public class A { + public void a(String s) {} + public void b(@A1 String s) {} + public void c(@A1 @A2 String s) {} + public void d(@A1 String s,@A2 String t) {} + + public void e(A1AnnotatedType s) {} + public void f(A2AnnotatedType s) {} + public void g(@A2 A1AnnotatedType s) {} + public void h(@A1 A1AnnotatedType s) {} + public void i(A1AnnotatedType s,@A2 String t) {} + public void j(@A1 @A2 String s) {} + +} diff --git a/weaver/src/test/java/test/A1.java b/weaver/src/test/java/test/A1.java new file mode 100644 index 000000000..616708345 --- /dev/null +++ b/weaver/src/test/java/test/A1.java @@ -0,0 +1,20 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ +package test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface A1 { + +} diff --git a/weaver/src/test/java/test/A1AnnotatedType.java b/weaver/src/test/java/test/A1AnnotatedType.java new file mode 100644 index 000000000..e40addbf5 --- /dev/null +++ b/weaver/src/test/java/test/A1AnnotatedType.java @@ -0,0 +1,17 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ +package test; + +@A1 +public class A1AnnotatedType { + +} diff --git a/weaver/src/test/java/test/A2.java b/weaver/src/test/java/test/A2.java new file mode 100644 index 000000000..48749a3d4 --- /dev/null +++ b/weaver/src/test/java/test/A2.java @@ -0,0 +1,20 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ +package test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface A2 { + +} diff --git a/weaver/src/test/java/test/A2AnnotatedType.java b/weaver/src/test/java/test/A2AnnotatedType.java new file mode 100644 index 000000000..0fa3b5c8a --- /dev/null +++ b/weaver/src/test/java/test/A2AnnotatedType.java @@ -0,0 +1,17 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ +package test; + +@A2 +public class A2AnnotatedType { + +} diff --git a/weaver/src/test/java/test/A3.java b/weaver/src/test/java/test/A3.java new file mode 100644 index 000000000..ab54388ae --- /dev/null +++ b/weaver/src/test/java/test/A3.java @@ -0,0 +1,19 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ +package test; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +public @interface A3 { + Color value() default Color.RED; +} diff --git a/weaver/src/test/java/test/AnnoValues.java b/weaver/src/test/java/test/AnnoValues.java new file mode 100644 index 000000000..08301d1a0 --- /dev/null +++ b/weaver/src/test/java/test/AnnoValues.java @@ -0,0 +1,20 @@ +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ +package test; + +public class AnnoValues { + public void none() {} + @A3 public void defaultMethod() {} + @A3(Color.GREEN) public void greenMethod() {} + @A3(Color.RED) public void redMethod() {} + @A3(Color.BLUE) public void blueMethod() {} +} diff --git a/weaver/src/test/java/test/Color.java b/weaver/src/test/java/test/Color.java new file mode 100644 index 000000000..dea2593ac --- /dev/null +++ b/weaver/src/test/java/test/Color.java @@ -0,0 +1,14 @@ +package test; +/* ******************************************************************* + * Copyright (c) 2008 Contributors + * All rights reserved. + * This program and the accompanying materials are made available + * under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors + * Andy Clement + * ******************************************************************/ + +public enum Color { RED, GREEN, BLUE } \ No newline at end of file -- cgit v1.2.3