5b6b514441
Reviewed-by: jlaskey, darcy
667 lines
25 KiB
Java
667 lines
25 KiB
Java
/*
|
|
* Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
|
|
* 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.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 7026941
|
|
* @summary path options ignored when reusing filemanager across tasks
|
|
* @modules java.compiler
|
|
* jdk.compiler
|
|
*/
|
|
|
|
import java.io.File;
|
|
import java.io.FileWriter;
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.net.URI;
|
|
import java.nio.file.Files;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.EnumSet;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.jar.JarEntry;
|
|
import java.util.jar.JarOutputStream;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import javax.tools.JavaCompiler;
|
|
import javax.tools.JavaCompiler.CompilationTask;
|
|
import javax.tools.JavaFileObject;
|
|
import javax.tools.SimpleJavaFileObject;
|
|
import javax.tools.StandardJavaFileManager;
|
|
import javax.tools.StandardLocation;
|
|
import javax.tools.ToolProvider;
|
|
|
|
import static javax.tools.StandardLocation.*;
|
|
|
|
/**
|
|
* Test for combinations of using javac command-line options and fileManager setLocation
|
|
* calls to affect the locations available in the fileManager.
|
|
*
|
|
* Using a single Java compiler and file manager, for each of the standard locations,
|
|
* a series of operations is performed, using either compiler options or setLocation
|
|
* calls. Each operation includes a compilation, and then a check for the value of
|
|
* the standard location available in the file manager.
|
|
*
|
|
* The operations generate and use unique files to minimize the possibility of false
|
|
* positive results.
|
|
*/
|
|
public class TestSearchPaths {
|
|
|
|
public static void main(String... args) throws Exception {
|
|
TestSearchPaths t = new TestSearchPaths();
|
|
t.run();
|
|
}
|
|
|
|
void run() throws Exception {
|
|
compiler = ToolProvider.getSystemJavaCompiler();
|
|
fileManager = compiler.getStandardFileManager(null, null, null);
|
|
try {
|
|
// basic output path
|
|
testClassOutput();
|
|
|
|
// basic search paths
|
|
testClassPath();
|
|
testSourcePath();
|
|
testPlatformClassPath();
|
|
|
|
// annotation processing
|
|
testAnnotationProcessorPath();
|
|
testSourceOutput();
|
|
|
|
// javah equivalent
|
|
testNativeHeaderOutput();
|
|
|
|
// future-proof: guard against new StandardLocations being added
|
|
if (!tested.equals(EnumSet.allOf(StandardLocation.class))) {
|
|
// FIXME: need to update for JDK 9 locations
|
|
// error("not all standard locations have been tested");
|
|
out.println("not yet tested: " + EnumSet.complementOf(tested));
|
|
}
|
|
|
|
if (errors > 0) {
|
|
throw new Exception(errors + " errors occurred");
|
|
}
|
|
} finally {
|
|
fileManager.close();
|
|
}
|
|
}
|
|
|
|
void testClassOutput() throws IOException {
|
|
String test = "testClassOutput";
|
|
System.err.println("test: " + test);
|
|
|
|
for (int i = 1; i <= 5; i++) {
|
|
File classes = createDir(test + "/" + i + "/classes");
|
|
List<String> options;
|
|
switch (i) {
|
|
default:
|
|
options = getOptions("-d", classes.getPath());
|
|
break;
|
|
|
|
case 3:
|
|
setLocation(CLASS_OUTPUT, classes);
|
|
options = null;
|
|
break;
|
|
}
|
|
List<JavaFileObject> sources = getSources("class C" + i + " { }");
|
|
callTask(options, sources);
|
|
checkPath(CLASS_OUTPUT, Mode.EQUALS, classes);
|
|
checkFile(CLASS_OUTPUT, "C" + i + ".class");
|
|
}
|
|
|
|
tested.add(CLASS_OUTPUT);
|
|
}
|
|
|
|
void testClassPath() throws IOException {
|
|
String test = "testClassPath";
|
|
System.err.println("test: " + test);
|
|
|
|
for (int i = 1; i <= 5; i++) {
|
|
File classes = createDir(test + "/" + i + "/classes");
|
|
File classpath = new File("testClassOutput/" + i + "/classes");
|
|
List<String> options;
|
|
switch (i) {
|
|
default:
|
|
options = getOptions("-d", classes.getPath(), "-classpath", classpath.getPath());
|
|
break;
|
|
|
|
case 3:
|
|
setLocation(CLASS_PATH, classpath);
|
|
options = getOptions("-d", classes.getPath());
|
|
break;
|
|
|
|
case 4:
|
|
options = getOptions("-d", classes.getPath(), "-cp", classpath.getPath());
|
|
break;
|
|
}
|
|
List<JavaFileObject> sources = getSources("class D" + i + " { C" + i + " c; }");
|
|
callTask(options, sources);
|
|
checkPath(CLASS_PATH, Mode.EQUALS, classpath);
|
|
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
|
}
|
|
|
|
tested.add(CLASS_PATH);
|
|
System.err.println();
|
|
}
|
|
|
|
void testSourcePath() throws IOException {
|
|
String test = "testSourcePath";
|
|
System.err.println("test: " + test);
|
|
setLocation(CLASS_PATH); // empty
|
|
|
|
for (int i = 1; i <= 5; i++) {
|
|
File src = createDir(test + "/" + i + "/src");
|
|
writeFile(src, "C" + i + ".java", "class C" + i + "{ }");
|
|
File classes = createDir(test + "/" + i + "/classes");
|
|
File srcpath = src;
|
|
List<String> options;
|
|
switch (i) {
|
|
default:
|
|
options = getOptions("-d", classes.getPath(), "-sourcepath", srcpath.getPath());
|
|
break;
|
|
|
|
case 3:
|
|
setLocation(SOURCE_PATH, srcpath);
|
|
options = getOptions("-d", classes.getPath());
|
|
break;
|
|
}
|
|
List<JavaFileObject> sources = getSources("class D" + i + " { C" + i + " c; }");
|
|
callTask(options, sources);
|
|
checkPath(SOURCE_PATH, Mode.EQUALS, srcpath);
|
|
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
|
}
|
|
|
|
tested.add(SOURCE_PATH);
|
|
System.err.println();
|
|
}
|
|
|
|
void testPlatformClassPath() throws IOException {
|
|
String test = "testPlatformClassPath";
|
|
System.err.println("test: " + test);
|
|
|
|
List<File> defaultPath = getLocation(PLATFORM_CLASS_PATH);
|
|
StringBuilder sb = new StringBuilder();
|
|
for (File f: defaultPath) {
|
|
if (sb.length() > 0)
|
|
sb.append(File.pathSeparator);
|
|
sb.append(f);
|
|
}
|
|
String defaultPathString = sb.toString();
|
|
|
|
setLocation(CLASS_PATH); // empty
|
|
setLocation(SOURCE_PATH); // empty
|
|
|
|
// Use -source 8 -target 8 to enable use of platform class path options
|
|
// FIXME: temporarily exclude cases referring to default bootclasspath
|
|
// for (int i = 1; i <= 10; i++) {
|
|
int[] cases = new int[] { 1, 2, 4, 5, 6, 7 };
|
|
for (int i : cases) {
|
|
File classes = createDir(test + "/" + i + "/classes");
|
|
File testJars = createDir(test + "/" + i + "/testJars");
|
|
File testClasses = createDir(test + "/" + i + "/testClasses");
|
|
callTask(getOptions("-d", testClasses.getPath()), getSources("class C" + i + " { }"));
|
|
|
|
List<String> options;
|
|
Mode mode;
|
|
List<File> match;
|
|
String reference = "C" + i + " c;";
|
|
|
|
File jar;
|
|
|
|
switch (i) {
|
|
case 1:
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-source", "8", "-target", "8",
|
|
"-Xbootclasspath/p:" + testClasses);
|
|
mode = Mode.STARTS_WITH;
|
|
match = Arrays.asList(testClasses);
|
|
break;
|
|
|
|
case 2:
|
|
// the default values for -extdirs and -endorseddirs come after the bootclasspath;
|
|
// so to check -Xbootclasspath/a: we specify empty values for those options.
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-source", "8", "-target", "8",
|
|
"-Xbootclasspath/a:" + testClasses,
|
|
"-extdirs", "",
|
|
"-endorseddirs", "");
|
|
mode = Mode.ENDS_WITH;
|
|
match = Arrays.asList(testClasses);
|
|
break;
|
|
|
|
case 3:
|
|
options = getOptions("-d", classes.getPath(), "-Xbootclasspath:" + defaultPathString);
|
|
mode = Mode.EQUALS;
|
|
match = defaultPath;
|
|
reference = "";
|
|
break;
|
|
|
|
case 4:
|
|
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
|
jar = new File(testJars, "j" + i + ".jar");
|
|
writeJar(jar, testClasses, "C" + i + ".class");
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-source", "8", "-target", "8",
|
|
"-endorseddirs", testJars.getPath());
|
|
mode = Mode.CONTAINS;
|
|
match = Arrays.asList(jar);
|
|
break;
|
|
|
|
case 5:
|
|
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
|
jar = new File(testJars, "j" + i + ".jar");
|
|
writeJar(jar, testClasses, "C" + i + ".class");
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-source", "8", "-target", "8",
|
|
"-Djava.endorsed.dirs=" + testJars.getPath());
|
|
mode = Mode.CONTAINS;
|
|
match = Arrays.asList(jar);
|
|
break;
|
|
|
|
case 6:
|
|
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
|
jar = new File(testJars, "j" + i + ".jar");
|
|
writeJar(jar, testClasses, "C" + i + ".class");
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-source", "8", "-target", "8",
|
|
"-extdirs", testJars.getPath());
|
|
mode = Mode.CONTAINS;
|
|
match = Arrays.asList(jar);
|
|
break;
|
|
|
|
case 7:
|
|
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
|
jar = new File(testJars, "j" + i + ".jar");
|
|
writeJar(jar, testClasses, "C" + i + ".class");
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-source", "8", "-target", "8",
|
|
"-Djava.ext.dirs=" + testJars.getPath());
|
|
mode = Mode.CONTAINS;
|
|
match = Arrays.asList(jar);
|
|
break;
|
|
|
|
case 8:
|
|
setLocation(PLATFORM_CLASS_PATH, defaultPath);
|
|
options = getOptions("-d", classes.getPath());
|
|
mode = Mode.EQUALS;
|
|
match = defaultPath;
|
|
reference = "";
|
|
break;
|
|
|
|
default:
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-source", "8", "-target", "8",
|
|
"-bootclasspath", defaultPathString);
|
|
mode = Mode.EQUALS;
|
|
match = defaultPath;
|
|
reference = "";
|
|
break;
|
|
}
|
|
List<JavaFileObject> sources = getSources("class D" + i + " { " + reference + " }");
|
|
|
|
callTask(options, sources);
|
|
checkPath(PLATFORM_CLASS_PATH, mode, match);
|
|
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
|
}
|
|
|
|
tested.add(PLATFORM_CLASS_PATH);
|
|
System.err.println();
|
|
}
|
|
|
|
void testAnnotationProcessorPath() throws IOException {
|
|
String test = "testAnnotationProcessorPath";
|
|
System.err.println("test: " + test);
|
|
|
|
fileManager.setLocation(PLATFORM_CLASS_PATH, null);
|
|
|
|
String template =
|
|
"import java.util.*;\n"
|
|
+ "import javax.annotation.processing.*;\n"
|
|
+ "import javax.lang.model.*;\n"
|
|
+ "import javax.lang.model.element.*;\n"
|
|
+ "@SupportedAnnotationTypes(\"*\")\n"
|
|
+ "public class A%d extends AbstractProcessor {\n"
|
|
+ " public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) {\n"
|
|
+ " return true;\n"
|
|
+ " }\n"
|
|
+ " public SourceVersion getSupportedSourceVersion() {\n"
|
|
+ " return SourceVersion.latest();\n"
|
|
+ " }\n"
|
|
+ "}";
|
|
|
|
for (int i = 1; i <= 5; i++) {
|
|
File classes = createDir(test + "/" + i + "/classes");
|
|
File annodir = createDir(test + "/" + i + "/processors");
|
|
callTask(getOptions("-d", annodir.getPath()), getSources(String.format(template, i)));
|
|
File annopath = annodir;
|
|
List<String> options;
|
|
switch (i) {
|
|
default:
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-processorpath", annopath.getPath(),
|
|
"-processor", "A" + i);
|
|
break;
|
|
|
|
case 3:
|
|
setLocation(ANNOTATION_PROCESSOR_PATH, annopath);
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-processor", "A" + i);
|
|
break;
|
|
}
|
|
List<JavaFileObject> sources = getSources("class D" + i + " { }");
|
|
callTask(options, sources);
|
|
checkPath(ANNOTATION_PROCESSOR_PATH, Mode.EQUALS, annopath);
|
|
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
|
}
|
|
|
|
tested.add(ANNOTATION_PROCESSOR_PATH);
|
|
System.err.println();
|
|
}
|
|
|
|
void testSourceOutput() throws IOException {
|
|
String test = "testAnnotationProcessorPath";
|
|
System.err.println("test: " + test);
|
|
|
|
String source =
|
|
"import java.io.*;\n"
|
|
+ "import java.util.*;\n"
|
|
+ "import javax.annotation.processing.*;\n"
|
|
+ "import javax.lang.model.*;\n"
|
|
+ "import javax.lang.model.element.*;\n"
|
|
+ "import javax.tools.*;\n"
|
|
+ "@SupportedOptions(\"name\")\n"
|
|
+ "@SupportedAnnotationTypes(\"*\")\n"
|
|
+ "public class A extends AbstractProcessor {\n"
|
|
+ " int round = 0;\n"
|
|
+ " public boolean process(Set<? extends TypeElement> annos, RoundEnvironment rEnv) {\n"
|
|
+ " if (round++ == 0) try {\n"
|
|
+ " String name = processingEnv.getOptions().get(\"name\");\n"
|
|
+ " JavaFileObject fo = processingEnv.getFiler().createSourceFile(name);\n"
|
|
+ " try (Writer out = fo.openWriter()) {\n"
|
|
+ " out.write(\"class \" + name + \" { }\");\n"
|
|
+ " }\n"
|
|
+ " } catch (IOException e) { throw new Error(e); }\n"
|
|
+ " return true;\n"
|
|
+ " }\n"
|
|
+ " public SourceVersion getSupportedSourceVersion() {\n"
|
|
+ " return SourceVersion.latest();\n"
|
|
+ " }\n"
|
|
+ "}";
|
|
|
|
File annodir = createDir(test + "/processors");
|
|
callTask(getOptions("-d", annodir.getPath()), getSources(source));
|
|
setLocation(ANNOTATION_PROCESSOR_PATH, annodir);
|
|
|
|
for (int i = 1; i <= 5; i++) {
|
|
File classes = createDir(test + "/" + i + "/classes");
|
|
File genSrc = createDir(test + "/" + "/genSrc");
|
|
List<String> options;
|
|
switch (i) {
|
|
default:
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-processor", "A", "-Aname=G" + i,
|
|
"-s", genSrc.getPath());
|
|
break;
|
|
|
|
case 3:
|
|
setLocation(SOURCE_OUTPUT, genSrc);
|
|
options = getOptions("-d", classes.getPath(),
|
|
"-processor", "A", "-Aname=G" + i);
|
|
break;
|
|
}
|
|
List<JavaFileObject> sources = getSources("class D" + i + " { }");
|
|
callTask(options, sources);
|
|
checkPath(SOURCE_OUTPUT, Mode.EQUALS, genSrc);
|
|
checkFile(CLASS_OUTPUT, "D" + i + ".class");
|
|
checkFile(CLASS_OUTPUT, "G" + i + ".class");
|
|
}
|
|
tested.add(SOURCE_OUTPUT);
|
|
System.err.println();
|
|
}
|
|
|
|
void testNativeHeaderOutput() throws IOException {
|
|
String test = "testNativeHeaderOutput";
|
|
System.err.println("test: " + test);
|
|
|
|
for (int i = 1; i <= 5; i++) {
|
|
File classes = createDir(test + "/" + i + "/classes");
|
|
File headers = createDir(test + "/" + i + "/hdrs");
|
|
List<String> options;
|
|
switch (i) {
|
|
default:
|
|
options = getOptions("-d", classes.getPath(), "-h", headers.getPath());
|
|
break;
|
|
|
|
case 3:
|
|
setLocation(NATIVE_HEADER_OUTPUT, headers);
|
|
options = getOptions("-d", classes.getPath());
|
|
break;
|
|
}
|
|
List<JavaFileObject> sources = getSources("class C" + i + " { native void m(); }");
|
|
callTask(options, sources);
|
|
checkPath(NATIVE_HEADER_OUTPUT, Mode.EQUALS, headers);
|
|
checkFile(NATIVE_HEADER_OUTPUT, "C" + i + ".h");
|
|
}
|
|
|
|
tested.add(StandardLocation.NATIVE_HEADER_OUTPUT);
|
|
System.err.println();
|
|
}
|
|
|
|
List<String> getOptions(String... args) {
|
|
return Arrays.asList(args);
|
|
}
|
|
|
|
List<JavaFileObject> getSources(String... sources) {
|
|
List<JavaFileObject> list = new ArrayList<>();
|
|
for (String s: sources)
|
|
list.add(getSource(s));
|
|
return list;
|
|
}
|
|
|
|
JavaFileObject getSource(final String source) {
|
|
return SimpleJavaFileObject.forSource(getURIFromSource(source),
|
|
source);
|
|
}
|
|
|
|
void callTask(List<String> options, List<JavaFileObject> files) {
|
|
out.print("compile: ");
|
|
if (options != null) {
|
|
for (String o: options) {
|
|
if (o.length() > 64) {
|
|
o = o.substring(0, 32) + "..." + o.substring(o.length() - 32);
|
|
}
|
|
out.print(" " + o);
|
|
}
|
|
}
|
|
for (JavaFileObject f: files)
|
|
out.print(" " + f.getName());
|
|
out.println();
|
|
CompilationTask t = compiler.getTask(out, fileManager, null, options, null, files);
|
|
boolean ok = t.call();
|
|
if (!ok)
|
|
error("compilation failed");
|
|
}
|
|
|
|
enum Mode { EQUALS, CONTAINS, STARTS_WITH, ENDS_WITH };
|
|
|
|
void checkFile(StandardLocation l, String path) {
|
|
if (!l.isOutputLocation()) {
|
|
error("Not an output location: " + l);
|
|
return;
|
|
}
|
|
|
|
List<File> files = getLocation(l);
|
|
if (files == null) {
|
|
error("location is unset: " + l);
|
|
return;
|
|
}
|
|
|
|
if (files.size() != 1)
|
|
error("unexpected number of entries on " + l + ": " + files.size());
|
|
|
|
File f = new File(files.get(0), path);
|
|
if (!f.exists())
|
|
error("file not found: " + f);
|
|
}
|
|
|
|
void checkPath(StandardLocation l, Mode m, File expect) {
|
|
checkPath(l, m, Arrays.asList(expect));
|
|
}
|
|
|
|
void checkPath(StandardLocation l, Mode m, List<File> expect) {
|
|
List<File> files = getLocation(l);
|
|
if (files == null) {
|
|
error("location is unset: " + l);
|
|
return;
|
|
}
|
|
|
|
switch (m) {
|
|
case EQUALS:
|
|
if (!Objects.equals(files, expect)) {
|
|
error("location does not match the expected files: " + l);
|
|
out.println("found: " + files);
|
|
out.println("expect: " + expect);
|
|
}
|
|
break;
|
|
|
|
case CONTAINS:
|
|
int containsIndex = Collections.indexOfSubList(files, expect);
|
|
if (containsIndex == -1) {
|
|
error("location does not contain the expected files: " + l);
|
|
out.println("found: " + files);
|
|
out.println("expect: " + expect);
|
|
}
|
|
break;
|
|
|
|
case STARTS_WITH:
|
|
int startsIndex = Collections.indexOfSubList(files, expect);
|
|
if (startsIndex != 0) {
|
|
error("location does not start with the expected files: " + l);
|
|
out.println("found: " + files);
|
|
out.println("expect: " + expect);
|
|
}
|
|
break;
|
|
|
|
case ENDS_WITH:
|
|
int endsIndex = Collections.lastIndexOfSubList(files, expect);
|
|
if (endsIndex != files.size() - expect.size()) {
|
|
error("location does not end with the expected files: " + l);
|
|
out.println("found: " + files);
|
|
out.println("expect: " + expect);
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
List<File> getLocation(StandardLocation l) {
|
|
Iterable<? extends File> iter = fileManager.getLocation(l);
|
|
if (iter == null)
|
|
return null;
|
|
List<File> files = new ArrayList<>();
|
|
for (File f: iter)
|
|
files.add(f);
|
|
return files;
|
|
}
|
|
|
|
void setLocation(StandardLocation l, File... files) throws IOException {
|
|
fileManager.setLocation(l, Arrays.asList(files));
|
|
}
|
|
|
|
void setLocation(StandardLocation l, List<File> files) throws IOException {
|
|
fileManager.setLocation(l, files);
|
|
}
|
|
|
|
void writeFile(File dir, String path, String body) throws IOException {
|
|
try (FileWriter w = new FileWriter(new File(dir, path))) {
|
|
w.write(body);
|
|
}
|
|
}
|
|
|
|
void writeJar(File jar, File dir, String... entries) throws IOException {
|
|
try (JarOutputStream j = new JarOutputStream(Files.newOutputStream(jar.toPath()))) {
|
|
for (String entry: entries) {
|
|
j.putNextEntry(new JarEntry(entry));
|
|
j.write(Files.readAllBytes(dir.toPath().resolve(entry)));
|
|
}
|
|
}
|
|
}
|
|
|
|
private static final Pattern packagePattern
|
|
= Pattern.compile("package\\s+(((?:\\w+\\.)*)(?:\\w+))");
|
|
private static final Pattern classPattern
|
|
= Pattern.compile("(?:public\\s+)?(?:class|enum|interface)\\s+(\\w+)");
|
|
|
|
|
|
private static URI getURIFromSource(String source) {
|
|
String packageName = null;
|
|
|
|
Matcher matcher = packagePattern.matcher(source);
|
|
if (matcher.find()) {
|
|
packageName = matcher.group(1).replace(".", "/");
|
|
}
|
|
|
|
matcher = classPattern.matcher(source);
|
|
if (matcher.find()) {
|
|
String className = matcher.group(1);
|
|
String path = ((packageName == null) ? "" : packageName + "/") + className + ".java";
|
|
return URI.create("myfo:///" + path);
|
|
} else {
|
|
throw new Error("Could not extract the java class "
|
|
+ "name from the provided source");
|
|
}
|
|
}
|
|
|
|
File createDir(String path) {
|
|
File dir = new File(path);
|
|
dir.mkdirs();
|
|
return dir;
|
|
}
|
|
|
|
JavaCompiler compiler;
|
|
StandardJavaFileManager fileManager;
|
|
|
|
/**
|
|
* Map for recording which standard locations have been tested.
|
|
*/
|
|
EnumSet<StandardLocation> tested = EnumSet.noneOf(StandardLocation.class);
|
|
|
|
/**
|
|
* Logging stream. Used directly with test and for getTask calls.
|
|
*/
|
|
final PrintWriter out = new PrintWriter(System.err, true);
|
|
|
|
/**
|
|
* Count of errors so far.
|
|
*/
|
|
int errors;
|
|
|
|
void error(String message) {
|
|
errors++;
|
|
out.println("Error: " + message);
|
|
}
|
|
}
|