Allow to exclude specific types from packages imported by default.
This commit is contained in:
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.utils.Printer
|
|||||||
|
|
||||||
class AllUnderImportScope(
|
class AllUnderImportScope(
|
||||||
descriptor: DeclarationDescriptor,
|
descriptor: DeclarationDescriptor,
|
||||||
aliasImportNames: Collection<FqName>
|
excludedImportNames: Collection<FqName>
|
||||||
) : BaseImportingScope(null) {
|
) : BaseImportingScope(null) {
|
||||||
|
|
||||||
private val scopes: List<ResolutionScope> = if (descriptor is ClassDescriptor) {
|
private val scopes: List<ResolutionScope> = if (descriptor is ClassDescriptor) {
|
||||||
@@ -40,12 +40,13 @@ class AllUnderImportScope(
|
|||||||
listOf((descriptor as PackageViewDescriptor).memberScope)
|
listOf((descriptor as PackageViewDescriptor).memberScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val excludedNames = if (aliasImportNames.isEmpty()) { // optimization
|
private val excludedNames: Set<Name> = if (excludedImportNames.isEmpty()) { // optimization
|
||||||
emptyList<Name>()
|
emptySet<Name>()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
val fqName = DescriptorUtils.getFqNameSafe(descriptor)
|
val fqName = DescriptorUtils.getFqNameSafe(descriptor)
|
||||||
aliasImportNames.mapNotNull { if (it.parent() == fqName) it.shortName() else null }
|
// toSet() is used here instead mapNotNullTo(hashSetOf()) because it results in not keeping empty sets as separate instances
|
||||||
|
excludedImportNames.mapNotNull { if (it.parent() == fqName) it.shortName() else null }.toSet()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<DeclarationDescriptor> {
|
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List<DeclarationDescriptor> {
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ class QualifiedExpressionResolver(val classifierUsageCheckers: Iterable<Classifi
|
|||||||
importDirective: KtImportDirective,
|
importDirective: KtImportDirective,
|
||||||
moduleDescriptor: ModuleDescriptor,
|
moduleDescriptor: ModuleDescriptor,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
aliasImportNames: Collection<FqName>,
|
excludedImportNames: Collection<FqName>,
|
||||||
packageFragmentForVisibilityCheck: PackageFragmentDescriptor?
|
packageFragmentForVisibilityCheck: PackageFragmentDescriptor?
|
||||||
): ImportingScope? { // null if some error happened
|
): ImportingScope? { // null if some error happened
|
||||||
val importedReference = importDirective.importedReference ?: return null
|
val importedReference = importDirective.importedReference ?: return null
|
||||||
@@ -182,7 +182,7 @@ class QualifiedExpressionResolver(val classifierUsageCheckers: Iterable<Classifi
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return AllUnderImportScope(packageOrClassDescriptor, aliasImportNames)
|
return AllUnderImportScope(packageOrClassDescriptor, excludedImportNames)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return processSingleImport(moduleDescriptor, trace, importDirective, path, lastPart, packageFragmentForCheck)
|
return processSingleImport(moduleDescriptor, trace, importDirective, path, lastPart, packageFragmentForCheck)
|
||||||
|
|||||||
@@ -58,26 +58,19 @@ class FileScopeFactory(
|
|||||||
val debugName = "LazyFileScope for file " + file.name
|
val debugName = "LazyFileScope for file " + file.name
|
||||||
val tempTrace = TemporaryBindingTrace.create(bindingTrace, "Transient trace for default imports lazy resolve")
|
val tempTrace = TemporaryBindingTrace.create(bindingTrace, "Transient trace for default imports lazy resolve")
|
||||||
|
|
||||||
|
infix fun <T> Collection<T>.concat(other: Collection<T>?) =
|
||||||
|
if (other == null || other.isEmpty()) this else this + other
|
||||||
|
|
||||||
val imports = file.importDirectives
|
val imports = file.importDirectives
|
||||||
|
|
||||||
val aliasImportNames = imports.mapNotNull { if (it.aliasName != null) it.importedFqName else null }
|
val aliasImportNames = imports.mapNotNull { if (it.aliasName != null) it.importedFqName else null }
|
||||||
|
|
||||||
val packageView = moduleDescriptor.getPackage(file.packageFqName)
|
|
||||||
val packageFragment = topLevelDescriptorProvider.getPackageFragment(file.packageFqName)
|
|
||||||
?: error("Could not find fragment ${file.packageFqName} for file ${file.name}")
|
|
||||||
|
|
||||||
fun createImportResolver(indexedImports: IndexedImports, trace: BindingTrace)
|
|
||||||
= LazyImportResolver(storageManager, qualifiedExpressionResolver, moduleDescriptor, indexedImports, aliasImportNames, trace, packageFragment)
|
|
||||||
|
|
||||||
val explicitImportResolver = createImportResolver(ExplicitImportsIndexed(imports), bindingTrace)
|
|
||||||
val allUnderImportResolver = createImportResolver(AllUnderImportsIndexed(imports), bindingTrace)
|
|
||||||
|
|
||||||
val extraImports = file.originalFile.virtualFile?.let { vFile ->
|
val extraImports = file.originalFile.virtualFile?.let { vFile ->
|
||||||
val scriptExternalDependencies = getScriptExternalDependencies(vFile, file.project)
|
val scriptExternalDependencies = getScriptExternalDependencies(vFile, file.project)
|
||||||
ktImportsFactory.createImportDirectives(scriptExternalDependencies?.imports?.map { ImportPath(it) }.orEmpty())
|
ktImportsFactory.createImportDirectives(scriptExternalDependencies?.imports?.map { ImportPath(it) }.orEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
val allImplicitImports = defaultImports + extraImports.orEmpty()
|
val allImplicitImports = defaultImports concat extraImports
|
||||||
|
|
||||||
val defaultImportsFiltered = if (aliasImportNames.isEmpty()) { // optimization
|
val defaultImportsFiltered = if (aliasImportNames.isEmpty()) { // optimization
|
||||||
allImplicitImports
|
allImplicitImports
|
||||||
@@ -85,8 +78,19 @@ class FileScopeFactory(
|
|||||||
else {
|
else {
|
||||||
allImplicitImports.filter { it.isAllUnder || it.importedFqName !in aliasImportNames }
|
allImplicitImports.filter { it.isAllUnder || it.importedFqName !in aliasImportNames }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val packageView = moduleDescriptor.getPackage(file.packageFqName)
|
||||||
|
val packageFragment = topLevelDescriptorProvider.getPackageFragment(file.packageFqName)
|
||||||
|
?: error("Could not find fragment ${file.packageFqName} for file ${file.name}")
|
||||||
|
|
||||||
|
fun createImportResolver(indexedImports: IndexedImports, trace: BindingTrace, excludedImports: List<FqName>? = null)
|
||||||
|
= LazyImportResolver(storageManager, qualifiedExpressionResolver, moduleDescriptor, indexedImports, aliasImportNames concat excludedImports, trace, packageFragment)
|
||||||
|
|
||||||
|
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 defaultExplicitImportResolver = createImportResolver(ExplicitImportsIndexed(defaultImportsFiltered), tempTrace)
|
||||||
val defaultAllUnderImportResolver = createImportResolver(AllUnderImportsIndexed(defaultImportsFiltered), tempTrace)
|
val defaultAllUnderImportResolver = createImportResolver(AllUnderImportsIndexed(defaultImportsFiltered), tempTrace, moduleDescriptor.excludedImports)
|
||||||
|
|
||||||
val dummyContainerDescriptor = DummyContainerDescriptor(file, packageFragment)
|
val dummyContainerDescriptor = DummyContainerDescriptor(file, packageFragment)
|
||||||
|
|
||||||
|
|||||||
@@ -75,14 +75,14 @@ class LazyImportResolver(
|
|||||||
val qualifiedExpressionResolver: QualifiedExpressionResolver,
|
val qualifiedExpressionResolver: QualifiedExpressionResolver,
|
||||||
val moduleDescriptor: ModuleDescriptor,
|
val moduleDescriptor: ModuleDescriptor,
|
||||||
val indexedImports: IndexedImports,
|
val indexedImports: IndexedImports,
|
||||||
aliasImportNames: Collection<FqName>,
|
excludedImportNames: Collection<FqName>,
|
||||||
private val traceForImportResolve: BindingTrace,
|
private val traceForImportResolve: BindingTrace,
|
||||||
private val packageFragment: PackageFragmentDescriptor
|
private val packageFragment: PackageFragmentDescriptor
|
||||||
) : ImportResolver {
|
) : ImportResolver {
|
||||||
private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues {
|
private val importedScopesProvider = storageManager.createMemoizedFunctionWithNullableValues {
|
||||||
directive: KtImportDirective ->
|
directive: KtImportDirective ->
|
||||||
val directiveImportScope = qualifiedExpressionResolver.processImportReference(
|
val directiveImportScope = qualifiedExpressionResolver.processImportReference(
|
||||||
directive, moduleDescriptor, traceForImportResolve, aliasImportNames, packageFragment) ?: return@createMemoizedFunctionWithNullableValues null
|
directive, moduleDescriptor, traceForImportResolve, excludedImportNames, packageFragment) ?: return@createMemoizedFunctionWithNullableValues null
|
||||||
|
|
||||||
if (!directive.isAllUnder) {
|
if (!directive.isAllUnder) {
|
||||||
PlatformTypesMappedToKotlinChecker.checkPlatformTypesMappedToKotlin(
|
PlatformTypesMappedToKotlinChecker.checkPlatformTypesMappedToKotlin(
|
||||||
|
|||||||
+1
-1
@@ -49,7 +49,7 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization
|
|||||||
val storageManager = LockBasedStorageManager()
|
val storageManager = LockBasedStorageManager()
|
||||||
val builtIns = JvmBuiltIns(storageManager)
|
val builtIns = JvmBuiltIns(storageManager)
|
||||||
val module = ModuleDescriptorImpl(Name.special("<runtime module for $classLoader>"), storageManager,
|
val module = ModuleDescriptorImpl(Name.special("<runtime module for $classLoader>"), storageManager,
|
||||||
ModuleParameters(listOf(), JavaToKotlinClassMap.INSTANCE), builtIns)
|
ModuleParameters(emptyList(), emptyList(), JavaToKotlinClassMap.INSTANCE), builtIns)
|
||||||
|
|
||||||
val reflectKotlinClassFinder = ReflectKotlinClassFinder(classLoader)
|
val reflectKotlinClassFinder = ReflectKotlinClassFinder(classLoader)
|
||||||
val deserializedDescriptorResolver = DeserializedDescriptorResolver(RuntimeErrorReporter)
|
val deserializedDescriptorResolver = DeserializedDescriptorResolver(RuntimeErrorReporter)
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ interface ModuleDescriptor : DeclarationDescriptor, ModuleParameters {
|
|||||||
|
|
||||||
interface ModuleParameters {
|
interface ModuleParameters {
|
||||||
val defaultImports: List<ImportPath>
|
val defaultImports: List<ImportPath>
|
||||||
|
val excludedImports: List<FqName> get() = emptyList()
|
||||||
val platformToKotlinClassMap: PlatformToKotlinClassMap
|
val platformToKotlinClassMap: PlatformToKotlinClassMap
|
||||||
|
|
||||||
object Empty: ModuleParameters {
|
object Empty: ModuleParameters {
|
||||||
@@ -57,8 +58,9 @@ interface ModuleParameters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ModuleParameters(defaultImports: List<ImportPath>, platformToKotlinClassMap: PlatformToKotlinClassMap): ModuleParameters =
|
fun ModuleParameters(defaultImports: List<ImportPath>, excludedImports: List<FqName>, platformToKotlinClassMap: PlatformToKotlinClassMap): ModuleParameters =
|
||||||
object : ModuleParameters {
|
object : ModuleParameters {
|
||||||
override val defaultImports: List<ImportPath> = defaultImports
|
override val defaultImports: List<ImportPath> = defaultImports
|
||||||
|
override val excludedImports: List<FqName> get() = excludedImports
|
||||||
override val platformToKotlinClassMap: PlatformToKotlinClassMap = platformToKotlinClassMap
|
override val platformToKotlinClassMap: PlatformToKotlinClassMap = platformToKotlinClassMap
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,12 @@ public class ErrorUtils {
|
|||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<FqName> getExcludedImports() {
|
||||||
|
return emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Annotations getAnnotations() {
|
public Annotations getAnnotations() {
|
||||||
|
|||||||
@@ -85,5 +85,5 @@ fun ResolutionFacade.resolveImportReference(
|
|||||||
val importDirective = KtPsiFactory(project).createImportDirective(ImportPath(fqName, false))
|
val importDirective = KtPsiFactory(project).createImportDirective(ImportPath(fqName, false))
|
||||||
val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, QualifiedExpressionResolver::class.java)
|
val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, QualifiedExpressionResolver::class.java)
|
||||||
return qualifiedExpressionResolver.processImportReference(
|
return qualifiedExpressionResolver.processImportReference(
|
||||||
importDirective, moduleDescriptor, BindingTraceContext(), aliasImportNames = emptyList(), packageFragmentForVisibilityCheck = null)?.getContributedDescriptors() ?: emptyList()
|
importDirective, moduleDescriptor, BindingTraceContext(), excludedImportNames = emptyList(), packageFragmentForVisibilityCheck = null)?.getContributedDescriptors() ?: emptyList()
|
||||||
}
|
}
|
||||||
+1
-1
@@ -136,7 +136,7 @@ class CodeFragmentAnalyzer(
|
|||||||
|
|
||||||
val importScopes = importList.imports.mapNotNull {
|
val importScopes = importList.imports.mapNotNull {
|
||||||
qualifierResolver.processImportReference(it, resolveSession.moduleDescriptor, resolveSession.trace,
|
qualifierResolver.processImportReference(it, resolveSession.moduleDescriptor, resolveSession.trace,
|
||||||
aliasImportNames = emptyList(), packageFragmentForVisibilityCheck = null)
|
excludedImportNames = emptyList(), packageFragmentForVisibilityCheck = null)
|
||||||
}
|
}
|
||||||
|
|
||||||
return scopeForContextElement.addImportingScopes(importScopes) to dataFlowInfo
|
return scopeForContextElement.addImportingScopes(importScopes) to dataFlowInfo
|
||||||
|
|||||||
+4
-1
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.context.ContextKt;
|
|||||||
import org.jetbrains.kotlin.context.MutableModuleContext;
|
import org.jetbrains.kotlin.context.MutableModuleContext;
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptorKt;
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptorKt;
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleParameters;
|
||||||
import org.jetbrains.kotlin.frontend.di.InjectionKt;
|
import org.jetbrains.kotlin.frontend.di.InjectionKt;
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex;
|
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex;
|
||||||
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope;
|
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope;
|
||||||
@@ -239,10 +240,12 @@ public class SourceNavigationHelper {
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
TargetPlatform platform = TargetPlatform.Default.INSTANCE;
|
TargetPlatform platform = TargetPlatform.Default.INSTANCE;
|
||||||
|
ModuleParameters defaultJvmModuleParameters = JvmPlatform.INSTANCE.getDefaultModuleParameters();
|
||||||
MutableModuleContext newModuleContext = ContextKt.ContextForNewModule(
|
MutableModuleContext newModuleContext = ContextKt.ContextForNewModule(
|
||||||
project, Name.special("<library module>"),
|
project, Name.special("<library module>"),
|
||||||
ModuleDescriptorKt.ModuleParameters(
|
ModuleDescriptorKt.ModuleParameters(
|
||||||
JvmPlatform.INSTANCE.getDefaultModuleParameters().getDefaultImports(),
|
defaultJvmModuleParameters.getDefaultImports(),
|
||||||
|
defaultJvmModuleParameters.getExcludedImports(),
|
||||||
PlatformToKotlinClassMap.EMPTY
|
PlatformToKotlinClassMap.EMPTY
|
||||||
),
|
),
|
||||||
DefaultBuiltIns.getInstance()
|
DefaultBuiltIns.getInstance()
|
||||||
|
|||||||
Reference in New Issue
Block a user