684 * only) getSupportedAnnotationTypes call to the processor. |
684 * only) getSupportedAnnotationTypes call to the processor. |
685 */ |
685 */ |
686 static class ProcessorState { |
686 static class ProcessorState { |
687 public Processor processor; |
687 public Processor processor; |
688 public boolean contributed; |
688 public boolean contributed; |
689 private ArrayList<Pattern> supportedAnnotationPatterns; |
689 private Set<String> supportedAnnotationStrings; // Used for warning generation |
690 private ArrayList<String> supportedOptionNames; |
690 private Set<Pattern> supportedAnnotationPatterns; |
|
691 private Set<String> supportedOptionNames; |
691 |
692 |
692 ProcessorState(Processor p, Log log, Source source, DeferredCompletionFailureHandler dcfh, |
693 ProcessorState(Processor p, Log log, Source source, DeferredCompletionFailureHandler dcfh, |
693 boolean allowModules, ProcessingEnvironment env) { |
694 boolean allowModules, ProcessingEnvironment env, boolean lint) { |
694 processor = p; |
695 processor = p; |
695 contributed = false; |
696 contributed = false; |
696 |
697 |
697 Handler prevDeferredHandler = dcfh.setHandler(dcfh.userCodeHandler); |
698 Handler prevDeferredHandler = dcfh.setHandler(dcfh.userCodeHandler); |
698 try { |
699 try { |
699 processor.init(env); |
700 processor.init(env); |
700 |
701 |
701 checkSourceVersionCompatibility(source, log); |
702 checkSourceVersionCompatibility(source, log); |
702 |
703 |
703 supportedAnnotationPatterns = new ArrayList<>(); |
704 |
704 for (String importString : processor.getSupportedAnnotationTypes()) { |
705 // Check for direct duplicates in the strings of |
705 supportedAnnotationPatterns.add(importStringToPattern(allowModules, |
706 // supported annotation types. Do not check for |
706 importString, |
707 // duplicates that would result after stripping of |
707 processor, |
708 // module prefixes. |
708 log)); |
709 supportedAnnotationStrings = new LinkedHashSet<>(); |
709 } |
710 supportedAnnotationPatterns = new LinkedHashSet<>(); |
710 |
711 for (String annotationPattern : processor.getSupportedAnnotationTypes()) { |
711 supportedOptionNames = new ArrayList<>(); |
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<>(); |
712 for (String optionName : processor.getSupportedOptions() ) { |
736 for (String optionName : processor.getSupportedOptions() ) { |
713 if (checkOptionName(optionName, log)) |
737 if (checkOptionName(optionName, log)) { |
714 supportedOptionNames.add(optionName); |
738 boolean optionAdded = supportedOptionNames.add(optionName); |
|
739 if (lint && !optionAdded) { |
|
740 log.warning(Warnings.ProcDuplicateOptionName(optionName, |
|
741 p.getClass().getName())); |
|
742 } |
|
743 } |
715 } |
744 } |
716 |
745 |
717 } catch (ClientCodeException e) { |
746 } catch (ClientCodeException e) { |
718 throw e; |
747 throw e; |
719 } catch (Throwable t) { |
748 } catch (Throwable t) { |
1703 /** |
1733 /** |
1704 * Convert import-style string for supported annotations into a |
1734 * Convert import-style string for supported annotations into a |
1705 * regex matching that string. If the string is not a valid |
1735 * regex matching that string. If the string is not a valid |
1706 * import-style string, return a regex that won't match anything. |
1736 * import-style string, return a regex that won't match anything. |
1707 */ |
1737 */ |
1708 private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log) { |
1738 private static Pattern importStringToPattern(boolean allowModules, String s, Processor p, Log log, boolean lint) { |
1709 String module; |
1739 String module; |
1710 String pkg; |
1740 String pkg; |
1711 int slash = s.indexOf('/'); |
1741 int slash = s.indexOf('/'); |
1712 if (slash == (-1)) { |
1742 if (slash == (-1)) { |
1713 if (s.equals("*")) { |
1743 if (s.equals("*")) { |
1714 return MatchingUtils.validImportStringToPattern(s); |
1744 return MatchingUtils.validImportStringToPattern(s); |
1715 } |
1745 } |
1716 module = allowModules ? ".*/" : ""; |
1746 module = allowModules ? ".*/" : ""; |
1717 pkg = s; |
1747 pkg = s; |
1718 } else { |
1748 } else { |
1719 module = Pattern.quote(s.substring(0, slash + 1)); |
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? |
1720 pkg = s.substring(slash + 1); |
1755 pkg = s.substring(slash + 1); |
1721 } |
1756 } |
1722 if (MatchingUtils.isValidImportString(pkg)) { |
1757 if (MatchingUtils.isValidImportString(pkg)) { |
1723 return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg)); |
1758 return Pattern.compile(module + MatchingUtils.validImportStringToPatternString(pkg)); |
1724 } else { |
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) { |
1725 log.warning(Warnings.ProcMalformedSupportedString(s, p.getClass().getName())); |
1766 log.warning(Warnings.ProcMalformedSupportedString(s, p.getClass().getName())); |
1726 return noMatches; // won't match any valid identifier |
1767 } |
1727 } |
1768 return noMatches; // won't match any valid identifier |
1728 } |
1769 } |
1729 |
1770 |
1730 /** |
1771 /** |
1731 * For internal use only. This method may be removed without warning. |
1772 * For internal use only. This method may be removed without warning. |
1732 */ |
1773 */ |