Skip to content

Commit

Permalink
Merge pull request #151 from yandex/wp/remove-legacy-conditions
Browse files Browse the repository at this point in the history
Api: Remove legacy Condition.
  • Loading branch information
Jeffset committed May 13, 2024
2 parents ccfdd05 + 602bf99 commit e1cbe57
Show file tree
Hide file tree
Showing 28 changed files with 191 additions and 569 deletions.
17 changes: 0 additions & 17 deletions api/public/api/public.api
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
public abstract interface annotation class com/yandex/yatagan/AllConditions : java/lang/annotation/Annotation {
public abstract fun value ()[Lcom/yandex/yatagan/Condition;
}

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

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

public abstract interface annotation class com/yandex/yatagan/Assisted : java/lang/annotation/Annotation {
public abstract fun value ()Ljava/lang/String;
}
Expand Down Expand Up @@ -58,11 +46,6 @@ public abstract interface annotation class com/yandex/yatagan/ComponentFlavor :
public abstract interface annotation class com/yandex/yatagan/ComponentVariantDimension : java/lang/annotation/Annotation {
}

public abstract interface annotation class com/yandex/yatagan/Condition : java/lang/annotation/Annotation {
public abstract fun condition ()Ljava/lang/String;
public abstract fun value ()Ljava/lang/Class;
}

public abstract interface annotation class com/yandex/yatagan/ConditionExpression : java/lang/annotation/Annotation {
public abstract fun importAs ()[Lcom/yandex/yatagan/ConditionExpression$ImportAs;
public abstract fun imports ()[Ljava/lang/Class;
Expand Down
28 changes: 0 additions & 28 deletions api/public/src/main/kotlin/com/yandex/yatagan/AllConditions.kt

This file was deleted.

29 changes: 0 additions & 29 deletions api/public/src/main/kotlin/com/yandex/yatagan/AnyCondition.kt

This file was deleted.

31 changes: 0 additions & 31 deletions api/public/src/main/kotlin/com/yandex/yatagan/AnyConditions.kt

This file was deleted.

2 changes: 1 addition & 1 deletion api/public/src/main/kotlin/com/yandex/yatagan/Binds.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ package com.yandex.yatagan
* This is an _explicitly absent_ binding, which declares that `Api` is always absent (under "never"-condition).
*
* @see Optional
* @see Condition
* @see ConditionExpression
* @see Conditional
*/
@MustBeDocumented
Expand Down
104 changes: 0 additions & 104 deletions api/public/src/main/kotlin/com/yandex/yatagan/Condition.kt

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@ package com.yandex.yatagan
import kotlin.reflect.KClass

/**
* A boolean expression in terms of [Conditional] system.
* This API supersedes the old [Condition]/[AnyCondition] API based on repeatable annotations and
* allows specifying an entire boolean expression using a single annotation and in a much more readable form.
* A boolean expression in terms of [Conditional] system. The expression consists of operations on boolean variables
* (conditions) and is evaluated at runtime.
*
* See [value] on detailed info on how to write expressions.
* ### Features
* A *feature* is an annotation class (`@interface`) declaration, annotated with [ConditionExpression].
* Features are supplied into [Conditional] annotations and may be referenced in other [ConditionExpression]s.
*
* Can not be used together with [Condition]/[AnyCondition] on the same _feature_,
* however different features are compatible with each other without regarding the API used.
* See [value] on detailed info on how to write expressions.
*
* Examples:
* ### Quick examples
* - `@ConditionExpression("!@MyFeature", MyFeature::class)` - negate the other feature.
* - `@ConditionExpression("FEATURE1.isEnabled & !FEATURE2.isEnabled", Features::class)` - single import, so the
* short form is used twice - `FEATURE1` and `FEATURE2` are evaluated on the `Features` class.
Expand All @@ -38,6 +38,19 @@ import kotlin.reflect.KClass
* IsDebug::class, Helper::class)` - qualified usages.
* - `@ConditionExpression("X::isEnabledA | X::isEnabledB & X::isRelease",
* importAs = [ImportAs(MyLongConditionsProviderName::class, "X")])` - [aliased import][importAs].
*
* ### Variable equality and caching
*
* Each boolean variable is computed only once per *its scope* and cached inside the corresponding component object.
* The caching scope is the topmost component where the condition is used. This is done to prevent discrepancies if
* the condition provider may return different results in different time.
*
* Variables in different [ConditionExpression]s are considered equal for caching purposes if and only if their resolved
* *condition providers* and their *access paths* are equal correspondingly.
* See [value] on the syntactic definitions.
*
* The moment where each variable is computed is currently not strictly defined. The framework may decide to compute
* the condition as early as component instance initialization, or it may compute it directly before the first usage.
*/
@ConditionsApi
@MustBeDocumented
Expand Down Expand Up @@ -66,7 +79,52 @@ public annotation class ConditionExpression(
* `@<imported-feature-name>`, e.g. `@ConditionExpression("@MyFeature", MyFeature::class)`.
* This way the entire expression from the `@MyFeature` is embedded into the referencing one.
*
* _Access path_ is interpreted in the same way, as in [Condition.value].
* ### Access path
*
* Each identifier in chain represents a non-private field, method, resolved on a
* resulting type of previous identifier or the root class if this is the first identifier.
* The last identifier must resolve into a primitive boolean result.
*
* If the first member is static, then the resulting condition is a *plain (static) condition* - it can be evaluated
* anywhere from static context.
* If the first member is non-static, then, naturally, an instance of the imported class is required to compute
* the condition. The instance is resolved *as a regular binding dependency*. Thus, it can be provided in any way
* as a normal graph node could be - inject constructor, provision, binds, etc.
*
* Names are considered from Java point of view, not Kotlin! So property names are not a thing, getters should be
* used instead; Kotlin objects are accessed with `.INSTANCE' or `.Companion`.
*
* ### Examples
* ```kotlin
* object SomeObject { val isEnabled = false }
* object SomeClass {
* @JvmStatic fun staticComputeCondition() = false
* @JvmStatic fun staticGetSubObject() = AnotherClass()
* }
* class AnotherClass { val memberCondition = false }
* class WithCompanion { companion object { val prop = false } }
* class ConditionProviderWithInject @Inject constructor() { val memberCondition = true }
*
* // Kotlin's singletons require explicit INSTANCE identifier:
* @ConditionExpression("INSTANCE.isEnabled", SomeObject::class)
* annotation class A
*
* // Static function from a class:
* @ConditionExpression("staticComputeCondition", SomeClass::class)
* annotation class B
*
* // Calls can be chained. Properties are accessible through explicit getters:
* @ConditionExpression("staticGetSubObject.getMemberCondition", SomeClass::class)
* annotation class C
*
* // Companion object must be mentioned explicitly:
* @ConditionExpression("Companion.getProp", WithCompanion::class)
* annotation class D
*
* // Non-static condition - an injectable class with non-static member:
* @ConditionExpression("!getMemberCondition", ConditionProviderWithInject::class)
* annotation class E
* ```
*/
val value: String,

Expand All @@ -77,11 +135,15 @@ public annotation class ConditionExpression(
* Conflicting/duplicated imports are not allowed. If one wishes to import two classes with the same simple name
* or just shorten the long class name to avoid writing it multiple times,
* one can use an [aliased import][importAs].
*
* @see value
*/
vararg val imports: KClass<*>,

/**
* Works the same way as [imports], but allows to import a given class by a specified name.
*
* @see value
*/
val importAs: Array<ImportAs> = [],
) {
Expand Down

0 comments on commit e1cbe57

Please sign in to comment.