Migrate Dagger's javatests/dagger/functional/subcomponent/ tests to Kotlin sources.
RELNOTES=N/A
PiperOrigin-RevId: 505510943
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/AnInterface.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/AnInterface.kt
new file mode 100644
index 0000000..1eaaf2c
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/AnInterface.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+interface AnInterface
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/BUILD b/javatests/dagger/functional/kotlinsrc/subcomponent/BUILD
new file mode 100644
index 0000000..d5edcba
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/BUILD
@@ -0,0 +1,33 @@
+# Copyright (C) 2023 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:
+# Functional tests for Dagger subcomponent usages.
+
+load("//:build_defs.bzl", "DOCLINT_HTML_AND_SYNTAX")
+load("//:test_defs.bzl", "GenKtTests")
+
+package(default_visibility = ["//:src"])
+
+GenKtTests(
+ name = "subcomponent",
+ srcs = glob(["*.kt"]),
+ javacopts = DOCLINT_HTML_AND_SYNTAX,
+ deps = [
+ "//:dagger_with_compiler",
+ "//third_party/java/guava/collect",
+ "//third_party/java/junit",
+ "//third_party/java/truth",
+ ],
+)
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/BoundAsSingleton.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/BoundAsSingleton.kt
new file mode 100644
index 0000000..f9f702a
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/BoundAsSingleton.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Qualifier
+
+@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION)
+@Qualifier
+internal annotation class BoundAsSingleton
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ChildAbstractClassComponent.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildAbstractClassComponent.kt
new file mode 100644
index 0000000..f0eb001
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildAbstractClassComponent.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Subcomponent
+
+@Subcomponent(modules = [ChildModule::class, StaticChildModule::class])
+abstract class ChildAbstractClassComponent : ChildComponent
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ChildComponent.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildComponent.kt
new file mode 100644
index 0000000..63c6208
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildComponent.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Subcomponent
+import javax.inject.Provider
+
+@Subcomponent(modules = [ChildModule::class, StaticChildModule::class])
+interface ChildComponent {
+ fun getUnscopedTypeProvider(): Provider<UnscopedType>
+ fun requiresSingleton(): RequiresSingletons
+ fun objectSet(): Set<Any>
+ fun newGrandchildComponent(): GrandchildComponent
+ fun any(): Any
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ChildComponentRequiringModules.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildComponentRequiringModules.kt
new file mode 100644
index 0000000..73a2123
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildComponentRequiringModules.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Subcomponent
+
+@Subcomponent(
+ modules = [ChildModule::class, ChildModuleWithParameters::class, ChildModuleWithState::class]
+)
+interface ChildComponentRequiringModules {
+ fun getInt(): Int
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModule.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModule.kt
new file mode 100644
index 0000000..6f8d43f
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModule.kt
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.IntoSet
+
+@Module
+internal object ChildModule {
+ @Provides
+ @IntoSet
+ fun provideUnscopedObject(): Any {
+ return object : Any() {
+ override fun toString(): String = "unscoped in child"
+ }
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModuleWithParameters.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModuleWithParameters.kt
new file mode 100644
index 0000000..b0b1a7f
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModuleWithParameters.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Module
+
+/** This is a module that can't be constructed with a default constructor. */
+@Module class ChildModuleWithParameters(@Suppress("UNUSED_PARAMETER") whatever: Any)
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModuleWithState.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModuleWithState.kt
new file mode 100644
index 0000000..2397447
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ChildModuleWithState.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Module
+import dagger.Provides
+
+/**
+ * This is a module that can be constructed with a default constructor, but has state, so callers
+ * might want to pass a reference anyway.
+ */
+@Module
+class ChildModuleWithState {
+ private var i = 0
+
+ @Provides
+ fun provideInt(): Int {
+ return i++
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/GenericParentComponent.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/GenericParentComponent.kt
new file mode 100644
index 0000000..9951eeb
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/GenericParentComponent.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+interface GenericParentComponent<B> {
+ fun subcomponent(): B
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/GrandchildComponent.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/GrandchildComponent.kt
new file mode 100644
index 0000000..cf7a4b3
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/GrandchildComponent.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Subcomponent
+import javax.inject.Provider
+
+@Subcomponent(modules = [GrandchildModule::class])
+interface GrandchildComponent {
+ fun getUnscopedTypeProvider(): Provider<UnscopedType>
+ fun requiresSingleton(): RequiresSingletons
+ fun objectSet(): Set<Any>
+ fun needsAnInterface(): NeedsAnInterface
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/GrandchildModule.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/GrandchildModule.kt
new file mode 100644
index 0000000..e14e111
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/GrandchildModule.kt
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.IntoSet
+
+@Module
+internal abstract class GrandchildModule {
+ @Binds abstract fun provideAnInterface(implementsAnInterface: ImplementsAnInterface): AnInterface
+
+ companion object {
+ @Provides
+ @IntoSet
+ fun provideUnscopedObject(): Any {
+ return object : Any() {
+ override fun toString(): String = "unscoped in grandchild"
+ }
+ }
+
+ @Provides
+ fun provideNeedsAnInterface(anInterface: AnInterface): NeedsAnInterface {
+ return NeedsAnInterface(anInterface)
+ }
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ImplementsAnInterface.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ImplementsAnInterface.kt
new file mode 100644
index 0000000..ee59e16
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ImplementsAnInterface.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Inject
+
+internal class ImplementsAnInterface @Inject constructor() : AnInterface
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/NeedsAnInterface.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/NeedsAnInterface.kt
new file mode 100644
index 0000000..b438e45
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/NeedsAnInterface.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+class NeedsAnInterface(@Suppress("UNUSED_PARAMETER") anInterface: AnInterface)
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ParentComponent.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentComponent.kt
new file mode 100644
index 0000000..a544063
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentComponent.kt
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Component
+import javax.inject.Singleton
+
+@Component(modules = [ParentModule::class, UnresolvableChildComponentModule::class])
+@Singleton
+interface ParentComponent : ParentGetters {
+ fun newChildComponent(): ChildComponent
+ fun newChildAbstractClassComponent(): ChildAbstractClassComponent
+ fun newChildComponentRequiringModules(
+ cmwp: ChildModuleWithParameters,
+ childModuleWithState: ChildModuleWithState
+ ): ChildComponentRequiringModules
+
+ /**
+ * Requests a qualified version of this subcomponent builder, which does not install it as a
+ * subcomponent, but instead, uses the explicit binding of this qualified builder.
+ */
+ @SomeQualifier fun unresolvableChildComponentBuilder(): UnresolvableChildComponent.Builder
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ParentGetters.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentGetters.kt
new file mode 100644
index 0000000..7bfceca
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentGetters.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Provider
+
+interface ParentGetters {
+ fun getUnscopedTypeProvider(): Provider<UnscopedType>
+ fun objectSet(): Set<Any>
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ParentModule.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentModule.kt
new file mode 100644
index 0000000..23d7d27
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentModule.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.IntoSet
+import javax.inject.Singleton
+
+@Module
+internal abstract class ParentModule {
+ @Binds
+ @Singleton
+ @BoundAsSingleton
+ abstract fun provideUnscopedTypeBoundAsSingleton(unscopedType: UnscopedType): UnscopedType
+
+ companion object {
+ @Provides
+ @IntoSet
+ fun provideUnscopedObject(): Any {
+ return object : Any() {
+ override fun toString(): String = "unscoped in parent"
+ }
+ }
+
+ @Provides
+ @IntoSet
+ @Singleton
+ fun provideSingletonObject(): Any {
+ return object : Any() {
+ override fun toString(): String = "singleton"
+ }
+ }
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/ParentOfGenericComponent.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentOfGenericComponent.kt
new file mode 100644
index 0000000..d570dc8
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/ParentOfGenericComponent.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Component
+import javax.inject.Singleton
+
+@Component(modules = [ParentModule::class])
+@Singleton
+interface ParentOfGenericComponent : GenericParentComponent<ChildComponent>, ParentGetters
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/RequiresSingletons.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/RequiresSingletons.kt
new file mode 100644
index 0000000..14bb6e6
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/RequiresSingletons.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Inject
+
+class RequiresSingletons
+@Inject
+constructor(
+ private val singletonType: SingletonType,
+ @BoundAsSingleton private val unscopedTypeBoundAsSingleton: UnscopedType
+) {
+ fun singletonType(): SingletonType = singletonType
+
+ fun unscopedTypeBoundAsSingleton(): UnscopedType = unscopedTypeBoundAsSingleton
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/SingletonType.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/SingletonType.kt
new file mode 100644
index 0000000..cc0046d
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/SingletonType.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton class SingletonType @Inject constructor()
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/SomeQualifier.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/SomeQualifier.kt
new file mode 100644
index 0000000..a5a140c
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/SomeQualifier.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Qualifier
+
+@Qualifier annotation class SomeQualifier
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/StaticChildModule.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/StaticChildModule.kt
new file mode 100644
index 0000000..ad7a2ae
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/StaticChildModule.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Module
+import dagger.Provides
+
+@Module
+internal object StaticChildModule {
+ @Provides fun provideStaticObject(): Any = "static"
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/SubcomponentFactoryMethodTest.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/SubcomponentFactoryMethodTest.kt
new file mode 100644
index 0000000..4c7ec3c
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/SubcomponentFactoryMethodTest.kt
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Component
+import dagger.Module
+import dagger.Provides
+import dagger.Subcomponent
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+/** Tests for subcomponent factory methods. */
+@RunWith(JUnit4::class)
+class SubcomponentFactoryMethodTest {
+ @Module
+ internal class IntModule {
+ @Provides fun provideInt(): Int = 42
+ }
+
+ @Module
+ internal class StringModule(val s: String) {
+ @Provides fun provideString(i: Int): String = s + i
+ }
+
+ @Component(modules = [IntModule::class])
+ internal interface TestComponent {
+ fun newSubcomponent(stringModule: StringModule?): TestSubcomponent
+ }
+
+ @Subcomponent(modules = [StringModule::class])
+ internal interface TestSubcomponent {
+ fun string(): String
+ }
+
+ @Test
+ fun creatingSubcomponentViaFactoryMethod_failsForNullParameter() {
+ val component: TestComponent = DaggerSubcomponentFactoryMethodTest_TestComponent.create()
+ try {
+ component.newSubcomponent(null)
+ Assert.fail()
+ } catch (expected: NullPointerException) {}
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/SubcomponentTest.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/SubcomponentTest.kt
new file mode 100644
index 0000000..26d4869
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/SubcomponentTest.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import com.google.common.collect.Sets
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.TruthJUnit.assume
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+class SubcomponentTest(val parentGetters: ParentGetters, val childComponent: ChildComponent) {
+ @Test
+ fun scopePropagatesUpward_class() {
+ assertThat(childComponent.requiresSingleton().singletonType())
+ .isSameInstanceAs(childComponent.requiresSingleton().singletonType())
+ assertThat(childComponent.requiresSingleton().singletonType())
+ .isSameInstanceAs(childComponent.newGrandchildComponent().requiresSingleton().singletonType())
+ }
+
+ @Test
+ fun scopePropagatesUpward_provides() {
+ assertThat(childComponent.requiresSingleton().unscopedTypeBoundAsSingleton())
+ .isSameInstanceAs(childComponent.requiresSingleton().unscopedTypeBoundAsSingleton())
+ assertThat(childComponent.requiresSingleton().unscopedTypeBoundAsSingleton())
+ .isSameInstanceAs(
+ childComponent.newGrandchildComponent().requiresSingleton().unscopedTypeBoundAsSingleton()
+ )
+ }
+
+ @Test
+ fun multibindingContributions() {
+ val parentObjectSet: Set<Any> = parentGetters.objectSet()
+ assertThat(parentObjectSet).hasSize(2)
+ val childObjectSet: Set<Any> = childComponent.objectSet()
+ assertThat(childObjectSet).hasSize(3)
+ val grandchildObjectSet: Set<Any> = childComponent.newGrandchildComponent().objectSet()
+ assertThat(grandchildObjectSet).hasSize(4)
+ assertThat(Sets.intersection(parentObjectSet, childObjectSet)).hasSize(1)
+ assertThat(Sets.intersection(parentObjectSet, grandchildObjectSet)).hasSize(1)
+ assertThat(Sets.intersection(childObjectSet, grandchildObjectSet)).hasSize(1)
+ }
+
+ @Test
+ fun unscopedProviders() {
+ assume().that(System.getProperty("dagger.mode")).doesNotContain("FastInit")
+ assertThat(parentGetters.getUnscopedTypeProvider())
+ .isSameInstanceAs(childComponent.getUnscopedTypeProvider())
+ assertThat(parentGetters.getUnscopedTypeProvider())
+ .isSameInstanceAs(childComponent.newGrandchildComponent().getUnscopedTypeProvider())
+ }
+
+ @Test
+ fun passedModules() {
+ val childModuleWithState: ChildModuleWithState = ChildModuleWithState()
+ val childComponent1: ChildComponentRequiringModules =
+ parentComponent.newChildComponentRequiringModules(
+ ChildModuleWithParameters(Any()),
+ childModuleWithState
+ )
+ val childComponent2: ChildComponentRequiringModules =
+ parentComponent.newChildComponentRequiringModules(
+ ChildModuleWithParameters(Any()),
+ childModuleWithState
+ )
+ assertThat(childComponent1.getInt()).isEqualTo(0)
+ assertThat(childComponent2.getInt()).isEqualTo(1)
+ }
+
+ @Test
+ fun dependenceisInASubcomponent() {
+ assertThat(childComponent.newGrandchildComponent().needsAnInterface()).isNotNull()
+ }
+
+ @Test
+ fun qualifiedSubcomponentIsBound() {
+ assertThat(parentComponent.unresolvableChildComponentBuilder().build().unboundString())
+ .isEqualTo("unbound")
+ }
+
+ companion object {
+ private val parentComponent = DaggerParentComponent.create()
+ private val parentOfGenericComponent = DaggerParentOfGenericComponent.create()
+
+ @JvmStatic
+ @Parameterized.Parameters
+ fun parameters(): Collection<Array<Any>> {
+ return listOf(
+ arrayOf(parentComponent, parentComponent.newChildComponent()),
+ arrayOf(parentComponent, parentComponent.newChildAbstractClassComponent()),
+ arrayOf(parentOfGenericComponent, parentOfGenericComponent.subcomponent()),
+ )
+ }
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/Unbound.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/Unbound.kt
new file mode 100644
index 0000000..a31d1e2
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/Unbound.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Qualifier
+
+/**
+ * A qualifier representing an unbound type, to verify that the compiler does not attempt to
+ * generate code depending on it.
+ */
+@Qualifier internal annotation class Unbound
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/UnresolvableChildComponent.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/UnresolvableChildComponent.kt
new file mode 100644
index 0000000..e2fb3f1
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/UnresolvableChildComponent.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Subcomponent
+
+/**
+ * A subcomponent that's not resolvable in any parent component, for testing that qualified methods
+ * on components that return subcomponents do not trigger actual subcomponents.
+ */
+@Subcomponent
+interface UnresolvableChildComponent {
+ /**
+ * Requests a type that is never bound in any component that this subcomponent might be installed
+ * in. If this subcomponent is ever attempted to be installed in a component, then it will produce
+ * a compiler error.
+ */
+ @Unbound fun unboundString(): String
+
+ @Subcomponent.Builder
+ interface Builder {
+ fun build(): UnresolvableChildComponent
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/UnresolvableChildComponentModule.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/UnresolvableChildComponentModule.kt
new file mode 100644
index 0000000..805262b
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/UnresolvableChildComponentModule.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import dagger.Module
+import dagger.Provides
+
+@Module
+internal object UnresolvableChildComponentModule {
+ /**
+ * Provides a qualified version of the [UnresolvableChildComponent]'s builder. If the subcomponent
+ * were actually installed in a component, this would be a duplicate binding; but since that
+ * doesn't happen, this binding is OK.
+ */
+ @Provides
+ @SomeQualifier
+ fun unresolvableChildComponentBuilder(): UnresolvableChildComponent.Builder {
+ return object : UnresolvableChildComponent.Builder {
+ override fun build(): UnresolvableChildComponent {
+ return object : UnresolvableChildComponent {
+ override fun unboundString(): String = "unbound"
+ }
+ }
+ }
+ }
+}
diff --git a/javatests/dagger/functional/kotlinsrc/subcomponent/UnscopedType.kt b/javatests/dagger/functional/kotlinsrc/subcomponent/UnscopedType.kt
new file mode 100644
index 0000000..5fb83fc
--- /dev/null
+++ b/javatests/dagger/functional/kotlinsrc/subcomponent/UnscopedType.kt
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2023 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.kotlinsrc.subcomponent
+
+import javax.inject.Inject
+
+class UnscopedType @Inject constructor(@Suppress("UNUSED_PARAMETER") singletonType: SingletonType)