[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)
// 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,
)
@@ -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<FirSymbolProvider>,
) -> List<FirSymbolProvider>
): 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,
@@ -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),
)
}
)
@@ -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,
@@ -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),
)
})
@@ -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
}