Sat, 01 Dec 2007 00:00:00 +0000
Initial load
1 /*
2 * Copyright 2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
26 package com.sun.tools.javac.main;
28 import com.sun.tools.javac.code.Source;
29 import com.sun.tools.javac.code.Type;
30 import com.sun.tools.javac.jvm.Target;
31 import com.sun.tools.javac.main.JavacOption.HiddenOption;
32 import com.sun.tools.javac.main.JavacOption.Option;
33 import com.sun.tools.javac.main.JavacOption.XOption;
34 import com.sun.tools.javac.util.List;
35 import com.sun.tools.javac.util.ListBuffer;
36 import com.sun.tools.javac.util.Log;
37 import com.sun.tools.javac.util.Options;
38 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
39 import java.io.File;
40 import java.io.FileWriter;
41 import java.io.PrintWriter;
42 import java.util.EnumSet;
43 import java.util.Set;
44 import java.util.StringTokenizer;
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 API supported by Sun Microsystems.
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_CUSTOM,
138 PROCESSOR,
139 PROCESSORPATH,
140 D,
141 S,
142 IMPLICIT,
143 ENCODING,
144 SOURCE,
145 TARGET,
146 VERSION,
147 FULLVERSION,
148 HELP,
149 A,
150 X,
151 J,
152 MOREINFO,
153 WERROR,
154 // COMPLEXINFERENCE,
155 PROMPT,
156 DOE,
157 PRINTSOURCE,
158 WARNUNCHECKED,
159 XMAXERRS,
160 XMAXWARNS,
161 XSTDOUT,
162 XPRINT,
163 XPRINTROUNDS,
164 XPRINTPROCESSORINFO,
165 XPREFER,
166 O,
167 XJCOV,
168 XD,
169 SOURCEFILE);
171 static Set<OptionName> javacFileManagerOptions = EnumSet.of(
172 CLASSPATH,
173 CP,
174 SOURCEPATH,
175 BOOTCLASSPATH,
176 XBOOTCLASSPATH_PREPEND,
177 XBOOTCLASSPATH_APPEND,
178 XBOOTCLASSPATH,
179 EXTDIRS,
180 DJAVA_EXT_DIRS,
181 ENDORSEDDIRS,
182 DJAVA_ENDORSED_DIRS,
183 PROCESSORPATH,
184 D,
185 S,
186 ENCODING,
187 SOURCE);
189 static Set<OptionName> javacToolOptions = EnumSet.of(
190 G,
191 G_NONE,
192 G_CUSTOM,
193 XLINT,
194 XLINT_CUSTOM,
195 NOWARN,
196 VERBOSE,
197 DEPRECATION,
198 PROC_CUSTOM,
199 PROCESSOR,
200 IMPLICIT,
201 SOURCE,
202 TARGET,
203 // VERSION,
204 // FULLVERSION,
205 // HELP,
206 A,
207 // X,
208 // J,
209 MOREINFO,
210 WERROR,
211 // COMPLEXINFERENCE,
212 PROMPT,
213 DOE,
214 PRINTSOURCE,
215 WARNUNCHECKED,
216 XMAXERRS,
217 XMAXWARNS,
218 // XSTDOUT,
219 XPRINT,
220 XPRINTROUNDS,
221 XPRINTPROCESSORINFO,
222 XPREFER,
223 O,
224 XJCOV,
225 XD);
227 static Option[] getJavaCompilerOptions(OptionHelper helper) {
228 return getOptions(helper, javacOptions);
229 }
231 public static Option[] getJavacFileManagerOptions(OptionHelper helper) {
232 return getOptions(helper, javacFileManagerOptions);
233 }
235 public static Option[] getJavacToolOptions(OptionHelper helper) {
236 return getOptions(helper, javacToolOptions);
237 }
239 static Option[] getOptions(OptionHelper helper, Set<OptionName> desired) {
240 ListBuffer<Option> options = new ListBuffer<Option>();
241 for (Option option : getAll(helper))
242 if (desired.contains(option.getName()))
243 options.append(option);
244 return options.toArray(new Option[options.length()]);
245 }
247 /**
248 * @param out the writer to use for diagnostic output
249 */
250 public static Option[] getAll(final OptionHelper helper) {
251 return new Option[]{
252 new Option(G, "opt.g"),
253 new Option(G_NONE, "opt.g.none") {
254 public boolean process(Options options, String option) {
255 options.put("-g:", "none");
256 return false;
257 }
258 },
260 new Option(G_CUSTOM, "opt.g.lines.vars.source") {
261 public boolean matches(String s) {
262 return s.startsWith("-g:");
263 }
264 public boolean process(Options options, String option) {
265 String suboptions = option.substring(3);
266 options.put("-g:", suboptions);
267 // enter all the -g suboptions as "-g:suboption"
268 for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) {
269 String tok = t.nextToken();
270 String opt = "-g:" + tok;
271 options.put(opt, opt);
272 }
273 return false;
274 }
275 },
277 new XOption(XLINT, "opt.Xlint"),
278 new XOption(XLINT_CUSTOM, "opt.Xlint.suboptlist") {
279 public boolean matches(String s) {
280 return s.startsWith("-Xlint:");
281 }
282 public boolean process(Options options, String option) {
283 String suboptions = option.substring(7);
284 options.put("-Xlint:", suboptions);
285 // enter all the -Xlint suboptions as "-Xlint:suboption"
286 for (StringTokenizer t = new StringTokenizer(suboptions, ","); t.hasMoreTokens(); ) {
287 String tok = t.nextToken();
288 String opt = "-Xlint:" + tok;
289 options.put(opt, opt);
290 }
291 return false;
292 }
293 },
295 // -nowarn is retained for command-line backward compatibility
296 new Option(NOWARN, "opt.nowarn") {
297 public boolean process(Options options, String option) {
298 options.put("-Xlint:none", option);
299 return false;
300 }
301 },
303 new Option(VERBOSE, "opt.verbose"),
305 // -deprecation is retained for command-line backward compatibility
306 new Option(DEPRECATION, "opt.deprecation") {
307 public boolean process(Options options, String option) {
308 options.put("-Xlint:deprecation", option);
309 return false;
310 }
311 },
313 new Option(CLASSPATH, "opt.arg.path", "opt.classpath"),
314 new Option(CP, "opt.arg.path", "opt.classpath") {
315 public boolean process(Options options, String option, String arg) {
316 return super.process(options, "-classpath", arg);
317 }
318 },
319 new Option(SOURCEPATH, "opt.arg.path", "opt.sourcepath"),
320 new Option(BOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") {
321 public boolean process(Options options, String option, String arg) {
322 options.remove("-Xbootclasspath/p:");
323 options.remove("-Xbootclasspath/a:");
324 return super.process(options, option, arg);
325 }
326 },
327 new XOption(XBOOTCLASSPATH_PREPEND,"opt.arg.path", "opt.Xbootclasspath.p"),
328 new XOption(XBOOTCLASSPATH_APPEND, "opt.arg.path", "opt.Xbootclasspath.a"),
329 new XOption(XBOOTCLASSPATH, "opt.arg.path", "opt.bootclasspath") {
330 public boolean process(Options options, String option, String arg) {
331 options.remove("-Xbootclasspath/p:");
332 options.remove("-Xbootclasspath/a:");
333 return super.process(options, "-bootclasspath", arg);
334 }
335 },
336 new Option(EXTDIRS, "opt.arg.dirs", "opt.extdirs"),
337 new XOption(DJAVA_EXT_DIRS, "opt.arg.dirs", "opt.extdirs") {
338 public boolean process(Options options, String option, String arg) {
339 return super.process(options, "-extdirs", arg);
340 }
341 },
342 new Option(ENDORSEDDIRS, "opt.arg.dirs", "opt.endorseddirs"),
343 new XOption(DJAVA_ENDORSED_DIRS, "opt.arg.dirs", "opt.endorseddirs") {
344 public boolean process(Options options, String option, String arg) {
345 return super.process(options, "-endorseddirs", arg);
346 }
347 },
348 new Option(PROC_CUSTOM, "opt.proc.none.only") {
349 public boolean matches(String s) {
350 return s.equals("-proc:none") || s.equals("-proc:only");
351 }
353 public boolean process(Options options, String option) {
354 if (option.equals("-proc:none")) {
355 options.remove("-proc:only");
356 } else {
357 options.remove("-proc:none");
358 }
359 options.put(option, option);
360 return false;
361 }
362 },
363 new Option(PROCESSOR, "opt.arg.class.list", "opt.processor"),
364 new Option(PROCESSORPATH, "opt.arg.path", "opt.processorpath"),
365 new Option(D, "opt.arg.directory", "opt.d"),
366 new Option(S, "opt.arg.directory", "opt.sourceDest"),
367 new Option(IMPLICIT, "opt.implicit") {
368 public boolean matches(String s) {
369 return s.equals("-implicit:none") || s.equals("-implicit:class");
370 }
371 public boolean process(Options options, String option, String operand) {
372 int sep = option.indexOf(":");
373 options.put(option.substring(0, sep), option.substring(sep+1));
374 options.put(option,option);
375 return false;
376 }
377 },
378 new Option(ENCODING, "opt.arg.encoding", "opt.encoding"),
379 new Option(SOURCE, "opt.arg.release", "opt.source") {
380 public boolean process(Options options, String option, String operand) {
381 Source source = Source.lookup(operand);
382 if (source == null) {
383 helper.error("err.invalid.source", operand);
384 return true;
385 }
386 return super.process(options, option, operand);
387 }
388 },
389 new Option(TARGET, "opt.arg.release", "opt.target") {
390 public boolean process(Options options, String option, String operand) {
391 Target target = Target.lookup(operand);
392 if (target == null) {
393 helper.error("err.invalid.target", operand);
394 return true;
395 }
396 return super.process(options, option, operand);
397 }
398 },
399 new Option(VERSION, "opt.version") {
400 public boolean process(Options options, String option) {
401 helper.printVersion();
402 return super.process(options, option);
403 }
404 },
405 new HiddenOption(FULLVERSION) {
406 public boolean process(Options options, String option) {
407 helper.printFullVersion();
408 return super.process(options, option);
409 }
410 },
411 new Option(HELP, "opt.help") {
412 public boolean process(Options options, String option) {
413 helper.printHelp();
414 return super.process(options, option);
415 }
416 },
417 new Option(A, "opt.arg.key.equals.value","opt.A") {
418 String helpSynopsis() {
419 hasSuffix = true;
420 return super.helpSynopsis();
421 }
423 public boolean matches(String arg) {
424 return arg.startsWith("-A");
425 }
427 public boolean hasArg() {
428 return false;
429 }
430 // Mapping for processor options created in
431 // JavacProcessingEnvironment
432 public boolean process(Options options, String option) {
433 int argLength = option.length();
434 if (argLength == 2) {
435 helper.error("err.empty.A.argument");
436 return true;
437 }
438 int sepIndex = option.indexOf('=');
439 String key = option.substring(2, (sepIndex != -1 ? sepIndex : argLength) );
440 if (!JavacProcessingEnvironment.isValidOptionName(key)) {
441 helper.error("err.invalid.A.key", option);
442 return true;
443 }
444 return process(options, option, option);
445 }
446 },
447 new Option(X, "opt.X") {
448 public boolean process(Options options, String option) {
449 helper.printXhelp();
450 return super.process(options, option);
451 }
452 },
454 // This option exists only for the purpose of documenting itself.
455 // It's actually implemented by the launcher.
456 new Option(J, "opt.arg.flag", "opt.J") {
457 String helpSynopsis() {
458 hasSuffix = true;
459 return super.helpSynopsis();
460 }
461 public boolean process(Options options, String option) {
462 throw new AssertionError
463 ("the -J flag should be caught by the launcher.");
464 }
465 },
467 // stop after parsing and attributing.
468 // new HiddenOption("-attrparseonly"),
470 // new Option("-moreinfo", "opt.moreinfo") {
471 new HiddenOption(MOREINFO) {
472 public boolean process(Options options, String option) {
473 Type.moreInfo = true;
474 return super.process(options, option);
475 }
476 },
478 // treat warnings as errors
479 new HiddenOption(WERROR),
481 // use complex inference from context in the position of a method call argument
482 new HiddenOption(COMPLEXINFERENCE),
484 // generare source stubs
485 // new HiddenOption("-stubs"),
487 // relax some constraints to allow compiling from stubs
488 // new HiddenOption("-relax"),
490 // output source after translating away inner classes
491 // new Option("-printflat", "opt.printflat"),
492 // new HiddenOption("-printflat"),
494 // display scope search details
495 // new Option("-printsearch", "opt.printsearch"),
496 // new HiddenOption("-printsearch"),
498 // prompt after each error
499 // new Option("-prompt", "opt.prompt"),
500 new HiddenOption(PROMPT),
502 // dump stack on error
503 new HiddenOption(DOE),
505 // output source after type erasure
506 // new Option("-s", "opt.s"),
507 new HiddenOption(PRINTSOURCE),
509 // output shrouded class files
510 // new Option("-scramble", "opt.scramble"),
511 // new Option("-scrambleall", "opt.scrambleall"),
513 // display warnings for generic unchecked operations
514 new HiddenOption(WARNUNCHECKED) {
515 public boolean process(Options options, String option) {
516 options.put("-Xlint:unchecked", option);
517 return false;
518 }
519 },
521 new XOption(XMAXERRS, "opt.arg.number", "opt.maxerrs"),
522 new XOption(XMAXWARNS, "opt.arg.number", "opt.maxwarns"),
523 new XOption(XSTDOUT, "opt.arg.file", "opt.Xstdout") {
524 public boolean process(Options options, String option, String arg) {
525 try {
526 helper.setOut(new PrintWriter(new FileWriter(arg), true));
527 } catch (java.io.IOException e) {
528 helper.error("err.error.writing.file", arg, e);
529 return true;
530 }
531 return super.process(options, option, arg);
532 }
533 },
535 new XOption(XPRINT, "opt.print"),
537 new XOption(XPRINTROUNDS, "opt.printRounds"),
539 new XOption(XPRINTPROCESSORINFO, "opt.printProcessorInfo"),
541 new XOption(XPREFER, "opt.prefer") {
542 public boolean matches(String s) {
543 return s.equals("-Xprefer:source") || s.equals("-Xprefer:newer");
544 }
545 public boolean process(Options options, String option, String operand) {
546 int sep = option.indexOf(":");
547 options.put(option.substring(0, sep), option.substring(sep+1));
548 options.put(option,option);
549 return false;
550 }
551 },
553 /* -O is a no-op, accepted for backward compatibility. */
554 new HiddenOption(O),
556 /* -Xjcov produces tables to support the code coverage tool jcov. */
557 new HiddenOption(XJCOV),
559 /* This is a back door to the compiler's option table.
560 * -XDx=y sets the option x to the value y.
561 * -XDx sets the option x to the value x.
562 */
563 new HiddenOption(XD) {
564 String s;
565 public boolean matches(String s) {
566 this.s = s;
567 return s.startsWith(name.optionName);
568 }
569 public boolean process(Options options, String option) {
570 s = s.substring(name.optionName.length());
571 int eq = s.indexOf('=');
572 String key = (eq < 0) ? s : s.substring(0, eq);
573 String value = (eq < 0) ? s : s.substring(eq+1);
574 options.put(key, value);
575 return false;
576 }
577 },
579 /*
580 * TODO: With apt, the matches method accepts anything if
581 * -XclassAsDecls is used; code elsewhere does the lookup to
582 * see if the class name is both legal and found.
583 *
584 * In apt, the process method adds the candiate class file
585 * name to a separate list.
586 */
587 new HiddenOption(SOURCEFILE) {
588 String s;
589 public boolean matches(String s) {
590 this.s = s;
591 return s.endsWith(".java") // Java source file
592 || SourceVersion.isName(s); // Legal type name
593 }
594 public boolean process(Options options, String option) {
595 if (s.endsWith(".java") ) {
596 File f = new File(s);
597 if (!f.exists()) {
598 helper.error("err.file.not.found", f);
599 return true;
600 }
601 if (!f.isFile()) {
602 helper.error("err.file.not.file", f);
603 return true;
604 }
605 helper.addFile(f);
606 }
607 else
608 helper.addClassName(s);
609 return false;
610 }
611 },
612 };
613 }
615 }