Skip to content

Commit

Permalink
Unused import: do not report for 'invoke' function import that is use…
Browse files Browse the repository at this point in the history
…d from same file

#KT-24281 Fixed
  • Loading branch information
t-kameyama authored and vladimirdolzhenko committed Apr 15, 2020
1 parent 8aa1205 commit 8c4fdd1
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ import org.jetbrains.kotlin.idea.core.targetDescriptors
import org.jetbrains.kotlin.idea.imports.KotlinImportOptimizer
import org.jetbrains.kotlin.idea.imports.OptimizedImportsBuilder
import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.references.KtInvokeFunctionReference
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtCodeFragment
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.siblings
import org.jetbrains.kotlin.resolve.ImportPath

Expand Down Expand Up @@ -86,6 +87,11 @@ class KotlinUnusedImportInspection : AbstractKotlinInspection() {
}
}

val invokeFunctionCallFqNames = optimizerData.references.mapNotNull {
val reference = (it.element as? KtCallExpression)?.mainReference as? KtInvokeFunctionReference ?: return@mapNotNull null
(reference.resolve() as? KtNamedFunction)?.descriptor?.importableFqName
}

val importPaths = HashSet<ImportPath>(directives.size)
val unusedImports = ArrayList<KtImportDirective>()

Expand All @@ -97,6 +103,7 @@ class KotlinUnusedImportInspection : AbstractKotlinInspection() {
!importPaths.add(importPath) -> false
importPath.isAllUnder -> importPath.fqName in parentFqNames
importPath.fqName in fqNames -> importPath.importedName?.let { it in fqNames.getValue(importPath.fqName) } ?: false
importPath.fqName in invokeFunctionCallFqNames -> true
// case for type alias
else -> directive.targetDescriptors(resolutionFacade).firstOrNull()?.let { it.importableFqName in fqNames } ?: false
}
Expand Down
18 changes: 18 additions & 0 deletions idea/testData/quickfix/optimizeImports/invoke.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// "Optimize imports" "false"
// WITH_RUNTIME
// ACTION: Introduce import alias
package ppp

import ppp.invoke<caret>

object Bar
object Foo {
val bar = Bar
}

fun Foo.bar() = 1
operator fun Bar.invoke() = 2

fun main() {
println(Foo.bar())
}
17 changes: 17 additions & 0 deletions idea/testData/quickfix/optimizeImports/invoke2.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// "Optimize imports" "true"
// WITH_RUNTIME
package ppp

import ppp.invoke<caret>

object Bar
object Foo {
// val bar = Bar
}

fun Foo.bar() = 1
operator fun Bar.invoke() = 2

fun main() {
println(Foo.bar())
}
15 changes: 15 additions & 0 deletions idea/testData/quickfix/optimizeImports/invoke2.kt.after
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// "Optimize imports" "true"
// WITH_RUNTIME
package ppp

object Bar
object Foo {
// val bar = Bar
}

fun Foo.bar() = 1
operator fun Bar.invoke() = 2

fun main() {
println(Foo.bar())
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 8c4fdd1

Please sign in to comment.