Skip to content

Commit

Permalink
Merge pull request #150 from yandex/wp/conditional-out-of-provides
Browse files Browse the repository at this point in the history
Api: Move `Provides.conditionals` API.
  • Loading branch information
Jeffset committed May 10, 2024
2 parents a554fc6 + 23e552e commit ccfdd05
Show file tree
Hide file tree
Showing 18 changed files with 97 additions and 82 deletions.
1 change: 0 additions & 1 deletion api/public/api/public.api
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ public abstract interface class com/yandex/yatagan/Optional$Function {
}

public abstract interface annotation class com/yandex/yatagan/Provides : java/lang/annotation/Annotation {
public abstract fun value ()[Lcom/yandex/yatagan/Conditional;
}

public abstract interface annotation class com/yandex/yatagan/Reusable : java/lang/annotation/Annotation {
Expand Down
7 changes: 6 additions & 1 deletion api/public/src/main/kotlin/com/yandex/yatagan/Conditional.kt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ import kotlin.reflect.KClass
* val a: UnderA,
* val b: UnderB,
* )
*
* // Can be specified on a provision also.
* @Provides
* @Conditional(FeatureA::class)
* fun someProvision(): SomeClass
* ```
*
* @see value
Expand All @@ -75,7 +80,7 @@ import kotlin.reflect.KClass
@MustBeDocumented
@JvmRepeatable(Conditionals::class)
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER)
public annotation class Conditional(
/**
* A list of **feature declarations** - annotation types, annotated with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ package com.yandex.yatagan
@ConditionsApi
@MustBeDocumented
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.CLASS)
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER)
public annotation class Conditionals(
vararg val value: Conditional,
)
8 changes: 1 addition & 7 deletions api/public/src/main/kotlin/com/yandex/yatagan/Provides.kt
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,4 @@ package com.yandex.yatagan
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
)
@OptIn(ConditionsApi::class)
public annotation class Provides(
/**
* One or more [Conditional] specifiers for this provision.
*/
vararg val value: Conditional = [],
)
public annotation class Provides
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ internal class ProvidesImpl(

private val conditionalsModel by lazy {
ConditionalHoldingModelImpl(
checkNotNull(method.getAnnotation(BuiltinAnnotation.Provides)) { "Not reached" }.conditionals
method.getAnnotations(BuiltinAnnotation.Conditional)
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,8 @@ public sealed interface BuiltinAnnotation {
* Models `com.yandex.yatagan.Provides` annotation.
*/
@Internal
public interface Provides : OnMethod {
public val conditionals: List<Conditional>

@Internal
public companion object : Target.OnMethod<Provides> {
override val modelClass: Class<Provides> get() = Provides::class.java
}
public object Provides : OnMethod, Target.OnMethod<Provides> {
override val modelClass: Class<Provides> get() = Provides::class.java
}

/**
Expand Down Expand Up @@ -236,12 +231,12 @@ public sealed interface BuiltinAnnotation {
* Represents `com.yandex.yatagan.Conditional` annotation.
*/
@Internal
public interface Conditional : OnClassRepeatable {
public interface Conditional : OnClassRepeatable, OnMethodRepeatable {
public val featureTypes: List<Type>
public val onlyIn: List<Type>

@Internal
public companion object : Target.OnClassRepeatable<Conditional> {
public companion object : Target.OnClassRepeatable<Conditional>, Target.OnMethodRepeatable<Conditional> {
override val modelClass: Class<Conditional> get() = Conditional::class.java
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ package com.yandex.yatagan.lang.compiled

import com.yandex.yatagan.Binds
import com.yandex.yatagan.BindsInstance
import com.yandex.yatagan.Conditional
import com.yandex.yatagan.Conditionals
import com.yandex.yatagan.ConditionsApi
import com.yandex.yatagan.IntoList
import com.yandex.yatagan.IntoMap
import com.yandex.yatagan.IntoSet
Expand All @@ -38,8 +41,8 @@ abstract class CtMethodBase : MethodBase() {
.takeIf { annotations.any { it.hasType<Binds>() } }
BuiltinAnnotation.BindsInstance -> (which as BuiltinAnnotation.BindsInstance)
.takeIf { annotations.any { it.hasType<BindsInstance>() } }
BuiltinAnnotation.Provides ->
annotations.find { it.hasType<Provides>() }?.let { CtProvidesAnnotationImpl(it) }
BuiltinAnnotation.Provides -> (which as BuiltinAnnotation.Provides)
.takeIf { annotations.any { it.hasType<Provides>() } }
BuiltinAnnotation.IntoMap -> (which as BuiltinAnnotation.IntoMap)
.takeIf { annotations.any { it.hasType<IntoMap>() } }
BuiltinAnnotation.Multibinds -> (which as BuiltinAnnotation.Multibinds)
Expand All @@ -50,6 +53,7 @@ abstract class CtMethodBase : MethodBase() {
return which.modelClass.cast(annotation)
}

@OptIn(ConditionsApi::class)
override fun <T : BuiltinAnnotation.OnMethodRepeatable> getAnnotations(
which: BuiltinAnnotation.Target.OnMethodRepeatable<T>
): List<T> {
Expand All @@ -64,6 +68,16 @@ abstract class CtMethodBase : MethodBase() {
}
}
}
BuiltinAnnotation.Conditional -> buildList {
for (annotation in annotations) {
when {
annotation.hasType<Conditional>() ->
add(which.modelClass.cast(CtConditionalAnnotationImpl(annotation)))
annotation.hasType<Conditionals>() -> for (contained in annotation.getAnnotations("value"))
add(which.modelClass.cast(CtConditionalAnnotationImpl(contained)))
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,6 @@ sealed interface InvalidNameModel : CtTypeNameModel {
}

class TypeVariable(private val typeVar: String) : InvalidNameModel {
init {
print("dsd")
}
override fun toString() = "<unresolved-type-var: $typeVar>"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,6 @@ internal class CtComponentFlavorAnnotationImpl(
override val dimension get() = impl.getType("dimension")
}

internal class CtProvidesAnnotationImpl(
impl: CtAnnotationBase,
) : CtBuiltinAnnotationBase(impl), BuiltinAnnotation.Provides {
override val conditionals get() = impl.getAnnotations("value").map { CtConditionalAnnotationImpl(it) }
}

internal class CtIntoListAnnotationImpl(
impl: CtAnnotationBase,
) : CtBuiltinAnnotationBase(impl), BuiltinAnnotation.IntoCollectionFamily.IntoList {
Expand Down
15 changes: 13 additions & 2 deletions lang/rt/src/main/kotlin/com/yandex/yatagan/lang/rt/RtMethodImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ package com.yandex.yatagan.lang.rt

import com.yandex.yatagan.Binds
import com.yandex.yatagan.BindsInstance
import com.yandex.yatagan.Conditional
import com.yandex.yatagan.Conditionals
import com.yandex.yatagan.ConditionsApi
import com.yandex.yatagan.IntoList
import com.yandex.yatagan.IntoMap
import com.yandex.yatagan.IntoSet
Expand Down Expand Up @@ -72,8 +75,8 @@ internal class RtMethodImpl(
.takeIf { impl.isAnnotationPresent(Binds::class.java) }
BuiltinAnnotation.BindsInstance -> (which as BuiltinAnnotation.BindsInstance)
.takeIf { impl.isAnnotationPresent(BindsInstance::class.java) }
BuiltinAnnotation.Provides ->
impl.getAnnotation(Provides::class.java)?.let { RtProvidesAnnotationImpl(it) }
BuiltinAnnotation.Provides -> (which as BuiltinAnnotation.Provides)
.takeIf { impl.isAnnotationPresent(Provides::class.java) }
BuiltinAnnotation.IntoMap -> (which as BuiltinAnnotation.IntoMap)
.takeIf { impl.isAnnotationPresent(IntoMap::class.java) }
BuiltinAnnotation.Multibinds -> (which as BuiltinAnnotation.Multibinds)
Expand All @@ -84,6 +87,7 @@ internal class RtMethodImpl(
return which.modelClass.cast(annotation)
}

@OptIn(ConditionsApi::class)
override fun <T : BuiltinAnnotation.OnMethodRepeatable> getAnnotations(
which: BuiltinAnnotation.Target.OnMethodRepeatable<T>,
): List<T> {
Expand All @@ -97,6 +101,13 @@ internal class RtMethodImpl(
}
}
}
BuiltinAnnotation.Conditional -> buildList {
for (annotation in impl.declaredAnnotations) when (annotation) {
is Conditional -> add(which.modelClass.cast(RtConditionalAnnotationImpl(annotation)))
is Conditionals -> for (contained in annotation.value)
add(which.modelClass.cast(RtConditionalAnnotationImpl(contained)))
}
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,19 +86,6 @@ internal class RtConditionalAnnotationImpl private constructor(
}
}

internal class RtProvidesAnnotationImpl private constructor(
lexicalScope: LexicalScope,
impl: Provides,
) : RtAnnotationImplBase<Provides>(impl), BuiltinAnnotation.Provides, LexicalScope by lexicalScope {
override val conditionals get() = impl.value.map {
RtConditionalAnnotationImpl(it)
}

companion object Factory : FactoryKey<Provides, RtProvidesAnnotationImpl> {
override fun LexicalScope.factory() = ::RtProvidesAnnotationImpl
}
}

internal class RtIntoListAnnotationImpl(
impl: IntoList,
) : RtAnnotationImplBase<IntoList>(impl), BuiltinAnnotation.IntoCollectionFamily.IntoList {
Expand Down
13 changes: 11 additions & 2 deletions testing/tests/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ val versionsToCheckLoaderCompatibility = listOf(
"1.1.0",
"1.2.0",
"1.3.0",
"1.5.0",
)

val baseTestRuntime: Configuration by configurations.creating
Expand All @@ -23,6 +24,7 @@ val compiledTestRuntime: Configuration by configurations.creating {

versionsToCheckLoaderCompatibility.forEach { version ->
configurations.register("kaptForCompatCheck$version")
configurations.register("apiForCompatCheck$version")
}

kotlin {
Expand Down Expand Up @@ -68,15 +70,22 @@ dependencies {

versionsToCheckLoaderCompatibility.forEach { version ->
add("kaptForCompatCheck$version", "com.yandex.yatagan:processor-jap:$version")
add("apiForCompatCheck$version", if (version < "2.0.0")
"com.yandex.yatagan:api-compiled:$version" else "com.yandex.yatagan:api-public:$version")
}
}

val genKaptClasspathForCompatCheckTasks = versionsToCheckLoaderCompatibility.map { version ->
val genKaptClasspathForCompatCheckTasks = versionsToCheckLoaderCompatibility.flatMap { version ->
val versionId = version.replace("[.-]".toRegex(), "_")
tasks.register<ClasspathSourceGeneratorTask>("generateKaptClasspathForCompatCheck_$versionId") {
val kapt = tasks.register<ClasspathSourceGeneratorTask>("generateKaptClasspathForCompatCheck_$versionId") {
propertyName.set("KaptClasspathForCompatCheck$versionId")
classpath.set(configurations.named("kaptForCompatCheck$version"))
}
val api = tasks.register<ClasspathSourceGeneratorTask>("generateApiClasspathForCompatCheck_$versionId") {
propertyName.set("ApiClasspathForCompatCheck$versionId")
classpath.set(configurations.named("apiForCompatCheck$version"))
}
listOf(kapt, api)
}

val generateDynamicApiClasspath by tasks.registering(ClasspathSourceGeneratorTask::class) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import androidx.room.compiler.processing.util.DiagnosticMessage
import androidx.room.compiler.processing.util.compiler.TestCompilationArguments
import androidx.room.compiler.processing.util.compiler.compile
import com.yandex.yatagan.generated.CompiledApiClasspath
import com.yandex.yatagan.generated.DynamicApiClasspath
import com.yandex.yatagan.processor.common.BooleanOption
import com.yandex.yatagan.processor.common.IntOption
import com.yandex.yatagan.processor.common.LoggerDecorator
Expand All @@ -38,7 +37,7 @@ import kotlin.io.path.deleteIfExists
import kotlin.io.path.writeText

abstract class CompileTestDriverBase private constructor(
private val apiType: ApiType,
private val apiClasspath: String,
private val mainSourceSet: SourceSet,
) : CompileTestDriver, SourceSet by mainSourceSet {
private var precompiledModuleOutputDirs: List<File>? = null
Expand All @@ -49,8 +48,8 @@ abstract class CompileTestDriverBase private constructor(
)

protected constructor(
apiType: ApiType = ApiType.Compiled,
) : this(apiType, SourceSet())
apiClasspath: String = CompiledApiClasspath,
) : this(apiClasspath, SourceSet())

override val testNameRule = TestNameRule()

Expand Down Expand Up @@ -201,10 +200,7 @@ abstract class CompileTestDriverBase private constructor(
private fun createBaseCompilationArguments() = TestCompilationArguments(
sources = sourceFiles,
classpath = buildList {
when (apiType) {
ApiType.Compiled -> CompiledApiClasspath
ApiType.Dynamic -> DynamicApiClasspath
}.split(File.pathSeparatorChar).forEach { add(File(it)) }
apiClasspath.split(File.pathSeparatorChar).forEach { add(File(it)) }
precompiledModuleOutputDirs?.let { addAll(it) }
},
inheritClasspath = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.yandex.yatagan.testing.tests

import com.squareup.javapoet.ClassName
import com.yandex.yatagan.Component
import com.yandex.yatagan.generated.DynamicApiClasspath
import com.yandex.yatagan.lang.jap.asTypeElement
import com.yandex.yatagan.lang.jap.isAnnotatedWith
import com.yandex.yatagan.processor.common.IntOption
Expand All @@ -37,9 +38,7 @@ import javax.lang.model.element.TypeElement

private const val TEST_DELEGATE = "test.TestValidationDelegate"

class DynamicCompileTestDriver(
apiType: ApiType = ApiType.Dynamic,
) : CompileTestDriverBase(apiType) {
class DynamicCompileTestDriver() : CompileTestDriverBase(DynamicApiClasspath) {
private val accumulator = ComponentBootstrapperGenerator()
private val options = mutableMapOf<Option<*>, Any>(
IntOption.MaxIssueEncounterPaths to 100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.yandex.yatagan.testing.tests

import com.yandex.yatagan.generated.CompiledApiClasspath
import com.yandex.yatagan.processor.jap.JapYataganProcessor
import java.io.File
import java.net.URLClassLoader
Expand All @@ -24,7 +25,10 @@ import javax.annotation.processing.Processor
class JapCompileTestDriver(
private val customProcessorClasspath: String? = null,
override val checkGoldenOutput: Boolean = true,
): CompileTestDriverBase() {
apiClasspath: String = CompiledApiClasspath,
): CompileTestDriverBase(
apiClasspath = apiClasspath,
) {
override fun createCompilationArguments() = super.createCompilationArguments().copy(
kaptProcessors = listOf(loadProcessorFromCustomClasspath() ?: JapYataganProcessor()),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -504,19 +504,16 @@ class ConditionsTest(
@Module
object MyModule {
@Provides(
Conditional(Conditions.FeatureA::class, onlyIn = [ActivityType.Main::class]),
Conditional(Conditions.FeatureB::class), // in the rest
)
@Conditional(Conditions.FeatureA::class, onlyIn = [ActivityType.Main::class])
@Conditional(Conditions.FeatureB::class) // in the rest
@Provides
fun provideApi(): Api {
return Impl()
}
@Named
@Provides(
Conditional(onlyIn = [ActivityType.Main::class]),
// Nowhere else
)
@Conditional(onlyIn = [ActivityType.Main::class]) // Nowhere else
@Provides
fun provideNamedApi(): Api {
return Impl()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ class CoreBindingsFailureTest(
fun provideObject(c: UnderA): Any = c
@Provides @Named("ok1")
fun provideObject2(c: Optional<Provider<UnderA>>): Any = c
@Provides(Conditional(A::class)) @Named("ok2")
@Provides @Conditional(A::class) @Named("ok2")
fun provideObject3(c: UnderA): Any = c
}
Expand Down

0 comments on commit ccfdd05

Please sign in to comment.