Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import static dagger.internal.codegen.xprocessing.XAnnotationSpecs.Suppression.UNCHECKED;
import static dagger.internal.codegen.xprocessing.XAnnotationSpecs.suppressWarnings;
import static dagger.internal.codegen.xprocessing.XCodeBlocks.makeParametersCodeBlock;
import static dagger.internal.codegen.xprocessing.XCodeBlocks.staticReferenceOf;
import static dagger.internal.codegen.xprocessing.XElements.asMethod;
import static dagger.internal.codegen.xprocessing.XElements.getSimpleName;
import static dagger.internal.codegen.xprocessing.XFunSpecs.constructorBuilder;
Expand Down Expand Up @@ -367,15 +368,16 @@ private XFunSpec callProducesMethod(ProductionBinding binding, FactoryFields fac
XCodeBlock.of(
"%L.%N(%L)",
factoryFields.moduleField.isPresent()
? factoryFields.moduleField.get().getName() // SUPPRESS_GET_NAME_CHECK
: XCodeBlock.of("%T", binding.bindingTypeElement().get().asClassName()),
? XCodeBlock.of("%N", factoryFields.moduleField.get())
: staticReferenceOf(binding.bindingTypeElement().get()),
getSimpleName(binding.bindingElement().get()),
makeParametersCodeBlock(parameterCodeBlocks.build()));

XCodeBlock returnCodeBlock;
switch (ProductionKind.fromProducesMethod(asMethod(binding.bindingElement().get()))) {
case IMMEDIATE:
returnCodeBlock = XCodeBlock.of("%T.immediateFuture(%L)", XTypeNames.FUTURES, moduleCodeBlock);
returnCodeBlock =
XCodeBlock.of("%T.immediateFuture(%L)", XTypeNames.FUTURES, moduleCodeBlock);
break;
case FUTURE:
returnCodeBlock = XCodeBlock.of("%L", moduleCodeBlock);
Expand Down
44 changes: 44 additions & 0 deletions javatests/dagger/functional/producers/kotlin/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright (C) 2024 The Dagger Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Description:
# Producers test code with Kotlin language features

load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library")
load("//:test_defs.bzl", "GenJavaTests")

package(default_visibility = ["//:src"])

GenJavaTests(
name = "ObjectModuleTest",
srcs = ["ObjectModuleTest.java"],
deps = [
":ObjectModuleClasses",
"//third_party/java/guava/util/concurrent",
"//third_party/java/junit",
"//third_party/java/truth",
],
)

kt_jvm_library(
name = "ObjectModuleClasses",
srcs = [
"ObjectModuleClasses.kt",
],
deps = [
"//third_party/java/dagger",
"//third_party/java/dagger:producers",
"//third_party/java/guava/util/concurrent",
],
)
128 changes: 128 additions & 0 deletions javatests/dagger/functional/producers/kotlin/ObjectModuleClasses.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* Copyright (C) 2024 The Dagger Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dagger.functional.producers.kotlin

import com.google.common.util.concurrent.ListenableFuture
import com.google.common.util.concurrent.MoreExecutors
import dagger.Module
import dagger.Provides
import dagger.multibindings.IntoSet
import dagger.producers.ProducerModule
import dagger.producers.Produces
import dagger.producers.Production
import dagger.producers.ProductionComponent
import java.util.concurrent.Executor
import javax.inject.Named

const val OBJECT_MODULE_VALUE = "object_module"
const val OBJECT_MODULE_STATIC_VALUE = "object_module_static"
const val OBJECT_MODULE_SET_VALUE = "object_module_set"
const val NESTED_OBJECT_MODULE_VALUE = "nested_object_module"
const val INTERFACE_COMPANION_OBJECT_MODULE_VALUE = "interface_companion_object_module"
const val NESTED_INTERFACE_COMPANION_OBJECT_MODULE_VALUE =
"nested_interface_companion_object_module"
const val CLASS_COMPANION_OBJECT_MODULE_VALUE = "class_companion_object_module"

// Regression test for b/347108703
@ProductionComponent(
modules =
[
ExecutorModule::class,
TestKotlinObjectModule::class,
TestModuleForNesting.TestNestedKotlinObjectModule::class,
TestInterfaceCompanionObjectModule::class,
TestModuleForNesting.TestNestedInterfaceCompanionObjectModule::class,
TestClassCompanionObjectModule::class,
]
)
interface TestKotlinComponentWithObjectModule {
@Named(OBJECT_MODULE_VALUE) fun getObjectModuleData(): ListenableFuture<TestData>

@Named(OBJECT_MODULE_STATIC_VALUE) fun getObjectModuleStaticData(): ListenableFuture<TestData>

@Named(NESTED_OBJECT_MODULE_VALUE) fun getNestedObjectModuleData(): ListenableFuture<TestData>

@Named(INTERFACE_COMPANION_OBJECT_MODULE_VALUE)
fun getInterfaceCompanionObjectModuleData(): ListenableFuture<TestData>

@Named(NESTED_INTERFACE_COMPANION_OBJECT_MODULE_VALUE)
fun getNestedInterfaceCompanionObjectModuleData(): ListenableFuture<TestData>

@Named(CLASS_COMPANION_OBJECT_MODULE_VALUE)
fun getClassCompanionObjectModuleData(): ListenableFuture<TestData>

@Named(OBJECT_MODULE_SET_VALUE) fun getSetOfData(): ListenableFuture<Set<TestData>>
}

@ProducerModule
object TestKotlinObjectModule {
@Produces @Named(OBJECT_MODULE_VALUE) fun provideData() = TestData(OBJECT_MODULE_VALUE)

@Produces
@JvmStatic
@Named(OBJECT_MODULE_STATIC_VALUE)
fun provideStaticData() = TestData(OBJECT_MODULE_STATIC_VALUE)

@Produces
@IntoSet
@Named(OBJECT_MODULE_SET_VALUE)
fun provideSetData() = TestData(OBJECT_MODULE_SET_VALUE)
}

class TestModuleForNesting {
@ProducerModule
object TestNestedKotlinObjectModule {
@Produces
@Named(NESTED_OBJECT_MODULE_VALUE)
fun provideData() = TestData(NESTED_OBJECT_MODULE_VALUE)
}

@ProducerModule
interface TestNestedInterfaceCompanionObjectModule {
companion object {
@Produces
@Named(NESTED_INTERFACE_COMPANION_OBJECT_MODULE_VALUE)
fun provideData() = TestData(NESTED_INTERFACE_COMPANION_OBJECT_MODULE_VALUE)
}
}
}

@ProducerModule
interface TestInterfaceCompanionObjectModule {
companion object {
@Produces
@Named(INTERFACE_COMPANION_OBJECT_MODULE_VALUE)
fun provideData() = TestData(INTERFACE_COMPANION_OBJECT_MODULE_VALUE)
}
}

@Suppress("ClassShouldBeObject")
@ProducerModule
class TestClassCompanionObjectModule {
companion object {
@Produces
@Named(CLASS_COMPANION_OBJECT_MODULE_VALUE)
fun provideData() = TestData(CLASS_COMPANION_OBJECT_MODULE_VALUE)
}
}

data class TestData(val data: String)

@Module
object ExecutorModule {
@Provides @Production fun executor(): Executor = MoreExecutors.directExecutor()
}
57 changes: 57 additions & 0 deletions javatests/dagger/functional/producers/kotlin/ObjectModuleTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright (C) 2024 The Dagger Authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package dagger.functional.producers.kotlin;

import static com.google.common.truth.Truth.assertThat;
import static dagger.functional.producers.kotlin.ObjectModuleClassesKt.CLASS_COMPANION_OBJECT_MODULE_VALUE;
import static dagger.functional.producers.kotlin.ObjectModuleClassesKt.INTERFACE_COMPANION_OBJECT_MODULE_VALUE;
import static dagger.functional.producers.kotlin.ObjectModuleClassesKt.NESTED_INTERFACE_COMPANION_OBJECT_MODULE_VALUE;
import static dagger.functional.producers.kotlin.ObjectModuleClassesKt.NESTED_OBJECT_MODULE_VALUE;
import static dagger.functional.producers.kotlin.ObjectModuleClassesKt.OBJECT_MODULE_SET_VALUE;
import static dagger.functional.producers.kotlin.ObjectModuleClassesKt.OBJECT_MODULE_STATIC_VALUE;
import static dagger.functional.producers.kotlin.ObjectModuleClassesKt.OBJECT_MODULE_VALUE;

import com.google.common.util.concurrent.ListenableFuture;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

@RunWith(JUnit4.class)
public class ObjectModuleTest {

@Test
public void verifyObjectModule() throws Exception {
TestKotlinComponentWithObjectModule component =
DaggerTestKotlinComponentWithObjectModule.create();
assertThat(component.getObjectModuleData().get().getData()).isEqualTo(OBJECT_MODULE_VALUE);
assertThat(component.getObjectModuleStaticData().get().getData())
.isEqualTo(OBJECT_MODULE_STATIC_VALUE);
assertThat(component.getNestedObjectModuleData().get().getData())
.isEqualTo(NESTED_OBJECT_MODULE_VALUE);
assertThat(component.getInterfaceCompanionObjectModuleData().get().getData())
.isEqualTo(INTERFACE_COMPANION_OBJECT_MODULE_VALUE);
assertThat(component.getNestedInterfaceCompanionObjectModuleData().get().getData())
.isEqualTo(NESTED_INTERFACE_COMPANION_OBJECT_MODULE_VALUE);
assertThat(component.getClassCompanionObjectModuleData().get().getData())
.isEqualTo(CLASS_COMPANION_OBJECT_MODULE_VALUE);
ListenableFuture<Set<TestData>> setFuture = component.getSetOfData();
assertThat(setFuture).isNotNull();
assertThat(setFuture.get()).hasSize(1);
assertThat(setFuture.get().iterator().next().getData()).isEqualTo(OBJECT_MODULE_SET_VALUE);
}
}
Loading