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.
This commit is contained in:
Denis Zharkov
2017-11-27 17:52:55 +03:00
parent 4b96311600
commit dd3dbda719
2 changed files with 37 additions and 10 deletions
@@ -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<FqName>): Collection<TypeAliasDescriptor> {
val result = mutableListOf<TypeAliasDescriptor>()
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<TypeAliasDescriptor>()
}
}
}
return result
}
}
val defaultImports: List<ImportPath> by storageManager.createLazyValue {
targetPlatform.getDefaultImports(languageVersionSettings.supportsFeature(DefaultImportOfPackageKotlinComparisons))
}
val excludedImports: List<FqName> 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<TypeAliasDescriptor>()
}
}
.filter { it.checkSinceKotlinVersionAccessibility(languageVersionSettings) }
val builtinTypeAliases =
moduleDescriptor.findTypeAliasesInPackages(PACKAGES_WITH_ALIASES)
.filter { it.checkSinceKotlinVersionAccessibility(languageVersionSettings) }
val nonKotlinDefaultImportedPackages =
defaultImports
@@ -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 <T> getCapability(capability: ModuleDescriptor.Capability<T>) = capabilities[capability] as? T
}
@@ -144,4 +152,4 @@ interface ModuleDependencies {
class ModuleDependenciesImpl(
override val allDependencies: List<ModuleDescriptorImpl>,
override val modulesWhoseInternalsAreVisible: Set<ModuleDescriptorImpl>
) : ModuleDependencies
) : ModuleDependencies