kelloggm / checkerframework-gradle-plugin

Gradle plugin to use the Checker Framework for Java
Apache License 2.0
66 stars 15 forks source link

Allow different compilation tasks to have their own checkerframework configuration options #110

Closed vlsi closed 4 years ago

vlsi commented 4 years ago

Use case: I want to ignore initialization.fields.uninitialized for my unit-test code. The problem with initialization.fields.uninitialized is unit-tests often initialize fields in @Before/@After methods.

Unfortunately, it looks like the current plugin code has a single configuration container only, so all the options apply to both compileJava and compileTestJava :(

I know I can add @SuppressWarning on a per-class level, however, that does not look right as I would have to add the suppression for each and every test class.

--

I'm adding checkerframework to pgjdbc: https://github.com/pgjdbc/pgjdbc/pull/1814

kelloggm commented 4 years ago

To solve your immediate issue, if you don't want to check tests at all you can use the excludeTests = true configuration option for the plugin, which causes the plugin not to be applied to test compilation targets. When first annotating a project (which it sounds like you're doing), I almost always disable checking tests until I've finished annotating the main sources.

Beyond that, I'm hesitant to add per-target configuration. I'm concerned that it would 1) greatly complicate the plugin code, and 2) make configuring the plugin even more verbose than it already is.

vlsi commented 4 years ago

I have already annotated the main code, and it passes the verification.

I do want to verify test code as it helps to capture corner cases

kelloggm commented 4 years ago

In that case, I think the best you'll be able in the near term to do is suppressing warnings, as you suggested above.

You might consider filing an issue with the main Checker Framework repository about the false positives with JUnit @Before/@After methods, though. Someone there might have encountered a similar issue before while using the nullness checker, and there might be a simple solution that doesn't require a change in configuration. (Or, they might be able to enhance the analysis to take into account @Before methods when deciding whether a field has been initialized.)

vlsi commented 4 years ago

1) greatly complicate the plugin code

I'm not sure that would significantly complicate code.

There might be a per-task extension (e.g. like Gradle's jacoco ) which would override the global values.

As a workaround I've added the following:

afterEvaluate {
    tasks.withType<JavaCompile>()
        .matching { "test" in it.name.toLowerCase() }
        .configureEach {
            options.compilerArgs.add(
                listOf(
                    "initialization.fields.uninitialized"
                ).joinToString(",", prefix="-AsuppressWarnings=")
            )
        }
}
wmdietl commented 4 years ago

There already is an issue for JUnit initialization: https://github.com/typetools/checker-framework/issues/1525