kgp_1.9.0..2.0.0__Main.co.touchlab.skie.compilerinject.interceptor.SimpleNamedPhaseInterceptorConfigurer.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.SimpleNamedCompilerPhase
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 SimpleNamedPhaseInterceptorConfigurer :
PhaseInterceptorConfigurer, Context, Input, Output>
where Context : LoggingContext, Context : ConfigChecks {
override fun canConfigurePhase(phase: Any): Boolean = phase is SimpleNamedCompilerPhase<*, *, *>
override fun configure(
configuration: CompilerConfiguration,
phase: SimpleNamedCompilerPhase,
interceptors: List>,
) {
val namedPhase = phase.reflector
val chain = ErasedPhaseInterceptorChain(interceptors)
synchronized(phase) {
val currentPhaseBody = namedPhase.op
val (originalPhaseBody, interceptorKey) = if (currentPhaseBody.isIntercepted()) {
val interceptedPhaseBody = InterceptedPhaseBodyReflector(currentPhaseBody)
interceptedPhaseBody.originalPhaseBody to interceptedPhaseBody.interceptorKey
} else {
currentPhaseBody to CompilerConfigurationKey.create("phaseInterceptor for phase $phase")
}
configuration.put(interceptorKey, chain)
val interceptedPhaseBody = InterceptedPhaseBody(
originalPhaseBody,
interceptorKey,
)
namedPhase.op = interceptedPhaseBody
}
}
private val SimpleNamedCompilerPhase.reflector: SimpleNamedCompilerPhaseReflector
get() = SimpleNamedCompilerPhaseReflector(this)
}
private class InterceptedPhaseBody(
val originalPhaseBody: OriginalPhaseBody,
val interceptorKey: CompilerConfigurationKey>,
) : (Context, Input) -> Output where Context : LoggingContext, Context : ConfigChecks {
override fun invoke(context: Context, input: Input): Output {
val interceptor = context.config.configuration.get(interceptorKey)
return if (interceptor != null) {
interceptor.invoke(context, input, originalPhaseBody)
} else {
originalPhaseBody.invoke(context, input)
}
}
}
private class SimpleNamedCompilerPhaseReflector(
override val instance: SimpleNamedCompilerPhase,
) : Reflector(instance::class) where Context : LoggingContext, Context : ConfigChecks {
var op: (Context, Input) -> Output by declaredField("\$op")
}
private class InterceptedPhaseBodyReflector(
override val instance: (Context, Input) -> Output,
) : Reflector(instance::class) where Context : LoggingContext, Context : ConfigChecks {
val originalPhaseBody: (Context, Input) -> Output by declaredField()
val interceptorKey: CompilerConfigurationKey> by declaredField()
}
private fun ((Context, Input) -> Output).isIntercepted(): Boolean where Context : LoggingContext, Context : ConfigChecks {
return javaClass.name == InterceptedPhaseBody::class.jvmName
}