Daniel Pitts
09/16/2024, 5:06 PMinterface ExtensibleAwareKey<E</* magic syntax here*/>> {
fun <B> of(type: KClass<B>): ExtensionKey<E<B>>
}
inline fun <reified B, E</*magicsyntax*/>> ExtensibleAwareKey.of() = of(B::class)
data class TypeDependentKey<B, E>(val type: KClass<B>) : ExtensionKey<E>
// example implementation:
class Describable<E> {
companion object : ExtensibleAwareKey<Describable</*magic*/>> {
override fun <B> of(type: KClass<B>): ExtensionKey<Describable<B>> = TypeDependentKey<B, Describable<B>>(type)
}
}
Ruckus
09/16/2024, 5:43 PMTypeDependencKey<B, ...>
which is ExtensionKey<B>
, but your function expects ExtensionKey<Describable<B>>
.Daniel Pitts
09/16/2024, 5:56 PMTypeDependentKey
, it should extend ExtensionKey<E>
. I've edited my original question.Ruckus
09/16/2024, 6:28 PMDaniel Pitts
09/16/2024, 6:28 PMRuckus
09/16/2024, 6:29 PMRuckus
09/16/2024, 6:30 PMDaniel Pitts
09/16/2024, 6:30 PMDaniel Pitts
09/16/2024, 6:33 PMinterface Extensible {
fun <E : Any> getExtension(key: ExtensionKey<E>): E?
fun <E : Any> putExtension(key: ExtensionKey<E>, value: E)
fun <E : Any> getOrPut(key: ExtensionKey<E>, initializer: () -> E): E
operator fun contains(key: ExtensionKey<*>): Boolean
fun remove(key: ExtensionKey<*>)
fun removeIf(predicate: EntryPredicate)
fun keepIf(predicate: EntryPredicate) = removeIf(predicate.not())
fun forEach(visitor: EntryVisitor)
}
operator fun <B : Extensible, E : Any> B.get(key: TypeDependentExtensionKey<B, E>): E? =
getExtension(key)
operator fun <E : Any> Extensible.get(key: ExtensionKey<E>): E? = getExtension(key)
operator fun <B : Extensible, E : Any> B.set(key: TypeDependentExtensionKey<B, E>, value: E) =
putExtension(key, value)
operator fun <E : Any> Extensible.set(key: ExtensionKey<E>, value: E) = putExtension(key, value)
TypeDependentExtensionKey.kt
open class TypeDependentExtensionKey<B : Extensible, E : Any>(val type: KClass<B>, val equality: Any) :
ExtensionKey<E> {
companion object {
inline operator fun <reified B : Extensible, E : Any> invoke(equality: Any) =
TypeDependentExtensionKey<B, E>(B::class, equality)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is TypeDependentExtensionKey<*, *>) return false
return type == other.type && equality == other.equality
}
override fun hashCode(): Int {
var result = type.hashCode()
result = 31 * result + equality.hashCode()
return result
}
}
Describers.kt
class Describers<B : Any> internal constructor(
private val builder: DescribersBuilderImpl<B> = DescribersBuilderImpl(),
) : DescribersBuilder<B> by builder {
companion object {
inline operator fun <reified B : Extensible> invoke() = TypeDependentExtensionKey<B, Describers<B>>(this)
}
}
Daniel Pitts
09/16/2024, 6:33 PMmyExtension[Describers()]
Daniel Pitts
09/16/2024, 6:34 PMmyExtension[Describers]
Ruckus
09/16/2024, 6:40 PMthis
in your Describers
companion is pointing at the companion, not at an instance of Describers
, so I don't see what good it does for the sake of an equality comparison (though I may just be missing the point of the code)Daniel Pitts
09/16/2024, 6:41 PMDescriber keys
from Other extension keys
.Daniel Pitts
09/16/2024, 6:42 PMDaniel Pitts
09/16/2024, 6:43 PM