Tue, 28 Dec 2010 15:54:52 -0800
6962318: Update copyright year
Reviewed-by: xdono
1 /*
2 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.javac.main;
28 import com.sun.tools.javac.code.Lint;
29 import com.sun.tools.javac.code.Source;
30 import com.sun.tools.javac.code.Type;
31 import com.sun.tools.javac.jvm.Target;
32 import com.sun.tools.javac.main.JavacOption.HiddenOption;
33 import com.sun.tools.javac.main.JavacOption.Option;
34 import com.sun.tools.javac.main.JavacOption.XOption;
35 import com.sun.tools.javac.util.ListBuffer;
36 import com.sun.tools.javac.util.Options;
37 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
38 import java.io.File;
39 import java.io.FileWriter;
40 import java.io.PrintWriter;
41 import java.util.EnumSet;
42 import java.util.LinkedHashMap;
43 import java.util.Map;
44 import java.util.Set;
45 import javax.lang.model.SourceVersion;
47 import static com.sun.tools.javac.main.OptionName.*;
49 /**
50 * TODO: describe com.sun.tools.javac.main.RecognizedOptions
51 *
52 * <p><b>This is NOT part of any supported API.
53 * If you write code that depends on this, you do so at your own
54 * risk. This code and its internal interfaces are subject to change
55 * or deletion without notice.</b></p>
56 */
57 public class RecognizedOptions {
59 private RecognizedOptions() {}
61 public interface OptionHelper {
63 void setOut(PrintWriter out);
65 void error(String key, Object... args);
67 void printVersion();
69 void printFullVersion();
71 void printHelp();
73 void printXhelp();
75 void addFile(File f);
77 void addClassName(String s);
79 }
81 public static class GrumpyHelper implements OptionHelper {
83 public void setOut(PrintWriter out) {
84 throw new IllegalArgumentException();
85 }
87 public void error(String key, Object... args) {
88 throw new IllegalArgumentException(Main.getLocalizedString(key, args));
89 }
91 public void printVersion() {
92 throw new IllegalArgumentException();
93 }
95 public void printFullVersion() {
96 throw new IllegalArgumentException();
97 }
99 public void printHelp() {
100 throw new IllegalArgumentException();
101 }
103 public void printXhelp() {
104 throw new IllegalArgumentException();
105 }
107 public void addFile(File f) {
108 throw new IllegalArgumentException(f.getPath());
109 }
111 public void addClassName(String s) {
112 throw new IllegalArgumentException(s);
113 }
115 }
117 static Set<OptionName> javacOptions = EnumSet.of(
118 G,
119 G_NONE,
120 G_CUSTOM,
121 XLINT,
122 XLINT_CUSTOM,
123 NOWARN,
124 VERBOSE,
125 DEPRECATION,
126 CLASSPATH,
127 CP,
128 SOURCEPATH,
129 BOOTCLASSPATH,
130 XBOOTCLASSPATH_PREPEND,
131 XBOOTCLASSPATH_APPEND,
132 XBOOTCLASSPATH,
133 EXTDIRS,
134 DJAVA_EXT_DIRS,
135 ENDORSEDDIRS,
136 DJAVA_ENDORSED_DIRS,
137 PROC,
138 PROCESSOR,
139 PROCESSORPATH,
140 D,
141 S,
142 IMPLICIT,
143 ENCODING,
144 SOURCE,
145 TARGET,
146 VERSION,
147 FULLVERSION,
148 DIAGS,
149 HELP,
150 A,
151 X,
152 J,
153 MOREINFO,
154 WERROR,
155 // COMPLEXINFERENCE,
156 PROMPT,
157 DOE,
158 PRINTSOURCE,
159 WARNUNCHECKED,
160 XMAXERRS,
161 XMAXWARNS,
162 XSTDOUT,
163 XPKGINFO,
164 XPRINT,
165 XPRINTROUNDS,
166 XPRINTPROCESSORINFO,
167 XPREFER,
168 O,
169 XJCOV,
170 XD,
171 SOURCEFILE);
173 static Set<OptionName> javacFileManagerOptions = EnumSet.of(
174 CLASSPATH,
175 CP,
176 SOURCEPATH,
177 BOOTCLASSPATH,
178 XBOOTCLASSPATH_PREPEND,
179 XBOOTCLASSPATH_APPEND,
180 XBOOTCLASSPATH,
181 EXTDIRS,
182 DJAVA_EXT_DIRS,
183 ENDORSEDDIRS,
184 DJAVA_ENDORSED_DIRS,
185 PROCESSORPATH,
186 D,
187 S,
188 ENCODING,
189 SOURCE);
191 static Set<OptionName> javacToolOptions = EnumSet.of(
192 G,
193 G_NONE,
194 G_CUSTOM,
195 XLINT,
196 XLINT_CUSTOM,
197 NOWARN,
198 VERBOSE,
199 DEPRECATION,
200 PROC,
201 PROCESSOR,
202 IMPLICIT,
203 SOURCE,
204 TARGET,
205 // VERSION,
206 // FULLVERSION,
207 // HELP,
208 A,
209 // X,
210 // J,
211 MOREINFO,
212 WERROR,
213 // COMPLEXINFERENCE,
214 PROMPT,
215 DOE,
216 PRINTSOURCE,
217 WARNUNCHECKED,
218 XMAXERRS,
219 XMAXWARNS,
220 // XSTDOUT,
221 XPKGINFO,
222 XPRINT,
223 XPRINTROUNDS,
224 XPRINTPROCESSORINFO,
225 XPREFER,
226 O,
227 XJCOV,
228 XD);
230 static Option[] getJavaCompilerOptions(OptionHelper helper) {
231 return getOptions(helper, javacOptions);
232 }
234 public static Option[] getJavacFileManagerOptions(OptionHelper helper) {
235 return getOptions(helper, javacFileManagerOptions);
236 }
238 public static Option[] getJavacToolOptions(OptionHelper helper) {
239 return getOptions(helper, javacToolOptions);
240 }
242 static Option[] getOptions(OptionHelper helper, Set<OptionName> desired) {
243 ListBuffer<Option> options = new ListBuffer<Option>();
244 for (Option option : getAll(helper))
245 if (desired.contains(option.getName()))
246 options.append(option);
247 return options.toArray(new Option[options.length()]);
248 }
250 /**
251 * Get all the recognized options.
252 * @param helper an {@code OptionHelper} to help when processing options
253 * @return an array of options
254 */
255 public static Option[] getAll(final OptionHelper helper) {
256 return new Option[] {
257 new Option(G, "opt.g"),
258 new Option(G_NONE, "opt.g.none") {
259 @Override
260 public boolean process(Options options, String option) {
261 options.put("-g:", "none");
262 return false;
263 }
264 },
266 new Option(G_CUSTOM, "opt.g.lines.vars.source",
267 Option.ChoiceKind.ANYOF, "lines", "vars", "source"),
269 new XOption(XLINT, "opt.Xlint"),
270 new XOption(XLINT_CUSTOM, "opt.Xlint.suboptlist",
271 Option.ChoiceKind.ANYOF, getXLintChoices()),
273 // -nowarn is retained for command-line backward compatibility
274 new Option(NOWARN, "opt.nowarn") {
275 @Override
276 public boolean process(Options options, String option) {
277 options.put("-Xlint:none", option);
278 return false;
279 }
280 },
282 new Option(VERBOSE, "opt.verbose"),
284 // -deprecation is retained for command-line backward compatibility
285 new Option(DEPRECATION, "opt.deprecation") {
286 @Override
287 public boolean process(Options options, String option) {
288 options.put("-Xlint:deprecation", option);
289 return false;
290 }
291 },
293 new Option(CLASSPATH, "opt.arg.path", "opt.classpath"),
294 new Option(CP, "opt.arg.path", "opt.classpath") {
295 @Override
296 public boolean process(Options options, String option, String arg) {
297 return super.process(options, "-classpath", arg);
298 }
299 },
300 new Option(SOURCEPATH, "opt.arg.path", "opt.sourcepath"),
301 new Option(BOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") {
302 @Override
303 public boolean process(Options options, String option, String arg) {
304 options.remove("-Xbootclasspath/p:");
305 options.remove("-Xbootclasspath/a:");
306 return super.process(options, option, arg);
307 }
308 },
309 new XOption(XBOOTCLASSPATH_PREPEND,"opt.arg.path", "opt.Xbootclasspath.p"),
310 new XOption(XBOOTCLASSPATH_APPEND, "opt.arg.path", "opt.Xbootclasspath.a"),
311 new XOption(XBOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") {
312 @Override
313 public boolean process(Options options, String option, String arg) {
314 options.remove("-Xbootclasspath/p:");
315 options.remove("-Xbootclasspath/a:");
316 return super.process(options, "-bootclasspath", arg);
317 }
318 },
319 new Option(EXTDIRS, "opt.arg.dirs", "opt.extdirs"),
320 new XOption(DJAVA_EXT_DIRS, "opt.arg.dirs", "opt.extdirs") {
321 @Override
322 public boolean process(Options options, String option, String arg) {
323 return super.process(options, "-extdirs", arg);
324 }
325 },
326 new Option(ENDORSEDDIRS, "opt.arg.dirs", "opt.endorseddirs"),
327 new XOption(DJAVA_ENDORSED_DIRS, "opt.arg.dirs", "opt.endorseddirs") {
328 @Override
329 public boolean process(Options options, String option, String arg) {
330 return super.process(options, "-endorseddirs", arg);
331 }
332 },
333 new Option(PROC, "opt.proc.none.only",
334 Option.ChoiceKind.ONEOF, "none", "only"),
335 new Option(PROCESSOR, "opt.arg.class.list", "opt.processor"),
336 new Option(PROCESSORPATH, "opt.arg.path", "opt.processorpath"),
337 new Option(D, "opt.arg.directory", "opt.d"),
338 new Option(S, "opt.arg.directory", "opt.sourceDest"),
339 new Option(IMPLICIT, "opt.implicit",
340 Option.ChoiceKind.ONEOF, "none", "class"),
341 new Option(ENCODING, "opt.arg.encoding", "opt.encoding"),
342 new Option(SOURCE, "opt.arg.release", "opt.source") {
343 @Override
344 public boolean process(Options options, String option, String operand) {
345 Source source = Source.lookup(operand);
346 if (source == null) {
347 helper.error("err.invalid.source", operand);
348 return true;
349 }
350 return super.process(options, option, operand);
351 }
352 },
353 new Option(TARGET, "opt.arg.release", "opt.target") {
354 @Override
355 public boolean process(Options options, String option, String operand) {
356 Target target = Target.lookup(operand);
357 if (target == null) {
358 helper.error("err.invalid.target", operand);
359 return true;
360 }
361 return super.process(options, option, operand);
362 }
363 },
364 new Option(VERSION, "opt.version") {
365 @Override
366 public boolean process(Options options, String option) {
367 helper.printVersion();
368 return super.process(options, option);
369 }
370 },
371 new HiddenOption(FULLVERSION) {
372 @Override
373 public boolean process(Options options, String option) {
374 helper.printFullVersion();
375 return super.process(options, option);
376 }
377 },
378 new HiddenOption(DIAGS) {
379 @Override
380 public boolean process(Options options, String option) {
381 Option xd = getOptions(helper, EnumSet.of(XD))[0];
382 option = option.substring(option.indexOf('=') + 1);
383 String diagsOption = option.contains("%") ?
384 "-XDdiagsFormat=" :
385 "-XDdiags=";
386 diagsOption += option;
387 if (xd.matches(diagsOption))
388 return xd.process(options, diagsOption);
389 else
390 return false;
391 }
392 },
393 new Option(HELP, "opt.help") {
394 @Override
395 public boolean process(Options options, String option) {
396 helper.printHelp();
397 return super.process(options, option);
398 }
399 },
400 new Option(A, "opt.arg.key.equals.value","opt.A") {
401 @Override
402 String helpSynopsis() {
403 hasSuffix = true;
404 return super.helpSynopsis();
405 }
407 @Override
408 public boolean matches(String arg) {
409 return arg.startsWith("-A");
410 }
412 @Override
413 public boolean hasArg() {
414 return false;
415 }
416 // Mapping for processor options created in
417 // JavacProcessingEnvironment
418 @Override
419 public boolean process(Options options, String option) {
420 int argLength = option.length();
421 if (argLength == 2) {
422 helper.error("err.empty.A.argument");
423 return true;
424 }
425 int sepIndex = option.indexOf('=');
426 String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
427 if (!JavacProcessingEnvironment.isValidOptionName(key)) {
428 helper.error("err.invalid.A.key", option);
429 return true;
430 }
431 return process(options, option, option);
432 }
433 },
434 new Option(X, "opt.X") {
435 @Override
436 public boolean process(Options options, String option) {
437 helper.printXhelp();
438 return super.process(options, option);
439 }
440 },
442 // This option exists only for the purpose of documenting itself.
443 // It's actually implemented by the launcher.
444 new Option(J, "opt.arg.flag", "opt.J") {
445 @Override
446 String helpSynopsis() {
447 hasSuffix = true;
448 return super.helpSynopsis();
449 }
450 @Override
451 public boolean process(Options options, String option) {
452 throw new AssertionError
453 ("the -J flag should be caught by the launcher.");
454 }
455 },
457 // stop after parsing and attributing.
458 // new HiddenOption("-attrparseonly"),
460 // new Option("-moreinfo", "opt.moreinfo") {
461 new HiddenOption(MOREINFO) {
462 @Override
463 public boolean process(Options options, String option) {
464 Type.moreInfo = true;
465 return super.process(options, option);
466 }
467 },
469 // treat warnings as errors
470 new Option(WERROR, "opt.Werror"),
472 // use complex inference from context in the position of a method call argument
473 new HiddenOption(COMPLEXINFERENCE),
475 // generare source stubs
476 // new HiddenOption("-stubs"),
478 // relax some constraints to allow compiling from stubs
479 // new HiddenOption("-relax"),
481 // output source after translating away inner classes
482 // new Option("-printflat", "opt.printflat"),
483 // new HiddenOption("-printflat"),
485 // display scope search details
486 // new Option("-printsearch", "opt.printsearch"),
487 // new HiddenOption("-printsearch"),
489 // prompt after each error
490 // new Option("-prompt", "opt.prompt"),
491 new HiddenOption(PROMPT),
493 // dump stack on error
494 new HiddenOption(DOE),
496 // output source after type erasure
497 // new Option("-s", "opt.s"),
498 new HiddenOption(PRINTSOURCE),
500 // output shrouded class files
501 // new Option("-scramble", "opt.scramble"),
502 // new Option("-scrambleall", "opt.scrambleall"),
504 // display warnings for generic unchecked operations
505 new HiddenOption(WARNUNCHECKED) {
506 @Override
507 public boolean process(Options options, String option) {
508 options.put("-Xlint:unchecked", option);
509 return false;
510 }
511 },
513 new XOption(XMAXERRS, "opt.arg.number", "opt.maxerrs"),
514 new XOption(XMAXWARNS, "opt.arg.number", "opt.maxwarns"),
515 new XOption(XSTDOUT, "opt.arg.file", "opt.Xstdout") {
516 @Override
517 public boolean process(Options options, String option, String arg) {
518 try {
519 helper.setOut(new PrintWriter(new FileWriter(arg), true));
520 } catch (java.io.IOException e) {
521 helper.error("err.error.writing.file", arg, e);
522 return true;
523 }
524 return super.process(options, option, arg);
525 }
526 },
528 new XOption(XPRINT, "opt.print"),
530 new XOption(XPRINTROUNDS, "opt.printRounds"),
532 new XOption(XPRINTPROCESSORINFO, "opt.printProcessorInfo"),
534 new XOption(XPREFER, "opt.prefer",
535 Option.ChoiceKind.ONEOF, "source", "newer"),
537 new XOption(XPKGINFO, "opt.pkginfo",
538 Option.ChoiceKind.ONEOF, "always", "legacy", "nonempty"),
540 /* -O is a no-op, accepted for backward compatibility. */
541 new HiddenOption(O),
543 /* -Xjcov produces tables to support the code coverage tool jcov. */
544 new HiddenOption(XJCOV),
546 /* This is a back door to the compiler's option table.
547 * -XDx=y sets the option x to the value y.
548 * -XDx sets the option x to the value x.
549 */
550 new HiddenOption(XD) {
551 String s;
552 @Override
553 public boolean matches(String s) {
554 this.s = s;
555 return s.startsWith(name.optionName);
556 }
557 @Override
558 public boolean process(Options options, String option) {
559 s = s.substring(name.optionName.length());
560 int eq = s.indexOf('=');
561 String key = (eq < 0) ? s : s.substring(0, eq);
562 String value = (eq < 0) ? s : s.substring(eq+1);
563 options.put(key, value);
564 return false;
565 }
566 },
568 /*
569 * TODO: With apt, the matches method accepts anything if
570 * -XclassAsDecls is used; code elsewhere does the lookup to
571 * see if the class name is both legal and found.
572 *
573 * In apt, the process method adds the candiate class file
574 * name to a separate list.
575 */
576 new HiddenOption(SOURCEFILE) {
577 String s;
578 @Override
579 public boolean matches(String s) {
580 this.s = s;
581 return s.endsWith(".java") // Java source file
582 || SourceVersion.isName(s); // Legal type name
583 }
584 @Override
585 public boolean process(Options options, String option) {
586 if (s.endsWith(".java") ) {
587 File f = new File(s);
588 if (!f.exists()) {
589 helper.error("err.file.not.found", f);
590 return true;
591 }
592 if (!f.isFile()) {
593 helper.error("err.file.not.file", f);
594 return true;
595 }
596 helper.addFile(f);
597 }
598 else
599 helper.addClassName(s);
600 return false;
601 }
602 },
603 };
604 }
606 public enum PkgInfo {
607 ALWAYS, LEGACY, NONEMPTY;
608 public static PkgInfo get(Options options) {
609 String v = options.get(XPKGINFO);
610 return (v == null
611 ? PkgInfo.LEGACY
612 : PkgInfo.valueOf(v.toUpperCase()));
613 }
614 }
616 private static Map<String,Boolean> getXLintChoices() {
617 Map<String,Boolean> choices = new LinkedHashMap<String,Boolean>();
618 choices.put("all", false);
619 for (Lint.LintCategory c : Lint.LintCategory.values())
620 choices.put(c.option, c.hidden);
621 for (Lint.LintCategory c : Lint.LintCategory.values())
622 choices.put("-" + c.option, c.hidden);
623 choices.put("none", false);
624 return choices;
625 }
627 }