From 87a9103cc6c700ffffd638556bfe41c059b68299 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Wed, 18 Jan 2023 16:48:25 +0200 Subject: [PATCH] [FIR] Extract SyntheticFunctionsCache from builtins provider into separate one This is needed because now set of available synthetic functional interfaces depends on session, because each module can contain different plugins, which provide different kinds of functional types --- .../structure/LLFirBuiltinsSessionFactory.kt | 10 +- .../api/fir/sessions/LLFirSessionFactory.kt | 3 + .../fir/types/ConeFunctionalTypeKind.kt | 9 + .../fir/session/FirAbstractSessionFactory.kt | 12 +- .../fir/session/FirCommonSessionFactory.kt | 5 +- .../kotlin/fir/session/FirJsSessionFactory.kt | 4 +- .../fir/session/FirJvmSessionFactory.kt | 4 +- .../fir/session/FirNativeSessionFactory.kt | 5 +- .../impl/FirBuiltinSymbolProvider.kt | 189 ++------------ ...ionSyntheticFunctionalInterfaceProvider.kt | 245 ++++++++++++++++++ .../types/FirFunctionalTypeKindServiceImpl.kt | 4 + .../fir/types/FirFunctionalTypeKindService.kt | 12 + 12 files changed, 316 insertions(+), 186 deletions(-) create mode 100644 compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionalInterfaceProvider.kt diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt index 1a339e9c15a..7aa0b867913 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/project/structure/LLFirBuiltinsSessionFactory.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.providers.LLFirBuiltinsAn import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirBuiltinsAndCloneableSession import org.jetbrains.kotlin.analysis.project.structure.KtBuiltinsModule import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices +import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl import org.jetbrains.kotlin.fir.BuiltinTypes import org.jetbrains.kotlin.fir.PrivateSessionConstructor import org.jetbrains.kotlin.fir.SessionConfiguration @@ -18,22 +19,22 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirExtensionSyntheticFunctionalInterfaceProvider import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped +import org.jetbrains.kotlin.fir.resolve.transformers.FirDummyCompilerLazyDeclarationResolver import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.session.registerCommonComponents +import org.jetbrains.kotlin.fir.session.registerCommonComponentsAfterExtensionsAreConfigured import org.jetbrains.kotlin.fir.session.registerCommonJavaComponents import org.jetbrains.kotlin.fir.session.registerModuleData import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver -import java.util.concurrent.ConcurrentHashMap -import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl -import org.jetbrains.kotlin.fir.resolve.transformers.FirDummyCompilerLazyDeclarationResolver -import org.jetbrains.kotlin.fir.session.registerCommonComponentsAfterExtensionsAreConfigured import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.isJs import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices +import java.util.concurrent.ConcurrentHashMap @OptIn(PrivateSessionConstructor::class, SessionConfiguration::class) class LLFirBuiltinsSessionFactory( @@ -63,6 +64,7 @@ class LLFirBuiltinsSessionFactory( register(FirKotlinScopeProvider::class, kotlinScopeProvider) val symbolProvider = createCompositeSymbolProvider(this) { add(LLFirBuiltinSymbolProvider(this@session, moduleData, kotlinScopeProvider)) + add(FirExtensionSyntheticFunctionalInterfaceProvider(this@session, moduleData, kotlinScopeProvider)) add(FirCloneableSymbolProvider(this@session, moduleData, kotlinScopeProvider)) } diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt index b5af4f0a4f4..e869e4e7ed9 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionFactory.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.fir.backend.jvm.FirJvmTypeMapper import org.jetbrains.kotlin.fir.extensions.* import org.jetbrains.kotlin.fir.java.JavaSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.* +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirExtensionSyntheticFunctionalInterfaceProvider import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.session.* @@ -148,6 +149,7 @@ internal object LLFirSessionFactory { } val javaSymbolProvider = createJavaSymbolProvider(this, moduleData, project, contentScope) + val syntheticFunctionalInterfaceProvider = FirExtensionSyntheticFunctionalInterfaceProvider(this, moduleData, scopeProvider) register( FirSymbolProvider::class, LLFirModuleWithDependenciesSymbolProvider( @@ -157,6 +159,7 @@ internal object LLFirSessionFactory { provider.symbolProvider, switchableExtensionDeclarationsSymbolProvider, javaSymbolProvider, + syntheticFunctionalInterfaceProvider, ), ) ) diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeFunctionalTypeKind.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeFunctionalTypeKind.kt index daf5b81438b..2ddf29facef 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeFunctionalTypeKind.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeFunctionalTypeKind.kt @@ -130,3 +130,12 @@ abstract class ConeFunctionalTypeKind internal constructor( override fun nonReflectKind(): ConeFunctionalTypeKind = SuspendFunction } } + +val ConeFunctionalTypeKind.isBuiltin: Boolean + get() = when (this) { + ConeFunctionalTypeKind.Function, + ConeFunctionalTypeKind.KFunction, + ConeFunctionalTypeKind.SuspendFunction, + ConeFunctionalTypeKind.KSuspendFunction -> true + else -> false + } diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt index 42024390dc5..9f6909a503d 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirAbstractSessionFactory.kt @@ -16,9 +16,7 @@ import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider import org.jetbrains.kotlin.fir.resolve.providers.DEPENDENCIES_SYMBOL_PROVIDER_QUALIFIED_KEY import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCachingCompositeSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirLibrarySessionProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl +import org.jetbrains.kotlin.fir.resolve.providers.impl.* import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.incremental.components.EnumWhenTracker @@ -79,6 +77,7 @@ abstract class FirAbstractSessionFactory { createProviders: ( FirSession, FirKotlinScopeProvider, FirSymbolProvider, FirSwitchableExtensionDeclarationsSymbolProvider?, + FirExtensionSyntheticFunctionalInterfaceProvider, dependencies: List, ) -> List ): FirSession { @@ -110,9 +109,14 @@ abstract class FirAbstractSessionFactory { val dependencyProviders = computeDependencyProviderList(moduleData) val generatedSymbolsProvider = FirSwitchableExtensionDeclarationsSymbolProvider.create(this) + val syntheticFunctionalInterfaceProvider = FirExtensionSyntheticFunctionalInterfaceProvider(this, moduleData, kotlinScopeProvider) val providers = createProviders( - this, kotlinScopeProvider, firProvider.symbolProvider, generatedSymbolsProvider, + this, + kotlinScopeProvider, + firProvider.symbolProvider, + generatedSymbolsProvider, + syntheticFunctionalInterfaceProvider, dependencyProviders, ) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt index d747e58ae2e..4ff196c9fd4 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirCommonSessionFactory.kt @@ -104,7 +104,7 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { it.registerNativeCheckers() }, createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } }, - createProviders = { session, kotlinScopeProvider, symbolProvider, generatedSymbolsProvider, dependencies -> + createProviders = { session, kotlinScopeProvider, symbolProvider, syntheticFunctionalInterfaceProvider, generatedSymbolsProvider, dependencies -> var symbolProviderForBinariesFromIncrementalCompilation: MetadataSymbolProvider? = null var optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation: OptionalAnnotationClassesProvider? = null incrementalCompilationContext?.let { @@ -140,6 +140,7 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { *(incrementalCompilationContext?.previousFirSessionsSymbolProviders?.toTypedArray() ?: emptyArray()), symbolProviderForBinariesFromIncrementalCompilation, generatedSymbolsProvider, + syntheticFunctionalInterfaceProvider, javaSymbolProvider, *dependencies.toTypedArray(), optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation, @@ -151,4 +152,4 @@ object FirCommonSessionFactory : FirAbstractSessionFactory() { } } } -} \ No newline at end of file +} diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt index 46d310a9065..d0100e521d3 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJsSessionFactory.kt @@ -44,10 +44,11 @@ object FirJsSessionFactory : FirAbstractSessionFactory() { }, registerExtraCheckers = { it.registerJsCheckers() }, createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } }, - createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependencies -> + createProviders = { _, _, symbolProvider, generatedSymbolsProvider, syntheticFunctionalInterfaceProvider, dependencies -> listOfNotNull( symbolProvider, generatedSymbolsProvider, + syntheticFunctionalInterfaceProvider, *dependencies.toTypedArray(), ) } @@ -78,6 +79,7 @@ object FirJsSessionFactory : FirAbstractSessionFactory() { // TODO: consider using "poisoning" provider for builtins to ensure that proper ones are taken from dependencies // NOTE: it requires precise filtering for true nuiltins, like Function* FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), + FirExtensionSyntheticFunctionalInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), ) } ) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt index ab7242560c5..0daf3bd442b 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirJvmSessionFactory.kt @@ -58,6 +58,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() { projectEnvironment.getFirJavaFacade(session, moduleDataProvider.allModuleData.last(), scope) ), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), + FirExtensionSyntheticFunctionalInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), OptionalAnnotationClassesProvider( session, @@ -100,7 +101,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() { }, registerExtraCheckers = { it.registerJvmCheckers() }, createKotlinScopeProvider = { FirKotlinScopeProvider(::wrapScopeWithJvmMapped) }, - createProviders = { session, kotlinScopeProvider, symbolProvider, generatedSymbolsProvider, dependencies -> + createProviders = { session, kotlinScopeProvider, symbolProvider, generatedSymbolsProvider, syntheticFunctionalInterfaceProvider, dependencies -> var symbolProviderForBinariesFromIncrementalCompilation: JvmClassFileBasedSymbolProvider? = null var optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation: OptionalAnnotationClassesProvider? = null incrementalCompilationContext?.let { @@ -137,6 +138,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() { symbolProviderForBinariesFromIncrementalCompilation, generatedSymbolsProvider, javaSymbolProvider, + syntheticFunctionalInterfaceProvider, *dependencies.toTypedArray(), optionalAnnotationClassesProviderForBinariesFromIncrementalCompilation, ) diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt index 05eab29bd06..424a7108494 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/FirNativeSessionFactory.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirExtensionSyntheticFunctionalInterfaceProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary @@ -40,6 +41,7 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() { listOf( KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), + FirExtensionSyntheticFunctionalInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), ) }) @@ -67,10 +69,11 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() { }, registerExtraCheckers = { it.registerNativeCheckers() }, createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } }, - createProviders = { _, _, symbolProvider, generatedSymbolsProvider, dependencies -> + createProviders = { _, _, symbolProvider, generatedSymbolsProvider, syntheticFunctionalInterfaceProvider, dependencies -> listOfNotNull( symbolProvider, generatedSymbolsProvider, + syntheticFunctionalInterfaceProvider, *dependencies.toTypedArray(), ) } 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 fef02e2071f..279cd47a70a 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 @@ -5,43 +5,33 @@ package org.jetbrains.kotlin.fir.resolve.providers.impl -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.fir.FirModuleData import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.ThreadSafeMutableState -import org.jetbrains.kotlin.fir.caches.createCache import org.jetbrains.kotlin.fir.caches.firCachesFactory -import org.jetbrains.kotlin.fir.caches.getValue import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin -import org.jetbrains.kotlin.fir.declarations.FirResolvePhase -import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass -import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction -import org.jetbrains.kotlin.fir.declarations.builder.buildTypeParameter -import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter -import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl -import org.jetbrains.kotlin.fir.declarations.utils.addDeclaration import org.jetbrains.kotlin.fir.deserialization.FirBuiltinAnnotationDeserializer import org.jetbrains.kotlin.fir.deserialization.FirConstDeserializer import org.jetbrains.kotlin.fir.deserialization.FirDeserializationContext import org.jetbrains.kotlin.fir.deserialization.deserializeClassToSymbol -import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation -import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyAnnotationArgumentMapping -import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider -import org.jetbrains.kotlin.fir.symbols.impl.* -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.builtins.BuiltInsBinaryVersion import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl -import org.jetbrains.kotlin.name.* +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.serialization.deserialization.ProtoBasedClassDataFinder import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol import org.jetbrains.kotlin.serialization.deserialization.getName -import org.jetbrains.kotlin.types.Variance -import org.jetbrains.kotlin.util.OperatorNameConventions import java.io.InputStream @ThreadSafeMutableState @@ -50,8 +40,13 @@ open class FirBuiltinSymbolProvider( val moduleData: FirModuleData, val kotlinScopeProvider: FirKotlinScopeProvider ) : FirSymbolProvider(session) { + private val syntheticFunctionalInterfaceProvider = FirBuiltinSyntheticFunctionalInterfaceProvider( + session, + moduleData, + kotlinScopeProvider + ) + private val allPackageFragments = loadBuiltIns().groupBy { it.fqName } - private val syntheticFunctionalInterfaceCache = SyntheticFunctionalInterfaceCache(session, moduleData, kotlinScopeProvider) private fun loadBuiltIns(): List { val classLoader = this::class.java.classLoader @@ -73,7 +68,7 @@ open class FirBuiltinSymbolProvider( override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? { return allPackageFragments[classId.packageFqName]?.firstNotNullOfOrNull { it.getClassLikeSymbolByClassId(classId) - } ?: syntheticFunctionalInterfaceCache.tryGetSyntheticFunctionalInterface(classId) + } ?: syntheticFunctionalInterfaceProvider.getClassLikeSymbolByClassId(classId) } override fun computePackageSetWithTopLevelCallables(): Set = @@ -199,155 +194,3 @@ private data class BinaryVersionAndPackageFragment( } } -private class SyntheticFunctionalInterfaceCache( - private val session: FirSession, - 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 = session.functionalTypeService.getKindByClassNamePrefix(packageFqName, className) ?: return 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() - containingDeclarationSymbol = this@symbol - 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() - containingDeclarationSymbol = this@symbol - 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 == ConeFunctionalTypeKind.SuspendFunction || - kind == ConeFunctionalTypeKind.KSuspendFunction - } - val typeArguments = typeParameters.map { - ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false).toFirResolvedTypeRef() - } - - fun createSuperType(kind: ConeFunctionalTypeKind): FirResolvedTypeRef { - return kind.classId(arity).toLookupTag() - .constructClassType(typeArguments.map { it.type }.toTypedArray(), isNullable = false) - .toFirResolvedTypeRef() - } - - if (kind.isReflectType) { - superTypeRefs += StandardClassIds.KFunction.toLookupTag() - .constructClassType(arrayOf(typeArguments.last().type), isNullable = false) - .toFirResolvedTypeRef() - superTypeRefs += createSuperType(kind.nonReflectKind()) - } else { - superTypeRefs += StandardClassIds.Function.toLookupTag() - .constructClassType(arrayOf(typeArguments.last().type), isNullable = false) - .toFirResolvedTypeRef() - } - - 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 - containingFunctionSymbol = this@buildSimpleFunction.symbol - origin = FirDeclarationOrigin.BuiltIns - resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES - returnTypeRef = typeArgument - this.name = parameterName - symbol = FirValueParameterSymbol(parameterName) - defaultValue = null - isCrossinline = false - isNoinline = false - isVararg = false - } - } - dispatchReceiverType = classId.defaultType(this@klass.typeParameters.map { it.symbol }) - kind.annotationOnInvokeClassId?.let { annotationClassId -> - annotations += buildAnnotation { - annotationTypeRef = annotationClassId - .constructClassLikeType(emptyArray(), isNullable = false) - .toFirResolvedTypeRef() - argumentMapping = FirEmptyAnnotationArgumentMapping - } - } - } - ) - } - } - } - } - - private fun ConeFunctionalTypeKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity)) -} diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionalInterfaceProvider.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionalInterfaceProvider.kt new file mode 100644 index 00000000000..ff9e89a4357 --- /dev/null +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionalInterfaceProvider.kt @@ -0,0 +1,245 @@ +/* + * Copyright 2010-2023 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.resolve.providers.impl + +import org.jetbrains.kotlin.descriptors.ClassKind +import org.jetbrains.kotlin.descriptors.EffectiveVisibility +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.descriptors.Visibilities +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.caches.createCache +import org.jetbrains.kotlin.fir.caches.firCachesFactory +import org.jetbrains.kotlin.fir.caches.getValue +import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin +import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.declarations.builder.buildRegularClass +import org.jetbrains.kotlin.fir.declarations.builder.buildSimpleFunction +import org.jetbrains.kotlin.fir.declarations.builder.buildTypeParameter +import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameter +import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl +import org.jetbrains.kotlin.fir.declarations.utils.addDeclaration +import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotation +import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyAnnotationArgumentMapping +import org.jetbrains.kotlin.fir.resolve.defaultType +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals +import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider +import org.jetbrains.kotlin.fir.symbols.impl.* +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl +import org.jetbrains.kotlin.name.* +import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.util.OperatorNameConventions + +/* + * Provides functional interfaces for functional kinds from compiler plugins + */ +class FirExtensionSyntheticFunctionalInterfaceProvider( + session: FirSession, + moduleData: FirModuleData, + kotlinScopeProvider: FirKotlinScopeProvider +) : FirSyntheticFunctionalInterfaceProviderBase(session, moduleData, kotlinScopeProvider) { + override fun ConeFunctionalTypeKind.isAcceptable(): Boolean { + return !this.isBuiltin + } +} + +/* + * Provides kotlin.FunctionN, kotlin.coroutines.SuspendFunctionN, kotlin.reflect.KFunctionN and kotlin.reflect.KSuspendFunctionN + */ +class FirBuiltinSyntheticFunctionalInterfaceProvider( + session: FirSession, + moduleData: FirModuleData, + kotlinScopeProvider: FirKotlinScopeProvider +) : FirSyntheticFunctionalInterfaceProviderBase(session, moduleData, kotlinScopeProvider) { + override fun ConeFunctionalTypeKind.isAcceptable(): Boolean { + return this.isBuiltin + } +} + +abstract class FirSyntheticFunctionalInterfaceProviderBase( + session: FirSession, + val moduleData: FirModuleData, + val kotlinScopeProvider: FirKotlinScopeProvider +) : FirSymbolProvider(session) { + override fun getClassLikeSymbolByClassId(classId: ClassId): FirRegularClassSymbol? { + return cache.getValue(classId) + } + + @FirSymbolProviderInternals + override fun getTopLevelCallableSymbolsTo(destination: MutableList>, packageFqName: FqName, name: Name) {} + + @FirSymbolProviderInternals + override fun getTopLevelFunctionSymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) {} + + @FirSymbolProviderInternals + override fun getTopLevelPropertySymbolsTo(destination: MutableList, packageFqName: FqName, name: Name) {} + + override fun getPackage(fqName: FqName): FqName? { + return fqName.takeIf { session.functionalTypeService.hasKindWithSpecificPackage(it) } + } + + override fun computePackageSetWithTopLevelCallables(): Set { + return emptySet() + } + + /** + * This method has no sence for synthetic functional interfaces + */ + override fun knownTopLevelClassifiersInPackage(packageFqName: FqName): Set? { + return emptySet() + } + + override fun computeCallableNamesInPackage(packageFqName: FqName): Set? { + return emptySet() + } + + private val cache = moduleData.session.firCachesFactory.createCache(::createSyntheticFunctionalInterface) + + protected abstract fun ConeFunctionalTypeKind.isAcceptable(): Boolean + + private fun createSyntheticFunctionalInterface(classId: ClassId): FirRegularClassSymbol? { + return with(classId) { + val className = relativeClassName.asString() + val kind = session.functionalTypeService.getKindByClassNamePrefix(packageFqName, className) ?: return null + if (!kind.isAcceptable()) return null + val prefix = kind.classNamePrefix + val arity = className.substring(prefix.length).toIntOrNull() ?: return null + FirRegularClassSymbol(classId).apply symbol@{ + buildRegularClass klass@{ + moduleData = this@FirSyntheticFunctionalInterfaceProviderBase.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@FirSyntheticFunctionalInterfaceProviderBase.moduleData + resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES + origin = FirDeclarationOrigin.BuiltIns + name = Name.identifier("P$it") + symbol = FirTypeParameterSymbol() + containingDeclarationSymbol = this@symbol + variance = Variance.IN_VARIANCE + isReified = false + bounds += moduleData.session.builtinTypes.nullableAnyType + } + }, + ) + typeParameters.add( + buildTypeParameter { + moduleData = this@FirSyntheticFunctionalInterfaceProviderBase.moduleData + resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES + origin = FirDeclarationOrigin.BuiltIns + name = Name.identifier("R") + symbol = FirTypeParameterSymbol() + containingDeclarationSymbol = this@symbol + 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 == ConeFunctionalTypeKind.SuspendFunction || + kind == ConeFunctionalTypeKind.KSuspendFunction + } + val typeArguments = typeParameters.map { + ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false).toFirResolvedTypeRef() + } + + fun createSuperType(kind: ConeFunctionalTypeKind): FirResolvedTypeRef { + return kind.classId(arity).toLookupTag() + .constructClassType(typeArguments.map { it.type }.toTypedArray(), isNullable = false) + .toFirResolvedTypeRef() + } + + if (kind.isReflectType) { + superTypeRefs += StandardClassIds.KFunction.toLookupTag() + .constructClassType(arrayOf(typeArguments.last().type), isNullable = false) + .toFirResolvedTypeRef() + superTypeRefs += createSuperType(kind.nonReflectKind()) + } else { + superTypeRefs += StandardClassIds.Function.toLookupTag() + .constructClassType(arrayOf(typeArguments.last().type), isNullable = false) + .toFirResolvedTypeRef() + } + + addDeclaration( + buildSimpleFunction { + moduleData = this@FirSyntheticFunctionalInterfaceProviderBase.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@FirSyntheticFunctionalInterfaceProviderBase.moduleData + containingFunctionSymbol = this@buildSimpleFunction.symbol + origin = FirDeclarationOrigin.BuiltIns + resolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES + returnTypeRef = typeArgument + this.name = parameterName + symbol = FirValueParameterSymbol(parameterName) + defaultValue = null + isCrossinline = false + isNoinline = false + isVararg = false + } + } + dispatchReceiverType = classId.defaultType(this@klass.typeParameters.map { it.symbol }) + kind.annotationOnInvokeClassId?.let { annotationClassId -> + annotations += buildAnnotation { + annotationTypeRef = annotationClassId + .constructClassLikeType(emptyArray(), isNullable = false) + .toFirResolvedTypeRef() + argumentMapping = FirEmptyAnnotationArgumentMapping + } + } + } + ) + } + } + } + } + + private fun ConeFunctionalTypeKind.classId(arity: Int) = ClassId(packageFqName, numberedClassName(arity)) +} diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindServiceImpl.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindServiceImpl.kt index 16397db57f3..7b0acdb8a1e 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindServiceImpl.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindServiceImpl.kt @@ -47,4 +47,8 @@ class FirFunctionalTypeKindServiceImpl(session: FirSession) : FirFunctionalTypeK } return null } + + override fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean { + return packageFqName in knownKindsByPackageFqName + } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindService.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindService.kt index f06dcb6fcb1..a6e6c860536 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindService.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/FirFunctionalTypeKindService.kt @@ -12,11 +12,19 @@ import org.jetbrains.kotlin.name.FqName abstract class FirFunctionalTypeKindService : FirSessionComponent { abstract fun getKindByClassNamePrefix(packageFqName: FqName, className: String): ConeFunctionalTypeKind? + abstract fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean /* * Should be used only in places where session is unavaliable by default (e.g. in default cone type render) */ object Default : FirFunctionalTypeKindService() { + private val packages = listOf( + ConeFunctionalTypeKind.Function, + ConeFunctionalTypeKind.SuspendFunction, + ConeFunctionalTypeKind.KFunction, + ConeFunctionalTypeKind.KSuspendFunction, + ).map { it.packageFqName }.toSet() + override fun getKindByClassNamePrefix(packageFqName: FqName, className: String): ConeFunctionalTypeKind? { return when (FunctionClassKind.parseClassName(className, packageFqName)?.kind) { FunctionClassKind.Function -> ConeFunctionalTypeKind.Function @@ -26,6 +34,10 @@ abstract class FirFunctionalTypeKindService : FirSessionComponent { null -> null } } + + override fun hasKindWithSpecificPackage(packageFqName: FqName): Boolean { + return packageFqName in packages + } } }