Optimize Imports: improve tooltip information

#KT-21374 Fixed
This commit is contained in:
Dmitry Gridin
2019-06-30 14:46:09 +07:00
parent 074829bcea
commit 9316f45a5c
14 changed files with 55 additions and 8 deletions
@@ -46,16 +46,30 @@ import org.jetbrains.kotlin.resolve.scopes.utils.*
class KotlinImportOptimizer : ImportOptimizer {
override fun supports(file: PsiFile?) = file is KtFile
override fun processFile(file: PsiFile?): Runnable {
val ktFile = (file as? KtFile) ?: return Runnable { /* empty runnable */ }
val preparedImports = prepareImports(ktFile) ?: return Runnable { /* empty runnable */ }
override fun processFile(file: PsiFile?): ImportOptimizer.CollectingInfoRunnable {
val ktFile = (file as? KtFile) ?: return DO_NOTHING
val (add, remove, imports) = prepareImports(ktFile) ?: return DO_NOTHING
return Runnable {
replaceImports(ktFile, preparedImports)
return object : ImportOptimizer.CollectingInfoRunnable {
override fun getUserNotificationInfo(): String = if (remove == 0) "Rearranged imports"
else buildString {
append("Removed ")
append(remove)
append(" import")
if (remove > 1) append("s")
if (add > 0) {
append(", added ")
append(add)
append(" import")
if (add > 1) append("s")
}
}
override fun run() = replaceImports(ktFile, imports)
}
}
private fun prepareImports(file: KtFile): List<ImportPath>? {
private fun prepareImports(file: KtFile): OptimizeInformation? {
ApplicationManager.getApplication().assertReadAccessAllowed()
val moduleInfo = file.getNullableModuleInfo()
@@ -68,9 +82,17 @@ class KotlinImportOptimizer : ImportOptimizer {
val descriptorsToImport = collectDescriptorsToImport(file)
return prepareOptimizedImports(file, descriptorsToImport)
val imports = prepareOptimizedImports(file, descriptorsToImport) ?: return null
val intersect = imports.intersect(oldImports.map { it.importPath })
return OptimizeInformation(
add = imports.size - intersect.size,
remove = oldImports.size - intersect.size,
imports = imports
)
}
private data class OptimizeInformation(val add: Int, val remove: Int, val imports: List<ImportPath>)
private class CollectUsedDescriptorsVisitor(file: KtFile) : KtVisitorVoid() {
private val currentPackageName = file.packageFqName
private val aliases: Map<FqName, List<Name>> = file.importDirectives
@@ -220,5 +242,11 @@ class KotlinImportOptimizer : ImportOptimizer {
return bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, element as? KtReferenceExpression]?.let { listOf(it) }
?: resolveToDescriptors(bindingContext)
}
private val DO_NOTHING = object : ImportOptimizer.CollectingInfoRunnable {
override fun run() = Unit
override fun getUserNotificationInfo() = "Unused imports not found"
}
}
}
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Unused imports not found"
import test1.MyClass
import test1.get
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Unused imports not found"
import test1.MyClass
import test1.get
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 5 imports, added 2 imports"
package test
import dependency.*
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 5 imports, added 2 imports"
package test
import dependency.A
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 4 imports, added 1 import"
import duration.*
import duration.hours as hour
import duration.minutes as minute
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 4 imports, added 1 import"
import duration.minutes
import duration.hours as hour
import duration.seconds as second
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 1 import"
package ppp
import ppp.*
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 1 import"
package ppp
open class C
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Rearranged imports"
import pack1.a
import pack1.a as a1
import kotlin.collections.List
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Rearranged imports"
import pack1.a
import kotlin.collections.List
import kotlin.run
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 1 import"
import pack1.a
import pack1.a as a1
import kotlin.run as run1
@@ -1,3 +1,4 @@
// WITH_MESSAGE: "Removed 1 import"
import pack1.a
import pack1.a as a1
import kotlin.run as run1
@@ -6,16 +6,23 @@
package org.jetbrains.kotlin.idea.imports
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.AbstractImportsTest
import org.jetbrains.kotlin.idea.test.KotlinStdJSProjectDescriptor
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.InTextDirectivesUtils
abstract class AbstractOptimizeImportsTest : AbstractImportsTest() {
override fun doTest(file: KtFile): String {
OptimizedImportsBuilder.testLog = StringBuilder()
try {
KotlinImportOptimizer().processFile(file).run()
val optimizer = KotlinImportOptimizer().processFile(file)
optimizer.run()
val message = InTextDirectivesUtils.findStringWithPrefixes(file.text, "// WITH_MESSAGE: ")
if (message != null) {
TestCase.assertEquals(message, optimizer.userNotificationInfo)
}
return OptimizedImportsBuilder.testLog.toString()
} finally {
OptimizedImportsBuilder.testLog = null