]> source.dussan.org Git - aspectj.git/commitdiff
LTW modules + AntSpec to test LTW in the sandbox + code cleanup in my FIXME + fix...
authoravasseur <avasseur>
Wed, 4 May 2005 14:57:21 +0000 (14:57 +0000)
committeravasseur <avasseur>
Wed, 4 May 2005 14:57:21 +0000 (14:57 +0000)
26 files changed:
bridge/src/org/aspectj/bridge/CountingMessageHandler.java
bridge/src/org/aspectj/bridge/IMessageHandler.java
bridge/src/org/aspectj/bridge/MessageUtil.java
bridge/src/org/aspectj/bridge/MessageWriter.java
lib/test/loadtime5.jar [new file with mode: 0644]
loadtime/src/org/aspectj/weaver/loadtime/Aj.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/WeaverMessageHandler.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AspectJBuilder.java
org.aspectj.ajdt.core/src/org/aspectj/tools/ajc/Main.java
org.aspectj.ajdt.core/testsrc/org/aspectj/tools/ajc/AjcTestCase.java
testing-client/testsrc/org/aspectj/testing/TesterTest.java
testing/newsrc/org/aspectj/testing/AntSpec.java [new file with mode: 0644]
testing/newsrc/org/aspectj/testing/XMLBasedAjcTestCase.java
testing/src/org/aspectj/testing/run/RunStatus.java
tests/java5/ataspectj/ajc-ant.xml [new file with mode: 0644]
tests/java5/ataspectj/ataspectj/AllLTWTests.java [new file with mode: 0644]
tests/java5/ataspectj/ataspectj/BindingTest.java
tests/java5/ataspectj/ataspectj/aop.xml [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml
weaver/src/org/aspectj/weaver/Shadow.java
weaver/src/org/aspectj/weaver/ataspectj/Aj5Attributes.java
weaver/src/org/aspectj/weaver/bcel/BcelAdvice.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java
weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java
weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java

index 3cdd7d482f282ff5f3932dc8a217a17c94c3ed91..5bfe0b97187d5d1d6a1aaa7cfd3c4cfe46a93cee 100644 (file)
@@ -65,7 +65,16 @@ public class CountingMessageHandler implements IMessageHandler {
     public boolean isIgnoring(IMessage.Kind kind) {
         return delegate.isIgnoring(kind);
     }
-    
+
+    /**
+     * Delegate
+     * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+     * @param kind
+     */
+    public void dontIgnore(IMessage.Kind kind) {
+        delegate.dontIgnore(kind);
+    }
+
     /** @return delegate.toString() */
     public String toString() {
         return delegate.toString();
index 76b76ec0b2f40718689357533370e5b83c844620..d3846db7363477c038ff27630c87c30bbaa2453c 100644 (file)
@@ -49,6 +49,9 @@ public interface IMessageHandler {
                        public boolean isIgnoring(IMessage.Kind kind) {
                                return false;
                        }
+            public void dontIgnore(IMessage.Kind kind) {
+                ;
+            }
                };
 
        /** 
@@ -66,4 +69,12 @@ public interface IMessageHandler {
         * @return true if this handler is ignoring all messages of this type
         */
        boolean isIgnoring(IMessage.Kind kind);
+
+    /**
+     * Allow fine grained configuration after initialization. Minaly used in LTW. Most of the
+     * implementation can have this method be a no-op.
+     *  
+     * @param kind
+     */
+    void dontIgnore(IMessage.Kind kind);
 }
index 79250943e86e0b06675fc8c7e328a27a3f599b18..fd4a41efe730e14db068fd9539fc4af2987c10bc 100644 (file)
@@ -358,6 +358,9 @@ public class MessageUtil {
             public boolean isIgnoring(Kind kind) {
                 return false;
             }
+            public void dontIgnore(IMessage.Kind kind) {
+                ;
+            }
         };
         return visitMessages(holder, selector, true, false);
     }
@@ -576,7 +579,11 @@ public class MessageUtil {
                 return (0 < IMessage.Kind.COMPARATOR.compare(sought, kind));
             }
         }
-        
+
+        public void dontIgnore(IMessage.Kind kind) {
+            ;
+        }
+
         private boolean textIn(IMessage message) {
             if (null == infix) {
                 return true;
index 467002c3b590bb9c409e08ad05869416496c1f94..bc9530314a5ebddc626786a4b9916c2bb7595a31 100644 (file)
@@ -52,13 +52,22 @@ public class MessageWriter implements IMessageHandler {
        }
     
     /**
-        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(Kind)
+        * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
         */
        public boolean isIgnoring(IMessage.Kind kind) { 
         // XXX share MessageHandler implementation in superclass
                return false;
        }
 
+    /**
+     * No-op
+     * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+     * @param kind
+     */
+    public void dontIgnore(IMessage.Kind kind) {
+        ;
+    }
+
     /** @return null to not print, or message rendering (including newlines) */
     protected String render(IMessage message) {
         return message.toString();    
diff --git a/lib/test/loadtime5.jar b/lib/test/loadtime5.jar
new file mode 100644 (file)
index 0000000..1889222
Binary files /dev/null and b/lib/test/loadtime5.jar differ
index 057669d2fd07ff2841fbdaad3068dfeecb1ab2d0..69af2ef1417da961203e681c2cff0bbfe3d12400 100644 (file)
@@ -128,6 +128,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
         String className = name.replace('.', '/');
         final File dir;
         if (className.indexOf('/') > 0) {
index a7c9bc056e4393605f108f9225ece162d6c678af..d703886050e5a2d4d293662e9b6eafb10c2a1eec 100644 (file)
@@ -120,7 +120,16 @@ public class WeaverMessageHandler implements IMessageHandler {
        public boolean isIgnoring(Kind kind) {
                return sink.isIgnoring(kind);
        }
-       
+
+    /**
+     * No-op
+     * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+     * @param kind
+     */
+    public void dontIgnore(IMessage.Kind kind) {
+        ;
+    }
+
        private int getStartPos(ISourceLocation sLoc,CompilationResult result) {
                int pos = 0;
                if (sLoc == null) return 0;
index 5407758fff76e4a109ec8a3f17555d09f1a47b6b..471770f7b06ecb9beb06c36f5aef9dde95d0e018 100644 (file)
@@ -228,7 +228,16 @@ public class AspectJBuilder extends JavaBuilder implements ICompilerAdapterFacto
                        if (kind == IMessage.DEBUG || kind == IMessage.INFO) return true;
                        return false;
                }
-               
+        
+        /**
+         * No-op
+         * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+         * @param kind
+         */
+        public void dontIgnore(IMessage.Kind kind) {
+            ;
+        }
+
        }
        
        
index 56aaaef5a8b32730cc8e368d810d7b0f0fdcf70a..365242c739adbb7643fcb5abc72a0789f16b913e 100644 (file)
@@ -534,8 +534,17 @@ public class Main {
         public boolean isIgnoring(IMessage.Kind kind) {
                        return (null != getStreamFor(kind));
                }
-        
-        /** @return System.err for FAIL, ABORT, ERROR, and WARNING, 
+
+        /**
+         * No-op
+         * @see org.aspectj.bridge.IMessageHandler#isIgnoring(org.aspectj.bridge.IMessage.Kind)
+         * @param kind
+         */
+        public void dontIgnore(IMessage.Kind kind) {
+            ;
+        }
+
+        /** @return System.err for FAIL, ABORT, ERROR, and WARNING,
          *           System.out for INFO if -verbose and WEAVEINFO if -showWeaveInfo.
          */
         protected PrintStream getStreamFor(IMessage.Kind kind) {
index 77e8a3b40e588d417a4ff102eb2a537dee57a4e8..02a5028c4ea9f421714fb6132b7239db822c3a03 100644 (file)
@@ -58,7 +58,7 @@ public class AjcTestCase extends TestCase {
         */
        protected Ajc ajc;
        
-       private static final String DEFAULT_CLASSPATH_ENTRIES = 
+       public static final String DEFAULT_CLASSPATH_ENTRIES = 
         File.pathSeparator + 
                ".." + File.separator + "runtime" + File.separator + "bin" + 
                File.pathSeparator +
index 5acce235de8008154c0d8422ce987b4fc555a41b..4ed67cac4692e2e4c11a7dd775f00e6c570a37c4 100644 (file)
@@ -202,7 +202,11 @@ public class TesterTest extends TestCase {
         public boolean isIgnoring(IMessage.Kind kind) {
             return false;
         }
-        
+
+        public void dontIgnore(IMessage.Kind kind) {
+            ;
+        }
+
         public boolean handleMessage(IMessage message) {
             (message.isFailed() ? failures : passes).add(message);
             return true;
diff --git a/testing/newsrc/org/aspectj/testing/AntSpec.java b/testing/newsrc/org/aspectj/testing/AntSpec.java
new file mode 100644 (file)
index 0000000..84abb4b
--- /dev/null
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * 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.testing;
+
+import org.aspectj.tools.ajc.AjcTestCase;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectHelper;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.types.Path;
+
+import java.io.File;
+import java.util.StringTokenizer;
+
+/**
+ * Element that allow to run an abritrary Ant target in a sandbox.
+ * <p/>
+ * Such a spec is used in a "<ajc-test><ant file="myAnt.xml" [target="..."] [verbose="true"]/> XML element.
+ * The "target" is optional. If not set, default myAnt.xml target is used.
+ * The "file" file is looked up from the <ajc-test dir="..."/> attribute.
+ * If "verbose" is set to "true", the ant -v output is piped, else nothing is reported except errors.
+ * <p/>
+ * The called Ant target benefits from 2 implicit variables:
+ * "${aj.sandbox}" points to the test current sandbox folder.
+ * "aj.path" is an Ant refid on the classpath formed with the sandbox folder + ltw + the AjcTestCase classpath
+ * (ie usually aspectjrt, junit, and testing infra)
+ * <p/>
+ * Element "<stdout><line text="..">" and "<stderr><line text="..">" can be used. For now a full match
+ * is performed on the output of the runned target only (not the whole Ant invocation). This is experimental
+ * and advised to use a "<junit>" task instead or a "<java>" whose main that throws some exception upon failure.
+ *
+ *
+ * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
+ */
+public class AntSpec implements ITestStep {
+    
+    private final static String DEFAULT_LTW_CLASSPATH_ENTRIES =
+            ".." + File.separator + "_IDE"//ALEX hack since IntelliJ does not produce modules/bin/
+            + File.pathSeparator + ".." + File.separator + "asm/bin"
+            + File.pathSeparator + ".." + File.separator + "bridge/bin"
+            + File.pathSeparator + ".." + File.separator + "loadtime/bin"
+            + File.pathSeparator + ".." + File.separator + "loadtime5/bin"
+            + File.pathSeparator + ".." + File.separator + "weaver/bin"
+            + File.pathSeparator + ".." + File.separator + "lib/bcel/bcel.jar";
+
+
+    private boolean m_verbose = false;
+    private AjcTest m_ajcTest;
+    private OutputSpec m_stdErrSpec;
+    private OutputSpec m_stdOutSpec;
+    private String m_antFile;
+    private String m_antTarget;
+
+    public void execute(AjcTestCase inTestCase) {
+        final String failMessage = "test \"" + m_ajcTest.getTitle() + "\" failed: ";
+
+        File buildFile = new File(m_ajcTest.getDir() + File.separatorChar + m_antFile);
+        if (!buildFile.exists()) {
+            AjcTestCase.fail(failMessage + "no such Ant file " + buildFile.getAbsolutePath());
+        }
+        Project p = new Project();
+        final StringBuffer stdout = new StringBuffer();
+        final StringBuffer stderr = new StringBuffer();
+        try {
+            // read the Ant file
+            p.init();
+            p.setUserProperty("ant.file", buildFile.getAbsolutePath());
+            // setup aj.sandbox
+            p.setUserProperty("aj.sandbox", inTestCase.getSandboxDirectory().getAbsolutePath());
+            // setup aj.dir "modules" folder
+            p.setUserProperty("aj.root", new File("..").getAbsolutePath());
+
+            ProjectHelper helper = ProjectHelper.getProjectHelper();
+            helper.parse(p, buildFile);
+
+            // use default target if no target specified
+            if (m_antTarget == null) {
+                m_antTarget = p.getDefaultTarget();
+            }
+
+            // make sure we listen for failure
+            DefaultLogger consoleLogger = new DefaultLogger() {
+                public void targetFinished(BuildEvent event) {
+                    super.targetFinished(event);
+                    if (event.getException() != null) {
+                        AjcTestCase.fail(failMessage + "failure in '" + event.getTarget() + "' " + event.getException());
+                    }
+                }
+                public void messageLogged(BuildEvent event) {
+                    super.messageLogged(event);
+                    if (event.getTarget() != null && event.getPriority() >= Project.MSG_INFO && m_antTarget.equals(event.getTarget().getName())) {
+                        if (event.getException() == null) {
+                            stdout.append(event.getMessage()).append('\n');
+                        } else {
+                            stderr.append(event.getMessage());
+                        }
+                    }
+                }
+            };
+            consoleLogger.setErrorPrintStream(System.err);
+            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());
+        }
+        try {
+            p.fireBuildStarted();
+            p.executeTarget(m_antTarget);
+            p.fireBuildFinished(null);
+        } catch (BuildException e) {
+            p.fireBuildFinished(e);
+        } catch (Throwable t) {
+            AjcTestCase.fail(failMessage + "error when invoking target :" + t.toString());
+        }
+
+        // match lines
+        //TODO AV experimental: requires full match so rather useless.
+        // if someone needs it, we ll have to impl a "include / exclude" stuff
+        if (m_stdOutSpec != null)
+            m_stdOutSpec.matchAgainst(stdout.toString());
+        // match lines
+        if (m_stdErrSpec != null)
+            m_stdErrSpec.matchAgainst(stdout.toString());
+    }
+
+    public void addStdErrSpec(OutputSpec spec) {
+        if (m_stdErrSpec!=null)
+            throw new UnsupportedOperationException("only one 'stderr' allowed in 'ant'");
+        m_stdErrSpec = spec;
+    }
+
+    public void addStdOutSpec(OutputSpec spec) {
+        if (m_stdOutSpec!=null)
+            throw new UnsupportedOperationException("only one 'stdout' allowed in 'ant'");
+        m_stdOutSpec = spec;
+    }
+
+    public void setVerbose(String verbose) {
+        if (verbose != null && "true".equalsIgnoreCase(verbose)) {
+            m_verbose = true;
+        }
+    }
+
+    public void setFile(String file) {
+        m_antFile = file;
+    }
+
+    public void setTarget(String target) {
+        m_antTarget = target;
+    }
+
+    public void addExpectedMessage(ExpectedMessageSpec message) {
+        throw new UnsupportedOperationException("don't use 'message' in 'ant' specs.");
+    }
+
+    public void setBaseDir(String dir) {
+        ;
+    }
+
+    public void setTest(AjcTest test) {
+        m_ajcTest = test;
+    }
+
+    private static void populatePath(Path path, String pathEntries) {
+        StringTokenizer st = new StringTokenizer(pathEntries, File.pathSeparator);
+        while (st.hasMoreTokens()) {
+            path.setPath(new File(st.nextToken()).getAbsolutePath());
+        }
+    }
+}
index 91ded4c1ab0eeef96cacd99029c1c9fd9710eee5..2f00a3c1b7ac20f20f29757c77973b3d3eb908c1 100644 (file)
@@ -145,6 +145,17 @@ public abstract class XMLBasedAjcTestCase extends AjcTestCase {
                digester.addObjectCreate("suite/ajc-test/weave",WeaveSpec.class);
                digester.addSetProperties("suite/ajc-test/weave");
                digester.addSetNext("suite/ajc-test/weave","addTestStep","org.aspectj.testing.ITestStep");
+
+        digester.addObjectCreate("suite/ajc-test/ant",AntSpec.class);
+        digester.addSetProperties("suite/ajc-test/ant");
+        digester.addSetNext("suite/ajc-test/ant","addTestStep","org.aspectj.testing.ITestStep");
+        digester.addObjectCreate("suite/ajc-test/ant/stderr",OutputSpec.class);
+        digester.addSetProperties("suite/ajc-test/ant/stderr");
+        digester.addSetNext("suite/ajc-test/ant/stderr","addStdErrSpec","org.aspectj.testing.OutputSpec");
+        digester.addObjectCreate("suite/ajc-test/ant/stdout",OutputSpec.class);
+        digester.addSetProperties("suite/ajc-test/ant/stdout");
+        digester.addSetNext("suite/ajc-test/ant/stdout","addStdOutSpec","org.aspectj.testing.OutputSpec");
+
                digester.addObjectCreate("suite/ajc-test/run/stderr",OutputSpec.class);
                digester.addSetProperties("suite/ajc-test/run/stderr");
                digester.addSetNext("suite/ajc-test/run/stderr","addStdErrSpec","org.aspectj.testing.OutputSpec");
index ce3bff73a64dd2bf521d5398d72f3050649041b2..71fd636128b967e5ed7cd4053a231899c0db9820 100644 (file)
@@ -224,7 +224,7 @@ public class RunStatus implements IRunStatus {
         * @return true if completed, not aborted, no thrown, no
         * messages of kind ERROR, FAIL or ABORT, and
         * result object is not IRunStatus.FAIL.
-        * @see org.aspectj.testing.harness.newbridge.IRunStatus#runResult()
+        * @see org.aspectj.testing.run.IRunStatus#runResult()
         */
        public boolean runResult() {
                return validator.runPassed(this);
@@ -277,23 +277,27 @@ public class RunStatus implements IRunStatus {
        public boolean isIgnoring(IMessage.Kind kind) {
                return messageHolder.isIgnoring(kind);
        }
-    
+
+    public void dontIgnore(IMessage.Kind kind) {
+        messageHolder.dontIgnore(kind);
+    }
+
     /**
-        * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(Kind, boolean)
+        * @see org.aspectj.bridge.IMessageHolder#hasAnyMessage(org.aspectj.bridge.IMessage.Kind, boolean)
         */
        public boolean hasAnyMessage(IMessage.Kind kind, boolean orGreater) {
         return messageHolder.hasAnyMessage(kind, orGreater);
        }
 
     /**
-        * @see org.aspectj.bridge.IMessageHolder#getMessages(Kind)
+        * @see org.aspectj.bridge.IMessageHolder#getMessages(org.aspectj.bridge.IMessage.Kind, boolean)
         */
        public IMessage[] getMessages(IMessage.Kind kind, boolean orGreater) {
                return messageHolder.getMessages(kind, orGreater);
        }
     
     /**
-        * @see org.aspectj.bridge.IMessageHolder#numMessages(Kind)
+        * @see org.aspectj.bridge.IMessageHolder#numMessages(org.aspectj.bridge.IMessage.Kind, boolean)
         */
        public int numMessages(IMessage.Kind kind, boolean orGreater) {
                return messageHolder.numMessages(kind, orGreater);
diff --git a/tests/java5/ataspectj/ajc-ant.xml b/tests/java5/ataspectj/ajc-ant.xml
new file mode 100644 (file)
index 0000000..4aaf76d
--- /dev/null
@@ -0,0 +1,20 @@
+<!-- ajc-ant script, not to be used from Ant commant line - see AntSpec -->
+<project name="foo" default="all">
+
+    <target name="compile:javac">
+        <!-- compile only javac compilable stuff -->
+        <javac destdir="${aj.sandbox}" classpathref="aj.path"
+            srcdir="${basedir}"
+            includes="ataspectj/*"
+            debug="true">
+        </javac>
+    </target>
+
+    <target name="all" depends="compile:javac">
+        <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>
+</project>
\ No newline at end of file
diff --git a/tests/java5/ataspectj/ataspectj/AllLTWTests.java b/tests/java5/ataspectj/ataspectj/AllLTWTests.java
new file mode 100644 (file)
index 0000000..eddd0cd
--- /dev/null
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2005 Contributors.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ *   Alexandre Vasseur         initial implementation
+ *******************************************************************************/
+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>
+ */
+public class AllLTWTests extends TestCase {
+
+    public static Test suite() {
+        TestSuite suite = new TestSuite("All tests");
+
+        suite.addTestSuite(ataspectj.SingletonAspectBindingsTest.class);
+        suite.addTestSuite(ataspectj.CflowTest.class);
+        suite.addTestSuite(ataspectj.PointcutReferenceTest.class);
+        suite.addTestSuite(ataspectj.AfterXTest.class);
+        //FIXME AV - fix the pc grammar to support if for @AJ aspects
+        System.err.println("(AllTests: IfPointcutTest fails)");
+        //suite.addTestSuite(IfPointcutTest.class);
+        suite.addTestSuite(ataspectj.XXJoinPointTest.class);
+        suite.addTestSuite(ataspectj.PrecedenceTest.class);
+        suite.addTestSuite(ataspectj.BindingTest.class);
+        suite.addTestSuite(ataspectj.PerClauseTest.class);
+        suite.addTestSuite(AroundInlineMungerTest.class);
+
+        return suite;
+    }
+
+    public static void main(String[] args) {
+        TestHelper.runAndThrowOnFailure(suite());
+    }
+
+}
index 342b8ebf06d78d32d57cc36c45efd0a0d95a7b6f..62e1dfe136ecfbf51245f828759571baa36921e0 100644 (file)
@@ -82,12 +82,12 @@ public class BindingTest extends TestCase {
     }
 
     public void testAccessAspectState() {
-        //TestAspect_1 aspect = (TestAspect_1) Aspects.aspectOf(TestAspect_1.class);
-        //aspect.m_count = 0;
+        TestAspect_1 aspect = (TestAspect_1) Aspects.aspectOf(TestAspect_1.class);
+        aspect.m_count = 0;
         int res = echo(3);
         res += echo(3);
         assertEquals(6, res);
-        //assertEquals(2, aspect.m_count);
+        assertEquals(2, aspect.m_count);
     }
 
     public void testTryCatch() {
@@ -181,7 +181,7 @@ public class BindingTest extends TestCase {
 
         @Around("call(int echo(int)) && withincode(void ataspectj.BindingTest.testAccessAspectState()) && args(i)")
         public Object aaround7(int i, final ProceedingJoinPoint jp) throws Throwable {
-            //m_count++;// what if inlined ?//FIXME
+            m_count++;// will be wrapped for inlining support
             return jp.proceed();
         }
 
diff --git a/tests/java5/ataspectj/ataspectj/aop.xml b/tests/java5/ataspectj/ataspectj/aop.xml
new file mode 100644 (file)
index 0000000..d76592f
--- /dev/null
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<aspectj>
+    <aspects>
+        <!-- see here nested class with ".", "$" is accepted as well -->
+        <aspect name="ataspectj.SingletonAspectBindingsTest.TestAspect"/>
+        <aspect name="ataspectj.CflowTest.TestAspect"/>
+        <aspect name="ataspectj.PointcutReferenceTest.TestAspect"/>
+        <aspect name="ataspectj.AfterXTest.TestAspect"/>
+<!--        <aspect name="ataspectj.IfPointcutTest.TestAspect"/>-->
+        <aspect name="ataspectj.XXJoinPointTest.TestAspect"/>
+        <aspect name="ataspectj.PrecedenceTest.TestAspect_2"/>
+        <aspect name="ataspectj.PrecedenceTest.TestAspect_1"/>
+        <aspect name="ataspectj.PrecedenceTest.TestAspect_3"/>
+        <aspect name="ataspectj.PrecedenceTest.TestAspect_Order"/>
+
+        <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.AroundInlineMungerTest.Open"/>
+    </aspects>
+</aspectj>
index eab2949e5e409fadcf04ab3c6fae931baed0feb8..89981e4fa196e255098966c7d705a55521ee37d5 100644 (file)
@@ -93,4 +93,8 @@
         <compile files="ataspectj/AroundInlineMungerTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore"/>
         <run class="ataspectj.AroundInlineMungerTest"/>
     </ajc-test>
+
+    <ajc-test dir="java5/ataspectj" title="RunThemAllWithJavacCompiledAndLTW">
+        <ant file="ajc-ant.xml" target="all"/>
+    </ajc-test>
 </suite>
\ No newline at end of file
index 93c49f0f0211afb9496bcf80b5432457ddab7c78..d0936c2146e63b08c8e5ef7e266f40cc2189ec84 100644 (file)
@@ -458,17 +458,16 @@ public abstract class Shadow {
                else if (ak.getKey()==AdviceKind.Around.getKey())
                                return IRelationship.Kind.ADVICE_AROUND;
                else if (ak.getKey()==AdviceKind.CflowEntry.getKey() ||
-               ak.getKey()==AdviceKind.CflowBelowEntry.getKey() ||
-               ak.getKey()==AdviceKind.InterInitializer.getKey() ||
-               ak.getKey()==AdviceKind.PerCflowEntry.getKey() ||
-               ak.getKey()==AdviceKind.PerCflowBelowEntry.getKey() ||
-               ak.getKey()==AdviceKind.PerThisEntry.getKey() ||
-               ak.getKey()==AdviceKind.PerTargetEntry.getKey() ||
-               ak.getKey()==AdviceKind.Softener.getKey() ||
-        ak.getKey()==AdviceKind.PerTypeWithinEntry.getKey()) {
-        //FIXME: Alex: why this System.err was there ?? It prints nasty thing in my LTW.
-          System.err.println("Dont want a message about this: "+ak);
-                         return null;
+                ak.getKey()==AdviceKind.CflowBelowEntry.getKey() ||
+                ak.getKey()==AdviceKind.InterInitializer.getKey() ||
+                ak.getKey()==AdviceKind.PerCflowEntry.getKey() ||
+                ak.getKey()==AdviceKind.PerCflowBelowEntry.getKey() ||
+                ak.getKey()==AdviceKind.PerThisEntry.getKey() ||
+                ak.getKey()==AdviceKind.PerTargetEntry.getKey() ||
+                ak.getKey()==AdviceKind.Softener.getKey() ||
+                ak.getKey()==AdviceKind.PerTypeWithinEntry.getKey()) {
+            //System.err.println("Dont want a message about this: "+ak);
+            return null;
                }
                throw new RuntimeException("Shadow.determineRelKind: What the hell is it? "+ak);
        }
index 290e32f615988c45dc7a9196de5ea2d17bfa2923..a9502994a959c196801719a28cbab6609b5a2da2 100644 (file)
@@ -425,7 +425,12 @@ public class Aj5Attributes {
             ElementNameValuePair beforeAdvice = getAnnotationElement(before, "value");
             if (beforeAdvice != null) {
                 // this/target/args binding
-                FormalBinding[] bindings = extractBindings(struct);
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                try {
+                    bindings = extractBindings(struct);
+                } catch (UnreadableDebugInfo unreadableDebugInfo) {
+                    return false;
+                }
                 IScope binding = new BindingScope(
                         struct.enclosingType,
                         bindings
@@ -470,7 +475,12 @@ public class Aj5Attributes {
             ElementNameValuePair afterAdvice = getAnnotationElement(after, "value");
             if (afterAdvice != null) {
                 // this/target/args binding
-                FormalBinding[] bindings = extractBindings(struct);
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                try {
+                    bindings = extractBindings(struct);
+                } catch (UnreadableDebugInfo unreadableDebugInfo) {
+                    return false;
+                }
                 IScope binding = new BindingScope(
                         struct.enclosingType,
                         bindings
@@ -538,7 +548,12 @@ public class Aj5Attributes {
 
             // this/target/args binding
             // exclude the return binding from the pointcut binding since it is an extraArg binding
-            FormalBinding[] bindings = (returned==null?extractBindings(struct):extractBindings(struct, returned));
+            FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+            try {
+                bindings = (returned==null?extractBindings(struct):extractBindings(struct, returned));
+            } catch (UnreadableDebugInfo unreadableDebugInfo) {
+                return false;
+            }
             IScope binding = new BindingScope(
                     struct.enclosingType,
                     bindings
@@ -611,7 +626,12 @@ public class Aj5Attributes {
 
             // this/target/args binding
             // exclude the throwned binding from the pointcut binding since it is an extraArg binding
-            FormalBinding[] bindings = (throwned==null?extractBindings(struct):extractBindings(struct, throwned));
+            FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+            try {
+                bindings = (throwned==null?extractBindings(struct):extractBindings(struct, throwned));
+            } catch (UnreadableDebugInfo unreadableDebugInfo) {
+                return false;
+            }
             IScope binding = new BindingScope(
                     struct.enclosingType,
                     bindings
@@ -660,7 +680,12 @@ public class Aj5Attributes {
             ElementNameValuePair aroundAdvice = getAnnotationElement(around, "value");
             if (aroundAdvice != null) {
                 // this/target/args binding
-                FormalBinding[] bindings = extractBindings(struct);
+                FormalBinding[] bindings = new org.aspectj.weaver.patterns.FormalBinding[0];
+                try {
+                    bindings = extractBindings(struct);
+                } catch (UnreadableDebugInfo unreadableDebugInfo) {
+                    return false;
+                }
                 IScope binding = new BindingScope(
                         struct.enclosingType,
                         bindings
@@ -732,10 +757,15 @@ public class Aj5Attributes {
                 }
 
                 // this/target/args binding
-                IScope binding = new BindingScope(
-                        struct.enclosingType,
-                        extractBindings(struct)
-                );
+                final IScope binding;
+                try {
+                    binding = new BindingScope(
+                            struct.enclosingType,
+                            extractBindings(struct)
+                    );
+                } catch(UnreadableDebugInfo e) {
+                    return;
+                }
 
                 TypeX[] argumentTypes = new TypeX[struct.method.getArgumentTypes().length];
                 for (int i = 0; i < argumentTypes.length; i++) {
@@ -788,15 +818,25 @@ public class Aj5Attributes {
      * Build the bindings for a given method (pointcut / advice)
      *
      * @param struct
-     * @return
+     * @return null if no debug info is available
      */
-    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct) {
+    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct)
+    throws UnreadableDebugInfo {
         Method method = struct.method;
         String[] argumentNames = struct.getArgumentNames();
 
         // assert debug info was here
         if (argumentNames.length != method.getArgumentTypes().length) {
-            throw new RuntimeException("cannot access debug info " + method);
+            struct.handler.handleMessage(
+                    new Message(
+                            "Cannot read debug info for @Aspect '" + struct.enclosingType.getName() + "'"
+                            + " (please compile with 'javac -g' or '<javac debug='true'.../>' in Ant)",
+                            IMessage.FAIL,
+                            null,
+                            struct.enclosingType.getSourceLocation()
+                    )
+            );
+            throw new UnreadableDebugInfo();
         }
 
         List bindings = new ArrayList();
@@ -823,7 +863,8 @@ public class Aj5Attributes {
     }
 
     //FIXME alex deal with exclude index
-    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct, String excludeFormal) {
+    private static FormalBinding[] extractBindings(AjAttributeMethodStruct struct, String excludeFormal)
+    throws UnreadableDebugInfo {
         FormalBinding[] bindings = extractBindings(struct);
         int excludeIndex = -1;
         for (int i = 0; i < bindings.length; i++) {
@@ -1056,4 +1097,10 @@ public class Aj5Attributes {
         }
         pointcut.m_ignoreUnboundBindingForNames = (String[])ignores.toArray(new String[ignores.size()]);
     }
+
+    /**
+     * A check exception when we cannot read debug info (needed for formal binding)
+     */
+    private static class UnreadableDebugInfo extends Exception {
+    }
 }
index 813cf82324a0d28ce273f898b03d2173f1593121..e25beb343a439fd718aed2e27e2217bc9095740c 100644 (file)
@@ -150,11 +150,17 @@ public class BcelAdvice extends Advice {
         } else if (getKind() == AdviceKind.After) {   
             shadow.weaveAfter(this);
         } else if (getKind() == AdviceKind.Around) {
+            // Note: under regular LTW the aspect is usually loaded after the first use of any class affecteted by it
+            // This means that as long as the aspect has not been thru the LTW, it's woven state is unknown
+            // and thus canInline(s) will return false.
+            // To force inlining (test), ones can do Class aspect = FQNAspect.class in the clinit of the target class
+            // FIXME AV : for AJC compiled @AJ aspect (or any code style aspect), the woven state can never be known
+            // if the aspect belongs to a parent classloader. In that case the aspect will never be inlined.
+            // It might be dangerous to change that especially for @AJ aspect non compiled with AJC since if those
+            // are not weaved (f.e. use of some limiteed LTW etc) then they cannot be prepared for inlining.
+            // One solution would be to flag @AJ aspect with an annotation as "prepared" and query that one.
                if (!canInline(s)) {
                        shadow.weaveAroundClosure(this, hasDynamicTests());
-                //FIXME : check Inlining and LTW
-                //ALEX : uncomment to force inlining for LTW - else inlining does not seems to happen.
-                //shadow.weaveAroundInline(this, hasDynamicTests());
                } else {
                shadow.weaveAroundInline(this, hasDynamicTests());
                }
@@ -231,7 +237,7 @@ public class BcelAdvice extends Advice {
      */
     public boolean mustCheckExceptions() {
         if (getConcreteAspect() == null) {
-            //FIXME Alex: not sure this is good to default to that.
+            //FIXME AV: not sure this is good to default to that.
             // dig when do we reach that ie not yet concretized
             return true;
         }
@@ -357,7 +363,7 @@ public class BcelAdvice extends Advice {
                                fact,
                                getExtraParameterType().resolve(world));
                        } else {
-                        //FIXME this code  will throw an error if ProceedingJP is used in a before advice f.e. ok ??
+                        //FIXME AV test for that - this code  will throw an error if ProceedingJP is used in a before advice f.e. ok ??
                         throw new Error("Should not happen - unbound advice argument at index " + i + " in [" +
                                 toString() + "]");
                        }
index 0442d8c6856a8fa2d85911e140a790b663952980..762bc52aed03678deff6746481c2a63d9f3ff0c3 100644 (file)
@@ -1942,14 +1942,10 @@ public class BcelShadow extends Shadow {
 
         // specific test for @AJ proceedInInners
         if (munger.getConcreteAspect().isAnnotationStyleAspect()) {
-            //FIXME
             // if we can't find one proceed()
             // we suspect that the call is happening in an inner class
             // so we don't inline it.
             // Note: for code style, this is done at Aspect compilation time.
-            // Limitation: if there is two calls and one is done in an inner class, inlining will happen
-            // since we will see the non proceed in inner one as if it was the sole one.
-            // The one made in the inner class will never be madeXXX. Should be documented.
             boolean canSeeProceedPassedToOther = false;
             InstructionHandle curr = adviceMethod.getBody().getStart();
             InstructionHandle end = adviceMethod.getBody().getEnd();
@@ -1957,11 +1953,7 @@ public class BcelShadow extends Shadow {
             while (curr != end) {
                 InstructionHandle next = curr.getNext();
                 Instruction inst = curr.getInstruction();
-                /*if ((inst instanceof INVOKEINTERFACE)
-                    && "proceed".equals(((INVOKEINTERFACE) inst).getMethodName(cpg))) {
-                    canSeeProceed = true;
-                    //continue since we may have a proceed in inner or pjp as arg
-                } else*/ if ((inst instanceof InvokeInstruction)
+                if ((inst instanceof InvokeInstruction)
                     && ((InvokeInstruction)inst).getSignature(cpg).indexOf("Lorg/aspectj/lang/ProceedingJoinPoint;") > 0) {
                     // we may want to refine to exclude stuff returning jp ?
                     // does code style skip inline if i write dump(thisJoinPoint) ?
index 5a62d9fc7877da1b22e8fb7358e5abbbe7766734..65db2076931c3831dfffd7c301192d438e0f80bc 100644 (file)
@@ -88,7 +88,7 @@ public final class LazyMethodGen {
     private  Attribute[]     attributes;
    // private AnnotationGen[]  annotations;
     /* private */ final LazyClassGen    enclosingClass;   
-    private final BcelMethod      memberView;
+    private /*final*/ BcelMethod      memberView;//FIXME AV LTW
     int highestLineNumber = 0;
 
        /** This is nonnull if this method is the result of an "inlining".  We currently
@@ -194,8 +194,10 @@ public final class LazyMethodGen {
        public boolean hasAnnotation(TypeX annotationTypeX) {
                initialize();
                if (memberView==null) {
-                       System.err.println("REPORT THIS! 02: Can't determine if "+this+" has annotation "+annotationTypeX);
-                       return false;
+            memberView = new BcelMethod(getEnclosingClass().getBcelObjectType(), getMethod());//FIXME AV LTW
+                       //System.err.println("REPORT THIS! 02: Can't determine if "+getEnclosingClass().getName() + "." + this.getName() + this.getSignature()+" has annotation "+annotationTypeX);
+                       //return false
+            return memberView.hasAnnotation(annotationTypeX);
                }
                return memberView.hasAnnotation(annotationTypeX);
        }
index a24008f7c48d5f8dcce59ff99cd3a1e23d922636..a1bf961cd5322987d4e6af2b2444d969b820bec4 100644 (file)
@@ -174,6 +174,7 @@ public class WeavingAdaptor {
         */
        public byte[] weaveClass (String name, byte[] bytes) throws IOException {
                if (shouldWeave(name)) {
+            System.out.println("WeavingAdaptor.weaveClass " + name);
                        info("weaving '" + name + "'");
                        bytes = getWovenBytes(name, bytes);
                }
@@ -192,7 +193,11 @@ public class WeavingAdaptor {
     }
 
        private boolean shouldWeaveName (String name) {
-               return !((name.startsWith("org.apache.bcel.") || name.startsWith("org.aspectj.") || name.startsWith("java.") || name.startsWith("javax.")));
+               return !((name.startsWith("org.apache.bcel.")//FIXME AV why ? bcel is wrapped in org.aspectj.
+                || name.startsWith("org.aspectj.")
+                || name.startsWith("java.")
+                || name.startsWith("javax."))
+                || name.startsWith("$Proxy"));//JDK proxies
        }
 
     /**
@@ -213,7 +218,6 @@ public class WeavingAdaptor {
         * @param bytes the bytes that define the class
         * @return byte[] the woven bytes for the class
         * @throws IOException
-        * @throws FileNotFoundException
         */
        private byte[] getWovenBytes(String name, byte[] bytes) throws IOException {
                WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
index e9173723d722d8ab29f9ed7415383e5b38b56bd1..35c191bbbc2693b88dc9f7ab827649979b9fd53b 100644 (file)
@@ -113,6 +113,7 @@ public class AnnotationPatternMatchingTestCase extends TestCase {
                        return false;
                }
                public boolean isIgnoring(Kind kind) {return false;}
+        public void dontIgnore(IMessage.Kind kind) {;}
        }
        
        public void testReferenceToNonAnnotationType() {