diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties index 6d54b77a516..a648fa059b5 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties @@ -119,6 +119,7 @@ goto.super.class.chooser.title=Choose super class or interface unused.class=Class ''{0}'' is never used unused.function=Function ''{0}'' is never used +unused.property=Property ''{0}'' is never used livetemplate.description.main=main() function livetemplate.description.soutp=Prints function parameter names and values to System.out diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt index c0ee7b4b167..4baba1006ed 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt @@ -44,6 +44,8 @@ import com.intellij.psi.search.PsiSearchHelper.SearchCostResult.* import org.jetbrains.kotlin.idea.search.usagesSearch.getOperationSymbolsToSearch import org.jetbrains.kotlin.idea.search.usagesSearch.INVOKE_OPERATION_NAME import org.jetbrains.kotlin.psi.JetEnumEntry +import org.jetbrains.kotlin.psi.JetProperty +import org.jetbrains.kotlin.idea.search.usagesSearch.PropertyUsagesSearchHelper public class UnusedSymbolInspection : AbstractKotlinInspection() { private val javaInspection = UnusedDeclarationInspection() @@ -82,6 +84,21 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() { ProblemHighlightType.LIKE_UNUSED_SYMBOL ) // TODO add quick fix to delete it } + + override fun visitProperty(property: JetProperty) { + if (property.getName() == null) return + + if (property.isLocal()) return + + if (property.hasModifier(JetTokens.OVERRIDE_KEYWORD)) return + if (hasNonTrivialUsages(property)) return + + holder.registerProblem( + property.getNameIdentifier(), + JetBundle.message("unused.property", property.getName()), + ProblemHighlightType.LIKE_UNUSED_SYMBOL + ) // TODO add quick fix to delete it + } } } @@ -132,6 +149,7 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() { val searchHelper: UsagesSearchHelper = when (declaration) { is JetClass -> ClassUsagesSearchHelper(constructorUsages = true, nonConstructorUsages = true, skipImports = true) is JetNamedFunction -> FunctionUsagesSearchHelper(skipImports = true) + is JetProperty -> PropertyUsagesSearchHelper(skipImports = true) else -> return false } diff --git a/idea/testData/inspections/unusedSymbol/class/usedOnlyInside.kt b/idea/testData/inspections/unusedSymbol/class/usedOnlyInside.kt index 78de9e90a7f..c40f0cfe089 100644 --- a/idea/testData/inspections/unusedSymbol/class/usedOnlyInside.kt +++ b/idea/testData/inspections/unusedSymbol/class/usedOnlyInside.kt @@ -1,3 +1,5 @@ class A { - val x: A? = null + { + val x: A? = null + } } \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/property/classMemberInheritedUsed.kt b/idea/testData/inspections/unusedSymbol/property/classMemberInheritedUsed.kt new file mode 100644 index 00000000000..8ef69feef15 --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/classMemberInheritedUsed.kt @@ -0,0 +1,9 @@ +open class Klass { + val used = ":)" +} + +class Subklass: Klass() + +fun main(args: Array) { + Subklass().used +} \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/property/classMemberOverriddenUsed.kt b/idea/testData/inspections/unusedSymbol/property/classMemberOverriddenUsed.kt new file mode 100644 index 00000000000..2fdc17fb2fc --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/classMemberOverriddenUsed.kt @@ -0,0 +1,11 @@ +open class Klass { + open val used = ":)" +} + +class Subklass: Klass() { + override fun used = ":|" +} + +fun main(args: Array) { + Subklass().used +} \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/property/classMemberOverride.kt b/idea/testData/inspections/unusedSymbol/property/classMemberOverride.kt new file mode 100644 index 00000000000..8d98c464f3e --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/classMemberOverride.kt @@ -0,0 +1,12 @@ +trait Trait { + val member: String +} + +class Klass: Trait { + override val member: String = ":)" +} + +fun main(args: Array) { + val t: Trait = Klass() + println(t.member) +} diff --git a/idea/testData/inspections/unusedSymbol/property/classMemberUnused.kt b/idea/testData/inspections/unusedSymbol/property/classMemberUnused.kt new file mode 100644 index 00000000000..82900da0b03 --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/classMemberUnused.kt @@ -0,0 +1,7 @@ +class Klass { + val unused = ":(" +} + +fun main(args: Array) { + Klass() +} \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/property/classMemberUsed.kt b/idea/testData/inspections/unusedSymbol/property/classMemberUsed.kt new file mode 100644 index 00000000000..29d30290506 --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/classMemberUsed.kt @@ -0,0 +1,7 @@ +class Klass { + fun used = ":)" +} + +fun main(args: Array) { + Klass().used +} \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/property/inspectionData/expected.xml b/idea/testData/inspections/unusedSymbol/property/inspectionData/expected.xml new file mode 100644 index 00000000000..8d6867e69aa --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/inspectionData/expected.xml @@ -0,0 +1,28 @@ + + + topLevelUnused.kt + 1 + light_idea_test_case + + Unused Symbol + Property 'unused' is never used + + + + topLevelOnlyInImport.kt + 5 + light_idea_test_case + + Unused Symbol + Property 'onlyInImport' is never used + + + + classMemberUnused.kt + 2 + light_idea_test_case + + Unused Symbol + Property 'unused' is never used + + diff --git a/idea/testData/inspections/unusedSymbol/property/inspectionData/inspections.test b/idea/testData/inspections/unusedSymbol/property/inspectionData/inspections.test new file mode 100644 index 00000000000..02aea1c357e --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/inspectionData/inspections.test @@ -0,0 +1 @@ +// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection diff --git a/idea/testData/inspections/unusedSymbol/property/local.kt b/idea/testData/inspections/unusedSymbol/property/local.kt new file mode 100644 index 00000000000..271608bebe0 --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/local.kt @@ -0,0 +1,3 @@ +fun main(args: Array) { + val local = ":(" // it is unused, but marked by front-end instead of inspection +} \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/property/topLevelOnlyInImport.kt b/idea/testData/inspections/unusedSymbol/property/topLevelOnlyInImport.kt new file mode 100644 index 00000000000..1befb0065d8 --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/topLevelOnlyInImport.kt @@ -0,0 +1,5 @@ +package foo + +import foo.onlyInImport + +val onlyInImport = ":(" diff --git a/idea/testData/inspections/unusedSymbol/property/topLevelUnused.kt b/idea/testData/inspections/unusedSymbol/property/topLevelUnused.kt new file mode 100644 index 00000000000..d4a4e7a73bd --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/topLevelUnused.kt @@ -0,0 +1 @@ +val unused = ":(" \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/property/topLevelUsed.kt b/idea/testData/inspections/unusedSymbol/property/topLevelUsed.kt new file mode 100644 index 00000000000..24f712b01cc --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/property/topLevelUsed.kt @@ -0,0 +1,5 @@ +fun used = ":)" + +fun main(args: Array) { + println(used) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/JetInspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/JetInspectionTestGenerated.java index dbafe700f5f..c07748ac99c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/JetInspectionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/JetInspectionTestGenerated.java @@ -89,5 +89,11 @@ public class JetInspectionTestGenerated extends AbstractJetInspectionTest { String fileName = JetTestUtils.navigationMetadata("idea/testData/inspections/unusedSymbol/function/inspectionData/inspections.test"); doTest(fileName); } + + @TestMetadata("unusedSymbol/property/inspectionData/inspections.test") + public void testUnusedSymbol_property_inspectionData_Inspections_test() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/inspections/unusedSymbol/property/inspectionData/inspections.test"); + doTest(fileName); + } } }