From d7c1993194d4fad5f32b97919d04c8064f49e9c6 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 13 Feb 2017 15:17:19 +0300 Subject: [PATCH] FileScopeFactory: postpone default import resolver construction --- .../kotlin/resolve/lazy/FileScopeFactory.kt | 87 ++++++++++--------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt index 8c5d3cbc9c5..71c08d858ab 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt @@ -59,29 +59,9 @@ class FileScopeFactory( } fun createScopesForFile(file: KtFile, existingImports: ImportingScope? = null): FileScopes { - val debugName = "LazyFileScope for file " + file.name - val tempTrace = TemporaryBindingTrace.create(bindingTrace, "Transient trace for default imports lazy resolve", false) - infix fun Collection.concat(other: Collection?) = if (other == null || other.isEmpty()) this else this + other - val imports = file.importDirectives - - val aliasImportNames = imports.mapNotNull { if (it.aliasName != null) it.importedFqName else null } - - val extraImports = file.originalFile.virtualFile?.let { vFile -> - val scriptExternalDependencies = getScriptExternalDependencies(vFile, file.project) - ktImportsFactory.createImportDirectives(scriptExternalDependencies?.imports?.map { ImportPath.fromString(it) }.orEmpty()) - } - - val allImplicitImports = defaultImports concat extraImports - - val defaultImportsFiltered = if (aliasImportNames.isEmpty()) { // optimization - allImplicitImports - } - else { - allImplicitImports.filter { it.isAllUnder || it.importedFqName !in aliasImportNames } - } val packageView = moduleDescriptor.getPackage(file.packageFqName) val packageFragment = topLevelDescriptorProvider.getPackageFragment(file.packageFqName) @@ -91,6 +71,10 @@ class FileScopeFactory( error("Could not find fragment ${file.packageFqName} for file ${file.name}") } + + val imports = file.importDirectives + val aliasImportNames = imports.mapNotNull { if (it.aliasName != null) it.importedFqName else null } + fun createImportResolver(indexedImports: IndexedImports, trace: BindingTrace, excludedImports: List? = null) = LazyImportResolver( storageManager, qualifiedExpressionResolver, moduleDescriptor, platformToKotlinClassMap, languageVersionSettings, @@ -100,37 +84,60 @@ class FileScopeFactory( val explicitImportResolver = createImportResolver(ExplicitImportsIndexed(imports), bindingTrace) val allUnderImportResolver = createImportResolver(AllUnderImportsIndexed(imports), bindingTrace) // TODO: should we count excludedImports here also? - val defaultExplicitImportResolver = createImportResolver(ExplicitImportsIndexed(defaultImportsFiltered), tempTrace) - val defaultAllUnderImportResolver = createImportResolver(AllUnderImportsIndexed(defaultImportsFiltered), tempTrace, defaultImportProvider.excludedImports) + val lazyImportingScope = object : ImportingScope by ImportingScope.Empty { + override val parent: ImportingScope by storageManager.createLazyValue { + val tempTrace = TemporaryBindingTrace.create(bindingTrace, "Transient trace for default imports lazy resolve", false) - val dummyContainerDescriptor = DummyContainerDescriptor(file, packageFragment) + val extraImports = file.originalFile.virtualFile?.let { vFile -> + val scriptExternalDependencies = getScriptExternalDependencies(vFile, file.project) + ktImportsFactory.createImportDirectives(scriptExternalDependencies?.imports?.map { ImportPath.fromString(it) }.orEmpty()) + } - var scope: ImportingScope + val allImplicitImports = defaultImports concat extraImports - scope = LazyImportScope(existingImports, defaultAllUnderImportResolver, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, - "Default all under imports in $debugName (invisible classes only)") + val defaultImportsFiltered = if (aliasImportNames.isEmpty()) { // optimization + allImplicitImports + } + else { + allImplicitImports.filter { it.isAllUnder || it.importedFqName !in aliasImportNames } + } - scope = LazyImportScope(scope, allUnderImportResolver, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, - "All under imports in $debugName (invisible classes only)") + val defaultExplicitImportResolver = createImportResolver(ExplicitImportsIndexed(defaultImportsFiltered), tempTrace) + val defaultAllUnderImportResolver = createImportResolver(AllUnderImportsIndexed(defaultImportsFiltered), tempTrace, defaultImportProvider.excludedImports) - scope = currentPackageScope(packageView, aliasImportNames, dummyContainerDescriptor, FilteringKind.INVISIBLE_CLASSES, scope) + val dummyContainerDescriptor = DummyContainerDescriptor(file, packageFragment) - scope = LazyImportScope(scope, defaultAllUnderImportResolver, LazyImportScope.FilteringKind.VISIBLE_CLASSES, - "Default all under imports in $debugName (visible classes)") + var scope: ImportingScope - scope = LazyImportScope(scope, allUnderImportResolver, LazyImportScope.FilteringKind.VISIBLE_CLASSES, - "All under imports in $debugName (visible classes)") + val debugName = "LazyFileScope for file " + file.name + scope = LazyImportScope(existingImports, defaultAllUnderImportResolver, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, + "Default all under imports in $debugName (invisible classes only)") - scope = LazyImportScope(scope, defaultExplicitImportResolver, LazyImportScope.FilteringKind.ALL, - "Default explicit imports in $debugName") + scope = LazyImportScope(scope, allUnderImportResolver, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, + "All under imports in $debugName (invisible classes only)") - scope = SubpackagesImportingScope(scope, moduleDescriptor, FqName.ROOT) + scope = currentPackageScope(packageView, aliasImportNames, dummyContainerDescriptor, FilteringKind.INVISIBLE_CLASSES, scope) - scope = currentPackageScope(packageView, aliasImportNames, dummyContainerDescriptor, FilteringKind.VISIBLE_CLASSES, scope) + scope = LazyImportScope(scope, defaultAllUnderImportResolver, LazyImportScope.FilteringKind.VISIBLE_CLASSES, + "Default all under imports in $debugName (visible classes)") - val importingScope = LazyImportScope(scope, explicitImportResolver, LazyImportScope.FilteringKind.ALL, "Explicit imports in $debugName") + scope = LazyImportScope(scope, allUnderImportResolver, LazyImportScope.FilteringKind.VISIBLE_CLASSES, + "All under imports in $debugName (visible classes)") + + scope = LazyImportScope(scope, defaultExplicitImportResolver, LazyImportScope.FilteringKind.ALL, + "Default explicit imports in $debugName") + + scope = SubpackagesImportingScope(scope, moduleDescriptor, FqName.ROOT) + + scope = currentPackageScope(packageView, aliasImportNames, dummyContainerDescriptor, FilteringKind.VISIBLE_CLASSES, scope) + + LazyImportScope(scope, explicitImportResolver, LazyImportScope.FilteringKind.ALL, "Explicit imports in $debugName") + + } + } + + val lexicalScope = LexicalScope.Empty(lazyImportingScope, topLevelDescriptorProvider.getPackageFragment(file.packageFqName)!!) - val lexicalScope = LexicalScope.Empty(importingScope, packageFragment) val importResolver = object : ImportResolver { override fun forceResolveAllImports() { @@ -148,7 +155,7 @@ class FileScopeFactory( } } - return FileScopes(lexicalScope, importingScope, importResolver) + return FileScopes(lexicalScope, lazyImportingScope, importResolver) } private enum class FilteringKind {