diff --git a/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java b/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java index a79a3e90733..22a00f75440 100644 --- a/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java +++ b/java/dagger/hilt/android/processor/internal/androidentrypoint/Generators.java @@ -28,6 +28,7 @@ import androidx.room.compiler.processing.XAnnotation; import androidx.room.compiler.processing.XConstructorElement; import androidx.room.compiler.processing.XElement; +import androidx.room.compiler.processing.XType; import androidx.room.compiler.processing.XTypeElement; import androidx.room.compiler.processing.XVariableElement; import com.google.common.base.Preconditions; @@ -130,13 +131,24 @@ private static Optional getNullableAnnotationSpec(XElement eleme return Optional.empty(); } + /** TODO(cpovirk): */ + private static TypeName withAnyNullnessAnnotation(XType type) { + for (XAnnotation annotation : type.getAllAnnotations()) { + if (annotation.getClassName().simpleName().contentEquals("Nullable")) { + return type.getTypeName().annotated(toAnnotationSpec(annotation)); + } + } + return type.getTypeName(); + } + /** * Returns a ParameterSpec of the input parameter, @Nullable annotated if existing in original * (this does not handle Nullable type annotations). */ private static ParameterSpec getParameterSpecWithNullable(XVariableElement parameter) { ParameterSpec.Builder builder = - ParameterSpec.builder(parameter.getType().getTypeName(), getSimpleName(parameter)); + ParameterSpec.builder( + withAnyNullnessAnnotation(parameter.getType()), getSimpleName(parameter)); getNullableAnnotationSpec(parameter).ifPresent(builder::addAnnotation); return builder.build(); } diff --git a/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java b/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java index 4fbec681b8c..5af0e622674 100644 --- a/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java +++ b/javatests/dagger/hilt/android/processor/internal/GeneratorsTest.java @@ -140,6 +140,51 @@ public void copyConstructorParametersConvertsAndroidInternalNullableToExternal() }); } + // This is a regression test for b/382104423 + @Test + public void typeUseNullableCopiedFromSuperConstructor() { + Source baseView = + HiltCompilerTests.javaSource( + "test.BaseView", + "package test;", + "", + "import android.content.Context;", + "import android.util.AttributeSet;", + "import android.view.View;", + "import org.jspecify.annotations.Nullable;", + "", + "public class BaseView extends View {", + " public BaseView(Context context, @Nullable AttributeSet attrs) {", + " super(context, attrs);", + " }", + "}"); + Source myView = + HiltCompilerTests.javaSource( + "test.MyView", + "package test;", + "", + "import android.content.Context;", + "import android.util.AttributeSet;", + "import android.view.View;", + "import dagger.hilt.android.AndroidEntryPoint;", + "import org.jspecify.annotations.Nullable;", + "", + "@AndroidEntryPoint(BaseView.class)", + "public class MyView extends Hilt_MyView {", + " public MyView(Context context, @Nullable AttributeSet attrs) {", + " super(context, attrs);", + " }", + "}"); + HiltCompilerTests.hiltCompiler(baseView, myView) + .compile( + subject -> { + subject.hasErrorCount(0); + StringSubject stringSubject = + subject.generatedSourceFileWithPath("test/Hilt_MyView.java"); + stringSubject.contains("org.jspecify.annotations.Nullable"); + }); + } + // This is a regression test for https://github.com/google/dagger/issues/3296 @Test public void isRestrictedApiConstructorWithPrimitiveParameterTest() {