kgp_1.9.0..2.0.0__Main.co.touchlab.skie.compilerinject.interceptor.SameTypeNamedPhaseInterceptorConfigurer.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-linker-plugin-kgp_1.9.20 Show documentation
Show all versions of kotlin-compiler-linker-plugin-kgp_1.9.20 Show documentation
Kotlin compiler plugin that improves Swift interface of a Kotlin Multiplatform framework.
The newest version!
package co.touchlab.skie.compilerinject.interceptor
import co.touchlab.skie.compilerinject.reflection.Reflector
import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfigurationService
import org.jetbrains.kotlin.backend.common.phaser.PhaserState
import org.jetbrains.kotlin.backend.common.phaser.SameTypeCompilerPhase
import org.jetbrains.kotlin.backend.common.phaser.SameTypeNamedCompilerPhase
import org.jetbrains.kotlin.backend.konan.ConfigChecks
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.CompilerConfigurationKey
import kotlin.reflect.jvm.jvmName
class SameTypeNamedPhaseInterceptorConfigurer :
SameTypePhaseInterceptorConfigurer, Context, Data> where Context : LoggingContext, Context : ConfigChecks {
override fun canConfigurePhase(phase: Any): Boolean = phase is SameTypeNamedCompilerPhase<*, *>
override fun configure(
configuration: CompilerConfiguration,
phase: SameTypeNamedCompilerPhase,
interceptors: List>,
) {
val namedPhase = phase.reflector
val chain = ErasedPhaseInterceptorChain(interceptors)
synchronized(phase) {
val currentPhase = namedPhase.lower
val (originalPhase, interceptorKey) = if (currentPhase.isIntercepted()) {
val interceptedPhase = InterceptedSameTypeCompilerPhaseReflector(currentPhase)
interceptedPhase.originalPhase to interceptedPhase.interceptorKey
} else {
currentPhase to CompilerConfigurationKey.create("phaseInterceptor for phase $phase")
}
configuration.put(interceptorKey, chain)
val interceptorPhase = InterceptedSameTypeCompilerPhase(originalPhase, interceptorKey)
namedPhase.lower = interceptorPhase
}
}
private val SameTypeNamedCompilerPhase.reflector: SameTypeNamedCompilerPhaseReflector
get() = SameTypeNamedCompilerPhaseReflector(this)
}
private class SameTypeNamedCompilerPhaseReflector(
override val instance: SameTypeNamedCompilerPhase,
) : Reflector(instance::class) where Context : LoggingContext {
var lower: SameTypeCompilerPhase by declaredField()
}
private class InterceptedSameTypeCompilerPhaseReflector(
override val instance: SameTypeCompilerPhase,
) : Reflector(instance::class) where Context : LoggingContext, Context : ConfigChecks {
val originalPhase: SameTypeCompilerPhase by declaredField()
val interceptorKey: CompilerConfigurationKey> by declaredField()
}
private class InterceptedSameTypeCompilerPhase(
val originalPhase: SameTypeCompilerPhase,
val interceptorKey: CompilerConfigurationKey>,
) : SameTypeCompilerPhase where Context : LoggingContext, Context : ConfigChecks {
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState, context: Context, input: Data): Data {
val interceptor = context.config.configuration.get(interceptorKey)
return if (interceptor != null) {
interceptor.invoke(context, input) { innerContext, innerInput ->
originalPhase.invoke(phaseConfig, phaserState, innerContext, innerInput)
}
} else {
originalPhase.invoke(phaseConfig, phaserState, context, input)
}
}
}
private fun SameTypeCompilerPhase.isIntercepted(): Boolean where Context : LoggingContext, Context : ConfigChecks {
return javaClass.name == InterceptedSameTypeCompilerPhase::class.jvmName
}