/* * Copyright (c) 2010, 2019, 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.
*/
/** * Class to handle example code designed to illustrate javac diagnostic messages.
*/ class Example implements Comparable<Example> { /* Create an Example from the files found at path. * The head of the file, up to the first Java code, is scanned * for information about the test, such as what resource keys it * generates when run, what options are required to run it, and so on.
*/
Example(File file) { this.file = file;
declaredKeys = new TreeSet<String>();
srcFiles = new ArrayList<File>();
procFiles = new ArrayList<File>();
srcPathFiles = new ArrayList<File>();
moduleSourcePathFiles = new ArrayList<File>();
patchModulePathFiles = new ArrayList<File>();
modulePathFiles = new ArrayList<File>();
classPathFiles = new ArrayList<File>();
additionalFiles = new ArrayList<File>();
nonEmptySrcFiles = new ArrayList<File>();
findFiles(file, srcFiles); for (File f: srcFiles) {
parse(f);
}
if (infoFile == null) thrownew Error("Example " + file + " has no info file");
}
/** * Get the set of resource keys that this test declares it will generate * when it is run.
*/
Set<String> getDeclaredKeys() { return declaredKeys;
}
/** * Get the set of resource keys that this test generates when it is run. * The test will be run if it has not already been run.
*/
Set<String> getActualKeys() { if (actualKeys == null)
actualKeys = run(false); return actualKeys;
}
/** * Run the test. Information in the test header is used to determine * how to run the test.
*/ void run(PrintWriter out, boolean raw, boolean verbose) { if (out == null) thrownew NullPointerException(); try {
run(out, null, raw, verbose);
} catch (IOException e) {
e.printStackTrace(out);
}
}
/** * Run the test. Information in the test header is used to determine * how to run the test.
*/ privatevoid run(PrintWriter out, Set<String> keys, boolean raw, boolean verbose) throws IOException {
List<String> opts = new ArrayList<String>(); if (!modulePathFiles.isEmpty()) {
File modulepathDir = new File(tempDir, "modulepath");
modulepathDir.mkdirs();
clean(modulepathDir); boolean hasModuleInfo =
modulePathFiles.stream()
.anyMatch(f -> f.getName().equalsIgnoreCase("module-info.java"));
Path modulePath = new File(file, "modulepath").toPath().toAbsolutePath(); if (hasModuleInfo) { //ordinary modules
List<String> sOpts =
Arrays.asList("-d", modulepathDir.getPath(), "--module-source-path", modulePath.toString()); new Jsr199Compiler(verbose).run(null, null, false, sOpts, modulePathFiles);
} else { //automatic modules:
Map<String, List<Path>> module2Files =
modulePathFiles.stream()
.map(f -> f.toPath().toAbsolutePath())
.collect(Collectors.groupingBy(p -> modulePath.relativize(p)
.getName(0)
.toString())); for (Entry<String, List<Path>> e : module2Files.entrySet()) {
File scratchDir = new File(tempDir, "scratch");
scratchDir.mkdirs();
clean(scratchDir);
List<String> sOpts =
Arrays.asList("-d", scratchDir.getPath()); new Jsr199Compiler(verbose).run(null, null, false,
sOpts,
e.getValue().stream()
.map(p -> p.toFile())
.collect(Collectors.toList())); try (JarOutputStream jarOut = new JarOutputStream(new FileOutputStream(new File(modulepathDir, e.getKey() + ".jar")))) {
Files.find(scratchDir.toPath(), Integer.MAX_VALUE, (p, attr) -> attr.isRegularFile())
.forEach(p -> { try (InputStream in = Files.newInputStream(p)) {
jarOut.putNextEntry(new ZipEntry(scratchDir.toPath()
.relativize(p)
.toString()));
jarOut.write(in.readAllBytes());
} catch (IOException ex) { thrownew IllegalStateException(ex);
}
});
}
}
}
opts.add("--module-path");
opts.add(modulepathDir.getAbsolutePath());
}
if (!classPathFiles.isEmpty()) {
File classpathDir = new File(tempDir, "classpath");
classpathDir.mkdirs();
clean(classpathDir);
List<String> sOpts = Arrays.asList("-d", classpathDir.getPath()); new Jsr199Compiler(verbose).run(null, null, false, sOpts, classPathFiles);
opts.add("--class-path");
opts.add(classpathDir.getAbsolutePath());
}
File classesDir = new File(tempDir, "classes");
classesDir.mkdirs();
clean(classesDir);
opts.add("-d");
opts.add(classesDir.getPath()); if (options != null)
opts.addAll(evalProperties(options));
if (procFiles.size() > 0) {
List<String> pOpts = new ArrayList<>(Arrays.asList("-d", classesDir.getPath()));
// hack to automatically add exports; a better solution would be to grep the // source for import statements or a magic comment for (File pf: procFiles) { if (pf.getName().equals("CreateBadClassFile.java")) {
pOpts.add("--add-modules=jdk.jdeps");
pOpts.add("--add-exports=jdk.jdeps/com.sun.tools.classfile=ALL-UNNAMED");
}
}
new Jsr199Compiler(verbose).run(null, null, false, pOpts, procFiles);
opts.add("-classpath"); // avoid using -processorpath for now
opts.add(classesDir.getPath());
createAnnotationServicesFile(classesDir, procFiles);
} elseif (options != null) { int i = options.indexOf("-processor"); // check for built-in anno-processor(s) if (i != -1 && options.get(i + 1).equals("DocCommentProcessor")) {
opts.add("-classpath");
opts.add(System.getProperty("test.classes"));
}
}
List<File> files = srcFiles;
if (srcPathDir != null) {
opts.add("-sourcepath");
opts.add(srcPathDir.getPath());
}
if (moduleSourcePathDir != null) {
opts.add("--module-source-path");
opts.add(moduleSourcePathDir.getPath());
files = new ArrayList<>();
files.addAll(moduleSourcePathFiles);
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
}
if (patchModulePathDir != null) { for (File mod : patchModulePathDir.listFiles()) {
opts.add("--patch-module");
opts.add(mod.getName() + "=" + mod.getPath());
}
files = new ArrayList<>();
files.addAll(patchModulePathFiles);
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
}
if (additionalFiles.size() > 0) {
List<String> sOpts = Arrays.asList("-d", classesDir.getPath()); new Jsr199Compiler(verbose).run(null, null, false, sOpts, additionalFiles);
}
try {
Compiler c = Compiler.getCompiler(runOpts, verbose);
c.run(out, keys, raw, opts, files);
} catch (IllegalArgumentException e) { if (out != null) {
out.println("Invalid value for run tag: " + runOpts);
}
}
}
privatestatic List<String> evalProperties(List<String> args) { boolean fast = true; for (String arg : args) {
fast = fast && (arg.indexOf("${") == -1);
} if (fast) { return args;
}
List<String> newArgs = new ArrayList<>(); for (String arg : args) {
newArgs.add(evalProperties(arg));
} return newArgs;
}
@Override public String toString() { return file.getPath();
}
/** * Read the contents of a file.
*/ private String read(File f) throws IOException { byte[] bytes = newbyte[(int) f.length()];
DataInputStream in = new DataInputStream(new FileInputStream(f)); try {
in.readFully(bytes);
} finally {
in.close();
} returnnew String(bytes);
}
/** * Clean the contents of a directory.
*/ boolean clean(File dir) { boolean ok = true; for (File f: dir.listFiles()) { if (f.isDirectory())
ok &= clean(f);
ok &= f.delete();
} return ok;
}
/** * Compile using the JSR 199 API. The diagnostics generated are * scanned for resource keys. Not all diagnostic keys are generated * via the JSR 199 API -- for example, rich diagnostics are not directly * accessible, and some diagnostics generated by the file manager may * not be generated (for example, the JSR 199 file manager does not see * -Xlint:path).
*/ staticclass Jsr199Compiler extends Compiler {
List<String> fmOpts;
Jsr199Compiler(boolean verbose, String... args) { super(verbose); for (int i = 0; i < args.length; i++) {
String arg = args[i]; if (arg.equals("-filemanager") && (i + 1 < args.length)) {
fmOpts = Arrays.asList(args[++i].split(","));
} else thrownew IllegalArgumentException(arg);
}
}
CompilationTask t = c.getTask(out, fm, dc, opts, null, fos); Boolean ok = t.call();
if (keys != null) { for (Diagnostic<? extends JavaFileObject> d: dc.getDiagnostics()) {
scanForKeys(unwrap(d), keys);
}
}
return ok;
} finally {
close(fm);
}
}
/** * Scan a diagnostic for resource keys. This will not detect additional * sub diagnostics that might be generated by a rich diagnostic formatter.
*/ privatestaticvoid scanForKeys(JCDiagnostic d, Set<String> keys) {
keys.add(d.getCode()); for (Object o: d.getArgs()) { if (o instanceof JCDiagnostic) {
scanForKeys((JCDiagnostic) o, keys);
}
} for (JCDiagnostic sd: d.getSubdiagnostics())
scanForKeys(sd, keys);
}
/** * Run the test using the standard simple entry point.
*/ staticclass SimpleCompiler extends Compiler {
SimpleCompiler(boolean verbose) { super(verbose);
}
if (keys != null || raw)
args.add("-XDrawDiagnostics");
args.addAll(opts); for (File f: files)
args.add(f.getPath());
try {
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line; while ((line = in.readLine()) != null) { if (keys != null)
scanForKeys(line, keys);
} int rc = p.waitFor();
privatestaticvoid scanForKeys(String text, Set<String> keys) {
StringTokenizer st = new StringTokenizer(text, " ,\r\n():"); while (st.hasMoreElements()) {
String t = st.nextToken(); if (t.startsWith("compiler."))
keys.add(t);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.