diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index ea0ff5adb42..00c8760c930 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -52,6 +52,7 @@ import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver import org.jetbrains.kotlin.resolve.jvm.multiplatform.OptionalAnnotationPackageFragmentProvider import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory +import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions fun createContainerForLazyResolveWithJava( jvmPlatform: TargetPlatform, @@ -71,11 +72,12 @@ fun createContainerForLazyResolveWithJava( configureJavaClassFinder: (StorageComponentContainer.() -> Unit)? = null, javaClassTracker: JavaClassesTracker? = null, implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter? = null, - sealedInheritorsProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider + sealedInheritorsProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider, + optimizingOptions: OptimizingOptions? = null, ): StorageComponentContainer = createContainer("LazyResolveWithJava", JvmPlatformAnalyzerServices) { configureModule( moduleContext, jvmPlatform, JvmPlatformAnalyzerServices, bindingTrace, languageVersionSettings, - sealedInheritorsProvider + sealedInheritorsProvider, optimizingOptions ) configureIncrementalCompilation(lookupTracker, expectActualTracker, inlineConstTracker, enumWhenTracker) diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt index 7d0a695c94e..279f4176aab 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmResolverForModuleFactory.kt @@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.TargetEnvironment import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService +import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions import org.jetbrains.kotlin.utils.addIfNotNull class JvmPlatformParameters( @@ -62,7 +63,8 @@ class JvmResolverForModuleFactory( moduleContent: ModuleContent, resolverForProject: ResolverForProject, languageVersionSettings: LanguageVersionSettings, - sealedInheritorsProvider: SealedClassInheritorsProvider + sealedInheritorsProvider: SealedClassInheritorsProvider, + resolveOptimizingOptions: OptimizingOptions? ): ResolverForModule { val (moduleInfo, syntheticFiles, moduleContentScope) = moduleContent val project = moduleContext.project @@ -119,7 +121,8 @@ class JvmResolverForModuleFactory( packagePartProvider, languageVersionSettings, sealedInheritorsProvider = sealedInheritorsProvider, - useBuiltInsProvider = platformParameters.useBuiltinsProviderForModule(moduleInfo) + useBuiltInsProvider = platformParameters.useBuiltinsProviderForModule(moduleInfo), + optimizingOptions = resolveOptimizingOptions, ) val providersForModule = arrayListOf( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt index a6aa5a8a8e2..87c01554773 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/AnalyzerFacade.kt @@ -33,6 +33,7 @@ import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.TargetPlatformVersion import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.SealedClassInheritorsProvider +import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue @@ -134,6 +135,7 @@ abstract class ResolverForModuleFactory { resolverForProject: ResolverForProject, languageVersionSettings: LanguageVersionSettings, sealedInheritorsProvider: SealedClassInheritorsProvider, + resolveOptimizingOptions: OptimizingOptions? = null, ): ResolverForModule } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt index cb976ee52d0..431a00a211e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonResolverForModuleFactory.kt @@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.extensions.AnalysisHandlerExtension import org.jetbrains.kotlin.resolve.lazy.ResolveSession import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService +import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragmentProvider import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider import org.jetbrains.kotlin.storage.StorageManager @@ -90,7 +91,8 @@ class CommonResolverForModuleFactory( moduleContent: ModuleContent, resolverForProject: ResolverForProject, languageVersionSettings: LanguageVersionSettings, - sealedInheritorsProvider: SealedClassInheritorsProvider + sealedInheritorsProvider: SealedClassInheritorsProvider, + resolveOptimizingOptions: OptimizingOptions?, ): ResolverForModule { val (moduleInfo, syntheticFiles, moduleContentScope) = moduleContent val project = moduleContext.project diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index d2247e14fe4..b41363b1df8 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.container.StorageComponentContainer import org.jetbrains.kotlin.container.useImpl import org.jetbrains.kotlin.container.useInstance +import org.jetbrains.kotlin.container.useInstanceIfNotNull import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.contracts.ContractDeserializerImpl import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor @@ -43,6 +44,7 @@ import org.jetbrains.kotlin.resolve.checkers.OptInUsageChecker import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled import org.jetbrains.kotlin.resolve.lazy.* import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory +import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions import org.jetbrains.kotlin.types.KotlinTypeRefinerImpl import org.jetbrains.kotlin.types.checker.KotlinTypePreparator import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner @@ -58,7 +60,8 @@ fun StorageComponentContainer.configureModule( analyzerServices: PlatformDependentAnalyzerServices, trace: BindingTrace, languageVersionSettings: LanguageVersionSettings, - sealedProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider + sealedProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider, + optimizingOptions: OptimizingOptions? = null, ) { useInstance(sealedProvider) useInstance(moduleContext) @@ -69,6 +72,8 @@ fun StorageComponentContainer.configureModule( useInstance(trace) useInstance(languageVersionSettings) + useInstanceIfNotNull(optimizingOptions) + useInstance(platform) useInstance(analyzerServices) @@ -179,8 +184,9 @@ fun createContainerForLazyBodyResolve( mainFunctionDetectorFactory: MainFunctionDetector.Factory, sealedProvider: SealedClassInheritorsProvider, controlFlowInformationProviderFactory: ControlFlowInformationProvider.Factory, + optimizingOptions: OptimizingOptions? = null ): StorageComponentContainer = createContainer("LazyBodyResolve", analyzerServices) { - configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings, sealedProvider) + configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings, sealedProvider, optimizingOptions) useInstance(mainFunctionDetectorFactory) useInstance(kotlinCodeAnalyzer) useInstance(kotlinCodeAnalyzer.fileScopeProvider) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt index 53de8a521bd..dea4bbdb93c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.ImportingScope +import org.jetbrains.kotlin.resolve.scopes.optimization.OptimizingOptions import org.jetbrains.kotlin.storage.NotNullLazyValue import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue @@ -94,7 +95,8 @@ class ImportResolutionComponents( val moduleDescriptor: ModuleDescriptor, val platformToKotlinClassMapper: PlatformToKotlinClassMapper, val languageVersionSettings: LanguageVersionSettings, - val deprecationResolver: DeprecationResolver + val deprecationResolver: DeprecationResolver, + val optimizingOptions: OptimizingOptions, ) open class LazyImportResolver( @@ -131,7 +133,17 @@ open class LazyImportResolver( indexedImports.imports.asIterable().flatMapToNullable(THashSet()) { getImportScope(it).computeImportedNames() } } - fun definitelyDoesNotContainName(name: Name) = allNames?.let { name !in it } == true + fun definitelyDoesNotContainName(name: Name): Boolean { + // Calculation of all names is undesirable for cases when the scope doesn't live long and is big enough. + // In such cases we often do the same work twice - first time for computing definitelyDoesNotContainName + // and second time for resolution itself. Results seem to be not reused. + // This optimization is used in Kotlin Notebooks + return if (components.optimizingOptions.shouldCalculateAllNamesForLazyImportScopeOptimizing(packageFragment?.containingDeclaration)) { + allNames?.let { name !in it } == true + } else { + false + } + } fun recordLookup(name: Name, location: LookupLocation) { if (allNames == null) return diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/optimization/OptimizingOptions.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/optimization/OptimizingOptions.kt new file mode 100644 index 00000000000..c1dd634d9c3 --- /dev/null +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/scopes/optimization/OptimizingOptions.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2022 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.resolve.scopes.optimization + +import org.jetbrains.kotlin.container.DefaultImplementation +import org.jetbrains.kotlin.descriptors.ModuleDescriptor + +@DefaultImplementation(OptimizingOptions.Default::class) +interface OptimizingOptions { + fun shouldCalculateAllNamesForLazyImportScopeOptimizing(moduleDescriptor: ModuleDescriptor?): Boolean + + object Default : OptimizingOptions { + override fun shouldCalculateAllNamesForLazyImportScopeOptimizing(moduleDescriptor: ModuleDescriptor?): Boolean { + return true + } + } +}