From dd3dbda719e9f23a332ba1de2f41af62642e19dd Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 27 Nov 2017 17:52:55 +0300 Subject: [PATCH] Optimize computation of default excluded import in IDE Prior to this change, it was rather slow since it would lead to a ModuleDescriptor::packageFragmentProviderForWholeModuleWithDependencies computation, that would force the computation of libraries' dependencies, that actually was the major bottleneck here. The idea is that we do not need to search through dependencies of dependencies, but only need contents of one of the modules direct content. This commit is made under the assumption that if a module has may see some runtime parts, than runtime jar should be among its direct depenencies. --- .../resolve/lazy/DefaultImportProvider.kt | 37 ++++++++++++++----- .../descriptors/impl/ModuleDescriptorImpl.kt | 10 ++++- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DefaultImportProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DefaultImportProvider.kt index da32d870059..57013e25935 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DefaultImportProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/DefaultImportProvider.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.LanguageFeature.DefaultImportOfPackageKotlinC import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor +import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.isChildOf import org.jetbrains.kotlin.name.isSubpackageOf @@ -38,20 +39,38 @@ class DefaultImportProvider( private val targetPlatform: TargetPlatform, private val languageVersionSettings: LanguageVersionSettings ) { + companion object { + private val PACKAGES_WITH_ALIASES = listOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.TEXT_PACKAGE_FQ_NAME) + + private fun ModuleDescriptor.findTypeAliasesInPackages(packages: Collection): Collection { + val result = mutableListOf() + + for (dependencyModuleDescriptor in allDependencyModules) { + if (dependencyModuleDescriptor !is ModuleDescriptorImpl) continue + + for (packageFqName in packages) { + dependencyModuleDescriptor.packageFragmentProviderForContent.getPackageFragments(packageFqName) + .flatMapTo(result) { + packageFragmentDescriptor -> + packageFragmentDescriptor.getMemberScope() + .getContributedDescriptors(DescriptorKindFilter.TYPE_ALIASES) + .filterIsInstance() + } + } + } + + return result + } + } + val defaultImports: List by storageManager.createLazyValue { targetPlatform.getDefaultImports(languageVersionSettings.supportsFeature(DefaultImportOfPackageKotlinComparisons)) } val excludedImports: List by storageManager.createLazyValue { - val packagesWithAliases = listOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.TEXT_PACKAGE_FQ_NAME) - val builtinTypeAliases = moduleDescriptor.allDependencyModules - .flatMap { dependencyModule -> - packagesWithAliases.map(dependencyModule::getPackage).flatMap { - it.memberScope.getContributedDescriptors(DescriptorKindFilter.TYPE_ALIASES).filterIsInstance() - } - } - .filter { it.checkSinceKotlinVersionAccessibility(languageVersionSettings) } - + val builtinTypeAliases = + moduleDescriptor.findTypeAliasesInPackages(PACKAGES_WITH_ALIASES) + .filter { it.checkSinceKotlinVersionAccessibility(languageVersionSettings) } val nonKotlinDefaultImportedPackages = defaultImports diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt index 38c30f9852c..e7c6862df9f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/ModuleDescriptorImpl.kt @@ -132,6 +132,14 @@ class ModuleDescriptorImpl @JvmOverloads constructor( return packageFragmentProviderForWholeModuleWithDependencies } + val packageFragmentProviderForContent: PackageFragmentProvider + get() { + assertValid() + return packageFragmentProviderForModuleContent.sure { + "Module $id was not initialized by the time packageFragmentProviderForContent was requested" + } + } + @Suppress("UNCHECKED_CAST") override fun getCapability(capability: ModuleDescriptor.Capability) = capabilities[capability] as? T } @@ -144,4 +152,4 @@ interface ModuleDependencies { class ModuleDependenciesImpl( override val allDependencies: List, override val modulesWhoseInternalsAreVisible: Set -) : ModuleDependencies \ No newline at end of file +) : ModuleDependencies