Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retain nullability annotations when building override versions of functions. #4474

Merged
merged 1 commit into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions java/dagger/internal/codegen/xprocessing/JavaPoetExt.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@

package dagger.internal.codegen.xprocessing;

import static dagger.internal.codegen.extension.DaggerStreams.toImmutableSet;
import static dagger.internal.codegen.xprocessing.XElements.getSimpleName;

import androidx.room.compiler.processing.XExecutableParameterElement;
import androidx.room.compiler.processing.XType;
import androidx.room.compiler.processing.XTypeElement;
import com.google.common.collect.ImmutableSet;
import com.squareup.javapoet.AnnotationSpec;
import com.squareup.javapoet.ParameterSpec;
import com.squareup.javapoet.TypeSpec;

Expand Down Expand Up @@ -53,5 +56,23 @@ public static ParameterSpec toParameterSpec(XExecutableParameterElement param) {
return ParameterSpec.builder(param.getType().getTypeName(), param.getJvmName()).build();
}

public static ParameterSpec toParameterSpec(
XExecutableParameterElement parameter, XType parameterType) {
Nullability nullability = Nullability.of(parameter);
ImmutableSet<AnnotationSpec> typeUseNullableAnnotations =
nullability.typeUseNullableAnnotations().stream()
.map(annotation -> AnnotationSpec.builder(annotation).build())
.collect(toImmutableSet());
ImmutableSet<AnnotationSpec> nonTypeUseNullableAnnotations =
nullability.nonTypeUseNullableAnnotations().stream()
.map(annotation -> AnnotationSpec.builder(annotation).build())
.collect(toImmutableSet());
return ParameterSpec.builder(
parameterType.getTypeName().annotated(typeUseNullableAnnotations.asList()),
parameter.getJvmName())
.addAnnotations(nonTypeUseNullableAnnotations)
.build();
}

private JavaPoetExt() {}
}
10 changes: 5 additions & 5 deletions java/dagger/internal/codegen/xprocessing/MethodSpecs.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@

package dagger.internal.codegen.xprocessing;

import static dagger.internal.codegen.xprocessing.JavaPoetExt.toParameterSpec;
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.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. */
Expand All @@ -46,9 +46,9 @@ 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);
XType parameterType = methodType.getParameterTypes().get(i);
builder.addParameter(toParameterSpec(parameter, parameterType));
}
method.getThrownTypes().stream().map(XType::getTypeName).forEach(builder::addException);
return builder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 =
Expand Down
Original file line number Diff line number Diff line change
@@ -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) {


}
}
}
Original file line number Diff line number Diff line change
@@ -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) {


}
}
}
Original file line number Diff line number Diff line change
@@ -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) {


}
}
}
Original file line number Diff line number Diff line change
@@ -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) {


}
}
}
Loading