test/tools/javac/diags/Example.java

Wed, 21 Sep 2011 21:56:53 -0700

author
jjg
date
Wed, 21 Sep 2011 21:56:53 -0700
changeset 1096
b0d5f00e69f7
parent 1073
f85d980faaf8
child 1097
497571d34112
permissions
-rw-r--r--

7092965: javac should not close processorClassLoader before end of compilation
Reviewed-by: darcy

jjg@610 1 /*
jjg@842 2 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
jjg@610 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
jjg@610 4 *
jjg@610 5 * This code is free software; you can redistribute it and/or modify it
jjg@610 6 * under the terms of the GNU General Public License version 2 only, as
jjg@610 7 * published by the Free Software Foundation.
jjg@610 8 *
jjg@610 9 * This code is distributed in the hope that it will be useful, but WITHOUT
jjg@610 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
jjg@610 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
jjg@610 12 * version 2 for more details (a copy is included in the LICENSE file that
jjg@610 13 * accompanied this code).
jjg@610 14 *
jjg@610 15 * You should have received a copy of the GNU General Public License version
jjg@610 16 * 2 along with this work; if not, write to the Free Software Foundation,
jjg@610 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
jjg@610 18 *
jjg@610 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
jjg@610 20 * or visit www.oracle.com if you need additional information or have any
jjg@610 21 * questions.
jjg@610 22 */
jjg@610 23
jjg@610 24 import java.io.*;
jjg@1073 25 import java.net.URL;
jjg@1073 26 import java.net.URLClassLoader;
jjg@610 27 import java.util.*;
jjg@610 28 import java.util.regex.*;
jjg@1073 29 import javax.annotation.processing.Processor;
jjg@610 30 import javax.tools.Diagnostic;
jjg@610 31 import javax.tools.DiagnosticCollector;
jjg@610 32 import javax.tools.JavaCompiler;
jjg@610 33 import javax.tools.JavaCompiler.CompilationTask;
jjg@610 34 import javax.tools.JavaFileObject;
jjg@610 35 import javax.tools.StandardJavaFileManager;
jjg@610 36 import javax.tools.ToolProvider;
jjg@610 37
jjg@610 38 // The following two classes are both used, but cannot be imported directly
jjg@610 39 // import com.sun.tools.javac.Main
jjg@610 40 // import com.sun.tools.javac.main.Main
jjg@610 41
jjg@1073 42 import com.sun.tools.javac.api.ClientCodeWrapper;
jjg@1073 43 import com.sun.tools.javac.file.JavacFileManager;
jjg@610 44 import com.sun.tools.javac.util.Context;
jjg@610 45 import com.sun.tools.javac.util.JavacMessages;
jjg@610 46 import com.sun.tools.javac.util.JCDiagnostic;
jjg@610 47
jjg@610 48 /**
jjg@610 49 * Class to handle example code designed to illustrate javac diagnostic messages.
jjg@610 50 */
jjg@610 51 class Example implements Comparable<Example> {
jjg@610 52 /* Create an Example from the files found at path.
jjg@610 53 * The head of the file, up to the first Java code, is scanned
jjg@610 54 * for information about the test, such as what resource keys it
jjg@610 55 * generates when run, what options are required to run it, and so on.
jjg@610 56 */
jjg@610 57 Example(File file) {
jjg@610 58 this.file = file;
jjg@610 59 declaredKeys = new TreeSet<String>();
jjg@610 60 srcFiles = new ArrayList<File>();
jjg@610 61 procFiles = new ArrayList<File>();
jjg@610 62 supportFiles = new ArrayList<File>();
jjg@610 63 srcPathFiles = new ArrayList<File>();
jjg@610 64
jjg@610 65 findFiles(file, srcFiles);
jjg@610 66 for (File f: srcFiles) {
jjg@610 67 parse(f);
jjg@610 68 }
jjg@610 69
jjg@610 70 if (infoFile == null)
jjg@610 71 throw new Error("Example " + file + " has no info file");
jjg@610 72 }
jjg@610 73
jjg@610 74 private void findFiles(File f, List<File> files) {
jjg@610 75 if (f.isDirectory()) {
jjg@610 76 for (File c: f.listFiles()) {
jjg@610 77 if (files == srcFiles && c.getName().equals("processors"))
jjg@610 78 findFiles(c, procFiles);
jjg@610 79 else if (files == srcFiles && c.getName().equals("sourcepath")) {
jjg@610 80 srcPathDir = c;
jjg@610 81 findFiles(c, srcPathFiles);
jjg@610 82 } else if (files == srcFiles && c.getName().equals("support"))
jjg@610 83 findFiles(c, supportFiles);
jjg@610 84 else
jjg@610 85 findFiles(c, files);
jjg@610 86 }
jjg@610 87 } else if (f.isFile() && f.getName().endsWith(".java")) {
jjg@610 88 files.add(f);
jjg@610 89 }
jjg@610 90 }
jjg@610 91
jjg@610 92 private void parse(File f) {
jjg@610 93 Pattern keyPat = Pattern.compile(" *// *key: *([^ ]+) *");
jjg@610 94 Pattern optPat = Pattern.compile(" *// *options: *(.*)");
jjg@610 95 Pattern runPat = Pattern.compile(" *// *run: *(.*)");
jjg@610 96 Pattern javaPat = Pattern.compile(" *@?[A-Za-z].*");
jjg@610 97 try {
jjg@610 98 String[] lines = read(f).split("[\r\n]+");
jjg@610 99 for (String line: lines) {
jjg@610 100 Matcher keyMatch = keyPat.matcher(line);
jjg@610 101 if (keyMatch.matches()) {
jjg@610 102 foundInfo(f);
jjg@610 103 declaredKeys.add(keyMatch.group(1));
jjg@610 104 continue;
jjg@610 105 }
jjg@610 106 Matcher optMatch = optPat.matcher(line);
jjg@610 107 if (optMatch.matches()) {
jjg@610 108 foundInfo(f);
jjg@610 109 options = Arrays.asList(optMatch.group(1).trim().split(" +"));
jjg@610 110 continue;
jjg@610 111 }
jjg@610 112 Matcher runMatch = runPat.matcher(line);
jjg@610 113 if (runMatch.matches()) {
jjg@610 114 foundInfo(f);
jjg@610 115 runOpts = Arrays.asList(runMatch.group(1).trim().split(" +"));
jjg@610 116 }
jjg@610 117 if (javaPat.matcher(line).matches())
jjg@610 118 break;
jjg@610 119 }
jjg@610 120 } catch (IOException e) {
jjg@610 121 throw new Error(e);
jjg@610 122 }
jjg@610 123 }
jjg@610 124
jjg@610 125 private void foundInfo(File file) {
jjg@610 126 if (infoFile != null && !infoFile.equals(file))
jjg@610 127 throw new Error("multiple info files found: " + infoFile + ", " + file);
jjg@610 128 infoFile = file;
jjg@610 129 }
jjg@610 130
jjg@610 131 String getName() {
jjg@610 132 return file.getName();
jjg@610 133 }
jjg@610 134
jjg@610 135 /**
jjg@610 136 * Get the set of resource keys that this test declares it will generate
jjg@610 137 * when it is run.
jjg@610 138 */
jjg@610 139 Set<String> getDeclaredKeys() {
jjg@610 140 return declaredKeys;
jjg@610 141 }
jjg@610 142
jjg@610 143 /**
jjg@610 144 * Get the set of resource keys that this test generates when it is run.
jjg@610 145 * The test will be run if it has not already been run.
jjg@610 146 */
jjg@610 147 Set<String> getActualKeys() {
jjg@610 148 if (actualKeys == null)
jjg@610 149 actualKeys = run(false);
jjg@610 150 return actualKeys;
jjg@610 151 }
jjg@610 152
jjg@610 153 /**
jjg@610 154 * Run the test. Information in the test header is used to determine
jjg@610 155 * how to run the test.
jjg@610 156 */
jjg@610 157 void run(PrintWriter out, boolean raw, boolean verbose) {
jjg@610 158 if (out == null)
jjg@610 159 throw new NullPointerException();
jjg@610 160 try {
jjg@610 161 run(out, null, raw, verbose);
jjg@610 162 } catch (IOException e) {
jjg@610 163 e.printStackTrace(out);
jjg@610 164 }
jjg@610 165 }
jjg@610 166
jjg@610 167 Set<String> run(boolean verbose) {
jjg@610 168 Set<String> keys = new TreeSet<String>();
jjg@610 169 try {
jjg@610 170 run(null, keys, true, verbose);
jjg@610 171 } catch (IOException e) {
jjg@842 172 e.printStackTrace(System.err);
jjg@610 173 }
jjg@610 174 return keys;
jjg@610 175 }
jjg@610 176
jjg@610 177 /**
jjg@610 178 * Run the test. Information in the test header is used to determine
jjg@610 179 * how to run the test.
jjg@610 180 */
jjg@610 181 private void run(PrintWriter out, Set<String> keys, boolean raw, boolean verbose)
jjg@610 182 throws IOException {
jjg@610 183 ClassLoader loader = getClass().getClassLoader();
jjg@610 184 if (supportFiles.size() > 0) {
jjg@610 185 File supportDir = new File(tempDir, "support");
jjg@610 186 supportDir.mkdirs();
jjg@610 187 clean(supportDir);
jjg@610 188 List<String> sOpts = Arrays.asList("-d", supportDir.getPath());
jjg@610 189 new Jsr199Compiler(verbose).run(null, null, false, sOpts, procFiles);
jjg@610 190 URLClassLoader ucl =
jjg@610 191 new URLClassLoader(new URL[] { supportDir.toURI().toURL() }, loader);
jjg@610 192 loader = ucl;
jjg@610 193 }
jjg@610 194
jjg@610 195 File classesDir = new File(tempDir, "classes");
jjg@610 196 classesDir.mkdirs();
jjg@610 197 clean(classesDir);
jjg@610 198
jjg@610 199 List<String> opts = new ArrayList<String>();
jjg@610 200 opts.add("-d");
jjg@610 201 opts.add(classesDir.getPath());
jjg@610 202 if (options != null)
jjg@610 203 opts.addAll(options);
jjg@610 204
jjg@610 205 if (procFiles.size() > 0) {
jjg@610 206 List<String> pOpts = Arrays.asList("-d", classesDir.getPath());
jjg@610 207 new Jsr199Compiler(verbose).run(null, null, false, pOpts, procFiles);
jjg@610 208 opts.add("-classpath"); // avoid using -processorpath for now
jjg@610 209 opts.add(classesDir.getPath());
jjg@610 210 createAnnotationServicesFile(classesDir, procFiles);
jjg@610 211 }
jjg@610 212
jjg@610 213 if (srcPathDir != null) {
jjg@610 214 opts.add("-sourcepath");
jjg@610 215 opts.add(srcPathDir.getPath());
jjg@610 216 }
jjg@610 217
jjg@610 218 try {
jjg@610 219 Compiler c = Compiler.getCompiler(runOpts, verbose);
jjg@610 220 c.run(out, keys, raw, opts, srcFiles);
jjg@610 221 } catch (IllegalArgumentException e) {
jjg@610 222 if (out != null) {
jjg@610 223 out.println("Invalid value for run tag: " + runOpts);
jjg@610 224 }
jjg@610 225 }
jjg@610 226 }
jjg@610 227
jjg@610 228 void createAnnotationServicesFile(File dir, List<File> procFiles) throws IOException {
jjg@610 229 File servicesDir = new File(new File(dir, "META-INF"), "services");
jjg@610 230 servicesDir.mkdirs();
jjg@610 231 File annoServices = new File(servicesDir, Processor.class.getName());
jjg@610 232 Writer out = new FileWriter(annoServices);
jjg@610 233 try {
jjg@610 234 for (File f: procFiles) {
jjg@610 235 out.write(f.getName().toString().replace(".java", ""));
jjg@610 236 }
jjg@610 237 } finally {
jjg@610 238 out.close();
jjg@610 239 }
jjg@610 240 }
jjg@610 241
jjg@610 242 @Override
jjg@610 243 public int compareTo(Example e) {
jjg@610 244 return file.compareTo(e.file);
jjg@610 245 }
jjg@610 246
jjg@610 247 @Override
jjg@610 248 public String toString() {
jjg@610 249 return file.getPath();
jjg@610 250 }
jjg@610 251
jjg@610 252 /**
jjg@610 253 * Read the contents of a file.
jjg@610 254 */
jjg@610 255 private String read(File f) throws IOException {
jjg@610 256 byte[] bytes = new byte[(int) f.length()];
jjg@610 257 DataInputStream in = new DataInputStream(new FileInputStream(f));
jjg@610 258 try {
jjg@610 259 in.readFully(bytes);
jjg@610 260 } finally {
jjg@610 261 in.close();
jjg@610 262 }
jjg@610 263 return new String(bytes);
jjg@610 264 }
jjg@610 265
jjg@610 266 /**
jjg@610 267 * Clean the contents of a directory.
jjg@610 268 */
jjg@610 269 boolean clean(File dir) {
jjg@610 270 boolean ok = true;
jjg@610 271 for (File f: dir.listFiles()) {
jjg@610 272 if (f.isDirectory())
jjg@610 273 ok &= clean(f);
jjg@610 274 ok &= f.delete();
jjg@610 275 }
jjg@610 276 return ok;
jjg@610 277 }
jjg@610 278
jjg@610 279 File file;
jjg@610 280 List<File> srcFiles;
jjg@610 281 List<File> procFiles;
jjg@610 282 File srcPathDir;
jjg@610 283 List<File> srcPathFiles;
jjg@610 284 List<File> supportFiles;
jjg@610 285 File infoFile;
jjg@610 286 private List<String> runOpts;
jjg@610 287 private List<String> options;
jjg@610 288 private Set<String> actualKeys;
jjg@610 289 private Set<String> declaredKeys;
jjg@610 290
jjg@610 291 static File tempDir = new File(System.getProperty("java.io.tmpdir"));
jjg@610 292 static void setTempDir(File tempDir) {
jjg@610 293 Example.tempDir = tempDir;
jjg@610 294 }
jjg@610 295
jjg@610 296 abstract static class Compiler {
jjg@842 297 interface Factory {
jjg@842 298 Compiler getCompiler(List<String> opts, boolean verbose);
jjg@842 299 }
jjg@842 300
jjg@842 301 static class DefaultFactory implements Factory {
jjg@842 302 public Compiler getCompiler(List<String> opts, boolean verbose) {
jjg@610 303 String first;
jjg@610 304 String[] rest;
jjg@842 305 if (opts == null || opts.isEmpty()) {
jjg@610 306 first = null;
jjg@610 307 rest = new String[0];
jjg@610 308 } else {
jjg@610 309 first = opts.get(0);
jjg@610 310 rest = opts.subList(1, opts.size()).toArray(new String[opts.size() - 1]);
jjg@610 311 }
jjg@610 312 if (first == null || first.equals("jsr199"))
jjg@610 313 return new Jsr199Compiler(verbose, rest);
jjg@610 314 else if (first.equals("simple"))
jjg@610 315 return new SimpleCompiler(verbose);
jjg@610 316 else if (first.equals("backdoor"))
jjg@610 317 return new BackdoorCompiler(verbose);
jjg@610 318 else
jjg@610 319 throw new IllegalArgumentException(first);
jjg@842 320 }
jjg@842 321 }
jjg@842 322
jjg@842 323 static Factory factory;
jjg@842 324
jjg@842 325 static Compiler getCompiler(List<String> opts, boolean verbose) {
jjg@842 326 if (factory == null)
jjg@842 327 factory = new DefaultFactory();
jjg@842 328
jjg@842 329 return factory.getCompiler(opts, verbose);
jjg@610 330 }
jjg@610 331
jjg@610 332 protected Compiler(boolean verbose) {
jjg@610 333 this.verbose = verbose;
jjg@610 334 }
jjg@610 335
jjg@610 336 abstract boolean run(PrintWriter out, Set<String> keys, boolean raw,
jjg@610 337 List<String> opts, List<File> files);
jjg@610 338
jjg@610 339 void setSupportClassLoader(ClassLoader cl) {
jjg@610 340 loader = cl;
jjg@610 341 }
jjg@610 342
jjg@610 343 protected ClassLoader loader;
jjg@610 344 protected boolean verbose;
jjg@610 345 }
jjg@610 346
jjg@610 347 /**
jjg@610 348 * Compile using the JSR 199 API. The diagnostics generated are
jjg@610 349 * scanned for resource keys. Not all diagnostic keys are generated
jjg@610 350 * via the JSR 199 API -- for example, rich diagnostics are not directly
jjg@610 351 * accessible, and some diagnostics generated by the file manager may
jjg@610 352 * not be generated (for example, the JSR 199 file manager does not see
jjg@610 353 * -Xlint:path).
jjg@610 354 */
jjg@610 355 static class Jsr199Compiler extends Compiler {
jjg@610 356 List<String> fmOpts;
jjg@610 357
jjg@610 358 Jsr199Compiler(boolean verbose, String... args) {
jjg@610 359 super(verbose);
jjg@610 360 for (int i = 0; i < args.length; i++) {
jjg@610 361 String arg = args[i];
jjg@610 362 if (arg.equals("-filemanager") && (i + 1 < args.length)) {
jjg@610 363 fmOpts = Arrays.asList(args[++i].split(","));
jjg@610 364 } else
jjg@610 365 throw new IllegalArgumentException(arg);
jjg@610 366 }
jjg@610 367 }
jjg@610 368
jjg@610 369 @Override
jjg@610 370 boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
jjg@610 371 if (out != null && keys != null)
jjg@610 372 throw new IllegalArgumentException();
jjg@610 373
jjg@610 374 if (verbose)
jjg@610 375 System.err.println("run_jsr199: " + opts + " " + files);
jjg@610 376
jjg@610 377 DiagnosticCollector<JavaFileObject> dc = null;
jjg@610 378 if (keys != null)
jjg@610 379 dc = new DiagnosticCollector<JavaFileObject>();
jjg@610 380
jjg@610 381 if (raw) {
jjg@610 382 List<String> newOpts = new ArrayList<String>();
jjg@610 383 newOpts.add("-XDrawDiagnostics");
jjg@610 384 newOpts.addAll(opts);
jjg@610 385 opts = newOpts;
jjg@610 386 }
jjg@610 387
jjg@610 388 JavaCompiler c = ToolProvider.getSystemJavaCompiler();
jjg@610 389
jjg@610 390 StandardJavaFileManager fm = c.getStandardFileManager(dc, null, null);
jjg@610 391 if (fmOpts != null)
jjg@610 392 fm = new FileManager(fm, fmOpts);
jjg@610 393
jjg@610 394 Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
jjg@610 395
jjg@610 396 CompilationTask t = c.getTask(out, fm, dc, opts, null, fos);
jjg@610 397 Boolean ok = t.call();
jjg@610 398
jjg@610 399 if (keys != null) {
jjg@610 400 for (Diagnostic<? extends JavaFileObject> d: dc.getDiagnostics()) {
jjg@1073 401 scanForKeys(unwrap(d), keys);
jjg@610 402 }
jjg@610 403 }
jjg@610 404
jjg@610 405 return ok;
jjg@610 406 }
jjg@610 407
jjg@610 408 /**
jjg@610 409 * Scan a diagnostic for resource keys. This will not detect additional
jjg@610 410 * sub diagnostics that might be generated by a rich diagnostic formatter.
jjg@610 411 */
jjg@610 412 private static void scanForKeys(JCDiagnostic d, Set<String> keys) {
jjg@610 413 keys.add(d.getCode());
jjg@610 414 for (Object o: d.getArgs()) {
jjg@610 415 if (o instanceof JCDiagnostic) {
jjg@610 416 scanForKeys((JCDiagnostic) o, keys);
jjg@610 417 }
jjg@610 418 }
jjg@610 419 for (JCDiagnostic sd: d.getSubdiagnostics())
mcimadamore@689 420 scanForKeys(sd, keys);
jjg@610 421 }
jjg@1073 422
jjg@1073 423 private JCDiagnostic unwrap(Diagnostic<? extends JavaFileObject> diagnostic) {
jjg@1073 424 if (diagnostic instanceof JCDiagnostic)
jjg@1073 425 return (JCDiagnostic) diagnostic;
jjg@1073 426 if (diagnostic instanceof ClientCodeWrapper.DiagnosticSourceUnwrapper)
jjg@1073 427 return ((ClientCodeWrapper.DiagnosticSourceUnwrapper)diagnostic).d;
jjg@1073 428 throw new IllegalArgumentException();
jjg@1073 429 }
jjg@610 430 }
jjg@610 431
jjg@610 432 /**
jjg@610 433 * Run the test using the standard simple entry point.
jjg@610 434 */
jjg@610 435 static class SimpleCompiler extends Compiler {
jjg@610 436 SimpleCompiler(boolean verbose) {
jjg@610 437 super(verbose);
jjg@610 438 }
jjg@610 439
jjg@610 440 @Override
jjg@610 441 boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
jjg@610 442 if (out != null && keys != null)
jjg@610 443 throw new IllegalArgumentException();
jjg@610 444
jjg@610 445 if (verbose)
jjg@610 446 System.err.println("run_simple: " + opts + " " + files);
jjg@610 447
jjg@636 448 List<String> args = new ArrayList<String>();
jjg@610 449
jjg@610 450 if (keys != null || raw)
jjg@610 451 args.add("-XDrawDiagnostics");
jjg@610 452
jjg@610 453 args.addAll(opts);
jjg@610 454 for (File f: files)
jjg@610 455 args.add(f.getPath());
jjg@610 456
jjg@610 457 StringWriter sw = null;
jjg@610 458 PrintWriter pw;
jjg@610 459 if (keys != null) {
jjg@610 460 sw = new StringWriter();
jjg@610 461 pw = new PrintWriter(sw);
jjg@610 462 } else
jjg@610 463 pw = out;
jjg@610 464
jjg@610 465 int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
jjg@610 466
jjg@610 467 if (keys != null) {
jjg@610 468 pw.close();
jjg@610 469 scanForKeys(sw.toString(), keys);
jjg@610 470 }
jjg@610 471
jjg@610 472 return (rc == 0);
jjg@610 473 }
jjg@610 474
jjg@610 475 private static void scanForKeys(String text, Set<String> keys) {
jjg@610 476 StringTokenizer st = new StringTokenizer(text, " ,\r\n():");
jjg@610 477 while (st.hasMoreElements()) {
jjg@610 478 String t = st.nextToken();
jjg@610 479 if (t.startsWith("compiler."))
jjg@610 480 keys.add(t);
jjg@610 481 }
jjg@610 482 }
jjg@610 483 }
jjg@610 484
jjg@610 485 static class BackdoorCompiler extends Compiler {
jjg@610 486 BackdoorCompiler(boolean verbose) {
jjg@610 487 super(verbose);
jjg@610 488 }
jjg@610 489
jjg@610 490 @Override
jjg@610 491 boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
jjg@610 492 if (out != null && keys != null)
jjg@610 493 throw new IllegalArgumentException();
jjg@610 494
jjg@610 495 if (verbose)
jjg@610 496 System.err.println("run_simple: " + opts + " " + files);
jjg@610 497
jjg@894 498 List<String> args = new ArrayList<String>();
jjg@610 499
jjg@610 500 if (out != null && raw)
jjg@610 501 args.add("-XDrawDiagnostics");
jjg@610 502
jjg@610 503 args.addAll(opts);
jjg@610 504 for (File f: files)
jjg@610 505 args.add(f.getPath());
jjg@610 506
jjg@610 507 StringWriter sw = null;
jjg@610 508 PrintWriter pw;
jjg@610 509 if (keys != null) {
jjg@610 510 sw = new StringWriter();
jjg@610 511 pw = new PrintWriter(sw);
jjg@610 512 } else
jjg@610 513 pw = out;
jjg@610 514
jjg@610 515 Context c = new Context();
jjg@610 516 JavacFileManager.preRegister(c); // can't create it until Log has been set up
jjg@610 517 MessageTracker.preRegister(c, keys);
jjg@610 518 com.sun.tools.javac.main.Main m = new com.sun.tools.javac.main.Main("javac", pw);
jjg@610 519 int rc = m.compile(args.toArray(new String[args.size()]), c);
jjg@610 520
jjg@610 521 if (keys != null) {
jjg@610 522 pw.close();
jjg@610 523 }
jjg@610 524
jjg@610 525 return (rc == 0);
jjg@610 526 }
jjg@610 527
jjg@610 528 static class MessageTracker extends JavacMessages {
mcimadamore@616 529
mcimadamore@616 530 MessageTracker(Context context) {
mcimadamore@616 531 super(context);
mcimadamore@616 532 }
mcimadamore@616 533
jjg@893 534 static void preRegister(Context c, final Set<String> keys) {
jjg@610 535 if (keys != null) {
jjg@610 536 c.put(JavacMessages.messagesKey, new Context.Factory<JavacMessages>() {
jjg@893 537 public JavacMessages make(Context c) {
mcimadamore@616 538 return new MessageTracker(c) {
jjg@610 539 @Override
jjg@610 540 public String getLocalizedString(Locale l, String key, Object... args) {
jjg@610 541 keys.add(key);
jjg@610 542 return super.getLocalizedString(l, key, args);
jjg@610 543 }
jjg@610 544 };
jjg@610 545 }
jjg@610 546 });
jjg@610 547 }
jjg@610 548 }
jjg@610 549 }
jjg@610 550
jjg@610 551 }
jjg@610 552 }

mercurial