Optimize FirSession component storage
This commit is contained in:
@@ -34,23 +34,20 @@ class FirJavaModuleBasedSession(
|
|||||||
init {
|
init {
|
||||||
sessionProvider.sessionCache[moduleInfo] = this
|
sessionProvider.sessionCache[moduleInfo] = this
|
||||||
|
|
||||||
_firSymbolProvider = FirCompositeSymbolProvider(
|
|
||||||
listOf(
|
|
||||||
service<FirProvider>(),
|
|
||||||
JavaSymbolProvider(this, sessionProvider.project, scope),
|
|
||||||
dependenciesProvider ?: FirDependenciesSymbolProviderImpl(this)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
registerComponent(
|
registerComponent(
|
||||||
FirSymbolProvider::class,
|
FirSymbolProvider::class,
|
||||||
_firSymbolProvider as FirSymbolProvider
|
FirCompositeSymbolProvider(
|
||||||
|
listOf(
|
||||||
|
service<FirProvider>(),
|
||||||
|
JavaSymbolProvider(this, sessionProvider.project, scope),
|
||||||
|
dependenciesProvider ?: FirDependenciesSymbolProviderImpl(this)
|
||||||
|
)
|
||||||
|
) as FirSymbolProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
_correspondingSupertypesCache = FirCorrespondingSupertypesCache(this)
|
|
||||||
registerComponent(
|
registerComponent(
|
||||||
FirCorrespondingSupertypesCache::class,
|
FirCorrespondingSupertypesCache::class,
|
||||||
_correspondingSupertypesCache as FirCorrespondingSupertypesCache
|
FirCorrespondingSupertypesCache(this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,7 +65,9 @@ class FirLibrarySession private constructor(
|
|||||||
init {
|
init {
|
||||||
sessionProvider.sessionCache[moduleInfo] = this
|
sessionProvider.sessionCache[moduleInfo] = this
|
||||||
val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, scope)
|
val javaSymbolProvider = JavaSymbolProvider(this, sessionProvider.project, scope)
|
||||||
_firSymbolProvider =
|
|
||||||
|
registerComponent(
|
||||||
|
FirSymbolProvider::class,
|
||||||
FirCompositeSymbolProvider(
|
FirCompositeSymbolProvider(
|
||||||
listOf(
|
listOf(
|
||||||
FirLibrarySymbolProviderImpl(this),
|
FirLibrarySymbolProviderImpl(this),
|
||||||
@@ -82,18 +81,13 @@ class FirLibrarySession private constructor(
|
|||||||
javaSymbolProvider,
|
javaSymbolProvider,
|
||||||
FirDependenciesSymbolProviderImpl(this)
|
FirDependenciesSymbolProviderImpl(this)
|
||||||
)
|
)
|
||||||
)
|
) as FirSymbolProvider
|
||||||
|
|
||||||
registerComponent(
|
|
||||||
FirSymbolProvider::class,
|
|
||||||
_firSymbolProvider as FirSymbolProvider
|
|
||||||
)
|
)
|
||||||
registerComponent(FirClassDeclaredMemberScopeProvider::class, FirClassDeclaredMemberScopeProvider())
|
registerComponent(FirClassDeclaredMemberScopeProvider::class, FirClassDeclaredMemberScopeProvider())
|
||||||
|
|
||||||
_correspondingSupertypesCache = FirCorrespondingSupertypesCache(this)
|
|
||||||
registerComponent(
|
registerComponent(
|
||||||
FirCorrespondingSupertypesCache::class,
|
FirCorrespondingSupertypesCache::class,
|
||||||
_correspondingSupertypesCache as FirCorrespondingSupertypesCache
|
FirCorrespondingSupertypesCache(this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.resolve
|
package org.jetbrains.kotlin.fir.resolve
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.declarations.toFirClassLike
|
import org.jetbrains.kotlin.fir.declarations.toFirClassLike
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||||
@@ -17,7 +18,7 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
abstract class FirSymbolProvider {
|
abstract class FirSymbolProvider : FirSessionComponent {
|
||||||
|
|
||||||
abstract fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>?
|
abstract fun getClassLikeSymbolByFqName(classId: ClassId): FirClassLikeSymbol<*>?
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.resolve
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.componentArrayAccessor
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
|
||||||
@@ -36,9 +38,8 @@ inline fun <K, V, VA : V> MutableMap<K, V>.getOrPut(key: K, defaultValue: (K) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val FirSession.firSymbolProvider: FirSymbolProvider get() = _firSymbolProvider as FirSymbolProvider? ?: service()
|
val FirSession.firSymbolProvider: FirSymbolProvider by componentArrayAccessor()
|
||||||
val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache
|
val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by componentArrayAccessor()
|
||||||
get() = _correspondingSupertypesCache as FirCorrespondingSupertypesCache? ?: service()
|
|
||||||
|
|
||||||
fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): ConeClassifierSymbol? {
|
fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): ConeClassifierSymbol? {
|
||||||
val firSymbolProvider = useSiteSession.firSymbolProvider
|
val firSymbolProvider = useSiteSession.firSymbolProvider
|
||||||
|
|||||||
+2
-1
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.declarations.toFirClassLike
|
import org.jetbrains.kotlin.fir.declarations.toFirClassLike
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructClassType
|
import org.jetbrains.kotlin.fir.resolve.constructClassType
|
||||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||||
@@ -16,7 +17,7 @@ import org.jetbrains.kotlin.types.model.CaptureStatus
|
|||||||
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
|
|
||||||
class FirCorrespondingSupertypesCache(private val session: FirSession) {
|
class FirCorrespondingSupertypesCache(private val session: FirSession) : FirSessionComponent {
|
||||||
private val context = ConeTypeCheckerContext(false, session)
|
private val context = ConeTypeCheckerContext(false, session)
|
||||||
private val cache = HashMap<ConeClassLikeSymbol, Map<ConeClassLikeSymbol, List<ConeClassLikeType>>?>(1000, 0.5f)
|
private val cache = HashMap<ConeClassLikeSymbol, Map<ConeClassLikeSymbol, List<ConeClassLikeType>>?>(1000, 0.5f)
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.fir
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||||
import org.jetbrains.kotlin.utils.Jsr305State
|
import org.jetbrains.kotlin.utils.Jsr305State
|
||||||
|
import kotlin.properties.ReadOnlyProperty
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
abstract class FirSession(val sessionProvider: FirSessionProvider?) {
|
abstract class FirSession(val sessionProvider: FirSessionProvider?) {
|
||||||
open val moduleInfo: ModuleInfo? get() = null
|
open val moduleInfo: ModuleInfo? get() = null
|
||||||
@@ -17,16 +19,21 @@ abstract class FirSession(val sessionProvider: FirSessionProvider?) {
|
|||||||
|
|
||||||
val components: MutableMap<KClass<*>, Any> = mutableMapOf()
|
val components: MutableMap<KClass<*>, Any> = mutableMapOf()
|
||||||
|
|
||||||
var _firSymbolProvider: Any? = null
|
internal val componentArray = ComponentArray()
|
||||||
|
|
||||||
var _correspondingSupertypesCache: Any? = null
|
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T : Any> getService(kclass: KClass<T>): T =
|
fun <T : Any> getService(kclass: KClass<T>): T =
|
||||||
components[kclass] as T
|
components[kclass] as T
|
||||||
|
|
||||||
protected fun <T : Any> registerComponent(tClass: KClass<T>, t: T) {
|
protected fun <T : Any /* TODO: FirSessionComponent */> registerComponent(tClass: KClass<T>, t: T) {
|
||||||
assert(tClass !in components) { "Already registered component" }
|
assert(tClass !in components) { "Already registered component" }
|
||||||
components[tClass] = t
|
components[tClass] = t
|
||||||
|
|
||||||
|
// TODO: Make t of FirSessionComponent
|
||||||
|
if (t is FirSessionComponent) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
componentArray[(tClass as KClass<FirSessionComponent>).componentId()] = t
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,3 +43,51 @@ interface FirSessionProvider {
|
|||||||
|
|
||||||
inline fun <reified T : Any> FirSession.service(): T =
|
inline fun <reified T : Any> FirSession.service(): T =
|
||||||
getService(T::class)
|
getService(T::class)
|
||||||
|
|
||||||
|
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]
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user