From 0488229a61414c6bbe337bcfc0716ea731dea1c3 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Mon, 25 May 2015 12:27:13 +0300 Subject: [PATCH] KT-7693 Unused constructor parameter is not detected if class is constructed with named argument #KT-7693 fixed --- .../org/jetbrains/kotlin/psi/JetParameter.java | 14 ++++++++++++++ .../kotlin/idea/findUsages/UsageTypeUtils.kt | 5 ++++- .../idea/findUsages/JetUsageTypeProvider.kt | 2 ++ .../idea/inspections/UnusedSymbolInspection.kt | 2 +- .../kotlinConstructorParameterUsages.0.kt | 8 ++++++++ ...otlinConstructorParameterUsages.results.txt | 2 ++ .../kotlinFunctionParameterUsages.0.kt | 4 ++++ .../kotlinFunctionParameterUsages.results.txt | 1 + .../parameter/inspectionData/expected.xml | 18 ++++++++++++++++++ .../paramPropertyUsedOnlyAsNamedArgument.kt | 5 +++++ 10 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 idea/testData/inspections/unusedSymbol/parameter/paramPropertyUsedOnlyAsNamedArgument.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java index 9d30960bd78..90a53502e19 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/JetParameter.java @@ -20,6 +20,7 @@ import com.intellij.lang.ASTNode; import com.intellij.navigation.ItemPresentation; import com.intellij.navigation.ItemPresentationProviders; import com.intellij.psi.PsiElement; +import com.intellij.psi.search.SearchScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.lexer.JetTokens; @@ -174,4 +175,17 @@ public class JetParameter extends JetNamedDeclarationStub i public List getTypeParameters() { return Collections.emptyList(); } + + @NotNull + @Override + public SearchScope getUseScope() { + PsiElement parent = getParent(); + if (parent != null) { + PsiElement grandparent = parent.getParent(); + if (grandparent instanceof JetNamedFunction) { + return grandparent.getUseScope(); + } + } + return super.getUseScope(); + } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt index fd396c45ab2..7121d0dc885 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/findUsages/UsageTypeUtils.kt @@ -133,6 +133,8 @@ public object UsageTypeUtils { return DELEGATE } + if (refExpr.getParent() is JetValueArgumentName) return NAMED_ARGUMENT + val dotQualifiedExpression = refExpr.getNonStrictParentOfType() if (dotQualifiedExpression != null) { @@ -258,5 +260,6 @@ enum class UsageTypeEnum { TYPE_PARAMETER, CLASS_CAST_TO, ANNOTATION, - CLASS_NEW_OPERATOR + CLASS_NEW_OPERATOR, + NAMED_ARGUMENT } diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/JetUsageTypeProvider.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/JetUsageTypeProvider.kt index ac2b9560d6d..30e8f21b23a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/JetUsageTypeProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/JetUsageTypeProvider.kt @@ -71,6 +71,7 @@ public object JetUsageTypeProvider : UsageTypeProviderEx { CLASS_CAST_TO -> UsageType.CLASS_CAST_TO ANNOTATION -> UsageType.ANNOTATION CLASS_NEW_OPERATOR -> UsageType.CLASS_NEW_OPERATOR + NAMED_ARGUMENT -> JetUsageTypes.NAMED_ARGUMENT } } } @@ -107,4 +108,5 @@ object JetUsageTypes { // common usage types val CALLABLE_REFERENCE = UsageType(JetBundle.message("usageType.callable.reference")) + val NAMED_ARGUMENT = UsageType("Named argument") } diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt index 8f8a1fd26aa..f784da55457 100644 --- a/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt +++ b/idea/src/org/jetbrains/kotlin/idea/inspections/UnusedSymbolInspection.kt @@ -199,7 +199,7 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() { return !query.forEach(Processor { assert(it != null, { "Found reference is null, was looking for: " + declaration.getElementTextWithContext() + " findAll(): " + query.findAll().map { it?.getElement()?.let{ it.getElementTextWithContext() } } }) - declaration.isAncestor(it.getElement()) + declaration.isAncestor(it.getElement()) || it.getElement().getParent() is JetValueArgumentName }) } diff --git a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.0.kt b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.0.kt index da4104add54..10a3916d8c7 100644 --- a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.0.kt +++ b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.0.kt @@ -6,4 +6,12 @@ open class A(foo: T) { } val t: T = foo + + fun usage() { + return A(foo = ":)") + } } + +fun usage() { + A(foo = ":)") +} \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.results.txt b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.results.txt index 70b5e9f71d9..b7a71509e7f 100644 --- a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.results.txt +++ b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinConstructorParameterUsages.results.txt @@ -1,2 +1,4 @@ +Named argument (11: 18) return A(foo = ":)") +Named argument (16: 7) A(foo = ":)") Value read (5: 17) println(foo) Value read (8: 16) val t: T = foo diff --git a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.0.kt b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.0.kt index d1e552c233f..cf8fe9d8b2e 100644 --- a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.0.kt +++ b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.0.kt @@ -4,3 +4,7 @@ fun foo(t: T): T { println(t) return t } + +fun usage() { + foo(t = ":)") +} \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.results.txt b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.results.txt index 2865abdc165..3abb86a24ab 100644 --- a/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.results.txt +++ b/idea/testData/findUsages/kotlin/findParameterUsages/kotlinFunctionParameterUsages.results.txt @@ -1,2 +1,3 @@ +Named argument (9: 9) foo(t = ":)") Value read (4: 13) println(t) Value read (5: 12) return t \ No newline at end of file diff --git a/idea/testData/inspections/unusedSymbol/parameter/inspectionData/expected.xml b/idea/testData/inspections/unusedSymbol/parameter/inspectionData/expected.xml index e7dcf602308..44ccb36db13 100644 --- a/idea/testData/inspections/unusedSymbol/parameter/inspectionData/expected.xml +++ b/idea/testData/inspections/unusedSymbol/parameter/inspectionData/expected.xml @@ -7,4 +7,22 @@ Unused Symbol Property 'param' is never used + + + paramPropertyUsedOnlyAsNamedArgument.kt + 1 + light_idea_test_case + + Unused Symbol + Property 'param1' is never used + + + + paramPropertyUsedOnlyAsNamedArgument.kt + 1 + light_idea_test_case + + Unused Symbol + Property 'param2' is never used + diff --git a/idea/testData/inspections/unusedSymbol/parameter/paramPropertyUsedOnlyAsNamedArgument.kt b/idea/testData/inspections/unusedSymbol/parameter/paramPropertyUsedOnlyAsNamedArgument.kt new file mode 100644 index 00000000000..85dd225f685 --- /dev/null +++ b/idea/testData/inspections/unusedSymbol/parameter/paramPropertyUsedOnlyAsNamedArgument.kt @@ -0,0 +1,5 @@ +class C(val param1: Int, val param2: Int) + +fun main(args: Array) { + C(1, param2 = 1) +} \ No newline at end of file