2012-11-07 17:01:19 -08:00
|
|
|
/*
|
2014-10-29 17:25:23 -07:00
|
|
|
* Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
|
2012-11-07 17:01:19 -08:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
|
|
* published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
|
|
* accompanied this code).
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License version
|
|
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
|
|
* questions.
|
|
|
|
*/
|
|
|
|
|
2013-02-13 23:05:17 -08:00
|
|
|
import java.io.File;
|
|
|
|
import java.io.IOException;
|
2012-11-07 17:01:19 -08:00
|
|
|
import java.net.URI;
|
|
|
|
import java.net.URISyntaxException;
|
|
|
|
import java.util.Arrays;
|
2013-02-13 23:05:17 -08:00
|
|
|
import java.util.Iterator;
|
|
|
|
|
|
|
|
import javax.tools.Diagnostic;
|
2012-11-07 17:01:19 -08:00
|
|
|
import javax.tools.DiagnosticCollector;
|
|
|
|
import javax.tools.JavaCompiler;
|
2013-02-13 23:05:17 -08:00
|
|
|
import javax.tools.JavaCompiler.CompilationTask;
|
2012-11-07 17:01:19 -08:00
|
|
|
import javax.tools.JavaFileObject;
|
|
|
|
import javax.tools.SimpleJavaFileObject;
|
2013-02-13 23:05:17 -08:00
|
|
|
import javax.tools.StandardJavaFileManager;
|
|
|
|
import javax.tools.StandardLocation;
|
2012-11-07 17:01:19 -08:00
|
|
|
import javax.tools.ToolProvider;
|
2013-02-13 23:05:17 -08:00
|
|
|
|
|
|
|
import com.sun.source.util.JavacTask;
|
2012-11-07 17:01:19 -08:00
|
|
|
|
|
|
|
public class Helper {
|
|
|
|
|
|
|
|
enum ContentVars {
|
2013-02-13 23:05:17 -08:00
|
|
|
|
2013-01-14 13:50:01 -08:00
|
|
|
IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.Repeatable;\n"),
|
2012-11-07 17:01:19 -08:00
|
|
|
IMPORTDEPRECATED("import java.lang.Deprecated;\n"),
|
|
|
|
IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"),
|
|
|
|
IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
|
2013-02-13 23:05:17 -08:00
|
|
|
IMPORTRETENTION("import java.lang.annotation.Retention;\n"
|
|
|
|
+ "\nimport java.lang.annotation.RetentionPolicy;\n"),
|
2013-02-07 20:47:06 -08:00
|
|
|
IMPORTSTMTS("import java.lang.annotation.*;\n"),
|
2013-02-13 23:05:17 -08:00
|
|
|
IMPORTEXPECTED("import expectedFiles.*;\n"),
|
2013-01-14 13:50:01 -08:00
|
|
|
REPEATABLE("\n@Repeatable(FooContainer.class)\n"),
|
2013-02-13 23:05:17 -08:00
|
|
|
CONTAINER("@interface FooContainer {\n" + " Foo[] value();\n}\n"),
|
2013-10-17 13:50:00 +02:00
|
|
|
BASE("@interface Foo {int value() default Integer.MAX_VALUE;}\n"),
|
|
|
|
BASEANNO("@Foo(0)"),
|
|
|
|
LEGACYCONTAINER("@FooContainer(value = {@Foo(1), @Foo(2)})\n"),
|
|
|
|
REPEATABLEANNO("\n@Foo(1) @Foo(2)"),
|
2012-11-07 17:01:19 -08:00
|
|
|
DEPRECATED("\n@Deprecated"),
|
|
|
|
DOCUMENTED("\n@Documented"),
|
|
|
|
INHERITED("\n@Inherited"),
|
2013-02-13 23:05:17 -08:00
|
|
|
TARGET("\n@Target(#VAL)\n"),
|
2013-02-07 20:47:06 -08:00
|
|
|
RETENTION("@Retention(RetentionPolicy.#VAL)\n"),
|
2013-02-13 23:05:17 -08:00
|
|
|
RETENTIONRUNTIME("@Retention(RetentionPolicy.RUNTIME)\n");
|
2012-11-07 17:01:19 -08:00
|
|
|
private String val;
|
|
|
|
|
|
|
|
private ContentVars(String val) {
|
|
|
|
this.val = val;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getVal() {
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create and compile FileObject using values for className and contents
|
|
|
|
public static boolean compileCode(String className, String contents,
|
|
|
|
DiagnosticCollector<JavaFileObject> diagnostics) {
|
|
|
|
boolean ok = false;
|
|
|
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
|
|
|
if (compiler == null) {
|
|
|
|
throw new RuntimeException("can't get javax.tools.JavaCompiler!");
|
|
|
|
}
|
|
|
|
|
|
|
|
JavaFileObject file = getFile(className, contents);
|
|
|
|
Iterable<? extends JavaFileObject> compilationUnit = Arrays.asList(file);
|
|
|
|
|
|
|
|
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnit);
|
|
|
|
ok = task.call();
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
// Compile a list of FileObjects
|
2013-02-13 23:05:17 -08:00
|
|
|
// Used when packages are needed and classes need to be loaded at runtime
|
|
|
|
static File destDir = new File(System.getProperty("user.dir"));
|
|
|
|
|
2012-11-07 17:01:19 -08:00
|
|
|
public static boolean compileCode(DiagnosticCollector<JavaFileObject> diagnostics, Iterable<? extends JavaFileObject> files) {
|
2013-02-13 23:05:17 -08:00
|
|
|
boolean ok = false;
|
2012-11-07 17:01:19 -08:00
|
|
|
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
|
|
|
if (compiler == null) {
|
|
|
|
throw new RuntimeException("can't get javax.tools.JavaCompiler!");
|
|
|
|
}
|
|
|
|
|
2014-10-29 17:25:23 -07:00
|
|
|
try (StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null)) {
|
|
|
|
// Assuming filesCount can maximum be 2 and if true, one file is package-info.java
|
|
|
|
if (isPkgInfoPresent(files)) {
|
|
|
|
JavacTask task = (JavacTask) compiler.getTask(null, fm, diagnostics, null, null, files);
|
|
|
|
try {
|
|
|
|
fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(destDir));
|
|
|
|
task.generate();
|
|
|
|
} catch (IOException ioe) {
|
|
|
|
throw new RuntimeException("Compilation failed for package level tests", ioe);
|
2013-02-13 23:05:17 -08:00
|
|
|
}
|
2014-10-29 17:25:23 -07:00
|
|
|
int err = 0;
|
|
|
|
for (Diagnostic<? extends JavaFileObject> d : diagnostics.getDiagnostics()) {
|
|
|
|
if(d.getKind() == Diagnostic.Kind.ERROR) {
|
|
|
|
err++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ok = (err == 0);
|
|
|
|
} else {
|
|
|
|
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, files);
|
|
|
|
ok = task.call();
|
2013-02-13 23:05:17 -08:00
|
|
|
}
|
2014-10-29 17:25:23 -07:00
|
|
|
return ok;
|
|
|
|
} catch (IOException e) {
|
|
|
|
throw new Error(e);
|
2013-02-13 23:05:17 -08:00
|
|
|
}
|
2012-11-07 17:01:19 -08:00
|
|
|
}
|
|
|
|
|
2013-02-13 23:05:17 -08:00
|
|
|
static private boolean isPkgInfoPresent(Iterable<? extends JavaFileObject> files) {
|
|
|
|
Iterator<? extends JavaFileObject> itr = files.iterator();
|
|
|
|
while (itr.hasNext()) {
|
|
|
|
String name = itr.next().getName();
|
|
|
|
if (name.contains("package-info")) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
/* String template where /*<TYPE>*/ /*gets replaced by repeating anno
|
|
|
|
* Used to generate test src for combo tests
|
|
|
|
* - BasicSyntaxCombo.java
|
|
|
|
* - TargetAnnoCombo.java
|
|
|
|
*/
|
|
|
|
|
|
|
|
public static final String template =
|
|
|
|
"/*PACKAGE*/\n"
|
|
|
|
+ "//pkg test;\n\n"
|
2013-03-15 13:39:04 +01:00
|
|
|
+ "/*ANNODATA*/\n" // import statements, declaration of Foo/FooContainer
|
2013-02-13 23:05:17 -08:00
|
|
|
+ "/*TYPE*/ //class\n"
|
|
|
|
+ "class #ClassName {\n"
|
|
|
|
+ " /*FIELD*/ //instance var\n"
|
|
|
|
+ " public int x = 0;\n\n"
|
|
|
|
+ " /*FIELD*/ //Enum constants\n"
|
|
|
|
+ " TestEnum testEnum;\n\n"
|
|
|
|
+ " /*FIELD*/ // Static field\n"
|
|
|
|
+ " public static int num;\n\n"
|
|
|
|
+ " /*STATIC_INI*/\n"
|
|
|
|
+ " static { \n" + "num = 10; \n }\n\n"
|
|
|
|
+ " /*CONSTRUCTOR*/\n"
|
|
|
|
+ " #ClassName() {}\n\n"
|
|
|
|
+ " /*INSTANCE_INI*/\n"
|
|
|
|
+ " { \n x = 10; \n }"
|
|
|
|
+ " /*INNER_CLASS*/\n"
|
|
|
|
+ " class innerClass {}\n"
|
|
|
|
+ " /*METHOD*/\n"
|
|
|
|
+ " void bar(/*PARAMETER*/ int baz) {\n"
|
|
|
|
+ " /*LOCAL_VARIABLE*/\n"
|
|
|
|
+ " int y = 0;\n"
|
|
|
|
+ " }\n"
|
|
|
|
+ "}\n\n"
|
|
|
|
+ "/*TYPE*/ //Enum\n"
|
|
|
|
+ "enum TestEnum {}\n\n"
|
|
|
|
+ "/*TYPE*/ //Interface\n"
|
|
|
|
+ "interface TestInterface {}\n\n"
|
|
|
|
+ "/*TYPE*/\n"
|
|
|
|
+ "/*ANNOTATION_TYPE*/\n"
|
|
|
|
+ "@interface TestAnnotationType{}\n"
|
|
|
|
+ "class TestPkg {}\n"
|
|
|
|
+ "class TestTypeAnno </*TYPE_PARAMETER*/ T extends Object> {\n"
|
|
|
|
+ " String /*TYPE_USE*/[] arr;\n"
|
|
|
|
+ "}";
|
|
|
|
|
2012-11-07 17:01:19 -08:00
|
|
|
static JavaFileObject getFile(String name, String code) {
|
|
|
|
JavaFileObject o = null;
|
|
|
|
try {
|
|
|
|
o = new JavaStringFileObject(name, code);
|
|
|
|
} catch (URISyntaxException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
return o;
|
|
|
|
}
|
2013-02-13 23:05:17 -08:00
|
|
|
|
2012-11-07 17:01:19 -08:00
|
|
|
static class JavaStringFileObject extends SimpleJavaFileObject {
|
2013-02-13 23:05:17 -08:00
|
|
|
|
2012-11-07 17:01:19 -08:00
|
|
|
final String theCode;
|
2013-02-13 23:05:17 -08:00
|
|
|
|
2012-11-07 17:01:19 -08:00
|
|
|
public JavaStringFileObject(String fileName, String theCode) throws URISyntaxException {
|
2013-02-13 23:05:17 -08:00
|
|
|
super(new URI("string:///" + fileName.replace('.', '/') + ".java"), Kind.SOURCE);
|
2012-11-07 17:01:19 -08:00
|
|
|
this.theCode = theCode;
|
|
|
|
}
|
2013-02-13 23:05:17 -08:00
|
|
|
|
2012-11-07 17:01:19 -08:00
|
|
|
@Override
|
|
|
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
|
|
|
return theCode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|