[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.
This commit is contained in:
Marco Pennekamp
2023-03-15 15:46:35 +01:00
committed by Space Team
parent 2d85e9db51
commit d9f515fbb8
6 changed files with 47 additions and 24 deletions
@@ -164,13 +164,8 @@ internal class LLFirSessionCache(private val project: Project) {
}) })
val javaSymbolProvider = createJavaSymbolProvider(this, moduleData, project, contentScope) val javaSymbolProvider = createJavaSymbolProvider(this, moduleData, project, contentScope)
val syntheticFunctionInterfaceProvider =
// We only need to add an extension synthetic function provider if the session's function type service even has extension kinds. FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(this, moduleData, scopeProvider)
// Otherwise, the provider will be completely useless.
val syntheticFunctionalInterfaceProvider = if (this.functionTypeService.hasExtensionKinds()) {
FirExtensionSyntheticFunctionInterfaceProvider(this, moduleData, scopeProvider)
} else null
register( register(
FirSymbolProvider::class, FirSymbolProvider::class,
LLFirModuleWithDependenciesSymbolProvider( LLFirModuleWithDependenciesSymbolProvider(
@@ -179,7 +174,7 @@ internal class LLFirSessionCache(private val project: Project) {
provider.symbolProvider, provider.symbolProvider,
switchableExtensionDeclarationsSymbolProvider, switchableExtensionDeclarationsSymbolProvider,
javaSymbolProvider, javaSymbolProvider,
syntheticFunctionalInterfaceProvider, syntheticFunctionInterfaceProvider,
), ),
dependencyProvider, dependencyProvider,
) )
@@ -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.DEPENDENCIES_SYMBOL_PROVIDER_QUALIFIED_KEY
import org.jetbrains.kotlin.fir.resolve.providers.FirProvider import org.jetbrains.kotlin.fir.resolve.providers.FirProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider 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.resolve.providers.symbolProvider
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.incremental.components.EnumWhenTracker import org.jetbrains.kotlin.incremental.components.EnumWhenTracker
@@ -77,7 +80,7 @@ abstract class FirAbstractSessionFactory {
createProviders: ( createProviders: (
FirSession, FirKotlinScopeProvider, FirSymbolProvider, FirSession, FirKotlinScopeProvider, FirSymbolProvider,
FirSwitchableExtensionDeclarationsSymbolProvider?, FirSwitchableExtensionDeclarationsSymbolProvider?,
FirExtensionSyntheticFunctionInterfaceProvider, FirExtensionSyntheticFunctionInterfaceProvider?,
dependencies: List<FirSymbolProvider>, dependencies: List<FirSymbolProvider>,
) -> List<FirSymbolProvider> ) -> List<FirSymbolProvider>
): FirSession { ): FirSession {
@@ -109,7 +112,8 @@ abstract class FirAbstractSessionFactory {
val dependencyProviders = computeDependencyProviderList(moduleData) val dependencyProviders = computeDependencyProviderList(moduleData)
val generatedSymbolsProvider = FirSwitchableExtensionDeclarationsSymbolProvider.create(this) val generatedSymbolsProvider = FirSwitchableExtensionDeclarationsSymbolProvider.create(this)
val syntheticFunctionInterfaceProvider = FirExtensionSyntheticFunctionInterfaceProvider(this, moduleData, kotlinScopeProvider) val syntheticFunctionInterfaceProvider =
FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(this, moduleData, kotlinScopeProvider)
val providers = createProviders( val providers = createProviders(
this, this,
@@ -5,21 +5,25 @@
package org.jetbrains.kotlin.fir.session package org.jetbrains.kotlin.fir.session
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.* 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.analysis.FirOverridesBackwardCompatibilityHelper
import org.jetbrains.kotlin.fir.checkers.registerJsCheckers import org.jetbrains.kotlin.fir.checkers.registerJsCheckers
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.resolve.calls.ConeCallConflictResolverFactory 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.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper import org.jetbrains.kotlin.fir.scopes.FirPlatformClassMapper
import org.jetbrains.kotlin.fir.scopes.impl.FirEnumEntriesSupport import org.jetbrains.kotlin.fir.scopes.impl.FirEnumEntriesSupport
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.metadata.resolver.KotlinResolvedLibrary
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
object FirJsSessionFactory : FirAbstractSessionFactory() { object FirJsSessionFactory : FirAbstractSessionFactory() {
@@ -75,13 +79,13 @@ object FirJsSessionFactory : FirAbstractSessionFactory() {
}, },
createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } }, createKotlinScopeProvider = { FirKotlinScopeProvider { _, declaredMemberScope, _, _ -> declaredMemberScope } },
createProviders = { session, builtinsModuleData, kotlinScopeProvider -> createProviders = { session, builtinsModuleData, kotlinScopeProvider ->
listOf( listOfNotNull(
KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries), KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries),
// (Most) builtins should be taken from the dependencies in JS compilation, therefore builtins provider is the last one // (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 // 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* // NOTE: it requires precise filtering for true nuiltins, like Function*
FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
FirExtensionSyntheticFunctionInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(session, builtinsModuleData, kotlinScopeProvider),
) )
} }
) )
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.fir.session package org.jetbrains.kotlin.fir.session
import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.* 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.checkers.registerJvmCheckers
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider 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.JavaSymbolProvider
import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider import org.jetbrains.kotlin.fir.java.deserialization.JvmClassFileBasedSymbolProvider
import org.jetbrains.kotlin.fir.java.deserialization.OptionalAnnotationClassesProvider 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.resolve.scopes.wrapScopeWithJvmMapped
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment import org.jetbrains.kotlin.fir.session.environment.AbstractProjectEnvironment
@@ -48,7 +53,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
}, },
createKotlinScopeProvider = { FirKotlinScopeProvider(::wrapScopeWithJvmMapped) }, createKotlinScopeProvider = { FirKotlinScopeProvider(::wrapScopeWithJvmMapped) },
createProviders = { session, builtinsModuleData, kotlinScopeProvider -> createProviders = { session, builtinsModuleData, kotlinScopeProvider ->
listOf( listOfNotNull(
JvmClassFileBasedSymbolProvider( JvmClassFileBasedSymbolProvider(
session, session,
moduleDataProvider, moduleDataProvider,
@@ -58,7 +63,7 @@ object FirJvmSessionFactory : FirAbstractSessionFactory() {
projectEnvironment.getFirJavaFacade(session, moduleDataProvider.allModuleData.last(), scope) projectEnvironment.getFirJavaFacade(session, moduleDataProvider.allModuleData.last(), scope)
), ),
FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
FirExtensionSyntheticFunctionInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(session, builtinsModuleData, kotlinScopeProvider),
FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
OptionalAnnotationClassesProvider( OptionalAnnotationClassesProvider(
session, session,
@@ -45,11 +45,11 @@ object FirNativeSessionFactory : FirAbstractSessionFactory() {
).apply { ).apply {
bindSession(session) bindSession(session)
} }
listOf( listOfNotNull(
KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries.map { it.library }), KlibBasedSymbolProvider(session, moduleDataProvider, kotlinScopeProvider, resolvedLibraries.map { it.library }),
NativeForwardDeclarationsSymbolProvider(session, forwardDeclarationsModuleData, kotlinScopeProvider, resolvedLibraries), NativeForwardDeclarationsSymbolProvider(session, forwardDeclarationsModuleData, kotlinScopeProvider, resolvedLibraries),
FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), FirBuiltinSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
FirExtensionSyntheticFunctionInterfaceProvider(session, builtinsModuleData, kotlinScopeProvider), FirExtensionSyntheticFunctionInterfaceProvider.createIfNeeded(session, builtinsModuleData, kotlinScopeProvider),
FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider), FirCloneableSymbolProvider(session, builtinsModuleData, kotlinScopeProvider),
) )
}) })
@@ -46,6 +46,21 @@ class FirExtensionSyntheticFunctionInterfaceProvider(
moduleData: FirModuleData, moduleData: FirModuleData,
kotlinScopeProvider: FirKotlinScopeProvider kotlinScopeProvider: FirKotlinScopeProvider
) : FirSyntheticFunctionInterfaceProviderBase(session, moduleData, kotlinScopeProvider) { ) : 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 { override fun FunctionTypeKind.isAcceptable(): Boolean {
return !this.isBuiltin return !this.isBuiltin
} }