Imports from current package are redundant too
This commit is contained in:
@@ -80,7 +80,6 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
//TODO: keep existing imports? at least aliases (comments)
|
//TODO: keep existing imports? at least aliases (comments)
|
||||||
|
|
||||||
val importInsertHelper = ImportInsertHelper.getInstance(file.getProject())
|
val importInsertHelper = ImportInsertHelper.getInstance(file.getProject())
|
||||||
val currentPackageName = file.getPackageFqName()
|
|
||||||
|
|
||||||
val descriptorsToImport = detectDescriptorsToImport()
|
val descriptorsToImport = detectDescriptorsToImport()
|
||||||
|
|
||||||
@@ -90,14 +89,9 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
for (descriptor in descriptorsToImport) {
|
for (descriptor in descriptorsToImport) {
|
||||||
val fqName = descriptor.importableFqNameSafe
|
val fqName = descriptor.importableFqNameSafe
|
||||||
val parentFqName = fqName.parent()
|
val parentFqName = fqName.parent()
|
||||||
if (descriptor is PackageViewDescriptor) {
|
if (descriptor is PackageViewDescriptor || parentFqName.isRoot()) {
|
||||||
importsToGenerate.add(ImportPath(fqName, false))
|
importsToGenerate.add(ImportPath(fqName, false))
|
||||||
}
|
}
|
||||||
else if (parentFqName.isRoot()) {
|
|
||||||
if (!currentPackageName.isRoot()) {
|
|
||||||
importsToGenerate.add(ImportPath(fqName, false))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
descriptorsByPackages.put(parentFqName, descriptor)
|
descriptorsByPackages.put(parentFqName, descriptor)
|
||||||
}
|
}
|
||||||
@@ -110,7 +104,7 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
for (packageName in descriptorsByPackages.keys()) {
|
for (packageName in descriptorsByPackages.keys()) {
|
||||||
val descriptors = descriptorsByPackages[packageName]
|
val descriptors = descriptorsByPackages[packageName]
|
||||||
val fqNames = descriptors.map { it.importableFqNameSafe }.toSet()
|
val fqNames = descriptors.map { it.importableFqNameSafe }.toSet()
|
||||||
val explicitImports = packageName != currentPackageName && fqNames.size() < codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT
|
val explicitImports = fqNames.size() < codeStyleSettings.NAME_COUNT_TO_USE_STAR_IMPORT
|
||||||
if (explicitImports) {
|
if (explicitImports) {
|
||||||
for (fqName in fqNames) {
|
for (fqName in fqNames) {
|
||||||
if (!isImportedByDefault(fqName)) {
|
if (!isImportedByDefault(fqName)) {
|
||||||
@@ -125,7 +119,7 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packageName != currentPackageName && !fqNames.all(::isImportedByDefault)) {
|
if (!fqNames.all(::isImportedByDefault)) {
|
||||||
importsToGenerate.add(ImportPath(packageName, true))
|
importsToGenerate.add(ImportPath(packageName, true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +127,7 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
|
|
||||||
// now check that there are no conflicts and all classes are really imported
|
// now check that there are no conflicts and all classes are really imported
|
||||||
val fileWithImportsText = StringBuilder {
|
val fileWithImportsText = StringBuilder {
|
||||||
append("package ").append(currentPackageName.render()).append("\n")
|
append("package ").append(file.getPackageFqName().render()).append("\n")
|
||||||
importsToGenerate.filter { it.isAllUnder() }.map { "import " + it.getPathStr() }.joinTo(this, "\n")
|
importsToGenerate.filter { it.isAllUnder() }.map { "import " + it.getPathStr() }.joinTo(this, "\n")
|
||||||
}.toString()
|
}.toString()
|
||||||
val fileWithImports = JetPsiFactory(file).createAnalyzableFile("Dummy.kt", fileWithImportsText, file)
|
val fileWithImports = JetPsiFactory(file).createAnalyzableFile("Dummy.kt", fileWithImportsText, file)
|
||||||
@@ -187,6 +181,7 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
|
|
||||||
public class CollectUsedDescriptorsVisitor(val file: JetFile, val recursive: Boolean) : JetVisitorVoid() {
|
public class CollectUsedDescriptorsVisitor(val file: JetFile, val recursive: Boolean) : JetVisitorVoid() {
|
||||||
private val _descriptors = HashSet<DeclarationDescriptor>()
|
private val _descriptors = HashSet<DeclarationDescriptor>()
|
||||||
|
private val currentPackageName = file.getPackageFqName()
|
||||||
|
|
||||||
public val descriptors: Set<DeclarationDescriptor>
|
public val descriptors: Set<DeclarationDescriptor>
|
||||||
get() = _descriptors
|
get() = _descriptors
|
||||||
@@ -218,7 +213,10 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
?: reference.resolveToDescriptors(bindingContext)
|
?: reference.resolveToDescriptors(bindingContext)
|
||||||
for (target in targets) {
|
for (target in targets) {
|
||||||
if (!target.canBeReferencedViaImport()) continue
|
if (!target.canBeReferencedViaImport()) continue
|
||||||
if (target is PackageViewDescriptor && target.fqName.parent() == FqName.ROOT) continue // no need to import top-level packages
|
val importableDescriptor = target.getImportableDescriptor()
|
||||||
|
val parentFqName = DescriptorUtils.getFqNameSafe(importableDescriptor).parent()
|
||||||
|
if (target is PackageViewDescriptor && parentFqName == FqName.ROOT) continue // no need to import top-level packages
|
||||||
|
if (target !is PackageViewDescriptor && parentFqName == currentPackageName) continue
|
||||||
|
|
||||||
if (!target.isExtension) { // for non-extension targets, count only non-qualified simple name usages
|
if (!target.isExtension) { // for non-extension targets, count only non-qualified simple name usages
|
||||||
if (element !is JetNameReferenceExpression) continue
|
if (element !is JetNameReferenceExpression) continue
|
||||||
@@ -226,7 +224,6 @@ public class KotlinImportOptimizer() : ImportOptimizer {
|
|||||||
if (element.getReceiverExpression() != null) continue
|
if (element.getReceiverExpression() != null) continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val importableDescriptor = target.getImportableDescriptor()
|
|
||||||
if (referencedName != null && importableDescriptor.getName() != referencedName) continue // resolved via alias
|
if (referencedName != null && importableDescriptor.getName() != referencedName) continue // resolved via alias
|
||||||
|
|
||||||
if (isAccessibleAsMember(importableDescriptor, element)) continue
|
if (isAccessibleAsMember(importableDescriptor, element)) continue
|
||||||
|
|||||||
+5
-1
@@ -9,10 +9,14 @@ import java.net.Unresolved // unused but unresolved
|
|||||||
|
|
||||||
import java.net.ConnectException as CE // highlighting of unused aliases not implemented yet
|
import java.net.ConnectException as CE // highlighting of unused aliases not implemented yet
|
||||||
|
|
||||||
fun foo(list: ArrayList<String>) {
|
import RootPackageClass // unused because it's in the current package
|
||||||
|
|
||||||
|
fun foo(list: ArrayList<String>, p: RootPackageClass) {
|
||||||
list.add("")
|
list.add("")
|
||||||
Date()
|
Date()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RootPackageClass
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FULL_JDK
|
// FULL_JDK
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package pack1
|
||||||
|
|
||||||
|
import pack1.ClassInPack1 // unused because it's in the current package
|
||||||
|
|
||||||
|
fun foo(p: ClassInPack1) {
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassInPack1
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package pack2
|
||||||
|
|
||||||
|
import pack2.* // unused because it's the current package
|
||||||
|
|
||||||
|
fun foo(p: ClassInPack2) {
|
||||||
|
}
|
||||||
|
|
||||||
|
class ClassInPack2
|
||||||
@@ -17,4 +17,21 @@
|
|||||||
<description>Unused import directive</description>
|
<description>Unused import directive</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>fileInPack1.kt</file>
|
||||||
|
<line>3</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="fileInPack1.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused import directive</problem_class>
|
||||||
|
<description>Unused import directive</description>
|
||||||
|
</problem>
|
||||||
|
|
||||||
|
<problem>
|
||||||
|
<file>fileInPack2.kt</file>
|
||||||
|
<line>3</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="fileInPack2.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused import directive</problem_class>
|
||||||
|
<description>Unused import directive</description>
|
||||||
|
</problem>
|
||||||
</problems>
|
</problems>
|
||||||
|
|||||||
Reference in New Issue
Block a user