61 import com.sun.tools.javac.platform.PlatformDescription; |
61 import com.sun.tools.javac.platform.PlatformDescription; |
62 import com.sun.tools.javac.platform.PlatformUtils; |
62 import com.sun.tools.javac.platform.PlatformUtils; |
63 import com.sun.tools.javac.resources.CompilerProperties.Errors; |
63 import com.sun.tools.javac.resources.CompilerProperties.Errors; |
64 import com.sun.tools.javac.resources.CompilerProperties.Warnings; |
64 import com.sun.tools.javac.resources.CompilerProperties.Warnings; |
65 import com.sun.tools.javac.util.Context; |
65 import com.sun.tools.javac.util.Context; |
|
66 import com.sun.tools.javac.util.JCDiagnostic; |
66 import com.sun.tools.javac.util.List; |
67 import com.sun.tools.javac.util.List; |
67 import com.sun.tools.javac.util.ListBuffer; |
68 import com.sun.tools.javac.util.ListBuffer; |
68 import com.sun.tools.javac.util.Log; |
69 import com.sun.tools.javac.util.Log; |
69 import com.sun.tools.javac.util.Log.PrefixKind; |
70 import com.sun.tools.javac.util.Log.PrefixKind; |
70 import com.sun.tools.javac.util.Log.WriterKind; |
71 import com.sun.tools.javac.util.Log.WriterKind; |
191 files = new LinkedHashSet<>(); |
197 files = new LinkedHashSet<>(); |
192 deferredFileManagerOptions = new LinkedHashMap<>(); |
198 deferredFileManagerOptions = new LinkedHashMap<>(); |
193 fileObjects = null; |
199 fileObjects = null; |
194 classNames = new LinkedHashSet<>(); |
200 classNames = new LinkedHashSet<>(); |
195 processArgs(List.from(args), Option.getJavaCompilerOptions(), cmdLineHelper, true, false); |
201 processArgs(List.from(args), Option.getJavaCompilerOptions(), cmdLineHelper, true, false); |
|
202 if (errors) { |
|
203 log.printLines(PrefixKind.JAVAC, "msg.usage", ownName); |
|
204 } |
196 } |
205 } |
197 |
206 |
198 private final OptionHelper apiHelper = new GrumpyHelper(null) { |
207 private final OptionHelper apiHelper = new GrumpyHelper(null) { |
199 @Override |
208 @Override |
200 public String get(Option option) { |
209 public String get(Option option) { |
201 return options.get(option.getText()); |
210 return options.get(option); |
202 } |
211 } |
203 |
212 |
204 @Override |
213 @Override |
205 public void put(String name, String value) { |
214 public void put(String name, String value) { |
206 options.put(name, value); |
215 options.put(name, value); |
295 return false; |
304 return false; |
296 |
305 |
297 String platformString = options.get(Option.RELEASE); |
306 String platformString = options.get(Option.RELEASE); |
298 |
307 |
299 checkOptionAllowed(platformString == null, |
308 checkOptionAllowed(platformString == null, |
300 option -> error("err.release.bootclasspath.conflict", option.getText()), |
309 option -> error("err.release.bootclasspath.conflict", option.getPrimaryName()), |
301 Option.BOOTCLASSPATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND, |
310 Option.BOOT_CLASS_PATH, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND, |
302 Option.XBOOTCLASSPATH_PREPEND, |
311 Option.XBOOTCLASSPATH_PREPEND, |
303 Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS, |
312 Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS, |
304 Option.EXTDIRS, Option.DJAVA_EXT_DIRS, |
313 Option.EXTDIRS, Option.DJAVA_EXT_DIRS, |
305 Option.SOURCE, Option.TARGET); |
314 Option.SOURCE, Option.TARGET); |
306 |
315 |
358 error("err.invalid.flag", arg); |
367 error("err.invalid.flag", arg); |
359 return false; |
368 return false; |
360 } |
369 } |
361 |
370 |
362 Option option = null; |
371 Option option = null; |
|
372 |
|
373 // first, check the provided set of javac options |
363 if (arg.startsWith("-")) { |
374 if (arg.startsWith("-")) { |
364 for (Option o : allowableOpts) { |
375 option = Option.lookup(arg, allowableOpts); |
365 if (o.matches(arg)) { |
|
366 option = o; |
|
367 break; |
|
368 } |
|
369 } |
|
370 } else if (allowOperands && Option.SOURCEFILE.matches(arg)) { |
376 } else if (allowOperands && Option.SOURCEFILE.matches(arg)) { |
371 option = Option.SOURCEFILE; |
377 option = Option.SOURCEFILE; |
372 } |
378 } |
373 |
379 |
374 if (option == null) { |
380 if (option != null) { |
375 if (fm != null && fm.handleOption(arg, argIter)) { |
381 if (!option.handleOption(helper, arg, argIter)) { |
376 continue; |
|
377 } |
|
378 error("err.invalid.flag", arg); |
|
379 return false; |
|
380 } |
|
381 |
|
382 if (option.hasArg()) { |
|
383 if (!argIter.hasNext()) { |
|
384 error("err.req.arg", arg); |
|
385 return false; |
382 return false; |
386 } |
383 } |
387 String operand = argIter.next(); |
384 continue; |
388 if (option.process(helper, arg, operand)) { |
385 } |
389 return false; |
386 |
390 } |
387 // check file manager option |
391 } else { |
388 if (fm != null && fm.handleOption(arg, argIter)) { |
392 if (option.process(helper, arg)) { |
389 continue; |
393 return false; |
390 } |
394 } |
391 |
395 } |
392 // none of the above |
|
393 error("err.invalid.flag", arg); |
|
394 return false; |
396 } |
395 } |
397 |
396 |
398 return true; |
397 return true; |
399 } |
398 } |
400 |
399 |
405 * @throws IllegalStateException if a problem is found and errorMode is set to |
404 * @throws IllegalStateException if a problem is found and errorMode is set to |
406 * ILLEGAL_STATE |
405 * ILLEGAL_STATE |
407 */ |
406 */ |
408 public boolean validate() { |
407 public boolean validate() { |
409 JavaFileManager fm = getFileManager(); |
408 JavaFileManager fm = getFileManager(); |
410 if (options.isSet(Option.M)) { |
409 if (options.isSet(Option.MODULE)) { |
411 if (!fm.hasLocation(StandardLocation.CLASS_OUTPUT)) { |
410 if (!fm.hasLocation(StandardLocation.CLASS_OUTPUT)) { |
412 log.error(Errors.OutputDirMustBeSpecifiedWithDashMOption); |
411 log.error(Errors.OutputDirMustBeSpecifiedWithDashMOption); |
413 } else if (!fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { |
412 } else if (!fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { |
414 log.error(Errors.ModulesourcepathMustBeSpecifiedWithDashMOption); |
413 log.error(Errors.ModulesourcepathMustBeSpecifiedWithDashMOption); |
415 } else { |
414 } else { |
416 java.util.List<String> modules = Arrays.asList(options.get(Option.M).split(",")); |
415 java.util.List<String> modules = Arrays.asList(options.get(Option.MODULE).split(",")); |
417 try { |
416 try { |
418 for (String module : modules) { |
417 for (String module : modules) { |
419 Location sourceLoc = fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, module); |
418 Location sourceLoc = fm.getModuleLocation(StandardLocation.MODULE_SOURCE_PATH, module); |
420 if (sourceLoc == null) { |
419 if (sourceLoc == null) { |
421 log.error(Errors.ModuleNotFoundInModuleSourcePath(module)); |
420 log.error(Errors.ModuleNotFoundInModuleSourcePath(module)); |
447 // But also note that none of these options are supported in API mode. |
446 // But also note that none of these options are supported in API mode. |
448 if (options.isSet(Option.HELP) |
447 if (options.isSet(Option.HELP) |
449 || options.isSet(Option.X) |
448 || options.isSet(Option.X) |
450 || options.isSet(Option.VERSION) |
449 || options.isSet(Option.VERSION) |
451 || options.isSet(Option.FULLVERSION) |
450 || options.isSet(Option.FULLVERSION) |
452 || options.isSet(Option.M)) |
451 || options.isSet(Option.MODULE)) |
453 return true; |
452 return true; |
454 |
453 |
455 if (emptyAllowed) |
454 if (emptyAllowed) |
456 return true; |
455 return true; |
457 |
456 |
458 if (JavaCompiler.explicitAnnotationProcessingRequested(options)) { |
457 if (!errors) { |
459 error("err.no.source.files.classes"); |
458 if (JavaCompiler.explicitAnnotationProcessingRequested(options)) { |
460 } else { |
459 error("err.no.source.files.classes"); |
461 error("err.no.source.files"); |
460 } else { |
462 } |
461 error("err.no.source.files"); |
|
462 } |
|
463 } |
|
464 |
463 return false; |
465 return false; |
464 } |
466 } |
465 |
467 |
466 if (!checkDirectory(Option.D)) { |
468 if (!checkDirectory(Option.D)) { |
467 return false; |
469 return false; |
540 error("warn.profile.target.conflict", profileString, target.name); |
542 error("warn.profile.target.conflict", profileString, target.name); |
541 } |
543 } |
542 |
544 |
543 // This check is only effective in command line mode, |
545 // This check is only effective in command line mode, |
544 // where the file manager options are added to options |
546 // where the file manager options are added to options |
545 if (options.get(Option.BOOTCLASSPATH) != null) { |
547 if (options.get(Option.BOOT_CLASS_PATH) != null) { |
546 error("err.profile.bootclasspath.conflict"); |
548 error("err.profile.bootclasspath.conflict"); |
547 } |
549 } |
548 } |
550 } |
549 |
551 |
550 if (options.isSet(Option.SOURCEPATH) && options.isSet(Option.MODULESOURCEPATH)) { |
552 if (options.isSet(Option.SOURCE_PATH) && options.isSet(Option.MODULE_SOURCE_PATH)) { |
551 error("err.sourcepath.modulesourcepath.conflict"); |
553 error("err.sourcepath.modulesourcepath.conflict"); |
552 } |
554 } |
553 |
555 |
554 boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); |
556 boolean lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option); |
555 |
557 |
576 obsoleteOptionFound = true; |
578 obsoleteOptionFound = true; |
577 } |
579 } |
578 |
580 |
579 final Target t = target; |
581 final Target t = target; |
580 checkOptionAllowed(t.compareTo(Target.JDK1_8) <= 0, |
582 checkOptionAllowed(t.compareTo(Target.JDK1_8) <= 0, |
581 option -> error("err.option.not.allowed.with.target", option.getText(), t.name), |
583 option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name), |
582 Option.BOOTCLASSPATH, |
584 Option.BOOT_CLASS_PATH, |
583 Option.XBOOTCLASSPATH_PREPEND, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND, |
585 Option.XBOOTCLASSPATH_PREPEND, Option.XBOOTCLASSPATH, Option.XBOOTCLASSPATH_APPEND, |
584 Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS, |
586 Option.ENDORSEDDIRS, Option.DJAVA_ENDORSED_DIRS, |
585 Option.EXTDIRS, Option.DJAVA_EXT_DIRS); |
587 Option.EXTDIRS, Option.DJAVA_EXT_DIRS); |
586 |
588 |
587 checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0, |
589 checkOptionAllowed(t.compareTo(Target.JDK1_9) >= 0, |
588 option -> error("err.option.not.allowed.with.target", option.getText(), t.name), |
590 option -> error("err.option.not.allowed.with.target", option.getPrimaryName(), t.name), |
589 Option.MODULESOURCEPATH, Option.UPGRADEMODULEPATH, |
591 Option.MODULE_SOURCE_PATH, Option.UPGRADE_MODULE_PATH, |
590 Option.SYSTEM, Option.MODULEPATH, Option.ADDMODS, Option.LIMITMODS, |
592 Option.SYSTEM, Option.MODULE_PATH, Option.ADD_MODULES, Option.LIMIT_MODULES, |
591 Option.XPATCH); |
593 Option.PATCH_MODULE); |
592 |
594 |
593 if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { |
595 if (fm.hasLocation(StandardLocation.MODULE_SOURCE_PATH)) { |
594 if (!options.isSet(Option.PROC, "only") |
596 if (!options.isSet(Option.PROC, "only") |
595 && !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) { |
597 && !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) { |
596 log.error(Errors.NoOutputDir); |
598 log.error(Errors.NoOutputDir); |
606 } |
608 } |
607 |
609 |
608 if (obsoleteOptionFound) |
610 if (obsoleteOptionFound) |
609 log.warning(LintCategory.OPTIONS, "option.obsolete.suppression"); |
611 log.warning(LintCategory.OPTIONS, "option.obsolete.suppression"); |
610 |
612 |
611 String addExports = options.get(Option.XADDEXPORTS); |
613 String addExports = options.get(Option.ADD_EXPORTS); |
612 if (addExports != null) { |
614 if (addExports != null) { |
613 // Each entry must be of the form module/package=target-list where target-list is a |
615 // Each entry must be of the form module/package=target-list where target-list is a |
614 // comma-separated list of module or ALL-UNNAMED. |
616 // comma-separated list of module or ALL-UNNAMED. |
615 // All module/package pairs must be unique. |
617 // All module/package pairs must be unique. |
616 Pattern p = Pattern.compile("([^/]+)/([^=]+)=(.*)"); |
618 Pattern p = Pattern.compile("([^/]+)/([^=]+)=(.*)"); |
634 // TODO: consider adding diag fragments for the entries |
636 // TODO: consider adding diag fragments for the entries |
635 } |
637 } |
636 }); |
638 }); |
637 } |
639 } |
638 |
640 |
639 String addReads = options.get(Option.XADDREADS); |
641 String addReads = options.get(Option.ADD_READS); |
640 if (addReads != null) { |
642 if (addReads != null) { |
641 // Each entry must be of the form module=source-list where source-list is a |
643 // Each entry must be of the form module=source-list where source-list is a |
642 // comma separated list of module or ALL-UNNAMED. |
644 // comma separated list of module or ALL-UNNAMED. |
643 // All target modules (i.e. on left of '=') must be unique. |
645 // All target modules (i.e. on left of '=') must be unique. |
644 Pattern p = Pattern.compile("([^=]+)=(.*)"); |
646 Pattern p = Pattern.compile("([^=]+)=(.*)"); |
722 doclintOpts.add(DocLint.XMSGS_OPTION); |
724 doclintOpts.add(DocLint.XMSGS_OPTION); |
723 if (xdoclintCustom != null) { |
725 if (xdoclintCustom != null) { |
724 for (String s: xdoclintCustom.split("\\s+")) { |
726 for (String s: xdoclintCustom.split("\\s+")) { |
725 if (s.isEmpty()) |
727 if (s.isEmpty()) |
726 continue; |
728 continue; |
727 doclintOpts.add(s.replace(Option.XDOCLINT_CUSTOM.text, DocLint.XMSGS_CUSTOM_PREFIX)); |
729 doclintOpts.add(DocLint.XMSGS_CUSTOM_PREFIX + s); |
728 } |
730 } |
729 } |
731 } |
730 |
732 |
731 if (doclintOpts.equals(Collections.singleton(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) |
733 if (doclintOpts.equals(Collections.singleton(DocLint.XMSGS_CUSTOM_PREFIX + "none"))) |
732 return List.nil(); |
734 return List.nil(); |
733 |
735 |
734 String checkPackages = options.get(Option.XDOCLINT_PACKAGE); |
736 String checkPackages = options.get(Option.XDOCLINT_PACKAGE); |
735 |
737 |
736 if (checkPackages != null) { |
738 if (checkPackages != null) { |
737 for (String s : checkPackages.split("\\s+")) { |
739 for (String s : checkPackages.split("\\s+")) { |
738 doclintOpts.add(s.replace(Option.XDOCLINT_PACKAGE.text, DocLint.XCHECK_PACKAGE)); |
740 doclintOpts.add(DocLint.XCHECK_PACKAGE + s); |
739 } |
741 } |
740 } |
742 } |
741 |
743 |
742 // standard doclet normally generates H1, H2, |
744 // standard doclet normally generates H1, H2, |
743 // so for now, allow user comments to assume that |
745 // so for now, allow user comments to assume that |
744 doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2"); |
746 doclintOpts.add(DocLint.XIMPLICIT_HEADERS + "2"); |
745 |
|
746 return List.from(doclintOpts.toArray(new String[doclintOpts.size()])); |
747 return List.from(doclintOpts.toArray(new String[doclintOpts.size()])); |
747 } |
748 } |
748 |
749 |
749 private boolean checkDirectory(Option option) { |
750 private boolean checkDirectory(Option option) { |
750 String value = options.get(option); |
751 String value = options.get(option); |
766 void checkOptionAllowed(boolean allowed, ErrorReporter r, Option... opts) { |
767 void checkOptionAllowed(boolean allowed, ErrorReporter r, Option... opts) { |
767 if (!allowed) { |
768 if (!allowed) { |
768 Stream.of(opts) |
769 Stream.of(opts) |
769 .filter(options :: isSet) |
770 .filter(options :: isSet) |
770 .forEach(r :: report); |
771 .forEach(r :: report); |
|
772 } |
|
773 } |
|
774 |
|
775 void error(JCDiagnostic.Error error) { |
|
776 errors = true; |
|
777 switch (errorMode) { |
|
778 case ILLEGAL_ARGUMENT: { |
|
779 String msg = log.localize(error); |
|
780 throw new PropagatedException(new IllegalArgumentException(msg)); |
|
781 } |
|
782 case ILLEGAL_STATE: { |
|
783 String msg = log.localize(error); |
|
784 throw new PropagatedException(new IllegalStateException(msg)); |
|
785 } |
|
786 case LOG: |
|
787 report(error); |
771 } |
788 } |
772 } |
789 } |
773 |
790 |
774 void error(String key, Object... args) { |
791 void error(String key, Object... args) { |
775 errors = true; |
792 errors = true; |
782 String msg = log.localize(PrefixKind.JAVAC, key, args); |
799 String msg = log.localize(PrefixKind.JAVAC, key, args); |
783 throw new PropagatedException(new IllegalStateException(msg)); |
800 throw new PropagatedException(new IllegalStateException(msg)); |
784 } |
801 } |
785 case LOG: |
802 case LOG: |
786 report(key, args); |
803 report(key, args); |
787 log.printLines(PrefixKind.JAVAC, "msg.usage", ownName); |
|
788 } |
804 } |
789 } |
805 } |
790 |
806 |
791 void warning(String key, Object... args) { |
807 void warning(String key, Object... args) { |
792 report(key, args); |
808 report(key, args); |
793 } |
809 } |
794 |
810 |
795 private void report(String key, Object... args) { |
811 private void report(String key, Object... args) { |
796 // Would be good to have support for -XDrawDiagnostics here |
812 // Would be good to have support for -XDrawDiagnostics here |
797 log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args)); |
813 log.printRawLines(ownName + ": " + log.localize(PrefixKind.JAVAC, key, args)); |
|
814 } |
|
815 |
|
816 private void report(JCDiagnostic.Error error) { |
|
817 // Would be good to have support for -XDrawDiagnostics here |
|
818 log.printRawLines(ownName + ": " + log.localize(error)); |
798 } |
819 } |
799 |
820 |
800 private JavaFileManager getFileManager() { |
821 private JavaFileManager getFileManager() { |
801 if (fileManager == null) |
822 if (fileManager == null) |
802 fileManager = context.get(JavaFileManager.class); |
823 fileManager = context.get(JavaFileManager.class); |