Skip to content

Commit 09ca4f6

Browse files
authored
Merge pull request #211 from yandex/users/bacecek/209-main
2 parents 727acad + f6a0e5c commit 09ca4f6

8 files changed

Lines changed: 169 additions & 56 deletions

File tree

.gitignore

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,8 @@
1-
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
2-
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
3-
# From: https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore
4-
51
# User-specific stuff
6-
.idea/**/workspace.xml
7-
.idea/**/tasks.xml
8-
.idea/**/misc.xml
9-
.idea/**/usage.statistics.xml
10-
.idea/**/dictionaries
11-
.idea/**/shelf
12-
13-
# Generated files
14-
.idea/**/contentModel.xml
15-
16-
# Sensitive or high-churn files
17-
.idea/**/dataSources/
18-
.idea/**/dataSources.ids
19-
.idea/**/dataSources.local.xml
20-
.idea/**/sqlDataSources.xml
21-
.idea/**/dynamic.xml
22-
.idea/**/uiDesigner.xml
23-
.idea/**/dbnavigator.xml
24-
25-
# Gradle
26-
.idea/**/gradle.xml
27-
.idea/**/libraries
28-
29-
# Gradle and Maven with auto-import
30-
# When using Gradle or Maven with auto-import, you should exclude module files,
31-
# since they will be recreated, and may cause churn.
32-
.idea/artifacts
33-
.idea/compiler.xml
34-
.idea/jarRepositories.xml
35-
.idea/modules.xml
36-
.idea/*.iml
37-
.idea/modules
38-
*.iml
39-
*.ipr
2+
.idea/
3+
!.idea/codeStyles
4+
!.idea/inspectionProfiles
5+
!.idea/vcs.xml
406

417
# Build dirs
428
/build/

.idea/kotlinc.xml

Lines changed: 0 additions & 6 deletions
This file was deleted.

codegen/impl/src/main/kotlin/com/yandex/yatagan/codegen/impl/AssistedInjectFactoryGenerator.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import com.yandex.yatagan.codegen.poetry.buildExpression
2525
import com.yandex.yatagan.core.graph.BindingGraph
2626
import com.yandex.yatagan.core.graph.bindings.AssistedInjectFactoryBinding
2727
import com.yandex.yatagan.core.model.AssistedInjectFactoryModel
28+
import com.yandex.yatagan.core.model.ConditionScope
2829
import com.yandex.yatagan.core.model.component1
2930
import com.yandex.yatagan.core.model.component2
3031
import javax.inject.Inject
@@ -38,13 +39,15 @@ internal class AssistedInjectFactoryGenerator @Inject constructor(
3839
) : ComponentGenerator.Contributor {
3940
private val modelToImpl: Map<AssistedInjectFactoryModel, ClassName> by lazy {
4041
val classNamespace = Namespace()
41-
thisGraph.localAssistedInjectFactories.associateWith { model ->
42-
componentImplName.nestedClass(classNamespace.name(
43-
nameModel = model.name,
44-
suffix = "Impl",
45-
firstCapital = true,
46-
))
47-
}
42+
thisGraph.localAssistedInjectFactories
43+
.filter { it.value != ConditionScope.Never }
44+
.mapValues {
45+
componentImplName.nestedClass(classNamespace.name(
46+
nameModel = it.key.name,
47+
suffix = "Impl",
48+
firstCapital = true,
49+
))
50+
}
4851
}
4952

5053
fun generateCreation(

core/graph/api/api/api.api

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ public abstract interface class com/yandex/yatagan/core/graph/BindingGraph : com
33
public abstract fun getCreator ()Lcom/yandex/yatagan/core/model/ComponentFactoryModel;
44
public abstract fun getDependencies ()Ljava/util/Collection;
55
public abstract fun getEntryPoints ()Ljava/util/Collection;
6-
public abstract fun getLocalAssistedInjectFactories ()Ljava/util/Collection;
6+
public abstract fun getLocalAssistedInjectFactories ()Ljava/util/Map;
77
public abstract fun getLocalBindings ()Ljava/util/Map;
88
public abstract fun getLocalConditionLiterals ()Ljava/util/Map;
99
public abstract fun getMemberInjectors ()Ljava/util/Collection;

core/graph/api/src/main/kotlin/com/yandex/yatagan/core/graph/BindingGraph.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ public interface BindingGraph : MayBeInvalid, Extensible<BindingGraph>,
7171
/**
7272
* [AssistedInjectFactoryModel]s that are hosted in this graph.
7373
*/
74-
public val localAssistedInjectFactories: Collection<AssistedInjectFactoryModel>
74+
@Incubating
75+
public val localAssistedInjectFactories: Map<AssistedInjectFactoryModel, ConditionScope>
7576

7677
/**
7778
* A collection of parent (not necessarily direct) [BindingGraph]s, from which bindings and/or conditions are used

core/graph/impl/src/main/kotlin/com/yandex/yatagan/core/graph/impl/BindingGraphImpl.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ internal class BindingGraphImpl private constructor(
122122
internal val localNodes = mutableSetOf<NodeModel>()
123123
override val localBindings = mutableMapOf<Binding, BindingUsageImpl>()
124124
override val localConditionLiterals = mutableMapOf<ConditionModel, LiteralUsage>()
125-
override val localAssistedInjectFactories = mutableSetOf<AssistedInjectFactoryModel>()
125+
override val localAssistedInjectFactories = mutableMapOf<AssistedInjectFactoryModel, ConditionScope>()
126126
override val usedParents = mutableSetOf<BindingGraph>()
127127
override val children: Collection<BindingGraphImpl>
128128

@@ -210,7 +210,7 @@ internal class BindingGraphImpl private constructor(
210210
binding.accept(object : Binding.Visitor<Unit> {
211211
override fun visitOther(binding: Binding) = Unit
212212
override fun visitAssistedInjectFactory(binding: AssistedInjectFactoryBinding) {
213-
localAssistedInjectFactories += binding.model
213+
localAssistedInjectFactories[binding.model] = binding.conditionScope
214214
}
215215
})
216216
}
@@ -259,7 +259,7 @@ internal class BindingGraphImpl private constructor(
259259
for (child in childrenSequence(includeThis = false)) {
260260
child as BindingGraphImpl
261261
val usesConditions = child.localConditionLiterals.keys.removeAll(localConditionLiterals.keys)
262-
val usesAssistedInjectFactories = child.localAssistedInjectFactories.removeAll(localAssistedInjectFactories)
262+
val usesAssistedInjectFactories = child.localAssistedInjectFactories.keys.removeAll(localAssistedInjectFactories.keys)
263263
if (usesConditions || usesAssistedInjectFactories) {
264264
// This will never be seen by materialization and that's okay, because no bindings are required here.
265265
child.usedParents += this

testing/tests/src/test/kotlin/com/yandex/yatagan/testing/tests/ConditionsTest.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,4 +1216,52 @@ class ConditionsTest(
12161216

12171217
compileRunAndValidate()
12181218
}
1219+
1220+
@Test
1221+
fun `issue #209 - assisted factory generated for unsupported variants`() {
1222+
includeFromSourceSet(flavors)
1223+
1224+
givenKotlinSource("test.TestCase", """
1225+
import com.yandex.yatagan.*
1226+
import javax.inject.*
1227+
1228+
@AssistedFactory
1229+
interface PhoneAssistedFactory {
1230+
fun create(i: Int): PhoneAssistedClass
1231+
}
1232+
1233+
@Conditional(onlyIn = [DeviceType.Phone::class])
1234+
class PhoneAssistedClass @AssistedInject constructor(
1235+
phoneDependency: PhoneDependency,
1236+
@Assisted arg: Int,
1237+
)
1238+
1239+
@Conditional(onlyIn = [DeviceType.Phone::class])
1240+
class PhoneDependency @Inject constructor()
1241+
1242+
class CommonClass @Inject constructor(
1243+
phoneFactory: Optional<PhoneAssistedFactory>,
1244+
)
1245+
1246+
interface CommonComponent {
1247+
fun getCommonClass(): CommonClass
1248+
}
1249+
1250+
@Component(variant = [DeviceType.Phone::class])
1251+
interface PhoneComponent: CommonComponent
1252+
1253+
@Component(variant = [DeviceType.Tablet::class])
1254+
interface TabletComponent: CommonComponent
1255+
1256+
fun test() {
1257+
val phoneComponent = Yatagan.create(PhoneComponent::class.java)
1258+
val tabletComponent = Yatagan.create(TabletComponent::class.java)
1259+
1260+
val phoneCommon = phoneComponent.getCommonClass()
1261+
val tabletCommon = tabletComponent.getCommonClass()
1262+
}
1263+
""".trimIndent())
1264+
1265+
compileRunAndValidate()
1266+
}
12191267
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2+
Name: test/YataganTabletComponent.java
3+
package test;
4+
5+
import com.yandex.yatagan.AutoBuilder;
6+
import com.yandex.yatagan.Optional;
7+
import com.yandex.yatagan.internal.Checks;
8+
import com.yandex.yatagan.internal.YataganGenerated;
9+
import java.lang.Class;
10+
import java.lang.Override;
11+
import java.lang.SuppressWarnings;
12+
import java.util.Collections;
13+
import javax.annotation.processing.Generated;
14+
15+
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems", "deprecation"})
16+
@YataganGenerated
17+
@Generated("com.yandex.yatagan.codegen.impl.ComponentGenerator")
18+
public final class YataganTabletComponent implements TabletComponent {
19+
private YataganTabletComponent() {
20+
}
21+
22+
@Override
23+
public CommonClass getCommonClass() {
24+
return new CommonClass(Optional.empty());
25+
}
26+
27+
public static AutoBuilder<YataganTabletComponent> autoBuilder() {
28+
return new AutoBuilderImpl();
29+
}
30+
31+
private static final class AutoBuilderImpl implements AutoBuilder<YataganTabletComponent> {
32+
@Override
33+
public final <I> AutoBuilder<YataganTabletComponent> provideInput(I input,
34+
Class<I> inputClass) {
35+
Checks.reportUnexpectedAutoBuilderInput(input.getClass(), Collections.emptyList());
36+
return this;
37+
}
38+
39+
@Override
40+
public final YataganTabletComponent create() {
41+
return new YataganTabletComponent();
42+
}
43+
}
44+
}
45+
46+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47+
Name: test/YataganPhoneComponent.java
48+
package test;
49+
50+
import com.yandex.yatagan.AutoBuilder;
51+
import com.yandex.yatagan.Optional;
52+
import com.yandex.yatagan.internal.Checks;
53+
import com.yandex.yatagan.internal.YataganGenerated;
54+
import java.lang.Class;
55+
import java.lang.Override;
56+
import java.lang.SuppressWarnings;
57+
import java.util.Collections;
58+
import javax.annotation.processing.Generated;
59+
60+
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems", "deprecation"})
61+
@YataganGenerated
62+
@Generated("com.yandex.yatagan.codegen.impl.ComponentGenerator")
63+
public final class YataganPhoneComponent implements PhoneComponent {
64+
private YataganPhoneComponent() {
65+
}
66+
67+
@Override
68+
public CommonClass getCommonClass() {
69+
return new CommonClass(this.optOfPhoneAssistedFactory());
70+
}
71+
72+
Optional optOfPhoneAssistedFactory() {
73+
return Optional.of(this.new PhoneAssistedFactoryImpl());
74+
}
75+
76+
public static AutoBuilder<YataganPhoneComponent> autoBuilder() {
77+
return new AutoBuilderImpl();
78+
}
79+
80+
private final class PhoneAssistedFactoryImpl implements PhoneAssistedFactory {
81+
@Override
82+
public PhoneAssistedClass create(int i) {
83+
return new PhoneAssistedClass(new PhoneDependency(), i);
84+
}
85+
}
86+
87+
private static final class AutoBuilderImpl implements AutoBuilder<YataganPhoneComponent> {
88+
@Override
89+
public final <I> AutoBuilder<YataganPhoneComponent> provideInput(I input, Class<I> inputClass) {
90+
Checks.reportUnexpectedAutoBuilderInput(input.getClass(), Collections.emptyList());
91+
return this;
92+
}
93+
94+
@Override
95+
public final YataganPhoneComponent create() {
96+
return new YataganPhoneComponent();
97+
}
98+
}
99+
}
100+
101+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)