FIR: use FirCachesFactory in BuiltInsPackageFragment.tryGetSyntheticFunctionalInterface
This commit is contained in:
committed by
teamcityserver
parent
ba2315430b
commit
f361312e45
+179
-171
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.caches.firCachesFactory
|
||||
import org.jetbrains.kotlin.fir.caches.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction
|
||||
@@ -47,11 +47,8 @@ open class FirBuiltinSymbolProvider(
|
||||
val moduleData: FirModuleData,
|
||||
val kotlinScopeProvider: FirKotlinScopeProvider
|
||||
) : FirSymbolProvider(session) {
|
||||
|
||||
private data class SyntheticFunctionalInterfaceSymbolKey(val kind: FunctionClassKind, val arity: Int)
|
||||
|
||||
private val allPackageFragments = loadBuiltIns().groupBy { it.fqName }
|
||||
private val syntheticFunctionalInterfaceSymbols = mutableMapOf<SyntheticFunctionalInterfaceSymbolKey, FirRegularClassSymbol>()
|
||||
private val syntheticFunctionalInterfaceCache = SyntheticFunctionalInterfaceCache(moduleData, kotlinScopeProvider)
|
||||
|
||||
private fun loadBuiltIns(): List<BuiltInsPackageFragment> {
|
||||
val classLoader = this::class.java.classLoader
|
||||
@@ -61,7 +58,7 @@ open class FirBuiltinSymbolProvider(
|
||||
return packageFqNames.map { fqName ->
|
||||
val resourcePath = BuiltInSerializerProtocol.getBuiltInsFilePath(fqName)
|
||||
val inputStream = streamProvider(resourcePath) ?: throw IllegalStateException("Resource not found in classpath: $resourcePath")
|
||||
BuiltInsPackageFragment(inputStream, fqName)
|
||||
BuiltInsPackageFragment(inputStream, fqName, moduleData, kotlinScopeProvider)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,164 +70,9 @@ open class FirBuiltinSymbolProvider(
|
||||
override fun getClassLikeSymbolByFqName(classId: ClassId): FirRegularClassSymbol? {
|
||||
return allPackageFragments[classId.packageFqName]?.firstNotNullOfOrNull {
|
||||
it.getClassLikeSymbolByFqName(classId)
|
||||
} ?: trySyntheticFunctionalInterface(classId)
|
||||
} ?: syntheticFunctionalInterfaceCache.tryGetSyntheticFunctionalInterface(classId)
|
||||
}
|
||||
|
||||
private fun trySyntheticFunctionalInterface(classId: ClassId): FirRegularClassSymbol? {
|
||||
return with(classId) {
|
||||
val className = relativeClassName.asString()
|
||||
val kind = FunctionClassKind.byClassNamePrefix(packageFqName, className) ?: return@with null
|
||||
val prefix = kind.classNamePrefix
|
||||
val arity = className.substring(prefix.length).toIntOrNull() ?: return null
|
||||
syntheticFunctionalInterfaceSymbols.getOrPut(SyntheticFunctionalInterfaceSymbolKey(kind, arity)) {
|
||||
FirRegularClassSymbol(this).apply symbol@{
|
||||
buildRegularClass klass@{
|
||||
moduleData = this@FirBuiltinSymbolProvider.moduleData
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
name = relativeClassName.shortName()
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
Visibilities.Public,
|
||||
Modality.ABSTRACT,
|
||||
EffectiveVisibility.Public
|
||||
).apply {
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isInner = false
|
||||
isCompanion = false
|
||||
isData = false
|
||||
isInline = false
|
||||
}
|
||||
classKind = ClassKind.INTERFACE
|
||||
scopeProvider = kotlinScopeProvider
|
||||
symbol = this@symbol
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
typeParameters.addAll(
|
||||
(1..arity).map {
|
||||
buildTypeParameter {
|
||||
moduleData = this@FirBuiltinSymbolProvider.moduleData
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
name = Name.identifier("P$it")
|
||||
symbol = FirTypeParameterSymbol()
|
||||
variance = Variance.IN_VARIANCE
|
||||
isReified = false
|
||||
bounds += session.builtinTypes.nullableAnyType
|
||||
}
|
||||
},
|
||||
)
|
||||
typeParameters.add(
|
||||
buildTypeParameter {
|
||||
moduleData = this@FirBuiltinSymbolProvider.moduleData
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
name = Name.identifier("R")
|
||||
symbol = FirTypeParameterSymbol()
|
||||
variance = Variance.OUT_VARIANCE
|
||||
isReified = false
|
||||
bounds += session.builtinTypes.nullableAnyType
|
||||
},
|
||||
)
|
||||
val name = OperatorNameConventions.INVOKE
|
||||
val functionStatus = FirResolvedDeclarationStatusImpl(
|
||||
Visibilities.Public,
|
||||
Modality.ABSTRACT,
|
||||
EffectiveVisibility.Public
|
||||
).apply {
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
isOperator = true
|
||||
isInfix = false
|
||||
isInline = false
|
||||
isTailRec = false
|
||||
isExternal = false
|
||||
isSuspend =
|
||||
kind == FunctionClassKind.SuspendFunction ||
|
||||
kind == FunctionClassKind.KSuspendFunction
|
||||
}
|
||||
val typeArguments = typeParameters.map {
|
||||
buildResolvedTypeRef {
|
||||
type = ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||
}
|
||||
}
|
||||
|
||||
fun createSuperType(
|
||||
kind: FunctionClassKind,
|
||||
): FirResolvedTypeRef {
|
||||
return buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(kind.classId(arity))
|
||||
.constructClassType(typeArguments.map { it.type }.toTypedArray(), isNullable = false)
|
||||
}
|
||||
}
|
||||
|
||||
superTypeRefs += when (kind) {
|
||||
FunctionClassKind.Function -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.Function)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
}
|
||||
)
|
||||
|
||||
FunctionClassKind.SuspendFunction -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.Function)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
}
|
||||
)
|
||||
|
||||
FunctionClassKind.KFunction -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.KFunction)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
},
|
||||
createSuperType(FunctionClassKind.Function)
|
||||
)
|
||||
|
||||
FunctionClassKind.KSuspendFunction -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.KFunction)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
},
|
||||
createSuperType(FunctionClassKind.SuspendFunction)
|
||||
)
|
||||
}
|
||||
addDeclaration(
|
||||
buildSimpleFunction {
|
||||
moduleData = this@FirBuiltinSymbolProvider.moduleData
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
returnTypeRef = typeArguments.last()
|
||||
this.name = name
|
||||
status = functionStatus
|
||||
symbol = FirNamedFunctionSymbol(
|
||||
CallableId(packageFqName, relativeClassName, name)
|
||||
)
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
valueParameters += typeArguments.dropLast(1).mapIndexed { index, typeArgument ->
|
||||
val parameterName = Name.identifier("p${index + 1}")
|
||||
buildValueParameter {
|
||||
moduleData = this@FirBuiltinSymbolProvider.moduleData
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
returnTypeRef = typeArgument
|
||||
this.name = parameterName
|
||||
symbol = FirVariableSymbol(parameterName)
|
||||
defaultValue = null
|
||||
isCrossinline = false
|
||||
isNoinline = false
|
||||
isVararg = false
|
||||
}
|
||||
}
|
||||
dispatchReceiverType = classId.defaultType(this@klass.typeParameters.map { it.symbol })
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun FunctionClassKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity))
|
||||
|
||||
@FirSymbolProviderInternals
|
||||
override fun getTopLevelCallableSymbolsTo(destination: MutableList<FirCallableSymbol<*>>, packageFqName: FqName, name: Name) {
|
||||
@@ -254,7 +96,10 @@ open class FirBuiltinSymbolProvider(
|
||||
override fun getTopLevelPropertySymbolsTo(destination: MutableList<FirPropertySymbol>, packageFqName: FqName, name: Name) {
|
||||
}
|
||||
|
||||
private inner class BuiltInsPackageFragment(stream: InputStream, val fqName: FqName) {
|
||||
private class BuiltInsPackageFragment(
|
||||
stream: InputStream, val fqName: FqName, val moduleData: FirModuleData,
|
||||
val kotlinScopeProvider: FirKotlinScopeProvider,
|
||||
) {
|
||||
|
||||
private val binaryVersionAndPackageFragment = BinaryVersionAndPackageFragment.createFromStream(stream)
|
||||
|
||||
@@ -268,23 +113,22 @@ open class FirBuiltinSymbolProvider(
|
||||
private val memberDeserializer by lazy {
|
||||
FirDeserializationContext.createForPackage(
|
||||
fqName, packageProto.`package`, nameResolver, moduleData,
|
||||
FirBuiltinAnnotationDeserializer(session),
|
||||
FirConstDeserializer(session),
|
||||
FirBuiltinAnnotationDeserializer(moduleData.session),
|
||||
FirConstDeserializer(moduleData.session),
|
||||
containerSource = null
|
||||
).memberDeserializer
|
||||
}
|
||||
|
||||
private val lookup = session.firCachesFactory.createCacheWithPostCompute(
|
||||
private val lookup = moduleData.session.firCachesFactory.createCacheWithPostCompute(
|
||||
{ classId: ClassId, context: FirDeserializationContext? -> FirRegularClassSymbol(classId) to context }
|
||||
) { classId, symbol, parentContext ->
|
||||
val classData = classDataFinder.findClassData(classId)!!
|
||||
val classProto = classData.classProto
|
||||
|
||||
deserializeClassToSymbol(
|
||||
classId, classProto, symbol, nameResolver, session,
|
||||
moduleData,
|
||||
defaultAnnotationDeserializer =null, kotlinScopeProvider, parentContext,
|
||||
containerSource =null,
|
||||
classId, classProto, symbol, nameResolver, moduleData.session, moduleData,
|
||||
null, kotlinScopeProvider, parentContext,
|
||||
null,
|
||||
origin = FirDeclarationOrigin.BuiltIns,
|
||||
this::findAndDeserializeClass,
|
||||
)
|
||||
@@ -332,7 +176,171 @@ private data class BinaryVersionAndPackageFragment(
|
||||
}
|
||||
|
||||
val packageFragment = ProtoBuf.PackageFragment.parseFrom(stream, BuiltInSerializerProtocol.extensionRegistry)
|
||||
return BinaryVersionAndPackageFragment(version, packageFragment)
|
||||
return BinaryVersionAndPackageFragment(version, packageFragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SyntheticFunctionalInterfaceCache(private val moduleData: FirModuleData, private val kotlinScopeProvider: FirKotlinScopeProvider) {
|
||||
private val syntheticFunctionalInterfaceCache =
|
||||
moduleData.session.firCachesFactory.createCache(::createSyntheticFunctionalInterface)
|
||||
|
||||
fun tryGetSyntheticFunctionalInterface(classId: ClassId): FirRegularClassSymbol? {
|
||||
return syntheticFunctionalInterfaceCache.getValue(classId)
|
||||
}
|
||||
|
||||
private fun createSyntheticFunctionalInterface(classId: ClassId): FirRegularClassSymbol? {
|
||||
return with(classId) {
|
||||
val className = relativeClassName.asString()
|
||||
val kind = FunctionClassKind.byClassNamePrefix(packageFqName, className) ?: return@with null
|
||||
val prefix = kind.classNamePrefix
|
||||
val arity = className.substring(prefix.length).toIntOrNull() ?: return null
|
||||
FirRegularClassSymbol(classId).apply symbol@{
|
||||
buildRegularClass klass@{
|
||||
moduleData = this@SyntheticFunctionalInterfaceCache.moduleData
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
name = relativeClassName.shortName()
|
||||
status = FirResolvedDeclarationStatusImpl(
|
||||
Visibilities.Public,
|
||||
Modality.ABSTRACT,
|
||||
EffectiveVisibility.Public
|
||||
).apply {
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isInner = false
|
||||
isCompanion = false
|
||||
isData = false
|
||||
isInline = false
|
||||
}
|
||||
classKind = ClassKind.INTERFACE
|
||||
scopeProvider = kotlinScopeProvider
|
||||
symbol = this@symbol
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
typeParameters.addAll(
|
||||
(1..arity).map {
|
||||
buildTypeParameter {
|
||||
moduleData = this@SyntheticFunctionalInterfaceCache.moduleData
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
name = Name.identifier("P$it")
|
||||
symbol = FirTypeParameterSymbol()
|
||||
variance = Variance.IN_VARIANCE
|
||||
isReified = false
|
||||
bounds += moduleData.session.builtinTypes.nullableAnyType
|
||||
}
|
||||
},
|
||||
)
|
||||
typeParameters.add(
|
||||
buildTypeParameter {
|
||||
moduleData = this@SyntheticFunctionalInterfaceCache.moduleData
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
name = Name.identifier("R")
|
||||
symbol = FirTypeParameterSymbol()
|
||||
variance = Variance.OUT_VARIANCE
|
||||
isReified = false
|
||||
bounds += moduleData.session.builtinTypes.nullableAnyType
|
||||
},
|
||||
)
|
||||
val name = OperatorNameConventions.INVOKE
|
||||
val functionStatus = FirResolvedDeclarationStatusImpl(
|
||||
Visibilities.Public,
|
||||
Modality.ABSTRACT,
|
||||
EffectiveVisibility.Public
|
||||
).apply {
|
||||
isExpect = false
|
||||
isActual = false
|
||||
isOverride = false
|
||||
isOperator = true
|
||||
isInfix = false
|
||||
isInline = false
|
||||
isTailRec = false
|
||||
isExternal = false
|
||||
isSuspend =
|
||||
kind == FunctionClassKind.SuspendFunction ||
|
||||
kind == FunctionClassKind.KSuspendFunction
|
||||
}
|
||||
val typeArguments = typeParameters.map {
|
||||
buildResolvedTypeRef {
|
||||
type = ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
|
||||
}
|
||||
}
|
||||
|
||||
fun createSuperType(
|
||||
kind: FunctionClassKind,
|
||||
): FirResolvedTypeRef {
|
||||
return buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(kind.classId(arity))
|
||||
.constructClassType(typeArguments.map { it.type }.toTypedArray(), isNullable = false)
|
||||
}
|
||||
}
|
||||
|
||||
superTypeRefs += when (kind) {
|
||||
FunctionClassKind.Function -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.Function)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
}
|
||||
)
|
||||
|
||||
FunctionClassKind.SuspendFunction -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.Function)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
}
|
||||
)
|
||||
|
||||
FunctionClassKind.KFunction -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.KFunction)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
},
|
||||
createSuperType(FunctionClassKind.Function)
|
||||
)
|
||||
|
||||
FunctionClassKind.KSuspendFunction -> listOf(
|
||||
buildResolvedTypeRef {
|
||||
type = ConeClassLikeLookupTagImpl(StandardClassIds.KFunction)
|
||||
.constructClassType(arrayOf(typeArguments.last().type), isNullable = false)
|
||||
},
|
||||
createSuperType(FunctionClassKind.SuspendFunction)
|
||||
)
|
||||
}
|
||||
addDeclaration(
|
||||
buildSimpleFunction {
|
||||
moduleData = this@SyntheticFunctionalInterfaceCache.moduleData
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
returnTypeRef = typeArguments.last()
|
||||
this.name = name
|
||||
status = functionStatus
|
||||
symbol = FirNamedFunctionSymbol(
|
||||
CallableId(packageFqName, relativeClassName, name)
|
||||
)
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
valueParameters += typeArguments.dropLast(1).mapIndexed { index, typeArgument ->
|
||||
val parameterName = Name.identifier("p${index + 1}")
|
||||
buildValueParameter {
|
||||
moduleData = this@SyntheticFunctionalInterfaceCache.moduleData
|
||||
origin = FirDeclarationOrigin.BuiltIns
|
||||
resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES
|
||||
returnTypeRef = typeArgument
|
||||
this.name = parameterName
|
||||
symbol = FirVariableSymbol(parameterName)
|
||||
defaultValue = null
|
||||
isCrossinline = false
|
||||
isNoinline = false
|
||||
isVararg = false
|
||||
}
|
||||
}
|
||||
dispatchReceiverType = classId.defaultType(this@klass.typeParameters.map { it.symbol })
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun FunctionClassKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity))
|
||||
}
|
||||
Reference in New Issue
Block a user