From f361312e45ffcf5ec7fdf65debe4842aae1ccae7 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Mon, 29 Mar 2021 15:33:59 +0200 Subject: [PATCH] FIR: use FirCachesFactory in BuiltInsPackageFragment.tryGetSyntheticFunctionalInterface --- .../impl/FirBuiltinSymbolProvider.kt | 350 +++++++++--------- 1 file changed, 179 insertions(+), 171 deletions(-) diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt index c712e0996ee..bcb2b747357 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirBuiltinSymbolProvider.kt @@ -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() + private val syntheticFunctionalInterfaceCache = SyntheticFunctionalInterfaceCache(moduleData, kotlinScopeProvider) private fun loadBuiltIns(): List { 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>, packageFqName: FqName, name: Name) { @@ -254,7 +96,10 @@ open class FirBuiltinSymbolProvider( override fun getTopLevelPropertySymbolsTo(destination: MutableList, 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)) +} \ No newline at end of file