From 1e2744d37cd2ac3438f8f1e6b8aae7c4a6c6b8d6 Mon Sep 17 00:00:00 2001 From: Andy Clement Date: Wed, 20 Aug 2014 08:00:10 -0700 Subject: [PATCH] enabling AJDT to use annotation processors --- .../core/BrowserCompilerConfiguration.java | 8 + .../ajde/core/ICompilerConfiguration.java | 10 ++ .../core/internal/AjdeCoreBuildManager.java | 13 ++ .../ajde/core/TestCompilerConfiguration.java | 8 + .../ui/utils/TestCompilerConfiguration.java | 10 ++ .../internal/core/builder/AjBuildConfig.java | 29 +++- .../CompilerConfigurationChangeFlags.java | 1 + .../aspectj/testing/ajde/CompileCommand.java | 8 + .../ProcessorConsumer1/base/src/Code.java | 26 +++ .../ProcessorConsumer2/base/src/Code.java | 26 +++ .../base/src/DemoProcessor.java | 47 ++++++ .../base/src/DemoProcessor.java | 47 ++++++ .../javax.annotation.processing.Processor | 1 + .../ProcessorProject2/base/src/proc.jar | Bin 0 -> 1289 bytes .../base/src/DemoProcessor2.java | 47 ++++++ .../javax.annotation.processing.Processor | 1 + .../org/aspectj/systemtest/AllTests16.java | 2 + ...jectIncrementalAjdeInteractionTestbed.java | 24 +++ .../tools/AjdeInteractionTestbed.java | 10 ++ .../tools/AnnotationProcessingTests.java | 151 ++++++++++++++++++ .../MultiProjTestCompilerConfiguration.java | 20 +++ .../tools/MultiProjectIncrementalTests.java | 16 +- 22 files changed, 490 insertions(+), 15 deletions(-) create mode 100644 tests/multiIncremental/ProcessorConsumer1/base/src/Code.java create mode 100644 tests/multiIncremental/ProcessorConsumer2/base/src/Code.java create mode 100644 tests/multiIncremental/ProcessorProject/base/src/DemoProcessor.java create mode 100644 tests/multiIncremental/ProcessorProject2/base/src/DemoProcessor.java create mode 100644 tests/multiIncremental/ProcessorProject2/base/src/META-INF/services/javax.annotation.processing.Processor create mode 100644 tests/multiIncremental/ProcessorProject2/base/src/proc.jar create mode 100644 tests/multiIncremental/ProcessorProject3/base/src/DemoProcessor2.java create mode 100644 tests/multiIncremental/ProcessorProject3/base/src/META-INF/services/javax.annotation.processing.Processor create mode 100644 tests/src/org/aspectj/systemtest/incremental/tools/AnnotationProcessingTests.java diff --git a/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java b/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java index 974705c3e..403ebb731 100644 --- a/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java +++ b/ajbrowser/src/org/aspectj/tools/ajbrowser/core/BrowserCompilerConfiguration.java @@ -116,4 +116,12 @@ public class BrowserCompilerConfiguration implements ICompilerConfiguration { return null; } + public String getProcessor() { + return null; + } + + public String getProcessorPath() { + return null; + } + } diff --git a/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java index aa389f052..b9684aa09 100644 --- a/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java +++ b/ajde.core/src/org/aspectj/ajde/core/ICompilerConfiguration.java @@ -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(); + } diff --git a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java index 267ac9329..531e9b01d 100644 --- a/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java +++ b/ajde.core/src/org/aspectj/ajde/core/internal/AjdeCoreBuildManager.java @@ -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 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; } diff --git a/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java b/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java index 921591c97..1070da969 100644 --- a/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java +++ b/ajde.core/testsrc/org/aspectj/ajde/core/TestCompilerConfiguration.java @@ -171,4 +171,12 @@ public class TestCompilerConfiguration implements ICompilerConfiguration { return null; } + public String getProcessor() { + return null; + } + + public String getProcessorPath() { + return null; + } + } diff --git a/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java b/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java index c76a388c2..2e5520a45 100644 --- a/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java +++ b/ajde/testsrc/org/aspectj/ajde/ui/utils/TestCompilerConfiguration.java @@ -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; + } + } diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java index e99cac6c0..98bd0484e 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/AjBuildConfig.java @@ -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 changedFiles; private List files = new ArrayList(); private List xmlfiles = new ArrayList(); + private String processor; + private String processorPath; private List binaryFiles = new ArrayList(); // .class files in indirs... private List inJars = new ArrayList(); private List inPath = new ArrayList(); @@ -134,6 +137,28 @@ public class AjBuildConfig implements CompilerConfigurationChangeFlags { public List 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 diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java index 59ade0ae0..7e3ef5ecd 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/core/builder/CompilerConfigurationChangeFlags.java @@ -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; } diff --git a/testing/src/org/aspectj/testing/ajde/CompileCommand.java b/testing/src/org/aspectj/testing/ajde/CompileCommand.java index 2f819db44..2fd748ff2 100644 --- a/testing/src/org/aspectj/testing/ajde/CompileCommand.java +++ b/testing/src/org/aspectj/testing/ajde/CompileCommand.java @@ -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 index 000000000..72efafcfa --- /dev/null +++ b/tests/multiIncremental/ProcessorConsumer1/base/src/Code.java @@ -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 index 000000000..72efafcfa --- /dev/null +++ b/tests/multiIncremental/ProcessorConsumer2/base/src/Code.java @@ -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 index 000000000..05ff20107 --- /dev/null +++ b/tests/multiIncremental/ProcessorProject/base/src/DemoProcessor.java @@ -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 index 000000000..05ff20107 --- /dev/null +++ b/tests/multiIncremental/ProcessorProject2/base/src/DemoProcessor.java @@ -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 index 000000000..3c594a8be --- /dev/null +++ b/tests/multiIncremental/ProcessorProject2/base/src/META-INF/services/javax.annotation.processing.Processor @@ -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 index 0000000000000000000000000000000000000000..be2dd1e858a811ef3cfd3f99ca7b4a8b5f55f662 GIT binary patch literal 1289 zcmWIWW@Zs#;Nak3$jRb&Wk3Q#3@i*Tsk!+9Mfu68#l`tWdRd8OiT_S9FqDS)`ad=h zuvOomWTws@u;VRbNT*lJ-;{2TtuYfOyym$w;l{+bEn%VmfA@X9xaESa$)w}P`Dyp6 z*Xd~I%Ix{nrXHlOK7FB#^6Dd*u{ZcHE-BmeW6H^?m-?(%h6YLMUWi&5XO}8Er)lZA zkH!b?iHb!mDza1EbL!Qp^hCS6r8CxRZ&~xuwO9Cti~2>gd#6vA7Wjq;-oYcv+QgU#t?^YZCSIFGHyCVKts6F=jQp340b~H%8V- zvfW<1gFA?IXVbilX^M%Zb8Z^%xW4sN|CW>2t|iWVaciPe&`zg~8F$WH@w!+s@x9cX z`G>b|aSBd;ko9(23A3ts{*1%BOT05~nuYv4(5t_>j?*bI)BKphxuY9`*cH^2VH(*|Z|Pb_BrWzqf8wB+VmljK}>bM@;1xz&O! zf%>84?3edU6q~>3^2YO-EVJE3=kl>KaI0{w`1<>uzb z%ky?#``EcIz*gero}0pP7d6wBXBzHwjFvgU*Z1?gw3f*|Kjw>m%=x#4^Z!rWc>H$L z13#U{zcZFHFq8WeQt1T{u;^Qm30w`f1>v*-9Tm-|n0F_))Ike|Kfo+Xdgh%KtZh zk+t~1OsU)d`*VNr2Y9n{>~ZjVewc}Y;V~-%LjW)va4|4&FfcI1p=JY4V3zQ84RO@< z^mEfkC<~}XRVIY2tT?r(EEAY%!0I8n3*A_Atm;8ItU@m_FE76&u_QA;Pp<%y`7-m; z_2Bui*z@dJevMQ9e!6<+^dB(+-OkSOfA&Ku0icn5Kpf!B$Rxsm$kfRG1Z8SefIW+Y z%-~|c9U=%b*qKqn2cZpH2qCoTA!|blFND)UA%^TNP>3Nw99I2AgU-%0BFe46aWAK literal 0 HcmV?d00001 diff --git a/tests/multiIncremental/ProcessorProject3/base/src/DemoProcessor2.java b/tests/multiIncremental/ProcessorProject3/base/src/DemoProcessor2.java new file mode 100644 index 000000000..e55e665bc --- /dev/null +++ b/tests/multiIncremental/ProcessorProject3/base/src/DemoProcessor2.java @@ -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 index 000000000..62e145eb6 --- /dev/null +++ b/tests/multiIncremental/ProcessorProject3/base/src/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1 @@ +DemoProcessor2 diff --git a/tests/src/org/aspectj/systemtest/AllTests16.java b/tests/src/org/aspectj/systemtest/AllTests16.java index 66e0d0bf3..f1f7b4a14 100644 --- a/tests/src/org/aspectj/systemtest/AllTests16.java +++ b/tests/src/org/aspectj/systemtest/AllTests16.java @@ -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; } diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/AbstractMultiProjectIncrementalAjdeInteractionTestbed.java b/tests/src/org/aspectj/systemtest/incremental/tools/AbstractMultiProjectIncrementalAjdeInteractionTestbed.java index 10c108067..229a22a5d 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/AbstractMultiProjectIncrementalAjdeInteractionTestbed.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/AbstractMultiProjectIncrementalAjdeInteractionTestbed.java @@ -12,12 +12,16 @@ 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); diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java b/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java index b063fc5ef..14e880a0a 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java @@ -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 s = new HashSet(); 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 index 000000000..bee582cf6 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/incremental/tools/AnnotationProcessingTests.java @@ -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 javaOptions = new Hashtable(); + 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 javaOptions = new Hashtable(); + 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 javaOptions = new Hashtable(); + 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 compiledFiles = new ArrayList(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); + } + } + + +} diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java index 803d5e7f6..f355e1557 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjTestCompilerConfiguration.java @@ -38,6 +38,8 @@ public class MultiProjTestCompilerConfiguration implements ICompilerConfiguratio private Set 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; + } + } diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java index 9a32b2f25..40bc9322a 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/MultiProjectIncrementalTests.java @@ -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 -- 2.39.5