]> source.dussan.org Git - aspectj.git/commitdiff
enabling AJDT to use annotation processors
authorAndy Clement <aclement@gopivotal.com>
Wed, 20 Aug 2014 15:00:10 +0000 (08:00 -0700)
committerAndy Clement <aclement@gopivotal.com>
Wed, 20 Aug 2014 15:00:10 +0000 (08:00 -0700)
22 files changed:
ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java
ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java
ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java
ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java
ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java
testing/src/org/aspectj/testing/ajde/CompileCommand.java
tests/multiIncremental/ProcessorConsumer1/base/src/Code.java [new file with mode: 0644]
tests/multiIncremental/ProcessorConsumer2/base/src/Code.java [new file with mode: 0644]
tests/multiIncremental/ProcessorProject/base/src/DemoProcessor.java [new file with mode: 0644]
tests/multiIncremental/ProcessorProject2/base/src/DemoProcessor.java [new file with mode: 0644]
tests/multiIncremental/ProcessorProject2/base/src/META-INF/services/javax.annotation.processing.Processor [new file with mode: 0644]
tests/multiIncremental/ProcessorProject2/base/src/proc.jar [new file with mode: 0644]
tests/multiIncremental/ProcessorProject3/base/src/DemoProcessor2.java [new file with mode: 0644]
tests/multiIncremental/ProcessorProject3/base/src/META-INF/services/javax.annotation.processing.Processor [new file with mode: 0644]
tests/src/org/aspectj/systemtest/AllTests16.java
tests/src/org/aspectj/systemtest/incremental/tools/AbstractMultiProjectIncrementalAjdeInteractionTestbed.java
tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java
tests/src/org/aspectj/systemtest/incremental/tools/AnnotationProcessingTests.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java
tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java

index 974705c3e7d0f5887e519b2f12c7fdbc04dcd20f..403ebb73116064f9e396a71e69b2707693947610 100644 (file)
@@ -116,4 +116,12 @@ public class BrowserCompilerConfiguration implements ICompilerConfiguration {
                return null;
        }
 
+       public String getProcessor() {
+               return null;
+       }
+
+       public String getProcessorPath() {
+               return null;
+       }
+
 }
index aa389f052ed43231c33ce8c70b3a0c0b5fdeaa0e..b9684aa09a8c72c9b94e845287474b67e284f3cf 100644 (file)
@@ -135,4 +135,14 @@ public interface ICompilerConfiguration extends CompilerConfigurationChangeFlags
         */
        public String getProjectEncoding();
 
+       /**
+        * @return the list of processor classes to execute
+        */
+       public String getProcessor();
+       
+       /**
+        * @return the processor path where the specified processor(s) can be found
+        */
+       public String getProcessorPath();
+
 }
index 267ac9329db7344df7e6cd73bb9c79a381821907..531e9b01d2edd42383abd694a62251a0a60626ba 100644 (file)
@@ -226,6 +226,17 @@ public class AjdeCoreBuildManager {
                        if (l == null) {
                                return null;
                        }
+                       // If the processor options are specified build the command line options for the JDT compiler to see
+                       String processor = compilerConfig.getProcessor();
+                       if (processor != null && processor.length() != 0) {
+                               l.add("-processor");
+                               l.add(processor);
+                       }
+                       String processorPath = compilerConfig.getProcessorPath();
+                       if (processorPath != null && processorPath.length() != 0) {
+                               l.add("-processorpath");
+                               l.add(processorPath);
+                       }
                        List<String> xmlfiles = compilerConfig.getProjectXmlConfigFiles();
                        if (xmlfiles != null && !xmlfiles.isEmpty()) {
                                args = new String[l.size() + xmlfiles.size() + 1];
@@ -331,6 +342,8 @@ public class AjdeCoreBuildManager {
                config.setProceedOnError(true);
 
                config.setProjectEncoding(compilerConfig.getProjectEncoding());
+               config.setProcessor(compilerConfig.getProcessor());
+               config.setProcessorPath(compilerConfig.getProcessorPath());
                return config;
        }
 
index 921591c97f89b5ce6aaf26db9e9dd40fac108b1c..1070da969282e9b0fa79ebb90afb1912a3e7eef7 100644 (file)
@@ -171,4 +171,12 @@ public class TestCompilerConfiguration implements ICompilerConfiguration {
                return null;
        }
 
+       public String getProcessor() {
+               return null;
+       }
+
+       public String getProcessorPath() {
+               return null;
+       }
+
 }
index c76a388c294acee3dadc778ed56178f3cc4e7adf..2e5520a4571b75d40a24ba8a0461760bf955ab24 100644 (file)
@@ -174,4 +174,14 @@ public class TestCompilerConfiguration implements ICompilerConfiguration {
                return null;
        }
 
+       public String getProcessor() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       public String getProcessorPath() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
 }
index e99cac6c0a52bf4368268842c5b8a369eb6da727..98bd0484e1b6ad87dad6544fd3aa54a66f77588d 100644 (file)
@@ -1,5 +1,5 @@
 /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ * Copyright (c) 2002 - 2014 Contributors
  * All rights reserved. 
  * This program and the accompanying materials are made available 
  * under the terms of the Eclipse Public License v1.0 
@@ -11,6 +11,7 @@
  *     Adrian Colyer  added constructor to populate javaOptions with
  *                                       default settings - 01.20.2003
  *                                       Bugzilla #29768, 29769
+ *      Andy Clement 
  * ******************************************************************/
 
 package org.aspectj.ajdt.internal.core.builder;
@@ -24,8 +25,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.StringTokenizer;
-import org.aspectj.ajdt.ajc.BuildArgParser;
 
+import org.aspectj.ajdt.ajc.BuildArgParser;
 import org.aspectj.ajdt.internal.compiler.CompilationResultDestinationManager;
 import org.aspectj.util.FileUtil;
 
@@ -50,6 +51,8 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
        private List<File> changedFiles;
        private List<File> files = new ArrayList<File>();
        private List<File> xmlfiles = new ArrayList<File>();
+       private String processor;
+       private String processorPath;
        private List<BinarySourceFile> binaryFiles = new ArrayList<BinarySourceFile>(); // .class files in indirs...
        private List<File> inJars = new ArrayList<File>();
        private List<File> inPath = new ArrayList<File>();
@@ -134,6 +137,28 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags {
        public List<File> getXmlFiles() {
                return xmlfiles;
        }
+       
+       public void setProcessor(String processor) {
+               this.processor = processor;
+       }
+       
+       /**
+        * @return the list of processor classes to execute
+        */
+       public String getProcessor() {
+               return this.processor;
+       }
+       
+       public void setProcessorPath(String processorPath) {
+               this.processorPath = processorPath;
+       }
+       
+       /**
+        * @return the processor path which can be searched for processors (via META-INF/services)
+        */
+       public String getProcessorPath() {
+               return this.processorPath;
+       }
 
        /**
         * returned files includes all .class files found in a directory on the inpath, but does not include .class files contained
index 59ade0ae0ab0f70cb6dec17a9a3bf5eedb8b3891..7e3ef5ecdaa644699329d7002aba8a1d102cc9db 100644 (file)
@@ -26,6 +26,7 @@ public interface CompilerConfigurationChangeFlags {
        int OUTPUTDESTINATIONS_CHANGED = 0x0100;
        int INJARS_CHANGED = 0x0200; // deprecated, not in use any more
        int XMLCONFIG_CHANGED = 0x0400;
+       int PROCESSOR_CHANGED = 0x0800;
        int EVERYTHING = 0xffff;
 
 }
index 2f819db44b597d39b81fac937b1b20617aeff57c..2fd748ff2798da9a85b495117aaaaa3fcdc30b62 100644 (file)
@@ -370,6 +370,14 @@ class MyCompilerConfig implements ICompilerConfiguration {
                return null;
        }
 
+       public String getProcessor() {
+               return null;
+       }
+
+       public String getProcessorPath() {
+               return null;
+       }
+
 }
 
 class MyOutputLocationManager implements IOutputLocationManager {
diff --git a/tests/multiIncremental/ProcessorConsumer1/base/src/Code.java b/tests/multiIncremental/ProcessorConsumer1/base/src/Code.java
new file mode 100644 (file)
index 0000000..72efafc
--- /dev/null
@@ -0,0 +1,26 @@
+public class Code {
+  public static void main(String []argv) {
+    new Code().run();
+  }
+
+  public static void runner() {
+    new Code().run();
+  }
+
+  public void run() {
+    aaa();
+    bbb();
+    ccc();
+    ddd();
+  }
+
+  @SuppressWarnings("rawtypes")
+  public void aaa() {}
+
+  public void bbb() {}
+
+  @SuppressWarnings("rawtypes")
+  public void ccc() {}
+
+  public void ddd() {}
+}
diff --git a/tests/multiIncremental/ProcessorConsumer2/base/src/Code.java b/tests/multiIncremental/ProcessorConsumer2/base/src/Code.java
new file mode 100644 (file)
index 0000000..72efafc
--- /dev/null
@@ -0,0 +1,26 @@
+public class Code {
+  public static void main(String []argv) {
+    new Code().run();
+  }
+
+  public static void runner() {
+    new Code().run();
+  }
+
+  public void run() {
+    aaa();
+    bbb();
+    ccc();
+    ddd();
+  }
+
+  @SuppressWarnings("rawtypes")
+  public void aaa() {}
+
+  public void bbb() {}
+
+  @SuppressWarnings("rawtypes")
+  public void ccc() {}
+
+  public void ddd() {}
+}
diff --git a/tests/multiIncremental/ProcessorProject/base/src/DemoProcessor.java b/tests/multiIncremental/ProcessorProject/base/src/DemoProcessor.java
new file mode 100644 (file)
index 0000000..05ff201
--- /dev/null
@@ -0,0 +1,47 @@
+import java.io.*;
+import javax.tools.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+
+@SupportedAnnotationTypes(value= {"*"})
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class DemoProcessor extends AbstractProcessor { 
+
+       private Filer filer;
+
+       @Override
+       public void init(ProcessingEnvironment env) {
+               filer = env.getFiler();
+       }
+
+       @Override
+       public boolean process(Set elements, RoundEnvironment env) {
+System.out.println("Processor running");
+               // Discover anything marked with @SuppressWarnings
+               for (Element element: env.getElementsAnnotatedWith(SuppressWarnings.class)) {
+                       if (element.getKind() == ElementKind.METHOD) {
+                               // For any methods we find, create an aspect:
+                               String methodName = element.getSimpleName().toString();
+                               String aspectText = 
+                                               "public aspect Advise_"+methodName+" {\n"+
+                                               "  before(): execution(* "+methodName+"(..)) {\n"+
+                                               "    System.out.println(\""+methodName+" running\");\n"+
+                                               "  }\n"+
+                                               "}\n";
+                               try {
+                                       JavaFileObject file = filer.createSourceFile("Advise_"+methodName, element);
+                                       file.openWriter().append(aspectText).close();
+                                       System.out.println("Generated aspect to advise "+element.getSimpleName());
+                               } catch (IOException ioe) {
+                                       // already creates message can appear if processor runs more than once
+                                       if (!ioe.getMessage().contains("already created")) {
+                                               ioe.printStackTrace();
+                                       }
+                               }
+                       }
+               }
+               return true;
+       }
+}
diff --git a/tests/multiIncremental/ProcessorProject2/base/src/DemoProcessor.java b/tests/multiIncremental/ProcessorProject2/base/src/DemoProcessor.java
new file mode 100644 (file)
index 0000000..05ff201
--- /dev/null
@@ -0,0 +1,47 @@
+import java.io.*;
+import javax.tools.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+
+@SupportedAnnotationTypes(value= {"*"})
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class DemoProcessor extends AbstractProcessor { 
+
+       private Filer filer;
+
+       @Override
+       public void init(ProcessingEnvironment env) {
+               filer = env.getFiler();
+       }
+
+       @Override
+       public boolean process(Set elements, RoundEnvironment env) {
+System.out.println("Processor running");
+               // Discover anything marked with @SuppressWarnings
+               for (Element element: env.getElementsAnnotatedWith(SuppressWarnings.class)) {
+                       if (element.getKind() == ElementKind.METHOD) {
+                               // For any methods we find, create an aspect:
+                               String methodName = element.getSimpleName().toString();
+                               String aspectText = 
+                                               "public aspect Advise_"+methodName+" {\n"+
+                                               "  before(): execution(* "+methodName+"(..)) {\n"+
+                                               "    System.out.println(\""+methodName+" running\");\n"+
+                                               "  }\n"+
+                                               "}\n";
+                               try {
+                                       JavaFileObject file = filer.createSourceFile("Advise_"+methodName, element);
+                                       file.openWriter().append(aspectText).close();
+                                       System.out.println("Generated aspect to advise "+element.getSimpleName());
+                               } catch (IOException ioe) {
+                                       // already creates message can appear if processor runs more than once
+                                       if (!ioe.getMessage().contains("already created")) {
+                                               ioe.printStackTrace();
+                                       }
+                               }
+                       }
+               }
+               return true;
+       }
+}
diff --git a/tests/multiIncremental/ProcessorProject2/base/src/META-INF/services/javax.annotation.processing.Processor b/tests/multiIncremental/ProcessorProject2/base/src/META-INF/services/javax.annotation.processing.Processor
new file mode 100644 (file)
index 0000000..3c594a8
--- /dev/null
@@ -0,0 +1 @@
+DemoProcessor
diff --git a/tests/multiIncremental/ProcessorProject2/base/src/proc.jar b/tests/multiIncremental/ProcessorProject2/base/src/proc.jar
new file mode 100644 (file)
index 0000000..be2dd1e
Binary files /dev/null and b/tests/multiIncremental/ProcessorProject2/base/src/proc.jar differ
diff --git a/tests/multiIncremental/ProcessorProject3/base/src/DemoProcessor2.java b/tests/multiIncremental/ProcessorProject3/base/src/DemoProcessor2.java
new file mode 100644 (file)
index 0000000..e55e665
--- /dev/null
@@ -0,0 +1,47 @@
+import java.io.*;
+import javax.tools.*;
+import java.util.*;
+import javax.annotation.processing.*;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+
+@SupportedAnnotationTypes(value= {"java.lang.SuppressWarnings"})
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class DemoProcessor2 extends AbstractProcessor { 
+
+       private Filer filer;
+
+       @Override
+       public void init(ProcessingEnvironment env) {
+               filer = env.getFiler();
+       }
+
+       @Override
+       public boolean process(Set elements, RoundEnvironment env) {
+System.out.println("Processor (around) running");
+               // Discover anything marked with @SuppressWarnings
+               for (Element element: env.getElementsAnnotatedWith(SuppressWarnings.class)) {
+                       if (element.getKind() == ElementKind.METHOD) {
+                               // For any methods we find, create an aspect:
+                               String methodName = element.getSimpleName().toString();
+                               String aspectText = 
+                                               "public aspect AroundAdvise_"+methodName+" {\n"+
+                                               "  void around(): execution(* "+methodName+"(..)) {\n"+
+                                               "    System.out.println(\"Around advice on "+methodName+" running\");\n"+
+                                               "  }\n"+
+                                               "}\n";
+                               try {
+                                       JavaFileObject file = filer.createSourceFile("AroundAdvise_"+methodName, element);
+                                       file.openWriter().append(aspectText).close();
+                                       System.out.println("Generated aspect with around advice to advise "+element.getSimpleName());
+                               } catch (IOException ioe) {
+                                       // already creates message can appear if processor runs more than once
+                                       if (!ioe.getMessage().contains("already created")) {
+                                               ioe.printStackTrace();
+                                       }
+                               }
+                       }
+               }
+               return false;
+       }
+}
diff --git a/tests/multiIncremental/ProcessorProject3/base/src/META-INF/services/javax.annotation.processing.Processor b/tests/multiIncremental/ProcessorProject3/base/src/META-INF/services/javax.annotation.processing.Processor
new file mode 100644 (file)
index 0000000..62e145e
--- /dev/null
@@ -0,0 +1 @@
+DemoProcessor2
index 66e0d0bf39d99bda91324cbbac234e00a22fd7c4..f1f7b4a145ca0e4556cea543f9c508989e8d9681 100644 (file)
@@ -18,6 +18,7 @@ import org.aspectj.systemtest.ajc165.AllTestsAspectJ165;
 import org.aspectj.systemtest.ajc166.AllTestsAspectJ166;
 import org.aspectj.systemtest.ajc167.AllTestsAspectJ167;
 import org.aspectj.systemtest.ajc169.AllTestsAspectJ169;
+import org.aspectj.systemtest.incremental.tools.AnnotationProcessingTests;
 
 public class AllTests16 {
 
@@ -37,6 +38,7 @@ public class AllTests16 {
                suite.addTest(AllTestsAspectJ1610.suite());
                suite.addTest(AllTestsAspectJ1611.suite());
                suite.addTest(AllTestsAspectJ1612.suite());
+               suite.addTestSuite(AnnotationProcessingTests.class);
                // $JUnit-END$
                return suite;
        }
index 10c108067248e5d604416a77e521cbfe42201c29..229a22a5db8a59564eb666cdf7971724e3535f07 100644 (file)
 package org.aspectj.systemtest.incremental.tools;
 
 import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.PrintStream;
 import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -78,6 +82,26 @@ public class AbstractMultiProjectIncrementalAjdeInteractionTestbed extends AjdeI
                AjState.FORCE_INCREMENTAL_DURING_TESTING = false;
        }
 
+       protected String runMethod(String projectName, String classname, String methodname) throws Exception {
+               File f = getProjectOutputRelativePath(projectName, "");
+               ClassLoader cl = new URLClassLoader(new URL[] { f.toURI().toURL() });
+               Class<?> clazz = Class.forName(classname, false, cl);
+               ByteArrayOutputStream baos = new ByteArrayOutputStream();
+               PrintStream realOut = System.out;
+               try {
+                       System.setOut(new PrintStream(baos));
+                       clazz.getDeclaredMethod(methodname).invoke(null);
+               } finally {
+                       System.setOut(realOut);
+               }
+               return new String(baos.toByteArray());
+       }
+
+       protected File getProjectOutputRelativePath(String p, String filename) {
+               File projDir = new File(getWorkingDir(), p);
+               return new File(projDir, "bin" + File.separator + filename);
+       }
+       
        public void build(String projectName) {
                constructUpToDateLstFile(projectName, "build.lst");
                doBuild(projectName);
index b063fc5ef58707b0bf9055b1ff30059bc129f6bd..14e880a0a92a47e3cd5431d91cf930d4efa49546 100644 (file)
@@ -104,6 +104,16 @@ public class AjdeInteractionTestbed extends TestCase {
                ((MultiProjTestCompilerConfiguration) compiler.getCompilerConfiguration()).setAspectPath(aspectpath);
        }
 
+       public void configureProcessor(String projectName, String processor) {
+               AjCompiler compiler = CompilerFactory.getCompilerForProjectWithDir(sandboxDir + File.separator + projectName);
+               ((MultiProjTestCompilerConfiguration) compiler.getCompilerConfiguration()).setProcessor(processor);
+       }
+
+       public void configureProcessorPath(String projectName, String processorPath) {
+               AjCompiler compiler = CompilerFactory.getCompilerForProjectWithDir(sandboxDir + File.separator + projectName);
+               ((MultiProjTestCompilerConfiguration) compiler.getCompilerConfiguration()).setProcessorPath(processorPath);
+       }
+
        public void configureAspectPath(String projectName, File aspectpath) {
                AjCompiler compiler = CompilerFactory.getCompilerForProjectWithDir(sandboxDir + File.separator + projectName);
                Set<File> s = new HashSet<File>();
diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/AnnotationProcessingTests.java b/tests/src/org/aspectj/systemtest/incremental/tools/AnnotationProcessingTests.java
new file mode 100644 (file)
index 0000000..bee582c
--- /dev/null
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright (c) 2014 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://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Andy Clement - initial API and implementation
+ *******************************************************************************/
+package org.aspectj.systemtest.incremental.tools;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+
+public class AnnotationProcessingTests extends AbstractMultiProjectIncrementalAjdeInteractionTestbed {
+       
+       // Basic test: turns on annotation processing and tries to run the DemoProcessor
+       public void testAnnotationProcessing1() throws Exception {
+               createAndBuildAnnotationProcessorProject("ProcessorProject");
+               initialiseProject("ProcessorConsumer1");
+               configureProcessorOptions("ProcessorConsumer1","DemoProcessor");
+               configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
+
+               Hashtable<String, String> javaOptions = new Hashtable<String, String>();
+               javaOptions.put("org.eclipse.jdt.core.compiler.compliance", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.source", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.processAnnotations","enabled");
+               configureJavaOptionsMap("ProcessorConsumer1", javaOptions);
+               
+               configureNewProjectDependency("ProcessorConsumer1", "ProcessorProject");
+               configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
+               build("ProcessorConsumer1");
+               checkWasFullBuild();
+               checkCompiledFiles("ProcessorConsumer1","Advise_ccc.java","Advise_aaa.java","Code.java");
+               assertEquals(2,getWeavingMessages("ProcessorConsumer1").size());
+               String out = runMethod("ProcessorConsumer1", "Code", "runner");
+               assertEquals("aaa running\nccc running\n",out);
+       }
+       
+       // services file in processor project
+       public void testAnnotationProcessing2() throws Exception {
+               createAndBuildAnnotationProcessorProject("ProcessorProject2"); // This has a META-INF services entry for DemoProcessor
+               
+               initialiseProject("ProcessorConsumer2"); 
+               // Paths here are the path to DemoProcessor (compiled into the output folder of the ProcessorProject2) and the path to
+               // the META-INF file declaring DemoProcessor (since it is not copied to that same output folder) - this exists in the test src
+               // folder for ProcessorProject2
+               configureProcessorPath("ProcessorConsumer2", getCompilerForProjectWithName("ProcessorProject2").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString()+File.pathSeparator+
+                               new File(testdataSrcDir + File.separatorChar + "ProcessorProject2" + File.separatorChar + "base"+File.separatorChar+"src").toString());
+               
+               Hashtable<String, String> javaOptions = new Hashtable<String, String>();
+               javaOptions.put("org.eclipse.jdt.core.compiler.compliance", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.source", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.processAnnotations","enabled");
+               configureJavaOptionsMap("ProcessorConsumer2", javaOptions);
+               initialiseProject("ProcessorConsumer2");
+               configureNewProjectDependency("ProcessorConsumer2", "ProcessorProject");
+               configureNonStandardCompileOptions("ProcessorConsumer2", "-showWeaveInfo");
+               build("ProcessorConsumer2");
+               checkWasFullBuild();    
+               checkCompiledFiles("ProcessorConsumer2","Advise_ccc.java","Advise_aaa.java","Code.java");
+               assertEquals(2,getWeavingMessages("ProcessorConsumer2").size());
+               String out = runMethod("ProcessorConsumer2", "Code", "runner");
+               assertEquals("aaa running\nccc running\n",out);
+       }
+       
+       // Two processors
+       public void testAnnotationProcessing3() throws Exception {
+               createAndBuildAnnotationProcessorProject("ProcessorProject2");
+               createAndBuildAnnotationProcessorProject("ProcessorProject3");
+               initialiseProject("ProcessorConsumer1");
+               // Paths here are the path to DemoProcessor/DemoProcessor2 compiled code and the path to
+               // the META-INF file declaring DemoProcessor/DemoProcessor2 (since they are not copied to that same output folder) - 
+               // these exists in the test src folders for ProcessorProject2/ProcessorProject3
+               configureProcessorPath("ProcessorConsumer1", 
+                               getCompilerForProjectWithName("ProcessorProject3").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString()+File.pathSeparator+
+                               new File(testdataSrcDir + File.separatorChar + "ProcessorProject3" + File.separatorChar + "base"+File.separatorChar+"src").toString()
+                               +File.pathSeparator+
+                               getCompilerForProjectWithName("ProcessorProject2").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString()+File.pathSeparator+
+                               new File(testdataSrcDir + File.separatorChar + "ProcessorProject2" + File.separatorChar + "base"+File.separatorChar+"src").toString()
+                               );
+               
+               // The order here is DemoProcessor2 then DemoProcessor - to get the second one to run I changed DemoProcessor2 to operate on a
+               // specific annotation (java.lang.SuppressWarnings) and return false at the end
+
+               configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
+
+               Hashtable<String, String> javaOptions = new Hashtable<String, String>();
+               javaOptions.put("org.eclipse.jdt.core.compiler.compliance", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.codegen.targetPlatform", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.source", "1.6");
+               javaOptions.put("org.eclipse.jdt.core.compiler.processAnnotations","enabled");
+               configureJavaOptionsMap("ProcessorConsumer1", javaOptions);
+               
+               configureNewProjectDependency("ProcessorConsumer1", "ProcessorProject");
+               configureNonStandardCompileOptions("ProcessorConsumer1", "-showWeaveInfo");
+               build("ProcessorConsumer1");
+               checkWasFullBuild();
+               checkCompiledFiles("ProcessorConsumer1","Advise_ccc.java","Advise_aaa.java","Code.java","AroundAdvise_ccc.java","AroundAdvise_aaa.java");
+               assertEquals(4,getWeavingMessages("ProcessorConsumer1").size());
+               String out = runMethod("ProcessorConsumer1", "Code", "runner");
+               assertEquals("aaa running\nAround advice on aaa running\nccc running\nAround advice on ccc running\n",out);
+       }
+       
+       // Tests:
+       // TODO Incremental compilation - what does that mean with annotation processors?
+
+       // ---
+
+       private void createAndBuildAnnotationProcessorProject(String processorProjectName) {
+               initialiseProject(processorProjectName);
+               build(processorProjectName);
+               checkWasFullBuild();
+               assertNoErrors(processorProjectName);
+       }
+
+       private void configureProcessorOptions(String projectName, String processor) {
+               configureProcessor(projectName, "DemoProcessor");
+               // Assume all processors from processor project
+               configureProcessorPath(projectName, getCompilerForProjectWithName("ProcessorProject").getCompilerConfiguration().getOutputLocationManager().getDefaultOutputLocation().toString());
+       }
+       
+       private void checkCompiledFiles(String projectName, String... expectedCompiledFiles) {
+               List<String> compiledFiles = new ArrayList<String>(getCompiledFiles(projectName));
+               if (compiledFiles.size()!=expectedCompiledFiles.length) {
+                       fail("Expected #"+expectedCompiledFiles.length+" files to be compiled but found that #"+compiledFiles.size()+" files were compiled.\nCompiled="+compiledFiles);
+               }
+               for (String expectedCompiledFile: expectedCompiledFiles) {
+                       String toRemove = null;
+                       for (String compiledFile: compiledFiles) {
+                               String cfile = compiledFile.substring(compiledFile.lastIndexOf("/")+1);
+                               if (cfile.equals(expectedCompiledFile)) {
+                                       toRemove = compiledFile;
+                                       break;
+                               }
+                       }
+                       if (toRemove!=null) compiledFiles.remove(toRemove);
+               }
+               // Anything left in compiledFiles wasn't expected to be built
+               if (compiledFiles.size()!=0) {
+                       fail("These were not expected to be compiled: "+compiledFiles);
+               }
+       }
+       
+       
+}
index 803d5e7f6f8a570320135eaa1daa73969e05ce9b..f355e1557e92cad02d5f9b9f13c4fb65b990910b 100644 (file)
@@ -38,6 +38,8 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio
        private Set<File> inpath;
        private String encoding = null;
        private String outjar;
+       private String processor;
+       private String processorPath;
        private String nonstandardoptions;
        private List modifiedFiles;
        private List modifiedDirs;
@@ -164,6 +166,16 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio
                this.outjar = outjar;
                this.changed |= ICompilerConfiguration.OUTJAR_CHANGED;
        }
+       
+       public void setProcessor(String processor) {
+               this.processor = processor;
+               this.changed |= ICompilerConfiguration.PROCESSOR_CHANGED;
+       }
+
+       public void setProcessorPath(String processorPath) {
+               this.processorPath = processorPath;
+               this.changed |= ICompilerConfiguration.PROCESSOR_CHANGED;
+       }
 
        public void setJavaOptions(Map javaOptions) {
                this.javaOptionsMap = javaOptions;
@@ -240,4 +252,12 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio
                return this.encoding;
        }
 
+       public String getProcessor() {
+               return this.processor;
+       }
+
+       public String getProcessorPath() {
+               return this.processorPath;
+       }
+
 }
index 9a32b2f255a8bc776fc21d68881ea70d8440d9d7..40bc9322ab853c1cf7da98063478a6bd3605c13b 100644 (file)
@@ -101,12 +101,6 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa
                runMethod(p, "demo.ConverterTest", "run");
        }
 
-       private void runMethod(String projectName, String classname, String methodname) throws Exception {
-               File f = getProjectOutputRelativePath(projectName, "");
-               ClassLoader cl = new URLClassLoader(new URL[] { f.toURI().toURL() });
-               Class<?> clazz = Class.forName(classname, false, cl);
-               clazz.getDeclaredMethod(methodname).invoke(null);
-       }
 
        public void testIncrementalITDInners4() throws Exception {
                String p = "prInner4";
@@ -1905,7 +1899,7 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa
                checkCompileWeaveCount("P1", 5, 3); // we compile X and A (the delta)
                // find out that
                // an aspect has changed, go back to the source
-               // and compile X,A,C, then weave them all.
+               // and compile X,A,C, then weave the all.
                build("P1");
                long timeTakenForSimpleIncBuild = getTimeTakenForBuild("P1");
                // I don't think this test will have timing issues as the times should
@@ -1915,6 +1909,7 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa
                                + "ms  second=" + timeTakenForSimpleIncBuild + "ms", timeTakenForSimpleIncBuild < timeTakenForFullBuildAndWeave);
        }
 
+       @SuppressWarnings("rawtypes")
        public void testBuildingTwoProjectsInTurns() {
                initialiseProject("P1");
                initialiseProject("P2");
@@ -1925,7 +1920,7 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa
                build("P2");
                checkWasntFullBuild();
        }
-
+       
        public void testBuildingBrokenCode_pr240360() {
                initialiseProject("pr240360");
                // configureNonStandardCompileOptions("pr240360","-proceedOnError");
@@ -4025,9 +4020,4 @@ public class MultiProjectIncrementalTests extends AbstractMultiProjectIncrementa
                }
        }
 
-       protected File getProjectOutputRelativePath(String p, String filename) {
-               File projDir = new File(getWorkingDir(), p);
-               return new File(projDir, "bin" + File.separator + filename);
-       }
-
 }
\ No newline at end of file