test/tools/javac/diags/Example.java

Mon, 21 Jan 2013 20:13:56 +0000

author
mcimadamore
date
Mon, 21 Jan 2013 20:13:56 +0000
changeset 1510
7873d37f5b37
parent 1409
33abf479f202
child 1773
3d9750039fff
permissions
-rw-r--r--

8005244: Implement overload resolution as per latest spec EDR
Summary: Add support for stuck expressions and provisional applicability
Reviewed-by: jjg

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

mercurial