669 return Collections.unmodifiableMap(tempOptions);
670 }
671
672 private Set<String> initUnmatchedProcessorOptions() {
673 Set<String> unmatchedProcessorOptions = new HashSet<>();
674 unmatchedProcessorOptions.addAll(processorOptions.keySet());
675 return unmatchedProcessorOptions;
676 }
677
678 /**
679 * State about how a processor has been used by the tool. If a
680 * processor has been used on a prior round, its process method is
681 * called on all subsequent rounds, perhaps with an empty set of
682 * annotations to process. The {@code annotationSupported} method
683 * caches the supported annotation information from the first (and
684 * only) getSupportedAnnotationTypes call to the processor.
685 */
686 static class ProcessorState {
687 public Processor processor;
688 public boolean contributed;
689 private ArrayList<Pattern> supportedAnnotationPatterns;
690 private ArrayList<String> supportedOptionNames;
691
692 ProcessorState(Processor p, Log log, Source source, DeferredCompletionFailureHandler dcfh,
693 boolean allowModules, ProcessingEnvironment env) {
694 processor = p;
695 contributed = false;
696
697 Handler prevDeferredHandler = dcfh.setHandler(dcfh.userCodeHandler);
698 try {
699 processor.init(env);
700
701 checkSourceVersionCompatibility(source, log);
702
703 supportedAnnotationPatterns = new ArrayList<>();
704 for (String importString : processor.getSupportedAnnotationTypes()) {
705 supportedAnnotationPatterns.add(importStringToPattern(allowModules,
706 importString,
707 processor,
708 log));
709 }
710
711 supportedOptionNames = new ArrayList<>();
712 for (String optionName : processor.getSupportedOptions() ) {
713 if (checkOptionName(optionName, log))
714 supportedOptionNames.add(optionName);
715 }
716
717 } catch (ClientCodeException e) {
718 throw e;
719 } catch (Throwable t) {
720 throw new AnnotationProcessingError(t);
721 } finally {
722 dcfh.setHandler(prevDeferredHandler);
723 }
724 }
725
726 /**
727 * Checks whether or not a processor's source version is
728 * compatible with the compilation source version. The
729 * processor's source version needs to be greater than or
730 * equal to the source version of the compile.
731 */
732 private void checkSourceVersionCompatibility(Source source, Log log) {
733 SourceVersion procSourceVersion = processor.getSupportedSourceVersion();
734
780 boolean onProcInterator;
781
782 ProcessorStateIterator(DiscoveredProcessors psi) {
783 this.psi = psi;
784 this.innerIter = psi.procStateList.iterator();
785 this.onProcInterator = false;
786 }
787
788 public ProcessorState next() {
789 if (!onProcInterator) {
790 if (innerIter.hasNext())
791 return innerIter.next();
792 else
793 onProcInterator = true;
794 }
795
796 if (psi.processorIterator.hasNext()) {
797 ProcessorState ps = new ProcessorState(psi.processorIterator.next(),
798 log, source, dcfh,
799 Feature.MODULES.allowedInSource(source),
800 JavacProcessingEnvironment.this);
801 psi.procStateList.add(ps);
802 return ps;
803 } else
804 throw new NoSuchElementException();
805 }
806
807 public boolean hasNext() {
808 if (onProcInterator)
809 return psi.processorIterator.hasNext();
810 else
811 return innerIter.hasNext() || psi.processorIterator.hasNext();
812 }
813
814 public void remove () {
815 throw new UnsupportedOperationException();
816 }
817
818 /**
819 * Run all remaining processors on the procStateList that
820 * have not already run this round with an empty set of
1688 public Locale getLocale() {
1689 return messages.getCurrentLocale();
1690 }
1691
1692 @DefinedBy(Api.ANNOTATION_PROCESSING)
1693 public boolean isPreviewEnabled() {
1694 return preview.isEnabled();
1695 }
1696
1697 public Set<Symbol.PackageSymbol> getSpecifiedPackages() {
1698 return specifiedPackages;
1699 }
1700
1701 public static final Pattern noMatches = Pattern.compile("(\\P{all})+");
1702
1703 /**
1704 * Convert import-style string for supported annotations into a
1705 * regex matching that string. If the string is not a valid
1706 * import-style string, return a regex that won't match anything.
1707 */
1708 private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log) {
1709 String module;
1710 String pkg;
1711 int slash = s.indexOf('/');
1712 if (slash == (-1)) {
1713 if (s.equals("*")) {
1714 return MatchingUtils.validImportStringToPattern(s);
1715 }
1716 module = allowModules ? ".*/" : "";
1717 pkg = s;
1718 } else {
1719 module = Pattern.quote(s.substring(0, slash + 1));
1720 pkg = s.substring(slash + 1);
1721 }
1722 if (MatchingUtils.isValidImportString(pkg)) {
1723 return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg));
1724 } else {
1725 log.warning(Warnings.ProcMalformedSupportedString(s, p.getClass().getName()));
1726 return noMatches; // won't match any valid identifier
1727 }
1728 }
1729
1730 /**
1731 * For internal use only. This method may be removed without warning.
1732 */
1733 public Context getContext() {
1734 return context;
1735 }
1736
1737 /**
1738 * For internal use only. This method may be removed without warning.
1739 */
1740 public ClassLoader getProcessorClassLoader() {
1741 return processorClassLoader;
1742 }
1743
1744 public String toString() {
1745 return "javac ProcessingEnvironment";
1746 }
1747
|
669 return Collections.unmodifiableMap(tempOptions);
670 }
671
672 private Set<String> initUnmatchedProcessorOptions() {
673 Set<String> unmatchedProcessorOptions = new HashSet<>();
674 unmatchedProcessorOptions.addAll(processorOptions.keySet());
675 return unmatchedProcessorOptions;
676 }
677
678 /**
679 * State about how a processor has been used by the tool. If a
680 * processor has been used on a prior round, its process method is
681 * called on all subsequent rounds, perhaps with an empty set of
682 * annotations to process. The {@code annotationSupported} method
683 * caches the supported annotation information from the first (and
684 * only) getSupportedAnnotationTypes call to the processor.
685 */
686 static class ProcessorState {
687 public Processor processor;
688 public boolean contributed;
689 private Set<String> supportedAnnotationStrings; // Used for warning generation
690 private Set<Pattern> supportedAnnotationPatterns;
691 private Set<String> supportedOptionNames;
692
693 ProcessorState(Processor p, Log log, Source source, DeferredCompletionFailureHandler dcfh,
694 boolean allowModules, ProcessingEnvironment env, boolean lint) {
695 processor = p;
696 contributed = false;
697
698 Handler prevDeferredHandler = dcfh.setHandler(dcfh.userCodeHandler);
699 try {
700 processor.init(env);
701
702 checkSourceVersionCompatibility(source, log);
703
704
705 // Check for direct duplicates in the strings of
706 // supported annotation types. Do not check for
707 // duplicates that would result after stripping of
708 // module prefixes.
709 supportedAnnotationStrings = new LinkedHashSet<>();
710 supportedAnnotationPatterns = new LinkedHashSet<>();
711 for (String annotationPattern : processor.getSupportedAnnotationTypes()) {
712 boolean patternAdded = supportedAnnotationStrings.add(annotationPattern);
713
714 supportedAnnotationPatterns.
715 add(importStringToPattern(allowModules, annotationPattern,
716 processor, log, lint));
717 if (lint && !patternAdded) {
718 log.warning(Warnings.ProcDuplicateSupportedAnnotation(annotationPattern,
719 p.getClass().getName()));
720 }
721 }
722
723 // If a processor supports "*", that matches
724 // everything and other entries are redundant. With
725 // more work, it could be checked that the supported
726 // annotation types were otherwise non-overlapping
727 // with each other in other cases, for example "foo.*"
728 // and "foo.bar.*".
729 if (lint &&
730 supportedAnnotationPatterns.contains(MatchingUtils.validImportStringToPattern("*")) &&
731 supportedAnnotationPatterns.size() > 1) {
732 log.warning(Warnings.ProcRedundantTypesWithWildcard(p.getClass().getName()));
733 }
734
735 supportedOptionNames = new LinkedHashSet<>();
736 for (String optionName : processor.getSupportedOptions() ) {
737 if (checkOptionName(optionName, log)) {
738 boolean optionAdded = supportedOptionNames.add(optionName);
739 if (lint && !optionAdded) {
740 log.warning(Warnings.ProcDuplicateOptionName(optionName,
741 p.getClass().getName()));
742 }
743 }
744 }
745
746 } catch (ClientCodeException e) {
747 throw e;
748 } catch (Throwable t) {
749 throw new AnnotationProcessingError(t);
750 } finally {
751 dcfh.setHandler(prevDeferredHandler);
752 }
753 }
754
755 /**
756 * Checks whether or not a processor's source version is
757 * compatible with the compilation source version. The
758 * processor's source version needs to be greater than or
759 * equal to the source version of the compile.
760 */
761 private void checkSourceVersionCompatibility(Source source, Log log) {
762 SourceVersion procSourceVersion = processor.getSupportedSourceVersion();
763
809 boolean onProcInterator;
810
811 ProcessorStateIterator(DiscoveredProcessors psi) {
812 this.psi = psi;
813 this.innerIter = psi.procStateList.iterator();
814 this.onProcInterator = false;
815 }
816
817 public ProcessorState next() {
818 if (!onProcInterator) {
819 if (innerIter.hasNext())
820 return innerIter.next();
821 else
822 onProcInterator = true;
823 }
824
825 if (psi.processorIterator.hasNext()) {
826 ProcessorState ps = new ProcessorState(psi.processorIterator.next(),
827 log, source, dcfh,
828 Feature.MODULES.allowedInSource(source),
829 JavacProcessingEnvironment.this,
830 lint);
831 psi.procStateList.add(ps);
832 return ps;
833 } else
834 throw new NoSuchElementException();
835 }
836
837 public boolean hasNext() {
838 if (onProcInterator)
839 return psi.processorIterator.hasNext();
840 else
841 return innerIter.hasNext() || psi.processorIterator.hasNext();
842 }
843
844 public void remove () {
845 throw new UnsupportedOperationException();
846 }
847
848 /**
849 * Run all remaining processors on the procStateList that
850 * have not already run this round with an empty set of
1718 public Locale getLocale() {
1719 return messages.getCurrentLocale();
1720 }
1721
1722 @DefinedBy(Api.ANNOTATION_PROCESSING)
1723 public boolean isPreviewEnabled() {
1724 return preview.isEnabled();
1725 }
1726
1727 public Set<Symbol.PackageSymbol> getSpecifiedPackages() {
1728 return specifiedPackages;
1729 }
1730
1731 public static final Pattern noMatches = Pattern.compile("(\\P{all})+");
1732
1733 /**
1734 * Convert import-style string for supported annotations into a
1735 * regex matching that string. If the string is not a valid
1736 * import-style string, return a regex that won't match anything.
1737 */
1738 private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log, boolean lint) {
1739 String module;
1740 String pkg;
1741 int slash = s.indexOf('/');
1742 if (slash == (-1)) {
1743 if (s.equals("*")) {
1744 return MatchingUtils.validImportStringToPattern(s);
1745 }
1746 module = allowModules ? ".*/" : "";
1747 pkg = s;
1748 } else {
1749 String moduleName = s.substring(0, slash);
1750 if (!SourceVersion.isIdentifier(moduleName)) {
1751 return warnAndNoMatches(s, p, log, lint);
1752 }
1753 module = Pattern.quote(moduleName + "/");
1754 // And warn if module is specified if modules aren't supported, conditional on -Xlint:proc?
1755 pkg = s.substring(slash + 1);
1756 }
1757 if (MatchingUtils.isValidImportString(pkg)) {
1758 return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg));
1759 } else {
1760 return warnAndNoMatches(s, p, log, lint);
1761 }
1762 }
1763
1764 private static Pattern warnAndNoMatches(String s, Processor p, Log log, boolean lint) {
1765 if (lint) {
1766 log.warning(Warnings.ProcMalformedSupportedString(s, p.getClass().getName()));
1767 }
1768 return noMatches; // won't match any valid identifier
1769 }
1770
1771 /**
1772 * For internal use only. This method may be removed without warning.
1773 */
1774 public Context getContext() {
1775 return context;
1776 }
1777
1778 /**
1779 * For internal use only. This method may be removed without warning.
1780 */
1781 public ClassLoader getProcessorClassLoader() {
1782 return processorClassLoader;
1783 }
1784
1785 public String toString() {
1786 return "javac ProcessingEnvironment";
1787 }
1788
|