diff --git a/README.md b/README.md index 13769974d7..ee37823b11 100644 --- a/README.md +++ b/README.md @@ -80,13 +80,13 @@ Unlike other annotation processors above, Lombok modifies the in-memory AST of t We do not particularly recommend using NullAway with Lombok. However, NullAway encodes some knowledge of common Lombok annotations and we do try for best-effort compatibility. In particular, common usages like `@lombok.Builder` and `@Data` classes should be supported. -In order for NullAway to successfully detect Lombok generated code within the in-memory Java AST, the following configuration option must be passed to Lombok as part of an applicable `lombok.config` file: +For the best compatibility with NullAway, add the following configuration options to an applicable `lombok.config` file: ``` -addLombokGeneratedAnnotation +lombok.addLombokGeneratedAnnotation = true +lombok.addNullAnnotations = ``` - -This causes Lombok to add `@lombok.Generated` to the methods/classes it generates. NullAway will ignore (i.e. not check) the implementation of this generated code, treating it as unannotated. +See the [Lombok configuration documentation](https://projectlombok.org/features/configuration) for more details. The `addLombokGeneratedAnnotation` option causes Lombok to add `@lombok.Generated` to the methods/classes it generates. NullAway will ignore (i.e. not check) the implementation of this generated code, treating it as unannotated. The `addNullAnnotations` options causes Lombok to add nullability annotations to its generated code, which can remove certain NullAway false positives. In particular, with this option enabled, Lombok adds a `@Nullable` annotation to the parameter of every generated `equals()` method, and then NullAway will not warn if a `@Nullable` argument is passed to such a method. ## Code Example diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 26fc151bd8..1786ed3790 100755 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -109,7 +109,7 @@ def test = [ rxjava2 : "io.reactivex.rxjava2:rxjava:2.1.2", commonsLang3 : "org.apache.commons:commons-lang3:3.8.1", commonsLang : "commons-lang:commons-lang:2.6", - lombok : "org.projectlombok:lombok:1.18.24", + lombok : "org.projectlombok:lombok:1.18.30", springBeans : "org.springframework:spring-beans:5.3.7", springContext : "org.springframework:spring-context:5.3.7", grpcCore : "io.grpc:grpc-core:1.15.1", // Should upgrade, but this matches our guava version diff --git a/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java b/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java index 7d76611b9d..7069497800 100644 --- a/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java +++ b/nullaway/src/main/java/com/uber/nullaway/handlers/LombokHandler.java @@ -86,26 +86,4 @@ public Nullness onOverrideMethodReturnNullability( } return returnNullness; } - - /** - * Mark the first argument of Lombok-generated {@code equals} methods as {@code @Nullable}, since - * Lombok does not generate the annotation. - */ - @Override - public Nullness[] onOverrideMethodInvocationParametersNullability( - VisitorState state, - Symbol.MethodSymbol methodSymbol, - boolean isAnnotated, - Nullness[] argumentPositionNullness) { - if (ASTHelpers.hasAnnotation(methodSymbol, LOMBOK_GENERATED_ANNOTATION_NAME, state)) { - // We assume that Lombok-generated equals methods with a single argument override - // Object.equals and are not an overload. - if (methodSymbol.getSimpleName().contentEquals("equals") - && methodSymbol.params().size() == 1) { - // The parameter is not annotated with @Nullable, but it should be. - argumentPositionNullness[0] = Nullness.NULLABLE; - } - } - return argumentPositionNullness; - } } diff --git a/test-java-lib-lombok/build.gradle b/test-java-lib-lombok/build.gradle index c70f54828d..0652b7e4ac 100644 --- a/test-java-lib-lombok/build.gradle +++ b/test-java-lib-lombok/build.gradle @@ -44,3 +44,8 @@ tasks.withType(JavaCompile) { "--add-opens=jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED" ] } + +// Needed so that compilation re-runs if the lombok.config is changed +tasks.named('compileJava') { + inputs.file('lombok.config') +} diff --git a/test-java-lib-lombok/lombok.config b/test-java-lib-lombok/lombok.config index df71bb6a0f..e94be7803d 100644 --- a/test-java-lib-lombok/lombok.config +++ b/test-java-lib-lombok/lombok.config @@ -1,2 +1,3 @@ config.stopBubbling = true lombok.addLombokGeneratedAnnotation = true +lombok.addNullAnnotations = javax