diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt index 8e8fe2c4150..97ab7fcd40e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyFileScope.kt @@ -75,9 +75,6 @@ class LazyFileScope private( ?: throw IllegalStateException("Root package not found") val packageFragment = resolveSession.getPackageFragment(file.getPackageFqName()) - val onlyVisibleFilter = VisibilityFilter(packageFragment, true) - val onlyInvisibleFilter = VisibilityFilter(packageFragment, false) - val aliasImportResolver = LazyImportResolver(resolveSession, packageView, AliasImportsIndexed(imports), traceForImportResolve, true) val allUnderImportResolver = LazyImportResolver(resolveSession, packageView, AllUnderImportsIndexed(imports), traceForImportResolve, true) val defaultAliasImportResolver = LazyImportResolver(resolveSession, rootPackageView, AliasImportsIndexed(defaultImports), traceForDefaultImportResolve, false) @@ -85,36 +82,24 @@ class LazyFileScope private( val scopeChain = ArrayList() - scopeChain.add(LazyImportScope(aliasImportResolver, { true }, "Alias imports in $debugName")) + scopeChain.add(LazyImportScope(aliasImportResolver, packageFragment, LazyImportScope.FilteringKind.ALL, "Alias imports in $debugName")) scopeChain.add(NoSubpackagesInPackageScope(packageView)) //TODO: problems with visibility too scopeChain.add(JetModuleUtil.getSubpackagesOfRootScope(resolveSession.getModuleDescriptor())) - scopeChain.add(LazyImportScope(defaultAliasImportResolver, { true }, "Default alias imports in $debugName")) + scopeChain.add(LazyImportScope(defaultAliasImportResolver, packageFragment, LazyImportScope.FilteringKind.ALL, "Default alias imports in $debugName")) - scopeChain.add(LazyImportScope(defaultAllUnderImportResolver, onlyVisibleFilter, "Default all under imports in $debugName (visible classes)")) - scopeChain.add(LazyImportScope(allUnderImportResolver, onlyVisibleFilter, "All under imports in $debugName (visible classes)")) + scopeChain.add(LazyImportScope(defaultAllUnderImportResolver, packageFragment, LazyImportScope.FilteringKind.VISIBLE_CLASSES, "Default all under imports in $debugName (visible classes)")) + scopeChain.add(LazyImportScope(allUnderImportResolver, packageFragment, LazyImportScope.FilteringKind.VISIBLE_CLASSES, "All under imports in $debugName (visible classes)")) scopeChain.addAll(additionalScopes) - scopeChain.add(LazyImportScope(defaultAllUnderImportResolver, onlyInvisibleFilter, "Default all under imports in $debugName (invisible classes only)")) - scopeChain.add(LazyImportScope(allUnderImportResolver, onlyInvisibleFilter, "All under imports in $debugName (invisible classes only)")) + scopeChain.add(LazyImportScope(defaultAllUnderImportResolver, packageFragment, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, "Default all under imports in $debugName (invisible classes only)")) + scopeChain.add(LazyImportScope(allUnderImportResolver, packageFragment, LazyImportScope.FilteringKind.INVISIBLE_CLASSES, "All under imports in $debugName (invisible classes only)")) return LazyFileScope(scopeChain, aliasImportResolver, allUnderImportResolver, packageFragment, debugName) } - private class VisibilityFilter( - private val packageFragment: PackageFragmentDescriptor, - private val visible: Boolean - ) : (DeclarationDescriptor) -> Boolean { - override fun invoke(descriptor: DeclarationDescriptor): Boolean { - if (descriptor !is ClassDescriptor) return visible - val visibility = descriptor.getVisibility() - if (!visibility.mustCheckInImports()) return visible - return Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, packageFragment) == visible - } - } - private fun getPackageViewDescriptor(file: JetFile, resolveSession: ResolveSession): PackageViewDescriptor { val fqName = file.getPackageFqName() return resolveSession.getModuleDescriptor().getPackage(fqName) 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 e93232fe8c5..b6a55261d25 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.ScopeByNameSelec import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.ScopeByNameMultiSelector import org.jetbrains.kotlin.psi.JetPsiUtil import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue trait IndexedImports { val imports: List @@ -225,55 +226,66 @@ class LazyImportResolver( class LazyImportScope( private val importResolver: LazyImportResolver, - private val filter: (DeclarationDescriptor) -> Boolean, + private val packageFragment: PackageFragmentDescriptor, + private val filteringKind: LazyImportScope.FilteringKind, private val debugName: String ) : JetScope { - private inner class FilteringScopeByNameSelector( - private val selector: ScopeByNameSelector - ) : ScopeByNameSelector { - override fun get(scope: JetScope, name: Name): D? { - val descriptor = selector.get(scope, name) - return if (descriptor != null && filter(descriptor)) descriptor else null - } + enum class FilteringKind { + ALL + VISIBLE_CLASSES + INVISIBLE_CLASSES } - private inner class FilteringScopeByNameMultiSelector( - private val selector: ScopeByNameMultiSelector - ) : ScopeByNameMultiSelector { - override fun get(scope: JetScope, name: Name): Collection { - return selector.get(scope, name).filter(filter) + private val classifierDescriptorSelector = object : ScopeByNameSelector { + override fun get(scope: JetScope, name: Name): ClassifierDescriptor? { + val descriptor = JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR.get(scope, name) + return if (descriptor != null && filter(descriptor as ClassDescriptor/*no type parameter can be imported*/)) descriptor else null + } + + private fun filter(descriptor: ClassDescriptor): Boolean { + if (filteringKind == FilteringKind.ALL) return true + val visibility = descriptor.getVisibility() + val includeVisible = filteringKind == FilteringKind.VISIBLE_CLASSES + if (!visibility.mustCheckInImports()) return includeVisible + return Visibilities.isVisible(ReceiverValue.IRRELEVANT_RECEIVER, descriptor, packageFragment) == includeVisible } } override fun getClassifier(name: Name): ClassifierDescriptor? { - return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, FilteringScopeByNameSelector(JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR)) + return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, classifierDescriptorSelector) } override fun getPackage(name: Name): PackageViewDescriptor? { - return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, FilteringScopeByNameSelector(JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR)) + if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return null + return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR) } override fun getProperties(name: Name): Collection { - return importResolver.collectFromImports(name, LookupMode.EVERYTHING, FilteringScopeByNameMultiSelector(JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR)) + if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf() + return importResolver.collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR) } override fun getLocalVariable(name: Name) = null override fun getFunctions(name: Name): Collection { - return importResolver.collectFromImports(name, LookupMode.EVERYTHING, FilteringScopeByNameMultiSelector(JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR)) + if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf() + return importResolver.collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR) } override fun getDeclarationsByLabel(labelName: Name): Collection = listOf() override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection { + // we do not perform any filtering by visibility here because all descriptors from both visible/invisible filter scopes are to be added anyway + if (filteringKind == FilteringKind.INVISIBLE_CLASSES) return listOf() + return importResolver.resolveSession.getStorageManager().compute { val descriptors = LinkedHashSet() for (directive in importResolver.indexedImports.imports) { val importPath = directive.getImportPath() ?: continue val importedName = importPath.getImportedName() if (importedName == null || nameFilter(importedName)) { - importResolver.getImportScope(directive, LookupMode.EVERYTHING).getDescriptors(kindFilter, nameFilter).filterTo(descriptors, filter) + descriptors.addAll(importResolver.getImportScope(directive, LookupMode.EVERYTHING).getDescriptors(kindFilter, nameFilter)) } } descriptors