KT-7021 Don't mark companion object as unused if some stuff from it is used

#KT-7021 fixed
This commit is contained in:
Evgeny Gerashchenko
2015-03-18 22:15:19 +03:00
parent efccde2c0b
commit edd51908ec
3 changed files with 34 additions and 16 deletions
@@ -107,9 +107,6 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() {
if (declaration is JetParameter && (declaration.getParent()?.getParent() !is JetClass || !declaration.hasValOrVarNode())) return
if (declaration is JetNamedFunction && isConventionalName(declaration)) return
// TODO companion objects are temporarily disabled
if (isCompanionObject) return
// More expensive, resolve-based checks
if (isEntryPoint(declaration)) return
// properties can be referred by component1/component2, which is too expensive to search, don't mark them as unused
@@ -165,24 +162,26 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() {
val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(declaration.getProject())
val useScope = declaration.getUseScope()
if (useScope is GlobalSearchScope) {
var zeroOccurrences = true
if (!(declaration is JetObjectDeclaration && declaration.isCompanion())) {
if (useScope is GlobalSearchScope) {
var zeroOccurrences = true
for (name in listOf(declaration.getName()) + declaration.getAccessorNames() + declaration.getClassNameForCompanionObject().singletonOrEmptyList()) {
when (psiSearchHelper.isCheapEnoughToSearch(name, useScope, null, null)) {
ZERO_OCCURRENCES -> {} // go on, check other names
FEW_OCCURRENCES -> zeroOccurrences = false
TOO_MANY_OCCURRENCES -> return true // searching usages is too expensive; behave like it is used
for (name in listOf(declaration.getName()) + declaration.getAccessorNames() + declaration.getClassNameForCompanionObject().singletonOrEmptyList()) {
when (psiSearchHelper.isCheapEnoughToSearch(name, useScope, null, null)) {
ZERO_OCCURRENCES -> {} // go on, check other names
FEW_OCCURRENCES -> zeroOccurrences = false
TOO_MANY_OCCURRENCES -> return true // searching usages is too expensive; behave like it is used
}
}
}
if (zeroOccurrences) {
return false
if (zeroOccurrences) {
return false
}
}
}
val searchHelper: UsagesSearchHelper<out JetNamedDeclaration> = when (declaration) {
is JetClass -> ClassUsagesSearchHelper(constructorUsages = true, nonConstructorUsages = true, skipImports = true)
is JetClassOrObject -> ClassUsagesSearchHelper(constructorUsages = true, nonConstructorUsages = true, skipImports = true)
is JetNamedFunction -> FunctionUsagesSearchHelper(skipImports = true)
is JetProperty, is JetParameter -> PropertyUsagesSearchHelper(skipImports = true)
else -> DefaultSearchHelper<JetNamedDeclaration>()
@@ -0,0 +1,21 @@
class A {
init {
foo()
v + v
v[v] // using companion object function by convention
}
companion object {
fun foo() {
}
val v = 42
fun Int.get(a: Int) = this + a
}
}
fun main(args: Array<String>) {
A()
}
@@ -32,7 +32,6 @@
<description>Object 'A' is never used</description>
</problem>
<!--
<problem>
<file>defaultObjectUnused.kt</file>
<line>2</line>
@@ -50,5 +49,4 @@
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused Symbol</problem_class>
<description>Object 'Named' is never used</description>
</problem>
-->
</problems>