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 + } } }