From 33e7dd7bcc8f693e21ea8903a1c7b86b4cb46aca Mon Sep 17 00:00:00 2001 From: Dagger Team <java-team-github-bot@google.com> Date: Thu, 26 Sep 2024 11:28:02 -0700 Subject: [PATCH] Retain nullability annotations when building override versions of functions. RELNOTES=n/a PiperOrigin-RevId: 679227064 --- .../codegen/xprocessing/MethodSpecs.java | 17 ++++++-- .../ComponentRequirementFieldTest.java | 39 +++++++++++++++++ ...ance_DEFAULT_MODE_test.DaggerTestComponent | 42 +++++++++++++++++++ ...ce_FAST_INIT_MODE_test.DaggerTestComponent | 42 +++++++++++++++++++ ...ance_DEFAULT_MODE_test.DaggerTestComponent | 42 +++++++++++++++++++ ...ce_FAST_INIT_MODE_test.DaggerTestComponent | 42 +++++++++++++++++++ 6 files changed, 220 insertions(+), 4 deletions(-) create mode 100644 javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_DEFAULT_MODE_test.DaggerTestComponent create mode 100644 javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent create mode 100644 javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_DEFAULT_MODE_test.DaggerTestComponent create mode 100644 javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent diff --git a/java/dagger/internal/codegen/xprocessing/MethodSpecs.java b/java/dagger/internal/codegen/xprocessing/MethodSpecs.java index cc8c2f45915..7931b1a39e2 100644 --- a/java/dagger/internal/codegen/xprocessing/MethodSpecs.java +++ b/java/dagger/internal/codegen/xprocessing/MethodSpecs.java @@ -16,15 +16,17 @@ package dagger.internal.codegen.xprocessing; +import static dagger.internal.codegen.extension.DaggerStreams.toImmutableList; import static javax.lang.model.element.Modifier.PROTECTED; import static javax.lang.model.element.Modifier.PUBLIC; +import androidx.room.compiler.processing.XExecutableParameterElement; import androidx.room.compiler.processing.XMethodElement; import androidx.room.compiler.processing.XMethodType; import androidx.room.compiler.processing.XType; +import com.squareup.javapoet.AnnotationSpec; import com.squareup.javapoet.MethodSpec; import com.squareup.javapoet.ParameterSpec; -import com.squareup.javapoet.TypeName; // TODO(bcorso): Consider moving these methods into XProcessing library. /** A utility class for {@link MethodSpec} helper methods. */ @@ -46,9 +48,16 @@ public static MethodSpec.Builder overriding(XMethodElement method, XType owner) builder.addModifiers(PROTECTED); } for (int i = 0; i < methodType.getParameterTypes().size(); i++) { - String parameterName = method.getParameters().get(i).getJvmName(); - TypeName parameterType = methodType.getParameterTypes().get(i).getTypeName(); - builder.addParameter(ParameterSpec.builder(parameterType, parameterName).build()); + XExecutableParameterElement parameter = method.getParameters().get(i); + builder.addParameter( + ParameterSpec.builder( + methodType.getParameterTypes().get(i).getTypeName(), parameter.getJvmName()) + // Retain nullability annotations on parameters. + .addAnnotations( + Nullability.of(parameter).nullableAnnotations().stream() + .map(annotation -> AnnotationSpec.builder(annotation).build()) + .collect(toImmutableList())) + .build()); } method.getThrownTypes().stream().map(XType::getTypeName).forEach(builder::addException); return builder; diff --git a/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java b/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java index 65929e7d926..dfe74bb61b6 100644 --- a/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java +++ b/javatests/dagger/internal/codegen/ComponentRequirementFieldTest.java @@ -33,6 +33,13 @@ public static Collection<Object[]> parameters() { return CompilerMode.TEST_PARAMETERS; } + private static final Source NON_TYPE_USE_NULLABLE = + CompilerTests.javaSource( + "test.Nullable", // force one-string-per-line format + "package test;", + "", + "public @interface Nullable {}"); + @Rule public GoldenFileRule goldenFileRule = new GoldenFileRule(); private final CompilerMode compilerMode; @@ -73,6 +80,38 @@ public void bindsInstance() throws Exception { }); } + @Test + public void testBindsNullableInstance() throws Exception { + Source component = + CompilerTests.javaSource( + "test.TestComponent", + "package test;", + "", + "import dagger.BindsInstance;", + "import dagger.Component;", + "", + "@Component", + "interface TestComponent {", + " @Component.Factory", + " interface Factory {", + " TestComponent create(@BindsInstance @Nullable Bar arg);", + "}", + "}"); + Source bar = + CompilerTests.javaSource( + "test.Bar", // force one-string-per-line format + "package test;", + "", + "interface Bar {}"); + CompilerTests.daggerCompiler(component, bar, NON_TYPE_USE_NULLABLE) + .withProcessingOptions(compilerMode.processorOptions()) + .compile( + subject -> { + subject.hasErrorCount(0); + subject.generatedSource(goldenFileRule.goldenSource("test/DaggerTestComponent")); + }); + } + @Test public void instanceModuleMethod() throws Exception { Source module = diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_DEFAULT_MODE_test.DaggerTestComponent new file mode 100644 index 00000000000..2fe8226e104 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_DEFAULT_MODE_test.DaggerTestComponent @@ -0,0 +1,42 @@ +package test; + +import dagger.internal.DaggerGenerated; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(Bar argParam) { + + + } + } +} \ No newline at end of file diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent new file mode 100644 index 00000000000..0feb62c2de5 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent @@ -0,0 +1,42 @@ +package test; + +import dagger.internal.DaggerGenerated; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(Bar argParam) { + + + } + } +} diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_DEFAULT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_DEFAULT_MODE_test.DaggerTestComponent new file mode 100644 index 00000000000..0feb62c2de5 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_DEFAULT_MODE_test.DaggerTestComponent @@ -0,0 +1,42 @@ +package test; + +import dagger.internal.DaggerGenerated; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(Bar argParam) { + + + } + } +} diff --git a/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent new file mode 100644 index 00000000000..0feb62c2de5 --- /dev/null +++ b/javatests/dagger/internal/codegen/goldens/ComponentRequirementFieldTest_testBindsTypeUseNullableInstance_FAST_INIT_MODE_test.DaggerTestComponent @@ -0,0 +1,42 @@ +package test; + +import dagger.internal.DaggerGenerated; +import javax.annotation.processing.Generated; + +@DaggerGenerated +@Generated( + value = "dagger.internal.codegen.ComponentProcessor", + comments = "https://dagger.dev" +) +@SuppressWarnings({ + "unchecked", + "rawtypes", + "KotlinInternal", + "KotlinInternalInJava", + "cast", + "deprecation" +}) +final class DaggerTestComponent { + private DaggerTestComponent() { + } + + public static TestComponent.Factory factory() { + return new Factory(); + } + + private static final class Factory implements TestComponent.Factory { + @Override + public TestComponent create(@Nullable Bar arg) { + return new TestComponentImpl(arg); + } + } + + private static final class TestComponentImpl implements TestComponent { + private final TestComponentImpl testComponentImpl = this; + + private TestComponentImpl(Bar argParam) { + + + } + } +}