FIR deserializer: support type-aliases

This commit is contained in:
Simon Ogorodnik
2019-04-18 18:18:53 +03:00
committed by Mikhail Glukhikh
parent e6ab38a583
commit 8324ee7272
6 changed files with 65 additions and 5 deletions
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeSymbol
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
class KotlinDeserializedJvmSymbolsProvider(
val session: FirSession,
@@ -44,13 +46,18 @@ class KotlinDeserializedJvmSymbolsProvider(
) : AbstractFirSymbolProvider() {
private val classesCache = mutableMapOf<ClassId, FirClassSymbol>()
private val typeAliasCache = mutableMapOf<ClassId, FirTypeAliasSymbol?>()
private val packagePartsCache = mutableMapOf<FqName, Collection<PackagePartsCacheData>>()
private class PackagePartsCacheData(val proto: ProtoBuf.Package, val context: FirDeserializationContext) {
val topLevelNameIndex by lazy {
val topLevelFunctionNameIndex by lazy {
proto.functionList.withIndex()
.groupBy({ context.nameResolver.getName(it.value.name) }) { (index) -> index }
}
val typeAliasNameIndex by lazy {
proto.typeAliasList.withIndex()
.groupBy({ context.nameResolver.getName(it.value.name) }) { (index) -> index }
}
}
private val knownClassNamesInPackage = mutableMapOf<FqName, Set<String>?>()
@@ -91,9 +98,24 @@ class KotlinDeserializedJvmSymbolsProvider(
}
override fun getClassLikeSymbolByFqName(classId: ClassId): ConeClassLikeSymbol? {
return findAndDeserializeClass(classId)
return findAndDeserializeClass(classId) ?: findAndDeserializeTypeAlias(classId)
}
private fun findAndDeserializeTypeAlias(
classId: ClassId
): FirTypeAliasSymbol? {
return typeAliasCache.getOrPut(classId) {
getPackageParts(classId.packageFqName).firstNotNullResult { part ->
val ids = part.typeAliasNameIndex[classId.shortClassName]
if (ids == null || ids.isEmpty()) return@firstNotNullResult null
val aliasProto = ids.map { part.proto.getTypeAlias(it) }.single()
part.context.memberDeserializer.loadTypeAlias(aliasProto).symbol
}
}
}
private fun findAndDeserializeClass(
classId: ClassId,
parentContext: FirDeserializationContext? = null
@@ -119,7 +141,7 @@ class KotlinDeserializedJvmSymbolsProvider(
override fun getTopLevelCallableSymbols(packageFqName: FqName, name: Name): List<ConeCallableSymbol> {
return getPackageParts(packageFqName).flatMap { part ->
val functionIds = part.topLevelNameIndex[name] ?: return@flatMap emptyList()
val functionIds = part.topLevelFunctionNameIndex[name] ?: return@flatMap emptyList()
functionIds.map { part.proto.getFunction(it) }
.map {
part.context.memberDeserializer.loadFunction(it).symbol