All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kgp_1.9.0..2.0.0__Main.co.touchlab.skie.compilerinject.interceptor.SameTypeNamedPhaseInterceptorConfigurer.kt Maven / Gradle / Ivy

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
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy