< prev index next >

test/jdk/tools/sincechecker/SinceChecker.java

Print this page

 84 
 85 Effective since value of an API element is computed as follows:
 86 - if the given element has a @since tag in its javadoc, it is used
 87 - in all other cases, return the effective since value of the enclosing element
 88 
 89 
 90 Special Handling for preview method, as per JEP 12:
 91 - When an element is still marked as preview, the `@since` should be the first JDK release where the element was added.
 92 - If the element is no longer marked as preview, the `@since` should be the first JDK release where it was no longer preview.
 93 
 94 note on legacy preview: Until JDK 14, the preview APIs were not marked in any machine-understandable way.
 95                         It was deprecated, and had a comment in the javadoc.
 96                         and the use of `@PreviewFeature` only became standard in JDK 17.
 97                         So the checker has an explicit knowledge of these preview elements.
 98 
 99 note: The `<unique-Element-ID>` for methods looks like
100       `method: <erased-return-descriptor> <binary-name-of-enclosing-class>.<method-name>(<ParameterDescriptor>)`.
101 it is somewhat inspired from the VM Method Descriptors. But we use the erased return so that methods
102 that were later generified remain the same.
103 




104 usage: the checker is run from a module specific test
105         `@run main SinceChecker <moduleName> [--exclude package1,package2 | --exclude package1 package2]`
106 */
107 
108 public class SinceChecker {
109     private final Map<String, Set<String>> LEGACY_PREVIEW_METHODS = new HashMap<>();
110     private final Map<String, IntroducedIn> classDictionary = new HashMap<>();
111     private final JavaCompiler tool;
112     private int errorCount = 0;
113 





114     // packages to skip during the test
115     private static final Set<String> EXCLUDE_LIST = new HashSet<>();
116 
117     public static class IntroducedIn {
118         public String introducedPreview;
119         public String introducedStable;
120     }
121 
122     public static void main(String[] args) throws Exception {
123         if (args.length == 0) {
124             throw new IllegalArgumentException("Test module not specified");
125         }
126         String moduleName = args[0];
127         boolean excludeFlag = false;
128 
129         for (int i = 1; i < args.length; i++) {
130             if ("--exclude".equals(args[i])) {




131                 excludeFlag = true;
132                 continue;
133             }
134 
135             if (excludeFlag) {
136                 if (args[i].contains(",")) {
137                     EXCLUDE_LIST.addAll(Arrays.asList(args[i].split(",")));
138                 } else {
139                     EXCLUDE_LIST.add(args[i]);
140                 }
141             }
142         }
143 
144         SinceChecker sinceCheckerTestHelper = new SinceChecker(moduleName);
145         sinceCheckerTestHelper.checkModule(moduleName);
146     }
147 
148     private void error(String message) {
149         System.err.println(message);
150         errorCount++;

435         }
436         sinceVersion = effectiveSince.toString();
437         IntroducedIn mappedVersion = classDictionary.get(uniqueId);
438         if (mappedVersion == null) {
439             error("Element: " + uniqueId + " was not mapped");
440             return;
441         }
442         String realMappedVersion = null;
443         try {
444             realMappedVersion = isPreview(element, uniqueId, currentVersion) ?
445                     mappedVersion.introducedPreview :
446                     mappedVersion.introducedStable;
447         } catch (Exception e) {
448             error("For element " + element + "mappedVersion" + mappedVersion + " is null " + e);
449         }
450         String position = javadocHelper.getElementPosition(uniqueId);
451         checkEquals(position, sinceVersion, realMappedVersion, uniqueId);
452     }
453 
454     private Version extractSinceVersionFromText(String documentation) {





455         Pattern pattern = Pattern.compile("@since\\s+(\\d+(?:\\.\\d+)?)");
456         Matcher matcher = pattern.matcher(documentation);
457         if (matcher.find()) {
458             String versionString = matcher.group(1);
459             try {
460                 if (versionString.equals("1.0")) {
461                     versionString = "1"; //ended up being necessary
462                 } else if (versionString.startsWith("1.")) {
463                     versionString = versionString.substring(2);
464                 }
465                 return Version.parse(versionString);
466             } catch (NumberFormatException ex) {
467                 error("`@since` value that cannot be parsed: " + versionString);
468                 return null;
469             }
470         } else {
471             return null;
472         }
473     }
474 

 84 
 85 Effective since value of an API element is computed as follows:
 86 - if the given element has a @since tag in its javadoc, it is used
 87 - in all other cases, return the effective since value of the enclosing element
 88 
 89 
 90 Special Handling for preview method, as per JEP 12:
 91 - When an element is still marked as preview, the `@since` should be the first JDK release where the element was added.
 92 - If the element is no longer marked as preview, the `@since` should be the first JDK release where it was no longer preview.
 93 
 94 note on legacy preview: Until JDK 14, the preview APIs were not marked in any machine-understandable way.
 95                         It was deprecated, and had a comment in the javadoc.
 96                         and the use of `@PreviewFeature` only became standard in JDK 17.
 97                         So the checker has an explicit knowledge of these preview elements.
 98 
 99 note: The `<unique-Element-ID>` for methods looks like
100       `method: <erased-return-descriptor> <binary-name-of-enclosing-class>.<method-name>(<ParameterDescriptor>)`.
101 it is somewhat inspired from the VM Method Descriptors. But we use the erased return so that methods
102 that were later generified remain the same.
103 
104 To help projects still in development, unsure of actual `@since` tag value, one may want to use token name instead of continuely
105 updating the current version since tags. For example, `@since LongRunningProjectName`. The option `--ignoreSince` maybe used to
106 ignore these tags (`--ignoreSince LongRunningProjectName`). Maybe be specified multiple times.
107 
108 usage: the checker is run from a module specific test
109         `@run main SinceChecker <moduleName> [--ignoreSince <string>] [--exclude package1,package2 | --exclude package1 package2]`
110 */
111 
112 public class SinceChecker {
113     private final Map<String, Set<String>> LEGACY_PREVIEW_METHODS = new HashMap<>();
114     private final Map<String, IntroducedIn> classDictionary = new HashMap<>();
115     private final JavaCompiler tool;
116     private int errorCount = 0;
117 
118     // Ignored since tags
119     private static final Set<String> IGNORE_SINCE = new HashSet<>();
120     // Simply replace ignored since tags with the latest version
121     private static final Version     IGNORE_VERSION = Version.parse(Integer.toString(Runtime.version().major()));
122 
123     // packages to skip during the test
124     private static final Set<String> EXCLUDE_LIST = new HashSet<>();
125 
126     public static class IntroducedIn {
127         public String introducedPreview;
128         public String introducedStable;
129     }
130 
131     public static void main(String[] args) throws Exception {
132         if (args.length == 0) {
133             throw new IllegalArgumentException("Test module not specified");
134         }
135         String moduleName = args[0];
136         boolean excludeFlag = false;
137 
138         for (int i = 1; i < args.length; i++) {
139             if ("--ignoreSince".equals(args[i])) {
140                 i++;
141                 IGNORE_SINCE.add("@since " + args[i]);
142             }
143             else if ("--exclude".equals(args[i])) {
144                 excludeFlag = true;
145                 continue;
146             }
147 
148             if (excludeFlag) {
149                 if (args[i].contains(",")) {
150                     EXCLUDE_LIST.addAll(Arrays.asList(args[i].split(",")));
151                 } else {
152                     EXCLUDE_LIST.add(args[i]);
153                 }
154             }
155         }
156 
157         SinceChecker sinceCheckerTestHelper = new SinceChecker(moduleName);
158         sinceCheckerTestHelper.checkModule(moduleName);
159     }
160 
161     private void error(String message) {
162         System.err.println(message);
163         errorCount++;

448         }
449         sinceVersion = effectiveSince.toString();
450         IntroducedIn mappedVersion = classDictionary.get(uniqueId);
451         if (mappedVersion == null) {
452             error("Element: " + uniqueId + " was not mapped");
453             return;
454         }
455         String realMappedVersion = null;
456         try {
457             realMappedVersion = isPreview(element, uniqueId, currentVersion) ?
458                     mappedVersion.introducedPreview :
459                     mappedVersion.introducedStable;
460         } catch (Exception e) {
461             error("For element " + element + "mappedVersion" + mappedVersion + " is null " + e);
462         }
463         String position = javadocHelper.getElementPosition(uniqueId);
464         checkEquals(position, sinceVersion, realMappedVersion, uniqueId);
465     }
466 
467     private Version extractSinceVersionFromText(String documentation) {
468         for (String ignoreSince : IGNORE_SINCE) {
469             if (documentation.contains(ignoreSince)) {
470                 return IGNORE_VERSION;
471             }
472         }
473         Pattern pattern = Pattern.compile("@since\\s+(\\d+(?:\\.\\d+)?)");
474         Matcher matcher = pattern.matcher(documentation);
475         if (matcher.find()) {
476             String versionString = matcher.group(1);
477             try {
478                 if (versionString.equals("1.0")) {
479                     versionString = "1"; //ended up being necessary
480                 } else if (versionString.startsWith("1.")) {
481                     versionString = versionString.substring(2);
482                 }
483                 return Version.parse(versionString);
484             } catch (NumberFormatException ex) {
485                 error("`@since` value that cannot be parsed: " + versionString);
486                 return null;
487             }
488         } else {
489             return null;
490         }
491     }
492 
< prev index next >