Skip to content

Commit c9903cc

Browse files
Chang-EricDagger Team
authored andcommitted
Fix handling of Kotlin object Producer modules so that @JvmStatic isn't required
RELNOTES=n/a PiperOrigin-RevId: 644066003
1 parent cb76f99 commit c9903cc

File tree

4 files changed

+182
-7
lines changed

4 files changed

+182
-7
lines changed

java/dagger/internal/codegen/writing/ProducerFactoryGenerator.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -314,25 +314,34 @@ private MethodSpec callProducesMethod(ProductionBinding binding, FactoryFields f
314314
methodBuilder.addAnnotation(AnnotationSpecs.suppressWarnings(UNCHECKED));
315315
}
316316

317-
CodeBlock moduleCodeBlock =
317+
CodeBlock moduleCodeBlock;
318+
if (factoryFields.moduleField.isPresent()) {
319+
moduleCodeBlock = CodeBlock.of(factoryFields.moduleField.get().name);
320+
} else if (binding.contributingModule().isPresent()
321+
&& binding.contributingModule().get().isKotlinObject()) {
322+
moduleCodeBlock = CodeBlock.of(
323+
"$T.INSTANCE", binding.bindingTypeElement().get().getClassName());
324+
} else {
325+
moduleCodeBlock = CodeBlock.of("$T", binding.bindingTypeElement().get().getClassName());
326+
}
327+
328+
CodeBlock factoryMethodCall =
318329
CodeBlock.of(
319330
"$L.$L($L)",
320-
factoryFields.moduleField.isPresent()
321-
? factoryFields.moduleField.get().name
322-
: CodeBlock.of("$T", binding.bindingTypeElement().get().getClassName()),
331+
moduleCodeBlock,
323332
getSimpleName(binding.bindingElement().get()),
324333
makeParametersCodeBlock(parameterCodeBlocks.build()));
325334

326335
switch (binding.productionKind().get()) {
327336
case IMMEDIATE:
328337
methodBuilder.addStatement(
329-
"return $T.<$T>immediateFuture($L)", FUTURES, contributedTypeName, moduleCodeBlock);
338+
"return $T.<$T>immediateFuture($L)", FUTURES, contributedTypeName, factoryMethodCall);
330339
break;
331340
case FUTURE:
332-
methodBuilder.addStatement("return $L", moduleCodeBlock);
341+
methodBuilder.addStatement("return $L", factoryMethodCall);
333342
break;
334343
case SET_OF_FUTURE:
335-
methodBuilder.addStatement("return $T.allAsSet($L)", PRODUCERS, moduleCodeBlock);
344+
methodBuilder.addStatement("return $T.allAsSet($L)", PRODUCERS, factoryMethodCall);
336345
break;
337346
}
338347
return methodBuilder.build();
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Copyright (C) 2024 The Dagger Authors.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# Description:
16+
# Producers test code with Kotlin language features
17+
18+
load("@io_bazel_rules_kotlin//kotlin:kotlin.bzl", "kt_jvm_library")
19+
load("//:test_defs.bzl", "GenJavaTests")
20+
21+
package(default_visibility = ["//:src"])
22+
23+
GenJavaTests(
24+
name = "ObjectModuleTest",
25+
srcs = ["ObjectModuleTest.java"],
26+
functional = True,
27+
test_only_deps = [
28+
"//third_party/java/guava/util/concurrent",
29+
"//third_party/java/junit",
30+
"//third_party/java/truth",
31+
],
32+
deps = [
33+
":ObjectModuleClasses",
34+
],
35+
)
36+
37+
kt_jvm_library(
38+
name = "ObjectModuleClasses",
39+
srcs = [
40+
"ObjectModuleClasses.kt",
41+
],
42+
deps = [
43+
"//:dagger_with_compiler",
44+
"//:producers_with_compiler",
45+
"//third_party/java/guava/util/concurrent",
46+
],
47+
)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright (C) 2024 The Dagger Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package dagger.functional.producers.kotlin
18+
19+
import com.google.common.util.concurrent.ListenableFuture
20+
import com.google.common.util.concurrent.MoreExecutors
21+
import dagger.Module
22+
import dagger.Provides
23+
import dagger.producers.ProducerModule
24+
import dagger.producers.Produces
25+
import dagger.producers.Production
26+
import dagger.producers.ProductionComponent
27+
import dagger.multibindings.IntoSet
28+
import java.util.concurrent.Executor
29+
import javax.inject.Named
30+
31+
@ProductionComponent(
32+
modules = [
33+
ExecutorModule::class,
34+
TestKotlinObjectModule::class,
35+
TestModuleForNesting.TestNestedKotlinObjectModule::class
36+
]
37+
)
38+
interface TestKotlinComponentWithObjectModule {
39+
fun getDataA(): ListenableFuture<TestDataA>
40+
@Named("nested-data-a")
41+
fun getDataAFromNestedModule(): ListenableFuture<TestDataA>
42+
fun getDataB(): ListenableFuture<TestDataB>
43+
fun getSetOfDataA(): ListenableFuture<Set<TestDataA>>
44+
}
45+
46+
@ProducerModule
47+
object TestKotlinObjectModule {
48+
@Produces
49+
fun provideDataA() = TestDataA("test")
50+
51+
@Produces
52+
@JvmStatic
53+
fun provideDataB() = TestDataB("static-test")
54+
55+
@Produces
56+
@IntoSet
57+
fun provideIntoMapDataA() = TestDataA("set-test")
58+
}
59+
60+
class TestModuleForNesting {
61+
@ProducerModule
62+
object TestNestedKotlinObjectModule {
63+
@Produces
64+
@Named("nested-data-a")
65+
fun provideDataA() = TestDataA("nested-test")
66+
}
67+
}
68+
69+
data class TestDataA(val data: String)
70+
data class TestDataB(val data: String)
71+
72+
@Module
73+
object ExecutorModule {
74+
@Provides
75+
@Production
76+
fun executor(): Executor = MoreExecutors.directExecutor()
77+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (C) 2024 The Dagger Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package dagger.functional.producers.kotlin;
18+
19+
import static com.google.common.truth.Truth.assertThat;
20+
21+
import com.google.common.util.concurrent.ListenableFuture;
22+
import java.util.Set;
23+
import org.junit.Test;
24+
import org.junit.runner.RunWith;
25+
import org.junit.runners.JUnit4;
26+
27+
@RunWith(JUnit4.class)
28+
public class ObjectModuleTest {
29+
30+
@Test
31+
public void verifyObjectModule() throws Exception {
32+
TestKotlinComponentWithObjectModule component =
33+
DaggerTestKotlinComponentWithObjectModule.create();
34+
assertThat(component.getDataA().get().getData()).isEqualTo("test");
35+
assertThat(component.getDataAFromNestedModule().get().getData()).isEqualTo("nested-test");
36+
assertThat(component.getDataB().get().getData()).isEqualTo("static-test");
37+
ListenableFuture<Set<TestDataA>> setFuture = component.getSetOfDataA();
38+
assertThat(setFuture).isNotNull();
39+
assertThat(setFuture.get()).hasSize(1);
40+
assertThat(setFuture.get().iterator().next().getData()).isEqualTo("set-test");
41+
}
42+
}

0 commit comments

Comments
 (0)