[LL FIR] StateKeeper: provide context
We need this to be able to construct new elements on the fly during arrangement ^KT-60552
This commit is contained in:
committed by
Space Team
parent
38ef5be217
commit
65fec8dc19
+3
-7
@@ -69,13 +69,9 @@ internal abstract class LLFirAbstractBodyTargetResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun calculateLazyBodies(declaration: FirElementWithResolveState) {
|
protected fun <T : FirElementWithResolveState> resolve(target: T, keeper: StateKeeper<T, FirDesignationWithFile>) {
|
||||||
val firDesignation = FirDesignationWithFile(nestedClassesStack, declaration, resolveTarget.firFile)
|
val firDesignation = FirDesignationWithFile(nestedClassesStack, target, resolveTarget.firFile)
|
||||||
FirLazyBodiesCalculator.calculateBodies(firDesignation)
|
resolveWithKeeper(target, firDesignation, keeper, { FirLazyBodiesCalculator.calculateBodies(firDesignation) }) {
|
||||||
}
|
|
||||||
|
|
||||||
protected fun <T : FirElementWithResolveState> resolve(target: T, keeper: StateKeeper<T>) {
|
|
||||||
resolveWithKeeper(target, keeper, ::calculateLazyBodies) {
|
|
||||||
rawResolve(target)
|
rawResolve(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-8
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyBodiesCalculator.calculateAnnotations
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyBodiesCalculator.calculateAnnotations
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkAnnotationArgumentsMappingIsResolved
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.checkAnnotationArgumentsMappingIsResolved
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.expressionGuard
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.expressionGuard
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
@@ -61,26 +62,26 @@ private class LLFirAnnotationArgumentsMappingTargetResolver(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
|
override fun doLazyResolveUnderLock(target: FirElementWithResolveState) {
|
||||||
resolveWithKeeper(target, AnnotationArgumentMappingStateKeepers.DECLARATION, ::calculateAnnotations) {
|
resolveWithKeeper(target, target.llFirSession, AnnotationArgumentMappingStateKeepers.DECLARATION, ::calculateAnnotations) {
|
||||||
transformAnnotations(target)
|
transformAnnotations(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal object AnnotationArgumentMappingStateKeepers {
|
internal object AnnotationArgumentMappingStateKeepers {
|
||||||
private val ANNOTATION: StateKeeper<FirAnnotation> = stateKeeper {
|
private val ANNOTATION: StateKeeper<FirAnnotation, FirSession> = stateKeeper { _, session ->
|
||||||
add(ANNOTATION_BASE)
|
add(ANNOTATION_BASE, session)
|
||||||
add(FirAnnotation::argumentMapping, FirAnnotation::replaceArgumentMapping)
|
add(FirAnnotation::argumentMapping, FirAnnotation::replaceArgumentMapping)
|
||||||
add(FirAnnotation::typeArgumentsCopied, FirAnnotation::replaceTypeArguments)
|
add(FirAnnotation::typeArgumentsCopied, FirAnnotation::replaceTypeArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val ANNOTATION_BASE: StateKeeper<FirAnnotation> = stateKeeper { annotation ->
|
private val ANNOTATION_BASE: StateKeeper<FirAnnotation, FirSession> = stateKeeper { annotation, session ->
|
||||||
if (annotation is FirAnnotationCall) {
|
if (annotation is FirAnnotationCall) {
|
||||||
entity(annotation, ANNOTATION_CALL)
|
entity(annotation, ANNOTATION_CALL, session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val ANNOTATION_CALL: StateKeeper<FirAnnotationCall> = stateKeeper { annotationCall ->
|
private val ANNOTATION_CALL: StateKeeper<FirAnnotationCall, FirSession> = stateKeeper { annotationCall, _ ->
|
||||||
add(FirAnnotationCall::calleeReference, FirAnnotationCall::replaceCalleeReference)
|
add(FirAnnotationCall::calleeReference, FirAnnotationCall::replaceCalleeReference)
|
||||||
|
|
||||||
val argumentList = annotationCall.argumentList
|
val argumentList = annotationCall.argumentList
|
||||||
@@ -100,12 +101,12 @@ internal object AnnotationArgumentMappingStateKeepers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val DECLARATION: StateKeeper<FirElementWithResolveState> = stateKeeper { target ->
|
val DECLARATION: StateKeeper<FirElementWithResolveState, FirSession> = stateKeeper { target, session ->
|
||||||
val visitor = object : FirVisitorVoid() {
|
val visitor = object : FirVisitorVoid() {
|
||||||
override fun visitElement(element: FirElement) {
|
override fun visitElement(element: FirElement) {
|
||||||
when (element) {
|
when (element) {
|
||||||
is FirDeclaration -> if (element !== target) return // Avoid nested declarations
|
is FirDeclaration -> if (element !== target) return // Avoid nested declarations
|
||||||
is FirAnnotation -> entity(element, ANNOTATION)
|
is FirAnnotation -> entity(element, ANNOTATION, session)
|
||||||
is FirStatement -> return
|
is FirStatement -> return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-16
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
||||||
@@ -154,16 +155,16 @@ private class LLFirBodyTargetResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal object BodyStateKeepers {
|
internal object BodyStateKeepers {
|
||||||
val SCRIPT: StateKeeper<FirScript> = stateKeeper {
|
val SCRIPT: StateKeeper<FirScript, FirDesignationWithFile> = stateKeeper { _, _ ->
|
||||||
// TODO Lazy body is not supported for scripts yet
|
// TODO Lazy body is not supported for scripts yet
|
||||||
}
|
}
|
||||||
|
|
||||||
val ANONYMOUS_INITIALIZER: StateKeeper<FirAnonymousInitializer> = stateKeeper {
|
val ANONYMOUS_INITIALIZER: StateKeeper<FirAnonymousInitializer, FirDesignationWithFile> = stateKeeper { _, _ ->
|
||||||
add(FirAnonymousInitializer::body, FirAnonymousInitializer::replaceBody, ::blockGuard)
|
add(FirAnonymousInitializer::body, FirAnonymousInitializer::replaceBody, ::blockGuard)
|
||||||
add(FirAnonymousInitializer::controlFlowGraphReference, FirAnonymousInitializer::replaceControlFlowGraphReference)
|
add(FirAnonymousInitializer::controlFlowGraphReference, FirAnonymousInitializer::replaceControlFlowGraphReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
val FUNCTION: StateKeeper<FirFunction> = stateKeeper { function ->
|
val FUNCTION: StateKeeper<FirFunction, FirDesignationWithFile> = stateKeeper { function, designation ->
|
||||||
if (function.isCertainlyResolved) {
|
if (function.isCertainlyResolved) {
|
||||||
return@stateKeeper
|
return@stateKeeper
|
||||||
}
|
}
|
||||||
@@ -174,18 +175,18 @@ internal object BodyStateKeepers {
|
|||||||
preserveContractBlock(function)
|
preserveContractBlock(function)
|
||||||
|
|
||||||
add(FirFunction::body, FirFunction::replaceBody, ::blockGuard)
|
add(FirFunction::body, FirFunction::replaceBody, ::blockGuard)
|
||||||
entityList(function.valueParameters, VALUE_PARAMETER)
|
entityList(function.valueParameters, VALUE_PARAMETER, designation)
|
||||||
}
|
}
|
||||||
|
|
||||||
add(FirFunction::controlFlowGraphReference, FirFunction::replaceControlFlowGraphReference)
|
add(FirFunction::controlFlowGraphReference, FirFunction::replaceControlFlowGraphReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
val CONSTRUCTOR: StateKeeper<FirConstructor> = stateKeeper {
|
val CONSTRUCTOR: StateKeeper<FirConstructor, FirDesignationWithFile> = stateKeeper { _, designation ->
|
||||||
add(FUNCTION)
|
add(FUNCTION, designation)
|
||||||
add(FirConstructor::delegatedConstructor, FirConstructor::replaceDelegatedConstructor, ::delegatedConstructorCallGuard)
|
add(FirConstructor::delegatedConstructor, FirConstructor::replaceDelegatedConstructor, ::delegatedConstructorCallGuard)
|
||||||
}
|
}
|
||||||
|
|
||||||
val VARIABLE: StateKeeper<FirVariable> = stateKeeper { variable ->
|
val VARIABLE: StateKeeper<FirVariable, FirDesignationWithFile> = stateKeeper { variable, _ ->
|
||||||
add(FirVariable::returnTypeRef, FirVariable::replaceReturnTypeRef)
|
add(FirVariable::returnTypeRef, FirVariable::replaceReturnTypeRef)
|
||||||
|
|
||||||
if (!isCallableWithSpecialBody(variable)) {
|
if (!isCallableWithSpecialBody(variable)) {
|
||||||
@@ -194,7 +195,7 @@ internal object BodyStateKeepers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val VALUE_PARAMETER: StateKeeper<FirValueParameter> = stateKeeper { valueParameter ->
|
private val VALUE_PARAMETER: StateKeeper<FirValueParameter, FirDesignationWithFile> = stateKeeper { valueParameter, _ ->
|
||||||
if (valueParameter.defaultValue != null) {
|
if (valueParameter.defaultValue != null) {
|
||||||
add(FirValueParameter::defaultValue, FirValueParameter::replaceDefaultValue, ::expressionGuard)
|
add(FirValueParameter::defaultValue, FirValueParameter::replaceDefaultValue, ::expressionGuard)
|
||||||
}
|
}
|
||||||
@@ -202,31 +203,31 @@ internal object BodyStateKeepers {
|
|||||||
add(FirValueParameter::controlFlowGraphReference, FirValueParameter::replaceControlFlowGraphReference)
|
add(FirValueParameter::controlFlowGraphReference, FirValueParameter::replaceControlFlowGraphReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
val FIELD: StateKeeper<FirField> = stateKeeper {
|
val FIELD: StateKeeper<FirField, FirDesignationWithFile> = stateKeeper { _, designation ->
|
||||||
add(VARIABLE)
|
add(VARIABLE, designation)
|
||||||
add(FirField::controlFlowGraphReference, FirField::replaceControlFlowGraphReference)
|
add(FirField::controlFlowGraphReference, FirField::replaceControlFlowGraphReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
val PROPERTY: StateKeeper<FirProperty> = stateKeeper { property ->
|
val PROPERTY: StateKeeper<FirProperty, FirDesignationWithFile> = stateKeeper { property, designation ->
|
||||||
if (property.bodyResolveState >= FirPropertyBodyResolveState.EVERYTHING_RESOLVED) {
|
if (property.bodyResolveState >= FirPropertyBodyResolveState.EVERYTHING_RESOLVED) {
|
||||||
return@stateKeeper
|
return@stateKeeper
|
||||||
}
|
}
|
||||||
|
|
||||||
add(VARIABLE)
|
add(VARIABLE, designation)
|
||||||
|
|
||||||
add(FirProperty::bodyResolveState, FirProperty::replaceBodyResolveState)
|
add(FirProperty::bodyResolveState, FirProperty::replaceBodyResolveState)
|
||||||
add(FirProperty::returnTypeRef, FirProperty::replaceReturnTypeRef)
|
add(FirProperty::returnTypeRef, FirProperty::replaceReturnTypeRef)
|
||||||
|
|
||||||
entity(property.getterIfUnresolved, FUNCTION)
|
entity(property.getterIfUnresolved, FUNCTION, designation)
|
||||||
entity(property.setterIfUnresolved, FUNCTION)
|
entity(property.setterIfUnresolved, FUNCTION, designation)
|
||||||
entity(property.backingFieldIfUnresolved, VARIABLE)
|
entity(property.backingFieldIfUnresolved, VARIABLE, designation)
|
||||||
|
|
||||||
add(FirProperty::controlFlowGraphReference, FirProperty::replaceControlFlowGraphReference)
|
add(FirProperty::controlFlowGraphReference, FirProperty::replaceControlFlowGraphReference)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context(StateKeeperBuilder)
|
context(StateKeeperBuilder)
|
||||||
private fun StateKeeperScope<FirFunction>.preserveContractBlock(function: FirFunction) {
|
private fun StateKeeperScope<FirFunction, FirDesignationWithFile>.preserveContractBlock(function: FirFunction) {
|
||||||
val oldBody = function.body
|
val oldBody = function.body
|
||||||
if (oldBody == null || oldBody is FirLazyBlock) {
|
if (oldBody == null || oldBody is FirLazyBlock) {
|
||||||
return
|
return
|
||||||
|
|||||||
+15
-14
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.FirDesignationWithFile
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.targets.LLFirResolveTarget
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.builder.LLFirLockProvider
|
||||||
@@ -77,11 +78,11 @@ private class LLFirContractsTargetResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private object ContractStateKeepers {
|
private object ContractStateKeepers {
|
||||||
private val CONTRACT_DESCRIPTION_OWNER: StateKeeper<FirContractDescriptionOwner> = stateKeeper {
|
private val CONTRACT_DESCRIPTION_OWNER: StateKeeper<FirContractDescriptionOwner, FirDesignationWithFile> = stateKeeper { _, _ ->
|
||||||
add(FirContractDescriptionOwner::contractDescription, FirContractDescriptionOwner::replaceContractDescription)
|
add(FirContractDescriptionOwner::contractDescription, FirContractDescriptionOwner::replaceContractDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val BODY_OWNER: StateKeeper<FirFunction> = stateKeeper { declaration ->
|
private val BODY_OWNER: StateKeeper<FirFunction, FirDesignationWithFile> = stateKeeper { declaration, _ ->
|
||||||
if (declaration is FirContractDescriptionOwner && declaration.contractDescription is FirRawContractDescription) {
|
if (declaration is FirContractDescriptionOwner && declaration.contractDescription is FirRawContractDescription) {
|
||||||
// No need to change the body, contract is declared separately
|
// No need to change the body, contract is declared separately
|
||||||
return@stateKeeper
|
return@stateKeeper
|
||||||
@@ -92,23 +93,23 @@ private object ContractStateKeepers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val SIMPLE_FUNCTION: StateKeeper<FirSimpleFunction> = stateKeeper {
|
val SIMPLE_FUNCTION: StateKeeper<FirSimpleFunction, FirDesignationWithFile> = stateKeeper { _, designation ->
|
||||||
add(CONTRACT_DESCRIPTION_OWNER)
|
add(CONTRACT_DESCRIPTION_OWNER, designation)
|
||||||
add(BODY_OWNER)
|
add(BODY_OWNER, designation)
|
||||||
}
|
}
|
||||||
|
|
||||||
val CONSTRUCTOR: StateKeeper<FirConstructor> = stateKeeper {
|
val CONSTRUCTOR: StateKeeper<FirConstructor, FirDesignationWithFile> = stateKeeper { _, designation ->
|
||||||
add(CONTRACT_DESCRIPTION_OWNER)
|
add(CONTRACT_DESCRIPTION_OWNER, designation)
|
||||||
add(BODY_OWNER)
|
add(BODY_OWNER, designation)
|
||||||
}
|
}
|
||||||
|
|
||||||
val PROPERTY_ACCESSOR: StateKeeper<FirPropertyAccessor> = stateKeeper {
|
val PROPERTY_ACCESSOR: StateKeeper<FirPropertyAccessor, FirDesignationWithFile> = stateKeeper { _, designation ->
|
||||||
add(CONTRACT_DESCRIPTION_OWNER)
|
add(CONTRACT_DESCRIPTION_OWNER, designation)
|
||||||
add(BODY_OWNER)
|
add(BODY_OWNER, designation)
|
||||||
}
|
}
|
||||||
|
|
||||||
val PROPERTY: StateKeeper<FirProperty> = stateKeeper { property ->
|
val PROPERTY: StateKeeper<FirProperty, FirDesignationWithFile> = stateKeeper { property, designation ->
|
||||||
entity(property.getter, PROPERTY_ACCESSOR)
|
entity(property.getter, PROPERTY_ACCESSOR, designation)
|
||||||
entity(property.setter, PROPERTY_ACCESSOR)
|
entity(property.setter, PROPERTY_ACCESSOR, designation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+33
-23
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.low.level.api.fir.transformers
|
|||||||
import com.intellij.openapi.util.registry.Registry
|
import com.intellij.openapi.util.registry.Registry
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
import org.jetbrains.kotlin.fir.FirElementWithResolveState
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
import org.jetbrains.kotlin.fir.expressions.FirStatement
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
@@ -29,7 +30,7 @@ internal interface StateKeeperBuilder {
|
|||||||
|
|
||||||
@JvmInline
|
@JvmInline
|
||||||
@StateKeeperDsl
|
@StateKeeperDsl
|
||||||
internal value class StateKeeperScope<Owner : Any>(private val owner: Owner) {
|
internal value class StateKeeperScope<Owner : Any, Context : Any>(private val owner: Owner) {
|
||||||
/**
|
/**
|
||||||
* Defines an entity state preservation rule.
|
* Defines an entity state preservation rule.
|
||||||
*
|
*
|
||||||
@@ -77,9 +78,9 @@ internal value class StateKeeperScope<Owner : Any>(private val owner: Owner) {
|
|||||||
* In other words, applies all rules defined in the [keeper] to the current entity.
|
* In other words, applies all rules defined in the [keeper] to the current entity.
|
||||||
*/
|
*/
|
||||||
context(StateKeeperBuilder)
|
context(StateKeeperBuilder)
|
||||||
fun add(keeper: StateKeeper<Owner>) {
|
fun add(keeper: StateKeeper<Owner, Context>, context: Context) {
|
||||||
val owner = this@StateKeeperScope.owner
|
val owner = this@StateKeeperScope.owner
|
||||||
register(keeper.prepare(owner))
|
register(keeper.prepare(owner, context))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,9 +100,9 @@ internal value class StateKeeperScope<Owner : Any>(private val owner: Owner) {
|
|||||||
* Does nothing if the [entity] is `null`.
|
* Does nothing if the [entity] is `null`.
|
||||||
*/
|
*/
|
||||||
context(StateKeeperBuilder)
|
context(StateKeeperBuilder)
|
||||||
internal fun <Entity : Any> entity(entity: Entity?, keeper: StateKeeper<Entity>) {
|
internal fun <Entity : Any, Context : Any> entity(entity: Entity?, keeper: StateKeeper<Entity, Context>, context: Context) {
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
StateKeeperScope(entity).add(keeper)
|
StateKeeperScope<Entity, Context>(entity).add(keeper, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,9 +111,13 @@ internal fun <Entity : Any> entity(entity: Entity?, keeper: StateKeeper<Entity>)
|
|||||||
* Does nothing if the [entity] is `null`.
|
* Does nothing if the [entity] is `null`.
|
||||||
*/
|
*/
|
||||||
context(StateKeeperBuilder)
|
context(StateKeeperBuilder)
|
||||||
internal inline fun <Entity : Any> entity(entity: Entity?, block: StateKeeperScope<Entity>.(Entity) -> Unit) {
|
internal inline fun <Entity : Any, Context : Any> entity(
|
||||||
|
entity: Entity?,
|
||||||
|
context: Context,
|
||||||
|
block: StateKeeperScope<Entity, Context>.(Entity, Context) -> Unit,
|
||||||
|
) {
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
StateKeeperScope(entity).block(entity)
|
StateKeeperScope<Entity, Context>(entity).block(entity, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,11 +127,11 @@ internal inline fun <Entity : Any> entity(entity: Entity?, block: StateKeeperSco
|
|||||||
* Skips `null` elements in the [list].
|
* Skips `null` elements in the [list].
|
||||||
*/
|
*/
|
||||||
context(StateKeeperBuilder)
|
context(StateKeeperBuilder)
|
||||||
internal fun <Entity : Any> entityList(list: List<Entity?>?, keeper: StateKeeper<Entity>) {
|
internal fun <Entity : Any, Context : Any> entityList(list: List<Entity?>?, keeper: StateKeeper<Entity, Context>, context: Context) {
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
for (entity in list) {
|
for (entity in list) {
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
StateKeeperScope(entity).add(keeper)
|
StateKeeperScope<Entity, Context>(entity).add(keeper, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -138,11 +143,15 @@ internal fun <Entity : Any> entityList(list: List<Entity?>?, keeper: StateKeeper
|
|||||||
* Skips `null` elements in the [list].
|
* Skips `null` elements in the [list].
|
||||||
*/
|
*/
|
||||||
context(StateKeeperBuilder)
|
context(StateKeeperBuilder)
|
||||||
internal inline fun <Entity : Any> entityList(list: List<Entity?>?, block: StateKeeperScope<Entity>.(Entity) -> Unit) {
|
internal inline fun <Entity : Any, Context : Any> entityList(
|
||||||
|
list: List<Entity?>?,
|
||||||
|
context: Context,
|
||||||
|
block: StateKeeperScope<Entity, Context>.(Entity, Context) -> Unit,
|
||||||
|
) {
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
for (entity in list) {
|
for (entity in list) {
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
StateKeeperScope(entity).block(entity)
|
StateKeeperScope<Entity, Context>(entity).block(entity, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -156,8 +165,8 @@ internal inline fun <Entity : Any> entityList(list: List<Entity?>?, block: State
|
|||||||
* The function collects rules for each individual owner separately.
|
* The function collects rules for each individual owner separately.
|
||||||
* Nested owners can be handled inside [entity] or [entityList] blocks.
|
* Nested owners can be handled inside [entity] or [entityList] blocks.
|
||||||
*/
|
*/
|
||||||
internal fun <Owner : Any> stateKeeper(block: context(StateKeeperBuilder) StateKeeperScope<Owner>.(Owner) -> Unit): StateKeeper<Owner> {
|
internal fun <Owner : Any, Context : Any> stateKeeper(block: context(StateKeeperBuilder) StateKeeperScope<Owner, Context>.(Owner, Context) -> Unit): StateKeeper<Owner, Context> {
|
||||||
return StateKeeper { owner ->
|
return StateKeeper { owner, context ->
|
||||||
val states = mutableListOf<PreservedState>()
|
val states = mutableListOf<PreservedState>()
|
||||||
|
|
||||||
val builder = object : StateKeeperBuilder {
|
val builder = object : StateKeeperBuilder {
|
||||||
@@ -166,8 +175,8 @@ internal fun <Owner : Any> stateKeeper(block: context(StateKeeperBuilder) StateK
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val scope = StateKeeperScope(owner)
|
val scope = StateKeeperScope<Owner, Context>(owner)
|
||||||
block(builder, scope, owner)
|
block(builder, scope, owner, context)
|
||||||
|
|
||||||
object : PreservedState {
|
object : PreservedState {
|
||||||
private var isPostProcessed = false
|
private var isPostProcessed = false
|
||||||
@@ -222,13 +231,13 @@ internal fun <Owner : Any> stateKeeper(block: context(StateKeeperBuilder) StateK
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
internal class StateKeeper<in Owner : Any>(val provider: (Owner) -> PreservedState) {
|
internal class StateKeeper<in Owner : Any, Context : Any>(val provider: (Owner, Context) -> PreservedState) {
|
||||||
/**
|
/**
|
||||||
* Backs up the [owner] state by calling providers, and potentially tweaks the object state with arrangers.
|
* Backs up the [owner] state by calling providers, and potentially tweaks the object state with arrangers.
|
||||||
* Note that post-processors are not run during preparation.
|
* Note that post-processors are not run during preparation.
|
||||||
*/
|
*/
|
||||||
fun prepare(owner: Owner): PreservedState {
|
fun prepare(owner: Owner, context: Context): PreservedState {
|
||||||
return provider(owner)
|
return provider(owner, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,11 +260,12 @@ internal interface PreservedState {
|
|||||||
fun restore()
|
fun restore()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal inline fun <Target : FirElementWithResolveState, Result> resolveWithKeeper(
|
internal inline fun <Target : FirElementWithResolveState, Context : Any, Result> resolveWithKeeper(
|
||||||
target: Target,
|
target: Target,
|
||||||
keeper: StateKeeper<Target>,
|
context: Context,
|
||||||
prepareTarget: (Target) -> Unit,
|
keeper: StateKeeper<Target, Context>,
|
||||||
action: () -> Result
|
prepareTarget: (Target) -> Unit = {},
|
||||||
|
action: () -> Result,
|
||||||
): Result {
|
): Result {
|
||||||
if (!USE_STATE_KEEPER) {
|
if (!USE_STATE_KEEPER) {
|
||||||
prepareTarget(target)
|
prepareTarget(target)
|
||||||
@@ -274,7 +284,7 @@ internal inline fun <Target : FirElementWithResolveState, Result> resolveWithKee
|
|||||||
var preservedState: PreservedState? = null
|
var preservedState: PreservedState? = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
preservedState = keeper.prepare(target)
|
preservedState = keeper.prepare(target, context)
|
||||||
prepareTarget(target)
|
prepareTarget(target)
|
||||||
preservedState.postProcess()
|
preservedState.postProcess()
|
||||||
return action()
|
return action()
|
||||||
|
|||||||
+16
-16
@@ -22,7 +22,7 @@ class StateKeeperTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val keeper: StateKeeper<Foo> = stateKeeper {
|
val keeper: StateKeeper<Foo, Unit> = stateKeeper { _, _ ->
|
||||||
add(Foo::getValue, Foo::setValue)
|
add(Foo::getValue, Foo::setValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ class StateKeeperTest {
|
|||||||
fun testProperty() {
|
fun testProperty() {
|
||||||
class Foo(var value: String)
|
class Foo(var value: String)
|
||||||
|
|
||||||
val keeper: StateKeeper<Foo> = stateKeeper {
|
val keeper: StateKeeper<Foo, Unit> = stateKeeper { _, _ ->
|
||||||
add(Foo::value::get, Foo::value::set)
|
add(Foo::value::get, Foo::value::set)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ class StateKeeperTest {
|
|||||||
fun testArranger() {
|
fun testArranger() {
|
||||||
class Foo(var value: String)
|
class Foo(var value: String)
|
||||||
|
|
||||||
val keeper: StateKeeper<Foo> = stateKeeper {
|
val keeper: StateKeeper<Foo, Unit> = stateKeeper { _, _ ->
|
||||||
add(Foo::value::get, Foo::value::set) { "Baz" }
|
add(Foo::value::get, Foo::value::set) { "Baz" }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,12 +80,12 @@ class StateKeeperTest {
|
|||||||
open class Foo(var one: String)
|
open class Foo(var one: String)
|
||||||
class Bar(one: String, var two: Int) : Foo(one)
|
class Bar(one: String, var two: Int) : Foo(one)
|
||||||
|
|
||||||
val fooKeeper: StateKeeper<Foo> = stateKeeper {
|
val fooKeeper: StateKeeper<Foo, Unit> = stateKeeper { _, _ ->
|
||||||
add(Foo::one::get, Foo::one::set)
|
add(Foo::one::get, Foo::one::set)
|
||||||
}
|
}
|
||||||
|
|
||||||
val barKeeper: StateKeeper<Bar> = stateKeeper {
|
val barKeeper: StateKeeper<Bar, Unit> = stateKeeper { _, context ->
|
||||||
add(fooKeeper)
|
add(fooKeeper, context)
|
||||||
add(Bar::two::get, Bar::two::set)
|
add(Bar::two::get, Bar::two::set)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,9 +109,9 @@ class StateKeeperTest {
|
|||||||
data class Foo(var value: Int)
|
data class Foo(var value: Int)
|
||||||
class Bar(var one: String, var foo: Foo)
|
class Bar(var one: String, var foo: Foo)
|
||||||
|
|
||||||
val barKeeper: StateKeeper<Bar> = stateKeeper { bar ->
|
val barKeeper: StateKeeper<Bar, Unit> = stateKeeper { bar, context ->
|
||||||
add(Bar::one::get, Bar::one::set)
|
add(Bar::one::get, Bar::one::set)
|
||||||
entity(bar.foo) {
|
entity(bar.foo, context) { _, _ ->
|
||||||
add(Foo::value::get, Foo::value::set)
|
add(Foo::value::get, Foo::value::set)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,13 +140,13 @@ class StateKeeperTest {
|
|||||||
data class Foo(var value: Int)
|
data class Foo(var value: Int)
|
||||||
class Bar(var one: String, var foo: Foo)
|
class Bar(var one: String, var foo: Foo)
|
||||||
|
|
||||||
val fooKeeper: StateKeeper<Foo> = stateKeeper {
|
val fooKeeper: StateKeeper<Foo, Unit> = stateKeeper { _, _ ->
|
||||||
add(Foo::value::get, Foo::value::set)
|
add(Foo::value::get, Foo::value::set)
|
||||||
}
|
}
|
||||||
|
|
||||||
val barKeeper: StateKeeper<Bar> = stateKeeper { bar ->
|
val barKeeper: StateKeeper<Bar, Unit> = stateKeeper { bar, context ->
|
||||||
add(Bar::one::get, Bar::one::set)
|
add(Bar::one::get, Bar::one::set)
|
||||||
entity(bar.foo, fooKeeper)
|
entity(bar.foo, fooKeeper, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
val foo = Foo(1)
|
val foo = Foo(1)
|
||||||
@@ -173,9 +173,9 @@ class StateKeeperTest {
|
|||||||
data class Foo(var value: Int)
|
data class Foo(var value: Int)
|
||||||
class Bar(var one: String, var foos: List<Foo>)
|
class Bar(var one: String, var foos: List<Foo>)
|
||||||
|
|
||||||
val barKeeper: StateKeeper<Bar> = stateKeeper { bar ->
|
val barKeeper: StateKeeper<Bar, Unit> = stateKeeper { bar, context ->
|
||||||
add(Bar::one::get, Bar::one::set)
|
add(Bar::one::get, Bar::one::set)
|
||||||
entityList(bar.foos) {
|
entityList(bar.foos, context) { _, _ ->
|
||||||
add(Foo::value::get, Foo::value::set) { it + 1 }
|
add(Foo::value::get, Foo::value::set) { it + 1 }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,7 +209,7 @@ class StateKeeperTest {
|
|||||||
fun testPostProcess() {
|
fun testPostProcess() {
|
||||||
class Foo(var value: String)
|
class Foo(var value: String)
|
||||||
|
|
||||||
val keeper: StateKeeper<Foo> = stateKeeper { foo ->
|
val keeper: StateKeeper<Foo, Unit> = stateKeeper { foo, _ ->
|
||||||
add(Foo::value::get, Foo::value::set) { "Baz" }
|
add(Foo::value::get, Foo::value::set) { "Baz" }
|
||||||
|
|
||||||
postProcess {
|
postProcess {
|
||||||
@@ -229,8 +229,8 @@ class StateKeeperTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <T : Any> StateKeeper<T>.withRestoration(owner: T, block: () -> Unit) {
|
private fun <T : Any> StateKeeper<T, Unit>.withRestoration(owner: T, block: () -> Unit) {
|
||||||
val state = prepare(owner)
|
val state = prepare(owner, Unit)
|
||||||
state.postProcess()
|
state.postProcess()
|
||||||
block()
|
block()
|
||||||
state.restore()
|
state.restore()
|
||||||
|
|||||||
Reference in New Issue
Block a user