
org.jetbrains.kotlin.fir.FirSession.kt Maven / Gradle / Ivy
/*
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.utils.Jsr305State
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
abstract class FirSession(val sessionProvider: FirSessionProvider?) {
open val moduleInfo: ModuleInfo? get() = null
val jsr305State: Jsr305State? get() = null
val builtinTypes: BuiltinTypes = BuiltinTypes()
val components: MutableMap, Any> = mutableMapOf()
internal val componentArray = ComponentArray()
@Suppress("UNCHECKED_CAST")
fun getService(kclass: KClass): T =
components[kclass] as T
protected fun registerComponent(tClass: KClass, t: T) {
assert(tClass !in components) { "Already registered component" }
components[tClass] = t
// TODO: Make t of FirSessionComponent
if (t is FirSessionComponent) {
@Suppress("UNCHECKED_CAST")
componentArray[(tClass as KClass).componentId()] = t
}
}
}
class BuiltinTypes {
val unitType: FirTypeRef = FirImplicitUnitTypeRef(null)
val anyType: FirTypeRef = FirImplicitAnyTypeRef(null)
val nullableAnyType: FirTypeRef = FirImplicitNullableAnyTypeRef(null)
val enumType: FirTypeRef = FirImplicitEnumTypeRef(null)
val annotationType: FirTypeRef = FirImplicitAnnotationTypeRef(null)
val booleanType: FirTypeRef = FirImplicitBooleanTypeRef(null)
val nothingType: FirTypeRef = FirImplicitNothingTypeRef(null)
val nullableNothingType: FirTypeRef = FirImplicitNullableNothingTypeRef(null)
val stringType: FirTypeRef = FirImplicitStringTypeRef(null)
}
interface FirSessionProvider {
fun getSession(moduleInfo: ModuleInfo): FirSession?
}
inline fun FirSession.service(): T =
getService(T::class)
internal object ComponentTypeRegistry {
private val idPerType = mutableMapOf, Int>()
fun id(kClass: KClass): Int {
return idPerType.getOrPut(kClass) { idPerType.size }
}
}
private fun KClass.componentId(): Int {
return ComponentTypeRegistry.id(this)
}
class ComponentArrayAccessor(val type: KClass) : ReadOnlyProperty {
val id: Int = type.componentId()
override fun getValue(thisRef: FirSession, property: KProperty<*>): T {
@Suppress("UNCHECKED_CAST")
return thisRef.componentArray.getOrNull(id) as? T ?: error("No '$type'($id) component in session: $thisRef")
}
}
inline fun componentArrayAccessor(): ComponentArrayAccessor {
return ComponentArrayAccessor(T::class)
}
interface FirSessionComponent
internal class ComponentArray : AbstractList() {
override val size: Int
get() = data.size
private var data = arrayOfNulls(20)
private fun ensureCapacity(index: Int) {
if (data.size < index) {
data = data.copyOf(data.size * 2)
}
}
operator fun set(index: Int, value: FirSessionComponent) {
ensureCapacity(index)
data[index] = value
}
override operator fun get(index: Int): FirSessionComponent? {
return data[index]
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy