Visible classes take priority when resolving imports with *
This commit is contained in:
@@ -27,32 +27,31 @@ import org.jetbrains.kotlin.resolve.NoSubpackagesInPackageScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import java.util.ArrayList
|
||||
|
||||
class LazyFileScope private(
|
||||
private val aliasImportsScope: LazyImportScope,
|
||||
private val allUnderImportsScope: LazyImportScope,
|
||||
private val defaultAliasImportsScope: LazyImportScope,
|
||||
private val defaultAllUnderImportsScope: LazyImportScope,
|
||||
currentPackageMembersScope: JetScope,
|
||||
rootPackagesScope: JetScope,
|
||||
additionalScopes: List<JetScope>,
|
||||
private val scopeChain: List<JetScope>,
|
||||
private val aliasImportResolver: LazyImportResolver,
|
||||
private val allUnderImportResolver: LazyImportResolver,
|
||||
containingDeclaration: PackageFragmentDescriptor,
|
||||
debugName: String
|
||||
) : ChainedScope(containingDeclaration,
|
||||
debugName,
|
||||
*(listOf(aliasImportsScope, currentPackageMembersScope, rootPackagesScope, defaultAliasImportsScope, defaultAllUnderImportsScope, allUnderImportsScope) + additionalScopes).copyToArray()) {
|
||||
) : ChainedScope(containingDeclaration, debugName, *scopeChain.copyToArray()) {
|
||||
|
||||
public fun forceResolveAllImports() {
|
||||
aliasImportsScope.forceResolveAllContents()
|
||||
allUnderImportsScope.forceResolveAllContents()
|
||||
aliasImportResolver.forceResolveAllContents()
|
||||
allUnderImportResolver.forceResolveAllContents()
|
||||
}
|
||||
|
||||
public fun forceResolveImport(importDirective: JetImportDirective) {
|
||||
if (importDirective.isAllUnder()) {
|
||||
allUnderImportsScope.forceResolveImportDirective(importDirective)
|
||||
allUnderImportResolver.forceResolveImportDirective(importDirective)
|
||||
}
|
||||
else {
|
||||
aliasImportsScope.forceResolveImportDirective(importDirective)
|
||||
aliasImportResolver.forceResolveImportDirective(importDirective)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,17 +74,46 @@ class LazyFileScope private(
|
||||
val inRootPackage = packageView.getFqName().isRoot()
|
||||
val rootPackageView = resolveSession.getModuleDescriptor().getPackage(FqName.ROOT)
|
||||
?: throw IllegalStateException("Root package not found")
|
||||
val packageFragment = resolveSession.getPackageFragment(file.getPackageFqName())
|
||||
|
||||
val currentPackageMembersScope = NoSubpackagesInPackageScope(packageView)
|
||||
val rootPackagesScope = JetModuleUtil.getSubpackagesOfRootScope(resolveSession.getModuleDescriptor())
|
||||
val aliasImportsScope = LazyImportScope(resolveSession, packageView, AliasImportsIndexed(imports), traceForImportResolve, "Alias imports in $debugName", inRootPackage)
|
||||
val allUnderImportsScope = LazyImportScope(resolveSession, packageView, AllUnderImportsIndexed(imports), traceForImportResolve, "All under imports in $debugName", inRootPackage)
|
||||
val defaultAliasImportsScope = LazyImportScope(resolveSession, rootPackageView, AliasImportsIndexed(defaultImports), traceForDefaultImportResolve, "Default alias imports in $debugName", false)
|
||||
val defaultAllUnderImportsScope = LazyImportScope(resolveSession, rootPackageView, AllUnderImportsIndexed(defaultImports), traceForDefaultImportResolve, "Default all under imports in $debugName", false)
|
||||
val onlyVisibleFilter = VisibilityFilter(packageFragment, true)
|
||||
val onlyInvisibleFilter = VisibilityFilter(packageFragment, false)
|
||||
|
||||
return LazyFileScope(aliasImportsScope, allUnderImportsScope, defaultAliasImportsScope, defaultAllUnderImportsScope,
|
||||
currentPackageMembersScope, rootPackagesScope, additionalScopes,
|
||||
resolveSession.getPackageFragment(file.getPackageFqName()), debugName)
|
||||
val aliasImportResolver = LazyImportResolver(resolveSession, packageView, AliasImportsIndexed(imports), traceForImportResolve, inRootPackage)
|
||||
val allUnderImportResolver = LazyImportResolver(resolveSession, packageView, AllUnderImportsIndexed(imports), traceForImportResolve, inRootPackage)
|
||||
val defaultAliasImportResolver = LazyImportResolver(resolveSession, rootPackageView, AliasImportsIndexed(defaultImports), traceForDefaultImportResolve, false)
|
||||
val defaultAllUnderImportResolver = LazyImportResolver(resolveSession, rootPackageView, AllUnderImportsIndexed(defaultImports), traceForDefaultImportResolve, false)
|
||||
|
||||
val scopeChain = ArrayList<JetScope>()
|
||||
|
||||
scopeChain.add(LazyImportScope(aliasImportResolver, { true }, "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(defaultAllUnderImportResolver, onlyVisibleFilter, "Default all under imports in $debugName (visible classes)"))
|
||||
scopeChain.add(LazyImportScope(allUnderImportResolver, onlyVisibleFilter, "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)"))
|
||||
|
||||
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 {
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.util.HashSet
|
||||
import com.google.common.collect.ListMultimap
|
||||
import kotlin.properties.Delegates
|
||||
import com.google.common.collect.ImmutableListMultimap
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.ScopeByNameSelector
|
||||
import org.jetbrains.kotlin.resolve.scopes.JetScopeSelectorUtil.ScopeByNameMultiSelector
|
||||
|
||||
trait IndexedImports {
|
||||
val imports: List<JetImportDirective>
|
||||
@@ -61,15 +63,13 @@ class AliasImportsIndexed(allImports: Collection<JetImportDirective>) : IndexedI
|
||||
override fun importsForName(name: Name) = nameToDirectives.get(name)
|
||||
}
|
||||
|
||||
class LazyImportScope(
|
||||
private val resolveSession: ResolveSession,
|
||||
private val containingDeclaration: PackageViewDescriptor,
|
||||
private val indexedImports: IndexedImports,
|
||||
class LazyImportResolver(
|
||||
val resolveSession: ResolveSession,
|
||||
val packageView: PackageViewDescriptor,
|
||||
val indexedImports: IndexedImports,
|
||||
private val traceForImportResolve: BindingTrace,
|
||||
private val debugName: String,
|
||||
private val inRootPackage: Boolean
|
||||
) : JetScope {
|
||||
|
||||
) {
|
||||
private val importedScopesProvider = resolveSession.getStorageManager().createMemoizedFunction {
|
||||
(directive: JetImportDirective) -> ImportDirectiveResolveCache(directive)
|
||||
}
|
||||
@@ -95,7 +95,7 @@ class LazyImportScope(
|
||||
cachedStatus.scope
|
||||
}
|
||||
else {
|
||||
val directiveImportScope = WritableScopeImpl(JetScope.Empty, containingDeclaration, RedeclarationHandler.DO_NOTHING, "Scope for import '" + directive.getDebugText() + "' resolve in " + toString())
|
||||
val directiveImportScope = WritableScopeImpl(JetScope.Empty, packageView, RedeclarationHandler.DO_NOTHING, "Scope for import '" + directive.getDebugText() + "' resolve in " + toString())
|
||||
directiveImportScope.changeLockLevel(WritableScope.LockLevel.BOTH)
|
||||
|
||||
val importer = Importer()
|
||||
@@ -104,11 +104,11 @@ class LazyImportScope(
|
||||
val descriptors: Collection<DeclarationDescriptor>
|
||||
try {
|
||||
val resolver = resolveSession.getQualifiedExpressionResolver()
|
||||
descriptors = resolver.processImportReference(directive, rootScope, containingDeclaration.getMemberScope(),
|
||||
descriptors = resolver.processImportReference(directive, rootScope, packageView.getMemberScope(),
|
||||
importer, traceForImportResolve, mode)
|
||||
importer.doImport(directiveImportScope)
|
||||
if (mode == LookupMode.EVERYTHING) {
|
||||
ImportsResolver.checkPlatformTypesMappedToKotlin(containingDeclaration.getModule(), traceForImportResolve, directive, descriptors)
|
||||
ImportsResolver.checkPlatformTypesMappedToKotlin(packageView.getModule(), traceForImportResolve, directive, descriptors)
|
||||
}
|
||||
}
|
||||
finally {
|
||||
@@ -139,10 +139,10 @@ class LazyImportScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : DeclarationDescriptor> selectSingleFromImports(
|
||||
public fun <D : DeclarationDescriptor> selectSingleFromImports(
|
||||
name: Name,
|
||||
lookupMode: LookupMode,
|
||||
descriptorSelector: JetScopeSelectorUtil.ScopeByNameSelector<D>
|
||||
descriptorSelector: ScopeByNameSelector<D>
|
||||
): D? {
|
||||
fun compute(): D? {
|
||||
val imports = indexedImports.importsForName(name)
|
||||
@@ -162,10 +162,10 @@ class LazyImportScope(
|
||||
return resolveSession.getStorageManager().compute(::compute)
|
||||
}
|
||||
|
||||
private fun <D : DeclarationDescriptor> collectFromImports(
|
||||
public fun <D : DeclarationDescriptor> collectFromImports(
|
||||
name: Name,
|
||||
lookupMode: LookupMode,
|
||||
descriptorsSelector: JetScopeSelectorUtil.ScopeByNameMultiSelector<D>
|
||||
descriptorsSelector: ScopeByNameMultiSelector<D>
|
||||
): Collection<D> {
|
||||
return resolveSession.getStorageManager().compute {
|
||||
val descriptors = HashSet<D>()
|
||||
@@ -182,36 +182,69 @@ class LazyImportScope(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getImportScope(directive: JetImportDirective, lookupMode: LookupMode) = importedScopesProvider(directive).scopeForMode(lookupMode)
|
||||
public fun getImportScope(directive: JetImportDirective, lookupMode: LookupMode): JetScope {
|
||||
return importedScopesProvider(directive).scopeForMode(lookupMode)
|
||||
}
|
||||
|
||||
override fun getClassifier(name: Name) = selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR)
|
||||
public fun printScopeStructure(p: Printer) {
|
||||
p.print("rootScope = ")
|
||||
rootScope.printScopeStructure(p.withholdIndentOnce())
|
||||
}
|
||||
}
|
||||
|
||||
override fun getPackage(name: Name) = selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR)
|
||||
class LazyImportScope(
|
||||
private val importResolver: LazyImportResolver,
|
||||
private val filter: (DeclarationDescriptor) -> Boolean,
|
||||
private val debugName: String
|
||||
) : JetScope {
|
||||
|
||||
override fun getProperties(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR)
|
||||
private inner class FilteringScopeByNameSelector<D : DeclarationDescriptor>(
|
||||
private val selector: ScopeByNameSelector<D>
|
||||
) : ScopeByNameSelector<D> {
|
||||
override fun get(scope: JetScope, name: Name): D? {
|
||||
val descriptor = selector.get(scope, name)
|
||||
return if (descriptor != null && filter(descriptor)) descriptor else null
|
||||
}
|
||||
}
|
||||
|
||||
private inner class FilteringScopeByNameMultiSelector<D : DeclarationDescriptor>(
|
||||
private val selector: ScopeByNameMultiSelector<D>
|
||||
) : ScopeByNameMultiSelector<D> {
|
||||
override fun get(scope: JetScope, name: Name): Collection<D> {
|
||||
return selector.get(scope, name).filter(filter)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getClassifier(name: Name): ClassifierDescriptor? {
|
||||
return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, FilteringScopeByNameSelector(JetScopeSelectorUtil.CLASSIFIER_DESCRIPTOR_SCOPE_SELECTOR))
|
||||
}
|
||||
|
||||
override fun getPackage(name: Name): PackageViewDescriptor? {
|
||||
return importResolver.selectSingleFromImports(name, LookupMode.ONLY_CLASSES_AND_PACKAGES, FilteringScopeByNameSelector(JetScopeSelectorUtil.PACKAGE_SCOPE_SELECTOR))
|
||||
}
|
||||
|
||||
override fun getProperties(name: Name): Collection<VariableDescriptor> {
|
||||
return importResolver.collectFromImports(name, LookupMode.EVERYTHING, FilteringScopeByNameMultiSelector(JetScopeSelectorUtil.NAMED_PROPERTIES_SCOPE_SELECTOR))
|
||||
}
|
||||
|
||||
override fun getLocalVariable(name: Name) = null
|
||||
|
||||
override fun getFunctions(name: Name) = collectFromImports(name, LookupMode.EVERYTHING, JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR)
|
||||
override fun getFunctions(name: Name): Collection<FunctionDescriptor> {
|
||||
return importResolver.collectFromImports(name, LookupMode.EVERYTHING, FilteringScopeByNameMultiSelector(JetScopeSelectorUtil.NAMED_FUNCTION_SCOPE_SELECTOR))
|
||||
}
|
||||
|
||||
override fun getDeclarationsByLabel(labelName: Name): Collection<DeclarationDescriptor> = listOf()
|
||||
|
||||
override fun getDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> {
|
||||
return resolveSession.getStorageManager().compute {
|
||||
return importResolver.resolveSession.getStorageManager().compute {
|
||||
val descriptors = LinkedHashSet<DeclarationDescriptor>()
|
||||
for (directive in indexedImports.imports) {
|
||||
if (directive == directiveUnderResolve) {
|
||||
// This is the recursion in imports analysis
|
||||
throw IllegalStateException("Recursion while resolving many imports: " + directive.getText())
|
||||
}
|
||||
|
||||
for (directive in importResolver.indexedImports.imports) {
|
||||
val importPath = directive.getImportPath() ?: continue
|
||||
val importedName = importPath.getImportedName()
|
||||
if (importedName == null || nameFilter(importedName)) {
|
||||
descriptors.addAll(getImportScope(directive, LookupMode.EVERYTHING).getDescriptors(kindFilter, nameFilter))
|
||||
importResolver.getImportScope(directive, LookupMode.EVERYTHING).getDescriptors(kindFilter, nameFilter).filterTo(descriptors, filter)
|
||||
}
|
||||
}
|
||||
|
||||
descriptors
|
||||
}
|
||||
}
|
||||
@@ -220,7 +253,7 @@ class LazyImportScope(
|
||||
|
||||
override fun getOwnDeclaredDescriptors() = listOf<DeclarationDescriptor>()
|
||||
|
||||
override fun getContainingDeclaration() = containingDeclaration
|
||||
override fun getContainingDeclaration() = importResolver.packageView
|
||||
|
||||
override fun toString() = "LazyImportScope: " + debugName
|
||||
|
||||
@@ -228,10 +261,9 @@ class LazyImportScope(
|
||||
p.println(javaClass.getSimpleName(), ": ", debugName, " {")
|
||||
p.pushIndent()
|
||||
|
||||
p.println("packageDescriptor = ", containingDeclaration)
|
||||
p.println("packageDescriptor = ", importResolver.packageView)
|
||||
|
||||
p.print("rootScope = ")
|
||||
rootScope.printScopeStructure(p.withholdIndentOnce())
|
||||
importResolver.printScopeStructure(p)
|
||||
|
||||
p.popIndent()
|
||||
p.println("}")
|
||||
|
||||
Reference in New Issue
Block a user