diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6b5369f5524..4c6b531c3e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,11 +35,11 @@ jobs: # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4.2.1 + uses: gradle/actions/setup-gradle@v4.2.2 - name: Setup Bazel - uses: bazel-contrib/setup-bazel@0.9.1 - if: matrix.script == 'cftests-nonjunit' + uses: bazel-contrib/setup-bazel@0.10.0 + if: ${{ matrix.script == 'cftests-nonjunit' }} with: # Avoid downloading Bazel every time. bazelisk-cache: true @@ -64,12 +64,24 @@ jobs: fail-fast: true matrix: # No need to run 'cftests-junit-jdk21' on JDK 21. - script: ['typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2', 'jspecify-conformance', 'jspecify-reference-checker'] + script: ['typecheck-part1', 'typecheck-part2', + 'guava', 'plume-lib', + 'daikon-part1', 'daikon-part2', + 'jspecify-conformance', 'jspecify-reference-checker', + 'misc'] java_version: [21] env: JAVA_VERSION: ${{ matrix.java_version }} steps: - uses: actions/checkout@v4 + if: ${{ matrix.script != 'misc' }} + with: + fetch-depth: 1 + - uses: actions/checkout@v4 + if: ${{ matrix.script == 'misc' }} + with: + # CI diff needs more history - 0 fetches all history. + fetch-depth: 0 - name: Set up JDK ${{ matrix.java_version }} uses: actions/setup-java@v4 with: @@ -79,8 +91,18 @@ jobs: # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4.2.1 - + uses: gradle/actions/setup-gradle@v4.2.2 + # Setup for misc tests + - name: Install misc dependencies + if: ${{ matrix.script == 'misc' }} + run: | + sudo apt install -y shellcheck devscripts python3-pip \ + texlive-latex-base texlive-latex-extra latexmk librsvg2-bin \ + autoconf dia hevea latexmk libasound2-dev rsync pdf2svg \ + libcups2-dev libfontconfig1-dev libx11-dev libxext-dev \ + libxrender-dev libxrandr-dev libxtst-dev libxt-dev \ + texlive-font-utils texlive-fonts-recommended texlive-latex-recommended + pip install black flake8 html5validator - name: Run test script checker/bin-devel/test-${{ matrix.script }} run: ./checker/bin-devel/test-${{ matrix.script }}.sh @@ -93,27 +115,81 @@ jobs: strategy: fail-fast: true matrix: - # jspecify-conformance and jspecify-reference-checker only tested on JDK 21. - script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', 'typecheck-part1', 'typecheck-part2', 'guava', 'plume-lib', 'daikon-part1', 'daikon-part2'] - # JDK 21 used by sanity before + # `jspecify-conformance` and `jspecify-reference-checker` only tested on JDK 21. + script: ['cftests-junit', 'cftests-nonjunit', 'cftests-junit-jdk21', + 'typecheck-part1', 'typecheck-part2', + 'guava', 'plume-lib', + 'daikon-part1', 'daikon-part2', + 'misc'] + # JDK 21 used by `sanity` and `remainder` before. + # `experimental` versions use the $version compiler, but run on JDK 21. java: [{version: '8', experimental: false}, {version: '11', experimental: false}, {version: '17', experimental: false}, - {version: '22', experimental: true}, - {version: '23-ea', experimental: true}, + {version: '23', experimental: false}, {version: '24-ea', experimental: true}] + exclude: + # JDK 8 does not allow toolchains, so testing 'cftests-junit-jdk21' is unnecessary. + - script: 'cftests-junit-jdk21' + java: {version: '8'} + # Only run `typecheck*`, `guava`, and `misc` scripts on core versions, + # so exclude 11 and 17. + - script: 'typecheck-part1' + java: {version: '11'} + - script: 'typecheck-part1' + java: {version: '17'} + - script: 'typecheck-part2' + java: {version: '11'} + - script: 'typecheck-part2' + java: {version: '17'} + - script: 'guava' + java: {version: '11'} + - script: 'guava' + java: {version: '17'} + - script: 'misc' + java: {version: '11'} + - script: 'misc' + java: {version: '17'} + # At least one plume-lib project no longer works on Java 8, + # so exclude 8, 11, and 17. + - script: 'plume-lib' + java: {version: '8'} + - script: 'plume-lib' + java: {version: '11'} + - script: 'plume-lib' + java: {version: '17'} + # Daikon produces 'this-escape' compiler warnings in JDK 22+. + # Exclude all versions here and just explicitly include with JDK 17. + - script: 'daikon-part1' + - script: 'daikon-part2' + include: + - script: 'daikon-part1' + java: {version: '17', experimental: false} + - script: 'daikon-part2' + java: {version: '17', experimental: false} + env: JAVA_VERSION: ${{ matrix.java.version }} continue-on-error: ${{ matrix.java.experimental }} steps: - - uses: actions/checkout@v4 + - name: Check out sources + uses: actions/checkout@v4 + if: ${{ matrix.script != 'misc' }} + with: + fetch-depth: 1 + - name: Check out sources with all history + uses: actions/checkout@v4 + if: ${{ matrix.script == 'misc' }} + with: + # CI diff needs more history - 0 fetches all history. + fetch-depth: 0 - name: Set up JDK ${{ matrix.java.version }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.java.version }} distribution: 'temurin' - name: Set up JDK 21 on an experimental platform - if: matrix.java.experimental + if: ${{ matrix.java.experimental }} uses: actions/setup-java@v4 with: # Install JDK 21 second, to make it the default on which gradle runs. @@ -124,11 +200,20 @@ jobs: # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4.2.1 - + uses: gradle/actions/setup-gradle@v4.2.2 + - name: Install misc dependencies + if: ${{ matrix.script == 'misc' }} + run: | + sudo apt install -y shellcheck devscripts python3-pip \ + texlive-latex-base texlive-latex-extra latexmk librsvg2-bin \ + autoconf dia hevea latexmk libasound2-dev rsync pdf2svg \ + libcups2-dev libfontconfig1-dev libx11-dev libxext-dev \ + libxrender-dev libxrandr-dev libxtst-dev libxt-dev \ + texlive-font-utils texlive-fonts-recommended texlive-latex-recommended + pip install black flake8 html5validator - name: Setup Bazel - uses: bazel-contrib/setup-bazel@0.9.1 - if: matrix.script == 'cftests-nonjunit' + uses: bazel-contrib/setup-bazel@0.10.0 + if: ${{ matrix.script == 'cftests-nonjunit' }} with: # Avoid downloading Bazel every time. bazelisk-cache: true @@ -139,15 +224,6 @@ jobs: - name: Run test script checker/bin-devel/test-${{ matrix.script }} run: ./checker/bin-devel/test-${{ matrix.script }}.sh - # TODO: it would be nicer to not run the job at all, but GH Actions does - # not allow accessing the matrix on the job-if clause. There is also no way - # for an earlier step to stop execution successfully. - # - # At least one plume-lib project no longer works on Java 8. - # Java 8 does not allow toolchains, so testing 'cftests-junit-jdk21' is unnecessary. - # Daikon produces 'this-escape' compiler warnings in JDK 22+. - if: (matrix.java.version != 8 || (matrix.script != 'plume-lib' && matrix.script != 'cftests-junit-jdk21')) && - (matrix.java.version <= 21 || (matrix.script != 'daikon-part1' && matrix.script != 'daikon-part2')) # Set the compiler version to use, allowing us to e.g. run Java 23 while gradle does not work # on Java 23 yet. This only tests the compiler, it does not use that version to run the tests. env: @@ -178,10 +254,10 @@ jobs: # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md - name: Setup Gradle - uses: gradle/actions/setup-gradle@v4.2.1 + uses: gradle/actions/setup-gradle@v4.2.2 - name: Install coreutils on MacOS - if: matrix.os == 'macos-latest' + if: ${{ matrix.os == 'macos-latest' }} run: brew install coreutils - name: Run test script checker/bin-devel/test-${{ matrix.script }} diff --git a/azure-pipelines.yml b/azure-pipelines.yml deleted file mode 100644 index 068eb5090d3..00000000000 --- a/azure-pipelines.yml +++ /dev/null @@ -1,75 +0,0 @@ -# Workaround for https://status.dev.azure.com/_event/179641421 -trigger: - branches: - include: - - '*' -pr: - branches: - include: - - '*' - -jobs: - -# Unlimited fetchDepth for misc_jobs, because of need to make contributors.tex -- job: misc_jdk8 - # dependsOn: - # - misc_jdk21 - pool: - vmImage: 'ubuntu-latest' - container: wmdietl/cf-ubuntu-jdk8-plus:latest - steps: - - checkout: self - - bash: ./checker/bin-devel/test-misc.sh - displayName: test-misc.sh -- job: misc_jdk11 - # dependsOn: - # - misc_jdk21 - pool: - vmImage: 'ubuntu-latest' - container: wmdietl/cf-ubuntu-jdk11-plus:latest - steps: - - checkout: self - - bash: ./checker/bin-devel/test-misc.sh - displayName: test-misc.sh -- job: misc_jdk17 - # dependsOn: - # - misc_jdk21 - pool: - vmImage: 'ubuntu-latest' - container: wmdietl/cf-ubuntu-jdk17-plus:latest - steps: - - checkout: self - - bash: ./checker/bin-devel/test-misc.sh - displayName: test-misc.sh -- job: misc_jdk21 - pool: - vmImage: 'ubuntu-latest' - container: wmdietl/cf-ubuntu-jdk21-plus:latest - steps: - - checkout: self - - bash: ./checker/bin-devel/test-misc.sh - displayName: test-misc.sh -# Disable until JDK 22 is stable -# - job: misc_jdk_latest -# dependsOn: -# # - canary_jobs -# - misc_jdk21 -# pool: -# vmImage: 'ubuntu-latest' -# container: wmdietl/cf-ubuntu-jdk-latest-plus:latest -# steps: -# - checkout: self -# - bash: ./checker/bin-devel/test-misc.sh -# displayName: test-misc.sh -- job: misc_jdk_next - # dependsOn: - # - misc_jdk21 - pool: - vmImage: 'ubuntu-latest' - container: wmdietl/cf-ubuntu-jdk-next-plus:latest - steps: - - checkout: self - # Run test, but do not cause overall failure - - bash: ./checker/bin-devel/test-misc.sh - continueOnError: true - displayName: test-misc.sh diff --git a/build.gradle b/build.gradle index d5f82170986..73a9d578bd3 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ apply plugin: 'de.undercouch.download' // There is another `repositories { ... }` block below; if you change this one, change that one as well. repositories { - maven { url 'https://oss.sonatype.org/content/repositories/snapshots/'} + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/'} mavenCentral() } @@ -51,8 +51,9 @@ ext { // The int corresponding to the major version of the current JVM. currentRuntimeJavaVersion = majorVersionToInt(JavaVersion.current().getMajorVersion()) - // As of 2024-08-06, delombok doesn't yet support JDK 23; see https://projectlombok.org/changelog . - skipDelombok = currentRuntimeJavaVersion >= 23 + // As of 2024-12-24, delombok doesn't yet support JDK 24; see https://projectlombok.org/changelog . + // Keep in sync with check in docs/examples/lombok/Makefile + skipDelombok = currentRuntimeJavaVersion >= 24 parentDir = file("${rootDir}/../").absolutePath @@ -115,7 +116,7 @@ task setLocalRepo(type:Exec) { // No group so it does not show up in the output of `gradlew tasks` task installGitHooks(type: Copy, dependsOn: 'setLocalRepo') { - description 'Copies git hooks to .git directory' + description = 'Copies git hooks to .git directory' from files('checker/bin-devel/git.post-merge', 'checker/bin-devel/git.pre-commit') rename('git\\.(.*)', '$1') into localRepo + '/hooks' @@ -158,7 +159,7 @@ allprojects { // * any new checkers have been added, or // * backward-incompatible changes have been made to APIs or elsewhere. // To make a snapshot release: ./gradlew publish - version '3.42.0-eisop5-SNAPSHOT' + version = '3.42.0-eisop6-SNAPSHOT' tasks.withType(JavaCompile).configureEach { options.fork = true @@ -170,11 +171,11 @@ allprojects { apply plugin: 'de.undercouch.download' apply plugin: 'net.ltgt.errorprone' - group 'io.github.eisop' + group = 'io.github.eisop' // Keep in sync with "repositories { ... }" block above. repositories { - maven { url 'https://oss.sonatype.org/content/repositories/snapshots/'} + maven { url = 'https://oss.sonatype.org/content/repositories/snapshots/'} mavenCentral() } @@ -352,6 +353,7 @@ allprojects { dependsOn(':checker:shadowJar') dependsOn(":framework-test:${tagletVersion}Classes") + doFirst { options.encoding = 'UTF-8' if (!name.equals('javadocDoclintAll')) { @@ -558,7 +560,7 @@ allprojects { } // end allProjects task version(group: 'Documentation') { - description 'Print Checker Framework version' + description = 'Print Checker Framework version' doLast { println version } @@ -575,8 +577,8 @@ task version(group: 'Documentation') { */ def createCheckTypeTask(projectName, taskName, checker, args = []) { project("${projectName}").tasks.create(name: "check${taskName}", type: JavaCompile, dependsOn: ':checker:shadowJar') { - description "Run the ${taskName} Checker on the main sources." - group 'Verification' + description = "Run the ${taskName} Checker on the main sources." + group = 'Verification' // Always run the task. outputs.upToDateWhen { false } source = project("${projectName}").sourceSets.main.java @@ -616,7 +618,7 @@ def createCheckTypeTask(projectName, taskName, checker, args = []) { } task htmlValidate(type: Exec, group: 'Format') { - description 'Validate that HTML files are well-formed' + description = 'Validate that HTML files are well-formed' executable 'html5validator' args = [ '--ignore', @@ -684,7 +686,7 @@ task allJavadoc(type: Javadoc, group: 'Documentation') { into "${rootDir}/docs/api" } injected.execOps.exec { - workingDir "${rootDir}/docs/api" + workingDir file("${rootDir}/docs/api") executable "${htmlToolsHome}/html-add-favicon" args += [ '.', @@ -747,18 +749,19 @@ def createJavadocTask(taskName, taskDescription, memberLevel) { createJavadocTask('javadocDoclintAll', 'Runs javadoc with -Xdoclint:all option.', JavadocMemberLevel.PRIVATE) task manual(group: 'Documentation') { - description 'Build the manual' + description = 'Build the manual' def injected = project.objects.newInstance(InjectedExecOps) doLast { injected.execOps.exec { - commandLine 'make', '-C', 'docs/manual', 'all' + workingDir = file('docs/manual') + commandLine 'make', 'all' } } } // No group so it does not show up in the output of `gradlew tasks` task downloadJtreg(type: Download) { - description "Downloads and unpacks jtreg." + description = 'Downloads and unpacks jtreg.' onlyIf { !(new File("${jtregHome}/lib/jtreg.jar").exists()) } // src 'https://ci.adoptopenjdk.net/view/Dependencies/job/jtreg/lastSuccessfulBuild/artifact/jtreg-4.2.0-tip.tar.gz' // If ci.adoptopenjdk.net is down, use this copy. @@ -795,7 +798,7 @@ task downloadJtreg(type: Download) { void clone(url, directory, ignoreError, extraArgs = []){ def injected = project.objects.newInstance(InjectedExecOps) injected.execOps.exec { - workingDir "${directory}/../" + workingDir file("${directory}/../") executable 'git' args = [ 'clone', @@ -806,8 +809,9 @@ void clone(url, directory, ignoreError, extraArgs = []){ ] args += extraArgs ignoreExitValue = ignoreError - timeout = 60000 // 60 seconds } + // TODO: not sure this does what it is supposed to. + // timeout = Duration.ofSeconds(60) } /** @@ -822,7 +826,7 @@ void clone(url, directory, ignoreError, extraArgs = []){ */ def createCloneTask(taskName, url, directory, extraArgs = []) { tasks.create(name: taskName) { - description "Obtain or update ${url}" + description = "Obtain or update ${url}" // Always run. outputs.upToDateWhen { false } @@ -832,12 +836,13 @@ def createCloneTask(taskName, url, directory, extraArgs = []) { doLast { if (file(directory).exists()) { injected.execOps.exec { - workingDir directory + workingDir file(directory) executable 'git' args = ['pull', '-q'] ignoreExitValue = true - timeout = 60000 // 60 seconds } + // TODO: not sure this does what it is supposed to. + // timeout = Duration.ofSeconds(60) } else { try { clone(url, directory, true, extraArgs) @@ -864,14 +869,14 @@ createCloneTask('getDoLikeJavac', 'https://github.com/opprop/do-like-javac.git', // No group so it does not show up in the output of `gradlew tasks` task pythonIsInstalled(type: Exec) { - description 'Check that the python3 executable is installed.' + description = 'Check that the python3 executable is installed.' executable = 'python3' args '--version' } task tags { - group 'Emacs' - description 'Create Emacs TAGS table' + group = 'Emacs' + description = 'Create Emacs TAGS table' def injected = project.objects.newInstance(InjectedExecOps) @@ -951,7 +956,7 @@ subprojects { if (!project.name.startsWith('checker-qual-android')) { task tags(type: Exec) { - description 'Create Emacs TAGS table' + description = 'Create Emacs TAGS table' commandLine 'bash', '-c', "find . \\( -name build -o -name jtreg -o -name tests \\) -prune -o -name '*.java' -print | sort-directory-order | xargs ctags -e -f TAGS" } } @@ -1039,7 +1044,7 @@ subprojects { // Add jtregTests to framework and checker modules if (project.name.is('framework') || project.name.is('checker')) { tasks.create(name: 'jtregTests', group: 'Verification') { - description 'Run the jtreg tests.' + description = 'Run the jtreg tests.' if (currentRuntimeJavaVersion < 11) { // jtreg only works on JDK 11+ @@ -1053,9 +1058,13 @@ subprojects { def injected = project.objects.newInstance(InjectedExecOps) + def isFramework = project.name.is('framework') + def isChecker = project.name.is('checker') + String jtregOutput = "${buildDir}/jtreg" String name = 'all' String tests = '.' + doLast { try { injected.execOps.exec { @@ -1089,12 +1098,12 @@ subprojects { '-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED', '-vmoptions:--add-opens=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED', ] - if (project.name.is('framework')) { + if (isFramework) { // Do not check for the annotated JDK args += [ '-javacoptions:-ApermitMissingJdk' ] - } else if (project.name.is('checker')) { + } else if (isChecker) { args += [ "-javacoptions:-classpath ${sourceSets.testannotations.output.asPath}", ] @@ -1126,7 +1135,7 @@ subprojects { sourceSets.test.allJava.filter {it.path.matches('.*test[\\\\/]junit.*')}.forEach { file -> String junitClassName = file.name.replaceAll('.java', '') tasks.create(name: "${junitClassName}", type: Test) { - description "Run ${junitClassName} tests." + description = "Run ${junitClassName} tests." include "**/${name}.class" testClassesDirs = testing.suites.test.sources.output.classesDirs classpath = testing.suites.test.sources.runtimeClasspath @@ -1157,7 +1166,7 @@ subprojects { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'failed' // Don't show the uninteresting stack traces from the exceptions. @@ -1181,7 +1190,7 @@ subprojects { // Create a nonJunitTests task per project tasks.create(name: 'nonJunitTests', group: 'Verification') { - description 'Run all Checker Framework tests except for the JUnit tests and inference tests.' + description = 'Run all Checker Framework tests except for the JUnit tests and inference tests.' if (project.name.is('framework') || project.name.is('checker')) { dependsOn('jtregTests') } @@ -1203,21 +1212,21 @@ subprojects { // Create an inferenceTests task per project tasks.create(name: 'inferenceTests', group: 'Verification') { - description 'Run inference tests.' + description = 'Run inference tests.' if (project.name.is('checker')) { // NO-AFU: Needs to depend on future AFU version of CF // dependsOn('inferenceTests-part1', 'inferenceTests-part1') } } tasks.create(name: 'inferenceTests-part1', group: 'Verification') { - description 'Run inference tests (part 1).' + description = 'Run inference tests (part 1).' if (project.name.is('checker')) { // NO-AFU: Needs to depend on future AFU version of CF // dependsOn('ainferTest', 'wpiManyTest') } } tasks.create(name: 'inferenceTests-part2', group: 'Verification') { - description 'Run inference tests (part 2).' + description = 'Run inference tests (part 2).' if (project.name.is('checker')) { // NO-AFU: Needs to depend on future AFU version of CF // dependsOn('wpiPlumeLibTest') @@ -1228,15 +1237,15 @@ subprojects { // This isn't a test of the Checker Framework as the test and nonJunitTests tasks are. // Tasks such as 'checkInterning' are constructed by createCheckTypeTask. tasks.create(name: 'typecheck', group: 'Verification') { - description 'Run the Checker Framework on itself' + description = 'Run the Checker Framework on itself' dependsOn('typecheck-part1', 'typecheck-part2') } tasks.create(name: 'typecheck-part1', group: 'Verification') { - description 'Run the Checker Framework on itself (part 1)' + description = 'Run the Checker Framework on itself (part 1)' dependsOn('checkFormatter', 'checkInterning', 'checkOptional', 'checkPurity') } tasks.create(name: 'typecheck-part2', group: 'Verification') { - description 'Run the Checker Framework on itself (part 2)' + description = 'Run the Checker Framework on itself (part 2)' dependsOn('checkResourceLeak', 'checkSignature') if (project.name.is('framework') || project.name.is('checker')) { dependsOn('checkCompilerMessages') @@ -1247,7 +1256,7 @@ subprojects { // Create an allTests task per project. // allTests = test + nonJunitTests + inferenceTests + typecheck tasks.create(name: 'allTests', group: 'Verification') { - description 'Run all Checker Framework tests' + description = 'Run all Checker Framework tests' // The 'test' target is just the JUnit tests. dependsOn('test', 'nonJunitTests', 'inferenceTests', 'typecheck') } @@ -1273,7 +1282,7 @@ assemble.dependsOn(':checker:assembleForJavac') assemble.mustRunAfter(clean) task buildAll(group: 'Build') { - description 'Build all jar files, including source and javadoc jars' + description = 'Build all jar files, including source and javadoc jars' dependsOn(allJavadoc) subprojects { Project subproject -> dependsOn("${subproject.name}:assemble") @@ -1284,7 +1293,7 @@ task buildAll(group: 'Build') { } task releaseBuild(group: 'Build') { - description 'Build everything required for a release' + description = 'Build everything required for a release' dependsOn(clean) doFirst { release = true @@ -1296,7 +1305,7 @@ task releaseBuild(group: 'Build') { // No group so it does not show up in the output of `gradlew tasks` task releaseAndTest { - description 'Build everything required for a release and run allTests' + description = 'Build everything required for a release and run allTests' dependsOn(releaseBuild) subprojects { Project subproject -> dependsOn("${subproject.name}:allTests") diff --git a/checker-qual-android/build.gradle b/checker-qual-android/build.gradle index b3677061d4d..135d2ecb0f3 100644 --- a/checker-qual-android/build.gradle +++ b/checker-qual-android/build.gradle @@ -1,7 +1,7 @@ evaluationDependsOn(':checker-qual') task copySources(type: Copy) { - description 'Copy checker-qual source to checker-qual-android' + description = 'Copy checker-qual source to checker-qual-android' includeEmptyDirs = false doFirst { // Delete the directory in case a previously copied file should no longer be in checker-qual diff --git a/checker/build.gradle b/checker/build.gradle index c342841e88b..bbc55daf3cd 100644 --- a/checker/build.gradle +++ b/checker/build.gradle @@ -80,13 +80,13 @@ dependencies { testImplementation 'com.amazonaws:aws-java-sdk-ec2' testImplementation 'com.amazonaws:aws-java-sdk-kms' // The AWS SDK is used for testing the Called Methods Checker. - testImplementation platform('com.amazonaws:aws-java-sdk-bom:1.12.770') + testImplementation platform('com.amazonaws:aws-java-sdk-bom:1.12.780') // For the Resource Leak Checker's support for JavaEE. testImplementation 'javax.servlet:javax.servlet-api:4.0.1' // For the Resource Leak Checker's support for IOUtils. testImplementation 'commons-io:commons-io:2.18.0' // For the Nullness Checker test of junit-assertions.astub in JUnitNull.java - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.3' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.11.4' testImplementation 'org.apiguardian:apiguardian-api:1.1.2' // For tests that use JSpecify annotations testImplementation 'org.jspecify:jspecify:1.0.0' @@ -131,10 +131,12 @@ jar { // It is useful for those who only want to run `javac`. // checker.jar is copied to checker/dist/ when it is built by the shadowJar task. task assembleForJavac(dependsOn: shadowJar, group: 'Build') { - description 'Builds or downloads jars required by CheckerMain and puts them in checker/dist/.' + description = 'Builds or downloads jars required by CheckerMain and puts them in checker/dist/.' dependsOn project(':checker-qual').tasks.jar + def checkerQualJarFile = file(project(':checker-qual').tasks.getByName('jar').archiveFile) + def checkerUtilJarFile = file(project(':checker-util').tasks.getByName('jar').archiveFile) + doLast { - def checkerQualJarFile = file(project(':checker-qual').tasks.getByName('jar').archiveFile) if (!checkerQualJarFile.exists()) { throw new GradleException('File not found: ' + checkerQualJarFile) } @@ -147,7 +149,6 @@ task assembleForJavac(dependsOn: shadowJar, group: 'Build') { } } - def checkerUtilJarFile = file(project(':checker-util').tasks.getByName('jar').archiveFile) if (!checkerUtilJarFile.exists()) { throw new GradleException('File not found: ' + checkerUtilJarFile) } @@ -172,10 +173,9 @@ task assembleForJavac(dependsOn: shadowJar, group: 'Build') { } assemble.dependsOn assembleForJavac -assemble.dependsOn(':getDoLikeJavac') task allSourcesJar(type: Jar, group: 'Build') { - description 'Creates a sources jar that includes sources for all Checker Framework classes in checker.jar' + description = 'Creates a sources jar that includes sources for all Checker Framework classes in checker.jar' destinationDirectory = file("${projectDir}/dist") archiveFileName = 'checker-source.jar' archiveClassifier = 'sources' @@ -185,7 +185,7 @@ task allSourcesJar(type: Jar, group: 'Build') { } task allJavadocJar(type: Jar, group: 'Build') { - description 'Creates javadoc jar including Javadoc for all of the Checker Framework' + description = 'Creates javadoc jar including Javadoc for all of the Checker Framework' dependsOn rootProject.tasks.allJavadoc destinationDirectory = file("${projectDir}/dist") archiveFileName = 'checker-javadoc.jar' @@ -197,7 +197,7 @@ task allJavadocJar(type: Jar, group: 'Build') { import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar task checkerJar(type: ShadowJar, dependsOn: compileJava, group: 'Build') { - description "Builds checker-${project.version}.jar with all dependencies except checker-qual and checker-util." + description = "Builds checker-${project.version}.jar with all dependencies except checker-qual and checker-util." includeEmptyDirs = false from shadowJar.source @@ -220,7 +220,7 @@ jar { } shadowJar { - description 'Creates checker-VERSION-all.jar and copies it to dist/checker.jar.' + description = 'Creates checker-VERSION-all.jar and copies it to dist/checker.jar.' // To see what files are incorporated into the shadow jar file: // doFirst { println sourceSets.main.runtimeClasspath.asPath } archiveClassifier = 'all' @@ -292,21 +292,21 @@ checkCompilerMessages { } task nullnessExtraTests(type: Exec, dependsOn: assembleForJavac, group: 'Verification') { - description 'Run extra tests for the Nullness Checker.' + description = 'Run extra tests for the Nullness Checker.' executable 'make' environment JAVAC: "${projectDir}/bin/javac -AnoJreVersionCheck", JAVAP: 'javap' args = ['-C', 'tests/nullness-extra/'] } task commandLineTests(type: Exec, dependsOn: assembleForJavac, group: 'Verification') { - description 'Run tests that need a special command line.' + description = 'Run tests that need a special command line.' executable 'make' environment JAVAC: "${projectDir}/bin/javac -AnoJreVersionCheck" args = ['-C', 'tests/command-line/'] } task tutorialTests(dependsOn: assembleForJavac, group: 'Verification') { - description 'Test that the tutorial is working as expected.' + description = 'Test that the tutorial is working as expected.' doLast { ant.ant(dir: "${rootDir}/docs/tutorial/tests", useNativeBasedir: 'true', inheritAll: 'false') { target(name: 'check-tutorial') @@ -315,14 +315,14 @@ task tutorialTests(dependsOn: assembleForJavac, group: 'Verification') { } task exampleTests(type: Exec, dependsOn: assembleForJavac, group: 'Verification') { - description 'Run tests for the example programs.' + description = 'Run tests for the example programs.' executable 'make' environment JAVAC: "${projectDir}/bin/javac -AnoJreVersionCheck" args = ['-C', '../docs/examples'] } task demosTests(dependsOn: assembleForJavac, group: 'Verification') { - description 'Test that the demos are working as expected.' + description = 'Test that the demos are working as expected.' def injected = project.objects.newInstance(InjectedExecOps) @@ -356,12 +356,12 @@ task demosTests(dependsOn: assembleForJavac, group: 'Verification') { } task allNullnessTests(type: Test, group: 'Verification') { - description 'Run all JUnit tests for the Nullness Checker.' + description = 'Run all JUnit tests for the Nullness Checker.' include '**/Nullness*.class' } task allCalledMethodsTests(type: Test, group: 'Verification') { - description 'Run all JUnit tests for the Called Methods Checker.' + description = 'Run all JUnit tests for the Called Methods Checker.' include '**/CalledMethods*.class' if (!skipDelombok) { dependsOn 'delombok' @@ -369,14 +369,14 @@ task allCalledMethodsTests(type: Test, group: 'Verification') { } task allResourceLeakTests(type: Test, group: 'Verification') { - description 'Run all JUnit tests for the Resource Leak Checker.' + description = 'Run all JUnit tests for the Resource Leak Checker.' include '**/ResourceLeak*.class' include '**/MustCall*.class' } // These are tests that should only be run with JDK 11+. task jtregJdk11Tests(dependsOn: ':downloadJtreg', group: 'Verification') { - description 'Run the jtreg tests made for JDK 11+.' + description = 'Run the jtreg tests made for JDK 11+.' dependsOn('compileJava') dependsOn('compileTestJava') dependsOn('shadowJar') @@ -420,7 +420,7 @@ task jtregJdk11Tests(dependsOn: ':downloadJtreg', group: 'Verification') { } task delombok { - description 'Delomboks the source code tree in tests/calledmethods-lombok' + description = 'Delomboks the source code tree in tests/calledmethods-lombok' def srcDelomboked = 'tests/calledmethods-delomboked' def srcJava = 'tests/calledmethods-lombok' @@ -465,7 +465,7 @@ test { } task ainferTestCheckerGenerateStubs(type: Test) { - description 'Internal task. Users should run ainferTestCheckerStubTest instead. This type-checks the ainfer-testchecker files with -Ainfer=stubs to generate stub files.' + description = 'Internal task. Users should run ainferTestCheckerStubTest instead. This type-checks the ainfer-testchecker files with -Ainfer=stubs to generate stub files.' dependsOn(compileTestJava) doFirst { @@ -479,7 +479,7 @@ task ainferTestCheckerGenerateStubs(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } @@ -508,7 +508,7 @@ task ainferTestCheckerGenerateStubs(type: Test) { } task ainferTestCheckerValidateStubs(type: Test) { - description 'Internal task. Users should run ainferTestCheckerStubTest instead. This type-checks the ainfer-testchecker tests using the stub files generated by ainferTestCheckerGenerateStubs.' + description = 'Internal task. Users should run ainferTestCheckerStubTest instead. This type-checks the ainfer-testchecker tests using the stub files generated by ainferTestCheckerGenerateStubs.' dependsOn(ainferTestCheckerGenerateStubs) outputs.upToDateWhen { false } @@ -518,13 +518,13 @@ task ainferTestCheckerValidateStubs(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } } task ainferTestCheckerGenerateAjava(type: Test) { - description 'Internal task. Users should run ainferTestCheckerAjavaTest instead. This type-checks the ainfer-testchecker files with -Ainfer=ajava to generate ajava files.' + description = 'Internal task. Users should run ainferTestCheckerAjavaTest instead. This type-checks the ainfer-testchecker files with -Ainfer=ajava to generate ajava files.' dependsOn(compileTestJava) doFirst { @@ -538,7 +538,7 @@ task ainferTestCheckerGenerateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } @@ -567,7 +567,7 @@ task ainferTestCheckerGenerateAjava(type: Test) { } task ainferTestCheckerValidateAjava(type: Test) { - description 'Internal task. Users should run ainferTestCheckerAjavaTest instead. This re-type-checks the ainfer-testchecker files using the ajava files generated by ainferTestCheckerGenerateAjava' + description = 'Internal task. Users should run ainferTestCheckerAjavaTest instead. This re-type-checks the ainfer-testchecker files using the ajava files generated by ainferTestCheckerGenerateAjava' dependsOn(ainferTestCheckerGenerateAjava) outputs.upToDateWhen { false } @@ -577,7 +577,7 @@ task ainferTestCheckerValidateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } } @@ -616,20 +616,20 @@ void copyNonannotatedToAnnotatedDirectory(String testdir) { // run the insert-annotations-to-source tool. Instead, it tests the -Ainfer=stubs feature // and the -AmergeStubsWithSource feature to do WPI using stub files. task ainferTestCheckerStubTest(dependsOn: 'shadowJar', group: 'Verification') { - description 'Run tests for whole-program inference using stub files' + description = 'Run tests for whole-program inference using stub files' dependsOn(ainferTestCheckerValidateStubs) outputs.upToDateWhen { false } } // Like ainferTestCheckerStubTest, but with ajava files instead task ainferTestCheckerAjavaTest(dependsOn: 'shadowJar', group: 'Verification') { - description 'Run tests for whole-program inference using ajava files' + description = 'Run tests for whole-program inference using ajava files' dependsOn(ainferTestCheckerValidateAjava) outputs.upToDateWhen { false } } task ainferTestCheckerGenerateJaifs(type: Test) { - description 'Internal task. Users should run ainferTestCheckerJaifTest instead. This type-checks the ainfer-testchecker files with -Ainfer=jaifs to generate .jaif files' + description = 'Internal task. Users should run ainferTestCheckerJaifTest instead. This type-checks the ainfer-testchecker files with -Ainfer=jaifs to generate .jaif files' dependsOn(compileTestJava) dependsOn(':checker-qual:jar') // For the Value Checker annotations. @@ -643,7 +643,7 @@ task ainferTestCheckerGenerateJaifs(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } @@ -708,7 +708,7 @@ task ainferTestCheckerGenerateJaifs(type: Test) { } task ainferTestCheckerValidateJaifs(type: Test) { - description 'Internal task. Users should run ainferTestCheckerJaifTest instead. This type-checks the ainfer-testchecker files using the .jaif files generated by ainferTestCheckerGenerateJaifs' + description = 'Internal task. Users should run ainferTestCheckerJaifTest instead. This type-checks the ainfer-testchecker files using the .jaif files generated by ainferTestCheckerGenerateJaifs' dependsOn(ainferTestCheckerGenerateJaifs) outputs.upToDateWhen { false } @@ -718,19 +718,19 @@ task ainferTestCheckerValidateJaifs(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } } task ainferTestCheckerJaifTest(dependsOn: 'shadowJar', group: 'Verification') { - description 'Run tests for whole-program inference using .jaif files' + description = 'Run tests for whole-program inference using .jaif files' dependsOn(ainferTestCheckerValidateJaifs) outputs.upToDateWhen { false } } task ainferIndexGenerateAjava(type: Test) { - description 'Internal task. Users should run ainferIndexAjavaTest instead. This type-checks the ainfer-index files with -Ainfer=ajava to generate ajava files.' + description = 'Internal task. Users should run ainferIndexAjavaTest instead. This type-checks the ainfer-index files with -Ainfer=ajava to generate ajava files.' dependsOn(compileTestJava) doFirst { @@ -744,7 +744,7 @@ task ainferIndexGenerateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } @@ -754,7 +754,7 @@ task ainferIndexGenerateAjava(type: Test) { } task ainferIndexValidateAjava(type: Test) { - description 'Internal task. Users should run ainferIndexAjavaTest instead. This re-type-checks the ainfer-index files using the ajava files generated by ainferIndexGenerateAjava' + description = 'Internal task. Users should run ainferIndexAjavaTest instead. This re-type-checks the ainfer-index files using the ajava files generated by ainferIndexGenerateAjava' dependsOn(ainferIndexGenerateAjava) outputs.upToDateWhen { false } @@ -764,19 +764,19 @@ task ainferIndexValidateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } } task ainferIndexAjavaTest(dependsOn: 'shadowJar', group: 'Verification') { - description 'Run tests for whole-program inference using ajava files and the Index Checker' + description = 'Run tests for whole-program inference using ajava files and the Index Checker' dependsOn(ainferIndexValidateAjava) outputs.upToDateWhen { false } } task ainferNullnessGenerateAjava(type: Test) { - description 'Internal task. Users should run ainferNullnessAjavaTest instead. This type-checks the ainfer-nullness files with -Ainfer=ajava to generate ajava files.' + description = 'Internal task. Users should run ainferNullnessAjavaTest instead. This type-checks the ainfer-nullness files with -Ainfer=ajava to generate ajava files.' dependsOn(compileTestJava) doFirst { @@ -790,7 +790,7 @@ task ainferNullnessGenerateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } @@ -800,7 +800,7 @@ task ainferNullnessGenerateAjava(type: Test) { } task ainferNullnessValidateAjava(type: Test) { - description 'Internal task. Users should run ainferNullnessAjavaTest instead. This re-type-checks the ainfer-nullness files using the ajava files generated by ainferNullnessGenerateAjava' + description = 'Internal task. Users should run ainferNullnessAjavaTest instead. This re-type-checks the ainfer-nullness files using the ajava files generated by ainferNullnessGenerateAjava' dependsOn(ainferNullnessGenerateAjava) outputs.upToDateWhen { false } @@ -810,19 +810,19 @@ task ainferNullnessValidateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } } task ainferNullnessAjavaTest(dependsOn: 'shadowJar', group: 'Verification') { - description 'Run tests for whole-program inference using ajava files and the Nullness Checker' + description = 'Run tests for whole-program inference using ajava files and the Nullness Checker' dependsOn(ainferNullnessValidateAjava) outputs.upToDateWhen { false } } task ainferResourceLeakGenerateAjava(type: Test) { - description 'Internal task. Users should run ainferResourceLeakAjavaTest instead. This type-checks the ainfer-index files with -Ainfer=ajava to generate ajava files.' + description = 'Internal task. Users should run ainferResourceLeakAjavaTest instead. This type-checks the ainfer-index files with -Ainfer=ajava to generate ajava files.' dependsOn(compileTestJava) doFirst { @@ -836,7 +836,7 @@ task ainferResourceLeakGenerateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } @@ -846,7 +846,7 @@ task ainferResourceLeakGenerateAjava(type: Test) { } task ainferResourceLeakValidateAjava(type: Test) { - description 'Internal task. Users should run ainferResourceLeakAjavaTest instead. This re-type-checks the ainfer-resourceleak files using the ajava files generated by ainferResourceLeakGenerateAjava' + description = 'Internal task. Users should run ainferResourceLeakAjavaTest instead. This re-type-checks the ainfer-resourceleak files using the ajava files generated by ainferResourceLeakGenerateAjava' dependsOn(ainferResourceLeakGenerateAjava) outputs.upToDateWhen { false } @@ -856,19 +856,19 @@ task ainferResourceLeakValidateAjava(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and the expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } } task ainferResourceLeakAjavaTest(dependsOn: 'shadowJar', group: 'Verification') { - description 'Run tests for whole-program inference using ajava files and the Resource Leak Checker' + description = 'Run tests for whole-program inference using ajava files and the Resource Leak Checker' dependsOn(ainferResourceLeakValidateAjava) outputs.upToDateWhen { false } } task ainferNullnessGenerateJaifs(type: Test) { - description 'Internal task. Users should run ainferNullnessJaifTest instead. This type-checks the ainfer-nullness files with -Ainfer=jaifs to generate .jaif files' + description = 'Internal task. Users should run ainferNullnessJaifTest instead. This type-checks the ainfer-nullness files with -Ainfer=jaifs to generate .jaif files' dependsOn(compileTestJava) doFirst { @@ -881,7 +881,7 @@ task ainferNullnessGenerateJaifs(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } @@ -930,7 +930,7 @@ task ainferNullnessGenerateJaifs(type: Test) { } task ainferNullnessValidateJaifs(type: Test) { - description 'Internal task. Users should run ainferNullnessJaifTest instead. This re-type-checks the ainfer-nullness files using the .jaif files generated by ainferNullnessGenerateJaifs' + description = 'Internal task. Users should run ainferNullnessJaifTest instead. This re-type-checks the ainfer-nullness files using the .jaif files generated by ainferNullnessGenerateJaifs' dependsOn(ainferNullnessGenerateJaifs) outputs.upToDateWhen { false } @@ -940,13 +940,13 @@ task ainferNullnessValidateJaifs(type: Test) { outputs.upToDateWhen { false } // Show the found unexpected diagnostics and expected diagnostics not found. - exceptionFormat 'full' + exceptionFormat = 'full' events 'passed', 'skipped', 'failed' } } task ainferNullnessJaifTest(dependsOn: 'shadowJar', group: 'Verification') { - description 'Run tests for whole-program inference using .jaif files' + description = 'Run tests for whole-program inference using .jaif files' dependsOn(ainferNullnessValidateJaifs) outputs.upToDateWhen { false } } @@ -955,7 +955,7 @@ task ainferNullnessJaifTest(dependsOn: 'shadowJar', group: 'Verification') { // Empty task that just runs both the jaif and stub WPI tests. // It is run as part of the inferenceTests task. task ainferTest(group: 'Verification') { - description 'Run tests for all whole program inference modes.' + description = 'Run tests for all whole program inference modes.' dependsOn('ainferTestCheckerJaifTest') dependsOn('ainferTestCheckerStubTest') dependsOn('ainferTestCheckerAjavaTest') @@ -971,7 +971,7 @@ task ainferTest(group: 'Verification') { // This is run as part of the inferenceTests task. task wpiManyTest(group: 'Verification') { - description 'Tests the wpi-many.sh script (and indirectly the wpi.sh script). Requires an Internet connection.' + description = 'Tests the wpi-many.sh script (and indirectly the wpi.sh script). Requires an Internet connection.' dependsOn(assembleForJavac) dependsOn(':getDoLikeJavac') // This test must always be re-run when requested. @@ -1104,7 +1104,7 @@ task wpiManyTest(group: 'Verification') { // This is run as part of the inferenceTests task. task wpiPlumeLibTest(group: 'Verification') { - description 'Tests whole-program inference on the plume-lib projects. Requires an Internet connection.' + description = 'Tests whole-program inference on the plume-lib projects. Requires an Internet connection.' dependsOn(assembleForJavac) dependsOn(':getDoLikeJavac') diff --git a/checker/src/main/java/org/checkerframework/checker/i18nformatter/I18nFormatterVisitor.java b/checker/src/main/java/org/checkerframework/checker/i18nformatter/I18nFormatterVisitor.java index 5a062276935..8d3ffdc6471 100644 --- a/checker/src/main/java/org/checkerframework/checker/i18nformatter/I18nFormatterVisitor.java +++ b/checker/src/main/java/org/checkerframework/checker/i18nformatter/I18nFormatterVisitor.java @@ -170,9 +170,9 @@ protected boolean commonAssignmentCheck( } } - /// TODO: What does "take precedence over" mean? Both are issued, but the - /// "i18nformat.excess.arguments" appears first in the output. Is this meant to not call - /// super.commonAssignmentCheck() if `result` is already false? + // TODO: What does "take precedence over" mean? Both are issued, but the + // "i18nformat.excess.arguments" appears first in the output. Is this meant to not call + // super.commonAssignmentCheck() if `result` is already false? // By calling super.commonAssignmentCheck() last, any "i18nformat.excess.arguments" // message issued for a given line of code will take precedence over the // "assignment.type.incompatible" diff --git a/checker/src/main/java/org/checkerframework/checker/index/upperbound/UpperBoundTransfer.java b/checker/src/main/java/org/checkerframework/checker/index/upperbound/UpperBoundTransfer.java index b0ccca0ff3a..37fe1b85bab 100644 --- a/checker/src/main/java/org/checkerframework/checker/index/upperbound/UpperBoundTransfer.java +++ b/checker/src/main/java/org/checkerframework/checker/index/upperbound/UpperBoundTransfer.java @@ -175,10 +175,16 @@ public TransferResult visitAssignment( * {@code node} is known to be {@code typeOfNode}. If the node is a plus or a minus then the * types of the left and right operands can be refined to include offsets. If the node is a * multiplication, its operands can also be refined. See {@link - * #propagateToAdditionOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)}, {@link - * #propagateToSubtractionOperands(LessThanLengthOf, NumericalSubtractionNode, TransferInput, - * CFStore)}, and {@link #propagateToMultiplicationOperand(LessThanLengthOf, Node, Node, - * TransferInput, CFStore)} for details. + * #propagateToAdditionOperand(UBQualifier.LessThanLengthOf, Node, Node, TransferInput, + * CFStore)}, {@link #propagateToSubtractionOperands(UBQualifier.LessThanLengthOf, + * NumericalSubtractionNode, TransferInput, CFStore)}, and {@link + * #propagateToMultiplicationOperand(UBQualifier.LessThanLengthOf, Node, Node, TransferInput, + * CFStore)} for details. + * + * @param typeOfNode type of node + * @param node the node + * @param in the TransferInput before propagate to this operand + * @param store location to store the refined type */ private void propagateToOperands( LessThanLengthOf typeOfNode, @@ -234,10 +240,10 @@ private void propagateToMultiplicationOperand( * *

This means that the left node is less than or equal to the length of the array when the * right node is subtracted from the left node. Note that unlike {@link - * #propagateToAdditionOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)} and {@link - * #propagateToMultiplicationOperand(LessThanLengthOf, Node, Node, TransferInput, CFStore)}, - * this method takes the NumericalSubtractionNode instead of the two operand nodes. This - * implements case 4. + * #propagateToAdditionOperand(UBQualifier.LessThanLengthOf, Node, Node, TransferInput, + * CFStore)} and {@link #propagateToMultiplicationOperand(UBQualifier.LessThanLengthOf, Node, + * Node, TransferInput, CFStore)}, this method takes the NumericalSubtractionNode instead of the + * two operand nodes. This implements case 4. * * @param typeOfSubtraction type of node * @param node subtraction node that has typeOfSubtraction diff --git a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java index 209c0247726..d5357bbbd06 100644 --- a/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java +++ b/checker/src/main/java/org/checkerframework/checker/initialization/InitializationParentAnnotatedTypeFactory.java @@ -716,6 +716,7 @@ public Void visitExecutable(AnnotatedExecutableType t, Void p) { if (elem.getKind() == ElementKind.CONSTRUCTOR) { AnnotatedDeclaredType returnType = (AnnotatedDeclaredType) t.getReturnType(); DeclaredType underlyingType = returnType.getUnderlyingType(); + // TODO: Make sure we check explicit annotations somewhere. returnType.replaceAnnotation( getUnderInitializationAnnotationOfSuperType(underlyingType)); } diff --git a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java index 9fd622fd1e4..24950471210 100644 --- a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java +++ b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitAnnotatedTypeFactory.java @@ -51,6 +51,8 @@ import org.checkerframework.framework.type.treeannotator.PropagationTreeAnnotator; import org.checkerframework.framework.type.treeannotator.TreeAnnotator; import org.checkerframework.framework.type.typeannotator.DefaultForTypeAnnotator; +import org.checkerframework.framework.type.typeannotator.ListTypeAnnotator; +import org.checkerframework.framework.type.typeannotator.TypeAnnotator; import org.checkerframework.javacutil.AnnotationBuilder; import org.checkerframework.javacutil.AnnotationUtils; import org.checkerframework.javacutil.TreeUtils; @@ -731,20 +733,22 @@ public Void visitUnary(UnaryTree tree, AnnotatedTypeMirror type) { return null; } - // The result of newly allocated structures is always non-null. + // The result of newly allocated structures is always non-null, + // explicit nullable annotations are left intact for the visitor to inspect. @Override public Void visitNewClass(NewClassTree tree, AnnotatedTypeMirror type) { - type.replaceAnnotation(NONNULL); + // The constructor return type should already be NONNULL, so in most cases this will do + // nothing. + type.addMissingAnnotation(NONNULL); return null; } + // The result of newly allocated structures is always non-null, + // explicit nullable annotations are left intact for the visitor to inspect. @Override public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) { super.visitNewArray(tree, type); - - // The result of newly allocated structures is always non-null. - type.replaceAnnotation(NONNULL); - + type.addMissingAnnotation(NONNULL); return null; } @@ -774,6 +778,38 @@ public Void visitMethodInvocation(MethodInvocationTree tree, AnnotatedTypeMirror } } + @Override + protected TypeAnnotator createTypeAnnotator() { + return new ListTypeAnnotator(super.createTypeAnnotator(), new NullnessTypeAnnotator(this)); + } + + /** + * This type annotator ensures that constructor return types are NONNULL, unless there is an + * explicit different annotation. + */ + protected class NullnessTypeAnnotator extends TypeAnnotator { + + /** + * Creates a new NullnessTypeAnnotator. + * + * @param atypeFactory this factory + */ + public NullnessTypeAnnotator(NullnessNoInitAnnotatedTypeFactory atypeFactory) { + super(atypeFactory); + } + + @Override + public Void visitExecutable(AnnotatedExecutableType t, Void p) { + Void result = super.visitExecutable(t, p); + Element elem = t.getElement(); + if (elem.getKind() == ElementKind.CONSTRUCTOR) { + AnnotatedDeclaredType returnType = (AnnotatedDeclaredType) t.getReturnType(); + returnType.addMissingAnnotation(NONNULL); + } + return result; + } + } + /** * Returns the list of annotations of the non-null type system. * diff --git a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitVisitor.java b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitVisitor.java index c7933484ef5..a11cc6173d6 100644 --- a/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitVisitor.java +++ b/checker/src/main/java/org/checkerframework/checker/nullness/NullnessNoInitVisitor.java @@ -47,7 +47,6 @@ import org.checkerframework.framework.type.AnnotatedTypeFactory; import org.checkerframework.framework.type.AnnotatedTypeMirror; import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedArrayType; -import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedDeclaredType; import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedExecutableType; import org.checkerframework.framework.type.AnnotatedTypeMirror.AnnotatedPrimitiveType; import org.checkerframework.javacutil.AnnotationMirrorSet; @@ -59,9 +58,7 @@ import org.checkerframework.javacutil.TreeUtilsAfterJava11.SwitchExpressionUtils; import org.checkerframework.javacutil.TypesUtils; -import java.lang.annotation.Annotation; import java.util.List; -import java.util.Set; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; @@ -174,16 +171,6 @@ public boolean isValidUse(AnnotatedPrimitiveType type, Tree tree) { return true; } - private boolean containsSameByName( - Set> quals, AnnotationMirror anno) { - for (Class q : quals) { - if (atypeFactory.areSameByClass(anno, q)) { - return true; - } - } - return false; - } - @Override protected void checkConstructorResult( AnnotatedExecutableType constructorType, ExecutableElement constructorElement) { @@ -348,14 +335,13 @@ public Void visitNewArray(NewArrayTree tree, Void p) { componentType.getAnnotations(), type.toString()); } - // type already contains substituted annotations so must look at original tree annotations - List annotations = - TreeUtils.annotationsFromArrayCreation(tree, 0); - if (AnnotationUtils.containsSame(annotations, NULLABLE) - || AnnotationUtils.containsSame(annotations, MONOTONIC_NONNULL) - || AnnotationUtils.containsSame(annotations, POLYNULL)) { + + if (type.hasEffectiveAnnotation(NULLABLE) + || type.hasEffectiveAnnotation(MONOTONIC_NONNULL) + || type.hasEffectiveAnnotation(POLYNULL)) { checker.reportError(tree, "nullness.on.new.array"); } + return super.visitNewArray(tree, p); } @@ -844,28 +830,13 @@ public Void visitNewClass(NewClassTree tree, Void p) { if (enclosingExpr != null) { checkForNullability(enclosingExpr, DEREFERENCE_OF_NULLABLE); } - AnnotatedDeclaredType type = atypeFactory.getAnnotatedType(tree); - ExpressionTree identifier = tree.getIdentifier(); - if (identifier instanceof AnnotatedTypeTree) { - AnnotatedTypeTree t = (AnnotatedTypeTree) identifier; - for (AnnotationMirror a : atypeFactory.getAnnotatedType(t).getAnnotations()) { - // is this an annotation of the nullness checker? - boolean nullnessCheckerAnno = - containsSameByName(atypeFactory.getNullnessAnnotations(), a); - if (nullnessCheckerAnno && !AnnotationUtils.areSame(NONNULL, a)) { - // The type is not non-null => warning - checker.reportWarning(tree, "new.class.type.invalid", type.getAnnotations()); - // Note that other consistency checks are made by isValid. - } - } - if (t.toString().contains("@PolyNull")) { - // TODO: this is a hack, but PolyNull gets substituted - // afterwards - checker.reportWarning(tree, "new.class.type.invalid", type.getAnnotations()); - } + + AnnotatedTypeMirror.AnnotatedDeclaredType type = atypeFactory.getAnnotatedType(tree); + if (type.hasEffectiveAnnotation(NULLABLE) + || type.hasEffectiveAnnotation(MONOTONIC_NONNULL) + || type.hasEffectiveAnnotation(POLYNULL)) { + checker.reportError(tree, "nullness.on.new.object"); } - // TODO: It might be nicer to introduce a framework-level - // isValidNewClassType or some such. return super.visitNewClass(tree, p); } diff --git a/checker/src/main/java/org/checkerframework/checker/nullness/messages.properties b/checker/src/main/java/org/checkerframework/checker/nullness/messages.properties index 4ab4be04edd..5867ce7a919 100644 --- a/checker/src/main/java/org/checkerframework/checker/nullness/messages.properties +++ b/checker/src/main/java/org/checkerframework/checker/nullness/messages.properties @@ -24,6 +24,7 @@ instanceof.nonnull.redundant=redundant @NonNull annotation on instanceof new.array.type.invalid=annotations %s may not be applied as component type for array "%s" nullness.on.constructor=do not write nullness annotations on a constructor, whose result is always non-null nullness.on.new.array=do not write nullness annotations on an array creation, which is always non-null +nullness.on.new.object=do not write nullness annotations on an object creation, which is always non-null nullness.on.enum=do not write nullness annotations on an enum constant, which is always non-null nullness.on.exception.parameter=do not write nullness annotations on an exception parameter, which is always non-null nullness.on.outer=nullness annotations are not applicable to outer types diff --git a/checker/src/test/java/org/checkerframework/checker/test/junit/AnnotatedForNullnessTest.java b/checker/src/test/java/org/checkerframework/checker/test/junit/AnnotatedForNullnessTest.java index 84add0104f6..57513de6147 100644 --- a/checker/src/test/java/org/checkerframework/checker/test/junit/AnnotatedForNullnessTest.java +++ b/checker/src/test/java/org/checkerframework/checker/test/junit/AnnotatedForNullnessTest.java @@ -28,6 +28,9 @@ public AnnotatedForNullnessTest(List testFiles) { */ @Parameters public static String[] getTestDirs() { - return new String[] {"nulless-conservative-defaults/annotatedfornullness"}; + return new String[] { + "nulless-conservative-defaults/annotatedfornullness", + "nulless-conservative-defaults/packageannotatedfornullness" + }; } } diff --git a/checker/tests/i18n-formatter/Syntax.java b/checker/tests/i18n-formatter/Syntax.java index 3e851eab032..4861d2d8030 100644 --- a/checker/tests/i18n-formatter/Syntax.java +++ b/checker/tests/i18n-formatter/Syntax.java @@ -83,8 +83,11 @@ public static void invalidSubformatPattern() { MessageFormat.format("{0, number, #.#.#}", 1); // :: error: (i18nformat.string.invalid) MessageFormat.format("{0, date, y.m.d.x}", new Date()); - // :: error: (i18nformat.string.invalid) - MessageFormat.format("{0, choice, 0##zero}", 0); + + // TODO: This pattern is valid starting with JDK 23. Decide how to handle version-specific + // issues. + // TODO :: error: (i18nformat.string.invalid) + // MessageFormat.format("{0, choice, 0##zero}", 0); // good MessageFormat.format("{0, number, #.#}", 1); diff --git a/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/annotated/Test.java b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/annotated/Test.java new file mode 100644 index 00000000000..01c4054ae2e --- /dev/null +++ b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/annotated/Test.java @@ -0,0 +1,10 @@ +package packageannotatedfornullness.annotated; + +import org.checkerframework.checker.nullness.qual.Nullable; + +public class Test { + void foo(@Nullable Object o) { + // :: error: (dereference.of.nullable) + o.toString(); + } +} diff --git a/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/annotated/package-info.java b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/annotated/package-info.java new file mode 100644 index 00000000000..86a35f93276 --- /dev/null +++ b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/annotated/package-info.java @@ -0,0 +1,4 @@ +@AnnotatedFor("nullness") +package packageannotatedfornullness.annotated; + +import org.checkerframework.framework.qual.AnnotatedFor; diff --git a/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/notannotated/Test.java b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/notannotated/Test.java new file mode 100644 index 00000000000..7b949d49943 --- /dev/null +++ b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/notannotated/Test.java @@ -0,0 +1,10 @@ +package packageannotatedfornullness.notannotated; + +import org.checkerframework.checker.nullness.qual.Nullable; + +public class Test { + void foo(@Nullable Object o) { + // No error because this package is not annotated for nullness. + o.toString(); + } +} diff --git a/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/notannotated/package-info.java b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/notannotated/package-info.java new file mode 100644 index 00000000000..e77a859e6ad --- /dev/null +++ b/checker/tests/nulless-conservative-defaults/packageannotatedfornullness/notannotated/package-info.java @@ -0,0 +1 @@ +package packageannotatedfornullness.notannotated; diff --git a/checker/tests/nullness/NewNullable.java b/checker/tests/nullness/NewNullable.java index 860ed8ad8ad..861dd794758 100644 --- a/checker/tests/nullness/NewNullable.java +++ b/checker/tests/nullness/NewNullable.java @@ -3,10 +3,11 @@ public class NewNullable { Object o = new Object(); Object nn = new @NonNull Object(); - // :: warning: (new.class.type.invalid) + // :: error: (nullness.on.new.object) @Nullable Object lazy = new @MonotonicNonNull Object(); - // :: warning: (new.class.type.invalid) + // :: error: (nullness.on.new.object) + // :: error: (invalid.polymorphic.qualifier.use) @Nullable Object poly = new @PolyNull Object(); - // :: warning: (new.class.type.invalid) + // :: error: (nullness.on.new.object) @Nullable Object nbl = new @Nullable Object(); } diff --git a/checker/tests/nullness/NewObjectNonNull.java b/checker/tests/nullness/NewObjectNonNull.java index 5f865bf81e5..b58321dd5d2 100644 --- a/checker/tests/nullness/NewObjectNonNull.java +++ b/checker/tests/nullness/NewObjectNonNull.java @@ -7,7 +7,14 @@ class A { A() {} } + @DefaultQualifier(Nullable.class) + class B { + // No explicit constructor. + // B() {} + } + void m() { new A().toString(); + new B().toString(); } } diff --git a/checker/tests/nullness/NullableObject.java b/checker/tests/nullness/NullableObject.java new file mode 100644 index 00000000000..2567fd58aca --- /dev/null +++ b/checker/tests/nullness/NullableObject.java @@ -0,0 +1,13 @@ +import org.checkerframework.checker.nullness.qual.Nullable; + +public class NullableObject { + + void foo() { + // :: error: (nullness.on.new.object) + Object nbl = new @Nullable Object(); + } + + void bar() { + Object nn = new Object(); + } +} diff --git a/dataflow/build.gradle b/dataflow/build.gradle index ee89c0af6a1..3179ba9e2db 100644 --- a/dataflow/build.gradle +++ b/dataflow/build.gradle @@ -38,7 +38,7 @@ import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar */ def createDataflowShaded(shadedPkgName) { tasks.create(name: "dataflow${shadedPkgName}Jar", type: ShadowJar, dependsOn: compileJava, group: 'Build') { - description "Builds dataflow-${shadedPkgName}.jar." + description = "Builds dataflow-${shadedPkgName}.jar." includeEmptyDirs = false archiveBaseName.set("dataflow-${shadedPkgName}") // Without this line, the Maven artifact will have the classifier "all". @@ -68,13 +68,14 @@ createDataflowShaded('nullaway') createDataflowShaded('errorprone') task manual(group: 'Documentation') { - description 'Build the manual' + description = 'Build the manual' def injected = project.objects.newInstance(InjectedExecOps) doLast { injected.execOps.exec { - commandLine 'make', '-C', 'manual' + workingDir = file('manual') + commandLine 'make' } } } @@ -87,7 +88,7 @@ tasks.withType(Test) { } tasks.create(name: 'allDataflowTests', group: 'Verification') { - description 'Run all dataflow analysis tests' + description = 'Run all dataflow analysis tests' // 'allDataflowTests' is automatically populated by testDataflowAnalysis(). } @@ -107,7 +108,7 @@ tasks.create(name: 'allDataflowTests', group: 'Verification') { */ def testDataflowAnalysis(taskName, dirName, className, diff) { tasks.create(name: taskName, dependsOn: [assemble, compileTestJava], group: 'Verification') { - description "Run the ${dirName} dataflow framework test." + description = "Run the ${dirName} dataflow framework test." def injected = project.objects.newInstance(InjectedExecOps) @@ -123,7 +124,7 @@ def testDataflowAnalysis(taskName, dirName, className, diff) { delete("tests/${dirName}/Test.class") doLast { injected.execOps.javaexec { - workingDir = "tests/${dirName}" + workingDir = file("tests/${dirName}") if (!JavaVersion.current().java9Compatible) { jvmArgs += "-Xbootclasspath/p:${configurations.javacJar.asPath}".toString() } @@ -152,7 +153,7 @@ def testDataflowAnalysis(taskName, dirName, className, diff) { } if (diff) { injected.execOps.exec { - workingDir = "tests/${dirName}" + workingDir = file("tests/${dirName}") executable 'diff' args = [ '-u', diff --git a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/UnconditionalJump.java b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/UnconditionalJump.java index 0d92c27ac88..df1749339db 100644 --- a/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/UnconditionalJump.java +++ b/dataflow/src/main/java/org/checkerframework/dataflow/cfg/builder/UnconditionalJump.java @@ -52,7 +52,7 @@ public FlowRule getFlowRule() { * Produce a string representation. * * @return a string representation - * @see org.checkerframework.dataflow.cfg.builder.CFGBuilder.PhaseOneResult#nodeToString + * @see org.checkerframework.dataflow.cfg.builder.PhaseOneResult#nodeToString */ @Override public String toString() { diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 3beec91fd08..43c0d06238a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,4 +1,16 @@ -Version 3.42.0-eisop5 (November ??, 2024) +Version 3.42.0-eisop6 (January ??, 2025) +---------------------------------------- + +**User-visible changes:** + +**Implementation details:** + +**Closed issues:** + +eisop#1003, eisop#1033. + + +Version 3.42.0-eisop5 (December 20, 2024) ----------------------------------------- **User-visible changes:** @@ -6,8 +18,8 @@ Version 3.42.0-eisop5 (November ??, 2024) Removed support for the `-Anocheckjdk` option, which was deprecated in version 3.1.1. Use `-ApermitMissingJdk` instead. -The Nullness Checker now reports an error if an array creation is annotated with `@Nullable`, -as array creations are intrinsically non-null. +The Nullness Checker now reports an error if an array or object creation is annotated +with `@Nullable`, as array and object creations are intrinsically non-null. **Implementation details:** @@ -19,7 +31,8 @@ Make `SourceChecker#suppressWarningsString` protected to allow adaptation in sub **Closed issues:** -eisop#413, eisop#777, eisop#782, eisop#927, eisop#982. +eisop#413, eisop#782, eisop#815, eisop#860, eisop#873, eisop#875, eisop#927, eisop#982, +eisop#1012. Version 3.42.0-eisop4 (July 12, 2024) diff --git a/docs/checker-framework-webpage.html b/docs/checker-framework-webpage.html index 38570a095ed..21fb399cb47 100644 --- a/docs/checker-framework-webpage.html +++ b/docs/checker-framework-webpage.html @@ -30,8 +30,8 @@

The Checker Framework

Installation instructions and tutorial.
  • - Download: checker-framework-3.42.0-eisop4.zip - (12 Jul 2024); + Download: checker-framework-3.42.0-eisop5.zip + (20 Dec 2024); includes source, platform-independent binary, tests, and documentation.
    Then, see the installation @@ -93,7 +93,7 @@

    The Checker Framework

    the .class file. The tools support both Java 5 declaration annotations and Java 8 type annotations.
      -
    • annotation-tools-3.42.0-eisop4.zip (12 Jul 2024) +
    • annotation-tools-3.42.0-eisop5.zip (20 Dec 2024)
    • source code repository
    • @@ -229,7 +229,7 @@

      Mailing lists


      -Last updated: 12 Jul 2024 +Last updated: 20 Dec 2024

      diff --git a/docs/developer/release/README-release-process.html b/docs/developer/release/README-release-process.html index 03254a9c69a..3932425d042 100644 --- a/docs/developer/release/README-release-process.html +++ b/docs/developer/release/README-release-process.html @@ -299,10 +299,11 @@

      Gradle Groovy (build.gradle< maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } -ext.checkerFrameworkVersion = '3.28.1-SNAPSHOT' +ext.checkerFrameworkVersion = '3.42.0-eisop5-SNAPSHOT' dependencies { compileOnly "io.github.eisop:checker-qual:${checkerFrameworkVersion}" testCompileOnly "io.github.eisop:checker-qual:${checkerFrameworkVersion}" + checkerFramework "io.github.eisop:checker-qual:${checkerFrameworkVersion}" checkerFramework "io.github.eisop:checker:${checkerFrameworkVersion}" } configurations.all { @@ -315,10 +316,11 @@

      Gradle Kotlin (build.gradle. to use the snapshot version of the Checker Framework:
      -val checkerFrameworkVersion = "3.41.1-SNAPSHOT"
      +val checkerFrameworkVersion = "3.42.0-eisop5-SNAPSHOT"
       dependencies {
          compileOnly("io.github.eisop:checker-qual:${checkerFrameworkVersion}")
          testCompileOnly("io.github.eisop:checker-qual:${checkerFrameworkVersion}")
      +   checkerFramework("io.github.eisop:checker-qual:${checkerFrameworkVersion}")
          checkerFramework("io.github.eisop:checker:${checkerFrameworkVersion}")
       }
       configurations.all({
      diff --git a/docs/developer/release/release.xml b/docs/developer/release/release.xml
      index ea5346e8290..adff848badf 100644
      --- a/docs/developer/release/release.xml
      +++ b/docs/developer/release/release.xml
      @@ -135,6 +135,17 @@
                       start="${checkers.ver.0}" end="${checkers.ver.1}"
                       with="${release.ver}"/>
       
      +        
      +
      +        
      +        
      +
           
       
           
      diff --git a/docs/examples/BazelExample/MODULE.bazel b/docs/examples/BazelExample/MODULE.bazel
      index 756b5d0c13c..a2e9681f531 100644
      --- a/docs/examples/BazelExample/MODULE.bazel
      +++ b/docs/examples/BazelExample/MODULE.bazel
      @@ -1,9 +1,9 @@
      -bazel_dep(name = "rules_jvm_external", version = "6.2")
      +bazel_dep(name = "rules_jvm_external", version = "6.6")
       maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
       maven.install(
           artifacts = [
      -        "io.github.eisop:checker-qual:3.42.0-eisop4",
      -	"io.github.eisop:checker:3.42.0-eisop4",
      +        "io.github.eisop:checker-qual:3.42.0-eisop5",
      +        "io.github.eisop:checker:3.42.0-eisop5",
           ],
           lock_file = "//:maven_install.json",
       )
      diff --git a/docs/examples/BazelExample/MODULE.bazel.lock b/docs/examples/BazelExample/MODULE.bazel.lock
      index 9c07f9f613c..ecdae713d72 100644
      --- a/docs/examples/BazelExample/MODULE.bazel.lock
      +++ b/docs/examples/BazelExample/MODULE.bazel.lock
      @@ -1,323 +1,237 @@
       {
      -  "lockFileVersion": 11,
      +  "lockFileVersion": 16,
         "registryFileHashes": {
           "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497",
           "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2",
           "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589",
      -    "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/source.json": "7e3a9adf473e9af076ae485ed649d5641ad50ec5c11718103f34de03170d94ad",
      -    "https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef",
      -    "https://bcr.bazel.build/modules/apple_support/1.5.0/source.json": "eb98a7627c0bc486b57f598ad8da50f6625d974c8f723e9ea71bd39f709c9862",
      +    "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0",
      +    "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb",
      +    "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16",
      +    "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915",
      +    "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
      +    "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da",
      +    "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
           "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
      -    "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df",
      -    "https://bcr.bazel.build/modules/bazel_features/1.13.0/source.json": "b01f6aaaf93527ff4267421ef416debbd89b3166b70af5c89400c6a95a89c133",
      +    "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d",
      +    "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d",
      +    "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a",
      +    "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58",
      +    "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b",
      +    "https://bcr.bazel.build/modules/bazel_features/1.21.0/source.json": "3e8379efaaef53ce35b7b8ba419df829315a880cb0a030e5bb45c96d6d5ecb5f",
      +    "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
      +    "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
           "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
      +    "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e",
           "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
           "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
           "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
           "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d",
           "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
      +    "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
           "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
      +    "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d",
           "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b",
           "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/source.json": "f121b43eeefc7c29efbd51b83d08631e2347297c95aac9764a701f2a6a2bb953",
           "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
           "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
      +    "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
           "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
      -    "https://bcr.bazel.build/modules/googletest/1.11.0/source.json": "c73d9ef4268c91bd0c1cd88f1f9dfa08e814b1dbe89b5f594a9f08ba0244d206",
      +    "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
      +    "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/source.json": "41e9e129f80d8c8bf103a7acc337b76e54fad1214ac0a7084bf24f4cd924b8b4",
      +    "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
      +    "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
      +    "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d",
      +    "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
           "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
           "https://bcr.bazel.build/modules/platforms/0.0.10/source.json": "f22828ff4cf021a6b577f1bf6341cb9dcd7965092a439f64fc1bb3b7a5ae4bd5",
           "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
           "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37",
           "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615",
           "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814",
      -    "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc",
      +    "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d",
           "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
      -    "https://bcr.bazel.build/modules/protobuf/21.7/source.json": "bbe500720421e582ff2d18b0802464205138c06056f443184de39fbb8187b09b",
      +    "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c",
      +    "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d",
      +    "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df",
      +    "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e",
      +    "https://bcr.bazel.build/modules/protobuf/29.0/source.json": "b857f93c796750eef95f0d61ee378f3420d00ee1dd38627b27193aa482f4f981",
           "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
      -    "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
      +    "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
      +    "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/source.json": "be4789e951dd5301282729fe3d4938995dc4c1a81c2ff150afc9f1b0504c6022",
      +    "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206",
      +    "https://bcr.bazel.build/modules/re2/2023-09-01/source.json": "e044ce89c2883cd957a2969a43e79f7752f9656f6b20050b62f90ede21ec6eb4",
           "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
           "https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
           "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
      +    "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
      +    "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
      +    "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac",
      +    "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc",
      +    "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87",
      +    "https://bcr.bazel.build/modules/rules_cc/0.0.16/source.json": "227e83737046aa4f50015da48e98e0d8ab42fd0ec74d8d653b6cc9f9a357f200",
           "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
      +    "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f",
           "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
           "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
      -    "https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
      +    "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
      +    "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8",
      +    "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/source.json": "c8b1e2c717646f1702290959a3302a178fb639d987ab61d548105019f11e527e",
           "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
      +    "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86",
      +    "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39",
      +    "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6",
      +    "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31",
      +    "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a",
      +    "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6",
           "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab",
      -    "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934",
      +    "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2",
           "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
      -    "https://bcr.bazel.build/modules/rules_java/7.6.5/MODULE.bazel": "481164be5e02e4cab6e77a36927683263be56b7e36fef918b458d7a8a1ebadb1",
      -    "https://bcr.bazel.build/modules/rules_java/7.6.5/source.json": "a805b889531d1690e3c72a7a7e47a870d00323186a9904b36af83aa3d053ee8d",
      +    "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2",
      +    "https://bcr.bazel.build/modules/rules_java/8.6.1/source.json": "f18d9ad3c4c54945bf422ad584fa6c5ca5b3116ff55a5b1bc77e5c1210be5960",
           "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7",
      +    "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909",
           "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036",
      -    "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99",
      -    "https://bcr.bazel.build/modules/rules_jvm_external/6.2/source.json": "7f4c0095f17d1b65f943169e1d4f5f831a7133d205179e7b1b515ffcb39a5aa4",
      -    "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025",
      -    "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/source.json": "4ea6e867a7db5ef01187a07636070110db267f94ed038367bec7bbd3aea5e612",
      +    "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d",
      +    "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4",
      +    "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0",
      +    "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55",
      +    "https://bcr.bazel.build/modules/rules_jvm_external/6.6/source.json": "b1d7ffc3877e5a76e6e48e6bce459cbb1712c90eba14861b112bd299587a534d",
      +    "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59",
      +    "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3",
      +    "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/source.json": "2faa4794364282db7c06600b7e5e34867a564ae91bda7cae7c29c64e9466b7d5",
           "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0",
           "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d",
      -    "https://bcr.bazel.build/modules/rules_license/0.0.7/source.json": "355cc5737a0f294e560d52b1b7a6492d4fff2caf0bef1a315df5a298fca2d34a",
      +    "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c",
      +    "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb",
           "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc",
      -    "https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c",
      +    "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff",
      +    "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a",
           "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
           "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
      -    "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/source.json": "d57902c052424dfda0e71646cb12668d39c4620ee0544294d9d941e7d12bc3a9",
      +    "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73",
      +    "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2",
      +    "https://bcr.bazel.build/modules/rules_proto/7.0.2/source.json": "1e5e7260ae32ef4f2b52fd1d0de8d03b606a44c91b694d2f1afb1d3b28a48ce1",
           "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
      -    "https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
           "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300",
      -    "https://bcr.bazel.build/modules/rules_python/0.23.1/source.json": "a6d9965700e3bd75df4e19140c0e651851bb720d8b9eb280ecd1ee44b92d7646",
      +    "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382",
      +    "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed",
      +    "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58",
           "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c",
      +    "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7",
      +    "https://bcr.bazel.build/modules/rules_python/0.40.0/source.json": "939d4bd2e3110f27bfb360292986bb79fd8dcefb874358ccd6cdaa7bda029320",
      +    "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
      +    "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b",
      +    "https://bcr.bazel.build/modules/rules_shell/0.3.0/source.json": "c55ed591aa5009401ddf80ded9762ac32c358d2517ee7820be981e2de9756cf3",
           "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
           "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
      +    "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
           "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c",
      -    "https://bcr.bazel.build/modules/stardoc/0.7.0/source.json": "e3c524bf2ef20992539ce2bc4a2243f4853130209ee831689983e28d05769099",
      +    "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7",
      +    "https://bcr.bazel.build/modules/stardoc/0.7.1/source.json": "b6500ffcd7b48cd72c29bb67bcac781e12701cc0d6d55d266a652583cfcdab01",
           "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
      -    "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/source.json": "f1ef7d3f9e0e26d4b23d1c39b5f5de71f584dd7d1b4ef83d9bbba6ec7a6a6459",
           "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0",
      -    "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27",
           "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79",
      -    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d"
      +    "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d",
      +    "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198"
         },
         "selectedYankedVersions": {},
         "moduleExtensions": {
      -    "@@apple_support~//crosstool:setup.bzl%apple_cc_configure_extension": {
      -      "general": {
      -        "bzlTransitiveDigest": "PjIds3feoYE8SGbbIq2SFTZy3zmxeO2tQevJZNDo7iY=",
      -        "usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
      -        "recordedFileInputs": {},
      -        "recordedDirentsInputs": {},
      -        "envVariables": {},
      -        "generatedRepoSpecs": {
      -          "local_config_apple_cc": {
      -            "bzlFile": "@@apple_support~//crosstool:setup.bzl",
      -            "ruleClassName": "_apple_cc_autoconf",
      -            "attributes": {}
      -          },
      -          "local_config_apple_cc_toolchains": {
      -            "bzlFile": "@@apple_support~//crosstool:setup.bzl",
      -            "ruleClassName": "_apple_cc_autoconf_toolchains",
      -            "attributes": {}
      -          }
      -        },
      -        "recordedRepoMappingEntries": [
      -          [
      -            "apple_support~",
      -            "bazel_tools",
      -            "bazel_tools"
      -          ]
      -        ]
      -      }
      -    },
           "@@platforms//host:extension.bzl%host_platform": {
             "general": {
               "bzlTransitiveDigest": "xelQcPZH8+tmuOHVjL9vDxMnnQNMlwj0SlvgoqBkm4U=",
      -        "usagesDigest": "V1R2Y2oMxKNfx2WCWpSCaUV1WefW1o8HZGm3v1vHgY4=",
      +        "usagesDigest": "SeQiIN/f8/Qt9vYQk7qcXp4I4wJeEC0RnQDiaaJ4tb8=",
               "recordedFileInputs": {},
               "recordedDirentsInputs": {},
               "envVariables": {},
               "generatedRepoSpecs": {
                 "host_platform": {
      -            "bzlFile": "@@platforms//host:extension.bzl",
      -            "ruleClassName": "host_platform_repo",
      +            "repoRuleId": "@@platforms//host:extension.bzl%host_platform_repo",
                   "attributes": {}
                 }
               },
               "recordedRepoMappingEntries": []
             }
           },
      -    "@@rules_kotlin~//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
      +    "@@rules_java+//java:rules_java_deps.bzl%compatibility_proxy": {
             "general": {
      -        "bzlTransitiveDigest": "kZ+9OOxWkWt07Jni1BKXITpFDZRZoYjB0LCALFyjGkc=",
      -        "usagesDigest": "K+i+NLBtqsvNSdO+8wYj1BOGr0DAXxBxW8myZpWViyc=",
      +        "bzlTransitiveDigest": "84xJEZ1jnXXwo8BXMprvBm++rRt4jsTu9liBxz0ivps=",
      +        "usagesDigest": "jTQDdLDxsS43zuRmg1faAjIEPWdLAbDAowI1pInQSoo=",
               "recordedFileInputs": {},
               "recordedDirentsInputs": {},
               "envVariables": {},
               "generatedRepoSpecs": {
      -          "rules_android": {
      -            "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
      -            "ruleClassName": "http_archive",
      -            "attributes": {
      -              "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
      -              "strip_prefix": "rules_android-0.1.1",
      -              "urls": [
      -                "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
      -              ]
      -            }
      -          },
      -          "com_github_pinterest_ktlint": {
      -            "bzlFile": "@@bazel_tools//tools/build_defs/repo:http.bzl",
      -            "ruleClassName": "http_file",
      -            "attributes": {
      -              "sha256": "2b3f6f674a944d25bb8d283c3539947bbe86074793012909a55de4b771f74bcc",
      -              "urls": [
      -                "https://github.com/pinterest/ktlint/releases/download/0.49.1/ktlint"
      -              ],
      -              "executable": true
      -            }
      -          },
      -          "com_github_jetbrains_kotlin": {
      -            "bzlFile": "@@rules_kotlin~//src/main/starlark/core/repositories:compiler.bzl",
      -            "ruleClassName": "kotlin_compiler_repository",
      -            "attributes": {
      -              "urls": [
      -                "https://github.com/JetBrains/kotlin/releases/download/v1.9.22/kotlin-compiler-1.9.22.zip"
      -              ],
      -              "sha256": "88b39213506532c816ff56348c07bbeefe0c8d18943bffbad11063cf97cac3e6",
      -              "compiler_version": "1.9.22"
      -            }
      -          },
      -          "com_github_google_ksp": {
      -            "bzlFile": "@@rules_kotlin~//src/main/starlark/core/repositories:ksp.bzl",
      -            "ruleClassName": "ksp_compiler_plugin_repository",
      -            "attributes": {
      -              "urls": [
      -                "https://github.com/google/ksp/releases/download/1.9.22-1.0.17/artifacts.zip"
      -              ],
      -              "sha256": "b39b373e09e5edefe700fef628572f71be7d49e6396dec0ea52eb10c16ead39e",
      -              "strip_version": "1.9.22-1.0.17"
      -            }
      +          "compatibility_proxy": {
      +            "repoRuleId": "@@rules_java+//java:rules_java_deps.bzl%_compatibility_proxy_repo_rule",
      +            "attributes": {}
                 }
               },
               "recordedRepoMappingEntries": [
                 [
      -            "rules_kotlin~",
      +            "rules_java+",
                   "bazel_tools",
                   "bazel_tools"
                 ]
               ]
             }
           },
      -    "@@rules_python~//python/extensions:python.bzl%python": {
      +    "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": {
             "general": {
      -        "bzlTransitiveDigest": "XaaZIw4dO4l6naftU5IBdrfCE1mOmelaT/Sq9uyBnhs=",
      -        "usagesDigest": "9rlrm2M/kJEEPWIo3UEIjkAFxHjzsbMIAFR9yrYnKsQ=",
      +        "bzlTransitiveDigest": "sFhcgPbDQehmbD1EOXzX4H1q/CD5df8zwG4kp4jbvr8=",
      +        "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=",
               "recordedFileInputs": {},
               "recordedDirentsInputs": {},
               "envVariables": {},
               "generatedRepoSpecs": {
      -          "python_aliases": {
      -            "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl",
      -            "ruleClassName": "multi_toolchain_aliases",
      +          "com_github_jetbrains_kotlin_git": {
      +            "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository",
                   "attributes": {
      -              "python_versions": {
      -                "3.11": "python_3_11"
      -              }
      -            }
      -          },
      -          "python_3_11": {
      -            "bzlFile": "@@rules_python~//python/private:toolchains_repo.bzl",
      -            "ruleClassName": "toolchain_aliases",
      -            "attributes": {
      -              "python_version": "3.11.1",
      -              "user_repository_name": "python_3_11"
      -            }
      -          },
      -          "python_3_11_aarch64-unknown-linux-gnu": {
      -            "bzlFile": "@@rules_python~//python:repositories.bzl",
      -            "ruleClassName": "python_repository",
      -            "attributes": {
      -              "sha256": "debf15783bdcb5530504f533d33fda75a7b905cec5361ae8f33da5ba6599f8b4",
      -              "patches": [],
      -              "platform": "aarch64-unknown-linux-gnu",
      -              "python_version": "3.11.1",
      -              "release_filename": "20230116/cpython-3.11.1+20230116-aarch64-unknown-linux-gnu-install_only.tar.gz",
                     "urls": [
      -                "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-aarch64-unknown-linux-gnu-install_only.tar.gz"
      +                "https://github.com/JetBrains/kotlin/releases/download/v1.9.23/kotlin-compiler-1.9.23.zip"
                     ],
      -              "distutils_content": "",
      -              "strip_prefix": "python",
      -              "ignore_root_user_error": false
      +              "sha256": "93137d3aab9afa9b27cb06a824c2324195c6b6f6179d8a8653f440f5bd58be88"
                   }
                 },
      -          "python_3_11_aarch64-apple-darwin": {
      -            "bzlFile": "@@rules_python~//python:repositories.bzl",
      -            "ruleClassName": "python_repository",
      +          "com_github_jetbrains_kotlin": {
      +            "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_capabilities_repository",
                   "attributes": {
      -              "sha256": "4918cdf1cab742a90f85318f88b8122aeaa2d04705803c7b6e78e81a3dd40f80",
      -              "patches": [],
      -              "platform": "aarch64-apple-darwin",
      -              "python_version": "3.11.1",
      -              "release_filename": "20230116/cpython-3.11.1+20230116-aarch64-apple-darwin-install_only.tar.gz",
      -              "urls": [
      -                "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-aarch64-apple-darwin-install_only.tar.gz"
      -              ],
      -              "distutils_content": "",
      -              "strip_prefix": "python",
      -              "ignore_root_user_error": false
      +              "git_repository_name": "com_github_jetbrains_kotlin_git",
      +              "compiler_version": "1.9.23"
                   }
                 },
      -          "python_3_11_x86_64-apple-darwin": {
      -            "bzlFile": "@@rules_python~//python:repositories.bzl",
      -            "ruleClassName": "python_repository",
      +          "com_github_google_ksp": {
      +            "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:ksp.bzl%ksp_compiler_plugin_repository",
                   "attributes": {
      -              "sha256": "20a4203d069dc9b710f70b09e7da2ce6f473d6b1110f9535fb6f4c469ed54733",
      -              "patches": [],
      -              "platform": "x86_64-apple-darwin",
      -              "python_version": "3.11.1",
      -              "release_filename": "20230116/cpython-3.11.1+20230116-x86_64-apple-darwin-install_only.tar.gz",
                     "urls": [
      -                "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-x86_64-apple-darwin-install_only.tar.gz"
      +                "https://github.com/google/ksp/releases/download/1.9.23-1.0.20/artifacts.zip"
                     ],
      -              "distutils_content": "",
      -              "strip_prefix": "python",
      -              "ignore_root_user_error": false
      -            }
      -          },
      -          "pythons_hub": {
      -            "bzlFile": "@@rules_python~//python/extensions/private:pythons_hub.bzl",
      -            "ruleClassName": "hub_repo",
      -            "attributes": {
      -              "toolchain_prefixes": [
      -                "_0000_python_3_11_"
      -              ],
      -              "toolchain_python_versions": [
      -                "3.11"
      -              ],
      -              "toolchain_set_python_version_constraints": [
      -                "False"
      -              ],
      -              "toolchain_user_repository_names": [
      -                "python_3_11"
      -              ]
      +              "sha256": "ee0618755913ef7fd6511288a232e8fad24838b9af6ea73972a76e81053c8c2d",
      +              "strip_version": "1.9.23-1.0.20"
                   }
                 },
      -          "python_3_11_x86_64-pc-windows-msvc": {
      -            "bzlFile": "@@rules_python~//python:repositories.bzl",
      -            "ruleClassName": "python_repository",
      +          "com_github_pinterest_ktlint": {
      +            "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
                   "attributes": {
      -              "sha256": "edc08979cb0666a597466176511529c049a6f0bba8adf70df441708f766de5bf",
      -              "patches": [],
      -              "platform": "x86_64-pc-windows-msvc",
      -              "python_version": "3.11.1",
      -              "release_filename": "20230116/cpython-3.11.1+20230116-x86_64-pc-windows-msvc-shared-install_only.tar.gz",
      +              "sha256": "01b2e0ef893383a50dbeb13970fe7fa3be36ca3e83259e01649945b09d736985",
                     "urls": [
      -                "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-x86_64-pc-windows-msvc-shared-install_only.tar.gz"
      +                "https://github.com/pinterest/ktlint/releases/download/1.3.0/ktlint"
                     ],
      -              "distutils_content": "",
      -              "strip_prefix": "python",
      -              "ignore_root_user_error": false
      +              "executable": true
                   }
                 },
      -          "python_3_11_x86_64-unknown-linux-gnu": {
      -            "bzlFile": "@@rules_python~//python:repositories.bzl",
      -            "ruleClassName": "python_repository",
      +          "rules_android": {
      +            "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
                   "attributes": {
      -              "sha256": "02a551fefab3750effd0e156c25446547c238688a32fabde2995c941c03a6423",
      -              "patches": [],
      -              "platform": "x86_64-unknown-linux-gnu",
      -              "python_version": "3.11.1",
      -              "release_filename": "20230116/cpython-3.11.1+20230116-x86_64-unknown-linux-gnu-install_only.tar.gz",
      +              "sha256": "cd06d15dd8bb59926e4d65f9003bfc20f9da4b2519985c27e190cddc8b7a7806",
      +              "strip_prefix": "rules_android-0.1.1",
                     "urls": [
      -                "https://github.com/indygreg/python-build-standalone/releases/download/20230116/cpython-3.11.1+20230116-x86_64-unknown-linux-gnu-install_only.tar.gz"
      -              ],
      -              "distutils_content": "",
      -              "strip_prefix": "python",
      -              "ignore_root_user_error": false
      +                "https://github.com/bazelbuild/rules_android/archive/v0.1.1.zip"
      +              ]
                   }
                 }
               },
               "recordedRepoMappingEntries": [
                 [
      -            "rules_python~",
      +            "rules_kotlin+",
                   "bazel_tools",
                   "bazel_tools"
                 ]
      diff --git a/docs/examples/BazelExample/Makefile b/docs/examples/BazelExample/Makefile
      index ede061d1c46..d34eeb6a5f2 100644
      --- a/docs/examples/BazelExample/Makefile
      +++ b/docs/examples/BazelExample/Makefile
      @@ -1,8 +1,15 @@
      +JAVA_VER := $(shell java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s///' | cut -d'.' -f1 | sed 's/-ea//')
      +
       .PHONY: all clean
       
      +ifeq ($(shell test $(JAVA_VER) -gt 21; echo $$?),0)
      +all:
      +	@echo "Skipping test because I don't know how to configure bazel to work on a JDK > 21..."
      +else
       all:
       	bazelisk run example > Out.txt 2>&1 || true
       	grep -qF "BazelExample.java:25: error: [assignment.type.incompatible] incompatible types in assignment." Out.txt || (echo "FAILURE.  Here is file Out.txt:" && cat Out.txt && echo "End of file Out.txt." && false)
      +endif
       
       clean:
       	-bazelisk clean
      diff --git a/docs/examples/BazelExample/maven_install.json b/docs/examples/BazelExample/maven_install.json
      index f951f679277..5cb5c49a762 100644
      --- a/docs/examples/BazelExample/maven_install.json
      +++ b/docs/examples/BazelExample/maven_install.json
      @@ -1,16 +1,70 @@
       {
         "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL",
      -  "__INPUT_ARTIFACTS_HASH": 350659846,
      -  "__RESOLVED_ARTIFACTS_HASH": 239981637,
      +  "__INPUT_ARTIFACTS_HASH": 1086149529,
      +  "__RESOLVED_ARTIFACTS_HASH": -245382296,
         "conflict_resolution": {
      -    "com.google.errorprone:error_prone_annotations:2.3.2": "com.google.errorprone:error_prone_annotations:2.11.0"
      +    "com.google.errorprone:error_prone_annotations:2.5.1": "com.google.errorprone:error_prone_annotations:2.18.0"
         },
         "artifacts": {
      +    "biz.aQute.bnd:biz.aQute.bnd.util": {
      +      "shasums": {
      +        "jar": "65b5bd4a0fab16812f1800c98ff74a038f37a38bfe899af382efed4efdc1e3e1"
      +      },
      +      "version": "6.4.0"
      +    },
      +    "biz.aQute.bnd:biz.aQute.bndlib": {
      +      "shasums": {
      +        "jar": "357145074872f9dbf67e629fcd237e6152707e575d735df4535282f9f588d2d8"
      +      },
      +      "version": "6.4.0"
      +    },
           "com.google.auto.value:auto-value-annotations": {
             "shasums": {
      -        "jar": "fedd59b0b4986c342f6ab2d182f2a4ee9fceb2c7e2d5bdc4dc764c92394a23d3"
      +        "jar": "37ec09b47d7ed35a99d13927db5c86fc9071f620f943ead5d757144698310852"
      +      },
      +      "version": "1.8.1"
      +    },
      +    "com.google.caliper:caliper": {
      +      "shasums": {
      +        "jar": "d54e1bfdbe9359a79e175c217b8d472555cf20da9c5c0a18bdb1ea7db979ed8e"
      +      },
      +      "version": "1.0-beta-3"
      +    },
      +    "com.google.caliper:caliper-api": {
      +      "shasums": {
      +        "jar": "374f0c6c0c1f8784cb69d885e1dcbb7498c34ca20369e0597264568530642928"
      +      },
      +      "version": "1.0-beta-3"
      +    },
      +    "com.google.caliper:caliper-core": {
      +      "shasums": {
      +        "jar": "514deac8f8b09dd4262733e0a4406a333208c899dc7ea726b03600b9bb94f192"
      +      },
      +      "version": "1.0-beta-3"
      +    },
      +    "com.google.caliper:caliper-runner": {
      +      "shasums": {
      +        "jar": "3ab58890aa01343361adedf859500d280f67813df0cedfcd165b169533b9b1fa"
      +      },
      +      "version": "1.0-beta-3"
      +    },
      +    "com.google.caliper:caliper-util": {
      +      "shasums": {
      +        "jar": "6e9af500c7020450dfdb5003d09501d512d395f431c54c7ee8f79e712463fe66"
      +      },
      +      "version": "1.0-beta-3"
      +    },
      +    "com.google.caliper:caliper-worker": {
      +      "shasums": {
      +        "jar": "315d8e51df1f60551645a0e3bf2c504d2c79762f688e6f728eb9d1d9cd9a491b"
             },
      -      "version": "1.7.4"
      +      "version": "1.0-beta-3"
      +    },
      +    "com.google.caliper:caliper-worker-jvm": {
      +      "shasums": {
      +        "jar": "e14e1ecfdf939c82abdb902105be41ff3f83c18cb968116232015f2662d065a4"
      +      },
      +      "version": "1.0-beta-3"
           },
           "com.google.code.findbugs:jsr305": {
             "shasums": {
      @@ -24,11 +78,29 @@
             },
             "version": "2.8.9"
           },
      +    "com.google.code.java-allocation-instrumenter:java-allocation-instrumenter": {
      +      "shasums": {
      +        "jar": "1ef5535a8bd41cf3072469f381b9ee6ab28275311a7499f53d6e52adf976fef0"
      +      },
      +      "version": "3.3.0"
      +    },
      +    "com.google.dagger:dagger": {
      +      "shasums": {
      +        "jar": "329d4340f24c4f5717af016c097e90668bfea2a5376e6aa9964b01cef3fd241a"
      +      },
      +      "version": "2.22.1"
      +    },
      +    "com.google.dagger:dagger-producers": {
      +      "shasums": {
      +        "jar": "f834a0082014213a68ff06a0f048d750178d02196c58b0b15beb367d32b97e35"
      +      },
      +      "version": "2.22.1"
      +    },
           "com.google.errorprone:error_prone_annotations": {
             "shasums": {
      -        "jar": "721cb91842b46fa056847d104d5225c8b8e1e8b62263b993051e1e5a0137b7ec"
      +        "jar": "9e6814cb71816988a4fd1b07a993a8f21bb7058d522c162b1de849e19bea54ae"
             },
      -      "version": "2.11.0"
      +      "version": "2.18.0"
           },
           "com.google.guava:failureaccess": {
             "shasums": {
      @@ -38,15 +110,15 @@
           },
           "com.google.guava:guava": {
             "shasums": {
      -        "jar": "a42edc9cab792e39fe39bb94f3fca655ed157ff87a8af78e1d6ba5b07c4a00ab"
      +        "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5"
             },
      -      "version": "31.1-jre"
      +      "version": "32.0.1-jre"
           },
           "com.google.guava:guava-testlib": {
             "shasums": {
      -        "jar": "aadc71b10d5c3ac474dd16be84cfb18d257e584d1e0a59f8cab64ef4376226ce"
      +        "jar": "c97511849a5e085280f106df2b059566febd280b118d33d6a9e068d238100b63"
             },
      -      "version": "31.1-jre"
      +      "version": "32.0.1-jre"
           },
           "com.google.guava:listenablefuture": {
             "shasums": {
      @@ -56,9 +128,9 @@
           },
           "com.google.j2objc:j2objc-annotations": {
             "shasums": {
      -        "jar": "21af30c92267bd6122c0e0b4d20cccb6641a37eaf956c6540ec471d584e64a7b"
      +        "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed"
             },
      -      "version": "1.3"
      +      "version": "2.8"
           },
           "com.google.truth:truth": {
             "shasums": {
      @@ -66,23 +138,77 @@
             },
             "version": "1.1.2"
           },
      +    "com.squareup.okhttp:okhttp": {
      +      "shasums": {
      +        "jar": "88ac9fd1bb51f82bcc664cc1eb9c225c90dc4389d660231b4cc737bebfe7d0aa"
      +      },
      +      "version": "2.7.5"
      +    },
      +    "com.squareup.okio:okio": {
      +      "shasums": {
      +        "jar": "114bdc1f47338a68bcbc95abf2f5cdc72beeec91812f2fcd7b521c1937876266"
      +      },
      +      "version": "1.6.0"
      +    },
      +    "com.sun.jersey:jersey-client": {
      +      "shasums": {
      +        "jar": "639c825c5db580f8115bf49ffc893093526d2ed1079fbc929b6a5fbd0b2eda40"
      +      },
      +      "version": "1.19.4"
      +    },
      +    "com.sun.jersey:jersey-core": {
      +      "shasums": {
      +        "jar": "64b03198e0264849d0fc341857ebcc9c882b1909a2dc35a0972fe7d901b826e5"
      +      },
      +      "version": "1.19.4"
      +    },
      +    "info.picocli:picocli": {
      +      "shasums": {
      +        "jar": "b0a5159e926de8084ff066025142270443533656bc599b8bb31d14d11fd138a4"
      +      },
      +      "version": "4.6.3"
      +    },
           "io.github.eisop:checker": {
             "shasums": {
      -        "jar": "146a54d39c81f6761bbd85b576c9fc16b556722580deb3793e0863bc1ca7b5f4"
      +        "jar": "4e3fd613e0166c78b6a66cde3482f31a5ca162e113d55ddf5e4663f1b1c01e5e"
             },
      -      "version": "3.42.0-eisop4"
      +      "version": "3.42.0-eisop5"
           },
           "io.github.eisop:checker-qual": {
             "shasums": {
      -        "jar": "0ff8e075aff823f765193f9e80112d6d7cd880f09e110194ffd6d9dd4231bcd6"
      +        "jar": "b79933a044d2e8b45e66257ce0a51bdd23411bcb6a1aaf0c5eff816ee3f45858"
             },
      -      "version": "3.42.0-eisop4"
      +      "version": "3.42.0-eisop5"
           },
           "io.github.eisop:checker-util": {
             "shasums": {
      -        "jar": "820e527ce66a001f58abdb8e192302ccb23c5884718be1d60721917dc0871147"
      +        "jar": "cd1f54ae982ebdbaa815d0c5d54ad29a26fbcc8806d39ac336cb3e6b19be0677"
      +      },
      +      "version": "3.42.0-eisop5"
      +    },
      +    "javax.annotation:javax.annotation-api": {
      +      "shasums": {
      +        "jar": "e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b"
      +      },
      +      "version": "1.3.2"
      +    },
      +    "javax.inject:javax.inject": {
      +      "shasums": {
      +        "jar": "91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff"
             },
      -      "version": "3.42.0-eisop4"
      +      "version": "1"
      +    },
      +    "javax.ws.rs:jsr311-api": {
      +      "shasums": {
      +        "jar": "ab1534b73b5fa055808e6598a5e73b599ccda28c3159c3c0908977809422ee4a"
      +      },
      +      "version": "1.1.1"
      +    },
      +    "joda-time:joda-time": {
      +      "shasums": {
      +        "jar": "dd8e7c92185a678d1b7b933f31209b6203c8ffa91e9880475a1be0346b9617e3"
      +      },
      +      "version": "2.10.10"
           },
           "junit:junit": {
             "shasums": {
      @@ -102,11 +228,17 @@
             },
             "version": "1.12.7"
           },
      +    "org.checkerframework:checker-compat-qual": {
      +      "shasums": {
      +        "jar": "d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d"
      +      },
      +      "version": "2.5.3"
      +    },
           "org.checkerframework:checker-qual": {
             "shasums": {
      -        "jar": "ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb"
      +        "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1"
             },
      -      "version": "3.12.0"
      +      "version": "3.33.0"
           },
           "org.hamcrest:hamcrest-core": {
             "shasums": {
      @@ -126,14 +258,183 @@
             },
             "version": "3.2"
           },
      +    "org.osgi:org.osgi.dto": {
      +      "shasums": {
      +        "jar": "cb75f3c7e48e5a31a31df22e26873346f5bf659e2dcab2369e031e4850d2ff43"
      +      },
      +      "version": "1.0.0"
      +    },
      +    "org.osgi:org.osgi.framework": {
      +      "shasums": {
      +        "jar": "ec194b7871af27681716ff05259319a5c3c9b9727e8000e9e832499b93484b4e"
      +      },
      +      "version": "1.8.0"
      +    },
      +    "org.osgi:org.osgi.resource": {
      +      "shasums": {
      +        "jar": "81fc50f1f1d38a4af28e131907d4afe213249aab05060484edca0e60c4af9b4a"
      +      },
      +      "version": "1.0.0"
      +    },
      +    "org.osgi:org.osgi.service.log": {
      +      "shasums": {
      +        "jar": "ff6710c4856d32684cf3ebdc45248f41036ff734f2b03bbc08c4609a61fecfa0"
      +      },
      +      "version": "1.3.0"
      +    },
      +    "org.osgi:org.osgi.service.repository": {
      +      "shasums": {
      +        "jar": "c5553e95b459529192433486d4c4cc22ff45a2eae4968484f9f717319264a532"
      +      },
      +      "version": "1.1.0"
      +    },
      +    "org.osgi:org.osgi.util.function": {
      +      "shasums": {
      +        "jar": "208819c7c71690c15a6bb8b187474e7f9d0147946b680182a62b9f222ae014ec"
      +      },
      +      "version": "1.2.0"
      +    },
      +    "org.osgi:org.osgi.util.promise": {
      +      "shasums": {
      +        "jar": "fef86e64f584d012a16a0306160764f6179663b90988a226c4641b920f3a4b36"
      +      },
      +      "version": "1.2.0"
      +    },
      +    "org.osgi:org.osgi.util.tracker": {
      +      "shasums": {
      +        "jar": "7d78c2cc9bcb6421c24f17aa097866ce8d9115c219a4f8d6cc753bc4dfb97efa"
      +      },
      +      "version": "1.5.4"
      +    },
      +    "org.osgi:osgi.annotation": {
      +      "shasums": {
      +        "jar": "a0e8a4c362bd3600812f37b0ea45fba966c7bc049d01fed56a09ecc74082759e"
      +      },
      +      "version": "8.0.1"
      +    },
           "org.ow2.asm:asm": {
             "shasums": {
               "jar": "0df97574914aee92fd349d0cb4e00f3345d45b2c239e0bb50f0a90ead47888e0"
             },
             "version": "9.0"
      +    },
      +    "org.ow2.asm:asm-analysis": {
      +      "shasums": {
      +        "jar": "be922aae60ff1ff1768e8e6544a38a7f92bd0a6d6b0b9791f94955d1bd453de2"
      +      },
      +      "version": "7.2"
      +    },
      +    "org.ow2.asm:asm-commons": {
      +      "shasums": {
      +        "jar": "0e86b8b179c5fb223d1a880a0ff4960b6978223984b94e62e71135f2d8ea3558"
      +      },
      +      "version": "7.2"
      +    },
      +    "org.ow2.asm:asm-tree": {
      +      "shasums": {
      +        "jar": "c063f5a67fa03cdc9bd79fd1c2ea6816cc4a19473ecdfbd9e9153b408c6f2656"
      +      },
      +      "version": "7.2"
      +    },
      +    "org.ow2.asm:asm-util": {
      +      "shasums": {
      +        "jar": "6e24913b021ffacfe8e7e053d6e0ccc731941148cfa078d4f1ed3d96904530f8"
      +      },
      +      "version": "7.2"
      +    },
      +    "org.slf4j:slf4j-api": {
      +      "shasums": {
      +        "jar": "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79"
      +      },
      +      "version": "1.7.25"
           }
         },
         "dependencies": {
      +    "biz.aQute.bnd:biz.aQute.bndlib": [
      +      "biz.aQute.bnd:biz.aQute.bnd.util",
      +      "org.osgi:org.osgi.dto",
      +      "org.osgi:org.osgi.framework",
      +      "org.osgi:org.osgi.resource",
      +      "org.osgi:org.osgi.service.log",
      +      "org.osgi:org.osgi.service.repository",
      +      "org.osgi:org.osgi.util.function",
      +      "org.osgi:org.osgi.util.promise",
      +      "org.osgi:org.osgi.util.tracker",
      +      "org.slf4j:slf4j-api"
      +    ],
      +    "com.google.caliper:caliper": [
      +      "com.google.caliper:caliper-core",
      +      "com.google.caliper:caliper-runner",
      +      "com.google.caliper:caliper-worker-jvm",
      +      "com.google.code.java-allocation-instrumenter:java-allocation-instrumenter",
      +      "com.google.dagger:dagger",
      +      "com.google.guava:guava",
      +      "com.sun.jersey:jersey-client"
      +    ],
      +    "com.google.caliper:caliper-api": [
      +      "com.google.guava:guava",
      +      "joda-time:joda-time"
      +    ],
      +    "com.google.caliper:caliper-core": [
      +      "com.google.auto.value:auto-value-annotations",
      +      "com.google.caliper:caliper-api",
      +      "com.google.caliper:caliper-util",
      +      "com.google.dagger:dagger",
      +      "com.google.guava:guava",
      +      "com.squareup.okhttp:okhttp",
      +      "joda-time:joda-time"
      +    ],
      +    "com.google.caliper:caliper-runner": [
      +      "com.google.caliper:caliper-api",
      +      "com.google.caliper:caliper-core",
      +      "com.google.caliper:caliper-util",
      +      "com.google.dagger:dagger",
      +      "com.google.dagger:dagger-producers",
      +      "com.google.guava:guava",
      +      "com.squareup.okhttp:okhttp",
      +      "joda-time:joda-time"
      +    ],
      +    "com.google.caliper:caliper-util": [
      +      "com.google.code.gson:gson",
      +      "com.google.dagger:dagger",
      +      "com.google.guava:guava",
      +      "joda-time:joda-time"
      +    ],
      +    "com.google.caliper:caliper-worker": [
      +      "com.google.caliper:caliper-api",
      +      "com.google.caliper:caliper-core",
      +      "com.google.caliper:caliper-util",
      +      "com.google.dagger:dagger",
      +      "com.google.guava:guava",
      +      "com.squareup.okhttp:okhttp",
      +      "joda-time:joda-time"
      +    ],
      +    "com.google.caliper:caliper-worker-jvm": [
      +      "com.google.caliper:caliper-core",
      +      "com.google.caliper:caliper-worker",
      +      "com.google.code.java-allocation-instrumenter:java-allocation-instrumenter",
      +      "com.google.dagger:dagger",
      +      "com.google.guava:guava",
      +      "com.sun.jersey:jersey-client"
      +    ],
      +    "com.google.code.java-allocation-instrumenter:java-allocation-instrumenter": [
      +      "com.google.guava:guava",
      +      "javax.annotation:javax.annotation-api",
      +      "org.ow2.asm:asm",
      +      "org.ow2.asm:asm-analysis",
      +      "org.ow2.asm:asm-commons",
      +      "org.ow2.asm:asm-tree",
      +      "org.ow2.asm:asm-util"
      +    ],
      +    "com.google.dagger:dagger": [
      +      "javax.inject:javax.inject"
      +    ],
      +    "com.google.dagger:dagger-producers": [
      +      "com.google.dagger:dagger",
      +      "com.google.guava:guava",
      +      "javax.inject:javax.inject",
      +      "org.checkerframework:checker-compat-qual"
      +    ],
           "com.google.guava:guava": [
             "com.google.code.findbugs:jsr305",
             "com.google.errorprone:error_prone_annotations",
      @@ -158,6 +459,15 @@
             "org.checkerframework:checker-qual",
             "org.ow2.asm:asm"
           ],
      +    "com.squareup.okhttp:okhttp": [
      +      "com.squareup.okio:okio"
      +    ],
      +    "com.sun.jersey:jersey-client": [
      +      "com.sun.jersey:jersey-core"
      +    ],
      +    "com.sun.jersey:jersey-core": [
      +      "javax.ws.rs:jsr311-api"
      +    ],
           "io.github.eisop:checker": [
             "io.github.eisop:checker-qual",
             "io.github.eisop:checker-util"
      @@ -172,13 +482,237 @@
             "net.bytebuddy:byte-buddy",
             "net.bytebuddy:byte-buddy-agent",
             "org.objenesis:objenesis"
      +    ],
      +    "org.osgi:org.osgi.util.function": [
      +      "org.osgi:osgi.annotation"
      +    ],
      +    "org.osgi:org.osgi.util.promise": [
      +      "org.osgi:org.osgi.util.function",
      +      "org.osgi:osgi.annotation"
      +    ],
      +    "org.osgi:org.osgi.util.tracker": [
      +      "org.osgi:osgi.annotation"
      +    ],
      +    "org.ow2.asm:asm-analysis": [
      +      "org.ow2.asm:asm-tree"
      +    ],
      +    "org.ow2.asm:asm-commons": [
      +      "org.ow2.asm:asm",
      +      "org.ow2.asm:asm-analysis",
      +      "org.ow2.asm:asm-tree"
      +    ],
      +    "org.ow2.asm:asm-tree": [
      +      "org.ow2.asm:asm"
      +    ],
      +    "org.ow2.asm:asm-util": [
      +      "org.ow2.asm:asm",
      +      "org.ow2.asm:asm-analysis",
      +      "org.ow2.asm:asm-tree"
           ]
         },
         "packages": {
      +    "biz.aQute.bnd:biz.aQute.bnd.util": [
      +      "aQute.bnd.classfile",
      +      "aQute.bnd.classfile.builder",
      +      "aQute.bnd.classfile.preview",
      +      "aQute.bnd.exceptions",
      +      "aQute.bnd.memoize",
      +      "aQute.bnd.result",
      +      "aQute.bnd.signatures",
      +      "aQute.bnd.stream",
      +      "aQute.bnd.unmodifiable",
      +      "aQute.lib.io",
      +      "aQute.lib.stringrover",
      +      "aQute.libg.glob"
      +    ],
      +    "biz.aQute.bnd:biz.aQute.bndlib": [
      +      "aQute.bnd.annotation",
      +      "aQute.bnd.annotation.baseline",
      +      "aQute.bnd.annotation.component",
      +      "aQute.bnd.annotation.headers",
      +      "aQute.bnd.annotation.jpms",
      +      "aQute.bnd.annotation.licenses",
      +      "aQute.bnd.annotation.metatype",
      +      "aQute.bnd.annotation.plugin",
      +      "aQute.bnd.annotation.service",
      +      "aQute.bnd.annotation.spi",
      +      "aQute.bnd.annotation.xml",
      +      "aQute.bnd.apiguardian.api",
      +      "aQute.bnd.aspectj.plugin",
      +      "aQute.bnd.build",
      +      "aQute.bnd.build.api",
      +      "aQute.bnd.build.model",
      +      "aQute.bnd.build.model.clauses",
      +      "aQute.bnd.build.model.conversions",
      +      "aQute.bnd.buildtool",
      +      "aQute.bnd.bundle.annotations",
      +      "aQute.bnd.cdi",
      +      "aQute.bnd.classindex",
      +      "aQute.bnd.compatibility",
      +      "aQute.bnd.component",
      +      "aQute.bnd.component.annotations",
      +      "aQute.bnd.component.error",
      +      "aQute.bnd.connection.settings",
      +      "aQute.bnd.differ",
      +      "aQute.bnd.exporter.executable",
      +      "aQute.bnd.exporter.runbundles",
      +      "aQute.bnd.filerepo",
      +      "aQute.bnd.header",
      +      "aQute.bnd.help",
      +      "aQute.bnd.help.instructions",
      +      "aQute.bnd.http",
      +      "aQute.bnd.junit",
      +      "aQute.bnd.make",
      +      "aQute.bnd.make.calltree",
      +      "aQute.bnd.make.component",
      +      "aQute.bnd.make.coverage",
      +      "aQute.bnd.make.metatype",
      +      "aQute.bnd.maven",
      +      "aQute.bnd.maven.support",
      +      "aQute.bnd.metatype",
      +      "aQute.bnd.metatype.annotations",
      +      "aQute.bnd.obr",
      +      "aQute.bnd.osgi",
      +      "aQute.bnd.osgi.eclipse",
      +      "aQute.bnd.osgi.repository",
      +      "aQute.bnd.osgi.resource",
      +      "aQute.bnd.plugin.ant",
      +      "aQute.bnd.plugin.eclipse",
      +      "aQute.bnd.plugin.git",
      +      "aQute.bnd.plugin.gradle",
      +      "aQute.bnd.plugin.jpms",
      +      "aQute.bnd.plugin.maven",
      +      "aQute.bnd.plugin.spi",
      +      "aQute.bnd.print",
      +      "aQute.bnd.properties",
      +      "aQute.bnd.remoteworkspace.client",
      +      "aQute.bnd.remoteworkspace.server",
      +      "aQute.bnd.resource.repository",
      +      "aQute.bnd.service",
      +      "aQute.bnd.service.action",
      +      "aQute.bnd.service.classparser",
      +      "aQute.bnd.service.clipboard",
      +      "aQute.bnd.service.diff",
      +      "aQute.bnd.service.export",
      +      "aQute.bnd.service.extension",
      +      "aQute.bnd.service.externalplugin",
      +      "aQute.bnd.service.generate",
      +      "aQute.bnd.service.library",
      +      "aQute.bnd.service.lifecycle",
      +      "aQute.bnd.service.maven",
      +      "aQute.bnd.service.message",
      +      "aQute.bnd.service.progress",
      +      "aQute.bnd.service.release",
      +      "aQute.bnd.service.remotelaunch",
      +      "aQute.bnd.service.remoteworkspace",
      +      "aQute.bnd.service.reporter",
      +      "aQute.bnd.service.repository",
      +      "aQute.bnd.service.resolve.hook",
      +      "aQute.bnd.service.specifications",
      +      "aQute.bnd.service.url",
      +      "aQute.bnd.service.verifier",
      +      "aQute.bnd.signing",
      +      "aQute.bnd.url",
      +      "aQute.bnd.util.dto",
      +      "aQute.bnd.util.home",
      +      "aQute.bnd.util.repository",
      +      "aQute.bnd.version",
      +      "aQute.bnd.version.maven",
      +      "aQute.bnd.xmlattribute",
      +      "aQute.lib.aspects",
      +      "aQute.lib.base64",
      +      "aQute.lib.collections",
      +      "aQute.lib.concurrent.serial",
      +      "aQute.lib.concurrentinit",
      +      "aQute.lib.converter",
      +      "aQute.lib.date",
      +      "aQute.lib.deployer",
      +      "aQute.lib.fileset",
      +      "aQute.lib.filter",
      +      "aQute.lib.formatter",
      +      "aQute.lib.hex",
      +      "aQute.lib.hierarchy",
      +      "aQute.lib.io",
      +      "aQute.lib.json",
      +      "aQute.lib.link",
      +      "aQute.lib.manifest",
      +      "aQute.lib.mavenpasswordobfuscator",
      +      "aQute.lib.persistentmap",
      +      "aQute.lib.redirect",
      +      "aQute.lib.settings",
      +      "aQute.lib.specinterface",
      +      "aQute.lib.spring",
      +      "aQute.lib.stringrover",
      +      "aQute.lib.strings",
      +      "aQute.lib.tag",
      +      "aQute.lib.utf8properties",
      +      "aQute.lib.watcher",
      +      "aQute.lib.xml",
      +      "aQute.lib.xpath",
      +      "aQute.lib.zip",
      +      "aQute.libg.command",
      +      "aQute.libg.cryptography",
      +      "aQute.libg.filelock",
      +      "aQute.libg.generics",
      +      "aQute.libg.glob",
      +      "aQute.libg.gzip",
      +      "aQute.libg.ints",
      +      "aQute.libg.map",
      +      "aQute.libg.qtokens",
      +      "aQute.libg.reporter",
      +      "aQute.libg.reporter.slf4j",
      +      "aQute.libg.sed",
      +      "aQute.libg.tuple",
      +      "aQute.libg.uri",
      +      "aQute.service.reporter"
      +    ],
           "com.google.auto.value:auto-value-annotations": [
             "com.google.auto.value",
             "com.google.auto.value.extension.memoized",
      -      "com.google.auto.value.extension.serializable"
      +      "com.google.auto.value.extension.serializable",
      +      "com.google.auto.value.extension.toprettystring"
      +    ],
      +    "com.google.caliper:caliper": [
      +      "com.google.caliper.runner",
      +      "com.google.caliper.runner.instrument",
      +      "com.google.caliper.runner.resultprocessor"
      +    ],
      +    "com.google.caliper:caliper-api": [
      +      "com.google.caliper",
      +      "com.google.caliper.api",
      +      "com.google.caliper.model"
      +    ],
      +    "com.google.caliper:caliper-core": [
      +      "com.google.caliper.bridge",
      +      "com.google.caliper.core",
      +      "com.google.caliper.memory"
      +    ],
      +    "com.google.caliper:caliper-runner": [
      +      "com.google.caliper.runner",
      +      "com.google.caliper.runner.config",
      +      "com.google.caliper.runner.experiment",
      +      "com.google.caliper.runner.instrument",
      +      "com.google.caliper.runner.options",
      +      "com.google.caliper.runner.resultprocessor",
      +      "com.google.caliper.runner.server",
      +      "com.google.caliper.runner.target",
      +      "com.google.caliper.runner.worker",
      +      "com.google.caliper.runner.worker.dryrun",
      +      "com.google.caliper.runner.worker.targetinfo",
      +      "com.google.caliper.runner.worker.trial"
      +    ],
      +    "com.google.caliper:caliper-util": [
      +      "com.google.caliper.json",
      +      "com.google.caliper.util"
      +    ],
      +    "com.google.caliper:caliper-worker": [
      +      "com.google.caliper.worker",
      +      "com.google.caliper.worker.connection",
      +      "com.google.caliper.worker.handler",
      +      "com.google.caliper.worker.instrument"
      +    ],
      +    "com.google.caliper:caliper-worker-jvm": [
      +      "com.google.caliper.worker"
           ],
           "com.google.code.findbugs:jsr305": [
             "javax.annotation",
      @@ -196,6 +730,48 @@
             "com.google.gson.reflect",
             "com.google.gson.stream"
           ],
      +    "com.google.code.java-allocation-instrumenter:java-allocation-instrumenter": [
      +      "com.google.monitoring.runtime.instrumentation",
      +      "com.google.monitoring.runtime.instrumentation.asm",
      +      "com.google.monitoring.runtime.instrumentation.asm.commons",
      +      "com.google.monitoring.runtime.instrumentation.asm.signature",
      +      "com.google.monitoring.runtime.instrumentation.asm.tree",
      +      "com.google.monitoring.runtime.instrumentation.asm.tree.analysis",
      +      "com.google.monitoring.runtime.instrumentation.asm.util",
      +      "com.google.monitoring.runtime.instrumentation.checker.nullness.compatqual",
      +      "com.google.monitoring.runtime.instrumentation.common.annotations",
      +      "com.google.monitoring.runtime.instrumentation.common.base",
      +      "com.google.monitoring.runtime.instrumentation.common.base.internal",
      +      "com.google.monitoring.runtime.instrumentation.common.cache",
      +      "com.google.monitoring.runtime.instrumentation.common.collect",
      +      "com.google.monitoring.runtime.instrumentation.common.escape",
      +      "com.google.monitoring.runtime.instrumentation.common.eventbus",
      +      "com.google.monitoring.runtime.instrumentation.common.graph",
      +      "com.google.monitoring.runtime.instrumentation.common.hash",
      +      "com.google.monitoring.runtime.instrumentation.common.html",
      +      "com.google.monitoring.runtime.instrumentation.common.io",
      +      "com.google.monitoring.runtime.instrumentation.common.math",
      +      "com.google.monitoring.runtime.instrumentation.common.net",
      +      "com.google.monitoring.runtime.instrumentation.common.primitives",
      +      "com.google.monitoring.runtime.instrumentation.common.reflect",
      +      "com.google.monitoring.runtime.instrumentation.common.util.concurrent",
      +      "com.google.monitoring.runtime.instrumentation.common.xml",
      +      "com.google.monitoring.runtime.instrumentation.errorprone.annotations",
      +      "com.google.monitoring.runtime.instrumentation.errorprone.annotations.concurrent",
      +      "com.google.monitoring.runtime.instrumentation.j2objc.annotations",
      +      "com.google.thirdparty.publicsuffix"
      +    ],
      +    "com.google.dagger:dagger": [
      +      "dagger",
      +      "dagger.internal",
      +      "dagger.multibindings"
      +    ],
      +    "com.google.dagger:dagger-producers": [
      +      "dagger.producers",
      +      "dagger.producers.internal",
      +      "dagger.producers.monitoring",
      +      "dagger.producers.monitoring.internal"
      +    ],
           "com.google.errorprone:error_prone_annotations": [
             "com.google.errorprone.annotations",
             "com.google.errorprone.annotations.concurrent"
      @@ -227,6 +803,7 @@
             "com.google.common.collect.testing",
             "com.google.common.collect.testing.features",
             "com.google.common.collect.testing.google",
      +      "com.google.common.collect.testing.suites",
             "com.google.common.collect.testing.testers",
             "com.google.common.escape.testing",
             "com.google.common.testing",
      @@ -238,6 +815,56 @@
           "com.google.truth:truth": [
             "com.google.common.truth"
           ],
      +    "com.squareup.okhttp:okhttp": [
      +      "com.squareup.okhttp",
      +      "com.squareup.okhttp.internal",
      +      "com.squareup.okhttp.internal.framed",
      +      "com.squareup.okhttp.internal.http",
      +      "com.squareup.okhttp.internal.io",
      +      "com.squareup.okhttp.internal.tls"
      +    ],
      +    "com.squareup.okio:okio": [
      +      "okio"
      +    ],
      +    "com.sun.jersey:jersey-client": [
      +      "com.sun.jersey.api.client",
      +      "com.sun.jersey.api.client.async",
      +      "com.sun.jersey.api.client.config",
      +      "com.sun.jersey.api.client.filter",
      +      "com.sun.jersey.client.impl",
      +      "com.sun.jersey.client.impl.async",
      +      "com.sun.jersey.client.proxy",
      +      "com.sun.jersey.client.urlconnection",
      +      "com.sun.ws.rs.ext"
      +    ],
      +    "com.sun.jersey:jersey-core": [
      +      "com.sun.jersey.api.provider.jaxb",
      +      "com.sun.jersey.api.representation",
      +      "com.sun.jersey.api.uri",
      +      "com.sun.jersey.core.header",
      +      "com.sun.jersey.core.header.reader",
      +      "com.sun.jersey.core.impl.provider.entity",
      +      "com.sun.jersey.core.impl.provider.header",
      +      "com.sun.jersey.core.impl.provider.xml",
      +      "com.sun.jersey.core.osgi",
      +      "com.sun.jersey.core.provider",
      +      "com.sun.jersey.core.provider.jaxb",
      +      "com.sun.jersey.core.reflection",
      +      "com.sun.jersey.core.spi.component",
      +      "com.sun.jersey.core.spi.component.ioc",
      +      "com.sun.jersey.core.spi.factory",
      +      "com.sun.jersey.core.spi.scanning",
      +      "com.sun.jersey.core.spi.scanning.uri",
      +      "com.sun.jersey.core.util",
      +      "com.sun.jersey.impl",
      +      "com.sun.jersey.localization",
      +      "com.sun.jersey.spi",
      +      "com.sun.jersey.spi.inject",
      +      "com.sun.jersey.spi.service"
      +    ],
      +    "info.picocli:picocli": [
      +      "picocli"
      +    ],
           "io.github.eisop:checker": [
             "com.github.javaparser",
             "com.github.javaparser.ast",
      @@ -275,6 +902,9 @@
             "com.github.javaparser.resolution.types",
             "com.github.javaparser.resolution.types.parametrization",
             "com.github.javaparser.utils",
      +      "javax.annotation",
      +      "javax.annotation.concurrent",
      +      "javax.annotation.meta",
             "org.checkerframework.checker.calledmethods",
             "org.checkerframework.checker.calledmethods.builder",
             "org.checkerframework.checker.compilermsgs",
      @@ -319,9 +949,11 @@
             "org.checkerframework.com.google.common.primitives",
             "org.checkerframework.com.google.common.reflect",
             "org.checkerframework.com.google.common.util.concurrent",
      +      "org.checkerframework.com.google.common.util.concurrent.internal",
             "org.checkerframework.com.google.common.xml",
             "org.checkerframework.com.google.errorprone.annotations",
             "org.checkerframework.com.google.errorprone.annotations.concurrent",
      +      "org.checkerframework.com.google.j2objc.annotations",
             "org.checkerframework.com.google.thirdparty.publicsuffix",
             "org.checkerframework.common.accumulation",
             "org.checkerframework.common.aliasing",
      @@ -413,6 +1045,28 @@
             "org.checkerframework.checker.signedness.util",
             "org.checkerframework.checker.units.util"
           ],
      +    "javax.annotation:javax.annotation-api": [
      +      "javax.annotation",
      +      "javax.annotation.security",
      +      "javax.annotation.sql"
      +    ],
      +    "javax.inject:javax.inject": [
      +      "javax.inject"
      +    ],
      +    "javax.ws.rs:jsr311-api": [
      +      "javax.ws.rs",
      +      "javax.ws.rs.core",
      +      "javax.ws.rs.ext"
      +    ],
      +    "joda-time:joda-time": [
      +      "org.joda.time",
      +      "org.joda.time.base",
      +      "org.joda.time.chrono",
      +      "org.joda.time.convert",
      +      "org.joda.time.field",
      +      "org.joda.time.format",
      +      "org.joda.time.tz"
      +    ],
           "junit:junit": [
             "junit.extensions",
             "junit.framework",
      @@ -491,6 +1145,9 @@
             "net.bytebuddy.agent",
             "net.bytebuddy.agent.utility.nullability"
           ],
      +    "org.checkerframework:checker-compat-qual": [
      +      "org.checkerframework.checker.nullness.compatqual"
      +    ],
           "org.checkerframework:checker-qual": [
             "org.checkerframework.checker.builder.qual",
             "org.checkerframework.checker.calledmethods.qual",
      @@ -504,6 +1161,7 @@
             "org.checkerframework.checker.initialization.qual",
             "org.checkerframework.checker.interning.qual",
             "org.checkerframework.checker.lock.qual",
      +      "org.checkerframework.checker.mustcall.qual",
             "org.checkerframework.checker.nullness.qual",
             "org.checkerframework.checker.optional.qual",
             "org.checkerframework.checker.propkey.qual",
      @@ -605,16 +1263,86 @@
             "org.objenesis.instantiator.util",
             "org.objenesis.strategy"
           ],
      +    "org.osgi:org.osgi.dto": [
      +      "org.osgi.dto"
      +    ],
      +    "org.osgi:org.osgi.framework": [
      +      "org.osgi.framework",
      +      "org.osgi.framework.dto",
      +      "org.osgi.framework.hooks.bundle",
      +      "org.osgi.framework.hooks.resolver",
      +      "org.osgi.framework.hooks.service",
      +      "org.osgi.framework.hooks.weaving",
      +      "org.osgi.framework.launch",
      +      "org.osgi.framework.namespace",
      +      "org.osgi.framework.startlevel",
      +      "org.osgi.framework.startlevel.dto",
      +      "org.osgi.framework.wiring",
      +      "org.osgi.framework.wiring.dto"
      +    ],
      +    "org.osgi:org.osgi.resource": [
      +      "org.osgi.resource",
      +      "org.osgi.resource.dto"
      +    ],
      +    "org.osgi:org.osgi.service.log": [
      +      "org.osgi.service.log"
      +    ],
      +    "org.osgi:org.osgi.service.repository": [
      +      "org.osgi.service.repository"
      +    ],
      +    "org.osgi:org.osgi.util.function": [
      +      "org.osgi.util.function"
      +    ],
      +    "org.osgi:org.osgi.util.promise": [
      +      "org.osgi.util.promise"
      +    ],
      +    "org.osgi:org.osgi.util.tracker": [
      +      "org.osgi.util.tracker"
      +    ],
      +    "org.osgi:osgi.annotation": [
      +      "org.osgi.annotation.bundle",
      +      "org.osgi.annotation.versioning"
      +    ],
           "org.ow2.asm:asm": [
             "org.objectweb.asm",
             "org.objectweb.asm.signature"
      +    ],
      +    "org.ow2.asm:asm-analysis": [
      +      "org.objectweb.asm.tree.analysis"
      +    ],
      +    "org.ow2.asm:asm-commons": [
      +      "org.objectweb.asm.commons"
      +    ],
      +    "org.ow2.asm:asm-tree": [
      +      "org.objectweb.asm.tree"
      +    ],
      +    "org.ow2.asm:asm-util": [
      +      "org.objectweb.asm.util"
      +    ],
      +    "org.slf4j:slf4j-api": [
      +      "org.slf4j",
      +      "org.slf4j.event",
      +      "org.slf4j.helpers",
      +      "org.slf4j.spi"
           ]
         },
         "repositories": {
           "https://repo1.maven.org/maven2/": [
      +      "biz.aQute.bnd:biz.aQute.bnd.util",
      +      "biz.aQute.bnd:biz.aQute.bndlib",
             "com.google.auto.value:auto-value-annotations",
      +      "com.google.caliper:caliper",
      +      "com.google.caliper:caliper-api",
      +      "com.google.caliper:caliper-core",
      +      "com.google.caliper:caliper-runner",
      +      "com.google.caliper:caliper-util",
      +      "com.google.caliper:caliper-worker",
      +      "com.google.caliper:caliper-worker-jvm",
             "com.google.code.findbugs:jsr305",
             "com.google.code.gson:gson",
      +      "com.google.code.java-allocation-instrumenter:java-allocation-instrumenter",
      +      "com.google.dagger:dagger",
      +      "com.google.dagger:dagger-producers",
             "com.google.errorprone:error_prone_annotations",
             "com.google.guava:failureaccess",
             "com.google.guava:guava",
      @@ -622,19 +1350,116 @@
             "com.google.guava:listenablefuture",
             "com.google.j2objc:j2objc-annotations",
             "com.google.truth:truth",
      +      "com.squareup.okhttp:okhttp",
      +      "com.squareup.okio:okio",
      +      "com.sun.jersey:jersey-client",
      +      "com.sun.jersey:jersey-core",
      +      "info.picocli:picocli",
             "io.github.eisop:checker",
             "io.github.eisop:checker-qual",
             "io.github.eisop:checker-util",
      +      "javax.annotation:javax.annotation-api",
      +      "javax.inject:javax.inject",
      +      "javax.ws.rs:jsr311-api",
      +      "joda-time:joda-time",
             "junit:junit",
             "net.bytebuddy:byte-buddy",
             "net.bytebuddy:byte-buddy-agent",
      +      "org.checkerframework:checker-compat-qual",
             "org.checkerframework:checker-qual",
             "org.hamcrest:hamcrest-core",
             "org.mockito:mockito-core",
             "org.objenesis:objenesis",
      -      "org.ow2.asm:asm"
      +      "org.osgi:org.osgi.dto",
      +      "org.osgi:org.osgi.framework",
      +      "org.osgi:org.osgi.resource",
      +      "org.osgi:org.osgi.service.log",
      +      "org.osgi:org.osgi.service.repository",
      +      "org.osgi:org.osgi.util.function",
      +      "org.osgi:org.osgi.util.promise",
      +      "org.osgi:org.osgi.util.tracker",
      +      "org.osgi:osgi.annotation",
      +      "org.ow2.asm:asm",
      +      "org.ow2.asm:asm-analysis",
      +      "org.ow2.asm:asm-commons",
      +      "org.ow2.asm:asm-tree",
      +      "org.ow2.asm:asm-util",
      +      "org.slf4j:slf4j-api"
           ]
         },
      -  "services": {},
      +  "services": {
      +    "com.sun.jersey:jersey-core": {
      +      "com.sun.jersey.spi.HeaderDelegateProvider": [
      +        "com.sun.jersey.core.impl.provider.header.CacheControlProvider",
      +        "com.sun.jersey.core.impl.provider.header.CookieProvider",
      +        "com.sun.jersey.core.impl.provider.header.DateProvider",
      +        "com.sun.jersey.core.impl.provider.header.EntityTagProvider",
      +        "com.sun.jersey.core.impl.provider.header.LocaleProvider",
      +        "com.sun.jersey.core.impl.provider.header.MediaTypeProvider",
      +        "com.sun.jersey.core.impl.provider.header.NewCookieProvider",
      +        "com.sun.jersey.core.impl.provider.header.StringProvider",
      +        "com.sun.jersey.core.impl.provider.header.URIProvider"
      +      ],
      +      "com.sun.jersey.spi.inject.InjectableProvider": [
      +        "com.sun.jersey.core.impl.provider.xml.DocumentBuilderFactoryProvider",
      +        "com.sun.jersey.core.impl.provider.xml.SAXParserContextProvider",
      +        "com.sun.jersey.core.impl.provider.xml.TransformerFactoryProvider",
      +        "com.sun.jersey.core.impl.provider.xml.XMLStreamReaderContextProvider"
      +      ],
      +      "javax.ws.rs.ext.MessageBodyReader": [
      +        "com.sun.jersey.core.impl.provider.entity.ByteArrayProvider",
      +        "com.sun.jersey.core.impl.provider.entity.DataSourceProvider",
      +        "com.sun.jersey.core.impl.provider.entity.DocumentProvider",
      +        "com.sun.jersey.core.impl.provider.entity.EntityHolderReader",
      +        "com.sun.jersey.core.impl.provider.entity.FileProvider",
      +        "com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider",
      +        "com.sun.jersey.core.impl.provider.entity.FormProvider",
      +        "com.sun.jersey.core.impl.provider.entity.InputStreamProvider",
      +        "com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider",
      +        "com.sun.jersey.core.impl.provider.entity.ReaderProvider",
      +        "com.sun.jersey.core.impl.provider.entity.RenderedImageProvider",
      +        "com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader",
      +        "com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader",
      +        "com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader",
      +        "com.sun.jersey.core.impl.provider.entity.StringProvider",
      +        "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$App",
      +        "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General",
      +        "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$Text",
      +        "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$App",
      +        "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General",
      +        "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$Text",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$Text",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$App",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$Text"
      +      ],
      +      "javax.ws.rs.ext.MessageBodyWriter": [
      +        "com.sun.jersey.core.impl.provider.entity.ByteArrayProvider",
      +        "com.sun.jersey.core.impl.provider.entity.DataSourceProvider",
      +        "com.sun.jersey.core.impl.provider.entity.DocumentProvider",
      +        "com.sun.jersey.core.impl.provider.entity.FileProvider",
      +        "com.sun.jersey.core.impl.provider.entity.FormMultivaluedMapProvider",
      +        "com.sun.jersey.core.impl.provider.entity.FormProvider",
      +        "com.sun.jersey.core.impl.provider.entity.InputStreamProvider",
      +        "com.sun.jersey.core.impl.provider.entity.MimeMultipartProvider",
      +        "com.sun.jersey.core.impl.provider.entity.ReaderProvider",
      +        "com.sun.jersey.core.impl.provider.entity.RenderedImageProvider",
      +        "com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter",
      +        "com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider",
      +        "com.sun.jersey.core.impl.provider.entity.StringProvider",
      +        "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$App",
      +        "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General",
      +        "com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$Text",
      +        "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$App",
      +        "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General",
      +        "com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$Text",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$App",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General",
      +        "com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$Text"
      +      ]
      +    }
      +  },
         "version": "2"
       }
      diff --git a/docs/examples/MavenExample/pom.xml b/docs/examples/MavenExample/pom.xml
      index c246deb6ab8..7357c7b89cb 100644
      --- a/docs/examples/MavenExample/pom.xml
      +++ b/docs/examples/MavenExample/pom.xml
      @@ -14,7 +14,7 @@
           UTF-8
           8
           8
      -    3.42.0-eisop4
      +    3.42.0-eisop5
         
       
         
      diff --git a/docs/examples/errorprone/build.gradle b/docs/examples/errorprone/build.gradle
      index e377e36f2e7..e1916676847 100644
      --- a/docs/examples/errorprone/build.gradle
      +++ b/docs/examples/errorprone/build.gradle
      @@ -6,17 +6,17 @@ plugins {
           id 'java'
           id 'net.ltgt.errorprone' version '4.1.0'
           // Checker Framework pluggable type-checking
      -    id 'org.checkerframework' version '0.6.47'
      +    id 'org.checkerframework' version '0.6.48' apply false
       }
       
       ext {
           versions = [
      -        eisopVersion: '3.42.0-eisop4',
      +        eisopVersion: '3.42.0-eisop5',
           ]
       }
       
       apply plugin: 'org.checkerframework'
      -if (true) {
      +if (false) {
           def cfHome = "${projectDir}/../../.."
           dependencies {
               compileOnly files(cfHome + '/checker/dist/checker-qual.jar')
      @@ -27,6 +27,7 @@ if (true) {
           dependencies {
               compileOnly "io.github.eisop:checker-qual:${versions.eisopVersion}"
               testCompileOnly "io.github.eisop:checker-qual:${versions.eisopVersion}"
      +        checkerFramework "io.github.eisop:checker-qual:${versions.eisopVersion}"
               checkerFramework "io.github.eisop:checker:${versions.eisopVersion}"
           }
       }
      diff --git a/docs/examples/lombok/Makefile b/docs/examples/lombok/Makefile
      index 3cd6a335b59..6419e8cbb15 100644
      --- a/docs/examples/lombok/Makefile
      +++ b/docs/examples/lombok/Makefile
      @@ -4,8 +4,8 @@ JAVA_VER := $(shell java -version 2>&1 | head -1 | cut -d'"' -f2 | sed '/^1\./s/
       
       # Delomboking seems to mess up line numbers. The actual error is on line 13, but the error appears on line 12.
       # So check for both the error message and make sure it is for the right assignment.
      -# As of 2023-09-23, lombok does not work under Java 22, see https://projectlombok.org/changelog .
      -ifeq (${JAVA_VER},22)
      +# As of 2024-12-24, lombok does not work under Java 24, see https://projectlombok.org/changelog .
      +ifeq ($(shell test $(JAVA_VER) -gt 23; echo $$?),0)
       all:
       	@echo "Skipping test because lombok does not work under Java ${JAVA_VER}"
       else
      diff --git a/docs/examples/lombok/build.gradle b/docs/examples/lombok/build.gradle
      index 53e1a7926cc..d320fe13eaa 100644
      --- a/docs/examples/lombok/build.gradle
      +++ b/docs/examples/lombok/build.gradle
      @@ -6,7 +6,7 @@ plugins {
           id 'java'
           id 'io.freefair.lombok' version '8.11'
           // Checker Framework pluggable type-checking
      -    id 'org.checkerframework' version '0.6.47'
      +    id 'org.checkerframework' version '0.6.48'
       }
       
       lombok {
      diff --git a/docs/manual/creating-a-checker.tex b/docs/manual/creating-a-checker.tex
      index bf5c2e83f0e..e3c578bf1fa 100644
      --- a/docs/manual/creating-a-checker.tex
      +++ b/docs/manual/creating-a-checker.tex
      @@ -212,7 +212,7 @@
       repository \url{https://github.com/eisop/checker-framework}.
       Another choice is to write it in a stand-alone repository.  Here is a
       template for a stand-alone repository:
      -\url{https://github.com/typetools/templatefora-checker}; at that URL,
      +\url{https://github.com/eisop/templatefora-checker}; at that URL,
       click the ``Use this template'' button.
       
       % You may also wish to consult Section~\ref{creating-testing-framework} for
      diff --git a/docs/manual/external-tools.tex b/docs/manual/external-tools.tex
      index 61fc8faa5b6..12fc7f236de 100644
      --- a/docs/manual/external-tools.tex
      +++ b/docs/manual/external-tools.tex
      @@ -118,7 +118,7 @@
       \begin{Verbatim}
       dependencies {
           ... existing dependencies...
      -    ext.checkerFrameworkVersion = '3.42.0-eisop4'
      +    ext.checkerFrameworkVersion = '3.42.0-eisop5'
           implementation "io.github.eisop:checker-qual-android:${checkerFrameworkVersion}"
           // or if you use no annotations in source code the above line could be
           // compileOnly "io.github.eisop:checker-qual-android:${checkerFrameworkVersion}"
      @@ -191,7 +191,7 @@
       \begin{Verbatim}
       dependencies {
           ... existing dependencies...
      -    ext.checkerFrameworkVersion = '3.42.0-eisop4'
      +    ext.checkerFrameworkVersion = '3.42.0-eisop5'
           implementation "io.github.eisop:checker-qual-android:${checkerFrameworkVersion}"
           // or if you use no annotations in source code the above line could be
           // compileOnly "io.github.eisop:checker-qual-android:${checkerFrameworkVersion}"
      @@ -353,13 +353,13 @@
       \begin{Verbatim}
       prebuilt_jar(
           name = 'checker-framework',
      -    binary_jar = 'checker-3.42.0-eisop4.jar',
      +    binary_jar = 'checker-3.42.0-eisop5.jar',
           visibility = [ 'PUBLIC' ]
       )
       
       prebuilt_jar(
           name = 'checker-qual',
      -    binary_jar = 'checker-qual-3.42.0-eisop4.jar',
      +    binary_jar = 'checker-qual-3.42.0-eisop5.jar',
           visibility = [ 'PUBLIC' ]
       )
       
      @@ -423,21 +423,21 @@
       use the last one.
       % Is the last one required for Cygwin, as well as for the Windows command shell?
       Adjust the pathnames if you have installed the Checker Framework somewhere
      -other than \<\${HOME}/checker-framework-3.42.0-eisop4/>.
      +other than \<\${HOME}/checker-framework-3.42.0-eisop5/>.
       
       
       \begin{itemize}
         \item
           Option 1:
           Add directory
      -    \code{.../checker-framework-3.42.0-eisop4/checker/bin} to your path, \emph{before} any other
      +    \code{.../checker-framework-3.42.0-eisop5/checker/bin} to your path, \emph{before} any other
           directory that contains a \ executable.
       
           If you are
           using the bash shell, a way to do this is to add the following to your
           \verb|~/.profile| (or alternately \verb|~/.bash_profile| or \verb|~/.bashrc|) file:
       \begin{Verbatim}
      -  export CHECKERFRAMEWORK=${HOME}/checker-framework-3.42.0-eisop4
      +  export CHECKERFRAMEWORK=${HOME}/checker-framework-3.42.0-eisop5
         export PATH=${CHECKERFRAMEWORK}/checker/bin:${PATH}
       \end{Verbatim}
       
      @@ -458,7 +458,7 @@
           file:
       % No Windows example because this doesn't work under Windows.
       \begin{Verbatim}
      -  export CHECKERFRAMEWORK=${HOME}/checker-framework-3.42.0-eisop4
      +  export CHECKERFRAMEWORK=${HOME}/checker-framework-3.42.0-eisop5
         alias javacheck='$CHECKERFRAMEWORK/checker/bin/javac'
       \end{Verbatim}
       
      @@ -480,11 +480,11 @@
       
       \begin{Verbatim}
         # Unix
      -  export CHECKERFRAMEWORK=${HOME}/checker-framework-3.42.0-eisop4
      +  export CHECKERFRAMEWORK=${HOME}/checker-framework-3.42.0-eisop5
         alias javacheck='java -jar "$CHECKERFRAMEWORK/checker/dist/checker.jar"'
       
         # Windows
      -  set CHECKERFRAMEWORK = C:\Program Files\checker-framework-3.42.0-eisop4\
      +  set CHECKERFRAMEWORK = C:\Program Files\checker-framework-3.42.0-eisop5\
         doskey javacheck=java -jar "%CHECKERFRAMEWORK%\checker\dist\checker.jar" $*
       \end{Verbatim}
       
      @@ -563,9 +563,9 @@
       
       \begin{itemize}
       \item \: \url{https://search.maven.org/artifact/com.google.errorprone/javac/9%2B181-r4173-1/jar}
      -\item \: \url{https://repo1.maven.org/maven2/io/github/eisop/checker-qual/3.42.0-eisop4/checker-qual-3.42.0-eisop4.jar}
      -\item \: \url{https://repo1.maven.org/maven2/io/github/eisop/checker-util/3.42.0-eisop4/checker-util-3.42.0-eisop4.jar}
      -\item \: \url{https://repo1.maven.org/maven2/io/github/eisop/checker/3.42.0-eisop4/checker-3.42.0-eisop4-all.jar}
      +\item \: \url{https://repo1.maven.org/maven2/io/github/eisop/checker-qual/3.42.0-eisop5/checker-qual-3.42.0-eisop5.jar}
      +\item \: \url{https://repo1.maven.org/maven2/io/github/eisop/checker-util/3.42.0-eisop5/checker-util-3.42.0-eisop5.jar}
      +\item \: \url{https://repo1.maven.org/maven2/io/github/eisop/checker/3.42.0-eisop5/checker-3.42.0-eisop5-all.jar}
       \end{itemize}
       
       Different arguments to \ are required for JDK 8
      @@ -813,13 +813,14 @@
       
       ext {
           versions = [
      -        eisopVersion: '3.42.0-eisop1',
      +        eisopVersion: '3.42.0-eisop5',
           ]
       }
       
       dependencies {
           compileOnly "io.github.eisop:checker-qual:${versions.eisopVersion}"
           testCompileOnly "io.github.eisop:checker-qual:${versions.eisopVersion}"
      +    checkerFramework "io.github.eisop:checker-qual:${versions.eisopVersion}"
           checkerFramework "io.github.eisop:checker:${versions.eisopVersion}"
       }
       \end{Verbatim}
      diff --git a/docs/manual/introduction.tex b/docs/manual/introduction.tex
      index f5374c84eb6..4d53afaceb1 100644
      --- a/docs/manual/introduction.tex
      +++ b/docs/manual/introduction.tex
      @@ -205,7 +205,7 @@
         %BEGIN LATEX
         \\
         %END LATEX
      -  \url{https://eisop.github.io/cf/checker-framework-3.42.0-eisop4.zip}
      +  \url{https://eisop.github.io/cf/checker-framework-3.42.0-eisop5.zip}
       
       \item
         Unzip it to create a \code{checker-framework-\ReleaseVersion{}} directory.
      @@ -596,6 +596,9 @@
         which is a javac argument to halt compilation if a warning is issued.
       \item \<-AignoreInvalidAnnotationLocations>
         Ignore annotations in bytecode that have invalid annotation locations.
      +\item \<-AignoreTargetLocations>
      +  Disables validating the target locations of qualifiers based on
      +  `@TargetLocations` meta-annotations. This option is not enabled by default.
       \end{itemize}
       
       \label{unsound-by-default}
      diff --git a/docs/manual/manual.tex b/docs/manual/manual.tex
      index d7b83a1e779..0c4f1528d74 100644
      --- a/docs/manual/manual.tex
      +++ b/docs/manual/manual.tex
      @@ -4,8 +4,8 @@
       
       \title{The Checker Framework Manual: \\ Custom pluggable types for Java}
       \author{\url{https://eisop.github.io/}}
      -\newcommand{\ReleaseVersion}{3.42.0-eisop4}
      -\newcommand{\ReleaseInfo}{3.42.0-eisop4 (12 Jul 2024)}
      +\newcommand{\ReleaseVersion}{3.42.0-eisop5}
      +\newcommand{\ReleaseInfo}{3.42.0-eisop5 (20 Dec 2024)}
       \date{Version \ReleaseInfo{}}
       
       \begin{document}
      diff --git a/docs/manual/map-key-checker.tex b/docs/manual/map-key-checker.tex
      index d87a71ca003..d2ea2665896 100644
      --- a/docs/manual/map-key-checker.tex
      +++ b/docs/manual/map-key-checker.tex
      @@ -2,8 +2,8 @@
       \chapterAndLabel{Map Key Checker}{map-key-checker}
       
       The Map Key Checker tracks which values are keys for which maps.  If variable
      -\code{v} has type \code{@KeyFor("m")...}, then the value of \code{v} is a key
      -in Map \code{m}.  That is, the expression \code{m.containsKey(v)} evaluates to
      +\code{k} has type \code{@KeyFor("m")...}, then the value of \code{k} is a key
      +in Map \code{m}.  That is, the expression \code{m.containsKey(k)} evaluates to
       \code{true}.
       
       Section~\ref{map-key-qualifiers} describes how \code{@KeyFor} annotations
      diff --git a/framework/build.gradle b/framework/build.gradle
      index 5eb212363b1..c6b4ed07177 100644
      --- a/framework/build.gradle
      +++ b/framework/build.gradle
      @@ -94,22 +94,22 @@ interface InjectedExecOps {
       }
       
       task cloneAnnotatedJdk() {
      -    description 'Obtain or update the annotated JDK.'
      +    description = 'Obtain or update the annotated JDK.'
       
           def injected = project.objects.newInstance(InjectedExecOps)
       
           doLast {
               if (file(annotatedJdkHome).exists()) {
                   injected.execOps.exec {
      -                workingDir annotatedJdkHome
      +                workingDir file(annotatedJdkHome)
                       executable 'git'
                       args = ['pull', '-q']
                       ignoreExitValue = true
                   }
               } else {
      -            println 'Cloning annotated JDK repository.'
      +            println "Cloning annotated JDK repository in ${annotatedJdkHome}/../"
                   injected.execOps.exec {
      -                workingDir "${annotatedJdkHome}/../"
      +                workingDir file("${annotatedJdkHome}/../")
                       executable 'git'
                       args = [
                           'clone',
      @@ -129,7 +129,7 @@ task copyAndMinimizeAnnotatedJdkFiles(dependsOn: cloneAnnotatedJdk, group: 'Buil
           def inputDir = "${annotatedJdkHome}/src"
           def outputDir = "${buildDir}/generated/resources/annotated-jdk/"
       
      -    description "Copy annotated JDK files to ${outputDir}. Removes private and package-private methods, method bodies, comments, etc. from the annotated JDK"
      +    description = "Copy annotated JDK files to ${outputDir}. Removes private and package-private methods, method bodies, comments, etc. from the annotated JDK"
       
           inputs.dir file(inputDir)
           outputs.dir file(outputDir)
      @@ -175,7 +175,7 @@ sourcesJar.dependsOn(copyAndMinimizeAnnotatedJdkFiles)
       processResources.dependsOn(copyAndMinimizeAnnotatedJdkFiles)
       
       task allSourcesJar(type: Jar, group: 'Build') {
      -    description 'Creates a sources jar that includes sources for all Checker Framework classes in framework.jar'
      +    description = 'Creates a sources jar that includes sources for all Checker Framework classes in framework.jar'
           destinationDirectory = file("${projectDir}/dist")
           archiveFileName = 'framework-source.jar'
           from (project(':framework').sourceSets.main.java,
      @@ -184,7 +184,7 @@ task allSourcesJar(type: Jar, group: 'Build') {
       }
       
       task allJavadocJar(type: Jar, group: 'Build') {
      -    description 'Creates javadoc jar include Javadoc for all of the framework'
      +    description = 'Creates javadoc jar include Javadoc for all of the framework'
           dependsOn (project(':framework').tasks.javadoc,
                   project(':dataflow').tasks.javadoc,
                   project(':javacutil').tasks.javadoc)
      @@ -198,7 +198,7 @@ task allJavadocJar(type: Jar, group: 'Build') {
       }
       
       shadowJar {
      -    description 'Creates the "fat" framework.jar in dist'
      +    description = 'Creates the "fat" framework.jar in dist'
           destinationDirectory = file("${projectDir}/dist")
           archiveFileName = 'framework.jar'
           manifest {
      @@ -217,7 +217,7 @@ checkCompilerMessages {
       }
       
       task loaderTests(dependsOn: 'shadowJar', group: 'Verification') {
      -    description 'Run tests for the annotation class loader'
      +    description = 'Run tests for the annotation class loader'
           dependsOn(compileTestJava)
       
           def injected = project.objects.newInstance(InjectedExecOps)
      @@ -227,12 +227,8 @@ task loaderTests(dependsOn: 'shadowJar', group: 'Verification') {
           dependsOn project(':checker').tasks.assemble
           doLast {
               injected.execOps.exec {
      -            executable 'make'
      -            args = [
      -                '-C',
      -                'tests/annotationclassloader/',
      -                'all'
      -            ]
      +            workingDir = file('tests/annotationclassloader')
      +            commandLine 'make', 'all'
               }
           }
       }
      @@ -253,7 +249,7 @@ clean {
       
       
       task delombok {
      -    description 'Delomboks the source code tree in tests/returnsreceiverlombok'
      +    description = 'Delomboks the source code tree in tests/returnsreceiverlombok'
       
           def srcDelomboked = 'tests/returnsreceiverdelomboked'
           def srcJava = 'tests/returnsreceiverlombok'
      diff --git a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java
      index 21f5bbaf089..6cb489b93f6 100644
      --- a/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java
      +++ b/framework/src/main/java/org/checkerframework/common/basetype/BaseTypeVisitor.java
      @@ -3815,7 +3815,7 @@ protected void reportMethodInvocabilityError(
            * constructor result type. This is equivalent to down-casting.
            *
            * 

      For type checking of the enclosing expression of inner type instantiations, see {@link - * #checkEnclosingExpr(NewClassTree, AnnotatedExecutableType)} + * #checkEnclosingExpr(NewClassTree, AnnotatedTypeMirror.AnnotatedExecutableType)} * * @param invocation the AnnotatedDeclaredType of the constructor invocation * @param constructor the AnnotatedExecutableType of the constructor declaration 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 62f34b763b0..d4edf72c042 100644 --- a/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java +++ b/framework/src/main/java/org/checkerframework/framework/source/SourceChecker.java @@ -85,6 +85,7 @@ import javax.annotation.processing.SupportedAnnotationTypes; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.util.Elements; import javax.lang.model.util.Types; @@ -2296,7 +2297,7 @@ public boolean shouldSuppressWarnings(@Nullable TreePath path, String errKey) { if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) { // Return false immediately. Do NOT check for AnnotatedFor in the enclosing - // elements, because they may not have an @AnnotatedFor. + // elements as the closest AnnotatedFor is already found. return false; } } else if (TreeUtils.classTreeKinds().contains(decl.getKind())) { @@ -2308,9 +2309,20 @@ public boolean shouldSuppressWarnings(@Nullable TreePath path, String errKey) { if (isAnnotatedForThisCheckerOrUpstreamChecker(elt)) { // Return false immediately. Do NOT check for AnnotatedFor in the enclosing - // elements, because they may not have an @AnnotatedFor. + // elements as the closest AnnotatedFor is already found. return false; } + Element packageElement = elt.getEnclosingElement(); + if (packageElement != null && packageElement.getKind() == ElementKind.PACKAGE) { + if (shouldSuppressWarnings(packageElement, errKey)) { + return true; + } + if (isAnnotatedForThisCheckerOrUpstreamChecker(packageElement)) { + // Return false immediately. Do NOT check for AnnotatedFor in the enclosing + // elements as the closest AnnotatedFor is already found. + return false; + } + } } else { throw new BugInCF("Unexpected declaration kind: " + decl.getKind() + " " + decl); } diff --git a/framework/src/main/java/org/checkerframework/framework/stub/AnnotationFileParser.java b/framework/src/main/java/org/checkerframework/framework/stub/AnnotationFileParser.java index 0557b75cb6f..955d4db1e30 100644 --- a/framework/src/main/java/org/checkerframework/framework/stub/AnnotationFileParser.java +++ b/framework/src/main/java/org/checkerframework/framework/stub/AnnotationFileParser.java @@ -82,6 +82,7 @@ import org.checkerframework.javacutil.BugInCF; import org.checkerframework.javacutil.ElementUtils; import org.checkerframework.javacutil.TreeUtils; +import org.checkerframework.javacutil.TypesUtils; import org.checkerframework.javacutil.UserError; import org.plumelib.util.ArrayMap; import org.plumelib.util.CollectionsPlume; @@ -1990,11 +1991,7 @@ private void annotateTypeParameters( } if (param.getTypeBound().size() == 1 && param.getTypeBound().get(0).getAnnotations().isEmpty() - && paramType - .getUpperBound() - .getUnderlyingType() - .toString() - .contentEquals("java.lang.Object")) { + && TypesUtils.isObject(paramType.getUpperBound().getUnderlyingType())) { // If there is an explicit "T extends Object" type parameter bound, // treat it like an explicit use of "Object" in code. AnnotatedTypeMirror ub = atypeFactory.getAnnotatedType(Object.class); diff --git a/framework/src/main/java/org/checkerframework/framework/type/AbstractViewpointAdapter.java b/framework/src/main/java/org/checkerframework/framework/type/AbstractViewpointAdapter.java index d85f0814579..a2121ad4bf0 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AbstractViewpointAdapter.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AbstractViewpointAdapter.java @@ -104,7 +104,6 @@ public void viewpointAdaptConstructor( AnnotatedTypeMirror receiverType, ExecutableElement constructorElt, AnnotatedExecutableType constructorType) { - // constructorType's typevar are not substituted when calling viewpointAdaptConstructor AnnotatedExecutableType unsubstitutedConstructorType = constructorType.deepCopy(); @@ -336,7 +335,6 @@ protected AnnotatedTypeMirror combineAnnotationWithType( return aat; } else if (declared.getKind() == TypeKind.WILDCARD) { AnnotatedWildcardType awt = (AnnotatedWildcardType) declared.shallowCopy(); - IdentityHashMap mappings = new IdentityHashMap<>(); @@ -361,7 +359,6 @@ protected AnnotatedTypeMirror combineAnnotationWithType( } AnnotatedTypeMirror result = AnnotatedTypeCopierWithReplacement.replace(awt, mappings); - return result; } else if (declared.getKind() == TypeKind.NULL) { AnnotatedNullType ant = (AnnotatedNullType) declared.shallowCopy(true); diff --git a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeCopier.java b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeCopier.java index ff03269fa1d..d072b53099a 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeCopier.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeCopier.java @@ -368,7 +368,6 @@ protected T makeOrReturnCopy( */ @SuppressWarnings("unchecked") protected T makeCopy(T original) { - T copy = (T) AnnotatedTypeMirror.createType( diff --git a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java index c8831335be3..4bfa54ee549 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeFactory.java @@ -2144,7 +2144,6 @@ protected Set> getFieldInvariantDeclarationAnnotatio */ public List typeVariablesFromUse( AnnotatedDeclaredType type, TypeElement element) { - AnnotatedDeclaredType generic = getAnnotatedType(element); List targs = type.getTypeArguments(); List tvars = generic.getTypeArguments(); diff --git a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeMirror.java b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeMirror.java index afef59f6f87..99bd9f76596 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeMirror.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AnnotatedTypeMirror.java @@ -1213,7 +1213,7 @@ private AnnotatedExecutableType(ExecutableType type, AnnotatedTypeFactory factor /** The parameter types; an unmodifiable list. */ private @MonotonicNonNull List paramTypes = null; - /** Whether {@link paramTypes} has been computed. */ + /** Whether {@link #paramTypes} has been computed. */ private boolean paramTypesComputed = false; /** @@ -1223,32 +1223,33 @@ private AnnotatedExecutableType(ExecutableType type, AnnotatedTypeFactory factor private @Nullable AnnotatedDeclaredType receiverType; /** - * The varargs type is the last element of {@link paramTypes} if the method or constructor - * accepts a variable number of arguments and the {@link paramTypes} has not been expanded + * The varargs type is the last element of {@link #paramTypes} if the method or constructor + * accepts a variable number of arguments and the {@link #paramTypes} has not been expanded * yet. This type needs to be stored in the field to avoid being affected by calling {@link - * AnnotatedTypes#adaptParameters(AnnotatedTypeFactory, AnnotatedExecutableType, List)}. + * AnnotatedTypes#adaptParameters(AnnotatedTypeFactory, + * AnnotatedTypeMirror.AnnotatedExecutableType, List, com.sun.source.tree.NewClassTree)}. */ private @MonotonicNonNull AnnotatedArrayType varargType = null; - /** Whether {@link receiverType} has been computed. */ + /** Whether {@link #receiverType} has been computed. */ private boolean receiverTypeComputed = false; /** The return type. */ private AnnotatedTypeMirror returnType; - /** Whether {@link returnType} has been computed. */ + /** Whether {@link #returnType} has been computed. */ private boolean returnTypeComputed = false; /** The thrown types; an unmodifiable list. */ private List thrownTypes; - /** Whether {@link thrownTypes} has been computed. */ + /** Whether {@link #thrownTypes} has been computed. */ private boolean thrownTypesComputed = false; /** The type variables; an unmodifiable list. */ private List typeVarTypes; - /** Whether {@link typeVarTypes} has been computed. */ + /** Whether {@link #typeVarTypes} has been computed. */ private boolean typeVarTypesComputed = false; /** @@ -1285,7 +1286,7 @@ public void addAnnotation(AnnotationMirror annotation) { /** * Sets the parameter types of this executable type, excluding the receiver.If paramTypes * has been computed and this type is a varargs method, computes and store {@link - * varargType} before calling this method, @see {@link varargType} + * #varargType} before calling this method, @see {@link #varargType} * * @param params an unmodifiable list of parameter types to be captured by this method, * excluding the receiver @@ -1344,11 +1345,11 @@ public List getParameterTypes() { } /** - * Computes the vararg type of this executable type and stores it in {@link varargType}. + * Computes the vararg type of this executable type and stores it in {@link #varargType}. * - *

      This method computes {@link varargType} using the {@link paramTypes} of this - * executable type. To use the {@link paramTypes} from different executable type, use {@link - * #computeVarargType(AnnotatedExecutableType)}. + *

      This method computes {@link #varargType} using the {@link #paramTypes} of this + * executable type. To use the {@link #paramTypes} from different executable type, use + * {@link #computeVarargType(AnnotatedTypeMirror.AnnotatedExecutableType)}. */ /*package-private*/ void computeVarargType() { computeVarargType(paramTypes); @@ -1356,7 +1357,7 @@ public List getParameterTypes() { /** * Computes the vararg type using the passed executable type and stores it in this {@link - * varargType}. + * #varargType}. * * @param annotatedExecutableType an AnnotatedExecutableType */ @@ -1367,7 +1368,7 @@ public List getParameterTypes() { /** * Helper function for {@link #computeVarargType()} and {@link - * #computeVarargType(AnnotatedExecutableType)}. + * #computeVarargType(AnnotatedTypeMirror.AnnotatedExecutableType)}. * * @param paramTypes the parameter types to determine the vararg type */ diff --git a/framework/src/main/java/org/checkerframework/framework/type/AnnotationClassLoader.java b/framework/src/main/java/org/checkerframework/framework/type/AnnotationClassLoader.java index b4af2eb77bf..233b42f66df 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/AnnotationClassLoader.java +++ b/framework/src/main/java/org/checkerframework/framework/type/AnnotationClassLoader.java @@ -553,7 +553,6 @@ private void loadBundledAnnotationClasses() { throw new BugInCF( "AnnotationClassLoader: cannot open the Jar file " + resourceURL.getFile()); } - } else if (resourceURL != null && resourceURL.getProtocol().contentEquals("file")) { // If the checker class file is found within the file system itself within some // directory (usually development build directories), then process the package as a file diff --git a/framework/src/main/java/org/checkerframework/framework/type/BoundsInitializer.java b/framework/src/main/java/org/checkerframework/framework/type/BoundsInitializer.java index 78f3ce86392..7ec310019a1 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/BoundsInitializer.java +++ b/framework/src/main/java/org/checkerframework/framework/type/BoundsInitializer.java @@ -374,7 +374,6 @@ public Void visitDeclared(AnnotatedDeclaredType type, Void aVoid) { @Override public Void visitIntersection(AnnotatedIntersectionType type, Void aVoid) { - if (intersections.containsKey(type.getUnderlyingType())) { return null; } @@ -393,7 +392,6 @@ public Void visitIntersection(AnnotatedIntersectionType type, Void aVoid) { @Override public Void visitUnion(AnnotatedUnionType type, Void aVoid) { - List alts = type.getAlternatives(); for (int i = 0; i < alts.size(); i++) { AnnotatedDeclaredType alt = alts.get(i); @@ -458,7 +456,6 @@ public Void visitNull(AnnotatedNullType type, Void aVoid) { public Void visitWildcard(AnnotatedWildcardType wildcard, Void aVoid) { if (wildcard.getSuperBoundField() == null) { initializeSuperBound(wildcard); - } else { throw new BugInCF( "Wildcard super field should not be initialized:%n" @@ -1195,7 +1192,6 @@ protected void replaceTypeInternal( @Override protected AnnotatedTypeMirror getTypeInternal(AnnotatedTypeMirror parent) { - AnnotatedTypeVariable parentAtv = (AnnotatedTypeVariable) parent; if (parentAtv.getLowerBoundField() != null) { return parentAtv.getLowerBoundField(); diff --git a/framework/src/main/java/org/checkerframework/framework/type/DefaultAnnotatedTypeFormatter.java b/framework/src/main/java/org/checkerframework/framework/type/DefaultAnnotatedTypeFormatter.java index 64f02980769..af7aac68aee 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/DefaultAnnotatedTypeFormatter.java +++ b/framework/src/main/java/org/checkerframework/framework/type/DefaultAnnotatedTypeFormatter.java @@ -474,7 +474,6 @@ public String visitWildcard(AnnotatedWildcardType type, Set sb.append("?"); if (!visiting.contains(type)) { - try { visiting.add(type); diff --git a/framework/src/main/java/org/checkerframework/framework/type/DefaultInferredTypesApplier.java b/framework/src/main/java/org/checkerframework/framework/type/DefaultInferredTypesApplier.java index 8dc8bb7cf23..e9551a21606 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/DefaultInferredTypesApplier.java +++ b/framework/src/main/java/org/checkerframework/framework/type/DefaultInferredTypesApplier.java @@ -74,7 +74,6 @@ private void apply( AnnotationMirror top) { AnnotationMirror primary = type.getAnnotationInHierarchy(top); if (inferred == null) { - if (primary == null) { // Type doesn't have a primary either, nothing to remove } else if (type.getKind() == TypeKind.TYPEVAR) { diff --git a/framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java b/framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java index 12592220cdc..0166487baa8 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java +++ b/framework/src/main/java/org/checkerframework/framework/type/DefaultTypeHierarchy.java @@ -1300,7 +1300,6 @@ protected boolean visitWildcard_Type( // If both have primary annotations then just check the primary annotations // as the bounds are the same. return isPrimarySubtype(subtype, supertype); - } else if (!subtypeHasAnno && !supertypeHasAnno && areEqualInHierarchy(subtype, supertype)) { diff --git a/framework/src/main/java/org/checkerframework/framework/type/EqualityAtmComparer.java b/framework/src/main/java/org/checkerframework/framework/type/EqualityAtmComparer.java index 20814ea6dd4..b07808acc4c 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/EqualityAtmComparer.java +++ b/framework/src/main/java/org/checkerframework/framework/type/EqualityAtmComparer.java @@ -43,7 +43,6 @@ protected boolean compare(AnnotatedTypeMirror type1, AnnotatedTypeMirror type2) if (type1 == type2) { return true; } - if (type1 == null || type2 == null) { return false; } diff --git a/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java b/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java index f1e43aa22b4..61dc17d5a01 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java +++ b/framework/src/main/java/org/checkerframework/framework/type/GenericAnnotatedTypeFactory.java @@ -648,7 +648,6 @@ public DefaultForTypeAnnotator getDefaultForTypeAnnotator() { */ @SuppressWarnings({"unchecked", "rawtypes"}) protected FlowAnalysis createFlowAnalysis() { - // Try to reflectively load the visitor. Class checkerClass = checker.getClass(); @@ -687,7 +686,6 @@ protected FlowAnalysis createFlowAnalysis() { // However, we ran into issues in callers of the method if we used that type. public TransferFunction createFlowTransferFunction( CFAbstractAnalysis analysis) { - // Try to reflectively load the visitor. Class checkerClass = checker.getClass(); @@ -996,7 +994,6 @@ public AnnotatedTypeMirror getResultingTypeOfConstructorMemberReference( */ public @Nullable AnnotationMirrorSet getAnnotationsFromJavaExpression( JavaExpression expr, Tree tree) { - // Look in the store if (CFAbstractStore.canInsertJavaExpression(expr)) { Store store = getStoreBefore(tree); @@ -1871,7 +1868,6 @@ public AnnotatedTypeMirror getAnnotatedTypeLhs(Tree lhsTree) { res = getAnnotatedType(lhsTree); // Value of shouldCache no longer used below, so no need to reset. break; - case MEMBER_SELECT: case ARRAY_ACCESS: res = getAnnotatedType(lhsTree); @@ -2659,11 +2655,9 @@ public final boolean isRelevant(AnnotatedTypeMirror tm) { * @return true if users can write type annotations from this type system on the given Java type */ protected boolean isRelevantImpl(TypeMirror tm) { - if (relevantJavaTypes == null) { return true; } - if (relevantJavaTypes.contains(tm)) { return true; } @@ -3110,14 +3104,12 @@ protected List getPreOrPostconditionAnnotations( AnnotatedTypeMirror declaredType, Analysis.BeforeOrAfter preOrPost, @Nullable List preconds) { - // Do not generate RequiresQualifier annotations for "this" or parameter expressions. if (preOrPost == BeforeOrAfter.BEFORE && ("this".equals(expression) || formalParameterPattern.matcher(expression).matches())) { return null; } - if (!qualifier.getElementValues().isEmpty()) { // @RequiresQualifier and @EnsuresQualifier do not yet support annotations with // elements/arguments. diff --git a/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java b/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java index 71225f28332..d61276dbe9d 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java +++ b/framework/src/main/java/org/checkerframework/framework/type/TypeFromExpressionVisitor.java @@ -123,7 +123,6 @@ public AnnotatedTypeMirror visitAnnotatedType(AnnotatedTypeTree tree, AnnotatedT @Override public AnnotatedTypeMirror visitTypeCast(TypeCastTree tree, AnnotatedTypeFactory f) { - // Use the annotated type of the type in the cast. return f.fromTypeTree(tree.getType()); } @@ -166,7 +165,6 @@ public AnnotatedTypeMirror visitLambdaExpression( @Override public AnnotatedTypeMirror visitAssignment(AssignmentTree tree, AnnotatedTypeFactory f) { - // Recurse on the type of the variable. return visit(tree.getVariable(), f); } @@ -319,7 +317,6 @@ public AnnotatedTypeMirror visitArrayAccess(ArrayAccessTree tree, AnnotatedTypeF @Override public AnnotatedTypeMirror visitNewArray(NewArrayTree tree, AnnotatedTypeFactory f) { - // Don't use fromTypeTree here, because tree.getType() is not an array type! AnnotatedArrayType result = (AnnotatedArrayType) f.type(tree); @@ -424,14 +421,12 @@ public AnnotatedTypeMirror visitMethodInvocation( @Override public AnnotatedTypeMirror visitParenthesized(ParenthesizedTree tree, AnnotatedTypeFactory f) { - // Recurse on the expression inside the parens. return visit(tree.getExpression(), f); } @Override public AnnotatedTypeMirror visitWildcard(WildcardTree tree, AnnotatedTypeFactory f) { - AnnotatedTypeMirror bound = visit(tree.getBound(), f); AnnotatedTypeMirror result = f.type(tree); diff --git a/framework/src/main/java/org/checkerframework/framework/type/TypeFromTypeTreeVisitor.java b/framework/src/main/java/org/checkerframework/framework/type/TypeFromTypeTreeVisitor.java index 75fd7891b99..44fa2096a3b 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/TypeFromTypeTreeVisitor.java +++ b/framework/src/main/java/org/checkerframework/framework/type/TypeFromTypeTreeVisitor.java @@ -115,7 +115,6 @@ public AnnotatedTypeMirror visitArrayType(ArrayTypeTree tree, AnnotatedTypeFacto @Override public AnnotatedTypeMirror visitParameterizedType( ParameterizedTypeTree tree, AnnotatedTypeFactory f) { - ClassSymbol baseType = (ClassSymbol) TreeUtils.elementFromTree(tree.getType()); updateWildcardBounds(tree.getTypeArguments(), baseType.getTypeParameters()); @@ -193,7 +192,6 @@ public AnnotatedTypeMirror visitPrimitiveType(PrimitiveTypeTree tree, AnnotatedT @Override public AnnotatedTypeVariable visitTypeParameter( TypeParameterTree tree, @FindDistinct AnnotatedTypeFactory f) { - List bounds = new ArrayList<>(tree.getBounds().size()); for (Tree t : tree.getBounds()) { AnnotatedTypeMirror bound; @@ -229,9 +227,7 @@ public AnnotatedTypeVariable visitTypeParameter( @Override public AnnotatedTypeMirror visitWildcard(WildcardTree tree, AnnotatedTypeFactory f) { - AnnotatedTypeMirror bound = visit(tree.getBound(), f); - AnnotatedTypeMirror result = f.type(tree); assert result instanceof AnnotatedWildcardType; @@ -318,7 +314,6 @@ private AnnotatedTypeVariable getTypeVariableFromDeclaration( */ private int findIndex( List typeParameters, TypeParameterElement type) { - TypeVariable typeVariable = (TypeVariable) type.asType(); for (int i = 0; i < typeParameters.size(); i++) { @@ -332,7 +327,6 @@ private int findIndex( @Override public AnnotatedTypeMirror visitIdentifier(IdentifierTree tree, AnnotatedTypeFactory f) { - AnnotatedTypeMirror type = f.type(tree); if (type.getKind() == TypeKind.TYPEVAR) { @@ -344,7 +338,6 @@ public AnnotatedTypeMirror visitIdentifier(IdentifierTree tree, AnnotatedTypeFac @Override public AnnotatedTypeMirror visitMemberSelect(MemberSelectTree tree, AnnotatedTypeFactory f) { - AnnotatedTypeMirror type = f.type(tree); if (type.getKind() == TypeKind.TYPEVAR) { diff --git a/framework/src/main/java/org/checkerframework/framework/type/TypeVariableSubstitutor.java b/framework/src/main/java/org/checkerframework/framework/type/TypeVariableSubstitutor.java index 67ce1c2671a..6ca013fb464 100644 --- a/framework/src/main/java/org/checkerframework/framework/type/TypeVariableSubstitutor.java +++ b/framework/src/main/java/org/checkerframework/framework/type/TypeVariableSubstitutor.java @@ -150,7 +150,6 @@ protected T makeCopy(T original) { public AnnotatedTypeMirror visitTypeVariable( AnnotatedTypeVariable original, IdentityHashMap originalToCopy) { - if (visitingExecutableTypeParam) { // AnnotatedExecutableType differs from AnnotatedDeclaredType in that its list of // type parameters cannot be adapted in place since the @@ -161,7 +160,6 @@ public AnnotatedTypeMirror visitTypeVariable( // AnnotatedTypeVariable's will remain visitingExecutableTypeParam = false; return super.visitTypeVariable(original, originalToCopy); - } else { Element typeVarElem = original.getUnderlyingType().asElement(); if (elementToArgMap.containsKey(typeVarElem)) { diff --git a/framework/src/test/java/viewpointtest/quals/A.java b/framework/src/test/java/viewpointtest/quals/A.java index 3578a501ec2..8bee242159e 100644 --- a/framework/src/test/java/viewpointtest/quals/A.java +++ b/framework/src/test/java/viewpointtest/quals/A.java @@ -8,6 +8,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** The A qualifier. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) diff --git a/framework/src/test/java/viewpointtest/quals/B.java b/framework/src/test/java/viewpointtest/quals/B.java index 1fc36246149..957096b3c9f 100644 --- a/framework/src/test/java/viewpointtest/quals/B.java +++ b/framework/src/test/java/viewpointtest/quals/B.java @@ -8,6 +8,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** The B qualifier. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) diff --git a/framework/src/test/java/viewpointtest/quals/Bottom.java b/framework/src/test/java/viewpointtest/quals/Bottom.java index 753d57fad71..1cdcd149e9d 100644 --- a/framework/src/test/java/viewpointtest/quals/Bottom.java +++ b/framework/src/test/java/viewpointtest/quals/Bottom.java @@ -10,6 +10,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** The Bottom qualifier. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) diff --git a/framework/src/test/java/viewpointtest/quals/Lost.java b/framework/src/test/java/viewpointtest/quals/Lost.java index ade8ff1d01b..38e215c5293 100644 --- a/framework/src/test/java/viewpointtest/quals/Lost.java +++ b/framework/src/test/java/viewpointtest/quals/Lost.java @@ -9,11 +9,11 @@ import java.lang.annotation.Target; /** - * The {@link Lost} qualifier indicates that a relationship cannot be expressed. It is the result of + * The Lost qualifier indicates that a relationship cannot be expressed. It is the result of * viewpoint adaptation that combines {@link Top} and {@link ReceiverDependentQual}. * - *

      It is not reflexive in the subtyping relationship and the only subtype for {@link Lost} is - * {@link Bottom}. + *

      It is not reflexive in the subtyping relationship and the only subtype for Lost is {@link + * Bottom}. */ @Documented @Retention(RetentionPolicy.RUNTIME) diff --git a/framework/src/test/java/viewpointtest/quals/PolyVP.java b/framework/src/test/java/viewpointtest/quals/PolyVP.java index 0904ee3f094..c89a201cc80 100644 --- a/framework/src/test/java/viewpointtest/quals/PolyVP.java +++ b/framework/src/test/java/viewpointtest/quals/PolyVP.java @@ -8,6 +8,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** The PolyVP qualifier is a polymorphic qualifier in this hierarchy. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) diff --git a/framework/src/test/java/viewpointtest/quals/ReceiverDependentQual.java b/framework/src/test/java/viewpointtest/quals/ReceiverDependentQual.java index 434561e183d..cb8adfc0635 100644 --- a/framework/src/test/java/viewpointtest/quals/ReceiverDependentQual.java +++ b/framework/src/test/java/viewpointtest/quals/ReceiverDependentQual.java @@ -8,6 +8,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** The ReceiverDependentQual qualifier. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) diff --git a/framework/src/test/java/viewpointtest/quals/Top.java b/framework/src/test/java/viewpointtest/quals/Top.java index 84b39223cdc..e98647e51f1 100644 --- a/framework/src/test/java/viewpointtest/quals/Top.java +++ b/framework/src/test/java/viewpointtest/quals/Top.java @@ -9,6 +9,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** The Top qualifier. */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER}) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e2847c82004..cea7a793a84 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6d6b1..f3b75f3b0d4 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java index d825b9c9202..eb57f65d855 100644 --- a/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java +++ b/javacutil/src/main/java/org/checkerframework/javacutil/TreeUtils.java @@ -21,6 +21,7 @@ import com.sun.source.tree.MethodTree; import com.sun.source.tree.NewArrayTree; import com.sun.source.tree.NewClassTree; +import com.sun.source.tree.PackageTree; import com.sun.source.tree.ParameterizedTypeTree; import com.sun.source.tree.ParenthesizedTree; import com.sun.source.tree.PrimitiveTypeTree; @@ -93,6 +94,7 @@ import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Name; import javax.lang.model.element.NestingKind; +import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; import javax.lang.model.type.ExecutableType; @@ -285,6 +287,20 @@ public static boolean isSelfAccess(ExpressionTree tree) { // This section of the file groups methods by their receiver type; that is, it puts all // `elementFrom*(FooTree)` methods together. + /** + * Return the package element corresponding to the given package declaration. + * + * @param tree package declaration + * @return the package element for the given package + */ + public static PackageElement elementFromDeclaration(PackageTree tree) { + PackageElement result = (PackageElement) TreeInfo.symbolFor((JCTree) tree); + if (result == null) { + throw new BugInCF("null element for package tree %s", tree); + } + return result; + } + // TODO: Document when this may return null. /** * Returns the type element corresponding to the given class declaration.