Skip to content

Commit 4bedb4b

Browse files
Chang-EricDagger Team
authored andcommitted
Support nullable type annotations with a flag.
Fixes #5165. RELNOTES=Support nullable type annotations when using the flag `-Adagger.nullableTypeAnnotations=enabled`. Fixes #5165. PiperOrigin-RevId: 933839515
1 parent 445e6f0 commit 4bedb4b

12 files changed

Lines changed: 365 additions & 4 deletions

File tree

dagger-compiler/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ gen_maven_artifact(
5252
"//dagger-compiler/main/java/dagger/internal/codegen/validation",
5353
"//dagger-compiler/main/java/dagger/internal/codegen/writing",
5454
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing",
55+
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing:nullability",
5556
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing:xpoet",
5657
],
5758
artifact_target_maven_deps = [

dagger-compiler/main/java/dagger/internal/codegen/binding/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ java_library(
3030
"//dagger-compiler/main/java/dagger/internal/codegen/kotlin",
3131
"//dagger-compiler/main/java/dagger/internal/codegen/model",
3232
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing",
33+
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing:nullability",
3334
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing:xpoet",
3435
"//dagger-runtime/main/java/dagger:core",
3536
"//dagger-spi",

dagger-compiler/main/java/dagger/internal/codegen/compileroption/CompilerOptions.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
package dagger.internal.codegen.compileroption;
1818

19+
import androidx.room3.compiler.processing.XProcessingEnv;
1920
import androidx.room3.compiler.processing.XTypeElement;
21+
import com.google.common.base.Ascii;
2022
import javax.tools.Diagnostic;
2123

2224
/** A collection of options that dictate how the compiler will run. */
@@ -168,4 +170,34 @@ public int keysPerComponentShard(XTypeElement component) {
168170
* boundaries at compile time (for Maps) and runtime (for Sets).
169171
*/
170172
public abstract boolean mapMultibindingDuplicateDetectionFix();
173+
174+
/**
175+
* Returns {@code true} if Dagger should also look for nullable type annotations.
176+
*
177+
* Note that when disabled, Dagger doesn't disallow usage of nullable type annotations. Instead,
178+
* the behavior is simply that Dagger does not look for them, so types marked with nullable type
179+
* annotations may appear to be non-nullable.
180+
*/
181+
public abstract boolean nullableTypeAnnotations();
182+
183+
/**
184+
* Returns {@code true} if Dagger should also look for nullable type annotations.
185+
*
186+
* @deprecated use {@link CompilerOptions#nullableTypeAnnotations()}. This method should only be
187+
* used for legacy code which requires accessing this flag from static methods that don't
188+
* easily have access to an instance of {@link CompilerOptions}.
189+
*/
190+
@Deprecated
191+
public static boolean nullableTypeAnnotations(XProcessingEnv processingEnv) {
192+
String optionName =
193+
ProcessingEnvironmentCompilerOptions.Feature.NULLABLE_TYPE_ANNOTATIONS.toString();
194+
String defaultValue =
195+
ProcessingEnvironmentCompilerOptions.Feature.NULLABLE_TYPE_ANNOTATIONS
196+
.defaultValue().name();
197+
String optionValue =
198+
processingEnv.getOptions().containsKey(optionName)
199+
? processingEnv.getOptions().get(optionName)
200+
: defaultValue;
201+
return Ascii.equalsIgnoreCase(optionValue, FeatureStatus.ENABLED.name());
202+
}
171203
}

dagger-compiler/main/java/dagger/internal/codegen/compileroption/ProcessingEnvironmentCompilerOptions.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.IGNORE_PROVISION_KEY_WILDCARDS;
3333
import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.INCLUDE_STACKTRACE_WITH_DEFERRED_ERROR_MESSAGES;
3434
import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.MAP_MULTIBINDING_DUPLICATE_DETECTION_FIX;
35+
import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.NULLABLE_TYPE_ANNOTATIONS;
3536
import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.PLUGINS_VISIT_FULL_BINDING_GRAPHS;
3637
import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.STRICT_MULTIBINDING_VALIDATION;
3738
import static dagger.internal.codegen.compileroption.ProcessingEnvironmentCompilerOptions.Feature.STRICT_SUPERFICIAL_VALIDATION;
@@ -216,6 +217,11 @@ public boolean mapMultibindingDuplicateDetectionFix() {
216217
return isEnabled(MAP_MULTIBINDING_DUPLICATE_DETECTION_FIX);
217218
}
218219

220+
@Override
221+
public boolean nullableTypeAnnotations() {
222+
return isEnabled(NULLABLE_TYPE_ANNOTATIONS);
223+
}
224+
219225
@Override
220226
public int keysPerComponentShard(XTypeElement component) {
221227
if (options.containsKey(KEYS_PER_COMPONENT_SHARD)) {
@@ -357,7 +363,9 @@ enum Feature implements EnumOption<FeatureStatus> {
357363

358364
VALIDATE_TRANSITIVE_COMPONENT_DEPENDENCIES(ENABLED),
359365

360-
MAP_MULTIBINDING_DUPLICATE_DETECTION_FIX(DISABLED);
366+
MAP_MULTIBINDING_DUPLICATE_DETECTION_FIX(DISABLED),
367+
368+
NULLABLE_TYPE_ANNOTATIONS;
361369

362370
final FeatureStatus defaultValue;
363371

dagger-compiler/main/java/dagger/internal/codegen/javac/JavacPluginCompilerOptions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,4 +145,9 @@ public boolean ignoreProvisionKeyWildcards() {
145145
public boolean mapMultibindingDuplicateDetectionFix() {
146146
return false;
147147
}
148+
149+
@Override
150+
public boolean nullableTypeAnnotations() {
151+
return false;
152+
}
148153
}

dagger-compiler/main/java/dagger/internal/codegen/validation/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ java_library(
3131
"//dagger-compiler/main/java/dagger/internal/codegen/kotlin",
3232
"//dagger-compiler/main/java/dagger/internal/codegen/model",
3333
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing",
34+
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing:nullability",
3435
"//dagger-runtime/main/java/dagger:core",
3536
"//dagger-spi",
3637
"//third_party/java/auto:value",

dagger-compiler/main/java/dagger/internal/codegen/writing/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ java_library(
3030
"//dagger-compiler/main/java/dagger/internal/codegen/compileroption",
3131
"//dagger-compiler/main/java/dagger/internal/codegen/model",
3232
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing",
33+
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing:nullability",
3334
"//dagger-compiler/main/java/dagger/internal/codegen/xprocessing:xpoet",
3435
"//dagger-runtime/main/java/dagger:core",
3536
"//dagger-spi",

dagger-compiler/main/java/dagger/internal/codegen/xprocessing/BUILD

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ load("//tools:bazel_compat.bzl", "compat_kt_jvm_library")
2020

2121
package(default_visibility = ["//dagger-compiler:internal"])
2222

23+
NULLABILITY_SRCS = [
24+
"Nullability.java",
25+
]
26+
2327
XPOET_SRCS = [
2428
"Accessibility.java",
2529
"NullableTypeNames.java",
@@ -33,10 +37,25 @@ XPOET_SRCS = [
3337
"XTypeSpecs.java",
3438
]
3539

40+
java_library(
41+
name = "nullability",
42+
srcs = NULLABILITY_SRCS,
43+
deps = [
44+
":xprocessing",
45+
"//dagger-compiler/main/java/dagger/internal/codegen/compileroption",
46+
"//dagger-spi",
47+
"//third_party/java/auto:value",
48+
"//third_party/java/guava/base",
49+
"//third_party/java/guava/collect",
50+
"//third_party/java/javapoet",
51+
],
52+
)
53+
3654
java_library(
3755
name = "xpoet",
3856
srcs = XPOET_SRCS,
3957
deps = [
58+
":nullability",
4059
":xprocessing",
4160
"//dagger-compiler/main/java/dagger/internal/codegen/compileroption",
4261
"//dagger-spi",
@@ -57,7 +76,7 @@ compat_kt_jvm_library(
5776
"*.java",
5877
"*.kt",
5978
],
60-
exclude = XPOET_SRCS,
79+
exclude = XPOET_SRCS + NULLABILITY_SRCS,
6180
),
6281
exports = [
6382
":xprocessing-lib",

dagger-compiler/main/java/dagger/internal/codegen/xprocessing/Nullability.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import static androidx.room3.compiler.processing.XElementKt.isMethod;
2020
import static androidx.room3.compiler.processing.XElementKt.isVariableElement;
21+
import static androidx.room3.compiler.processing.compat.XConverters.getProcessingEnv;
2122
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList;
2223
import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
2324
import static dagger.internal.codegen.xprocessing.XElements.asMethod;
@@ -36,6 +37,7 @@
3637
import com.squareup.javapoet.AnnotationSpec;
3738
import com.squareup.javapoet.ParameterizedTypeName;
3839
import com.squareup.javapoet.TypeName;
40+
import dagger.internal.codegen.compileroption.CompilerOptions;
3941
import java.util.Optional;
4042

4143
/**
@@ -57,8 +59,12 @@ public abstract class Nullability {
5759
public static Nullability of(XElement element) {
5860
ImmutableSet<XClassName> nonTypeUseNullableAnnotations = getNullableAnnotations(element);
5961
Optional<XType> type = getType(element);
60-
ImmutableSet<XClassName> typeUseNullableAnnotations =
61-
ImmutableSet.of();
62+
ImmutableSet<XClassName> typeUseNullableAnnotations;
63+
if (CompilerOptions.nullableTypeAnnotations(getProcessingEnv(element))) {
64+
typeUseNullableAnnotations = type.map(Nullability::getNullableAnnotations).orElse(ImmutableSet.of());
65+
} else {
66+
typeUseNullableAnnotations = ImmutableSet.of();
67+
}
6268
boolean isKotlinTypeNullable =
6369
// Note: Technically, it isn't possible for Java sources to have nullable types like in
6470
// Kotlin sources, but for some reason KSP treats certain types as nullable if they have a

javatests/dagger/functional/jdk8/BUILD

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,27 @@ GenJavaTests(
6464
"//third_party/java/truth",
6565
],
6666
)
67+
68+
GenJavaLibrary(
69+
name = "type_use_nullability_classes",
70+
srcs = ["TypeUseNullabilityClasses.java"],
71+
javacopts = DOCLINT_HTML_AND_SYNTAX,
72+
deps = [
73+
"//third_party/java/dagger",
74+
],
75+
)
76+
77+
# TODO(b/203233586): Replace with GenJavaTest
78+
GenJavaTests(
79+
name = "TypeUseNullabilityTest",
80+
srcs = ["TypeUseNullabilityTest.java"],
81+
gen_library_deps = [":type_use_nullability_classes"],
82+
javacopts = DOCLINT_HTML_AND_SYNTAX + ["-Adagger.nullableTypeAnnotations=ENABLED"],
83+
deps = [
84+
"//third_party/java/dagger",
85+
"//third_party/java/guava/base",
86+
"//third_party/java/guava/collect",
87+
"//third_party/java/junit",
88+
"//third_party/java/truth",
89+
],
90+
)

0 commit comments

Comments
 (0)