[FIR] Generify ComponentArray
This commit is contained in:
@@ -52,12 +52,12 @@ inline fun <K, V, VA : V> MutableMap<K, V>.getOrPut(key: K, defaultValue: (K) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.firSymbolProvider: FirSymbolProvider by componentArrayAccessor()
|
val FirSession.firSymbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor()
|
||||||
val FirSession.firProvider: FirProvider by componentArrayAccessor()
|
val FirSession.firProvider: FirProvider by FirSession.sessionComponentAccessor()
|
||||||
val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by componentArrayAccessor()
|
val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by FirSession.sessionComponentAccessor()
|
||||||
val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by componentArrayAccessor()
|
val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by FirSession.sessionComponentAccessor()
|
||||||
val FirSession.qualifierResolver: FirQualifierResolver by componentArrayAccessor()
|
val FirSession.qualifierResolver: FirQualifierResolver by FirSession.sessionComponentAccessor()
|
||||||
val FirSession.typeResolver: FirTypeResolver by componentArrayAccessor()
|
val FirSession.typeResolver: FirTypeResolver by FirSession.sessionComponentAccessor()
|
||||||
|
|
||||||
fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): FirClassLikeSymbol<*>? {
|
fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): FirClassLikeSymbol<*>? {
|
||||||
if (this is ConeClassLookupTagWithFixedSymbol) {
|
if (this is ConeClassLookupTagWithFixedSymbol) {
|
||||||
|
|||||||
+1
-2
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.componentArrayAccessor
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||||
|
|
||||||
@@ -29,4 +28,4 @@ abstract class ConeCallConflictResolverFactory : FirSessionComponent {
|
|||||||
abstract fun create(typeSpecificityComparator: TypeSpecificityComparator, components: InferenceComponents): ConeCallConflictResolver
|
abstract fun create(typeSpecificityComparator: TypeSpecificityComparator, components: InferenceComponents): ConeCallConflictResolver
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.callConflictResolverFactory by componentArrayAccessor<ConeCallConflictResolverFactory>()
|
val FirSession.callConflictResolverFactory: ConeCallConflictResolverFactory by FirSession.sessionComponentAccessor()
|
||||||
@@ -8,32 +8,33 @@ package org.jetbrains.kotlin.fir
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.fir.types.impl.*
|
import org.jetbrains.kotlin.fir.types.impl.*
|
||||||
|
import org.jetbrains.kotlin.fir.utils.ComponentArrayAccessor
|
||||||
|
import org.jetbrains.kotlin.fir.utils.ComponentArrayOwner
|
||||||
|
import org.jetbrains.kotlin.fir.utils.ComponentTypeRegistry
|
||||||
import org.jetbrains.kotlin.utils.Jsr305State
|
import org.jetbrains.kotlin.utils.Jsr305State
|
||||||
import kotlin.properties.ReadOnlyProperty
|
|
||||||
import kotlin.reflect.KClass
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
abstract class FirSession(val sessionProvider: FirSessionProvider?) {
|
interface FirSessionComponent
|
||||||
|
|
||||||
|
abstract class FirSession(val sessionProvider: FirSessionProvider?) : ComponentArrayOwner<FirSessionComponent, FirSessionComponent>() {
|
||||||
|
companion object : ComponentTypeRegistry<FirSessionComponent, FirSessionComponent>() {
|
||||||
|
inline fun <reified T : FirSessionComponent> sessionComponentAccessor(): ComponentArrayAccessor<FirSessionComponent, FirSessionComponent, T> {
|
||||||
|
return generateAccessor(T::class)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open val moduleInfo: ModuleInfo? get() = null
|
open val moduleInfo: ModuleInfo? get() = null
|
||||||
|
|
||||||
val jsr305State: Jsr305State? get() = null
|
val jsr305State: Jsr305State? get() = null
|
||||||
|
|
||||||
val builtinTypes: BuiltinTypes = BuiltinTypes()
|
val builtinTypes: BuiltinTypes = BuiltinTypes()
|
||||||
|
|
||||||
private val registeredComponents: MutableSet<KClass<*>> = mutableSetOf()
|
final override val typeRegistry: ComponentTypeRegistry<FirSessionComponent, FirSessionComponent> = Companion
|
||||||
|
}
|
||||||
|
|
||||||
internal val componentArray = ComponentArray()
|
interface FirSessionProvider {
|
||||||
|
val project: Project
|
||||||
|
|
||||||
protected fun <T : Any /* TODO: FirSessionComponent */> registerComponent(tClass: KClass<T>, t: T) {
|
fun getSession(moduleInfo: ModuleInfo): FirSession?
|
||||||
assert(tClass !in registeredComponents) { "Already registered component" }
|
|
||||||
registeredComponents += tClass
|
|
||||||
|
|
||||||
// TODO: Make t of FirSessionComponent
|
|
||||||
if (t is FirSessionComponent) {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
componentArray[(tClass as KClass<FirSessionComponent>).componentId()] = t
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BuiltinTypes {
|
class BuiltinTypes {
|
||||||
@@ -47,58 +48,4 @@ class BuiltinTypes {
|
|||||||
val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null)
|
val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null)
|
||||||
val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null)
|
val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null)
|
||||||
val stringType: FirImplicitBuiltinTypeRef = FirImplicitStringTypeRef(null)
|
val stringType: FirImplicitBuiltinTypeRef = FirImplicitStringTypeRef(null)
|
||||||
}
|
|
||||||
|
|
||||||
interface FirSessionProvider {
|
|
||||||
val project: Project
|
|
||||||
|
|
||||||
fun getSession(moduleInfo: ModuleInfo): FirSession?
|
|
||||||
}
|
|
||||||
|
|
||||||
internal object ComponentTypeRegistry {
|
|
||||||
private val idPerType = mutableMapOf<KClass<out FirSessionComponent>, Int>()
|
|
||||||
|
|
||||||
fun <T : FirSessionComponent> id(kClass: KClass<T>): Int {
|
|
||||||
return idPerType.getOrPut(kClass) { idPerType.size }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun <T : FirSessionComponent> KClass<T>.componentId(): Int {
|
|
||||||
return ComponentTypeRegistry.id(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ComponentArrayAccessor<T : FirSessionComponent>(val type: KClass<T>) : ReadOnlyProperty<FirSession, T> {
|
|
||||||
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 <reified T : FirSessionComponent> componentArrayAccessor(): ComponentArrayAccessor<T> {
|
|
||||||
return ComponentArrayAccessor(T::class)
|
|
||||||
}
|
|
||||||
|
|
||||||
interface FirSessionComponent
|
|
||||||
|
|
||||||
internal class ComponentArray : AbstractList<FirSessionComponent?>() {
|
|
||||||
override val size: Int
|
|
||||||
get() = data.size
|
|
||||||
private var data = arrayOfNulls<FirSessionComponent>(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]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.utils
|
||||||
|
|
||||||
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
abstract class ComponentArrayOwner<K : Any, V : Any> {
|
||||||
|
internal val componentArray: ComponentArray<V> = ComponentArray()
|
||||||
|
protected abstract val typeRegistry: ComponentTypeRegistry<K, V>
|
||||||
|
|
||||||
|
protected fun registerComponent(tClass: KClass<out K>, value: V) {
|
||||||
|
componentArray[(typeRegistry.getId(tClass))] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
abstract class ComponentTypeRegistry<K : Any, V : Any> {
|
||||||
|
private val idPerType = mutableMapOf<KClass<out K>, Int>()
|
||||||
|
|
||||||
|
fun <T : V, KK : K> generateAccessor(kClass: KClass<KK>): ComponentArrayAccessor<K, V, T> {
|
||||||
|
return ComponentArrayAccessor(kClass, getId(kClass))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T : K> getId(kClass: KClass<T>): Int {
|
||||||
|
return idPerType.getOrPut(kClass) { idPerType.size }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ComponentArrayAccessor<K : Any, V : Any, T : V>(
|
||||||
|
private val key: KClass<out K>,
|
||||||
|
private val id: Int
|
||||||
|
) : ReadOnlyProperty<ComponentArrayOwner<K, V>, V> {
|
||||||
|
override fun getValue(thisRef: ComponentArrayOwner<K, V>, property: KProperty<*>): T {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return thisRef.componentArray[id] as T? ?: error("No '$key'($id) component in session: $thisRef")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ComponentArray<T : Any> {
|
||||||
|
companion object {
|
||||||
|
private const val DEFAULT_SIZE = 20
|
||||||
|
private const val INCREASE_K = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
private var data = arrayOfNulls<Any>(DEFAULT_SIZE)
|
||||||
|
private fun ensureCapacity(index: Int) {
|
||||||
|
if (data.size < index) {
|
||||||
|
data = data.copyOf(data.size * INCREASE_K)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun set(index: Int, value: T) {
|
||||||
|
ensureCapacity(index)
|
||||||
|
data[index] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun get(index: Int): T? {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return data.getOrNull(index) as T
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user