Skip to content

Support package annotation subpackage opt-outs - #1996

Open
aosen-xiong wants to merge 4 commits into
eisop:masterfrom
aosen-xiong:eisop-1990
Open

Support package annotation subpackage opt-outs#1996
aosen-xiong wants to merge 4 commits into
eisop:masterfrom
aosen-xiong:eisop-1990

Conversation

@aosen-xiong

@aosen-xiong aosen-xiong commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Closes #1990.

Merge with eisop/jdk#138.

Adds applyToSubpackages to @AnnotatedFor, @HasQualifierParameter, and @ReportUse. The element defaults to true to preserve existing behavior.

Package lookup applies an annotation from an enclosing package only when applyToSubpackages is true. An annotation always applies to the package where it is written.

Tests are organized into opt-in and opt-out directories for each annotation:

  • Opt-in tests use the default value of true and check that the annotation reaches direct and transitively nested subpackages.
  • Opt-out tests set applyToSubpackages=false and check that the annotated package remains covered while direct and transitively nested subpackages are excluded.

Each package annotation and its package/subpackage classes are compiled in the same per-directory test invocation. This is particularly necessary for @AnnotatedFor, which has source retention.

Copilot AI lite review requested due to automatic review settings September 1, 2026 14:27

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an applyToSubpackages element (default true) to several package-applicable annotations so users can opt out of having an enclosing package’s annotation implicitly apply to subpackages, while preserving existing behavior by default. This updates the framework’s package-walk logic to respect the opt-out and adds tests and documentation to lock in the semantics.

Changes:

  • Extend @AnnotatedFor, @HasQualifierParameter, and @ReportUse with applyToSubpackages (default true) and update package-chain lookup to gate propagation to enclosing packages on that element.
  • Add regression tests covering both opt-in (default behavior) and opt-out behavior, including transitive subpackages.
  • Document the new behavior in the manual and changelog, including compatibility behavior when an older checker-qual is on the classpath.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated no comments.

Show a summary per file
File Description
framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java Adds reflective access to new elements; gates @HasQualifierParameter package propagation; exposes doesAnnotatedForApplyToSubpackages.
framework/src/main/java/org/checkerframework/common/basetype/BaseTypeChecker.java Updates @AnnotatedFor package propagation logic to respect opt-out via a dedicated “reaches subpackages” cache.
framework/src/main/java/org/checkerframework/common/util/report/ReportVisitor.java Updates @ReportUse lookup to respect applyToSubpackages for enclosing packages (but always apply to the annotated package itself).
checker-qual/src/main/java/org/checkerframework/framework/qual/AnnotatedFor.java Adds applyToSubpackages element and documents package/subpackage semantics.
checker-qual/src/main/java/org/checkerframework/framework/qual/HasQualifierParameter.java Adds applyToSubpackages element and updates Javadoc to describe opt-out behavior.
checker-qual/src/main/java/org/checkerframework/common/util/report/qual/ReportUse.java Converts marker annotation to include applyToSubpackages element and documents semantics.
framework/tests/report/reportuseoptin/package-info.java Package-level @ReportUse opt-in coverage test (default behavior).
framework/tests/report/reportuseoptin/InInnerPackage.java ReportUse opt-in: direct subpackage should be reported.
framework/tests/report/reportuseoptin/InNestedSubpackage.java ReportUse opt-in: transitive subpackage should be reported.
framework/tests/report/reportuseoptin/Uses.java ReportUse opt-in: verifies uses in nested packages trigger diagnostics.
framework/tests/report/reportuseoptout/package-info.java Package-level @ReportUse(applyToSubpackages=false) opt-out coverage test.
framework/tests/report/reportuseoptout/InPackage.java ReportUse opt-out: annotated package still reported.
framework/tests/report/reportuseoptout/InNestedSubpackage.java ReportUse opt-out: transitive subpackage excluded.
framework/tests/report/reportuseoptout/Uses.java ReportUse opt-out: verifies subpackages are excluded while package remains covered.
framework/tests/conservative-defaults/annotatedfor/subpkgoptin/package-info.java @AnnotatedFor opt-in package propagation test setup.
framework/tests/conservative-defaults/annotatedfor/subpkgoptin/InPackage.java @AnnotatedFor opt-in: package itself in scope (errors expected).
framework/tests/conservative-defaults/annotatedfor/subpkgoptin/InSubpackage.java @AnnotatedFor opt-in: direct subpackage in scope (errors expected).
framework/tests/conservative-defaults/annotatedfor/subpkgoptin/InNestedSubpackage.java @AnnotatedFor opt-in: transitive subpackage in scope (errors expected).
framework/tests/conservative-defaults/annotatedfor/subpkgoptout/package-info.java @AnnotatedFor(applyToSubpackages=false) opt-out test setup.
framework/tests/conservative-defaults/annotatedfor/subpkgoptout/InPackage.java @AnnotatedFor opt-out: annotated package still in scope (errors expected).
framework/tests/conservative-defaults/annotatedfor/subpkgoptout/InSubpackage.java @AnnotatedFor opt-out: direct subpackage excluded (no errors expected).
framework/tests/conservative-defaults/annotatedfor/subpkgoptout/InNestedSubpackage.java @AnnotatedFor opt-out: transitive subpackage excluded (no errors expected).
checker/tests/tainting/hqpoptin/package-info.java @HasQualifierParameter opt-in test setup for package propagation.
checker/tests/tainting/hqpoptin/InSubpackage.java @HasQualifierParameter opt-in: subpackage inherits qualifier parameter (poly use allowed).
checker/tests/tainting/hqpoptin/InNestedSubpackage.java @HasQualifierParameter opt-in: transitive subpackage inherits qualifier parameter.
checker/tests/tainting/hqpoptout/package-info.java @HasQualifierParameter(applyToSubpackages=false) opt-out test setup.
checker/tests/tainting/hqpoptout/InPackage.java @HasQualifierParameter opt-out: annotated package still has qualifier parameter.
checker/tests/tainting/hqpoptout/InSubpackage.java @HasQualifierParameter opt-out: subpackage excluded (poly use rejected).
checker/tests/tainting/hqpoptout/InNestedSubpackage.java @HasQualifierParameter opt-out: transitive subpackage excluded (poly use rejected).
docs/manual/annotating-libraries.tex Documents package-level @AnnotatedFor and the new opt-out element.
docs/manual/generics.tex Documents package-level @HasQualifierParameter opt-out behavior.
docs/manual/advanced-features.tex Documents @DefaultQualifier(applyToSubpackages=false) as the existing analogous mechanism.
docs/CHANGELOG.md Records user-visible behavior and the new API/method for package propagation gating.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Should @AnnotatedFor on a package apply to subpackages?

3 participants