@@ -42,7 +42,7 @@ public class ModelPerformanceTest extends AjdeTestCase { | |||
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); | |||
} | |||
@@ -55,6 +55,8 @@ public class Aj implements ClassPreProcessor { | |||
__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; | |||
} | |||
@@ -110,7 +112,7 @@ public class Aj implements ClassPreProcessor { | |||
* @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) { |
@@ -0,0 +1,55 @@ | |||
/******************************************************************************* | |||
* 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; | |||
} | |||
} | |||
} |
@@ -30,37 +30,6 @@ import java.util.List; | |||
*/ | |||
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"; | |||
@@ -125,6 +94,8 @@ public class Options { | |||
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( |
@@ -252,8 +252,9 @@ public class EclipseFactory { | |||
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); |
@@ -472,6 +472,10 @@ public class AjcTask extends MatchingTask { | |||
cmd.addFlag("-Xreweavable",reweavable); | |||
} | |||
public void setXNoInline(boolean noInline) { | |||
cmd.addFlag("-XnoInline",noInline); | |||
} | |||
public void setShowWeaveInfo(boolean showweaveinfo) { | |||
cmd.addFlag("-showWeaveInfo",showweaveinfo); | |||
} |
@@ -30,7 +30,10 @@ public class AjcTest { | |||
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")) { |
@@ -79,6 +79,12 @@ public class AntSpec implements ITestStep { | |||
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); | |||
@@ -90,6 +96,12 @@ public class AntSpec implements ITestStep { | |||
// 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) { | |||
@@ -111,12 +123,6 @@ public class AntSpec implements ITestStep { | |||
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()); | |||
} |
@@ -240,10 +240,10 @@ public class CompileSpec implements ITestStep { | |||
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); | |||
} | |||
} |
@@ -38,7 +38,7 @@ public class AbstractRunSpecTest extends TestCase { | |||
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() { |
@@ -1,5 +1,9 @@ | |||
<!-- 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 --> | |||
@@ -10,11 +14,29 @@ | |||
</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> |
@@ -13,7 +13,6 @@ package ataspectj; | |||
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> |
@@ -45,8 +45,8 @@ public class PerClauseTest extends TestCase { | |||
// 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()); | |||
} | |||
@@ -55,24 +55,9 @@ public class PerClauseTest extends TestCase { | |||
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"); | |||
} | |||
@@ -84,8 +69,8 @@ public class PerClauseTest extends TestCase { | |||
// 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 | |||
@@ -93,8 +78,8 @@ public class PerClauseTest extends TestCase { | |||
// 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()); | |||
@@ -103,44 +88,29 @@ public class PerClauseTest extends TestCase { | |||
// 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()); | |||
} | |||
@@ -156,8 +126,8 @@ public class PerClauseTest extends TestCase { | |||
// 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 | |||
@@ -167,8 +137,8 @@ public class PerClauseTest extends TestCase { | |||
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 | |||
@@ -179,8 +149,8 @@ public class PerClauseTest extends TestCase { | |||
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 | |||
@@ -204,45 +174,30 @@ public class PerClauseTest extends TestCase { | |||
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 | |||
@@ -258,19 +213,4 @@ public class PerClauseTest extends TestCase { | |||
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) { | |||
; | |||
} | |||
} | |||
} |
@@ -0,0 +1,85 @@ | |||
/******************************************************************************* | |||
* 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) { | |||
; | |||
} | |||
} | |||
} |
@@ -13,9 +13,16 @@ package ataspectj; | |||
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. | |||
@@ -24,7 +31,7 @@ import java.util.Enumeration; | |||
* | |||
* @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(); | |||
@@ -33,18 +40,30 @@ public class TestHelper { | |||
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; | |||
} | |||
} |
@@ -1,5 +1,6 @@ | |||
<?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"/> | |||
@@ -15,10 +16,10 @@ | |||
<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> |
@@ -12,6 +12,7 @@ package org.aspectj.systemtest.ajc150; | |||
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; | |||
@@ -47,6 +48,7 @@ public class AllTestsAspectJ150 { | |||
suite.addTest(GenericsTests.suite()); | |||
suite.addTest(AtAjSyntaxTests.suite()); | |||
suite.addTest(AtAjMisuseTests.suite()); | |||
suite.addTest(AtAjLTWTests.suite()); | |||
//$JUnit-END$ | |||
return suite; | |||
} |
@@ -0,0 +1,31 @@ | |||
/******************************************************************************* | |||
* 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"); | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
<!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> |
@@ -15,7 +15,8 @@ | |||
<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> | |||
@@ -81,9 +81,9 @@ | |||
</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> | |||
@@ -94,7 +94,4 @@ | |||
<run class="ataspectj.AroundInlineMungerTest"/> | |||
</ajc-test> | |||
<ajc-test dir="java5/ataspectj" title="RunThemAllWithJavacCompiledAndLTW"> | |||
<ant file="ajc-ant.xml" target="all"/> | |||
</ajc-test> | |||
</suite> |
@@ -226,7 +226,7 @@ public abstract class Advice extends ShadowMunger { | |||
// ---- | |||
/** @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(); |
@@ -48,7 +48,8 @@ public class CrosscuttingMembers { | |||
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); | |||
@@ -88,18 +89,24 @@ public class CrosscuttingMembers { | |||
} | |||
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) { | |||
@@ -196,7 +203,12 @@ public class CrosscuttingMembers { | |||
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; | |||
@@ -258,7 +270,11 @@ public class CrosscuttingMembers { | |||
public List getTypeMungers() { | |||
return typeMungers; | |||
} | |||
public List getLateTypeMungers() { | |||
return lateTypeMungers; | |||
} | |||
public List getDeclareAnnotationOnTypes() { | |||
return declareAnnotationsOnType; | |||
} |
@@ -31,11 +31,12 @@ import org.aspectj.weaver.patterns.DeclareParents; | |||
*/ | |||
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; | |||
@@ -92,6 +93,7 @@ public class CrosscuttingMembersSet { | |||
private void clearCaches() { | |||
shadowMungers = null; | |||
typeMungers = null; | |||
lateTypeMungers = null; | |||
declareSofts = null; | |||
declareParents = null; | |||
declareDominates = null; | |||
@@ -119,7 +121,18 @@ public class CrosscuttingMembersSet { | |||
} | |||
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(); |
@@ -15,12 +15,36 @@ package org.aspectj.weaver; | |||
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; | |||
@@ -66,7 +90,14 @@ public class PerObjectInterfaceTypeMunger extends ResolvedTypeMunger { | |||
// 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) { |
@@ -414,6 +414,7 @@ public abstract class ResolvedTypeX extends TypeX implements AnnotatedElement { | |||
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()); | |||
@@ -70,6 +70,8 @@ public abstract class World implements Dump.INode { | |||
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); |
@@ -35,12 +35,16 @@ import org.aspectj.weaver.Shadow; | |||
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. | |||
@@ -136,7 +140,26 @@ public class BcelAdvice extends Advice { | |||
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) { |
@@ -75,6 +75,7 @@ import org.aspectj.weaver.TypeX; | |||
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; | |||
@@ -88,9 +89,10 @@ class BcelClassWeaver implements IClassWeaver { | |||
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; | |||
@@ -101,6 +103,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
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() | |||
@@ -137,7 +140,8 @@ class BcelClassWeaver implements IClassWeaver { | |||
BcelWorld world, | |||
LazyClassGen clazz, | |||
List shadowMungers, | |||
List typeMungers) | |||
List typeMungers, | |||
List lateTypeMungers) | |||
{ | |||
super(); | |||
// assert world == clazz.getType().getWorld() | |||
@@ -145,6 +149,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
this.clazz = clazz; | |||
this.shadowMungers = shadowMungers; | |||
this.typeMungers = typeMungers; | |||
this.lateTypeMungers = lateTypeMungers; | |||
this.ty = clazz.getBcelObjectType(); | |||
this.cpg = clazz.getConstantPoolGen(); | |||
this.fact = clazz.getFactory(); | |||
@@ -328,7 +333,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
// 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(); | |||
@@ -369,7 +374,6 @@ class BcelClassWeaver implements IClassWeaver { | |||
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) { | |||
@@ -378,7 +382,7 @@ class BcelClassWeaver implements IClassWeaver { | |||
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();) { | |||
@@ -397,7 +401,28 @@ class BcelClassWeaver implements IClassWeaver { | |||
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(); |
@@ -124,6 +124,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
//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) { | |||
@@ -218,6 +219,10 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { | |||
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); | |||
@@ -147,7 +147,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
return changed; | |||
} | |||
private String getShortname(String path) { | |||
int takefrom = path.lastIndexOf('/'); | |||
if (takefrom == -1) { |
@@ -72,6 +72,7 @@ import org.aspectj.weaver.WeaverMessages; | |||
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; | |||
@@ -119,8 +120,9 @@ public class BcelWeaver implements IWeaver { | |||
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; | |||
@@ -426,6 +428,7 @@ public class BcelWeaver implements IWeaver { | |||
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 - | |||
@@ -1004,7 +1007,7 @@ public class BcelWeaver implements IWeaver { | |||
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) { | |||
@@ -1356,7 +1359,7 @@ public class BcelWeaver implements IWeaver { | |||
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; |
@@ -100,14 +100,14 @@ public class PerCflow extends PerClause { | |||
//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; |
@@ -72,7 +72,7 @@ public class PerFromSuper extends PerClause { | |||
private PerClause lookupConcretePerClause(ResolvedTypeX lookupType) { | |||
public PerClause lookupConcretePerClause(ResolvedTypeX lookupType) { | |||
PerClause ret = lookupType.getPerClause(); | |||
if (ret == null) return null; | |||
if (ret instanceof PerFromSuper) { |
@@ -106,18 +106,18 @@ public class PerObject extends PerClause { | |||
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; | |||
@@ -139,7 +139,11 @@ public class PerObject extends PerClause { | |||
public PerClause.Kind getKind() { | |||
return PEROBJECT; | |||
} | |||
public boolean isThis() { | |||
return isThis; | |||
} | |||
public String toString() { | |||
return "per" + (isThis ? "this" : "target") + | |||
"(" + entry + ")"; |
@@ -100,14 +100,14 @@ public class PerSingleton extends PerClause { | |||
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; |
@@ -150,14 +150,14 @@ public class PerTypeWithin extends PerClause { | |||
//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; |