Skip to content

Commit 2506bb6

Browse files
cypressiousmglukhikh
authored andcommitted
Inspection checking that destructuring variable name matches the name of different component #KT-12004 Fixed
1 parent af7de9a commit 2506bb6

File tree

7 files changed

+100
-0
lines changed

7 files changed

+100
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<html>
2+
<body>
3+
This inspection reports entries of destructuring declarations that match the name of a different property of the destructured data class.
4+
</body>
5+
</html>

idea/src/META-INF/plugin.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,6 +2051,14 @@
20512051
language="kotlin"
20522052
/>
20532053

2054+
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.DestructuringWrongNameInspection"
2055+
displayName="Variable in destructuring declaration uses name of a wrong data class property"
2056+
groupName="Kotlin"
2057+
enabledByDefault="true"
2058+
level="WARNING"
2059+
language="kotlin"
2060+
/>
2061+
20542062

20552063
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
20562064

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2010-2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.idea.inspections
18+
19+
import com.intellij.codeInsight.daemon.impl.quickfix.RenameElementFix
20+
import com.intellij.codeInspection.ProblemsHolder
21+
import com.intellij.psi.PsiElementVisitor
22+
import org.jetbrains.kotlin.descriptors.ClassDescriptor
23+
import org.jetbrains.kotlin.idea.caches.resolve.analyze
24+
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
25+
import org.jetbrains.kotlin.psi.KtVisitorVoid
26+
27+
class DestructuringWrongNameInspection : AbstractKotlinInspection() {
28+
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
29+
return object : KtVisitorVoid() {
30+
override fun visitDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration) {
31+
super.visitDestructuringDeclaration(destructuringDeclaration)
32+
33+
val initializer = destructuringDeclaration.initializer ?: return
34+
val type = initializer.analyze().getType(initializer) ?: return
35+
36+
val classDescriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return
37+
38+
val primaryParameterNames = classDescriptor.constructors
39+
.firstOrNull { it.isPrimary }
40+
?.valueParameters
41+
?.map { it.name.asString() } ?: return
42+
43+
destructuringDeclaration.entries.forEachIndexed { entryIndex, entry ->
44+
val variableName = entry.name
45+
if (variableName != primaryParameterNames.getOrNull(entryIndex)) {
46+
for ((parameterIndex, parameterName) in primaryParameterNames.withIndex()) {
47+
if (parameterIndex == entryIndex) continue
48+
if (variableName == parameterName) {
49+
val fix = primaryParameterNames.getOrNull(entryIndex)?.let { RenameElementFix(entry, it) }
50+
holder.registerProblem(
51+
entry,
52+
"Variable name '$variableName' matches the name of a different component",
53+
*listOfNotNull(fix).toTypedArray())
54+
break
55+
}
56+
}
57+
}
58+
}
59+
}
60+
}
61+
}
62+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<problems>
2+
<problem>
3+
<file>test.kt</file>
4+
<line>4</line>
5+
<module>light_idea_test_case</module>
6+
<entry_point TYPE="file" FQNAME="temp:///src/test.kt"/>
7+
<problem_class severity="WARNING" attribute_key="WARNING_ATTRIBUTES">Variable in destructuring declaration uses name of a wrong data
8+
class property
9+
</problem_class>
10+
<description>Variable name 'c' matches the name of a different component</description>
11+
</problem>
12+
</problems>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.DestructuringWrongNameInspection
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
data class Foo(val a: String, val b: Int, val c: String)
2+
3+
fun bar(f: Foo) {
4+
val (a, c) = f
5+
}

idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ public void testDataClassPrivateConstructor_inspectionData_Inspections_test() th
179179
doTest(fileName);
180180
}
181181

182+
@TestMetadata("destructuringWrongName/inspectionData/inspections.test")
183+
public void testDestructuringWrongName_inspectionData_Inspections_test() throws Exception {
184+
String fileName =
185+
KotlinTestUtils.navigationMetadata("idea/testData/inspections/destructuringWrongName/inspectionData/inspections.test");
186+
doTest(fileName);
187+
}
188+
182189
@TestMetadata("dynamic/js/inspectionData/inspections.test")
183190
public void testDynamic_js_inspectionData_Inspections_test() throws Exception {
184191
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/dynamic/js/inspectionData/inspections.test");

0 commit comments

Comments
 (0)