From d9f515fbb81db3c3ec9694e7678faac263c1f477 Mon Sep 17 00:00:00 2001 From: Marco Pennekamp Date: Wed, 15 Mar 2023 15:46:35 +0100 Subject: [PATCH] [FIR] KT-57220 Avoid creating useless synthetic function providers - This optimization applied to LL FIR can be extended to K2 as a whole. Likely, there won't be any performance benefits in CLI runs, but it's still better to avoid useless symbol providers. --- .../level/api/fir/sessions/LLFirSessionCache.kt | 11 +++-------- .../fir/session/FirAbstractSessionFactory.kt | 10 +++++++--- .../kotlin/fir/session/FirJsSessionFactory.kt | 16 ++++++++++------ .../kotlin/fir/session/FirJvmSessionFactory.kt | 15 ++++++++++----- .../fir/session/FirNativeSessionFactory.kt | 4 ++-- ...xtensionSyntheticFunctionInterfaceProvider.kt | 15 +++++++++++++++ 6 files changed, 47 insertions(+), 24 deletions(-) diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt index 7c55736ccf7..19ab4b85e0d 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/sessions/LLFirSessionCache.kt @@ -164,13 +164,8 @@ internal class LLFirSessionCache(private val project: Project) { }) val javaSymbolProvider = createJavaSymbolProvider(this, moduleData, project, contentScope) - - // We only need to add an extension synthetic function provider if the session's function type service even has extension kinds. - // Otherwise, the provider will be completely useless. - val syntheticFunctionalInterfaceProvider = if (this.functionTypeService.hasExtensionKinds()) { - FirExtensionSyntheticFunctionInterfaceProvider(this, moduleData, scopeProvider) - } else null - + val syntheticFunctionInterfaceProvider = + FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(this, moduleData, scopeProvider) register( FirSymbolProvider::class, LLFirModuleWithDependenciesSymbolProvider( @@ -179,7 +174,7 @@ internal class LLFirSessionCache(private val project: Project) { provider.symbolProvider, switchableExtensionDeclarationsSymbolProvider, javaSymbolProvider, - syntheticFunctionalInterfaceProvider, + syntheticFunctionInterfaceProvider, ), dependencyProvider, ) 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 3059987da3a..e17efdf03c5 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,7 +16,10 @@ 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.* +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCachingCompositeSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirExtensionSyntheticFunctionInterfaceProvider +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.symbolProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.incremental.components.EnumWhenTracker @@ -77,7 +80,7 @@ abstract class FirAbstractSessionFactory { createProviders: ( FirSession, FirKotlinScopeProvider, FirSymbolProvider, FirSwitchableExtensionDeclarationsSymbolProvider?, - FirExtensionSyntheticFunctionInterfaceProvider, + FirExtensionSyntheticFunctionInterfaceProvider?, dependencies: List, ) -> List ): FirSession { @@ -109,7 +112,8 @@ abstract class FirAbstractSessionFactory { val dependencyProviders = computeDependencyProviderList(moduleData) val generatedSymbolsProvider = FirSwitchableExtensionDeclarationsSymbolProvider.create(this) - val syntheticFunctionInterfaceProvider = FirExtensionSyntheticFunctionInterfaceProvider(this, moduleData, kotlinScopeProvider) + val syntheticFunctionInterfaceProvider = + FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(this, moduleData, kotlinScopeProvider) val providers = createProviders( this, 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 c0e6e83e0f0..54c1e4a6c7b 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 @@ -5,21 +5,25 @@ package org.jetbrains.kotlin.fir.session -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirVisibilityChecker +import org.jetbrains.kotlin.fir.SessionConfiguration import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper import org.jetbrains.kotlin.fir.checkers.registerJsCheckers import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory -import org.jetbrains.kotlin.fir.resolve.providers.impl.* +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirBuiltinSymbolProvider +import org.jetbrains.kotlin.fir.resolve.providers.impl.FirExtensionSyntheticFunctionInterfaceProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper import org.jetbrains.kotlin.fir.scopes.impl.FirEnumEntriesSupport import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.library.KotlinLibrary -import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary import org.jetbrains.kotlin.name.Name object FirJsSessionFactory : FirAbstractSessionFactory() { @@ -75,13 +79,13 @@ object FirJsSessionFactory : FirAbstractSessionFactory() { }, createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } }, createProviders = { session, builtinsModuleData, kotlinScopeProvider -> - listOf( + listOfNotNull( KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries), // (Most) builtins should be taken from the dependencies in JS compilation, therefore builtins provider is the last one // 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), - FirExtensionSyntheticFunctionInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), + FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(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 532ce78fb81..3ca1d677aad 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 @@ -5,8 +5,11 @@ package org.jetbrains.kotlin.fir.session -import org.jetbrains.kotlin.config.* -import org.jetbrains.kotlin.fir.* +import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl +import org.jetbrains.kotlin.fir.FirModuleData +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.SessionConfiguration import org.jetbrains.kotlin.fir.checkers.registerJvmCheckers import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider @@ -16,7 +19,9 @@ import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider import org.jetbrains.kotlin.fir.java.JavaSymbolProvider import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider -import org.jetbrains.kotlin.fir.resolve.providers.impl.* +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.FirExtensionSyntheticFunctionInterfaceProvider import org.jetbrains.kotlin.fir.resolve.scopes.wrapScopeWithJvmMapped import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment @@ -48,7 +53,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() { }, createKotlinScopeProvider = { FirKotlinScopeProvider(::wrapScopeWithJvmMapped) }, createProviders = { session, builtinsModuleData, kotlinScopeProvider -> - listOf( + listOfNotNull( JvmClassFileBasedSymbolProvider( session, moduleDataProvider, @@ -58,7 +63,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() { projectEnvironment.getFirJavaFacade(session, moduleDataProvider.allModuleData.last(), scope) ), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), - FirExtensionSyntheticFunctionInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), + FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(session, builtinsModuleData, kotlinScopeProvider), FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), OptionalAnnotationClassesProvider( session, 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 16fafef9fee..87e3fb29b86 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 @@ -45,11 +45,11 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() { ).apply { bindSession(session) } - listOf( + listOfNotNull( KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries.map { it.library }), NativeForwardDeclarationsSymbolProvider(session, forwardDeclarationsModuleData, kotlinScopeProvider, resolvedLibraries), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), - FirExtensionSyntheticFunctionInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), + FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(session, builtinsModuleData, kotlinScopeProvider), FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), ) }) diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionInterfaceProvider.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionInterfaceProvider.kt index 94c5782d84a..cdbeb22dd63 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionInterfaceProvider.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirExtensionSyntheticFunctionInterfaceProvider.kt @@ -46,6 +46,21 @@ class FirExtensionSyntheticFunctionInterfaceProvider( moduleData: FirModuleData, kotlinScopeProvider: FirKotlinScopeProvider ) : FirSyntheticFunctionInterfaceProviderBase(session, moduleData, kotlinScopeProvider) { + companion object { + /** + * A [FirExtensionSyntheticFunctionInterfaceProvider] only needs to be created if the session's function type service has extension + * function kinds. Otherwise, the provider would be useless. + */ + fun createIfNeeded( + session: FirSession, + moduleData: FirModuleData, + kotlinScopeProvider: FirKotlinScopeProvider, + ): FirExtensionSyntheticFunctionInterfaceProvider? { + if (!session.functionTypeService.hasExtensionKinds()) return null + return FirExtensionSyntheticFunctionInterfaceProvider(session, moduleData, kotlinScopeProvider) + } + } + override fun FunctionTypeKind.isAcceptable(): Boolean { return !this.isBuiltin }