long modelBuildTime = timedBuild(true);
float overhead = (float)modelBuildTime / (float)rawBuildTime;
- assertTrue(overhead < 1.3);
+ assertTrue("overhead is " + overhead + " > 1.3", overhead < 1.3);
// System.err.println("> overhead: " + overhead);
}
__dump(className, weaved);
return weaved;
} catch (Throwable t) {
+ //FIXME AV wondering if we should have the option to fail (throw runtime exception) here
+ // would make sense at least in test f.e. see TestHelper.handleMessage()
t.printStackTrace();
return bytes;
}
* @throws Throwable
*/
static void __dump(String name, byte[] b) throws Throwable {
- if (true) return;//FIXME AV have an option
+ //if (true) return;//FIXME AV have an option
String className = name.replace('.', '/');
final File dir;
if (className.indexOf('/') > 0) {
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Vasseur initial implementation
+ *******************************************************************************/
+package org.aspectj.weaver.loadtime;
+
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.AbortException;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class DefaultMessageHandler implements IMessageHandler {
+
+ boolean isVerbose = false;
+ boolean showWeaveInfo = false;
+ boolean showWarn = true;
+
+ public boolean handleMessage(IMessage message) throws AbortException {
+ if (message.getKind().isSameOrLessThan(IMessage.INFO)) {
+ return SYSTEM_OUT.handleMessage(message);
+ } else {
+ return SYSTEM_ERR.handleMessage(message);
+ }
+ }
+
+ public boolean isIgnoring(IMessage.Kind kind) {
+ if (kind.equals(IMessage.WEAVEINFO)) {
+ return !showWeaveInfo;
+ }
+ if (kind.isSameOrLessThan(IMessage.INFO)) {
+ return !isVerbose;
+ }
+ return !showWarn;
+ }
+
+ public void dontIgnore(IMessage.Kind kind) {
+ if (kind.equals(IMessage.WEAVEINFO)) {
+ showWeaveInfo = true;
+ } else if (kind.equals(IMessage.DEBUG)) {
+ isVerbose = true;
+ } else if (kind.equals(IMessage.WARNING)) {
+ showWarn = false;
+ }
+ }
+
+}
*/
public class Options {
- private static class DefaultMessageHandler implements IMessageHandler {
-
- boolean isVerbose = false;
- boolean showWeaveInfo = false;
- boolean showWarn = true;
-
- public boolean handleMessage(IMessage message) throws AbortException {
- return SYSTEM_OUT.handleMessage(message);
- }
-
- public boolean isIgnoring(IMessage.Kind kind) {
- if (kind.equals(IMessage.WEAVEINFO)) {
- return !showWeaveInfo;
- }
- if (kind.isSameOrLessThan(IMessage.INFO)) {
- return !isVerbose;
- }
- return !showWarn;
- }
-
- public void dontIgnore(IMessage.Kind kind) {
- if (kind.equals(IMessage.WEAVEINFO)) {
- showWeaveInfo = true;
- } else if (kind.equals(IMessage.DEBUG)) {
- isVerbose = true;
- } else if (kind.equals(IMessage.WARNING)) {
- showWarn = false;
- }
- }
- }
-
private final static String OPTION_15 = "-1.5";
private final static String OPTION_lazyTjp = "-XlazyTjp";
private final static String OPTION_noWarn = "-nowarn";
weaverOption.showWeaveInfo = true;
} else if (arg.equalsIgnoreCase(OPTION_verbose)) {
weaverOption.verbose = true;
+ } else if (arg.startsWith(OPTIONVALUED_messageHolder)) {
+ ;// handled in first round
} else {
weaverOption.messageHandler.handleMessage(
new Message(
public void finishTypeMungers() {
// make sure that type mungers are
Collection ret = new ArrayList();
- Collection baseTypeMungers =
- getWorld().getCrosscuttingMembersSet().getTypeMungers();
+ Collection baseTypeMungers = getWorld().getCrosscuttingMembersSet().getTypeMungers();
+ baseTypeMungers.addAll(getWorld().getCrosscuttingMembersSet().getLateTypeMungers());
+
for (Iterator i = baseTypeMungers.iterator(); i.hasNext(); ) {
ConcreteTypeMunger munger = (ConcreteTypeMunger) i.next();
EclipseTypeMunger etm = makeEclipseTypeMunger(munger);
cmd.addFlag("-Xreweavable",reweavable);
}
+ public void setXNoInline(boolean noInline) {
+ cmd.addFlag("-XnoInline",noInline);
+ }
+
public void setShowWeaveInfo(boolean showweaveinfo) {
cmd.addFlag("-showWeaveInfo",showweaveinfo);
}
private static boolean is15VMOrGreater = false;
static {
- String vm = System.getProperty("java.vm.version");
+ String vm = System.getProperty("java.runtime.version");
+ if (vm == null) {
+ vm = System.getProperty("java.vm.version");
+ }
if (vm.startsWith("1.3")) {
is14VMOrGreater = false;
} else if (vm.startsWith("1.5")) {
p.setUserProperty("aj.sandbox", inTestCase.getSandboxDirectory().getAbsolutePath());
// setup aj.dir "modules" folder
p.setUserProperty("aj.root", new File("..").getAbsolutePath());
+
+ // create the test implicit path aj.path that contains the sandbox + regular test infra path
+ Path path = new Path(p, inTestCase.getSandboxDirectory().getAbsolutePath());
+ populatePath(path, DEFAULT_LTW_CLASSPATH_ENTRIES);
+ populatePath(path, AjcTestCase.DEFAULT_CLASSPATH_ENTRIES);
+ p.addReference("aj.path", path);
ProjectHelper helper = ProjectHelper.getProjectHelper();
helper.parse(p, buildFile);
// make sure we listen for failure
DefaultLogger consoleLogger = new DefaultLogger() {
+ public void buildFinished(BuildEvent event) {
+ super.buildFinished(event);
+ if (event.getException() != null) {
+ AjcTestCase.fail(failMessage + "failure " + event.getException());
+ }
+ }
public void targetFinished(BuildEvent event) {
super.targetFinished(event);
if (event.getException() != null) {
consoleLogger.setOutputPrintStream(System.out);
consoleLogger.setMessageOutputLevel(m_verbose?Project.MSG_VERBOSE:Project.MSG_ERR);
p.addBuildListener(consoleLogger);
-
- // create the test implicit path aj.path that contains the sandbox + regular test infra path
- Path path = new Path(p, inTestCase.getSandboxDirectory().getAbsolutePath());
- populatePath(path, DEFAULT_LTW_CLASSPATH_ENTRIES);
- populatePath(path, AjcTestCase.DEFAULT_CLASSPATH_ENTRIES);
- p.addReference("aj.path", path);
} catch (Throwable t) {
AjcTestCase.fail(failMessage + "invalid Ant script :" + t.toString());
}
if (files == null) files = "";
StringTokenizer strTok = new StringTokenizer(files,",");
while (strTok.hasMoreTokens()) {
- String file = strTok.nextToken();
+ final String file = strTok.nextToken();
if (file.endsWith(".jar")) {
jarList.add(file);
- } else {
+ } else {
fileList.add(file);
}
}
spec.setDescription("some description, with extra");
XMLWriter out = new XMLWriter(new PrintWriter(System.out));
spec.writeXml(out);
- out.close();
+ //out.close();//FIXME this close System.out and makes the IntelliJ test runner hang (AV)
}
public void testSetOptions() {
<!-- ajc-ant script, not to be used from Ant commant line - see AntSpec -->
-<project name="foo" default="all">
+<project name="foo" default="javac.ltw">
+
+ <property
+ name="jdwp"
+ value=""/>
<target name="compile:javac">
<!-- compile only javac compilable stuff -->
</javac>
</target>
- <target name="all" depends="compile:javac">
+ <target name="ltw">
<java fork="yes" classname="ataspectj.AllLTWTests" failonerror="yes">
<classpath refid="aj.path"/>
<jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/>
<jvmarg value="-Daj5.def=ataspectj/aop.xml"/>
</java>
</target>
+
+ <target name="ltw.PerClauseTest">
+ <java fork="yes" classname="ataspectj.PerClauseTest" failonerror="yes">
+ <classpath refid="aj.path"/>
+ <jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/>
+ <jvmarg value="-Daj5.def=ataspectj/aop.xml"/>
+ </java>
+ </target>
+
+ <target name="ltw.AroundInlineMungerTest">
+ <java fork="yes" classname="ataspectj.AroundInlineMungerTest" failonerror="yes">
+ <classpath refid="aj.path"/>
+ <jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/>
+ <jvmarg value="-Daj5.def=ataspectj/aop.xml"/>
+ </java>
+ </target>
+
+ <target name="javac.ltw" depends="compile:javac, ltw"/>
</project>
\ No newline at end of file
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
-import test.loadtime5.AtAspectJTest;
/**
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
// singleton is bound as soon as clinit
try {
- assertTrue(Aspects.hasAspect(TestAspectPerSingleton.class));
- Aspects.aspectOf(TestAspectPerSingleton.class);
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerSingleton.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPerSingleton.class);
} catch (NoAspectBoundException e) {
fail(e.toString());
}
assertEquals("AOP.perSingleton perSingleton ", s_log.toString());
perSingleton();
- assertEquals(1, TestAspectPerSingleton.s_count);
+ assertEquals(1, PerClauseTestAspects.TestAspectPerSingleton.s_count);
}
- @Aspect()
- public static class TestAspectPerSingleton {
- static int s_count = 0;
- public TestAspectPerSingleton() {
- s_count++;
- }
-
- @Before("execution(* ataspectj.PerClauseTest.perSingleton()) && target(t)")
- public void before(JoinPoint jp, Object t) {
- log("AOP."+jp.getSignature().getName());
- assertTrue("perX match", this.equals(Aspects.aspectOf(getClass())));
- }
- }
-
-
public void perTarget() {
log("perTarget");
}
// calling singleton API will fail
try {
- assertFalse(Aspects.hasAspect(TestAspectPerTarget.class));
- Aspects.aspectOf(TestAspectPerTarget.class);
+ assertFalse(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerTarget.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPerTarget.class);
fail("should fail with NOABE");
} catch (NoAspectBoundException e) {
;//ok
// this per
try {
- assertTrue(Aspects.hasAspect(TestAspectPerTarget.class, this));
- TestAspectPerTarget aspect = (TestAspectPerTarget) Aspects.aspectOf(TestAspectPerTarget.class, this);
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerTarget.class, this));
+ PerClauseTestAspects.TestAspectPerTarget aspect = (PerClauseTestAspects.TestAspectPerTarget) Aspects.aspectOf(PerClauseTestAspects.TestAspectPerTarget.class, this);
assertNotNull(aspect);
} catch (NoAspectBoundException e) {
fail(e.toString());
// another per
PerClauseTest me = new PerClauseTest();
try {
- assertFalse(Aspects.hasAspect(TestAspectPerTarget.class, me));
- Aspects.aspectOf(TestAspectPerTarget.class, me);
+ assertFalse(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerTarget.class, me));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPerTarget.class, me);
fail("should fail");
} catch (NoAspectBoundException e) {
;//ok
}
me.perTarget();
try {
- assertTrue(Aspects.hasAspect(TestAspectPerTarget.class, me));
- TestAspectPerTarget aspect = (TestAspectPerTarget) Aspects.aspectOf(TestAspectPerTarget.class, me);
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerTarget.class, me));
+ PerClauseTestAspects.TestAspectPerTarget aspect = (PerClauseTestAspects.TestAspectPerTarget) Aspects.aspectOf(PerClauseTestAspects.TestAspectPerTarget.class, me);
assertNotNull(aspect);
} catch (NoAspectBoundException e) {
fail(e.toString());
}
- assertEquals(2, TestAspectPerTarget.s_count);
- }
-
- @Aspect("pertarget(execution(* ataspectj.PerClauseTest.perTarget()))")
- public static class TestAspectPerTarget {
- static int s_count;
-
- public TestAspectPerTarget() {
- s_count++;
- }
-
- @Before("execution(* ataspectj.PerClauseTest.perTarget()) && target(t)")
- public void before(JoinPoint jp, Object t) {
- log("AOP."+jp.getSignature().getName());
- assertTrue("perX match", this.equals(Aspects.aspectOf(getClass(), t)));
- }
+ assertEquals(2, PerClauseTestAspects.TestAspectPerTarget.s_count);
}
public void perCflowEntry() {
// the aspect is bound to the executing thread
try {
- assertTrue(Aspects.hasAspect(TestAspectPerCflow.class));
- Aspects.aspectOf(TestAspectPerCflow.class);
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerCflow.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPerCflow.class);
} catch (NoAspectBoundException e) {
fail(e.toString());
}
// no aspect bound yet
try {
- assertFalse(Aspects.hasAspect(TestAspectPerCflow.class));
- Aspects.aspectOf(TestAspectPerCflow.class);
+ assertFalse(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerCflow.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPerCflow.class);
fail("No perCflow should be bound yet");
} catch (NoAspectBoundException e) {
;//ok
assertEquals("perCflow ", s_log.toString());
// still no aspect bound yet
try {
- assertFalse(Aspects.hasAspect(TestAspectPerCflow.class));
- Aspects.aspectOf(TestAspectPerCflow.class);
+ assertFalse(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerCflow.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPerCflow.class);
fail("No perCflow should be bound yet");
} catch (NoAspectBoundException e) {
;//ok
assertEquals("AOP.perCflow perCflow ", s_log.toString());
// no aspect bound anymore since went OUT of the per clause
try {
- assertFalse(Aspects.hasAspect(TestAspectPerCflow.class));
- Aspects.aspectOf(TestAspectPerCflow.class);
+ assertFalse(Aspects.hasAspect(PerClauseTestAspects.TestAspectPerCflow.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPerCflow.class);
fail("No perCflow should be bound anymore");
} catch (NoAspectBoundException e) {
;//ok
trko.start();
trko.join();
- assertEquals(2, TestAspectPerCflow.s_count);
- }
-
- @Aspect("percflow(execution(* ataspectj.PerClauseTest.perCflowEntry()))")
- public static class TestAspectPerCflow {
- static int s_count;
-
- public TestAspectPerCflow() {
- s_count++;
- }
-
- @Before("execution(* ataspectj.PerClauseTest.perCflow())")
- public void before(JoinPoint jp) {
- log("AOP."+jp.getSignature().getName());
- assertTrue("perX match", this.equals(Aspects.aspectOf(getClass())));
- }
+ assertEquals(2, PerClauseTestAspects.TestAspectPerCflow.s_count);
}
public void testPerTypeWithin() {
- assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW1.class));
- assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW2.class));
- assertFalse(Aspects.hasAspect(TestAspectPTW.class, PTWNoMatch.class));
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPTW.class, PTW1.class));
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPTW.class, PTW2.class));
+ assertFalse(Aspects.hasAspect(PerClauseTestAspects.TestAspectPTW.class, PTWNoMatch.class));
PTW1.foo();
PTW2.foo();
PTWNoMatch.foo();
- assertEquals(2, TestAspectPTW.s_count);
+ assertEquals(2, PerClauseTestAspects.TestAspectPTW.s_count);
try {
- assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW1.class));
- assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW2.class));
- Aspects.aspectOf(TestAspectPTW.class, PTW1.class);
- Aspects.aspectOf(TestAspectPTW.class, PTW2.class);
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPTW.class, PTW1.class));
+ assertTrue(Aspects.hasAspect(PerClauseTestAspects.TestAspectPTW.class, PTW2.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPTW.class, PTW1.class);
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPTW.class, PTW2.class);
} catch (NoAspectBoundException e) {
fail(e.toString());
}
try {
- assertFalse(Aspects.hasAspect(TestAspectPTW.class, PTWNoMatch.class));
- Aspects.aspectOf(TestAspectPTW.class, PTWNoMatch.class);
+ assertFalse(Aspects.hasAspect(PerClauseTestAspects.TestAspectPTW.class, PTWNoMatch.class));
+ Aspects.aspectOf(PerClauseTestAspects.TestAspectPTW.class, PTWNoMatch.class);
fail("should not have PTW aspect");
} catch (NoAspectBoundException e) {
;//ok
static class PTWNoMatch {
static void foo() {};
}
-
- @Aspect("pertypewithin(ataspectj.PerClauseTest.PTW* && !ataspectj.PerClauseTest.PTWNoMatch)")
- public static class TestAspectPTW {
- static int s_count;
-
- public TestAspectPTW() {
- s_count++;
- }
-
- @Before("execution(* ataspectj.PerClauseTest.PTW*.foo())")
- public void before(JoinPoint jp) {
- ;
- }
-
- }
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Vasseur initial implementation
+ *******************************************************************************/
+package ataspectj;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Aspects;
+import junit.framework.Assert;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class PerClauseTestAspects {
+
+ @Aspect()
+ public static class TestAspectPerSingleton {
+ static int s_count = 0;
+ public TestAspectPerSingleton() {
+ s_count++;
+ }
+
+ @Before("execution(* ataspectj.PerClauseTest.perSingleton()) && target(t)")
+ public void before(JoinPoint jp, Object t) {
+ PerClauseTest.log("AOP."+jp.getSignature().getName());
+ Assert.assertTrue("perX match", this.equals(Aspects.aspectOf(getClass())));
+ }
+ }
+
+ @Aspect("pertarget(execution(* ataspectj.PerClauseTest.perTarget()))")
+ public static class TestAspectPerTarget {
+ static int s_count;
+
+ public TestAspectPerTarget() {
+ s_count++;
+ }
+
+ @Before("execution(* ataspectj.PerClauseTest.perTarget()) && target(t)")
+ public void before(JoinPoint jp, Object t) {
+ PerClauseTest.log("AOP."+jp.getSignature().getName());
+ Assert.assertTrue("perX match", this.equals(Aspects.aspectOf(getClass(), t)));
+ }
+ }
+
+ @Aspect("percflow(execution(* ataspectj.PerClauseTest.perCflowEntry()))")
+ public static class TestAspectPerCflow {
+ static int s_count;
+
+ public TestAspectPerCflow() {
+ s_count++;
+ }
+
+ @Before("execution(* ataspectj.PerClauseTest.perCflow())")
+ public void before(JoinPoint jp) {
+ PerClauseTest.log("AOP."+jp.getSignature().getName());
+ Assert.assertTrue("perX match", this.equals(Aspects.aspectOf(getClass())));
+ }
+ }
+
+ @Aspect("pertypewithin(ataspectj.PerClauseTest.PTW* && !ataspectj.PerClauseTest.PTWNoMatch)")
+ public static class TestAspectPTW {
+ static int s_count;
+
+ public TestAspectPTW() {
+ s_count++;
+ }
+
+ @Before("execution(* ataspectj.PerClauseTest.PTW*.foo())")
+ public void before(JoinPoint jp) {
+ ;
+ }
+
+ }
+
+
+}
import junit.textui.TestRunner;
import junit.framework.TestResult;
+import junit.framework.Assert;
+import junit.framework.TestFailure;
import java.util.Enumeration;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.AbortException;
+import org.aspectj.weaver.loadtime.DefaultMessageHandler;
+
/**
* Helper to run a test as a main class, but still throw exception and not just print on stderr
* upon test failure.
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
-public class TestHelper {
+public class TestHelper extends DefaultMessageHandler {
public static void runAndThrowOnFailure(junit.framework.Test test) {
TestRunner r = new TestRunner();
StringBuffer sb = new StringBuffer("\n");
Enumeration e = rr.failures();
while (e.hasMoreElements()) {
- sb.append("Failure: ");
- sb.append(e.nextElement());
+ sb.append("JUnit Failure: ");
+ sb.append(((TestFailure)e.nextElement()).thrownException().toString());
sb.append("\n");
}
e = rr.errors();
while (e.hasMoreElements()) {
- sb.append("Error: ");
- sb.append(e.nextElement());
+ sb.append("JUnit Error: ");
+ sb.append(((TestFailure)e.nextElement()).thrownException().toString());
sb.append("\n");
}
throw new RuntimeException(sb.toString());
}
}
+ public boolean handleMessage(IMessage message) throws AbortException {
+ boolean ret = super.handleMessage(message);
+ if (message.getKind().isSameOrLessThan(IMessage.INFO)) {
+ ;
+ } else {
+ // we do exit here since Assert.fail will only trigger a runtime exception that might
+ // be catched by the weaver anyway
+ System.exit(-1);
+ }
+ return ret;
+ }
+
}
<?xml version="1.0"?>
<aspectj>
+ <weaver options="-XmessageHolderClass:ataspectj.TestHelper"/>
<aspects>
<!-- see here nested class with ".", "$" is accepted as well -->
<aspect name="ataspectj.SingletonAspectBindingsTest.TestAspect"/>
<aspect name="ataspectj.BindingTest.TestAspect_1"/>
- <aspect name="ataspectj.PerClauseTest.TestAspectPerSingleton"/>
- <aspect name="ataspectj.PerClauseTest.TestAspectPerTarget"/>
- <aspect name="ataspectj.PerClauseTest.TestAspectPerCflow"/>
- <aspect name="ataspectj.PerClauseTest.TestAspectPTW"/>
+ <aspect name="ataspectj.PerClauseTestAspects.TestAspectPerSingleton"/>
+ <aspect name="ataspectj.PerClauseTestAspects.TestAspectPerTarget"/>
+ <aspect name="ataspectj.PerClauseTestAspects.TestAspectPerCflow"/>
+ <aspect name="ataspectj.PerClauseTestAspects.TestAspectPTW"/>
<aspect name="ataspectj.AroundInlineMungerTest.Open"/>
</aspects>
import org.aspectj.systemtest.ajc150.ataspectj.AtAjSyntaxTests;
import org.aspectj.systemtest.ajc150.ataspectj.AtAjMisuseTests;
+import org.aspectj.systemtest.ajc150.ataspectj.AtAjLTWTests;
import junit.framework.Test;
import junit.framework.TestSuite;
suite.addTest(GenericsTests.suite());
suite.addTest(AtAjSyntaxTests.suite());
suite.addTest(AtAjMisuseTests.suite());
+ suite.addTest(AtAjLTWTests.suite());
//$JUnit-END$
return suite;
}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alexandre Vasseur initial implementation
+ *******************************************************************************/
+package org.aspectj.systemtest.ajc150.ataspectj;
+
+import org.aspectj.testing.AutowiredXMLBasedAjcTestCase;
+import junit.framework.Test;
+
+import java.io.File;
+
+/**
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class AtAjLTWTests extends AutowiredXMLBasedAjcTestCase {
+
+ public static Test suite() {
+ return AutowiredXMLBasedAjcTestCase.loadSuite(org.aspectj.systemtest.ajc150.ataspectj.AtAjLTWTests.class);
+ }
+
+ protected File getSpecFile() {
+ return new File("../tests/src/org/aspectj/systemtest/ajc150/ataspectj/ltw.xml");
+ }
+}
--- /dev/null
+<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>
+<suite>
+
+ <ajc-test dir="java5/ataspectj" title="RunThemAllWithJavacCompiledAndLTW">
+ <ant file="ajc-ant.xml" target="javac.ltw"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="AjcLTW PerClauseTest -XnoWeave">
+ <compile
+ files="ataspectj/PerClauseTest.java,ataspectj/PerClauseTestAspects.java,ataspectj/TestHelper.java"
+ options="-1.5 -XnoWeave"/>
+ <ant file="ajc-ant.xml" target="ltw.PerClauseTest" verbose="true"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="AjcLTW PerClauseTest -Xreweavable">
+ <compile
+ files="ataspectj/PerClauseTest.java,ataspectj/PerClauseTestAspects.java,ataspectj/TestHelper.java"
+ options="-1.5 -Xreweavable"/>
+ <ant file="ajc-ant.xml" target="ltw.PerClauseTest" verbose="true"/>
+ </ajc-test>
+
+<!-- FIXME AV: todo by Andy-->
+<!-- <ajc-test dir="java5/ataspectj" title="JavaCAjcLTW PerClauseTest">-->
+<!-- <compile-->
+<!-- files="ataspectj/PerClauseTest.java,ataspectj/TestHelper.java"-->
+<!-- options="-1.5 -XnoWeave"/>-->
+<!-- <comment>-->
+<!-- aspectOf methods will be pushed in, ignore warning for adviceDidNotMatch but still do the logic for them-->
+<!-- since such just added methods are an interesting case (percflow ajc$perCflowStack advice)-->
+<!-- </comment>-->
+<!-- <compile-->
+<!-- files="ataspectj/PerClauseTestAspects.java"-->
+<!-- options="-1.5 -Xdev:NoAtAspectJProcessing">-->
+<!-- <message kind="warning"/>-->
+<!-- </compile>-->
+<!-- <ant file="ajc-ant.xml" target="ltw.PerClauseTest" verbose="true"/>-->
+<!-- </ajc-test>-->
+
+</suite>
\ No newline at end of file
<ajc-test dir="java5/ataspectj"
pr="" title="class with @Before extending @Aspect class">
<compile files="ataspectj/misuse/Test006.java" options="-1.5 -Xdev:NoAtAspectJProcessing">
- <message kind="warning" line="11" text="Found @AspectJ annotations in a non @Aspect type 'ataspectj.misuse.Test006B'"/>
+ <!-- FIXME AV - optim in place. Check and remove useless test -->
+ <!--<message kind="warning" line="11" text="Found @AspectJ annotations in a non @Aspect type 'ataspectj.misuse.Test006B'"/>-->
</compile>
</ajc-test>
</ajc-test>
<ajc-test dir="java5/ataspectj" title="PerClause">
- <compile files="ataspectj/PerClauseTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing"/>
+ <compile files="ataspectj/PerClauseTest.java,ataspectj/PerClauseTestAspects.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing"/>
<run class="ataspectj.PerClauseTest"/>
- <compile files="ataspectj/PerClauseTest.java,ataspectj/TestHelper.java" options="-1.5"/>
+ <compile files="ataspectj/PerClauseTest.java,ataspectj/PerClauseTestAspects.java,ataspectj/TestHelper.java" options="-1.5"/>
<run class="ataspectj.PerClauseTest"/>
</ajc-test>
<run class="ataspectj.AroundInlineMungerTest"/>
</ajc-test>
- <ajc-test dir="java5/ataspectj" title="RunThemAllWithJavacCompiledAndLTW">
- <ant file="ajc-ant.xml" target="all"/>
- </ajc-test>
</suite>
\ No newline at end of file
// ----
/** @param fromType is guaranteed to be a non-abstract aspect
- * @param perClause has been concretized at a higher level
+ * @param clause has been concretized at a higher level
*/
public ShadowMunger concretize(ResolvedTypeX fromType, World world, PerClause clause) {
// assert !fromType.isAbstract();
private List shadowMungers = new ArrayList(4);
private List typeMungers = new ArrayList(4);
-
+ private List lateTypeMungers = new ArrayList(0);
+
private List declareParents = new ArrayList(4);
private List declareSofts = new ArrayList(0);
private List declareDominates = new ArrayList(4);
}
public void addTypeMunger(ConcreteTypeMunger m) {
- if (m == null) return; //???
+ if (m == null) throw new Error("FIXME AV - should not happen or what ?");//return; //???
typeMungers.add(m);
}
-
+
+ public void addLateTypeMungers(Collection c) {
+ lateTypeMungers.addAll(c);
+ }
+
+ public void addLateTypeMunger(ConcreteTypeMunger m) {
+ lateTypeMungers.add(m);
+ }
+
public void addDeclares(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
addDeclare( (Declare)i.next() );
}
}
-
-
public void addDeclare(Declare declare) {
// this is not extensible, oh well
if (declare instanceof DeclareErrorOrWarning) {
changed = true;
typeMungers = other.typeMungers;
}
-
+
+ if (!lateTypeMungers.equals(other.lateTypeMungers)) {
+ changed = true;
+ lateTypeMungers = other.lateTypeMungers;
+ }
+
if (!declareDominates.equals(other.declareDominates)) {
changed = true;
declareDominates = other.declareDominates;
public List getTypeMungers() {
return typeMungers;
}
-
+
+ public List getLateTypeMungers() {
+ return lateTypeMungers;
+ }
+
public List getDeclareAnnotationOnTypes() {
return declareAnnotationsOnType;
}
*/
public class CrosscuttingMembersSet {
private World world;
- //FIXME Alex: we may need a sequencedHashMap there to ensure source based precedence for @AJ advice
+ //FIXME AV - ? we may need a sequencedHashMap there to ensure source based precedence for @AJ advice
private Map members = new HashMap();
private List shadowMungers = null;
private List typeMungers = null;
+ private List lateTypeMungers = null;
private List declareSofts = null;
private List declareParents = null;
private List declareAnnotationOnTypes = null;
private void clearCaches() {
shadowMungers = null;
typeMungers = null;
+ lateTypeMungers = null;
declareSofts = null;
declareParents = null;
declareDominates = null;
}
return typeMungers;
}
-
+
+ public List getLateTypeMungers() {
+ if (lateTypeMungers == null) {
+ ArrayList ret = new ArrayList();
+ for (Iterator i = members.values().iterator(); i.hasNext(); ) {
+ ret.addAll(((CrosscuttingMembers)i.next()).getLateTypeMungers());
+ }
+ lateTypeMungers = ret;
+ }
+ return lateTypeMungers;
+ }
+
public List getDeclareSofts() {
if (declareSofts == null) {
ArrayList ret = new ArrayList();
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.HashMap;
import org.aspectj.weaver.patterns.Pointcut;
import org.aspectj.weaver.patterns.FastMatchInfo;
+import org.aspectj.weaver.patterns.PerClause;
import org.aspectj.util.FuzzyBoolean;
public class PerObjectInterfaceTypeMunger extends ResolvedTypeMunger {
+
+ // key is advisedType, value is Set of aspect type that advise the type and are perObject
+ public static Map s_advisedTypeToAspects = new HashMap();
+ public static void registerAsAdvisedBy(ResolvedTypeX matchType, ResolvedTypeX aspectType) {
+ if (PerClause.PEROBJECT.equals(aspectType.getPerClause().getKind())) {
+ Set aspects = (Set)s_advisedTypeToAspects.get(matchType);
+ if (aspects == null) {
+ aspects = new HashSet(1);
+ s_advisedTypeToAspects.put(matchType, aspects);
+ }
+ aspects.add(aspectType);
+ }
+ }
+ public static void unregisterFromAsAdvisedBy(ResolvedTypeX matchType) {
+ s_advisedTypeToAspects.remove(matchType);
+ }
+
private ResolvedMember getMethod;
private ResolvedMember setMethod;
private TypeX aspectType;
// comment from Andy - this is hard to fix...
// right now I filter @AJ aspect else it end up with duplicate members
- return !matchType.isInterface() && !matchType.isAnnotationStyleAspect();
+ //return !matchType.isInterface() && !matchType.isAnnotationStyleAspect();
+ Set aspects = (Set)s_advisedTypeToAspects.get(matchType);
+ if (aspects == null) {
+ return false;
+ } else {
+ return aspects.contains(aspectType);
+ }
+
}
private FuzzyBoolean isWithinType(ResolvedTypeX type) {
crosscuttingMembers.setPerClause(getPerClause());
crosscuttingMembers.addShadowMungers(collectShadowMungers());
crosscuttingMembers.addTypeMungers(getTypeMungers());
+ //FIXME AV - skip but needed ?? or ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers());
crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
visitor.visitList(crosscuttingMembersSet.getShadowMungers());
visitor.visitString("Type mungers:");
visitor.visitList(crosscuttingMembersSet.getTypeMungers());
+ visitor.visitString("Late Type mungers:");
+ visitor.visitList(crosscuttingMembersSet.getLateTypeMungers());
if (dumpState_cantFindTypeExceptions!=null) {
visitor.visitString("Cant find type problems:");
visitor.visitList(dumpState_cantFindTypeExceptions);
import org.aspectj.weaver.TypeX;
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.World;
+import org.aspectj.weaver.PerObjectInterfaceTypeMunger;
import org.aspectj.weaver.ataspectj.Ajc5MemberMaker;
import org.aspectj.weaver.ast.Literal;
import org.aspectj.weaver.ast.Test;
import org.aspectj.weaver.patterns.ExactTypePattern;
import org.aspectj.weaver.patterns.ExposedState;
import org.aspectj.weaver.patterns.Pointcut;
+import org.aspectj.weaver.patterns.PerClause;
+import org.aspectj.weaver.patterns.PerObject;
+import org.aspectj.weaver.patterns.PerFromSuper;
/**
* Advice implemented for bcel.
public void implementOn(Shadow s) {
hasMatchedAtLeastOnce=true;
- BcelShadow shadow = (BcelShadow) s;
+ BcelShadow shadow = (BcelShadow) s;
+
+ //FIXME AV ok ?
+ // callback for perObject AJC MightHaveAspect postMunge (#75442)
+ if (getConcreteAspect() != null
+ && getConcreteAspect().getPerClause() != null
+ && PerClause.PEROBJECT.equals(getConcreteAspect().getPerClause().getKind())) {
+ final PerObject clause;
+ if (getConcreteAspect().getPerClause() instanceof PerFromSuper) {
+ clause = (PerObject)((PerFromSuper) getConcreteAspect().getPerClause()).lookupConcretePerClause(getConcreteAspect());
+ } else {
+ clause = (PerObject) getConcreteAspect().getPerClause();
+ }
+ if (clause.isThis()) {
+ PerObjectInterfaceTypeMunger.registerAsAdvisedBy(s.getThisVar().getType(), getConcreteAspect());
+ } else {
+ PerObjectInterfaceTypeMunger.registerAsAdvisedBy(s.getTargetVar().getType(), getConcreteAspect());
+ }
+ }
+
if (getKind() == AdviceKind.Before) {
shadow.weaveBefore(this);
} else if (getKind() == AdviceKind.AfterReturning) {
import org.aspectj.weaver.WeaverMessages;
import org.aspectj.weaver.WeaverMetrics;
import org.aspectj.weaver.WeaverStateInfo;
+import org.aspectj.weaver.PerObjectInterfaceTypeMunger;
import org.aspectj.weaver.Shadow.Kind;
import org.aspectj.weaver.patterns.DeclareAnnotation;
import org.aspectj.weaver.patterns.FastMatchInfo;
BcelWorld world,
LazyClassGen clazz,
List shadowMungers,
- List typeMungers)
+ List typeMungers,
+ List lateTypeMungers)
{
- boolean b = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers).weave();
+ boolean b = new BcelClassWeaver(world, clazz, shadowMungers, typeMungers, lateTypeMungers).weave();
//System.out.println(clazz.getClassName() + ", " + clazz.getType().getWeaverState());
//clazz.print();
return b;
private final LazyClassGen clazz;
private final List shadowMungers;
private final List typeMungers;
+ private final List lateTypeMungers;
private final BcelObjectType ty; // alias of clazz.getType()
private final BcelWorld world; // alias of ty.getWorld()
BcelWorld world,
LazyClassGen clazz,
List shadowMungers,
- List typeMungers)
+ List typeMungers,
+ List lateTypeMungers)
{
super();
// assert world == clazz.getType().getWorld()
this.clazz = clazz;
this.shadowMungers = shadowMungers;
this.typeMungers = typeMungers;
+ this.lateTypeMungers = lateTypeMungers;
this.ty = clazz.getBcelObjectType();
this.cpg = clazz.getConstantPoolGen();
this.fact = clazz.getFactory();
// we want to "touch" all aspects
if (clazz.getType().isAspect()) isChanged = true;
-
+
// start by munging all typeMungers
for (Iterator i = typeMungers.iterator(); i.hasNext(); ) {
Object o = i.next();
List methodGens = new ArrayList(clazz.getMethodGens());
for (Iterator i = methodGens.iterator(); i.hasNext();) {
LazyMethodGen mg = (LazyMethodGen)i.next();
- //mg.getBody();
if (! mg.hasBody()) continue;
boolean shadowMungerMatched = match(mg);
if (shadowMungerMatched) {
isChanged = true;
}
}
- if (! isChanged) return false;
+ //if (! isChanged) return false;//FIXME AV - was active, WHY ?? I need to reach the lateTypeMunger
// now we weave all but the initialization shadows
for (Iterator i = methodGens.iterator(); i.hasNext();) {
positionAndImplement(initializationShadows);
}
-
+ // now proceed with late type mungers
+ if (lateTypeMungers != null) {
+ for (Iterator i = lateTypeMungers.iterator(); i.hasNext(); ) {
+ Object o = i.next();
+ if ( !(o instanceof BcelTypeMunger) ) {
+ throw new Error("should not happen or what ?");//FIXME AV ??was System.err.println("surprising: " + o);
+ //continue;
+ }
+ BcelTypeMunger munger = (BcelTypeMunger)o;
+ if (munger.matches(clazz.getType())) {
+ //FIXME AV - Andy must track change by this lateMunging only and deal with a reweavable thing
+ boolean typeMungerAffectedType = munger.munge(this);
+ if (typeMungerAffectedType) {
+ isChanged = true;
+ if (inReweavableMode) aspectsAffectingType.add(munger.getAspectType().getName());
+ }
+ }
+ }
+ }
+ // flush to save some memory - FIXME AV - extract in a better way ?
+ PerObjectInterfaceTypeMunger.unregisterFromAsAdvisedBy(clazz.getType());
+
// finally, if we changed, we add in the introduced methods.
if (isChanged) {
clazz.getOrCreateWeaverStateInfo();
//we cannot return onType.equals(aspectType)
//since we need to eagerly create the nested ajcMighHaveAspect interface on LTW
return true;
+ //return aspectType.equals(onType);
}
private void generatePerClauseMembers(LazyClassGen classGen) {
tryEnd.setTarget(il.getEnd());
// replace the original "return" with a "nop"
+ //TODO AV - a bit odd, looks like Bcel alters bytecode and has a IMPDEP1 in its representation
+ if (clinit.getBody().getEnd().getInstruction().getOpcode() == Constants.IMPDEP1) {
+ clinit.getBody().getEnd().getPrev().setInstruction(new NOP());
+ }
clinit.getBody().getEnd().setInstruction(new NOP());
clinit.getBody().append(il);
return changed;
}
-
+
private String getShortname(String path) {
int takefrom = path.lastIndexOf('/');
if (takefrom == -1) {
import org.aspectj.weaver.WeaverMetrics;
import org.aspectj.weaver.WeaverStateInfo;
import org.aspectj.weaver.World;
+import org.aspectj.weaver.ResolvedMember;
import org.aspectj.weaver.patterns.AndPointcut;
import org.aspectj.weaver.patterns.BindingAnnotationTypePattern;
import org.aspectj.weaver.patterns.BindingTypePattern;
private boolean needToReweaveWorld = false;
private List shadowMungerList = null; // setup by prepareForWeave
- private List typeMungerList = null; // setup by prepareForWeave
- private List declareParentsList = null; // setup by prepareForWeave
+ private List typeMungerList = null; // setup by prepareForWeave
+ private List lateTypeMungerList = null; // setup by prepareForWeave
+ private List declareParentsList = null; // setup by prepareForWeave
private ZipOutputStream zipOutputStream;
shadowMungerList = xcutSet.getShadowMungers();
rewritePointcuts(shadowMungerList);
typeMungerList = xcutSet.getTypeMungers();
+ lateTypeMungerList = xcutSet.getLateTypeMungers();
declareParentsList = xcutSet.getDeclareParents();
// The ordering here used to be based on a string compare on toString() for the two mungers -
ShadowMunger element = (ShadowMunger) iter.next();
if (element instanceof BcelAdvice) { // This will stop us incorrectly reporting deow Checkers
BcelAdvice ba = (BcelAdvice)element;
- if (!ba.hasMatchedSomething()) {
+ if (!ba.hasMatchedSomething()) {
// Because we implement some features of AJ itself by creating our own kind of mungers, you sometimes
// find that ba.getSignature() is not a BcelMethod - for example it might be a cflow entry munger.
if (ba.getSignature()!=null) {
clazz = classType.getLazyClassGen();
//System.err.println("got lazy gen: " + clazz + ", " + clazz.getWeaverState());
try {
- boolean isChanged = BcelClassWeaver.weave(world, clazz, shadowMungers, typeMungers);
+ boolean isChanged = BcelClassWeaver.weave(world, clazz, shadowMungers, typeMungers, lateTypeMungerList);
if (isChanged) {
if (dump) dump(classFile, clazz);
return clazz;
//ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects
if (inAspect.isAnnotationStyleAspect()) {
- inAspect.crosscuttingMembers.addTypeMunger(
+ inAspect.crosscuttingMembers.addLateTypeMunger(
inAspect.getWorld().makePerClauseAspect(inAspect, getKind())
);
}
//ATAJ inline around advice support
if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
- inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
+ inAspect.crosscuttingMembers.addLateTypeMunger(new BcelAccessForInlineMunger(inAspect));
}
return ret;
- private PerClause lookupConcretePerClause(ResolvedTypeX lookupType) {
+ public PerClause lookupConcretePerClause(ResolvedTypeX lookupType) {
PerClause ret = lookupType.getPerClause();
if (ret == null) return null;
if (ret instanceof PerFromSuper) {
Advice.makePerObjectEntry(world, concreteEntry, isThis, inAspect));
ResolvedTypeMunger munger =
new PerObjectInterfaceTypeMunger(inAspect, concreteEntry);
- inAspect.crosscuttingMembers.addTypeMunger(world.concreteTypeMunger(munger, inAspect));
+ inAspect.crosscuttingMembers.addLateTypeMunger(world.concreteTypeMunger(munger, inAspect));
//ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects
if (inAspect.isAnnotationStyleAspect()) {
- inAspect.crosscuttingMembers.addTypeMunger(
+ inAspect.crosscuttingMembers.addLateTypeMunger(
inAspect.getWorld().makePerClauseAspect(inAspect, getKind())
);
}
//ATAJ inline around advice support
if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
- inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
+ inAspect.crosscuttingMembers.addLateTypeMunger(new BcelAccessForInlineMunger(inAspect));
}
return ret;
public PerClause.Kind getKind() {
return PEROBJECT;
}
-
+
+ public boolean isThis() {
+ return isThis;
+ }
+
public String toString() {
return "per" + (isThis ? "this" : "target") +
"(" + entry + ")";
if (!inAspect.isAbstract() && Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
//TODO will those change be ok if we add a serializable aspect ?
// dig: "can't be Serializable/Cloneable unless -XserializableAspects"
- inAspect.crosscuttingMembers.addTypeMunger(
+ inAspect.crosscuttingMembers.addLateTypeMunger(
inAspect.getWorld().makePerClauseAspect(inAspect, getKind())
);
}
//ATAJ inline around advice support
if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
- inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
+ inAspect.crosscuttingMembers.addLateTypeMunger(new BcelAccessForInlineMunger(inAspect));
}
return ret;
//ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects
if (inAspect.isAnnotationStyleAspect()) {
- inAspect.crosscuttingMembers.addTypeMunger(
+ inAspect.crosscuttingMembers.addLateTypeMunger(
inAspect.getWorld().makePerClauseAspect(inAspect, getKind())
);
}
//ATAJ inline around advice support
if (Ajc5MemberMaker.isAnnotationStyleAspect(inAspect)) {
- inAspect.crosscuttingMembers.addTypeMunger(new BcelAccessForInlineMunger(inAspect));
+ inAspect.crosscuttingMembers.addLateTypeMunger(new BcelAccessForInlineMunger(inAspect));
}
return ret;