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

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