From ada7732369b4fd2a9c22b536d7abc96fe635058a Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Wed, 11 Dec 2024 23:31:56 -0500 Subject: [PATCH 1/4] Link documentation --- .../initialization/InitializationChecker.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java index 8aa8cdd3db31..e1bd711e7908 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java @@ -91,7 +91,10 @@ public InitializationChecker() {} /** * Also handle {@code AnnotatedFor} annotations for this checker. See {@link * InitializationFieldAccessSubchecker#getUpstreamCheckerNames()} and the two implementations - * should be kept in sync. + * should be kept in sync. The name of this checker is also added in {@link + * #getSuppressWarningsPrefixes()}. + * + * @return the list of checkers that should be run before this checker */ @Override public List<@FullyQualifiedName String> getUpstreamCheckerNames() { @@ -102,6 +105,13 @@ public InitializationChecker() {} return upstreamCheckerNames; } + /** + * Manually add the default prefix "initialization" to the set of prefixes that can be used to + * suppress warnings. The checker is also added in {@link #getUpstreamCheckerNames()} for + * AnnotatedFor annotations to be recognized by this checker. + * + * @return the set of prefixes that can be used to suppress warnings + */ @Override public NavigableSet getSuppressWarningsPrefixes() { NavigableSet result = super.getSuppressWarningsPrefixes(); From 31515c9b07b04a3e4fda0de06c19127a42d7e382 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Tue, 26 May 2026 12:31:07 -0400 Subject: [PATCH 2/4] Address comment and add changelog --- .../initialization/InitializationChecker.java | 12 +---------- docs/CHANGELOG.md | 1 + .../framework/source/SourceChecker.java | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java index 1b43d0743dee..12f5a219fd1c 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java @@ -92,10 +92,7 @@ public InitializationChecker() {} /** * Also handle {@code AnnotatedFor} annotations for this checker. See {@link * InitializationFieldAccessSubchecker#getUpstreamCheckerNames()} and the two implementations - * should be kept in sync. The name of this checker is also added in {@link - * #getSuppressWarningsPrefixes()}. - * - * @return the list of checkers that should be run before this checker + * should be kept in sync. */ @Override public List<@FullyQualifiedName String> getUpstreamCheckerNames() { @@ -106,13 +103,6 @@ public InitializationChecker() {} return upstreamCheckerNames; } - /** - * Manually add the default prefix "initialization" to the set of prefixes that can be used to - * suppress warnings. The checker is also added in {@link #getUpstreamCheckerNames()} for - * AnnotatedFor annotations to be recognized by this checker. - * - * @return the set of prefixes that can be used to suppress warnings - */ @Override public NavigableSet getSuppressWarningsPrefixes() { NavigableSet result = super.getSuppressWarningsPrefixes(); diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d5f4d358af06..6b230f444b14 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -11,6 +11,7 @@ Optional Checker. **Closed issues:** +eisop#1011. Version 3.49.5-eisop1 (April 26, 2026) -------------------------------------- diff --git a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java index 076ccaaed36b..e536cf1f593f 100644 --- a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java +++ b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java @@ -836,8 +836,20 @@ protected void setRoot(CompilationUnitTree newRoot) { * Returns a list containing this checker name and all checkers it is a part of (that is, * checkers that called it). * + *

This list determines which {@code @AnnotatedFor} annotations are recognized as covering + * this checker. + * + *

Note: {@link #getUpstreamCheckerNames()} and {@link #getSuppressWarningsPrefixes()} are a + * related pair and should be kept in sync. If you override this method to add an additional + * checker name (for example, the name of an abstract parent class that this checker extends), + * you should also override {@link #getSuppressWarningsPrefixes()} to add the corresponding + * {@code @SuppressWarnings} prefix for that checker. Otherwise, code marked + * {@code @AnnotatedFor} for the parent will be checked, but {@code @SuppressWarnings} written + * with the parent's prefix will not be honored (or vice versa). + * * @return a list containing this checker name and all checkers it is a part of (that is, * checkers that called it) + * @see #getSuppressWarningsPrefixes() */ public List<@FullyQualifiedName String> getUpstreamCheckerNames() { if (upstreamCheckerNames == null) { @@ -3062,7 +3074,15 @@ private boolean isAnnotatedForThisCheckerOrUpstreamChecker(@Nullable Element elt * *

The collection must not be empty and must not contain only {@link #SUPPRESS_ALL_PREFIX}. * + *

Note: {@link #getSuppressWarningsPrefixes()} and {@link #getUpstreamCheckerNames()} are a + * related pair and should be kept in sync. If you override this method to add an additional + * prefix (for example, the prefix of an abstract parent class that this checker extends), you + * should also override {@link #getUpstreamCheckerNames()} to add the corresponding checker + * name. Otherwise, {@code @SuppressWarnings} written with the parent's prefix will be honored, + * but code marked {@code @AnnotatedFor} for the parent will not be checked (or vice versa). + * * @return non-empty modifiable set of lower-case prefixes for SuppressWarnings strings + * @see #getUpstreamCheckerNames() */ public NavigableSet getSuppressWarningsPrefixes() { return getStandardSuppressWarningsPrefixes(); From 02ccca4c3241bdfb20a5809b1eb5f87fb32410fd Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Thu, 11 Jun 2026 13:45:25 -0400 Subject: [PATCH 3/4] Derive suppression prefixes from upstream checkers --- .../initialization/InitializationChecker.java | 3 -- .../framework/source/SourceChecker.java | 48 +++++++++++-------- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java index 12f5a219fd1c..efe89737d460 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationChecker.java @@ -109,9 +109,6 @@ public NavigableSet getSuppressWarningsPrefixes() { // "fbc" is for backward compatibility only; you should use // "initialization" instead. result.add("fbc"); - // The default prefix "initialization" must be added manually because this checker class - // is abstract and its subclasses are not named "InitializationChecker". - result.add("initialization"); return result; } diff --git a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java index e536cf1f593f..0bf965a8ea01 100644 --- a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java +++ b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java @@ -839,13 +839,11 @@ protected void setRoot(CompilationUnitTree newRoot) { *

This list determines which {@code @AnnotatedFor} annotations are recognized as covering * this checker. * - *

Note: {@link #getUpstreamCheckerNames()} and {@link #getSuppressWarningsPrefixes()} are a - * related pair and should be kept in sync. If you override this method to add an additional - * checker name (for example, the name of an abstract parent class that this checker extends), - * you should also override {@link #getSuppressWarningsPrefixes()} to add the corresponding - * {@code @SuppressWarnings} prefix for that checker. Otherwise, code marked - * {@code @AnnotatedFor} for the parent will be checked, but {@code @SuppressWarnings} written - * with the parent's prefix will not be honored (or vice versa). + *

This method is related to {@link #getSuppressWarningsPrefixes()}. By default, {@link + * #getSuppressWarningsPrefixes()} includes lower-case prefixes derived from all checker names + * returned by this method. For example, if an override adds the name of an abstract parent class + * that this checker extends, the parent class's lower-case checker name is also accepted as a + * {@code @SuppressWarnings} prefix. * * @return a list containing this checker name and all checkers it is a part of (that is, * checkers that called it) @@ -3074,12 +3072,10 @@ private boolean isAnnotatedForThisCheckerOrUpstreamChecker(@Nullable Element elt * *

The collection must not be empty and must not contain only {@link #SUPPRESS_ALL_PREFIX}. * - *

Note: {@link #getSuppressWarningsPrefixes()} and {@link #getUpstreamCheckerNames()} are a - * related pair and should be kept in sync. If you override this method to add an additional - * prefix (for example, the prefix of an abstract parent class that this checker extends), you - * should also override {@link #getUpstreamCheckerNames()} to add the corresponding checker - * name. Otherwise, {@code @SuppressWarnings} written with the parent's prefix will be honored, - * but code marked {@code @AnnotatedFor} for the parent will not be checked (or vice versa). + *

This method is related to {@link #getUpstreamCheckerNames()}. By default, the returned set + * includes lower-case prefixes derived from all checker names returned by {@link + * #getUpstreamCheckerNames()}, unless this checker class has a {@link SuppressWarningsPrefix} + * meta-annotation. * * @return non-empty modifiable set of lower-case prefixes for SuppressWarnings strings * @see #getUpstreamCheckerNames() @@ -3091,8 +3087,9 @@ public NavigableSet getSuppressWarningsPrefixes() { /** * Returns a sorted set of SuppressWarnings prefixes read from the {@link * SuppressWarningsPrefix} meta-annotation on the checker class. Or if no {@link - * SuppressWarningsPrefix} is used, the checker name is used. {@link #SUPPRESS_ALL_PREFIX} is - * also added, at the end, unless {@link #useAllcheckersPrefix} is false. + * SuppressWarningsPrefix} is used, prefixes are inferred from the upstream checker names. + * {@link #SUPPRESS_ALL_PREFIX} is also added, at the end, unless {@link #useAllcheckersPrefix} + * is false. * * @return a sorted set of SuppressWarnings prefixes */ @@ -3110,9 +3107,11 @@ protected final NavigableSet getStandardSuppressWarningsPrefixes() { return prefixes; } - // No @SuppressWarningsPrefixes annotation, by default infer key from class name. - String defaultPrefix = getDefaultSuppressWarningsPrefix(); - prefixes.add(defaultPrefix); + // No @SuppressWarningsPrefixes annotation, by default infer keys from upstream checker + // names. + for (String checkerName : getUpstreamCheckerNames()) { + prefixes.add(getDefaultSuppressWarningsPrefix(checkerName)); + } return prefixes; } @@ -3122,7 +3121,18 @@ protected final NavigableSet getStandardSuppressWarningsPrefixes() { * @return the default SuppressWarnings prefix for this checker based on the checker name */ private String getDefaultSuppressWarningsPrefix() { - String className = this.getClass().getSimpleName(); + return getDefaultSuppressWarningsPrefix(this.getClass().getSimpleName()); + } + + /** + * Returns the default SuppressWarnings prefix for the given checker name. + * + * @param checkerName a fully-qualified or simple checker class name + * @return the default SuppressWarnings prefix for the given checker name + */ + private static String getDefaultSuppressWarningsPrefix(String checkerName) { + int lastDot = checkerName.lastIndexOf('.'); + String className = lastDot == -1 ? checkerName : checkerName.substring(lastDot + 1); int indexOfChecker = className.lastIndexOf("Checker"); if (indexOfChecker == -1) { indexOfChecker = className.lastIndexOf("Subchecker"); From deef6da90bf2d3a500d17b51474327a87ae64cd1 Mon Sep 17 00:00:00 2001 From: Aosen Xiong Date: Thu, 11 Jun 2026 13:55:03 -0400 Subject: [PATCH 4/4] Clarify upstream checker name uses --- .../framework/source/SourceChecker.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java index 0bf965a8ea01..7576191bd63c 100644 --- a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java +++ b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java @@ -836,14 +836,16 @@ protected void setRoot(CompilationUnitTree newRoot) { * Returns a list containing this checker name and all checkers it is a part of (that is, * checkers that called it). * - *

This list determines which {@code @AnnotatedFor} annotations are recognized as covering - * this checker. - * - *

This method is related to {@link #getSuppressWarningsPrefixes()}. By default, {@link - * #getSuppressWarningsPrefixes()} includes lower-case prefixes derived from all checker names - * returned by this method. For example, if an override adds the name of an abstract parent class - * that this checker extends, the parent class's lower-case checker name is also accepted as a - * {@code @SuppressWarnings} prefix. + *

This list has two uses: + * + *

    + *
  • It determines which {@code @AnnotatedFor} annotations are recognized as covering this + * checker. + *
  • By default, {@link #getSuppressWarningsPrefixes()} includes lower-case prefixes derived + * from all checker names returned by this method. For example, if an override adds the + * name of an abstract parent class that this checker extends, the parent class's + * lower-case checker name is also accepted as a {@code @SuppressWarnings} prefix. + *
* * @return a list containing this checker name and all checkers it is a part of (that is, * checkers that called it)