diff options
author | wisberg <wisberg> | 2002-12-16 17:58:19 +0000 |
---|---|---|
committer | wisberg <wisberg> | 2002-12-16 17:58:19 +0000 |
commit | d842c4f1139629c1f062b74ba818d233b2c31043 (patch) | |
tree | 842d3871620bc0eb60edcd95e55804d67e0f61fa /weaver/testsrc | |
parent | 3ce247199704eae6b2c92c6e38c69584e3250c52 (diff) | |
download | aspectj-d842c4f1139629c1f062b74ba818d233b2c31043.tar.gz aspectj-d842c4f1139629c1f062b74ba818d233b2c31043.zip |
initial version
Diffstat (limited to 'weaver/testsrc')
56 files changed, 5209 insertions, 0 deletions
diff --git a/weaver/testsrc/Aspect.java b/weaver/testsrc/Aspect.java new file mode 100644 index 000000000..bdb8108f4 --- /dev/null +++ b/weaver/testsrc/Aspect.java @@ -0,0 +1,347 @@ +/* This file is part of the compiler and core tools for the AspectJ(tm) + * programming language; see http://aspectj.org + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License at + * either http://www.mozilla.org/MPL/ or http://aspectj.org/MPL/. + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is AspectJ. + * + * The Initial Developer of the Original Code is Palo Alto Research Center, + * Incorporated (PARC). Portions created by PARC are are + * Copyright (C) 2002 Palo Alto Research Center, Incorporated. + * All Rights Reserved. + * + * Contributor(s): + */ + +import java.util.*; + +import org.aspectj.runtime.internal.*; +import org.aspectj.runtime.internal.AroundClosure; +import org.aspectj.lang.JoinPoint; + +public class Aspect { + + public static void ajc_before_0() { + System.out.println("before_0"); + } + public static void ajc_before_0(String s) { + System.out.println("before_0: " + s); + } + public static boolean ajc_around_0(ArrayList s, AroundClosure c) throws Throwable { + System.out.println("doing around, got " + s); + Object ret = c.run(new Object[] {s}); // proceed(s) + return ((Boolean) ret).booleanValue(); + } + + public static void ajc_before_0(java.util.ArrayList list) { + System.out.println("before_0: " + list); + } + + public static void ajc_before_method_execution() { + + } + public static void ajc_before_method_execution(Object o) { + System.out.println("before_method_execution: " + o); + } + + public static void ajc_after_method_execution() { + System.out.println("after_method_execution"); + } + public static void ajc_after_method_execution(Object o) { + System.out.println("after_method_execution: " + o); + } + + public static void ajc_afterReturning_method_execution() { + System.out.println("ajc_afterReturning_method_execution"); + } + public static void ajc_afterReturning_method_execution(Object o) { + System.out.println("afterReturning_method_execution: " + o); + } + + public static void ajc_afterThrowing_method_execution() { + System.out.println("ajc_afterThrowing_method_execution"); + } + public static void ajc_afterThrowing_method_execution(Object o) { + System.out.println("afterThrowing_method_execution: " + o); + } + + + + + + public static Object ajc_around(AroundClosure closure) throws Throwable { + Object ret = closure.run(new Object[] {}); + return ret; + } + + public static Object ajc_around(AroundClosure closure, JoinPoint tjp) throws Throwable { + System.out.println("thisJoinPoint: " + tjp); + Object ret = closure.run(new Object[] {}); + return ret; + } + + // --- + + + public static void ajc_before_method_call() { + System.out.println("before_method_call"); + } + public static void ajc_before_method_call(Object o) { + System.out.println("before_method_call: " + o); + } + + public static void ajc_after_method_call() { + System.out.println("after_method_call"); + } + public static void ajc_after_method_call(Object o) { + System.out.println("after_method_call: " + o); + } + + public static void ajc_afterReturning_method_call() { + System.out.println("ajc_afterReturning_method_call"); + } + public static void ajc_afterReturning_method_call(Object o) { + System.out.println("afterReturning_method_call: " + o); + } + + public static void ajc_afterThrowing_method_call() { + System.out.println("ajc_afterThrowing_method_call"); + } + public static void ajc_afterThrowing_method_call(Object o) { + System.out.println("afterThrowing_method_call: " + o); + } + + public static Object ajc_around_method_call(AroundClosure closure) throws Throwable { + Object ret = null; + for (int i=0; i<3; i++) { + System.out.println("enter: " + i); + ret = closure.run(new Object[] {}); + } + return ret; + } + + // ---- + + public static void ajc_before_constructor_call() { + System.out.println("before_constructor_call"); + } + public static void ajc_before_constructor_call(Object o) { + System.out.println("before_constructor_call: " + o); + } + + public static void ajc_after_constructor_call() { + System.out.println("after_constructor_call"); + } + public static void ajc_after_constructor_call(Object o) { + System.out.println("after_constructor_call: " + o); + } + + public static void ajc_afterReturning_constructor_call() { + System.out.println("ajc_afterReturning_constructor_call"); + } + public static void ajc_afterReturning_constructor_call(Object o) { + System.out.println("afterReturning_constructor_call: " + o); + } + + public static void ajc_afterThrowing_constructor_call() { + System.out.println("ajc_afterThrowing_constructor_call"); + } + public static void ajc_afterThrowing_constructor_call(Object o) { + System.out.println("afterThrowing_constructor_call: " + o); + } + + public static Object ajc_around_constructor_call(AroundClosure closure) throws Throwable { + Object ret = null; + for (int i=0; i<3; i++) { + System.out.println("enter: " + i); + ret = closure.run(new Object[] {}); + } + return ret; + } + // ---- + + public static void ajc_before_constructor_execution() { + System.out.println("before_constructor_execution"); + } + public static void ajc_before_constructor_execution(Object o) { + System.out.println("before_constructor_execution: " + o); + } + + public static void ajc_after_constructor_execution() { + System.out.println("after_constructor_execution"); + } + public static void ajc_after_constructor_execution(Object o) { + System.out.println("after_constructor_execution: " + o); + } + + public static void ajc_afterReturning_constructor_execution() { + System.out.println("ajc_afterReturning_constructor_execution"); + } + public static void ajc_afterReturning_constructor_execution(Object o) { + System.out.println("afterReturning_constructor_execution: " + o); + } + + public static void ajc_afterThrowing_constructor_execution() { + System.out.println("ajc_afterThrowing_constructor_execution"); + } + public static void ajc_afterThrowing_constructor_execution(Object o) { + System.out.println("afterThrowing_constructor_execution: " + o); + } + + public static Object ajc_around_constructor_execution(AroundClosure closure) throws Throwable { + Object ret = null; + for (int i=0; i<3; i++) { + System.out.println("enter: " + i); + ret = closure.run(new Object[] {}); + } + return ret; + } + + + // --- + + + public static void ajc_before_field_get() { + System.out.println("before_field_get"); + } + public static void ajc_before_field_get(Object o) { + System.out.println("before_field_get: " + o); + } + + public static void ajc_after_field_get() { + System.out.println("after_field_get"); + } + public static void ajc_after_field_get(Object o) { + System.out.println("after_field_get: " + o); + } + + public static void ajc_afterReturning_field_get() { + System.out.println("afterReturning_field_get"); + } + public static void ajc_afterReturning_field_get(Object o) { + System.out.println("afterReturning_field_get: " + o); + } + + public static void ajc_afterThrowing_field_get() { + System.out.println("afterThrowing_field_get"); + } + public static void ajc_afterThrowing_field_get(Object o) { + System.out.println("afterThrowing_field_get: " + o); + } + public static void ajc_afterThrowing_field_get(Throwable t) { + System.out.println("afterThrowing_field_get: " + t); + } + + public static Object ajc_around_field_get(AroundClosure closure) throws Throwable { + Object ret = closure.run(new Object[] {}); + return ret; + } + + + // --- + + + public static void ajc_before_field_set() { + System.out.println("before_field_set"); + } + public static void ajc_before_field_set(Object o) { + System.out.println("before_field_set: " + o); + } + + public static void ajc_after_field_set() { + System.out.println("after_field_set"); + } + public static void ajc_after_field_set(Object o) { + System.out.println("after_field_set: " + o); + } + + public static void ajc_afterReturning_field_set() { + System.out.println("afterReturning_field_set"); + } + public static void ajc_afterReturning_field_set(Object o) { + System.out.println("afterReturning_field_set: " + o); + } + + public static void ajc_afterThrowing_field_set() { + System.out.println("afterThrowing_field_set"); + } + public static void ajc_afterThrowing_field_set(Object o) { + System.out.println("afterThrowing_field_set: " + o); + } + public static void ajc_afterThrowing_field_set(Throwable t) { + System.out.println("afterThrowing_field_set: " + t); + } + + public static Object ajc_around_field_set(AroundClosure closure) throws Throwable { + Object ret = closure.run(new Object[] {}); + return ret; + } + + // don't call this method for callee-side call join points + public static void ajc_before(JoinPoint.StaticPart tjp) { + System.out.println("before: " + tjp); + if (tjp.getSourceLocation() == null) { + throw new RuntimeException("didn't want null"); + } + System.out.println(" loc: " + tjp.getSourceLocation()); + } + + public static void ajc_before(JoinPoint tjp) { + System.out.println("before: " + tjp + " this = " + tjp.getThis() + + " target = " + tjp.getTarget() + + " args = " + Arrays.asList(tjp.getArgs())); + } + + // per object stuff + + private static Map objects = new HashMap(); + + public static void ajc$perObjectBind(Object o) { + if (objects.containsKey(o)) return; + objects.put(o, new Aspect()); + } + + public static boolean hasAspect(Object o) { + return objects.containsKey(o); + } + + public static Aspect aspectOf(Object o) { + return (Aspect) objects.get(o); + } + + + // per cflow stuff + + public static void ajc$perCflowPush() { + ajc$perCflowStack.pushInstance(new Aspect()); + } + + public static boolean hasAspect() { + return ajc$perCflowStack.isValid(); + } + + public static Aspect aspectOf() { + return (Aspect) ajc$perCflowStack.peekInstance(); + } + + public static CFlowStack ajc$perCflowStack = new CFlowStack(); + + // non-static methods + + public static Aspect ajc$perSingletonInstance = new Aspect(); + public void ajc_before() { + System.out.println("before in: " + this); + } + + public static CFlowStack ajc$cflowStack$0 = new CFlowStack(); + + +} diff --git a/weaver/testsrc/BcweaverModuleTests.java b/weaver/testsrc/BcweaverModuleTests.java new file mode 100644 index 000000000..4c4617338 --- /dev/null +++ b/weaver/testsrc/BcweaverModuleTests.java @@ -0,0 +1,30 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + +// default package + +import junit.framework.*; +import junit.framework.Test; + +public class BcweaverModuleTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(BcweaverModuleTests.class.getName()); + suite.addTest(org.aspectj.weaver.bcel.BcelTests.suite()); + suite.addTest(org.aspectj.weaver.BcweaverTests.suite()); + suite.addTest(org.aspectj.weaver.patterns.PatternsTests.suite()); + return suite; + } + + public BcweaverModuleTests(String name) { super(name); } + +} diff --git a/weaver/testsrc/DynamicHelloWorld.java b/weaver/testsrc/DynamicHelloWorld.java new file mode 100644 index 000000000..f3818050e --- /dev/null +++ b/weaver/testsrc/DynamicHelloWorld.java @@ -0,0 +1,24 @@ +import java.io.*; +import java.util.*; + +/** + * @version 1.0 + * @author + */ +public class DynamicHelloWorld implements Serializable { + + public static void main(String[] args) { + try { + new DynamicHelloWorld().doit("hello", Collections.EMPTY_LIST); + } catch (UnsupportedOperationException t) { + System.out.println("expected and caught: " + t); + return; + } + throw new RuntimeException("should have caught exception"); + } + + String doit(String s, List l) { + l.add(s); // this will throw an exception + return l.toString(); + } +} diff --git a/weaver/testsrc/FancyHelloWorld.java b/weaver/testsrc/FancyHelloWorld.java new file mode 100644 index 000000000..96bd4a067 --- /dev/null +++ b/weaver/testsrc/FancyHelloWorld.java @@ -0,0 +1,24 @@ +import java.io.PrintStream; + +/** + * @version 1.0 + * @author + */ +public abstract class FancyHelloWorld { + public static void main(String[] args) { + PrintStream out = System.out; + try { + out.println("bye"); + } catch (Exception e) { + out.println(e); + } finally { + out.println("finally"); + } + } + + public static String getName() { + int x = 0; + x += "name".hashCode(); + return "name" + x; + } +} diff --git a/weaver/testsrc/FieldyHelloWorld.java b/weaver/testsrc/FieldyHelloWorld.java new file mode 100644 index 000000000..b5502abf8 --- /dev/null +++ b/weaver/testsrc/FieldyHelloWorld.java @@ -0,0 +1,10 @@ +public class FieldyHelloWorld { + + public static String str = "Hello"; + + public static void main(String[] args) { + str += " World"; + + System.out.println(str); + } +} diff --git a/weaver/testsrc/HelloWorld.java b/weaver/testsrc/HelloWorld.java new file mode 100644 index 000000000..b296ba704 --- /dev/null +++ b/weaver/testsrc/HelloWorld.java @@ -0,0 +1,12 @@ +/** + * @version 1.0 + * @author + */ +public class HelloWorld { + + public static void main(String[] args) { + System.out + .println("hello world"); + //System.out.println("hello world"); + } +} diff --git a/weaver/testsrc/MultiArgHelloWorld.java b/weaver/testsrc/MultiArgHelloWorld.java new file mode 100644 index 000000000..9fccf0ec6 --- /dev/null +++ b/weaver/testsrc/MultiArgHelloWorld.java @@ -0,0 +1,12 @@ + + +public class MultiArgHelloWorld { + + public static void main(String[] args) { + foo("Hello", "World"); + } + + static void foo(Object s, Object t) { + System.out.println(s + " " + t); + } +} diff --git a/weaver/testsrc/Test.java b/weaver/testsrc/Test.java new file mode 100644 index 000000000..97f37d943 --- /dev/null +++ b/weaver/testsrc/Test.java @@ -0,0 +1,11 @@ +public class Test { + public static void main(String[] args) { + foo() + . + foo(); + } + public static Test foo() { + new Exception().printStackTrace(); + return new Test(); + } +} diff --git a/weaver/testsrc/TestSwitchy.java b/weaver/testsrc/TestSwitchy.java new file mode 100644 index 000000000..1f65a12d8 --- /dev/null +++ b/weaver/testsrc/TestSwitchy.java @@ -0,0 +1,31 @@ +/** + * @author hilsdale + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public abstract class TestSwitchy { + + + public int i = 3; + + public static final int j = 4; + + + public static void main(String[] args) { + switch (args.length) { + case 0: System.err.println("hi"); + case 1: System.err.println("bye"); break; + case 2: System.err.println("two"); + default: System.err.println("ning"); + } + System.err.println("done"); + } + + + abstract int goo(); + + void nimbo() {} +} diff --git a/weaver/testsrc/fluffy/Aspect.java b/weaver/testsrc/fluffy/Aspect.java new file mode 100644 index 000000000..7cb35bfa4 --- /dev/null +++ b/weaver/testsrc/fluffy/Aspect.java @@ -0,0 +1,31 @@ +package fluffy; +import java.util.*; + +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/testsrc/fluffy/Base.java b/weaver/testsrc/fluffy/Base.java new file mode 100644 index 000000000..9aa148d68 --- /dev/null +++ b/weaver/testsrc/fluffy/Base.java @@ -0,0 +1,15 @@ +package fluffy; + +public class Base { + + public static void onlyBase() {} + public static void both() {} + + public int onlyBase; + public int both; + + public Base() {} + public Base(int i) {} + + public void m() throws CloneNotSupportedException {} +} diff --git a/weaver/testsrc/fluffy/Derived.java b/weaver/testsrc/fluffy/Derived.java new file mode 100644 index 000000000..6c38db40e --- /dev/null +++ b/weaver/testsrc/fluffy/Derived.java @@ -0,0 +1,17 @@ +package fluffy; + +import java.io.IOException; + +public class Derived extends Base { + + public static void onlyDerived() throws IOException, CloneNotSupportedException {} + public static void both() {} + + public int onlyDerived; + public int both; + + public Derived() {} + + public void m() {} + +} diff --git a/weaver/testsrc/org/aspectj/weaver/AbstractWorldTestCase.java b/weaver/testsrc/org/aspectj/weaver/AbstractWorldTestCase.java new file mode 100644 index 000000000..4ae04c77f --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/AbstractWorldTestCase.java @@ -0,0 +1,179 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +import java.lang.reflect.Modifier; +import java.util.*; + +import junit.framework.TestCase; + +import org.aspectj.testing.util.TestUtil; + +/** This isn't a test case, it's extended by test cases, and includes tests that + * should be true in all worlds. + */ + +public abstract class AbstractWorldTestCase extends TestCase { + + public AbstractWorldTestCase(String name) { + super(name); + } + + protected abstract World getWorld(); + + private final TypeX[] primitiveTypeXs = + TypeX.forSignatures( + new String[] {"B", "S", "C", "I", "J", "F", "D", "V"}); + + public void testPrimitiveTypes() { + ResolvedTypeX[] primitives = getWorld().resolve(primitiveTypeXs); + for(int i = 0, len = primitives.length; i < len; i++) { + ResolvedTypeX ty = primitives[i]; + modifiersTest(ty, Modifier.PUBLIC | Modifier.FINAL); + fieldsTest(ty, ResolvedMember.NONE); + methodsTest(ty, ResolvedMember.NONE); + interfacesTest(ty, ResolvedTypeX.NONE); + superclassTest(ty, null); + pointcutsTest(ty, ResolvedMember.NONE); + isInterfaceTest(ty, false); + isClassTest(ty, false); + isAspectTest(ty, false); + for (int j = 0; j < len; j++) { + ResolvedTypeX ty1 = primitives[j]; + if (ty.equals(ty1)) { + isCoerceableFromTest(ty, ty1, true); + } else if (ty == ResolvedTypeX.BOOLEAN || ty1 == ResolvedTypeX.BOOLEAN || + ty == ResolvedTypeX.VOID || ty1 == ResolvedTypeX.VOID) { + isCoerceableFromTest(ty, ty1, false); + } else { + isCoerceableFromTest(ty, ty1, true); + } + } + isCoerceableFromTest(ty, TypeX.OBJECT, false); + + primAssignTest("B", new String[] {}); + primAssignTest("S", new String[] {"B"}); + primAssignTest("C", new String[] {"B"}); + primAssignTest("I", new String[] {"B", "S", "C"}); + primAssignTest("J", new String[] {"B", "S", "C", "I"}); + primAssignTest("F", new String[] {"B", "S", "C", "I", "J"}); + primAssignTest("D", new String[] {"B", "S", "C", "I", "J", "F"}); + primAssignTest("Z", new String[] {}); + primAssignTest("V", new String[] {}); + + } + } + private void primAssignTest(String sig, String[] lowers) { + ResolvedTypeX[] primitives = getWorld().resolve(primitiveTypeXs); + ResolvedTypeX ty = getWorld().resolve(TypeX.forSignature(sig)); + ResolvedTypeX[] lowerTyArray = + getWorld().resolve(TypeX.forSignatures(lowers)); + List lowerTys = new ArrayList(Arrays.asList(lowerTyArray)); + lowerTys.add(ty); + Set allLowerTys = new HashSet(lowerTys); + Set allUpperTys = new HashSet(Arrays.asList(primitives)); + allUpperTys.removeAll(allLowerTys); + + for (Iterator i = allLowerTys.iterator(); i.hasNext(); ) { + ResolvedTypeX other = (ResolvedTypeX) i.next(); + isAssignableFromTest(ty, other, true); + } + for (Iterator i = allUpperTys.iterator(); i.hasNext(); ) { + ResolvedTypeX other = (ResolvedTypeX) i.next(); + isAssignableFromTest(ty, other, false); + } + } + + public void testPrimitiveArrays() { + ResolvedTypeX[] primitives = getWorld().resolve(primitiveTypeXs); + for(int i = 0, len = primitives.length; i < len; i++) { + ResolvedTypeX ty = primitives[i]; + ResolvedTypeX aty = getWorld().resolve(TypeX.forSignature("[" + ty.getSignature())); + modifiersTest(aty, Modifier.PUBLIC | Modifier.FINAL); + fieldsTest(aty, ResolvedMember.NONE); + methodsTest(aty, ResolvedMember.NONE); + interfacesTest(aty, new ResolvedTypeX[] { + getWorld().resolve(TypeX.CLONEABLE), + getWorld().resolve(TypeX.SERIALIZABLE) }); + superclassTest(aty, TypeX.OBJECT); + + pointcutsTest(aty, ResolvedMember.NONE); + isInterfaceTest(aty, false); + isClassTest(aty, false); + isAspectTest(aty, false); + for (int j = 0; j < len; j++) { + ResolvedTypeX ty1 = primitives[j]; + isCoerceableFromTest(aty, ty1, false); + ResolvedTypeX aty1 = getWorld().resolve(TypeX.forSignature("[" + ty1.getSignature())); + if (ty.equals(ty1)) { + isCoerceableFromTest(aty, aty1, true); + isAssignableFromTest(aty, aty1, true); + } else { + isCoerceableFromTest(aty, aty1, false); + isAssignableFromTest(aty, aty1, false); + } + } + } + } + + // ---- tests for parts of ResolvedTypeX objects + + protected void modifiersTest(ResolvedTypeX ty, int mods) { + assertEquals(ty + " modifiers:", Modifier.toString(mods), Modifier.toString(ty.getModifiers())); + } + protected void fieldsTest(ResolvedTypeX ty, Member[] x) { + TestUtil.assertSetEquals(ty + " fields:", x, ty.getDeclaredJavaFields()); + } + protected void methodsTest(ResolvedTypeX ty, Member[] x) { + TestUtil.assertSetEquals(ty + " methods:", x, ty.getDeclaredJavaMethods()); + } + protected void mungersTest(ResolvedTypeX ty, ShadowMunger[] x) { + TestUtil.assertSetEquals(ty + " mungers:", x, ty.getDeclaredShadowMungersArray()); + } + protected void interfacesTest(ResolvedTypeX ty, ResolvedTypeX[] x) { + TestUtil.assertArrayEquals(ty + " interfaces:", x, ty.getDeclaredInterfaces()); + } + protected void superclassTest(ResolvedTypeX ty, TypeX x) { + assertEquals(ty + " superclass:", x, ty.getSuperclass()); + } + protected void pointcutsTest(ResolvedTypeX ty, Member[] x) { + TestUtil.assertSetEquals(ty + " pointcuts:", x, ty.getDeclaredPointcuts()); + } + protected void isInterfaceTest(ResolvedTypeX ty, boolean x) { + assertEquals(ty + " is interface:", x, ty.isInterface()); + } + protected void isAspectTest(ResolvedTypeX ty, boolean x) { + assertEquals(ty + " is aspect:", x, ty.isAspect()); + } + protected void isClassTest(ResolvedTypeX ty, boolean x) { + assertEquals(ty + " is class:", x, ty.isClass()); + } + protected void isCoerceableFromTest(TypeX ty0, TypeX ty1, boolean x) { + assertEquals(ty0 + " is coerceable from " + ty1, x, ty0.isCoerceableFrom(ty1, getWorld())); + assertEquals(ty1 + " is coerceable from " + ty0, x, ty1.isCoerceableFrom(ty0, getWorld())); + } + protected void isAssignableFromTest(TypeX ty0, TypeX ty1, boolean x) { + assertEquals(ty0 + " is assignable from " + ty1, x, ty0.isAssignableFrom(ty1, getWorld())); + } + + // ---- tests for parts of ResolvedMethod objects + + protected void modifiersTest(ResolvedMember m, int mods) { + assertEquals(m + " modifiers:", Modifier.toString(mods), Modifier.toString(m.getModifiers())); + } + protected void exceptionsTest(ResolvedMember m, TypeX[] exns) { + TestUtil.assertSetEquals(m + " exceptions:", exns, m.getExceptions()); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java b/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java new file mode 100644 index 000000000..5f2419dd0 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java @@ -0,0 +1,33 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +import junit.framework.*; + +public class BcweaverTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(BcweaverTests.class.getName()); + // abstract + //suite.addTestSuite(AbstractWorldTestCase.class); + //$JUnit-BEGIN$ + suite.addTestSuite(MemberTestCase.class); + suite.addTestSuite(TypeXTestCase.class); + //$JUnit-END$ + return suite; + } + + public BcweaverTests(String name) { super(name); } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/MemberTestCase.java b/weaver/testsrc/org/aspectj/weaver/MemberTestCase.java new file mode 100644 index 000000000..d3e2919b3 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/MemberTestCase.java @@ -0,0 +1,175 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +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 = Member.methodFromString("void Foo.goo(int)"); + Member t = Member.method(TypeX.forName("Foo"), 0, "goo", "(I)V"); + Member u = Member.methodFromString("void Foo1.goo(int)"); + Member v = Member.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 = Member.fieldFromString("int Foo.goo"); + t = Member.field("Foo", 0, "goo", "I"); + u = Member.fieldFromString("int Foo.goo1"); + v = Member.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 = Member.methodFromString("void Foo.goo(int)"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "Foo"); + nameTest(m, "goo"); + parameterTypesTest(m, new TypeX[] { ResolvedTypeX.INT }); + returnTypeTest(m, ResolvedTypeX.VOID); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = Member.methodFromString("interface java.lang.Object java.util.Iterator.next()"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "java.util.Iterator"); + nameTest(m, "next"); + parameterTypesTest(m, TypeX.NONE); + returnTypeTest(m, TypeX.OBJECT); + isInterfaceTest(m, true); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = Member.methodFromString("void Foo.<init>(int, java.lang.Object)"); + kindTest(m, Member.CONSTRUCTOR); + declaringTypeTest(m, "Foo"); + nameTest(m, "<init>"); + parameterTypesTest(m, new TypeX[] { ResolvedTypeX.INT, TypeX.OBJECT } ); + returnTypeTest(m, ResolvedTypeX.VOID); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, true); + isStaticTest(m, false); + + m = Member.methodFromString("private double Foo.sqrt(double)"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "Foo"); + nameTest(m, "sqrt"); + parameterTypesTest(m, new TypeX[] { ResolvedTypeX.DOUBLE } ); + returnTypeTest(m, ResolvedTypeX.DOUBLE); + isInterfaceTest(m, false); + isPrivateTest(m, true); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = Member.methodFromString("static int java.lang.Math.max(int, int)"); + kindTest(m, Member.METHOD); + declaringTypeTest(m, "java.lang.Math"); + nameTest(m, "max"); + parameterTypesTest(m, new TypeX[] { ResolvedTypeX.INT, ResolvedTypeX.INT } ); + returnTypeTest(m, ResolvedTypeX.INT); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, true); + } + + public void testFieldContents() { + Member m = Member.fieldFromString("int Foo.goo"); + kindTest(m, Member.FIELD); + declaringTypeTest(m, "Foo"); + nameTest(m, "goo"); + parameterTypesTest(m, TypeX.NONE); + returnTypeTest(m, ResolvedTypeX.INT); + isInterfaceTest(m, false); + isPrivateTest(m, false); + isConstructorTest(m, false); + isStaticTest(m, false); + + m = Member.fieldFromString("static java.util.Iterator goo.Bar.i"); + kindTest(m, Member.FIELD); + declaringTypeTest(m, "goo.Bar"); + nameTest(m, "i"); + parameterTypesTest(m, TypeX.NONE); + returnTypeTest(m, TypeX.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, m.isStatic()); + } + 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, m.isPrivate()); + } + private void isInterfaceTest(Member m, boolean b) { + assertEquals(m + " is interface", b, m.isInterface()); + } + private void returnTypeTest(Member m, TypeX returnType) { + assertEquals(m + " return type", returnType, m.getReturnType()); + } + private void parameterTypesTest(Member m, TypeX[] 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", TypeX.forName(declaringName), m.getDeclaringType()); + } + private void kindTest(Member m, Member.Kind kind) { + assertEquals(m + " kind", kind, m.getKind()); + } + + + +} diff --git a/weaver/testsrc/org/aspectj/weaver/TestShadow.java b/weaver/testsrc/org/aspectj/weaver/TestShadow.java new file mode 100644 index 000000000..ae22c8000 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/TestShadow.java @@ -0,0 +1,79 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +import org.aspectj.weaver.ast.Var; +import org.aspectj.bridge.SourceLocation; + +public class TestShadow extends Shadow { + + private final World world; + private final TypeX thisType; + + public TestShadow(Kind kind, Member signature, TypeX thisType, World world) { + super(kind, signature); + this.world = world; + this.thisType = thisType; + } + + public World getIWorld() { + return world; + } + + public boolean hasThis() { return true; } + + public TypeX getThisType() { + return thisType; + } + + /** this is subtly wrong. ha ha */ + public TypeX 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 getThisJoinPointVar() { + throw new RuntimeException("unimplemented"); + } + + public SourceLocation getSourceLocation() { + throw new RuntimeException("unimplemented"); + } + + public Member getEnclosingCodeSignature() { + throw new RuntimeException("unimplemented"); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java b/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java new file mode 100644 index 000000000..87b0317f8 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/TypeXTestCase.java @@ -0,0 +1,124 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver; + +import junit.framework.TestCase; + +import org.aspectj.testing.util.TestUtil; + +/** + * This is a test case for all the portions of TypeX 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(TypeX.forNames(testNames), componentNames); + arrayTest(TypeX.forSignatures(testSigs), componentNames); + + sizeTest(TypeX.forNames(testNames), sizes); + sizeTest(TypeX.forSignatures(testSigs), sizes); + + isPrimitiveTest(TypeX.forSignatures(testSigs), isPrimitive); + } + + public void testNameAndSigWithInners() { + TypeX t = TypeX.forName("java.util.Map$Entry"); + assertEquals(t.getName(), "java.util.Map$Entry"); + assertEquals(t.getSignature(), "Ljava/util/Map$Entry;"); + assertEquals(t.getDeclaringType(), TypeX.forName("java.util.Map")); + assertNull(TypeX.forName("java.util.Map").getDeclaringType()); + } + + private void isPrimitiveTest(TypeX[] types, boolean[] isPrimitives) { + for (int i = 0, len = types.length; i < len; i++) { + TypeX type = types[i]; + boolean b = isPrimitives[i]; + assertEquals(type + " is primitive: ", b, type.isPrimitive()); + } + } + + private void sizeTest(TypeX[] types, int[] sizes) { + for (int i = 0, len = types.length; i < len; i++) { + TypeX type = types[i]; + int size = sizes[i]; + assertEquals("size of " + type + ": ", size, type.getSize()); + } + } + + private void arrayTest(TypeX[] types, String[] components) { + for (int i = 0, len = types.length; i < len; i++) { + TypeX 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]; + TypeX tn = TypeX.forName(n); + TypeX ts = TypeX.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; + TypeX tn1 = TypeX.forName(ns[j]); + TypeX ts1 = TypeX.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/testsrc/org/aspectj/weaver/bcel/AfterReturningWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/AfterReturningWeaveTestCase.java new file mode 100644 index 000000000..a66fc0d40 --- /dev/null +++ b/weaver/testsrc/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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/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/testsrc/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java new file mode 100644 index 000000000..0202fdb69 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/AfterThrowingWeaveTestCase.java @@ -0,0 +1,43 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +import org.aspectj.weaver.*; + +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 = + world.shadowMunger("afterThrowing(): get(* *.out) -> static void Aspect.ajc_afterThrowing_field_get(java.lang.Throwable)", + Advice.ExtraArgument); + ShadowMunger cm = myMunger.concretize(ResolvedTypeX.MISSING, world, null); + + weaveTest(getStandardTargets(), "AfterThrowingParam", cm); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/AfterWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/AfterWeaveTestCase.java new file mode 100644 index 000000000..ef91d979f --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/AfterWeaveTestCase.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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.util.*; +import java.io.*; + +import junit.framework.TestResult; + +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/testsrc/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java new file mode 100644 index 000000000..e0761bf0d --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/ArgsWeaveTestCase.java @@ -0,0 +1,109 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.util.*; +import java.io.*; + +import org.apache.bcel.Constants; +import org.apache.bcel.generic.*; +import org.aspectj.weaver.bcel.*; +import org.aspectj.weaver.*; + +/**. + */ +public class ArgsWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public ArgsWeaveTestCase(String name) { + super(name); + } + + + public void testAfterReturningArgs() throws IOException { + weaveTest("HelloWorld", "ArgsAfterReturningHelloWorld", makeArgsMunger("afterReturning")); + } + + + public void testFancyAfterReturningArgs() throws IOException { + weaveTest("FancyHelloWorld", "ArgsAfterReturningFancyHelloWorld", makeArgsMunger("afterReturning")); + } + + public void testThrowing() throws IOException { + weaveTest("HelloWorld", "ArgsAfterThrowingHelloWorld", makeArgsMunger("afterThrowing")); + } + + public void testLots() throws IOException { + List l = new ArrayList(); + + + BcelAdvice p1 = + makeArgsMunger("before"); + + BcelAdvice p2 = + makeArgsMunger("afterThrowing"); + + BcelAdvice p3 = + makeArgsMunger("afterReturning"); + + l.add(p1); + l.add(p2); + l.add(p3); + + + weaveTest("HelloWorld", "ArgsBeforeAfterHelloWorld", addLexicalOrder(l)); + } + + private InstructionList getArgsAdviceTag(BcelShadow shadow, String where) { + String methodName = + "ajc_" + where + "_" + shadow.getKind().toLegalJavaIdentifier(); + InstructionFactory fact = shadow.getFactory(); + InstructionList il = new InstructionList(); + + + il.append( + BcelRenderer.renderExpr( + fact, + new BcelWorld(), + shadow.getArgVar(0), + Type.OBJECT)); + + il.append( + fact.createInvoke( + "Aspect", + methodName, + Type.VOID, + new Type[] { Type.OBJECT }, + Constants.INVOKESTATIC)); + + return il; + } + + private BcelAdvice makeArgsMunger(final String kindx) { + return new BcelAdvice(AdviceKind.stringToKind(kindx), makePointcutNoZeroArg(), + Member.method(TypeX.forName("Aspect"), 0, "foo", "()V"), 0, -1, -1, null, + world.resolve(TypeX.forName("Aspect"))) { + public void specializeOn(Shadow shadow) { + super.specializeOn(shadow); + shadow.getArgVar(0); + } + public InstructionList getAdviceInstructions(BcelShadow shadow, BcelVar extraVar, InstructionHandle fk) { + return getArgsAdviceTag(shadow, kindx); + } + }; + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/AroundArgsWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/AroundArgsWeaveTestCase.java new file mode 100644 index 000000000..47b80d7ef --- /dev/null +++ b/weaver/testsrc/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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/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/testsrc/org/aspectj/weaver/bcel/AroundWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/AroundWeaveTestCase.java new file mode 100644 index 000000000..28d0e1a7a --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/AroundWeaveTestCase.java @@ -0,0 +1,93 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.*; + +import org.aspectj.weaver.*; + +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 = new BcelWorld(); + final Member sig = + Member.method( + TypeX.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, TypeX.forName("Aspect").resolve(world)) + { + public void specializeOn(Shadow s) { + super.specializeOn(s); + ((BcelShadow) s).initializeForAroundClosure(); + } + }; + } + + private void aroundTest(String outName, final boolean matchOnlyPrintln) throws IOException { + weaveTest(getStandardTargets(), outName, makeAroundMunger(matchOnlyPrintln)); + } + + private void aroundTestAndOthers(String outName, final boolean matchOnlyPrintln) + throws IOException + { + + List l = new ArrayList(); + + // the afterReturning was taken out to avoid circular advice dependency + + l.addAll(makeAdviceAll("before", matchOnlyPrintln)); + //l.addAll(makeAdviceAll("afterReturning", matchOnlyPrintln)); + + l.add(makeAroundMunger(matchOnlyPrintln)); + + l.addAll(makeAdviceAll("before", matchOnlyPrintln)); + //l.addAll(makeAdviceAll("afterReturning", matchOnlyPrintln)); + + l.add(makeAroundMunger(matchOnlyPrintln)); + weaveTest(getStandardTargets(), outName, addLexicalOrder(l)); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/BcelTests.java b/weaver/testsrc/org/aspectj/weaver/bcel/BcelTests.java new file mode 100644 index 000000000..88b252b6a --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/BcelTests.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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import junit.framework.*; + +public class BcelTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(BcelTests.class.getName()); + // abstract + //suite.addTestSuite(WeaveTestCase.class); + //$JUnit-BEGIN$ + suite.addTestSuite(AfterReturningWeaveTestCase.class); + suite.addTestSuite(AfterThrowingWeaveTestCase.class); + suite.addTestSuite(AfterWeaveTestCase.class); + suite.addTestSuite(ArgsWeaveTestCase.class); + suite.addTestSuite(AroundArgsWeaveTestCase.class); + suite.addTestSuite(AroundWeaveTestCase.class); + suite.addTestSuite(BeforeWeaveTestCase.class); + suite.addTestSuite(CheckerTestCase.class); + suite.addTestSuite(FieldSetTestCase.class); + suite.addTestSuite(HierarchyDependsTestCase.class); + suite.addTestSuite(IdWeaveTestCase.class); + suite.addTestSuite(MoveInstructionsWeaveTestCase.class); + suite.addTestSuite(NonstaticWeaveTestCase.class); + suite.addTestSuite(PatternWeaveTestCase.class); + suite.addTestSuite(PointcutResidueTestCase.class); + suite.addTestSuite(TraceJarWeaveTestCase.class); + suite.addTestSuite(TjpWeaveTestCase.class); + suite.addTestSuite(UtilityTestCase.class); + suite.addTestSuite(WeaveOrderTestCase.class); + suite.addTestSuite(WorldTestCase.class); + suite.addTestSuite(ZipTestCase.class); + //$JUnit-END$ + return suite; + } + + public BcelTests(String name) { super(name); } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/BeforeWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/BeforeWeaveTestCase.java new file mode 100644 index 000000000..04a285096 --- /dev/null +++ b/weaver/testsrc/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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/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/testsrc/org/aspectj/weaver/bcel/CheckerTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/CheckerTestCase.java new file mode 100644 index 000000000..f0a2747e8 --- /dev/null +++ b/weaver/testsrc/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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/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/testsrc/org/aspectj/weaver/bcel/FieldSetTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/FieldSetTestCase.java new file mode 100644 index 000000000..15d1fa680 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/FieldSetTestCase.java @@ -0,0 +1,35 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.util.Collections; + +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/testsrc/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java new file mode 100644 index 000000000..939a62748 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/HierarchyDependsTestCase.java @@ -0,0 +1,67 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import junit.framework.TestCase; + +import org.apache.bcel.classfile.JavaClass; +import org.aspectj.weaver.TypeX; +import org.aspectj.weaver.patterns.*; + + +public class HierarchyDependsTestCase extends TestCase { + + /** + * Constructor for ParserTestCase. + * @param arg0 + */ + public HierarchyDependsTestCase(String arg0) { + super(arg0); + } + + + public void testHierarchyDepends() { + BcelWorld world = new BcelWorld(); + TypePatternQuestions questions = new TypePatternQuestions(); + BcelObjectType runnableType = (BcelObjectType)world.resolve("java.lang.Runnable"); + BcelObjectType numberType = (BcelObjectType)world.resolve("java.lang.Number"); + BcelObjectType integerType = (BcelObjectType)world.resolve("java.lang.Integer"); + BcelObjectType stringType = (BcelObjectType)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/testsrc/org/aspectj/weaver/bcel/IdWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/IdWeaveTestCase.java new file mode 100644 index 000000000..031bf1c8d --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/IdWeaveTestCase.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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.util.*; + +import org.apache.bcel.util.ClassPath; +import org.aspectj.weaver.*; +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"}, "Id", 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 void implementOn(Shadow shadow) { + l.add(shadow); + } + }; + weaveTest(new String[] {"HelloWorld"}, "Id", 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/testsrc/org/aspectj/weaver/bcel/MegaZipTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/MegaZipTestCase.java new file mode 100644 index 000000000..72ad0d0a4 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/MegaZipTestCase.java @@ -0,0 +1,111 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.*; +import java.lang.reflect.Modifier; +import java.util.*; + +import org.aspectj.weaver.*; + +public class MegaZipTestCase extends WeaveTestCase { + + public MegaZipTestCase(String arg0) { + super(arg0); + } + + + private BcelAdvice makeAroundMunger(final boolean matchOnlyPrintln) { + BcelWorld world = new BcelWorld(); + final Member sig = + Member.method( + TypeX.forName("fluffy.Aspect"), + Modifier.STATIC, + "aroundFun", + "(Lorg/aspectj/runtime/internal/AroundClosure;)Ljava/lang/Object;"); + + return new BcelAdvice( + AdviceKind.stringToKind("around"), + matchOnlyPrintln ? makePointcutPrintln() : makePointcutAll(), + sig, 0, -1, -1, null, null) + { + public void specializeOn(Shadow s) { + super.specializeOn(s); + ((BcelShadow) s).initializeForAroundClosure(); + } + }; + } + + public List getShadowMungers() { + List ret = new ArrayList(); + ret.add( + makeConcreteAdvice( + "before" + + "(): call(* *.println(..)) -> static void fluffy.Aspect.before_method_call()")); + ret.add( + makeConcreteAdvice( + "afterReturning" + + "(): call(* *.println(..)) -> static void fluffy.Aspect.afterReturning_method_call()")); + + ret.add( + makeConcreteAdvice( + "before" + + "(): execution(* *.*(..)) -> static void fluffy.Aspect.ignoreMe()")); + + ret.add( + makeConcreteAdvice( + "afterReturning" + + "(): execution(* *.*(..)) -> static void fluffy.Aspect.ignoreMe()")); + + ret.add( + makeConcreteAdvice( + "afterThrowing" + + "(): execution(* *.*(..)) -> static void fluffy.Aspect.afterThrowing_method_execution(java.lang.Throwable)", + 1)); + ret.add( + makeConcreteAdvice( + "after" + + "(): execution(* *.*(..)) -> static void fluffy.Aspect.ignoreMe()")); + + + ret.add(makeAroundMunger(true)); + return ret; + } + + + public void zipTest(String fileName) throws IOException { + long startTime = System.currentTimeMillis(); + File inFile = new File("testdata", fileName); + File outFile = new File("out", 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); + } + + // this is something we test every now and again. + public void testBig() throws IOException { + System.out.println("could take 80 seconds..."); + zipTest("aspectjtools.jar"); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java new file mode 100644 index 000000000..3c964c4ae --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/MoveInstructionsWeaveTestCase.java @@ -0,0 +1,73 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.util.*; +import java.io.*; + +import junit.framework.TestResult; + +import org.apache.bcel.generic.*; +import org.apache.bcel.generic.InstructionList; +import org.aspectj.weaver.*; + +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 void implementOn(Shadow s) { + BcelShadow shadow = (BcelShadow) s; + LazyMethodGen newMethod = shadow.extractMethod(shadow.getSignature().getExtractableName() + "_extracted"); + shadow.getRange().append(shadow.makeCallToCallback(newMethod)); + + if (! shadow.isFallsThrough()) { + shadow.getRange().append(shadow.getFactory().createReturn(newMethod.getReturnType())); + } + } + }; + + 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 void implementOn(Shadow s) { + BcelShadow shadow = (BcelShadow) s; + LazyMethodGen newMethod = shadow.extractMethod(shadow.getSignature().getExtractableName() + "_extracted" + counter++); + shadow.getRange().append(shadow.makeCallToCallback(newMethod)); + + if (! shadow.isFallsThrough()) { + shadow.getRange().append(shadow.getFactory().createReturn(newMethod.getReturnType())); + } + } + }; + + weaveTest("FancyHelloWorld", "ExtractedFancyHelloWorld", p); + } +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java new file mode 100644 index 000000000..75247d3f2 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/NonstaticWeaveTestCase.java @@ -0,0 +1,86 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; +import java.util.*; +import java.util.List; + +import org.aspectj.weaver.*; +import org.aspectj.weaver.ShadowMunger; +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)); + + ResolvedTypeX onAspect = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(onAspect); + 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)); + + ResolvedTypeX onAspect = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(onAspect); + 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/testsrc/org/aspectj/weaver/bcel/PatternWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/PatternWeaveTestCase.java new file mode 100644 index 000000000..22c0a2011 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/PatternWeaveTestCase.java @@ -0,0 +1,117 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.*; +import java.util.*; + +import org.aspectj.weaver.*; +import org.aspectj.weaver.patterns.*; + +public class PatternWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public PatternWeaveTestCase(String name) { + super(name); + } + + String[] none = new String[0]; + + + 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(ResolvedTypeX.MISSING, 0); + + final List l = new ArrayList(); + BcelAdvice p = new BcelAdvice(null, cp, null, 0, -1, -1, null, null) { + public void implementOn(Shadow shadow) { + l.add(shadow); + } + }; + 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(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + Pointcut newP = Pointcut.read(in, null); + + assertEquals("write/read", p, newP); + } + + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/PointcutResidueTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/PointcutResidueTestCase.java new file mode 100644 index 000000000..7dafd2f9b --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/PointcutResidueTestCase.java @@ -0,0 +1,236 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.*; +import java.lang.reflect.Modifier; +import java.util.*; + +import org.aspectj.weaver.*; +import org.aspectj.weaver.patterns.*; +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(TypeX.forNames(formalTypes), + formalNames) + )); + + ShadowMunger pp = + world.concreteAdvice( + AdviceKind.Before, + rp, + Member.method( + TypeX.forName("Aspect"), + Modifier.STATIC, + "ajc_before_0", + Member.typesToSignature( + ResolvedTypeX.VOID, + TypeX.forNames(formalTypes))), + 0, -1, -1, null); + + ResolvedTypeX inAspect = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(inAspect); + 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(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + Pointcut newP = Pointcut.read(in, null); + + assertEquals("write/read", p, newP); + } + + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java new file mode 100644 index 000000000..32aede4d7 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/TjpWeaveTestCase.java @@ -0,0 +1,97 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.util.*; +import java.io.*; + +import org.apache.bcel.Constants; +import org.apache.bcel.generic.*; +import org.aspectj.weaver.bcel.*; +import org.aspectj.weaver.*; + +public class TjpWeaveTestCase extends WeaveTestCase { + { + regenerate = false; + } + + public TjpWeaveTestCase(String name) { + super(name); + } + + + public void testStaticTjp() throws IOException { + BcelAdvice munger = new BcelAdvice( + AdviceKind.stringToKind("before"), + makePointcutAll(), + Member.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(), + Member.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(), + Member.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(), + Member.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 { + BcelAdvice munger1 = new BcelAdvice( + AdviceKind.stringToKind("around"), + makePointcutAll(), + Member.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, + world.resolve(TypeX.forName("Aspect"))); + + BcelAdvice munger2 = new BcelAdvice( + AdviceKind.stringToKind("around"), + makePointcutAll(), + Member.methodFromString("static java.lang.Object Aspect.ajc_around(org.aspectj.runtime.internal.AroundClosure, org.aspectj.lang.JoinPoint)"), + Advice.ThisJoinPoint | Advice.ExtraArgument, -1, -1, null, + world.resolve(TypeX.forName("Aspect"))); + + weaveTest("HelloWorld", "TjpAround2HelloWorld", Arrays.asList(new BcelAdvice[] {munger1, munger2})); + } + + + + +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/TraceJarWeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/TraceJarWeaveTestCase.java new file mode 100644 index 000000000..ed06ecd1e --- /dev/null +++ b/weaver/testsrc/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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.IOException; + +public class TraceJarWeaveTestCase extends WeaveTestCase { + { + regenerate = true; + } + + 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", outDir); + + weaver.addClassFile(classFile); + weaver.prepareForWeave(); + + weaveTestInner(weaver, classFile, "DynamicHelloWorld", "TraceJarHello"); + } +} diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/UtilityTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/UtilityTestCase.java new file mode 100644 index 000000000..a18856711 --- /dev/null +++ b/weaver/testsrc/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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; +import java.io.*; + +import junit.framework.TestCase; + +import org.apache.bcel.util.ClassPath; + +public class UtilityTestCase extends TestCase { + + public UtilityTestCase(String name) { + super(name); + } + + public void disassembleTest(String name) throws IOException { + BcelWorld world = new BcelWorld("../bcweaver/bin"); + + LazyClassGen clazz = new LazyClassGen((BcelObjectType) 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((BcelObjectType)world.resolve(args[0])); + clazz.print(); + } +} + diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/WeaveOrderTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveOrderTestCase.java new file mode 100644 index 000000000..a2a4c9787 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveOrderTestCase.java @@ -0,0 +1,155 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.util.*; +import java.io.*; + +import org.apache.bcel.Constants; +import org.apache.bcel.generic.*; +import org.aspectj.weaver.patterns.*; +import org.aspectj.weaver.patterns.DeclareDominates; +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, TypeX.OBJECT, TypeX.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.THROWABLE, 2); + + assertEquals(-1, a2.compareTo(a1)); + assertEquals(+1, a1.compareTo(a2)); + } + + public void testLexicalOrderWithAfter() { + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.After, TypeX.OBJECT, TypeX.THROWABLE, 2); + + assertEquals(+1, a2.compareTo(a1)); + assertEquals(-1, a1.compareTo(a2)); + + a1 = + makeConcreteAdvice(AdviceKind.After, TypeX.OBJECT, TypeX.OBJECT, 1); + a2 = + makeConcreteAdvice(AdviceKind.After, TypeX.OBJECT, TypeX.THROWABLE, 2); + + assertEquals(+1, a2.compareTo(a1)); + assertEquals(-1, a1.compareTo(a2)); + } + + public void testSubtypes() { + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, TypeX.THROWABLE, TypeX.OBJECT, 1); + Advice a3 = + makeConcreteAdvice(AdviceKind.Before, TypeX.forName("java.lang.String"), TypeX.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 dominates: java.lang.String, java.lang.Throwable").parseDeclare(); + //??? concretize dom + ResolvedTypeX aType = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(aType); + aType.crosscuttingMembers = xcut; + xcut.addDeclare(dom); + world.getCrosscuttingMembersSet().addFixedCrosscuttingMembers(aType); + + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.OBJECT, 1); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.THROWABLE, 2); + Advice a3 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.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 dominates: *, java.lang.String, java.lang.Throwable").parseDeclare(); + //??? concretize dom + ResolvedTypeX aType = world.resolve("Aspect"); + CrosscuttingMembers xcut = new CrosscuttingMembers(aType); + aType.crosscuttingMembers = xcut; + xcut.addDeclare(dom); + world.getCrosscuttingMembersSet().addFixedCrosscuttingMembers(aType); + + Advice a1 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.OBJECT, 2); + Advice a2 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.THROWABLE, 1); + Advice a3 = + makeConcreteAdvice(AdviceKind.Before, TypeX.OBJECT, TypeX.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, TypeX declaringAspect, + TypeX concreteAspect, int lexicalPosition) + { + Advice a1 = new BcelAdvice(kind, makeResolvedPointcut("this(*)"), + Member.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/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java new file mode 100644 index 000000000..62c078e61 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/WeaveTestCase.java @@ -0,0 +1,324 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; +import java.io.*; +import java.util.*; +import java.util.zip.*; +import java.util.zip.ZipFile; + +import junit.framework.*; + +import org.apache.bcel.Constants; +import org.apache.bcel.generic.*; +import org.aspectj.weaver.*; +import org.aspectj.weaver.patterns.*; +import org.aspectj.testing.util.TestUtil; +import org.aspectj.util.FileUtil; + +public abstract class WeaveTestCase extends TestCase { + + public boolean regenerate = false; + public boolean runTests = true; + + public BcelWorld world = new BcelWorld(); + + public WeaveTestCase(String name) { + super(name); + } + + public static InstructionList getAdviceTag(BcelShadow shadow, String where) { + String methodName = + "ajc_" + where + "_" + shadow.getKind().toLegalJavaIdentifier(); + + InstructionFactory fact = shadow.getFactory(); + InvokeInstruction il = + fact.createInvoke("Aspect", methodName, Type.VOID, new Type[] { + }, Constants.INVOKESTATIC); + return new InstructionList(il); + } + + public void weaveTest(String name, String outName, ShadowMunger planner) throws IOException { + List l = new ArrayList(1); + l.add(planner); + weaveTest(name, outName, l); + } + + static String classDir = "../bcweaver/bin"; + static String outDir = "out"; + + + public void weaveTest(String name, String outName, List planners) throws IOException { + BcelWeaver weaver = new BcelWeaver(world); + + UnwovenClassFile classFile = makeUnwovenClassFile(classDir, name, outDir); + + weaver.addClassFile(classFile); + weaver.setShadowMungers(planners); + weaveTestInner(weaver, classFile, name, outName); + } + + + protected void weaveTestInner( + BcelWeaver weaver, + UnwovenClassFile classFile, + String name, + String outName) + throws IOException + { + //int preErrors = currentResult.errorCount(); + BcelObjectType classType = + (BcelObjectType) 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 = new LazyClassGen(classType); + } + try { + checkClass(gen, outDir, outName + ".txt"); + if (runTests) { + System.out.println( + "*******RUNNING: " + outName + " " + name + " *******"); + TestUtil.runMain(makeClassPath(outDir), name); + } + } catch (Error e) { + gen.print(System.err); + throw e; + } catch (RuntimeException e) { + gen.print(System.err); + throw e; + } + } + + public String makeClassPath(String outDir) { + return outDir + + File.pathSeparator + + getTraceJar() + + 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); + } + + void genClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException { + //ClassGen b = getJavaClass(outDir, className); + FileOutputStream out = new FileOutputStream(new File("testdata", expectedFile)); + PrintStream ps = new PrintStream(out); + gen.print(ps); + ps.flush(); + + } + + void realCheckClass(LazyClassGen gen, String outDir, String expectedFile) throws IOException { + TestUtil.assertMultiLineStringEquals("classes", + FileUtil.readAsString(new File("testdata", 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 = + world.shadowMunger(mungerString, extraArgFlag); + +// PerSingleton s = new PerSingleton(); +// s.concretize(world.resolve("Aspect")); + //System.err.println(((KindedPointcut)myMunger.getPointcut().getPointcut()).getKind()); + Advice cm = (Advice) myMunger.concretize(myMunger.getDeclaringAspect().resolve(world), + world, perClause); + return cm; + } + + public ShadowMunger makeAdviceField(String kind, String extraArgType) { + return makeConcreteAdvice( + kind + + "(): get(* *.*) -> static void Aspect.ajc_" + + kind + + "_field_get(" + + extraArgType + + ")", + 1); + } + + public List makeAdviceAll(String kind, boolean matchOnlyPrintln) { + List ret = new ArrayList(); + if (matchOnlyPrintln) { + ret.add( + makeConcreteAdvice( + kind + + "(): call(* *.println(..)) -> static void Aspect.ajc_" + + kind + + "_method_execution()")); + } else { + ret.add( + makeConcreteAdvice( + kind + + "(): call(* *.*(..)) -> static void Aspect.ajc_" + + kind + + "_method_call()")); + ret.add( + makeConcreteAdvice( + kind + + "(): call(*.new(..)) -> static void Aspect.ajc_" + + kind + + "_constructor_call()")); + ret.add( + makeConcreteAdvice( + kind + + "(): execution(* *.*(..)) -> static void Aspect.ajc_" + + kind + + "_method_execution()")); + ret.add( + makeConcreteAdvice( + kind + + "(): execution(*.new(..)) -> static void Aspect.ajc_" + + kind + + "_constructor_execution()")); +// ret.add( +// makeConcreteMunger( +// kind +// + "(): staticinitialization(*) -> static void Aspect.ajc_" +// + kind +// + "_staticinitialization()")); + ret.add( + makeConcreteAdvice( + kind + "(): get(* *.*) -> static void Aspect.ajc_" + kind + "_field_get()")); +// ret.add( +// makeConcreteMunger( +// kind + "(): set(* *.*) -> static void Aspect.ajc_" + kind + "_field_set()")); + // XXX no test for advice execution, staticInitialization or (god help us) preInitialization + } + return ret; + } + + public List makeAdviceAll(final String kind) { + return makeAdviceAll(kind, false); + } + + public Pointcut makePointcutAll() { + return makeConcretePointcut("get(* *.*) || call(* *.*(..)) || execution(* *.*(..)) || call(*.new(..)) || execution(*.new(..))"); + } + public Pointcut makePointcutNoZeroArg() { + return makeConcretePointcut("call(* *.*(*, ..)) || execution(* *.*(*, ..)) || call(*.new(*, ..)) || execution(*.new(*, ..))"); + } + + public Pointcut makePointcutPrintln() { + return makeConcretePointcut("call(* *.println(..))"); + } + + + public Pointcut makeConcretePointcut(String s) { + return makeResolvedPointcut(s).concretize(null, 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 "testdata/tracing.jar"; + } + + // ---- + + protected void weaveTest( + String[] inClassNames, + String outKind, + ShadowMunger patternMunger) throws IOException { + for (int i = 0; i < inClassNames.length; i++) { + String inFileName = inClassNames[i]; + weaveTest(inFileName, outKind + inFileName, patternMunger); + } + } + protected void weaveTest( + String[] inClassNames, + String outKind, + List patternMungers) throws IOException { + for (int i = 0; i < inClassNames.length; i++) { + String inFileName = inClassNames[i]; + weaveTest(inFileName, outKind + inFileName, patternMungers); + } + } + + protected List addLexicalOrder(List l) { + int i = 10; + for (Iterator iter = l.iterator(); iter.hasNext();) { + Advice element = (Advice) iter.next(); + 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/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java new file mode 100644 index 000000000..47202bb66 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/WorldTestCase.java @@ -0,0 +1,148 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.lang.reflect.Modifier; + +import org.apache.bcel.util.ClassPath; +import org.aspectj.weaver.*; + +/** + * This is a test case for the nameType parts of worlds. + */ +public class WorldTestCase extends AbstractWorldTestCase { + + public WorldTestCase(String name) { + super(name); + } + + private final BcelWorld world = new BcelWorld("testdata/tracing.jar"); + + protected World getWorld() { + return world; + } + + // XXX fix the various XXXs before expecting this test to work + public void xtestTraceJar() { + ResolvedTypeX trace = world.resolve(TypeX.forName("Trace")); + + fieldsTest(trace, Member.NONE); + Member constr = Member.methodFromString("void Trace.<init>()"); + //XXX need attribute fix - + //methodsTest(trace, new Member[] { constr }); + + interfacesTest(trace, ResolvedTypeX.NONE); + superclassTest(trace, TypeX.OBJECT); + isInterfaceTest(trace, false); + isClassTest(trace, false); + isAspectTest(trace, true); + + pointcutsTest(trace, + new Member[] { + Member.pointcut(trace, "traced", "(Ljava/lang/Object;)V"), + }); + + modifiersTest(trace.findPointcut("traced"), + Modifier.PUBLIC | Modifier.ABSTRACT); + + mungersTest(trace, + new ShadowMunger[] { + world.shadowMunger("before(foo): traced(foo) -> void Trace.ajc_before_4(java.lang.Object))", + 0), + world.shadowMunger("afterReturning(foo): traced(foo) -> void Trace.ajc_afterreturning_3(java.lang.Object, java.lang.Object))", + Advice.ExtraArgument), + world.shadowMunger("around(): execution(* doit(..)) -> java.lang.Object Trace.ajc_around_2(org.aspectj.runtime.internal.AroundClosure))", + Advice.ExtraArgument), + world.shadowMunger("around(foo): traced(foo) -> java.lang.Object Trace.ajc_around_1(java.lang.Object, org.aspectj.runtime.internal.AroundClosure))", + Advice.ExtraArgument), + }); + + ResolvedTypeX myTrace = world.resolve(TypeX.forName("MyTrace")); + + interfacesTest(myTrace, ResolvedTypeX.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[] { + Member.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; + ResolvedTypeX iter = world.resolve(TypeX.forName("java.util.Iterator")); + + modifiersTest(iter, abstractPublic | Modifier.INTERFACE); + fieldsTest(iter, ResolvedMember.NONE); + methodsTest(iter, + new Member[] { + Member.method(iter, 0, "hasNext", "()Z"), + Member.method(iter, 0, "remove", "()V"), + Member.method(iter, 0, "next", "()Ljava/lang/Object;"), + }); + ResolvedMember remove = iter.lookupMethod(Member.method(iter, 0, "remove", "()V")); + assertNotNull("iterator doesn't have remove" , remove); + modifiersTest(remove, abstractPublic | Modifier.INTERFACE); + exceptionsTest(remove, TypeX.NONE); + + ResolvedMember clone = iter.lookupMethod(Member.method(TypeX.OBJECT, 0, "clone", "()Ljava/lang/Object;")); + assertNotNull("iterator doesn't have clone" , clone); + modifiersTest(clone, Modifier.PROTECTED | Modifier.NATIVE); + exceptionsTest(clone, TypeX.forNames(new String[] {"java.lang.CloneNotSupportedException"})); + + interfacesTest(iter, ResolvedTypeX.NONE); + superclassTest(iter, TypeX.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/testsrc/org/aspectj/weaver/bcel/ZipTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/ZipTestCase.java new file mode 100644 index 000000000..27e68fc93 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/bcel/ZipTestCase.java @@ -0,0 +1,90 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.bcel; + +import java.io.*; +import java.util.Collection; + +import junit.framework.TestCase; + +public class ZipTestCase extends TestCase { + + /** + * Constructor for ZipTestCase. + * @param arg0 + */ + public ZipTestCase(String arg0) { + super(arg0); + } + + + 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("out", inFile.getName()); + + + BcelWorld world = new BcelWorld(); + //BcelWeaver weaver1 = new BcelWeaver(world); + BcelWeaver weaver = new BcelWeaver(world); + + long startTime = System.currentTimeMillis(); + weaver.addJarFile(inFile, new File(".")); + if (aspectjar != null) { + if (isInJar) { + weaver.addJarFile(new File(aspectjar), new File(".")); + } else { + weaver.addLibraryJarFile(new File(aspectjar)); + } + } + + + Collection woven = weaver.weave(outFile); + long stopTime = System.currentTimeMillis(); + + + System.out.println("handled " + woven.size() + " entries, in " + + (stopTime-startTime)/1000. + " seconds"); + assertTrue(outFile.lastModified() > startTime); + } + + public void testSmall() throws IOException { + zipTest("testdata/Regex.jar", null); + } + + public void testSmallWithAspects() throws IOException { + System.out.println("could take 4 seconds..."); + zipTest("testdata/Regex.jar", "testdata/megatrace.jar"); + } + + public void testSmallWithAspectsNoWeave() throws IOException { + System.out.println("could take 4 seconds..."); + zipTest("testdata/Regex.jar", "testdata/megatraceNoweave.jar", true); + } + + // this is something we test every now and again. + public void testBig() throws IOException { + System.out.println("could take 4 seconds..."); + zipTest("../lib/bcel/bcel.jar", null); + } + + public void xtestBigWithAspects() throws IOException { + System.out.println("could take 40 seconds..."); + zipTest("../lib/bcel/bcel.jar", "testdata/megatrace.jar"); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.java new file mode 100644 index 000000000..e1dac9ba7 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/AndOrNotTestCase.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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; +import java.lang.reflect.*; + +import org.aspectj.weaver.bcel.*; +import org.aspectj.util.FuzzyBoolean; + +import junit.framework.TestCase; +import org.aspectj.weaver.*; + +/** + * @author hugunin + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class AndOrNotTestCase extends TestCase { + /** + * Constructor for PatternTestCase. + * @param name + */ + public AndOrNotTestCase(String name) { + super(name); + } + + World world; + + + public void testMatch() throws IOException { + world = new BcelWorld(); + + Pointcut foo = makePointcut("this(Foo)"); + Pointcut bar = makePointcut("this(Bar)"); + Pointcut c = makePointcut("this(C)"); + + checkEquals("this(Foo) && this(Bar)", new AndPointcut(foo, bar)); + checkEquals("this(Foo) && this(Bar) && this(C)", new AndPointcut(foo, new AndPointcut(bar, c))); + + + checkEquals("this(Foo) || this(Bar)", new OrPointcut(foo, bar)); + checkEquals("this(Foo) || this(Bar) || this(C)", new OrPointcut(foo, new OrPointcut(bar, c))); + + checkEquals("this(Foo) && this(Bar) || this(C)", new OrPointcut(new AndPointcut(foo, bar), c)); + checkEquals("this(Foo) || this(Bar) && this(C)", new OrPointcut(foo, new AndPointcut(bar, c))); + checkEquals("(this(Foo) || this(Bar)) && this(C)", new AndPointcut(new OrPointcut(foo, bar), c)); + checkEquals("this(Foo) || (this(Bar) && this(C))", new OrPointcut(foo, new AndPointcut(bar, c))); + + checkEquals("!this(Foo)", new NotPointcut(foo)); + checkEquals("!this(Foo) && this(Bar)", new AndPointcut(new NotPointcut(foo), bar)); + checkEquals("!(this(Foo) && this(Bar)) || this(C)", new OrPointcut(new NotPointcut(new AndPointcut(foo, bar)), c)); + checkEquals("!!this(Foo)", new NotPointcut(new NotPointcut(foo))); + + } + + private Pointcut makePointcut(String pattern) { + return new PatternParser(pattern).parsePointcut(); + } + + private void checkEquals(String pattern, Pointcut p) throws IOException { + assertEquals(pattern, p, makePointcut(pattern)); + checkSerialization(pattern); + } + + +// private void checkMatch(Pointcut p, Signature[] matches, boolean shouldMatch) { +// for (int i=0; i<matches.length; i++) { +// boolean result = p.matches(matches[i]); +// String msg = "matches " + p + " to " + matches[i] + " expected "; +// if (shouldMatch) { +// assertTrue(msg + shouldMatch, result); +// } else { +// assertTrue(msg + shouldMatch, !result); +// } +// } +// } +// +// public void testSerialization() throws IOException { +// String[] patterns = new String[] { +// "public * *(..)", "void *.foo(A, B)", "A b()" +// }; +// +// for (int i=0, len=patterns.length; i < len; i++) { +// checkSerialization(patterns[i]); +// } +// } + + /** + * Method checkSerialization. + * @param string + */ + private void checkSerialization(String string) throws IOException { + Pointcut p = makePointcut(string); + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + Pointcut newP = Pointcut.read(in, null); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/BindingTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/BindingTestCase.java new file mode 100644 index 000000000..d1d2b3923 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/BindingTestCase.java @@ -0,0 +1,142 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.util.*; + +import org.aspectj.weaver.bcel.*; +import org.aspectj.weaver.bcel.BcelShadow; + +import junit.framework.TestCase; + +import org.aspectj.bridge.AbortException; +import org.aspectj.weaver.*; + +/** + * @author hugunin + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class BindingTestCase extends TestCase { + + /** + * Constructor for ParserTestCase. + * @param arg0 + */ + public BindingTestCase(String arg0) { + super(arg0); + } + + World world = new BcelWorld(); + + + public void testResolveBindings() { + BindingTypePattern at = new BindingTypePattern(world.resolve("java.lang.Object"), 0); + BindingTypePattern bt = new BindingTypePattern(world.resolve("java.lang.Object"), 1); + + BindingTypePattern[] all = new BindingTypePattern[] {at, bt}; + BindingTypePattern[] none = new BindingTypePattern[] {null, null}; + BindingTypePattern[] a = new BindingTypePattern[] {at, null}; + BindingTypePattern[] b = new BindingTypePattern[] {null, bt}; + + checkBindings("this(b)",b); + checkBindings("this(Foo)", none); + checkBindings("this(*)", none); + checkBindings("this(a)", a); + + checkBindings("args(.., a,..,b)", all); + checkBindings("args(a,..,b, ..)", all); + + checkBindings("args(a,..,b)", all); + checkBindings("args(b)", b); + + checkBindings("args()", none); + + checkBindings("this(a) && this(b)", all); + + checkBindingFailure("this(a) && this(a)", "multiple"); + //checkBindingFailure("this(a) && this(b)"); + + checkBindingFailure("this(a) || this(b)", "inconsistent"); + checkBindingFailure("this(A) || this(b)", "inconsistent"); + checkBindingFailure("this(a) || this(B)", "inconsistent"); + checkBindings("this(a) || this(a)", a); + + checkBindings("!this(Foo)", none); + checkBindings("!this(Foo) && this(a)", a); + checkBindingFailure("!this(a)", "negation"); + //checkBindingFailure("this(a)"); + + + checkBindings("cflow(this(a))", a); + checkBindings("cflow(this(a)) && this(b)", all); + + checkBindingFailure("cflow(this(a)) || this(b)", "inconsistent"); + checkBindingFailure("cflow(this(a)) && this(a)", "multiple"); + + checkBindingFailure("!cflow(this(a))", "negation"); + + // todo + // this should fail since a isn't visible to if + //checkBindingFailure("cflow(if(a != null)) && this(a)"); + //checkBinding("cflow(if(a != null) && this(a))", a); + + } + + + /** + * Method checkBindingFailure. (assumes an env where "a" and "b" are formals). + * @param string + */ + private void checkBindingFailure(String pattern, String prefix) { + PatternParser parser = new PatternParser(pattern); + Pointcut p = parser.parsePointcut(); + Bindings actualBindings = new Bindings(2); + try { + p.resolveBindings(makeSimpleScope(), actualBindings); + } catch (AbortException re) { + assertEquals(prefix, re.getIMessage().getMessage().substring(0, prefix.length())); + //System.out.println("expected exception: " + re); + return; + } + assertTrue("should have failed", false); + } + + + /** + * Method checkBindings. + * @param string + * @param i + */ + private void checkBindings(String pattern, BindingTypePattern[] expectedBindings) { + PatternParser parser = new PatternParser(pattern); + Pointcut p = parser.parsePointcut(); + Bindings actualBindings = new Bindings(expectedBindings.length); + + TestScope simpleScope = makeSimpleScope(); + p.resolveBindings(simpleScope, actualBindings); + //System.out.println(actualBindings); + + new Bindings(expectedBindings).checkEquals(actualBindings, simpleScope); + } + + + public TestScope makeSimpleScope() { + return new TestScope(new String[] {"int", "java.lang.String"}, new String[] {"a", "b"}, world); + } +} + diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ConcretizationTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ConcretizationTestCase.java new file mode 100644 index 000000000..1f71719ce --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ConcretizationTestCase.java @@ -0,0 +1,161 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; +import java.lang.reflect.Modifier; +import java.util.*; + +import org.aspectj.testing.util.TestUtil; +import org.aspectj.weaver.*; +import org.aspectj.weaver.bcel.*; +import org.aspectj.weaver.bcel.WeaveTestCase; + +public class ConcretizationTestCase extends WeaveTestCase { + { + regenerate = false; + } + public ConcretizationTestCase(String name) { + super(name); + } + + String[] none = new String[0]; + + + public void testCflowResidual() throws IOException { + + BcelAdvice a = (BcelAdvice) makeConcreteTestAdviceEntryPart(); + + TestShadow shadow = new TestShadow(Shadow.MethodCall, + Member.methodFromString("int Aspect.i(int x)"), + TypeX.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( + TypeX.forName("Aspect"), + 0, + "foo", + new TypeX[] { ResolvedTypeX.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(TypeX.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(TypeX.forName("Aspect"), + 0, "foo", new TypeX[] { ResolvedTypeX.INT }, + createResolvedPointcut("args(refA)", + new String[] {"refA"}, new String[] {"int"})); + + List expectedSlots = new ArrayList(); + expectedSlots.add(new ConcreteCflowPointcut.Slot(1, ResolvedTypeX.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(TypeX.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(TypeX.forNames(formalTypes), + formalNames) + )); + return rp; + } +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/DeclareErrorOrWarningTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/DeclareErrorOrWarningTestCase.java new file mode 100644 index 000000000..7c125b48c --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/DeclareErrorOrWarningTestCase.java @@ -0,0 +1,61 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; + +import junit.framework.TestCase; + +public class DeclareErrorOrWarningTestCase extends TestCase { + + public DeclareErrorOrWarningTestCase(String name) { + super(name); + } + + + public void testParse() throws IOException { + DeclareErrorOrWarning d = + parse("declare error: call(void foo()): \"that is bad\";"); + assertTrue(d.isError()); + assertEquals(d.getPointcut(), + new PatternParser("call(void foo())").parsePointcut()); + assertEquals("that is bad", d.getMessage()); + checkSerialization(d); + + d = parse("declare warning: bar() && baz(): \"boo!\";"); + assertTrue(!d.isError()); + assertEquals(d.getPointcut(), + new PatternParser("bar() && baz()").parsePointcut()); + assertEquals("boo!", d.getMessage()); + checkSerialization(d); + + } + + private DeclareErrorOrWarning parse(String string) { + return (DeclareErrorOrWarning)new PatternParser(string).parseDeclare(); + } + + private void checkSerialization(Declare declare) throws IOException { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + declare.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + Declare newDeclare = Declare.read(in, null); + + assertEquals("write/read", declare, newDeclare); + } +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ModifiersPatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ModifiersPatternTestCase.java new file mode 100644 index 000000000..38bc0fdad --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ModifiersPatternTestCase.java @@ -0,0 +1,140 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; +import java.lang.reflect.*; + +import org.aspectj.weaver.bcel.*; +import org.aspectj.util.FuzzyBoolean; + +import junit.framework.TestCase; +import org.aspectj.weaver.*; + +public class ModifiersPatternTestCase extends TestCase { + /** + * Constructor for PatternTestCase. + * @param name + */ + public ModifiersPatternTestCase(String name) { + super(name); + } + + World world; + + public void testMatch() { + world = new BcelWorld(); + + int[] publicMatches = new int[] { + Modifier.PUBLIC, + Modifier.PUBLIC | Modifier.STATIC, + Modifier.PUBLIC | Modifier.STATIC | Modifier.STRICT | Modifier.FINAL, + }; + + int[] publicFailures = new int[] { + Modifier.PRIVATE, + 0, + Modifier.STATIC | Modifier.STRICT | Modifier.FINAL, + }; + + int[] publicStaticMatches = new int[] { + Modifier.PUBLIC | Modifier.STATIC, + Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL | Modifier.STRICT, + }; + + int[] publicStaticFailures = new int[] { + 0, + Modifier.PUBLIC, + Modifier.STATIC, + }; + + int[] trickMatches = new int[] { + Modifier.PRIVATE, + Modifier.PRIVATE | Modifier.ABSTRACT, + Modifier.PRIVATE | Modifier.FINAL, + }; + + int[] trickFailures = new int[] { + Modifier.PUBLIC, + Modifier.PRIVATE | Modifier.STATIC, + Modifier.PRIVATE | Modifier.STRICT, + }; + + + int[] none = new int[0]; + + checkMatch("", publicMatches, none); + checkMatch("", publicFailures, none); + checkMatch("!public", publicFailures, publicMatches); + checkMatch("public", publicMatches, publicFailures); + checkMatch("public static", none, publicFailures); + checkMatch("public static", publicStaticMatches, publicStaticFailures); + + checkMatch("private !static !strictfp", trickMatches, trickFailures); + checkMatch("private !static !strictfp", none, publicMatches); + checkMatch("private !static !strictfp", none, publicStaticMatches); + } + + private ModifiersPattern makeModifiersPattern(String pattern) { + return new PatternParser(pattern).parseModifiersPattern(); + } + + private void checkMatch(String pattern, int[] shouldMatch, int[] shouldFail) { + ModifiersPattern p = makeModifiersPattern(pattern); + checkMatch(p, shouldMatch, true); + checkMatch(p, shouldFail, false); + } + + private void checkMatch(ModifiersPattern p, int[] matches, boolean shouldMatch) { + for (int i=0; i<matches.length; i++) { + boolean result = p.matches(matches[i]); + String msg = "matches " + p + " to " + Modifier.toString(matches[i]) + " expected "; + if (shouldMatch) { + assertTrue(msg + shouldMatch, result); + } else { + assertTrue(msg + shouldMatch, !result); + } + } + } + + public void testSerialization() throws IOException { + String[] patterns = new String[] { + "", "!public", "public", "public static", + "private !static !strictfp", + }; + + for (int i=0, len=patterns.length; i < len; i++) { + checkSerialization(patterns[i]); + } + } + + /** + * Method checkSerialization. + * @param string + */ + private void checkSerialization(String string) throws IOException { + ModifiersPattern p = makeModifiersPattern(string); + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + ModifiersPattern newP = ModifiersPattern.read(in); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java new file mode 100644 index 000000000..22e180250 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternParserTestCase.java @@ -0,0 +1,65 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; + +import org.aspectj.weaver.patterns.*; + +import junit.framework.TestCase; + +/** + * @author hugunin + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class NamePatternParserTestCase extends TestCase { + /** + * Constructor for PatternTestCase. + * @param name + */ + public NamePatternParserTestCase(String name) { + super(name); + } + + public void testMatch() { + checkMatch(NamePatternTestCase.matchAll); + checkMatch(NamePatternTestCase.match1); + checkMatch(NamePatternTestCase.match2); + + + NamePattern p = new PatternParser("abc *").parseNamePattern(); + assertEquals(new NamePattern("abc"), p); + } + + /** + * Method checkMatch. + * @param string + * @param matchAll + * @param b + */ + private void checkMatch(String[] patterns) { + for (int i=0, len=patterns.length; i < len; i++) { + String pattern = patterns[i]; + ITokenSource tokenSource = BasicTokenSource.makeTokenSource(pattern); + NamePattern p1 = new PatternParser(tokenSource).parseNamePattern(); + NamePattern p2 = new NamePattern(pattern); + assertEquals("pattern: " + pattern, p2, p1); + assertEquals("eof", IToken.EOF, tokenSource.next()); + } + } +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternTestCase.java new file mode 100644 index 000000000..3382dd4e7 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/NamePatternTestCase.java @@ -0,0 +1,118 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; + +import org.aspectj.weaver.patterns.*; + +import junit.framework.TestCase; + +/** + * @author hugunin + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class NamePatternTestCase extends TestCase { + static String[] matchAll = new String[] { + "*****", + "*" + }; + + + static String[] match1 = new String[] { + "abcde", "abc*", "abcd*", "abcde*", + "*e", "*cde", "*abcde", + "a*e", "ab*e", "abc*de", + "*a*b*c*d*e*", "a*c*e", "a***bcde", + "*d*", + }; + + static String[] match2 = new String[] { + "abababab", + "aba*", "abab*", "abababab*", + "*b", "*ab", "*ababab", "*abababab", + "a*b", "ab*b", "abab*abab", + "*a*b*a*b*a*b*a*b*", "a*****b", "a**b", "ab*b*b", + }; + + /** + * Constructor for PatternTestCase. + * @param name + */ + public NamePatternTestCase(String name) { + super(name); + } + + public void testMatch() { + checkMatch("abcde", matchAll, true); + checkMatch("abcde", match1, true); + checkMatch("abcde", match2, false); + + checkMatch("abababab", matchAll, true); + checkMatch("abababab", match1, false); + checkMatch("abababab", match2, true); + + } + + /** + * Method checkMatch. + * @param string + * @param matchAll + * @param b + */ + private void checkMatch(String string, String[] patterns, boolean shouldMatch) { + for (int i=0, len=patterns.length; i < len; i++) { + NamePattern p = new NamePattern(patterns[i]); + checkMatch(string, p, shouldMatch); + } + } + + private void checkMatch(String string, NamePattern p, boolean shouldMatch) { + String msg = "matching " + string + " to " + p; + assertEquals(msg, shouldMatch, p.matches(string)); + } + + + public void testSerialization() throws IOException { + checkSerialization(matchAll); + checkSerialization(match1); + checkSerialization(match2); + } + + private void checkSerialization(String[] patterns) throws IOException { + for (int i=0, len=patterns.length; i < len; i++) { + NamePattern p = new NamePattern(patterns[i]); + checkSerialization(p); + } + } + + + private void checkSerialization(NamePattern p) throws IOException { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + NamePattern newP = NamePattern.read(in); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java new file mode 100644 index 000000000..d6f17f3e9 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java @@ -0,0 +1,70 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.util.*; + +import org.aspectj.weaver.bcel.*; +import org.aspectj.weaver.bcel.*; +import org.aspectj.weaver.bcel.BcelShadow; + +import junit.framework.TestCase; +import org.aspectj.weaver.*; + +/** + * @author hugunin + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class ParserTestCase extends TestCase { + + public ParserTestCase(String arg0) { + super(arg0); + } + + World world = new BcelWorld(); + + public void testNamePatterns() { + + +// checkNoMatch("abc *", "abcd"); +// checkNoMatch("* d", "abcd"); + } + + + + public void testParse() { + PatternParser parser = new PatternParser("execution(void Hello.*(..))"); + KindedPointcut p = (KindedPointcut) parser.parsePointcut(); + //System.out.println(p); + assertEquals(p.kind, BcelShadow.MethodExecution); + assertTrue(p.signature.getName().matches("foobar")); + + + try { + new PatternParser("initialization(void foo())").parsePointcut(); + this.fail("should have been a parse error"); + } catch (ParserException pe) { + // good + } + + + + } +} + + diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java b/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.java new file mode 100644 index 000000000..e66fd3e12 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/PatternsTests.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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import junit.framework.*; + +public class PatternsTests extends TestCase { + + public static Test suite() { + TestSuite suite = new TestSuite(PatternsTests.class.getName()); + //$JUnit-BEGIN$ + suite.addTestSuite(AndOrNotTestCase.class); + suite.addTestSuite(BindingTestCase.class); + suite.addTestSuite(DeclareErrorOrWarningTestCase.class); + suite.addTestSuite(ModifiersPatternTestCase.class); + suite.addTestSuite(NamePatternParserTestCase.class); + suite.addTestSuite(NamePatternTestCase.class); + suite.addTestSuite(ParserTestCase.class); + suite.addTestSuite(SignaturePatternTestCase.class); + suite.addTestSuite(ThisOrTargetTestCase.class); + suite.addTestSuite(TypePatternListTestCase.class); + suite.addTestSuite(TypePatternTestCase.class); + suite.addTestSuite(WithinTestCase.class); + //$JUnit-END$ + return suite; + } + + public PatternsTests(String name) { super(name); } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java new file mode 100644 index 000000000..b7c8789dc --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/SignaturePatternTestCase.java @@ -0,0 +1,175 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; + +import junit.framework.*; + +import org.aspectj.weaver.*; +import org.aspectj.weaver.bcel.*; + +public class SignaturePatternTestCase extends TestCase { + /** + * Constructor for PatternTestCase. + * @param name + */ + public SignaturePatternTestCase(String name) { + super(name); + } + + BcelWorld world = new BcelWorld(); + + public void testThrowsMatch() throws IOException { + Member onlyDerivedOnDerived = Member.methodFromString("static void fluffy.Derived.onlyDerived()"); + Member mOnBase = Member.methodFromString("void fluffy.Base.m()"); + Member mOnDerived = Member.methodFromString("void fluffy.Derived.m()"); + + checkMatch(makeMethodPat("* fluffy.Base.*(..) throws java.lang.CloneNotSupportedException"), + new Member[] { mOnBase }, + new Member[] { mOnDerived }); + + checkMatch(makeMethodPat("* fluffy.Derived.*(..) throws java.lang.CloneNotSupportedException"), + new Member[] { }, + new Member[] { mOnBase, mOnDerived }); + + //XXX need pattern checks + Member[] NONE = new Member[] {}; + Member[] M = new Member[] { onlyDerivedOnDerived }; + Member[] NO_EXCEPTIONS = new Member[] { mOnDerived }; + Member[] BOTH = new Member[] {mOnDerived, onlyDerivedOnDerived}; + + checkMatch(makeMethodPat("* *(..)"), M, NONE); + checkMatch(makeMethodPat("* *(..) throws !*"), NO_EXCEPTIONS, M); + checkMatch(makeMethodPat("* *(..) throws *"), M, NO_EXCEPTIONS); + checkMatch(makeMethodPat("* *(..) throws *, !*"), NONE, BOTH); + + checkMatch(makeMethodPat("* *(..) throws (!*)"), NONE, BOTH); + checkMatch(makeMethodPat("* *(..) throws !(!*)"), BOTH, NONE); + + checkMatch(makeMethodPat("* *(..) throws *..IOException"), M, NO_EXCEPTIONS); + checkMatch(makeMethodPat("* *(..) throws *..IOException, *..Clone*"), M, NO_EXCEPTIONS); + checkMatch(makeMethodPat("* *(..) throws *..IOException, !*..Clone*"), NONE, BOTH); + checkMatch(makeMethodPat("* *(..) throws !*..IOException"), NO_EXCEPTIONS, M); + } + + public void testInstanceMethodMatch() throws IOException { + Member objectToString = Member.methodFromString("java.lang.String java.lang.Object.toString()"); + Member integerToString = Member.methodFromString("java.lang.String java.lang.Integer.toString()"); + Member integerIntValue = Member.methodFromString("int java.lang.Integer.intValue()"); + //Member objectToString = Member.methodFromString("java.lang.String java.lang.Object.toString()"); + + checkMatch(makeMethodPat("* java.lang.Object.*(..)"), + new Member[] { objectToString, integerToString }, + new Member[] { integerIntValue }); + + checkMatch(makeMethodPat("* java.lang.Integer.*(..)"), + new Member[] { integerIntValue, integerToString }, + new Member[] { objectToString }); + } + + + public void testStaticMethodMatch() throws IOException { + Member onlyBaseOnBase = Member.methodFromString("static void fluffy.Base.onlyBase()"); + Member onlyBaseOnDerived = Member.methodFromString("static void fluffy.Derived.onlyBase()"); + Member onlyDerivedOnDerived = Member.methodFromString("static void fluffy.Derived.onlyDerived()"); + Member bothOnBase = Member.methodFromString("static void fluffy.Base.both()"); + Member bothOnDerived = Member.methodFromString("static void fluffy.Derived.both()"); + + checkMatch(makeMethodPat("* fluffy.Base.*(..)"), + new Member[] { onlyBaseOnBase, onlyBaseOnDerived, bothOnBase }, + new Member[] { onlyDerivedOnDerived, bothOnDerived }); + + checkMatch(makeMethodPat("* fluffy.Derived.*(..)"), + new Member[] { onlyBaseOnDerived, bothOnDerived, onlyDerivedOnDerived }, + new Member[] { onlyBaseOnBase, bothOnBase }); + } + + public void testFieldMatch() throws IOException { + Member onlyBaseOnBase = Member.fieldFromString("int fluffy.Base.onlyBase"); + Member onlyBaseOnDerived = Member.fieldFromString("int fluffy.Derived.onlyBase"); + Member onlyDerivedOnDerived = Member.fieldFromString("int fluffy.Derived.onlyDerived"); + Member bothOnBase = Member.fieldFromString("int fluffy.Base.both"); + Member bothOnDerived = Member.fieldFromString("int fluffy.Derived.both"); + + checkMatch(makeFieldPat("* fluffy.Base.*"), + new Member[] { onlyBaseOnBase, onlyBaseOnDerived, bothOnBase }, + new Member[] { onlyDerivedOnDerived, bothOnDerived }); + + checkMatch(makeFieldPat("* fluffy.Derived.*"), + new Member[] { onlyBaseOnDerived, bothOnDerived, onlyDerivedOnDerived }, + new Member[] { onlyBaseOnBase, bothOnBase }); + } + + public void testConstructorMatch() throws IOException { + Member onBase = Member.methodFromString("void fluffy.Base.<init>()"); + Member onDerived = Member.methodFromString("void fluffy.Derived.<init>()"); + Member onBaseWithInt = Member.methodFromString("void fluffy.Base.<init>(int)"); + + + checkMatch(makeMethodPat("fluffy.Base.new(..)"), + new Member[] { onBase, onBaseWithInt }, + new Member[] { onDerived }); + + checkMatch(makeMethodPat("fluffy.Derived.new(..)"), + new Member[] { onDerived}, + new Member[] { onBase, onBaseWithInt }); + } + + + + + + public void checkMatch(SignaturePattern p, Member[] yes, Member[] no) throws IOException { + p = p.resolveBindings(new TestScope(world, new FormalBinding[0]), new Bindings(0)); + + for (int i=0; i < yes.length; i++) { + checkMatch(p, yes[i], true); + } + + for (int i=0; i < no.length; i++) { + checkMatch(p, no[i], false); + } + + checkSerialization(p); + } + + private void checkMatch(SignaturePattern p, Member member, boolean b) { + boolean matches = p.matches(member, world); + assertEquals(p.toString() + " matches " + member.toString(), b, matches); + } + + + private SignaturePattern makeMethodPat(String pattern) { + return new PatternParser(pattern).parseMethodOrConstructorSignaturePattern(); + } + + private SignaturePattern makeFieldPat(String pattern) { + return new PatternParser(pattern).parseFieldSignaturePattern(); + } + + private void checkSerialization(SignaturePattern p) throws IOException { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + SignaturePattern newP = SignaturePattern.read(in, null); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/TestScope.java b/weaver/testsrc/org/aspectj/weaver/patterns/TestScope.java new file mode 100644 index 000000000..d18f8f63c --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/TestScope.java @@ -0,0 +1,30 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import org.aspectj.weaver.*; + +public class TestScope extends SimpleScope { + + public TestScope( + World world, + FormalBinding[] bindings) + { + super(world, bindings); + } + + public TestScope(String[] formalTypes, String[] formalNames, World world) { + super(world, SimpleScope.makeFormalBindings(TypeX.forNames(formalTypes), formalNames)); + } +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java new file mode 100644 index 000000000..9fd2a9e07 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ThisOrTargetTestCase.java @@ -0,0 +1,102 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; +import java.lang.reflect.*; + +import org.aspectj.weaver.bcel.*; +import org.aspectj.util.FuzzyBoolean; + +import junit.framework.TestCase; +import org.aspectj.weaver.*; + +/** + * @author hugunin + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class ThisOrTargetTestCase extends TestCase { + /** + * Constructor for PatternTestCase. + * @param name + */ + public ThisOrTargetTestCase(String name) { + super(name); + } + + World world; + + + public void testMatch() throws IOException { + world = new BcelWorld(); + + + + } + + private Pointcut makePointcut(String pattern) { + return new PatternParser(pattern).parsePointcut(); + } + + private void checkEquals(String pattern, Pointcut p) throws IOException { + assertEquals(pattern, p, makePointcut(pattern)); + checkSerialization(pattern); + } + + +// private void checkMatch(Pointcut p, Signature[] matches, boolean shouldMatch) { +// for (int i=0; i<matches.length; i++) { +// boolean result = p.matches(matches[i]); +// String msg = "matches " + p + " to " + matches[i] + " expected "; +// if (shouldMatch) { +// assertTrue(msg + shouldMatch, result); +// } else { +// assertTrue(msg + shouldMatch, !result); +// } +// } +// } +// +// public void testSerialization() throws IOException { +// String[] patterns = new String[] { +// "public * *(..)", "void *.foo(A, B)", "A b()" +// }; +// +// for (int i=0, len=patterns.length; i < len; i++) { +// checkSerialization(patterns[i]); +// } +// } + + /** + * Method checkSerialization. + * @param string + */ + private void checkSerialization(String string) throws IOException { + Pointcut p = makePointcut(string); + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + Pointcut newP = Pointcut.read(in, null); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java new file mode 100644 index 000000000..e756d11f4 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternListTestCase.java @@ -0,0 +1,190 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; +import java.util.Arrays; + +import org.aspectj.weaver.bcel.*; +import org.aspectj.util.*; + +import junit.framework.TestCase; +import org.aspectj.weaver.*; + +/** + * @author hugunin + * + * To change this generated comment edit the template variable "typecomment": + * Window>Preferences>Java>Templates. + * To enable and disable the creation of type comments go to + * Window>Preferences>Java>Code Generation. + */ +public class TypePatternListTestCase extends TestCase { + /** + * Constructor for PatternTestCase. + * @param name + */ + public TypePatternListTestCase(String name) { + super(name); + } + + World world; + + //XXX when instanceof matching works add tests for that here + + + public void testMatch() { + world = new BcelWorld(); + + checkStaticMatch("()", new String[] {}, FuzzyBoolean.YES); + checkStaticMatch("()", new String[] {"java.lang.Object"}, FuzzyBoolean.NO); + + checkStaticMatch("(java.lang.Object)", new String[] {"java.lang.Object"}, FuzzyBoolean.YES); + + checkStaticMatch("(java.lang.String)", new String[] {"java.lang.Object"}, FuzzyBoolean.NO); + + checkStaticMatch("(java.lang.Object)", new String[] {"java.lang.String"}, FuzzyBoolean.NO); + + checkStaticMatch("()", new String[] {"java.lang.Object"}, FuzzyBoolean.NO); + + checkStaticMatch("(..)", new String[] {}, FuzzyBoolean.YES); + checkStaticMatch("(..)", new String[] {"int", "char"}, FuzzyBoolean.YES); + + + checkStaticMatch("(int,..,int)", new String[] {"int", "int"}, FuzzyBoolean.YES); + + checkStaticMatch("(int,..)", new String[] {}, FuzzyBoolean.NO); + checkStaticMatch("(int,..)", new String[] {"int"}, FuzzyBoolean.YES); + + checkStaticMatch("(..,int,..)", new String[] {"int"}, FuzzyBoolean.YES); + + // these checks are taken from new/ExpandedDotPattern.java + stupidCheck("( .., .., ..)", new boolean[] { true, true, true, true, true }); + stupidCheck("( .., .., int)", new boolean[] { false, true, true, true, true }); + stupidCheck("( .., int, ..)", new boolean[] { false, true, true, true, true }); + stupidCheck("( .., int, int)", new boolean[] { false, false, true, true, true }); + stupidCheck("(int, .., ..)", new boolean[] { false, true, true, true, true }); + stupidCheck("(int, .., int)", new boolean[] { false, false, true, true, true }); + stupidCheck("(int, int, ..)", new boolean[] { false, false, true, true, true }); + stupidCheck("(int, int, int)", new boolean[] { false, false, false, true, false }); + + stupidCheck("( .., .., .., ..)", new boolean[] { true, true, true, true, true }); + stupidCheck("( .., .., .., int)", new boolean[] { false, true, true, true, true }); + stupidCheck("( .., .., int, ..)", new boolean[] { false, true, true, true, true }); + stupidCheck("( .., .., int, int)", new boolean[] { false, false, true, true, true }); + stupidCheck("( .., int, .., ..)", new boolean[] { false, true, true, true, true }); + stupidCheck("( .., int, .., int)", new boolean[] { false, false, true, true, true }); + stupidCheck("( .., int, int, ..)", new boolean[] { false, false, true, true, true }); + stupidCheck("( .., int, int, int)", new boolean[] { false, false, false, true, true }); + + stupidCheck("(int, .., .., ..)", new boolean[] { false, true, true, true, true }); + stupidCheck("(int, .., .., int)", new boolean[] { false, false, true, true, true }); + stupidCheck("(int, .., int, ..)", new boolean[] { false, false, true, true, true }); + stupidCheck("(int, .., int, int)", new boolean[] { false, false, false, true, true }); + stupidCheck("(int, int, .., ..)", new boolean[] { false, false, true, true, true }); + stupidCheck("(int, int, .., int)", new boolean[] { false, false, false, true, true }); + stupidCheck("(int, int, int, ..)", new boolean[] { false, false, false, true, true }); + stupidCheck("(int, int, int, int)", new boolean[] { false, false, false, false, true }); + } + + private TypePatternList makeArgumentsPattern(String pattern) { + return new PatternParser(pattern).parseArgumentsPattern(); + } + + private void checkStaticMatch(String pattern, String[] names, + FuzzyBoolean shouldMatchStatically) { + // We're only doing TypePattern.STATIC matching here because my intent was + // to test the wildcarding, and we don't do DYNAMIC matching on wildcarded things. + + TypePatternList p = makeArgumentsPattern(pattern); + ResolvedTypeX[] types = new ResolvedTypeX[names.length]; + for (int i = 0; i < names.length; i++) { + types[i] = world.resolve(names[i]); + } + + p.resolveBindings(makeTestScope(), Bindings.NONE, false); + //System.out.println("type: " + type); + FuzzyBoolean result = p.matches(types, TypePattern.STATIC); + String msg = "matches statically " + pattern + " to " + Arrays.asList(types); + assertEquals(msg, shouldMatchStatically, result); + } + + private TestScope makeTestScope() { + TestScope scope = new TestScope(CollectionUtil.NO_STRINGS, CollectionUtil.NO_STRINGS, world); + return scope; + } + + public void stupidCheck(String pattern, boolean[] matches) { + TypePatternList p = makeArgumentsPattern(pattern); + p.resolveBindings(makeTestScope(), Bindings.NONE, false); + + int len = matches.length; + + for (int j = 0; j < len; j++) { + + ResolvedTypeX[] types = new ResolvedTypeX[j]; + for (int i = 0; i < j; i++) { + types[i] = world.resolve("int"); + } + + FuzzyBoolean result = p.matches(types, TypePattern.STATIC); + String msg = "matches statically " + pattern + " to " + Arrays.asList(types); + assertEquals(msg, FuzzyBoolean.fromBoolean(matches[j]), result); + } + } + + public void testSerialization() throws IOException { + String[] patterns = new String[] { + "( .., .., .., int)", + "( .., .., int, ..)", + "( .., .., int, int)", + "( .., int, .., ..)", + "( .., int, .., int)", + "( .., int, int, ..)", + "( .., int, int, int)", + + "(int, .., .., ..)", + "(int, .., .., int)", + "(int, .., int, ..)", + "(int, .., int, int)", + "(int, int, .., ..)", + "(int, int, .., int)", + "(int, int, int, ..)", + "(int, int, int, int)" + }; + + for (int i=0, len=patterns.length; i < len; i++) { + checkSerialization(patterns[i]); + } + } + + /** + * Method checkSerialization. + * @param string + */ + private void checkSerialization(String string) throws IOException { + TypePatternList p = makeArgumentsPattern(string); + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + TypePatternList newP = TypePatternList.read(in, null); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternTestCase.java new file mode 100644 index 000000000..5b3c702e8 --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/TypePatternTestCase.java @@ -0,0 +1,290 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; +import java.util.*; + +import org.aspectj.weaver.bcel.*; +import org.aspectj.bridge.AbortException; +import org.aspectj.util.FuzzyBoolean; + +import junit.framework.TestCase; +import org.aspectj.weaver.*; + +public class TypePatternTestCase extends TestCase { + /** + * Constructor for PatternTestCase. + * @param name + */ + public TypePatternTestCase(String name) { + super(name); + } + + World world; + + public void testStaticMatch() { + world = new BcelWorld(); + + checkMatch("java.lang.Object", "java.lang.Object", true); + checkMatch("java.lang.Object+", "java.lang.Object", true); + checkMatch("java.lang.Object+", "java.lang.String", true); + checkMatch("java.lang.String+", "java.lang.Object", false); + checkMatch("java.lang.Integer", "java.lang.String", false); + + checkMatch("java.lang.Integer", "int", false); + + checkMatch("java.lang.Number+", "java.lang.Integer", true); + + + checkMatch("java..*", "java.lang.Integer", true); + checkMatch("java..*", "java.lang.reflect.Modifier", true); + checkMatch("java..*", "int", false); + checkMatch("java..*", "javax.swing.Action", false); + checkMatch("java..*+", "javax.swing.Action", true); + + checkMatch("*.*.Object", "java.lang.Object", true); + checkMatch("*.Object", "java.lang.Object", false); + checkMatch("*..*", "java.lang.Object", true); + checkMatch("*..*", "int", false); + checkMatch("java..Modifier", "java.lang.reflect.Modifier", true); + checkMatch("java.lang.reflect.Mod..ifier", "java.lang.reflect.Modifier", false); + + checkMatch("java..reflect..Modifier", "java.lang.reflect.Modifier", true); + checkMatch("java..lang..Modifier", "java.lang.reflect.Modifier", true); + checkMatch("java..*..Modifier", "java.lang.reflect.Modifier", true); + checkMatch("java..*..*..Modifier", "java.lang.reflect.Modifier", true); + checkMatch("java..*..*..*..Modifier", "java.lang.reflect.Modifier", false); + //checkMatch("java..reflect..Modifier", "java.lang.reflect.Modxifier", false); + checkMatch("ja*va..Modifier", "java.lang.reflect.Modifier", true); + checkMatch("java..*..Mod*ifier", "java.lang.reflect.Modifier", true); + + } + + + // three levels: + // 0. defined in current compilation unit, or imported by name + // 1. defined in current package/type/whatever + // 2. defined in package imported by * + /** + * We've decided not to test this here, but rather in any compilers + */ + public void testImportResolve() { + world = new BcelWorld(); +// checkIllegalImportResolution("List", new String[] { "java.util", "java.awt", }, +// ZERO_STRINGS); + + + } + + + // Assumption for bcweaver: Already resolved type patterns with no *s or ..'s into exact type + // patterns. Exact type patterns don't have import lists. non-exact-type pattens don't + // care about precedence, so the current package can be included with all the other packages, + // and we don't care about compilation units, and we don't care about ordering. + + // only giving this wild-type patterns + public void testImportMatch() { + world = new BcelWorld(); + + checkImportMatch("*List", new String[] { "java.awt.", }, ZERO_STRINGS, "java.awt.List", true); + checkImportMatch("*List", new String[] { "java.awt.", }, ZERO_STRINGS, "java.awt.List", true); + checkImportMatch("*List", new String[] { "java.awt.", }, ZERO_STRINGS, "java.util.List", false); + checkImportMatch("*List", new String[] { "java.util.", }, ZERO_STRINGS, "java.awt.List", false); + checkImportMatch("*List", new String[] { "java.util.", }, ZERO_STRINGS, "java.util.List", true); + + checkImportMatch("*List", ZERO_STRINGS, new String[] { "java.awt.List", }, "java.awt.List", true); + + checkImportMatch("awt.*List", ZERO_STRINGS, new String[] { "java.awt.List", }, "java.awt.List", false); + checkImportMatch("*Foo", ZERO_STRINGS, new String[] { "java.awt.List", }, "java.awt.List", false); + + checkImportMatch("*List", new String[] { "java.util.", "java.awt.", }, + ZERO_STRINGS, "java.util.List", true); + checkImportMatch("*List", new String[] { "java.util.", "java.awt.", }, + ZERO_STRINGS, "java.awt.List", true); + + checkImportMatch("*..List", new String[] { "java.util." }, ZERO_STRINGS, "java.util.List", true); + checkImportMatch("*..List", new String[] { "java.util." }, ZERO_STRINGS, "java.awt.List", true); + + } + + public void testImportMatchWithInners() { + world = new BcelWorld(); + checkImportMatch("*Entry", new String[] { "java.util.", "java.util.Map$"}, ZERO_STRINGS, + "java.util.Map$Entry", true); + + checkImportMatch("java.util.Map.*Entry", ZERO_STRINGS, ZERO_STRINGS, + "java.util.Map$Entry", true); + + checkImportMatch("*Entry", new String[] { "java.util.", }, ZERO_STRINGS, + "java.util.Map$Entry", false); + + checkImportMatch("*.Entry", new String[] { "java.util.", }, ZERO_STRINGS, + "java.util.Map$Entry", true); + + checkImportMatch("Map.*", new String[] { "java.util.", }, ZERO_STRINGS, + "java.util.Map$Entry", true); + + checkImportMatch("Map.*", ZERO_STRINGS, new String[] { "java.util.Map" }, + "java.util.Map$Entry", true); + } + + private void checkImportMatch( + String wildPattern, + String[] importedPackages, + String[] importedNames, + String matchName, + boolean shouldMatch) + { + WildTypePattern p = makeResolvedWildTypePattern(wildPattern, importedPackages, importedNames); + checkPatternMatch(p, matchName, shouldMatch); + } + + + private WildTypePattern makeResolvedWildTypePattern( + String wildPattern, + String[] importedPackages, + String[] importedNames) + { + WildTypePattern unresolved = (WildTypePattern) new PatternParser(wildPattern).parseTypePattern(); + + WildTypePattern resolved = resolve(unresolved, importedPackages, importedNames); + return resolved; + + } + + private WildTypePattern resolve( + WildTypePattern unresolved, + String[] importedPrefixes, + String[] importedNames) + { + + TestScope scope = makeTestScope(); + scope.setImportedPrefixes(importedPrefixes); + scope.setImportedNames(importedNames); + return (WildTypePattern) unresolved.resolveBindings(scope, Bindings.NONE, false); + } + + + + public static final String[] ZERO_STRINGS = new String[0]; + + public void testInstanceofMatch() { + world = new BcelWorld(); + + checkInstanceofMatch("java.lang.Object", "java.lang.Object", FuzzyBoolean.YES); + + checkIllegalInstanceofMatch("java.lang.Object+", "java.lang.Object"); + checkIllegalInstanceofMatch("java.lang.Object+", "java.lang.String"); + checkIllegalInstanceofMatch("java.lang.String+", "java.lang.Object"); + checkIllegalInstanceofMatch("java.lang.*", "java.lang.Object"); + checkInstanceofMatch("java.lang.Integer", "java.lang.String", FuzzyBoolean.NO); + + checkInstanceofMatch("java.lang.Number", "java.lang.Integer", FuzzyBoolean.YES); + checkInstanceofMatch("java.lang.Integer", "java.lang.Number", FuzzyBoolean.MAYBE); + + + checkIllegalInstanceofMatch("java..Integer", "java.lang.Integer"); + + + checkInstanceofMatch("*", "java.lang.Integer", FuzzyBoolean.YES); + + + } + + private void checkIllegalInstanceofMatch(String pattern, String name) { + try { + TypePattern p = makeTypePattern(pattern); + ResolvedTypeX type = world.resolve(name); + FuzzyBoolean result = p.matchesInstanceof(type); + } catch (AbortException e) { + return; + } + assertTrue("matching " + pattern + " with " + name + " should fail", false); + } + + private void checkInstanceofMatch(String pattern, String name, FuzzyBoolean shouldMatch) { + TypePattern p = makeTypePattern(pattern); + ResolvedTypeX type = world.resolve(name); + + p = p.resolveBindings(makeTestScope(), null, false); + + + //System.out.println("type: " + p); + FuzzyBoolean result = p.matchesInstanceof(type); + String msg = "matches " + pattern + " to " + type; + assertEquals(msg, shouldMatch, result); + } + + private TestScope makeTestScope() { + TestScope scope = new TestScope(ZERO_STRINGS, ZERO_STRINGS, world); + return scope; + } + + private TypePattern makeTypePattern(String pattern) { + return new PatternParser(pattern).parseSingleTypePattern(); + } + + private void checkMatch(String pattern, String name, boolean shouldMatch) { + TypePattern p = makeTypePattern(pattern); + p = p.resolveBindings(makeTestScope(), null, false); + checkPatternMatch(p, name, shouldMatch); + } + + private void checkPatternMatch( + TypePattern p, + String name, + boolean shouldMatch) + { + ResolvedTypeX type = world.resolve(name); + //System.out.println("type: " + type); + boolean result = p.matchesStatically(type); + String msg = "matches " + p + " to " + type + " expected "; + if (shouldMatch) { + assertTrue(msg + shouldMatch, result); + } else { + assertTrue(msg + shouldMatch, !result); + } + } + + public void testSerialization() throws IOException { + String[] patterns = new String[] { + "java.lang.Object", "java.lang.Object+", "java.lang.Integer", + "int", "java..*", "java..util..*", "*.*.Object", "*", + }; + + for (int i=0, len=patterns.length; i < len; i++) { + checkSerialization(patterns[i]); + } + } + + /** + * Method checkSerialization. + * @param string + */ + private void checkSerialization(String string) throws IOException { + TypePattern p = makeTypePattern(string); + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + TypePattern newP = TypePattern.read(in, null); + + assertEquals("write/read", p, newP); + } + +} diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java new file mode 100644 index 000000000..4d8fef75b --- /dev/null +++ b/weaver/testsrc/org/aspectj/weaver/patterns/WithinTestCase.java @@ -0,0 +1,102 @@ +/* ******************************************************************* + * 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 Common Public License v1.0 + * which accompanies this distribution and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Xerox/PARC initial implementation + * ******************************************************************/ + + +package org.aspectj.weaver.patterns; + +import java.io.*; + +import junit.framework.TestCase; + +import org.aspectj.weaver.*; +import org.aspectj.weaver.bcel.*; +import org.aspectj.weaver.bcel.BcelWorld; +import org.aspectj.util.FuzzyBoolean; + +public class WithinTestCase extends TestCase { + + World world = new BcelWorld(); + + public WithinTestCase(String name) { + super(name); + } + + public void testMatch() throws IOException { + Shadow getOutFromArrayList = new TestShadow( + Shadow.FieldGet, + Member.fieldFromString("java.io.PrintStream java.lang.System.out"), + TypeX.forName("java.util.ArrayList"), + world); + + checkMatch(makePointcut("within(*)"), getOutFromArrayList, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.util.*)"), getOutFromArrayList, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.lang.*)"), getOutFromArrayList, FuzzyBoolean.NO); + checkMatch(makePointcut("within(java.util.List+)"), getOutFromArrayList, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.uti*.List+)"), getOutFromArrayList, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.uti*..*)"), getOutFromArrayList, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.util.*List)"), getOutFromArrayList, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.util.List*)"), getOutFromArrayList, FuzzyBoolean.NO); + + + Shadow getOutFromEntry = new TestShadow( + Shadow.FieldGet, + Member.fieldFromString("java.io.PrintStream java.lang.System.out"), + TypeX.forName("java.util.Map$Entry"), + world); + + checkMatch(makePointcut("within(*)"), getOutFromEntry, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.util.*)"), getOutFromEntry, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.util.Map.*)"), getOutFromEntry, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.util..*)"), getOutFromEntry, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.util.Map..*)"), getOutFromEntry, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.lang.*)"), getOutFromEntry, FuzzyBoolean.NO); + checkMatch(makePointcut("within(java.util.List+)"), getOutFromEntry, FuzzyBoolean.NO); + checkMatch(makePointcut("within(java.util.Map+)"), getOutFromEntry, FuzzyBoolean.YES); + checkMatch(makePointcut("within(java.lang.Object+)"), getOutFromEntry, FuzzyBoolean.YES); + + //this is something we should in type patterns tests + //checkMatch(makePointcut("within(*List)"), getOut, FuzzyBoolean.NO); + + } + + public Pointcut makePointcut(String pattern) { + Pointcut pointcut0 = Pointcut.fromString(pattern); + + Bindings bindingTable = new Bindings(0); + IScope scope = new SimpleScope(world, FormalBinding.NONE); + + pointcut0.resolveBindings(scope, bindingTable); + Pointcut pointcut1 = pointcut0; + return pointcut1.concretize1(null, new IntMap()); + } + + + private void checkMatch(Pointcut p, Shadow s, FuzzyBoolean shouldMatch) throws IOException { + FuzzyBoolean doesMatch = p.match(s); + assertEquals(p + " matches " + s, shouldMatch, doesMatch); + checkSerialization(p); + } + + private void checkSerialization(Pointcut p) throws IOException { + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bo); + p.write(out); + out.close(); + + ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); + DataInputStream in = new DataInputStream(bi); + Pointcut newP = Pointcut.read(in, null); + + assertEquals("write/read", p, newP); + } + +} |