From 83655ff47c1af1ca58c8043626799e0483d5acd4 Mon Sep 17 00:00:00 2001 From: avasseur Date: Tue, 10 May 2005 15:44:11 +0000 Subject: [PATCH] fix 75442 thru lateTypeMungers, currently @AJaspectOf and perObject are lateTypeMungers. new LTW tests, some fix in the LTW test error reporting --- .../aspectj/ajde/ModelPerformanceTest.java | 2 +- .../src/org/aspectj/weaver/loadtime/Aj.java | 4 +- .../loadtime/DefaultMessageHandler.java | 55 ++++++++ .../org/aspectj/weaver/loadtime/Options.java | 33 +---- .../compiler/lookup/EclipseFactory.java | 5 +- .../aspectj/tools/ant/taskdefs/AjcTask.java | 4 + .../newsrc/org/aspectj/testing/AjcTest.java | 5 +- .../newsrc/org/aspectj/testing/AntSpec.java | 18 ++- .../org/aspectj/testing/CompileSpec.java | 4 +- .../harness/bridge/AbstractRunSpecTest.java | 2 +- tests/java5/ataspectj/ajc-ant.xml | 26 +++- .../ataspectj/ataspectj/AllLTWTests.java | 1 - .../ataspectj/ataspectj/PerClauseTest.java | 122 +++++------------- .../ataspectj/PerClauseTestAspects.java | 85 ++++++++++++ .../java5/ataspectj/ataspectj/TestHelper.java | 29 ++++- tests/java5/ataspectj/ataspectj/aop.xml | 9 +- .../systemtest/ajc150/AllTestsAspectJ150.java | 2 + .../ajc150/ataspectj/AtAjLTWTests.java | 31 +++++ .../systemtest/ajc150/ataspectj/ltw.xml | 39 ++++++ .../systemtest/ajc150/ataspectj/misuse.xml | 3 +- .../systemtest/ajc150/ataspectj/syntax.xml | 7 +- weaver/src/org/aspectj/weaver/Advice.java | 2 +- .../aspectj/weaver/CrosscuttingMembers.java | 30 ++++- .../weaver/CrosscuttingMembersSet.java | 17 ++- .../weaver/PerObjectInterfaceTypeMunger.java | 33 ++++- .../src/org/aspectj/weaver/ResolvedTypeX.java | 1 + weaver/src/org/aspectj/weaver/World.java | 2 + .../org/aspectj/weaver/bcel/BcelAdvice.java | 25 +++- .../aspectj/weaver/bcel/BcelClassWeaver.java | 39 +++++- .../weaver/bcel/BcelPerClauseAspectAdder.java | 5 + .../aspectj/weaver/bcel/BcelTypeMunger.java | 2 +- .../org/aspectj/weaver/bcel/BcelWeaver.java | 11 +- .../org/aspectj/weaver/patterns/PerCflow.java | 4 +- .../aspectj/weaver/patterns/PerFromSuper.java | 2 +- .../aspectj/weaver/patterns/PerObject.java | 12 +- .../aspectj/weaver/patterns/PerSingleton.java | 4 +- .../weaver/patterns/PerTypeWithin.java | 4 +- 37 files changed, 490 insertions(+), 189 deletions(-) create mode 100644 loadtime/src/org/aspectj/weaver/loadtime/DefaultMessageHandler.java create mode 100644 tests/java5/ataspectj/ataspectj/PerClauseTestAspects.java create mode 100644 tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjLTWTests.java create mode 100644 tests/src/org/aspectj/systemtest/ajc150/ataspectj/ltw.xml diff --git a/ajde/testsrc/org/aspectj/ajde/ModelPerformanceTest.java b/ajde/testsrc/org/aspectj/ajde/ModelPerformanceTest.java index 1734c4211..044d62bf4 100644 --- a/ajde/testsrc/org/aspectj/ajde/ModelPerformanceTest.java +++ b/ajde/testsrc/org/aspectj/ajde/ModelPerformanceTest.java @@ -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); } diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java index 4bb83cbad..a087c5c81 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/Aj.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/Aj.java @@ -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) { diff --git a/loadtime/src/org/aspectj/weaver/loadtime/DefaultMessageHandler.java b/loadtime/src/org/aspectj/weaver/loadtime/DefaultMessageHandler.java new file mode 100644 index 000000000..e099dee7c --- /dev/null +++ b/loadtime/src/org/aspectj/weaver/loadtime/DefaultMessageHandler.java @@ -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 Alexandre Vasseur + */ +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; + } + } + +} diff --git a/loadtime/src/org/aspectj/weaver/loadtime/Options.java b/loadtime/src/org/aspectj/weaver/loadtime/Options.java index c466f9787..387eca2bf 100644 --- a/loadtime/src/org/aspectj/weaver/loadtime/Options.java +++ b/loadtime/src/org/aspectj/weaver/loadtime/Options.java @@ -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( diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java index b294efccb..b6998e919 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java @@ -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); diff --git a/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java b/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java index 56125af4d..60fba4b89 100644 --- a/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java +++ b/taskdefs/src/org/aspectj/tools/ant/taskdefs/AjcTask.java @@ -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); } diff --git a/testing/newsrc/org/aspectj/testing/AjcTest.java b/testing/newsrc/org/aspectj/testing/AjcTest.java index c1c88cd85..a406ae2fe 100644 --- a/testing/newsrc/org/aspectj/testing/AjcTest.java +++ b/testing/newsrc/org/aspectj/testing/AjcTest.java @@ -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")) { diff --git a/testing/newsrc/org/aspectj/testing/AntSpec.java b/testing/newsrc/org/aspectj/testing/AntSpec.java index 84abb4b2a..0623923be 100644 --- a/testing/newsrc/org/aspectj/testing/AntSpec.java +++ b/testing/newsrc/org/aspectj/testing/AntSpec.java @@ -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()); } diff --git a/testing/newsrc/org/aspectj/testing/CompileSpec.java b/testing/newsrc/org/aspectj/testing/CompileSpec.java index 93d0e2bb5..4cc0f01de 100644 --- a/testing/newsrc/org/aspectj/testing/CompileSpec.java +++ b/testing/newsrc/org/aspectj/testing/CompileSpec.java @@ -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); } } diff --git a/testing/testsrc/org/aspectj/testing/harness/bridge/AbstractRunSpecTest.java b/testing/testsrc/org/aspectj/testing/harness/bridge/AbstractRunSpecTest.java index f7871872d..fdafdca82 100644 --- a/testing/testsrc/org/aspectj/testing/harness/bridge/AbstractRunSpecTest.java +++ b/testing/testsrc/org/aspectj/testing/harness/bridge/AbstractRunSpecTest.java @@ -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() { diff --git a/tests/java5/ataspectj/ajc-ant.xml b/tests/java5/ataspectj/ajc-ant.xml index 4aaf76d0d..ec223ea54 100644 --- a/tests/java5/ataspectj/ajc-ant.xml +++ b/tests/java5/ataspectj/ajc-ant.xml @@ -1,5 +1,9 @@ - + + + @@ -10,11 +14,29 @@ - + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/java5/ataspectj/ataspectj/AllLTWTests.java b/tests/java5/ataspectj/ataspectj/AllLTWTests.java index eddd0cde2..e015a0a8e 100644 --- a/tests/java5/ataspectj/ataspectj/AllLTWTests.java +++ b/tests/java5/ataspectj/ataspectj/AllLTWTests.java @@ -13,7 +13,6 @@ package ataspectj; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; -import test.loadtime5.AtAspectJTest; /** * @author Alexandre Vasseur diff --git a/tests/java5/ataspectj/ataspectj/PerClauseTest.java b/tests/java5/ataspectj/ataspectj/PerClauseTest.java index ff8a354d2..268873696 100644 --- a/tests/java5/ataspectj/ataspectj/PerClauseTest.java +++ b/tests/java5/ataspectj/ataspectj/PerClauseTest.java @@ -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) { - ; - } - - } } diff --git a/tests/java5/ataspectj/ataspectj/PerClauseTestAspects.java b/tests/java5/ataspectj/ataspectj/PerClauseTestAspects.java new file mode 100644 index 000000000..175eb79ce --- /dev/null +++ b/tests/java5/ataspectj/ataspectj/PerClauseTestAspects.java @@ -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 Alexandre Vasseur + */ +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) { + ; + } + + } + + +} diff --git a/tests/java5/ataspectj/ataspectj/TestHelper.java b/tests/java5/ataspectj/ataspectj/TestHelper.java index bf30408fc..ba8eab807 100644 --- a/tests/java5/ataspectj/ataspectj/TestHelper.java +++ b/tests/java5/ataspectj/ataspectj/TestHelper.java @@ -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 Alexandre Vasseur */ -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; + } + } diff --git a/tests/java5/ataspectj/ataspectj/aop.xml b/tests/java5/ataspectj/ataspectj/aop.xml index d76592f04..efe556127 100644 --- a/tests/java5/ataspectj/ataspectj/aop.xml +++ b/tests/java5/ataspectj/ataspectj/aop.xml @@ -1,5 +1,6 @@ + @@ -15,10 +16,10 @@ - - - - + + + + diff --git a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java index 004eb0a0d..6069f845a 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java +++ b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java @@ -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; } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjLTWTests.java b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjLTWTests.java new file mode 100644 index 000000000..0f820873e --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjLTWTests.java @@ -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 Alexandre Vasseur + */ +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"); + } +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/ltw.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/ltw.xml new file mode 100644 index 000000000..ae296871c --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/ltw.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml index d9c0ba75c..5427a4a2c 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml @@ -15,7 +15,8 @@ - + + diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml index d839dda28..12a84bf09 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml @@ -81,9 +81,9 @@ - + - + @@ -94,7 +94,4 @@ - - - \ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/Advice.java b/weaver/src/org/aspectj/weaver/Advice.java index 183272886..ce3516515 100644 --- a/weaver/src/org/aspectj/weaver/Advice.java +++ b/weaver/src/org/aspectj/weaver/Advice.java @@ -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(); diff --git a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java index 5787f39c6..403f4e46b 100644 --- a/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java +++ b/weaver/src/org/aspectj/weaver/CrosscuttingMembers.java @@ -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; } diff --git a/weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java b/weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java index 652666393..b84c44a71 100644 --- a/weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java +++ b/weaver/src/org/aspectj/weaver/CrosscuttingMembersSet.java @@ -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(); diff --git a/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java b/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java index 2a9f73202..116d146a1 100644 --- a/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/PerObjectInterfaceTypeMunger.java @@ -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) { diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java index 05fe9ed92..5154d1aa6 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java @@ -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()); diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index cdcac9fc5..6a3b0814e 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -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); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java index e25beb343..d28034fed 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java @@ -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) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java index c966e346c..305bdcf23 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java @@ -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(); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java index 3cedb9235..54bae2c9c 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java @@ -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); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index 31af19713..ced005ed5 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -147,7 +147,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { return changed; } - + private String getShortname(String path) { int takefrom = path.lastIndexOf('/'); if (takefrom == -1) { diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java index cfd23c4ec..c41201142 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelWeaver.java @@ -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; diff --git a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java index 3d647c455..76a2fc345 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerCflow.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerCflow.java @@ -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; diff --git a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java index 87d6b61db..63131f5ad 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerFromSuper.java @@ -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) { diff --git a/weaver/src/org/aspectj/weaver/patterns/PerObject.java b/weaver/src/org/aspectj/weaver/patterns/PerObject.java index 2374b8e2c..7e8645608 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerObject.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerObject.java @@ -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 + ")"; diff --git a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java index 7c053e98d..ad780fc02 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerSingleton.java @@ -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; diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java index 157f10223..1971fa83b 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java @@ -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; -- 2.39.5