From e6d8e67a3acc8db228a24363afc9e2f8fe415374 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 22 Apr 2020 16:09:04 +0300 Subject: [PATCH] [FIR] Generify ComponentArray --- .../kotlin/fir/resolve/ResolveUtils.kt | 12 +-- .../resolve/calls/ConeCallConflictResolver.kt | 3 +- .../org/jetbrains/kotlin/fir/FirSession.kt | 87 ++++--------------- .../kotlin/fir/utils/ComponentArray.kt | 67 ++++++++++++++ 4 files changed, 91 insertions(+), 78 deletions(-) create mode 100644 compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ComponentArray.kt diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index 8c99a325786..16af27e23d9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -52,12 +52,12 @@ inline fun MutableMap.getOrPut(key: K, defaultValue: (K) -> } } -val FirSession.firSymbolProvider: FirSymbolProvider by componentArrayAccessor() -val FirSession.firProvider: FirProvider by componentArrayAccessor() -val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by componentArrayAccessor() -val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by componentArrayAccessor() -val FirSession.qualifierResolver: FirQualifierResolver by componentArrayAccessor() -val FirSession.typeResolver: FirTypeResolver by componentArrayAccessor() +val FirSession.firSymbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor() +val FirSession.firProvider: FirProvider by FirSession.sessionComponentAccessor() +val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by FirSession.sessionComponentAccessor() +val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by FirSession.sessionComponentAccessor() +val FirSession.qualifierResolver: FirQualifierResolver by FirSession.sessionComponentAccessor() +val FirSession.typeResolver: FirTypeResolver by FirSession.sessionComponentAccessor() fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): FirClassLikeSymbol<*>? { if (this is ConeClassLookupTagWithFixedSymbol) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeCallConflictResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeCallConflictResolver.kt index 0d1c832530c..f690f087e90 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeCallConflictResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ConeCallConflictResolver.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.resolve.calls import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSessionComponent -import org.jetbrains.kotlin.fir.componentArrayAccessor import org.jetbrains.kotlin.fir.resolve.inference.InferenceComponents import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator @@ -29,4 +28,4 @@ abstract class ConeCallConflictResolverFactory : FirSessionComponent { abstract fun create(typeSpecificityComparator: TypeSpecificityComparator, components: InferenceComponents): ConeCallConflictResolver } -val FirSession.callConflictResolverFactory by componentArrayAccessor() \ No newline at end of file +val FirSession.callConflictResolverFactory: ConeCallConflictResolverFactory by FirSession.sessionComponentAccessor() \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt index a1a5fd3a73b..ff3528c44bd 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirSession.kt @@ -8,32 +8,33 @@ package org.jetbrains.kotlin.fir import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analyzer.ModuleInfo 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 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() { + companion object : ComponentTypeRegistry() { + inline fun sessionComponentAccessor(): ComponentArrayAccessor { + return generateAccessor(T::class) + } + } + open val moduleInfo: ModuleInfo? get() = null val jsr305State: Jsr305State? get() = null val builtinTypes: BuiltinTypes = BuiltinTypes() - private val registeredComponents: MutableSet> = mutableSetOf() + final override val typeRegistry: ComponentTypeRegistry = Companion +} - internal val componentArray = ComponentArray() +interface FirSessionProvider { + val project: Project - protected fun registerComponent(tClass: KClass, t: T) { - 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).componentId()] = t - } - } + fun getSession(moduleInfo: ModuleInfo): FirSession? } class BuiltinTypes { @@ -47,58 +48,4 @@ class BuiltinTypes { val nothingType: FirImplicitBuiltinTypeRef = FirImplicitNothingTypeRef(null) val nullableNothingType: FirImplicitBuiltinTypeRef = FirImplicitNullableNothingTypeRef(null) val stringType: FirImplicitBuiltinTypeRef = FirImplicitStringTypeRef(null) -} - -interface FirSessionProvider { - val project: Project - - fun getSession(moduleInfo: ModuleInfo): FirSession? -} - -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] - } } \ No newline at end of file diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ComponentArray.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ComponentArray.kt new file mode 100644 index 00000000000..450f204cb08 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/utils/ComponentArray.kt @@ -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 { + internal val componentArray: ComponentArray = ComponentArray() + protected abstract val typeRegistry: ComponentTypeRegistry + + protected fun registerComponent(tClass: KClass, value: V) { + componentArray[(typeRegistry.getId(tClass))] = value + } +} + + +abstract class ComponentTypeRegistry { + private val idPerType = mutableMapOf, Int>() + + fun generateAccessor(kClass: KClass): ComponentArrayAccessor { + return ComponentArrayAccessor(kClass, getId(kClass)) + } + + fun getId(kClass: KClass): Int { + return idPerType.getOrPut(kClass) { idPerType.size } + } +} + + +class ComponentArrayAccessor( + private val key: KClass, + private val id: Int +) : ReadOnlyProperty, V> { + override fun getValue(thisRef: ComponentArrayOwner, property: KProperty<*>): T { + @Suppress("UNCHECKED_CAST") + return thisRef.componentArray[id] as T? ?: error("No '$key'($id) component in session: $thisRef") + } +} + +class ComponentArray { + companion object { + private const val DEFAULT_SIZE = 20 + private const val INCREASE_K = 2 + } + + private var data = arrayOfNulls(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 + } +} \ No newline at end of file