aboutsummaryrefslogtreecommitdiffstats
path: root/weaver/src/test
diff options
context:
space:
mode:
authorAndy Clement <aclement@pivotal.io>2019-01-25 15:14:30 -0800
committerAndy Clement <aclement@pivotal.io>2019-01-25 15:14:30 -0800
commitd3da67c03dc7d19782d60d82fdf8fc7c7895280e (patch)
treeb8c82793fa0b6843e022a126f942dc132133b3fd /weaver/src/test
parent7758d629f9bc6818709d5ae97bbb98a27c908f75 (diff)
downloadaspectj-d3da67c03dc7d19782d60d82fdf8fc7c7895280e.tar.gz
aspectj-d3da67c03dc7d19782d60d82fdf8fc7c7895280e.zip
mavenizing weaver - wip
Diffstat (limited to 'weaver/src/test')
-rw-r--r--weaver/src/test/java/$Proxy1.java28
-rw-r--r--weaver/src/test/java/CounterAspect.java52
-rw-r--r--weaver/src/test/java/GenericService.java17
-rw-r--r--weaver/src/test/java/MA.java15
-rw-r--r--weaver/src/test/java/MB.java15
-rw-r--r--weaver/src/test/java/MC.java15
-rw-r--r--weaver/src/test/java/MD.java15
-rw-r--r--weaver/src/test/java/MessageService.java13
-rw-r--r--weaver/src/test/java/fluffy/Aspect.java29
-rw-r--r--weaver/src/test/java/fluffy/Base.java18
-rw-r--r--weaver/src/test/java/fluffy/Derived.java20
-rw-r--r--weaver/src/test/java/org/aspectj/matcher/tools/ReflectionWorldAdvancedPointcutExpressionTest.java30
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/AbstractTraceTest.java153
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/AllWeaver5Tests.java40
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/BcweaverModule15Test.java41
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/BoundedReferenceTypeTestCase.java106
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/CommonReferenceTypeTests.java91
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/CommonsTraceFactoryTest.java26
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/CommonsTraceTest.java35
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/DefaultTraceFactoryTest.java30
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/DefaultTraceTest.java38
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/DumpTestCase.java147
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/GenericSignatureParserTest.java63
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/Java5ReflectionBasedReferenceTypeDelegateTest.java154
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/Jdk14TraceFactoryTest.java30
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/Jdk14TraceTest.java34
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/JoinPointSignatureIteratorTest.java107
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/LocaleTest.java53
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/Member15Test.java155
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/Member15TestCase.java81
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/MemberTestCase.java183
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java84
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/ReferenceTypeTestCase.java854
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/ResolvedMemberSignatures15TestCase.java281
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/TestShadow.java131
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/TraceFactoryTest.java31
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java81
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/TypeVariableTestCase.java110
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/TypeXTestCase.java219
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/Weaver5ModuleTests.java37
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/WeaverMessagesTestCase.java47
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/WeaverTestCase.java50
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/AfterReturningWeaveTestCase.java58
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java45
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/AfterWeaveTestCase.java31
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java119
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/AroundArgsWeaveTestCase.java41
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/AroundWeaveTestCase.java100
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java68
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/BcelTestUtils.java65
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/BcelWorldReferenceTypeTest.java23
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/BeforeWeaveTestCase.java31
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/CheckerTestCase.java48
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/ClassLoaderRepositoryTest.java213
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/FieldSetTestCase.java34
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java63
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/IdWeaveTestCase.java101
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/JImageTestCase.java139
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/MegaZipTestCase.java107
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java81
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java83
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/PatternWeaveTestCase.java122
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/PointcutResidueTestCase.java189
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/TjpWeaveTestCase.java99
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/TraceJarWeaveTestCase.java40
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/UtilityTestCase.java52
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/WeaveOrderTestCase.java149
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/WeaveTestCase.java318
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/WorldTestCase.java163
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/ZipFileWeaver.java39
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/bcel/ZipTestCase.java121
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java252
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/AnnotationPatternTestCase.java382
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/ConcretizationTestCase.java116
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/WildTypePatternResolutionTestCase.java422
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelAndOrNotTestCase.java24
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelBindingTestCase.java24
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelModifiersPatternTestCase.java24
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelParserTestCase.java25
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelSignaturePatternTestCase.java24
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternListTestCase.java23
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelTypePatternTestCase.java24
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/patterns/bcel/BcelWithinTestCase.java23
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateTest.java316
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldReferenceTypeTest.java27
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/reflect/ReflectionWorldTest.java290
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java746
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/PointcutDesignatorHandlerTest.java251
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/PointcutExpressionTest.java596
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/PointcutParserTest.java391
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/ReadingAttributesTest.java66
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/TypePatternMatcherTest.java55
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/AbstractCacheBackingTestSupport.java379
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/AsynchronousFileCacheBackingTestSupport.java193
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultCacheKeyResolverTest.java95
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/DefaultFileCacheBackingTest.java179
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/FlatFileCacheBackingTest.java147
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/SimpleClassCacheTest.java71
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/WeavedClassCacheTest.java152
-rw-r--r--weaver/src/test/java/org/aspectj/weaver/tools/cache/ZippedFileCacheBackingTest.java154
-rw-r--r--weaver/src/test/java/reflect/tests/C.java33
-rw-r--r--weaver/src/test/java/test/A.java27
-rw-r--r--weaver/src/test/java/test/A1.java20
-rw-r--r--weaver/src/test/java/test/A1AnnotatedType.java17
-rw-r--r--weaver/src/test/java/test/A2.java20
-rw-r--r--weaver/src/test/java/test/A2AnnotatedType.java17
-rw-r--r--weaver/src/test/java/test/A3.java19
-rw-r--r--weaver/src/test/java/test/AnnoValues.java20
-rw-r--r--weaver/src/test/java/test/Color.java14
109 files changed, 12159 insertions, 0 deletions
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<T extends Serializable> {
+ 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<Long> {
+
+}
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<java.util.List<java.lang.String>>[]").resolve(world);
+ ut = UnresolvedType.forSignature("[Pjava/util/List<Pjava/util/List<Ljava/lang/String;>;>;").resolve(world);
+ assertEquals("Signatures not equal ", "[Pjava/util/List<Pjava/util/List<Ljava/lang/String;>;>;", ut.getSignature());
+ assertEquals("Names not equal ", "java.util.List<java.util.List<java.lang.String>>[]", 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<methods.length;j++) {
+ ResolvedMember method = methods[j];
+ if (method.getName().equals("toArray") && method.getParameterSignature().equals("([TT;)")) {
+ i = j;
+ }
+ }
+ assertTrue("Couldn't find 'toArray' in the set of methods? ", i != -1);
+ // String expectedSignature = "java.lang.Object[] java.util.Collection.toArray(java.lang.Object[])";
+ String expectedSignature = "([Ljava/lang/Object;)[Ljava/lang/Object;";
+
+ assertTrue("Expected signature of '" + expectedSignature + "' but it was '" + methods[i].getSignatureErased(), methods[i]
+ .getSignatureErased().equals(expectedSignature));
+ }
+
+ /**
+ * Can we resolve the dreaded Enum type...
+ */
+ public void testResolveEnum() {
+ ResolvedType enumType = world.resolve("java.lang.Enum");
+ assertTrue("Should be the raw type but is " + enumType.typeKind, enumType.isRawType());
+ ResolvedType theGenericEnumType = enumType.getGenericType();
+ assertTrue("Should have a type variable ", theGenericEnumType.getTypeVariables().length > 0);
+ TypeVariable tv = theGenericEnumType.getTypeVariables()[0];
+ String expected = "TypeVar E extends java.lang.Enum<E>";
+ 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;","<T:Ljava/lang/Object;>Ljava/lang/Object;");
+ assertEquals("Porg/aspectj/weaver/MemberTestCase15$One<TT;>;",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<java.lang.String>");
+ assertNotNull(one);
+ assertFalse(one.isMissing());
+
+ // Look at the methods on the parameterized type One<String>
+ 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<Ljava/lang/String;>;",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<Ljava/lang/String;>;",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<TT;>;",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;
+ T getter() {
+ return null;
+ }
+ List<T> 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.<init>(int, java.lang.Object)");
+ kindTest(m, Member.CONSTRUCTOR);
+ declaringTypeTest(m, "Foo");
+ nameTest(m, "<init>");
+ 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<java.lang.String>.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<Ljava/lang/String;>;",returnType.getSignature());
+
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ world = new BcelWorld();
+ world.setBehaveInJava5Way(true);
+ listOfString = (ReferenceType)
+ TypeFactory.createTypeFromSignature("Pjava/util/List<Ljava/lang/String;>;").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<Ljava/lang/String;>;"));
+ ReferenceType listOfInteger = (ReferenceType) world.resolve(UnresolvedType
+ .forSignature("Pjava/util/List<Ljava/lang/Integer;>;"));
+ assertFalse(listOfInteger.isAssignableFrom(listOfString));
+ assertFalse(listOfString.isAssignableFrom(listOfInteger));
+ assertFalse(listOfInteger.isCoerceableFrom(listOfString));
+ assertFalse(listOfString.isCoerceableFrom(listOfInteger));
+ }
+
+ public void testAssignable01() {
+ List list = new ArrayList();
+ List<String> listOfString = new ArrayList<String>();
+ List<?> listOfSomething = new ArrayList<Integer>();
+ List<? extends Number> listOfSomethingNumberish = new ArrayList<Integer>();
+ List<? super Double> listOfSomethingSuperDouble = new ArrayList<Number>();
+ // interfaces too List<? extends A,B>
+
+ ReferenceType ajList = resolve("Ljava/util/List;");
+ ReferenceType ajListOfString = resolve("Pjava/util/List<Ljava/lang/String;>;");
+ 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<String>
+ 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<String>) 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<? extends Number>) listOfSomething;
+ assertTrue(ajListOfSomethingNumberish.isCoerceableFrom(ajListOfSomething));
+ // error: listOfSomethingNumberish = listOfSomethingSuperDouble;
+ assertFalse(ajListOfSomethingNumberish.isAssignableFrom(ajListOfSomethingSuperDouble));
+ // listOfSomethingNumberish = (List<? extends Number>) listOfSomethingSuperDouble;
+ // assertTrue(ajListOfSomethingNumberish.isCoerceableFrom(ajListOfSomethingSuperDouble));
+ }
+
+ class C<E extends Number> {
+ void m1(List<Integer> e) {
+ }
+
+ void m2(List<? extends Number> e) {
+ }
+
+ void m3(List<Number> e) {
+ }
+
+ void m4(List<?> e) {
+ }
+
+ void m5(List<E> e) {
+ }
+
+ void m6(List<? extends E> e) {
+ }
+
+ void m7(List<? extends List<? extends E>> 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<E2 extends C1> {
+ void m5(List<E2> e) {
+ }
+ }
+
+ public void testAssignable02() {
+ List list = new ArrayList();
+ ArrayList arraylist = null;
+ List<String> listOfString = new ArrayList<String>();
+ List<?> listOfSomething = new ArrayList<Integer>();
+ ArrayList<?> arrayListOfSomething = null;
+ List<Number> listOfNumber = null;
+ ArrayList<Number> arrayListOfNumber = null;
+ ArrayList<? extends Number> arrayListOfSomethingNumberish = null;
+ List<? extends Number> listOfSomethingNumberish = new ArrayList<Integer>();
+ List<? super Double> listOfSomethingSuperDouble = new ArrayList<Number>();
+ List<Integer> listOfInteger = new ArrayList<Integer>();
+ ArrayList<String> arrayListOfString;
+ ArrayList<Integer> arraylistOfInteger;
+ // interfaces too List<? extends A,B>
+
+ ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList<Ljava/lang/String;>;");
+ ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList<Ljava/lang/Integer;>;");
+ ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList<Ljava/lang/Number;>;");
+ 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<Ljava/lang/String;>;");
+ 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<Ljava/lang/Integer;>;");
+ ReferenceType ajListOfNumber = resolve("Pjava/util/List<Ljava/lang/Number;>;");
+ // 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<Integer>){} //: Should match (it does)
+ assertTrue(ajListOfInteger.isAssignableFrom(ajListOfInteger));
+
+ // void around(): execution(* C.m1(..)) && args(ArrayList<Integer>){}//: Should runtime check (it does!)
+ ArrayList<Integer> x = (ArrayList<Integer>) listOfInteger;
+ assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfInteger));
+ assertTrue(ajArrayListOfInteger.isCoerceableFrom(ajListOfInteger));
+
+ // void around(): execution(* C.m1(..)) && args(List<Number>){} // Should not match (it does not!)
+ // error: listOfNumber = listOfInteger;
+ assertFalse(ajListOfNumber.isAssignableFrom(ajListOfInteger));
+ assertFalse(ajListOfNumber.isCoerceableFrom(ajListOfInteger));
+
+ // void around(): execution(* C.m1(..)) && args(ArrayList<Number>){} // Should not match (it does not)
+ // error: arrayListOfNumber = listOfInteger;
+ assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfInteger));
+ assertFalse(ajArrayListOfNumber.isCoerceableFrom(ajListOfInteger));
+
+ // void around(): execution(* C.m1(..)) && args(List<? extends Number>){} // Should match (it does)
+ listOfSomethingNumberish = listOfInteger;
+ assertTrue(ajListOfSomethingNumberish.isAssignableFrom(ajListOfInteger));
+
+ // void around(): execution(* C.m1(..)) && args(ArrayList<? extends Number>){}// Should runtime check (it does!)
+ arrayListOfSomethingNumberish = (ArrayList<? extends Number>) 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<String>){}// 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<String> listOfString = new ArrayList<String>();
+ List<?> listOfSomething = new ArrayList<Integer>();
+ ArrayList<?> arrayListOfSomething = null;
+ List<Number> listOfNumber = null;
+ ArrayList<Number> arrayListOfNumber = null;
+ ArrayList<Integer> arrayListOfInteger = null;
+ ArrayList<? extends Number> arrayListOfSomethingNumberish = null;
+ List<? extends Number> listOfSomethingNumberish = new ArrayList<Integer>();
+ List<? super Double> listOfSomethingSuperDouble = new ArrayList<Number>();
+ List<Integer> listOfInteger = new ArrayList<Integer>();
+ ArrayList<String> arrayListOfString;
+ ArrayList<Integer> arraylistOfInteger;
+ // interfaces too List<? extends A,B>
+
+ ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList<Ljava/lang/String;>;");
+ ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList<Ljava/lang/Integer;>;");
+ ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList<Ljava/lang/Number;>;");
+ 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<Ljava/lang/String;>;");
+ 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<Ljava/lang/Integer;>;");
+ ReferenceType ajListOfNumber = resolve("Pjava/util/List<Ljava/lang/Number;>;");
+
+ // void m2(List<? extends Number> e) {}
+
+ // comment 11
+ // void around(): execution(* C.m2(..)) && args(List<Integer>){} //: Should not match (but it does) ERROR
+ listOfInteger = (List<Integer>) listOfSomethingNumberish;
+ assertFalse(ajListOfInteger.isAssignableFrom(ajListOfSomethingNumberish));
+ assertTrue(ajListOfInteger.isCoerceableFrom(ajListOfSomethingNumberish));
+
+ // void around(): execution(* C.m2(..)) && args(ArrayList<Integer>){}//: Should not match (but it does!) ERROR
+ arrayListOfInteger = (ArrayList<Integer>) listOfSomethingNumberish;
+ assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfSomethingNumberish));
+ assertTrue(ajArrayListOfInteger.isCoerceableFrom(ajListOfSomethingNumberish));
+
+ // void around(): execution(* C.m2(..)) && args(List<Number>){} //: Should not match (but it does) ERROR
+ listOfNumber = (List<Number>) listOfSomethingNumberish;
+ assertFalse(ajListOfNumber.isAssignableFrom(ajListOfSomethingNumberish));
+ assertTrue(ajListOfNumber.isCoerceableFrom(ajListOfSomethingNumberish));
+
+ // void around(): execution(* C.m2(..)) && args(ArrayList<Number>){}//: Should not runtime check (but it does!) ERROR
+ arrayListOfNumber = (ArrayList<Number>) listOfSomethingNumberish;
+ assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfSomethingNumberish));
+ assertTrue(ajArrayListOfNumber.isCoerceableFrom(ajListOfSomethingNumberish));
+
+ // void around(): execution(* C.m2(..)) && args(List<? extends Number>){}//: Should match (it does)
+ listOfSomethingNumberish = listOfSomethingNumberish;
+ assertTrue(ajListOfSomethingNumberish.isAssignableFrom(ajListOfSomethingNumberish));
+
+ // void around(): execution(* C.m2(..)) && args(ArrayList<? extends Number>){}//: Should runtime check (it does!)
+ arrayListOfSomethingNumberish = (ArrayList<? extends Number>) 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<String>){}//: 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<String> listOfString = new ArrayList<String>();
+ List<?> listOfSomething = new ArrayList<Integer>();
+ ArrayList<?> arrayListOfSomething = null;
+ List<Number> listOfNumber = null;
+ ArrayList<Number> arrayListOfNumber = null;
+ ArrayList<Integer> arrayListOfInteger = null;
+ ArrayList<? extends Number> arrayListOfSomethingNumberish = null;
+ List<? extends Number> listOfSomethingNumberish = new ArrayList<Integer>();
+ List<? super Double> listOfSomethingSuperDouble = new ArrayList<Number>();
+ List<Integer> listOfInteger = new ArrayList<Integer>();
+ ArrayList arrayList = null;
+ ArrayList<String> arrayListOfString;
+ ArrayList<Integer> arraylistOfInteger;
+ // interfaces too List<? extends A,B>
+
+ ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList<Ljava/lang/String;>;");
+ ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList<Ljava/lang/Integer;>;");
+ ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList<Ljava/lang/Number;>;");
+ 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<Ljava/lang/String;>;");
+ 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<Ljava/lang/Integer;>;");
+ ReferenceType ajListOfNumber = resolve("Pjava/util/List<Ljava/lang/Number;>;");
+
+ // void m3(List<Number> e) { }
+
+ // void around(): execution(* C.m3(..)) && args(List<Integer>){} //: Should not match (it does not)
+ // error: listOfInteger = listOfNumber;
+ assertFalse(ajListOfInteger.isAssignableFrom(ajListOfNumber));
+ assertFalse(ajListOfInteger.isCoerceableFrom(ajListOfNumber));
+
+ // void around(): execution(* C.m3(..)) && args(ArrayList<Integer>){}//: Should not match (it does not)
+ // error: arrayListOfInteger = listOfNumber;
+ assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfNumber));
+ assertFalse(ajArrayListOfInteger.isCoerceableFrom(ajListOfNumber));
+
+ // void around(): execution(* C.m3(..)) && args(List<Number>){}//: Should match (it does)
+ listOfNumber = listOfNumber;
+ assertTrue(ajListOfNumber.isAssignableFrom(ajListOfNumber));
+
+ // void around(): execution(* C.m3(..)) && args(ArrayList<Number>){}//: Should runtime match (it does)
+ arrayListOfNumber = (ArrayList<Number>) listOfNumber;
+ assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfNumber));
+ assertTrue(ajArrayListOfNumber.isCoerceableFrom(ajListOfNumber));
+
+ // void around(): execution(* C.m3(..)) && args(List<? extends Number>){}//: Should match (it does)
+ listOfSomethingNumberish = listOfNumber;
+ assertTrue(ajListOfSomethingNumberish.isAssignableFrom(ajListOfNumber));
+
+ // void around(): execution(* C.m3(..)) && args(ArrayList<? extends Number>){}//: Should runtime check (it does!)
+ arrayListOfSomethingNumberish = (ArrayList<? extends Number>) 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<String>){}//: Should not match (it does not match!)
+ // error: arrayListOfString = listOfNumber;
+ assertFalse(ajArrayListOfString.isAssignableFrom(ajListOfNumber));
+ assertFalse(ajArrayListOfString.isCoerceableFrom(ajListOfNumber));
+
+ }
+
+ static class ClassA<T> {
+ }
+
+ static interface IMarker<H> {
+ }
+
+ static class ClassB<T> implements IMarker<ClassA<T>> {
+ }
+
+ static class ClassC<T> implements IMarker<T> {
+ }
+
+ 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<Porg/aspectj/weaver/ReferenceTypeTestCase$ClassA<TT;>;>;");
+ 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<String> listOfString = new ArrayList<String>();
+ List<?> listOfSomething = new ArrayList<Integer>();
+ ArrayList<?> arrayListOfSomething = null;
+ List<Number> listOfNumber = null;
+ ArrayList<Number> arrayListOfNumber = null;
+ ArrayList<? extends Number> arrayListOfSomethingNumberish = null;
+ List<? extends Number> listOfSomethingNumberish = new ArrayList<Integer>();
+ List<? super Double> listOfSomethingSuperDouble = new ArrayList<Number>();
+ List<Integer> listOfInteger = new ArrayList<Integer>();
+ ArrayList<String> arrayListOfString;
+ ArrayList<Integer> arraylistOfInteger;
+ // interfaces too List<? extends A,B>
+
+ ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList<Ljava/lang/String;>;");
+ ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList<Ljava/lang/Integer;>;");
+ ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList<Ljava/lang/Number;>;");
+ 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<Ljava/lang/String;>;");
+ 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<Ljava/lang/Integer;>;");
+ ReferenceType ajListOfNumber = resolve("Pjava/util/List<Ljava/lang/Number;>;");
+
+ // void m4(List<?> e) {}
+
+ // void around(): execution(* C.m4(..)) && args(List<Integer>){} //: Should match with unchecked warning
+ listOfInteger = (List<Integer>) listOfSomething;
+ assertFalse(ajListOfInteger.isAssignableFrom(ajListOfSomething));
+ assertTrue(ajListOfInteger.isCoerceableFrom(ajListOfSomething));
+
+ // void around(): execution(* C.m4(..)) && args(ArrayList<Integer>){} // Should match with unchecked warning
+ arraylistOfInteger = (ArrayList<Integer>) listOfSomething;
+ assertFalse(ajArrayListOfInteger.isAssignableFrom(ajListOfSomething));
+ assertTrue(ajArrayListOfInteger.isCoerceableFrom(ajListOfSomething));
+
+ // void around(): execution(* C.m4(..)) && args(List<Number>){} // Should match with unchecked warning
+ listOfNumber = (List<Number>) listOfSomething;
+ assertFalse(ajListOfNumber.isAssignableFrom(ajListOfSomething));
+ assertTrue(ajListOfNumber.isCoerceableFrom(ajListOfSomething));
+
+ // void around(): execution(* C.m4(..)) && args(ArrayList<Number>){} // Should match with unchecked warning
+ arrayListOfNumber = (ArrayList<Number>) listOfSomething;
+ assertFalse(ajArrayListOfNumber.isAssignableFrom(ajListOfSomething));
+ assertTrue(ajArrayListOfNumber.isCoerceableFrom(ajListOfSomething));
+
+ // void around(): execution(* C.m4(..)) && args(List<? extends Number>){} // Should match with unchecked warning
+ listOfSomethingNumberish = (List<? extends Number>) listOfSomething;
+ assertFalse(ajListOfSomethingNumberish.isAssignableFrom(ajListOfSomething));
+ assertTrue(ajListOfSomethingNumberish.isCoerceableFrom(ajListOfSomething));
+
+ // void around(): execution(* C.m4(..)) && args(ArrayList<? extends Number>){} // Should match with unchecked warning
+ arrayListOfSomethingNumberish = (ArrayList<? extends Number>) 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<String>){} // Should match with unchecked warning
+ arrayListOfString = (ArrayList<String>) 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<ConcreteTypeMunger> list = new ArrayList<ConcreteTypeMunger>();
+
+ 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, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable, E8 extends Throwable, E9 extends Throwable, E10 extends Throwable, E11 extends Throwable, E12 extends Throwable, E13 extends Throwable, E14 extends Throwable> {
+ T execute(String aArg) throws E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E14, RemoteException;
+ }
+
+ public interface Operator13<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable, E8 extends Throwable, E9 extends Throwable, E10 extends Throwable, E11 extends Throwable, E12 extends Throwable, E13 extends Throwable>
+ extends Operator14<T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E13, E13> {
+ }
+
+ public interface Operator12<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable, E8 extends Throwable, E9 extends Throwable, E10 extends Throwable, E11 extends Throwable, E12 extends Throwable>
+ extends Operator13<T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E12, E12> {
+ }
+
+ public interface Operator11<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable, E8 extends Throwable, E9 extends Throwable, E10 extends Throwable, E11 extends Throwable>
+ extends Operator12<T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E11, E11> {
+ }
+
+ public interface Operator10<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable, E8 extends Throwable, E9 extends Throwable, E10 extends Throwable>
+ extends Operator11<T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E10, E10> {
+
+ }
+
+ public interface Operator9<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable, E8 extends Throwable, E9 extends Throwable>
+ extends Operator10<T, E1, E2, E3, E4, E5, E6, E7, E8, E9, E9> {
+ }
+
+ public interface Operator8<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable, E8 extends Throwable>
+ extends Operator9<T, E1, E2, E3, E4, E5, E6, E7, E8, E8> {
+ }
+
+ public interface Operator7<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable, E7 extends Throwable>
+ extends Operator8<T, E1, E2, E3, E4, E5, E6, E7, E7> {
+ }
+
+ public interface Operator6<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable, E6 extends Throwable>
+ extends Operator7<T, E1, E2, E3, E4, E5, E6, E6> {
+
+ }
+
+ public interface Operator5<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable, E5 extends Throwable>
+ extends Operator6<T, E1, E2, E3, E4, E5, E5> {
+ }
+
+ public interface Operator4<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable, E4 extends Throwable> extends
+ Operator5<T, E1, E2, E3, E4, E4> {
+ }
+
+ public interface Operator3<T, E1 extends Throwable, E2 extends Throwable, E3 extends Throwable> extends
+ Operator4<T, E1, E2, E3, E3> {
+ }
+
+ public interface Operator2<T, E1 extends Throwable, E2 extends Throwable> extends Operator3<T, E1, E2, E2> {
+
+ }
+
+ public interface Operator1<T, E1 extends Throwable> extends Operator2<T, E1, E1> {
+ }
+
+ public interface Operator<T> extends Operator1<T, RuntimeException> {
+ }
+
+ class Foo implements Operator<String> {
+ 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<String> listOfString = new ArrayList<String>();
+ // List<?> listOfSomething = new ArrayList<Integer>();
+ // ArrayList<?> arrayListOfSomething = null;
+ // List<Number> listOfNumber = null;
+ // ArrayList<Number> arrayListOfNumber = null;
+ // ArrayList<? extends Number> arrayListOfSomethingNumberish = null;
+ // List<? extends Number> listOfSomethingNumberish = new ArrayList<Integer>();
+ // List<? super Double> listOfSomethingSuperDouble = new ArrayList<Number>();
+ // List<Integer> listOfInteger = new ArrayList<Integer>();
+ // ArrayList<String> arrayListOfString;
+ // ArrayList<Integer> arraylistOfInteger;
+ // // interfaces too List<? extends A,B>
+ //
+ // ReferenceType ajArrayListOfString = resolve("Pjava/util/ArrayList<Ljava/lang/String;>;");
+ // ReferenceType ajArrayListOfInteger = resolve("Pjava/util/ArrayList<Ljava/lang/Integer;>;");
+ // ReferenceType ajArrayListOfNumber = resolve("Pjava/util/ArrayList<Ljava/lang/Number;>;");
+ // 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<Ljava/lang/String;>;");
+ // 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<Ljava/lang/Integer;>;");
+ // ReferenceType ajListOfNumber = resolve("Pjava/util/List<Ljava/lang/Number;>;");
+ // ReferenceType ajListOfEextendsNumber = resolve("Pjava/util/List<+TE")
+ //
+ // // class C<E extends Number> {
+ // // void m5(List<E> e) { }
+ // //
+ // // void around(): execution(* C.m5(..)) && args(List<Integer>){} Should not match (but it does) ERROR
+ //
+ // // void around(): execution(* C.m5(..)) && args(ArrayList<Integer>){}//: Should not match (but it does!) ERROR
+ // // void around(): execution(* C.m5(..)) && args(List<Number>){}//: Should not match (but it does!) ERROR
+ // // void around(): execution(* C.m5(..)) && args(ArrayList<Number>){}//: Should not match (it does) ERROR
+ // // void around(): execution(* C.m5(..)) && args(List<? extends Number>){}//: Should match (it does)
+ // // void around(): execution(* C.m5(..)) && args(ArrayList<? extends Number>){}//: 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<String>){}//: Should not match (it does not match!)
+ // //
+ // // // void around(): execution(* D2.m5(..)) && args(List<D1>){} //: Should
+ // // not match (but it does) ERROR
+ // // // void around(): execution(* D2.m5(..)) && args(ArrayList<D1>){}//:
+ // // Should not match (but it does!) ERROR
+ // // // void around(): execution(* D2.m5(..)) && args(List<C1>){}//: Should
+ // // not match (but it does!) ERROR
+ // // // void around(): execution(* D2.m5(..)) && args(ArrayList<C1>){}//:
+ // // Should not match (it does) ERROR
+ // // // void around(): execution(* D2.m5(..)) && args(List<? extends B1>){}//:
+ // // Should match (it does)
+ // // // void around(): execution(* D2.m5(..)) && args(ArrayList<? extends
+ // // B1>){}//: Should runtime check (it does!)
+ // // // void around(): execution(* D2.m5(..)) && args(List<? extends C1>){}//:
+ // // Should match (it does)
+ // // // void around(): execution(* D2.m5(..)) && args(ArrayList<? extends
+ // // C1>){}//: 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<String>){}//:
+ // // Should not match (it does not match!)
+ // //
+ // // // void around(): execution(* C.m6(..)) && args(List<Integer>){} //:
+ // // Should not match (but it does) ERROR
+ // // // void around(): execution(* C.m6(..)) && args(ArrayList<Integer>){}//:
+ // // Should not match (but it does!) ERROR
+ // // // void around(): execution(* C.m6(..)) && args(List<Number>){}//: Should
+ // // not match (but it does!) ERROR
+ // // // void around(): execution(* C.m6(..)) && args(ArrayList<Number>){}//:
+ // // Should not match (it does) ERROR
+ // // // void around(): execution(* C.m6(..)) && args(List<? extends
+ // // Number>){}//: Should match (it does)
+ // // // void around(): execution(* C.m6(..)) && args(ArrayList<? extends
+ // // Number>){}//: 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<String>){}//:
+ // // Should not match (it does not match!)
+ // //
+ // // // void around(): execution(* C.m7(..)) && args(List<List<Integer>>){}
+ // // //: Should not match (but it does) ERROR
+ // // // void around(): execution(* C.m7(..)) &&
+ // // args(ArrayList<List<Integer>>){}//: Should not match (but it does!) ERROR
+ // // // void around(): execution(* C.m7(..)) && args(List<List<Number>>){}//:
+ // // Should not match (but it does!) ERROR
+ // // // void around(): execution(* C.m7(..)) &&
+ // // args(ArrayList<List<Number>>){}//: Should not match (but it does) ERROR
+ // // // void around(): execution(* C.m7(..)) && args(List<? extends
+ // // List<Number>>){}//: Should not match (but it does) ERROR
+ // // // void around(): execution(* C.m7(..)) && args(ArrayList< ? extends
+ // // List<Number>>){}//: Should not match (but it does!) ERROR
+ // // // void around(): execution(* C.m7(..)) && args(List< ? extends List<?
+ // // extends Number>>){}//: Should match (it does!)
+ // // // void around(): execution(* C.m7(..)) && args(ArrayList< ? extends
+ // // List<? extends Number>>){}//: 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<List<String>>){}//: Should not match (it does not match!)
+ // //
+ // // // void around(): execution(* C.m8(..)) && args(List<Integer>){} //:
+ // // Should match with unchecked conversion (it does)
+ // // // void around(): execution(* C.m8(..)) && args(ArrayList<Integer>){}//:
+ // // Should runtime check with unchecked conversion (it does!)
+ // // // void around(): execution(* C.m8(..)) && args(List<Number>){}//: Should
+ // // match with unchecked conversion (it does!)
+ // // // void around(): execution(* C.m8(..)) && args(ArrayList<Number>){}//:
+ // // Should runtime check with unchecked conversion (it does)
+ // // // void around(): execution(* C.m8(..)) && args(List<? extends
+ // // Number>){}//: Should match with unchecked conversion (it does!)
+ // // // void around(): execution(* C.m8(..)) && args(ArrayList<? extends
+ // // Number>){}//: 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<String>){}//:
+ // // Should not match (it does not match!)
+ // //
+ // // // void around(): execution(* C.m9(..)) && args(List<Integer>){} //:
+ // // Should not match (but it does) ERROR
+ // // // void around(): execution(* C.m9(..)) && args(ArrayList<Integer>){}//:
+ // // 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<? extends
+ // // Number>){}//: Should not match (but it does) ERROR
+ // // // void around(): execution(* C.m9(..)) && args(ArrayList<? extends
+ // // Number>){}//: 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"),
+ "<init>",
+ 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"),
+ "<init>",
+ 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<T extends Number> {
+ 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<java.lang.String>");
+ assertEquals(t.getName(),"java.util.List<java.lang.String>");
+ assertEquals(t.getSignature(),"Pjava/util/List<Ljava/lang/String;>;");
+ t = UnresolvedType.forSignature("Pjava/util/List<Ljava/lang/String;>;");
+ assertEquals(t.getName(),"java.util.List<java.lang.String>");
+ assertEquals(t.getSignature(),"Pjava/util/List<Ljava/lang/String;>;");
+ t = UnresolvedType.forName("java.util.Map<java.util.String,java.util.List<java.lang.Integer>>");
+ assertEquals(t.getName(),"java.util.Map<java.util.String,java.util.List<java.lang.Integer>>");
+ assertEquals(t.getSignature(),"Pjava/util/Map<Ljava/util/String;Pjava/util/List<Ljava/lang/Integer;>;>;");
+ t = UnresolvedType.forSignature("Pjava/util/Map<Ljava/util/String;Pjava/util/List<Ljava/lang/Integer;>;>;");
+ assertEquals(t.getName(),"java.util.Map<java.util.String,java.util.List<java.lang.Integer>>");
+ assertEquals(t.getSignature(),"Pjava/util/Map<Ljava/util/String;Pjava/util/List<Ljava/lang/Integer;>;>;");
+ }
+
+ /**
+ * Verify UnresolvedType signature processing creates the right kind of UnresolvedType's from a signature.
+ *
+ * For example, calling UnresolvedType.dump() for
+ * "Ljava/util/Map<Ljava/util/List<Ljava/lang/String;>;Ljava/lang/String;>;"
+ * results in:
+ * UnresolvedType: signature=Ljava/util/Map<Ljava/util/List<Ljava/lang/String;>;Ljava/lang/String;>; parameterized=true #params=2
+ * UnresolvedType: signature=Ljava/util/List<Ljava/lang/String;>; 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<Ljava/lang/String;>;");
+ checkTX(tx,true,1);
+
+ tx = UnresolvedType.forSignature("Pjava/util/Set<Pjava/util/List<Ljava/lang/String;>;>;");
+ checkTX(tx,true,1);
+
+ tx = UnresolvedType.forSignature("Pjava/util/Map<Pjava/util/List<Ljava/lang/String;>;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<Ljava/lang/String;>;");
+ assertEquals(1, enumOfSimpleType.getTypeParameters().length);
+
+ UnresolvedType enumOfNestedType =
+ TypeFactory.createTypeFromSignature("Pjava/lang/Enum<Ljavax/jws/soap/SOAPBinding$ParameterStyle;>;");
+ assertEquals(1, enumOfNestedType.getTypeParameters().length);
+
+ // is this signature right?
+ UnresolvedType nestedTypeOfParameterized =
+ TypeFactory.createTypeFromSignature("PMyInterface<Ljava/lang/String;>$MyOtherType;");
+ assertEquals(0, nestedTypeOfParameterized.getTypeParameters().length);
+
+ // how about this one? is this valid?
+ UnresolvedType doublyNestedTypeSignatures =
+ TypeFactory.createTypeFromSignature("PMyInterface<Ljava/lang/String;Ljava/lang/String;>$MyOtherType<Ljava/lang/Object;>;");
+ assertEquals(1, doublyNestedTypeSignatures.getTypeParameters().length);
+
+ }
+ }
+
+ private void checkTX(UnresolvedType tx,boolean shouldBeParameterized,int numberOfTypeParameters) {
+ assertTrue("Expected parameterization flag to be "+shouldBeParameterized,tx.isParameterizedType()==shouldBeParameterized);
+ if (numberOfTypeParameters==0) {
+ 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<String> fieldList = new ArrayList<String>();
+ 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<ShadowMunger> 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<ShadowMunger> 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<TE;>;", 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("<T::Ljava/io/Serializable;>Ljava/lang/Object;Ljava/lang/Comparable<TT;>;");
+ 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.
+ *
+ * <blockquote>
+ *
+ * <pre>
+ * Kind ( Id , ... ) : Pointcut -&gt; MethodSignature
+ * </pre>
+ *
+ * </blockquote>
+ */
+ public static Advice shadowMunger(World w, String str, int extraFlag) {
+ str = str.trim();
+ int start = 0;
+ int i = str.indexOf('(');
+ AdviceKind kind = AdviceKind.stringToKind(str.substring(start, i));
+ start = ++i;
+ i = str.indexOf(')', i);
+ String[] ids = 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<threads.length; i++) {
+ threads[i] = new TestThread((i%3)*1000);
+ threads[i].start();
+ }
+ for (int i=0; i<threads.length; i++) {
+ threads[i].join();
+ if (threads[i].getFailure() != null) {
+ throw threads[i].getFailure();
+ }
+ }
+ }
+
+ private class TestThread extends Thread {
+ public Throwable failure = null;
+ Enumeration entries;
+
+ // ensure the threads are loading DIFFERENT shared classes at the same time...
+ public TestThread(int skip) {
+ entries = zf.entries();
+ for (int i=0; i<skip && entries.hasMoreElements(); i++) {
+ entries.nextElement();
+ }
+ }
+
+ public void run() {
+ try {
+ ClassLoaderRepository rep = 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('/','.');
+ rep.loadClass(clazzname);
+ rep.loadClass(clazzname);
+ i++;
+ }
+ }
+ System.err.println("Thread finished: "+rep.report());
+ } catch (Throwable t) {
+ failure = t;
+ }
+ }
+ public Throwable getFailure() {
+ return failure;
+ }
+ }
+
+ public void testNotSharedRepository() throws Exception {
+ ClassLoaderRepository.useSharedCache=false;
+ compareTwoRepositories();
+ }
+
+ public void testSharedUrlRepository() throws Exception {
+ ClassLoaderRepository.useSharedCache=true;
+ compareTwoRepositories();
+// ClassLoaderRepository.compactSharedCache();
+ }
+
+ public void testPurgeUrlRepository() throws Exception {
+ ClassLoaderRepository.useSharedCache = true;
+ ClassLoaderRepository rep = setupRepository();
+ Reference ref = null;
+
+ while (ref==null && 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);
+ assertEquals("expected one entry in shared URL cache "+map.size(), 1, map.size());
+ ref = (Reference)map.values().iterator().next();
+ ref.clear();
+ ref.enqueue();
+ map.size();//force purge
+ }
+ }
+ assertEquals("expected empty shared URL cache "+map.size(), 0, map.size());
+ }
+
+ public void testAutoPurgeUrlRepository() throws Exception {
+ ClassLoaderRepository.useSharedCache = true;
+ assertEquals("expected empty shared URL cache "+map.size(), 0, map.size());
+ ClassLoaderRepository rep = setupRepository();
+ Reference ref = null;
+ int i = 0;
+
+ while (i<3 && 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);
+ ref = (Reference)map.values().iterator().next();
+ ref.clear();
+ ref.enqueue();
+ i++;
+ }
+ }
+ assertTrue("expected smaller shared URL cache "+map.size(), map.size()<3);
+ }
+
+ private Field getSharedMapField() throws Exception {
+ Field field = ClassLoaderRepository.class.getDeclaredField("sharedCache");
+ field.setAccessible(true);
+ return field;
+ }
+
+ private Map getSharedMap() throws Exception {
+ return (Map)getSharedMapField() .get(null);
+ }
+}
+
diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/FieldSetTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/FieldSetTestCase.java
new file mode 100644
index 000000000..c81827229
--- /dev/null
+++ b/weaver/src/test/java/org/aspectj/weaver/bcel/FieldSetTestCase.java
@@ -0,0 +1,34 @@
+/* *******************************************************************
+ * 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 FieldSetTestCase extends WeaveTestCase {
+ {
+ regenerate = false;
+ }
+
+ public FieldSetTestCase(String name) {
+ super(name);
+ }
+
+ public void testBefore() throws IOException {
+ weaveTest(
+ "FieldyHelloWorld",
+ "FieldSet",
+ makeAdviceAll("before")
+ );
+ }
+}
diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java
new file mode 100644
index 000000000..062f3dbef
--- /dev/null
+++ b/weaver/src/test/java/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java
@@ -0,0 +1,63 @@
+/* *******************************************************************
+ * 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 junit.framework.TestCase;
+
+
+public class HierarchyDependsTestCase extends TestCase {
+
+ public HierarchyDependsTestCase(String arg0) {
+ super(arg0);
+ }
+
+ public void testToDo() {}
+
+ /**
+ * XXX not currently used, fix tests when using
+ public void testHierarchyDepends() {
+ BcelWorld world = new BcelWorld();
+ TypePatternQuestions questions = new TypePatternQuestions();
+ ResolvedType runnableType = world.resolve("java.lang.Runnable");
+ ResolvedType numberType = world.resolve("java.lang.Number");
+ ResolvedType integerType = world.resolve("java.lang.Integer");
+ ResolvedType stringType = world.resolve("java.lang.String");
+
+
+ TypePattern numberPattern = new ExactTypePattern(numberType, false);
+ questions.askQuestion(numberPattern, integerType, TypePattern.STATIC);
+ questions.askQuestion(numberPattern, integerType, TypePattern.DYNAMIC);
+ assertNull(questions.anyChanges());
+
+ JavaClass saveClass = integerType.getJavaClass();
+ integerType.replaceJavaClass(stringType.getJavaClass());
+ assertNotNull(questions.anyChanges());
+
+ integerType.replaceJavaClass(saveClass);
+ assertNull(questions.anyChanges());
+
+ TypePattern runnablePattern = new ExactTypePattern(runnableType, false);
+ questions.askQuestion(runnablePattern, stringType, TypePattern.DYNAMIC);
+ assertNull(questions.toString(), questions.anyChanges());
+
+ saveClass = stringType.getJavaClass();
+ stringType.replaceJavaClass(numberType.getJavaClass());
+ assertNotNull(questions.toString(), questions.anyChanges());
+
+ stringType.replaceJavaClass(saveClass);
+ assertNull(questions.toString(), questions.anyChanges());
+ }
+ */
+}
+
diff --git a/weaver/src/test/java/org/aspectj/weaver/bcel/IdWeaveTestCase.java b/weaver/src/test/java/org/aspectj/weaver/bcel/IdWeaveTestCase.java
new file mode 100644
index 000000000..cf16b73b1
--- /dev/null
+++ b/weaver/src/test/java/org/aspectj/weaver/bcel/IdWeaveTestCase.java
@@ -0,0 +1,101 @@
+/* *******************************************************************
+ * 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.weaver.Shadow;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.patterns.Pointcut;
+
+public class IdWeaveTestCase extends WeaveTestCase {
+ {
+ regenerate = false;
+ }
+
+ public IdWeaveTestCase(String name) {
+ super(name);
+ }
+
+ public void testFancyId() throws IOException {
+ final List l = new ArrayList();
+ Pointcut pointcut2 = makePointcutAll();
+ BcelAdvice p = new BcelAdvice(null, pointcut2, null, 0, -1, -1, null, null) {
+ public boolean match(Shadow shadow, World world) {
+ if (super.match(shadow, world)) {
+ l.add(shadow);
+ }
+ return false;
+ }
+ };
+ weaveTest(new String[] { "FancyHelloWorld" }, "Id2", p);
+
+ checkShadowSet(l, new String[] { "method-call(void java.io.PrintStream.println(java.lang.Object))",
+ "method-call(void java.io.PrintStream.println(java.lang.String))",
+ "method-call(java.lang.StringBuffer java.lang.StringBuffer.append(int))",
+ "method-call(java.lang.String java.lang.StringBuffer.toString())",
+ "method-execution(java.lang.String FancyHelloWorld.getName())",
+ "field-get(java.io.PrintStream java.lang.System.out)",
+ "method-call(void java.io.PrintStream.println(java.lang.String))",
+ "method-execution(void FancyHelloWorld.main(java.lang.String[]))", "method-call(int java.lang.String.hashCode())",
+ "constructor-execution(void FancyHelloWorld.<init>())",
+ "constructor-call(void java.lang.StringBuffer.<init>(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.<init>())", });
+ }
+
+ // 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.<init>())",
+ // // 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<String> 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<Entry> 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<String, Path> 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<String> getAllTheClasses() {
+ final List<String> result = new ArrayList<>();
+ URI JRT_URI = URI.create("jrt:/"); //$NON-NLS-1$
+ FileSystem fs = FileSystems.getFileSystem(JRT_URI);
+ Iterable<java.nio.file.Path> roots = fs.getRootDirectories();
+ try {
+ for (java.nio.file.Path path : roots) {
+ Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
+ @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<ShadowMunger> getShadowMungers() {
+ List<ShadowMunger> ret = new ArrayList<ShadowMunger>();
+ 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<ShadowMunger> l = new ArrayList<ShadowMunger>(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<ShadowMunger> 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<ShadowMunger> makeAdviceAll(String kind, boolean matchOnlyPrintln) {
+ List<ShadowMunger> ret = new ArrayList<ShadowMunger>();
+ 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<ShadowMunger> 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<ShadowMunger> patternMungers) throws IOException {
+ for (int i = 0; i < inClassNames.length; i++) {
+ String inFileName = inClassNames[i];
+ weaveTest(inFileName, outKind + inFileName, patternMungers);
+ }
+ }
+
+ protected List<ShadowMunger> addLexicalOrder(List<ShadowMunger> 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.<init>()");
+ // 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<? super E> 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<String> 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<IMessage> messages = new ArrayList<IMessage>();
+
+ 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<String> 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<String>; - parameterized)
+ */
+ public void testParameterized() {
+ TypePattern rtp = resolveWildTypePattern("List<String>", false);
+
+ assertTrue("resolves to exact type", rtp instanceof ExactTypePattern);
+ UnresolvedType exactType = rtp.getExactType();
+ assertTrue(exactType.isParameterizedType());
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", exactType.getSignature());
+
+ ResolvedType rt = exactType.resolve(world);
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", rt.getSignature());
+ assertTrue(rt.isParameterizedType());
+
+ ExactTypePattern etp = (ExactTypePattern) writeAndRead(rtp);
+ exactType = etp.getExactType();
+
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", rt.getSignature());
+ assertTrue(rt.isParameterizedType());
+
+ rt = exactType.resolve(world);
+ assertEquals("Pjava/util/List<Ljava/lang/String;>;", 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<Str*> 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<Str*>", 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*<String> 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*<String>", 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<? extends Number>
+ */
+ public void testSomethingExtends() {
+ TypePattern rtp = resolveWildTypePattern("List<? extends Number>", 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<? extends Number+>
+ */
+ public void testSomethingExtendsPattern() {
+ TypePattern rtp = resolveWildTypePattern("List<? extends Number+>", 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<? extends Num*>
+ */
+ public void testSomethingExtendsPatternv2() {
+ TypePattern rtp = resolveWildTypePattern("List<? extends Num*>", 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<? super Number>
+ *
+ */
+ public void testSomethingSuper() {
+ TypePattern rtp = resolveWildTypePattern("List<? super Double>", 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("<init>", 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 <clinit> (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("<clinit>"))
+ 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<A,B> {}
+ static interface InterfaceOne {}
+ static interface InterfaceTwo<A> {}
+ static class ID {}
+ static abstract class AbstractTestClass<T> extends AbstractSuperClass<T,ID> implements InterfaceOne, InterfaceTwo<T> {
+
+ }
+ static class TestType {}
+// static class ConcreteClass extends AbstractTestClass<TestType> {
+ static class ConcreteClass extends AbstractTestClass<List<TestType>> {
+ }
+
+ 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<T>.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<String>.Inner m3() { return new TestClass2<String>.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<java.lang.String>.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<String>.Inner m3() { return new TestClass2<String>.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<java.lang.String>.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<T> {
+ class Inner {
+ T t;
+ Inner(T t) {
+ this.t = t;
+ }
+ }
+ public String m() { return ""; }
+ public Inner m2() { return null; }
+ public TestClass2<String> f;
+ public TestClass2<String>.Inner m3() { return new TestClass2<String>.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<PointcutPrimitive> DEFAULT_SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();
+
+ 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<String> expected = new HashSet<String>();
+ 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<String>();
+ 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<String> parameterAnnotations = new ArrayList<String>();
+ private List<String> parameterTypeAnnotations = new ArrayList<String>();
+
+ public String getStringRepresentation() { return stringRep.toString(); }
+ public List<String> getParameterAnnotations() { return parameterAnnotations; }
+ public List<String> 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<org.aspectj.weaver.tools.Java15PointcutExpressionTest.C>))");
+ 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<C> 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<PointcutPrimitive> 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<PointcutPrimitive> 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<PointcutPrimitive> p = PointcutParser.getAllSupportedPointcutPrimitives();
+ PointcutParser parser = PointcutParser
+ .getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(p, this.getClass()
+ .getClassLoader());
+ assertEquals("Should use the set we pass in", p, parser.getSupportedPrimitives());
+ Set<PointcutPrimitive> q = new HashSet<PointcutPrimitive>();
+ 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 &quot;target&quot; folder lookup up the
+ * hierarchy
+ * @return The &quot;target&quot; <U>folder</U> - <code>null</code> 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 &quot;target&quot; folder lookup up the
+ * hierarchy
+ * @return The &quot;target&quot; <U>folder</U> - <code>null</code> 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
+ * <code>null</code> 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
+ * <code>null</code> 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
+ * <code>null</code> 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 &quot;anchor&quot; {@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:</P></BR>
+ * <UL>
+ * <LI>
+ * If a non-<code>null</code> loader is returned from the
+ * {@link Thread#getContextClassLoader()} call then use it.
+ * </LI>
+ *
+ * <LI>
+ * Otherwise, use the same loader that was used to load the anchor class.
+ * </LI>
+ * </UL>
+ * @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 <code>null</code>
+ * @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
+ * <code>null</code>/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.<IndexEntry>emptyList() : Arrays.asList(entries));
+ }
+
+ protected static final void writeIndex (File indexFile, Collection<? extends IndexEntry> 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<String, IndexEntry> indexMap=cache.getIndexMap();
+ assertEquals("Mismatched index size", 0, indexMap.size());
+
+ // no data files were created
+ Map<String, byte[]> 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<String, File> createDataFiles (IndexEntry ... entries) throws IOException {
+ return createDataFiles(LangUtil.isEmpty(entries) ? Collections.<IndexEntry>emptyList() : Arrays.asList(entries));
+ }
+
+ protected Map<String, File> createDataFiles (Collection<? extends IndexEntry> entries) throws IOException {
+ if (LangUtil.isEmpty(entries)) {
+ return Collections.emptyMap();
+ }
+
+ Map<String, File> files=new TreeMap<String, File>();
+ 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.<String>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<String, File> dataFiles = createDataFiles(entries);
+
+ File cacheDir = getCacheDir();
+ AsynchronousFileCacheBacking cache = createFileBacking(cacheDir);
+ Map<String, IndexEntry> indexMap = cache.getIndexMap();
+ assertEquals("Mismatched index size", entries.length, indexMap.size());
+
+ Map<String, byte[]> 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<String, File> dataFiles = createDataFiles(entries);
+ long newCrc = generateNewBytes();
+ assertTrue("Bad new CRC", newCrc != (-1L));
+
+ Map<String, File> badFiles = new TreeMap<String, File>();
+ 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<String, IndexEntry> indexMap = cache.getIndexMap();
+ assertEquals("Mismatched index size", dataFiles.size(), indexMap.size());
+
+ Map<String, byte[]> bytesMap = cache.getBytesMap();
+ assertEquals("Mismatched bytes size", dataFiles.size(), bytesMap.size());
+
+ for (Map.Entry<String, File> 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<String, File> dataFiles = new TreeMap<String, File>();
+ 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<String, IndexEntry> indexMap = cache.getIndexMap();
+ assertEquals("Mismatched index size", dataFiles.size(), indexMap.size());
+
+ Map<String, byte[]> 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<String, CachedClassEntry> cache = new HashMap<String, CachedClassEntry>();
+
+ public String[] getKeys(String regex) {
+ Set<String> keys = cache.keySet();
+ List<String> matches = new LinkedList<String>();
+ 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<String> classesISaw = new LinkedList<String>();
+
+ 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<String,byte[]> entriesMap=new TreeMap<String,byte[]>();
+ 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<String, IndexEntry> indexMap=cache.getIndexMap();
+ assertEquals("Mismatched index size", entries.length, indexMap.size());
+
+ Map<String, byte[]> 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<String,byte[]> entriesMap=new TreeMap<String,byte[]>();
+ 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<String, byte[]> bytesMap=ZippedFileCacheBacking.readZipClassBytes(zipFile);
+ assertEquals("Mismatched recovered entries size", entriesMap.size(), bytesMap.size());
+ for (Map.Entry<String,byte[]> 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<String,byte[]> entriesMap=new TreeMap<String,byte[]>();
+ 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<String, IndexEntry> indexMap=cache.getIndexMap();
+ assertEquals("Mismatched index size", 1 /* only the ignored entry */, indexMap.size());
+
+ Map<String, byte[]> 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