Call method references search in UnusedSymbolInspection.hasReferences to fix secondary constructor search

Makes #KT-12500 Fixed
Makes #KT-12501 Fixed
This commit is contained in:
Mikhail Glukhikh
2016-11-25 16:12:47 +03:00
parent 784fe31053
commit 299f477a1b
12 changed files with 124 additions and 4 deletions
@@ -40,6 +40,7 @@ import com.intellij.psi.search.PsiSearchHelper
import com.intellij.psi.search.PsiSearchHelper.SearchCostResult.*
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.DefinitionsScopedSearch
import com.intellij.psi.search.searches.MethodReferencesSearch
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.refactoring.safeDelete.SafeDeleteHandler
import org.jetbrains.kotlin.asJava.LightClassUtil
@@ -243,7 +244,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
}
private fun hasReferences(declaration: KtNamedDeclaration, useScope: SearchScope): Boolean {
return !ReferencesSearch.search(declaration, useScope).forEach(fun (ref: PsiReference): Boolean {
fun checkReference(ref: PsiReference): Boolean {
if (declaration.isAncestor(ref.element)) return true // usages inside element's declaration are not counted
if (ref.element.parent is KtValueArgumentName) return true // usage of parameter in form of named argument is not counted
@@ -273,7 +275,16 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
}
return false
})
}
if (declaration is KtCallableDeclaration) {
val lightMethods = declaration.toLightMethods()
for (method in lightMethods) {
if (!MethodReferencesSearch.search(method).forEach(::checkReference)) return true
}
}
return !ReferencesSearch.search(declaration, useScope).forEach(::checkReference)
}
private fun hasOverrides(declaration: KtNamedDeclaration, useScope: SearchScope): Boolean {
@@ -347,7 +358,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
}
class SafeDeleteFix(declaration: KtDeclaration) : LocalQuickFix {
private val name =
private val name: String =
if (declaration is KtConstructor<*>) "Safe delete constructor"
else QuickFixBundle.message("safe.delete.text", declaration.name)
@@ -0,0 +1,20 @@
class CtorUsedByOtherCtor {
constructor()
constructor(p: String): this()
}
open class CtorUsedParent {
constructor()
}
class CtorUsedChild : CtorUsedParent {
constructor() : super()
}
@test.anno.EntryPoint
fun use(): Int {
val first = CtorUsedByOtherCtor("")
val second = CtorUsedChild(true)
return first.hashCode() + second.hashCode()
}
@@ -2,4 +2,9 @@ class RandomJavaClass {
void g() {
foo.UsedInJavaKt.usedInJava();
}
public void context() {
foo.Ctor c = new foo.Ctor(0);
c.justCompare();
}
}
@@ -1,4 +1,9 @@
package foo
fun usedInJava() {
}
}
class Ctor {
constructor(p: Int)
fun justCompare() {}
}
@@ -0,0 +1,6 @@
class RandomJavaClass {
public void context() {
Ctor c = new Ctor(0);
c.justCompare();
}
}
@@ -0,0 +1,11 @@
// "Safe delete constructor" "false"
// ACTION: Convert to primary constructor
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
class Ctor {
<caret>constructor(p: Int)
fun justCompare() {}
}
@@ -0,0 +1,5 @@
class RandomJavaClass extends Ctor {
RandomJavaClass() {
super(42);
}
}
@@ -0,0 +1,9 @@
// "Safe delete constructor" "false"
// ACTION: Convert to primary constructor
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
open class Ctor {
<caret>constructor(p: Int)
}
@@ -0,0 +1,11 @@
// "Safe delete constructor" "false"
// ACTION: Convert to primary constructor
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
class CtorUsedByOtherCtor {
<caret>constructor()
constructor(p: String): this()
}
@@ -0,0 +1,13 @@
// "Safe delete constructor" "false"
// ACTION: Convert to primary constructor
// ACTION: Make internal
// ACTION: Make private
// ACTION: Make protected
open class CtorUsedParent {
<caret>constructor()
}
class CtorUsedChild : CtorUsedParent {
constructor() : super()
}
@@ -1831,6 +1831,18 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
doTestWithExtraFile(fileName);
}
@TestMetadata("secondaryConstructorFromJava.before.Main.kt")
public void testSecondaryConstructorFromJava() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/removeUnused/secondaryConstructorFromJava.before.Main.kt");
doTestWithExtraFile(fileName);
}
@TestMetadata("secondaryConstructorFromJavaDelegate.before.Main.kt")
public void testSecondaryConstructorFromJavaDelegate() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/removeUnused/secondaryConstructorFromJavaDelegate.before.Main.kt");
doTestWithExtraFile(fileName);
}
@TestMetadata("usedObjectAsAliasMulti.before.Main.kt")
public void testUsedObjectAsAliasMulti() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/removeUnused/usedObjectAsAliasMulti.before.Main.kt");
@@ -7524,6 +7524,18 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("unusedDelegatedConstructor.kt")
public void testUnusedDelegatedConstructor() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/removeUnused/unusedDelegatedConstructor.kt");
doTest(fileName);
}
@TestMetadata("unusedDelegatedConstructorSuper.kt")
public void testUnusedDelegatedConstructorSuper() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/removeUnused/unusedDelegatedConstructorSuper.kt");
doTest(fileName);
}
@TestMetadata("unusedFunction.kt")
public void testUnusedFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/removeUnused/unusedFunction.kt");