diff --git a/idea/resources/inspectionDescriptions/DestructuringWrongName.html b/idea/resources/inspectionDescriptions/DestructuringWrongName.html
new file mode 100644
index 00000000000..efc282e244f
--- /dev/null
+++ b/idea/resources/inspectionDescriptions/DestructuringWrongName.html
@@ -0,0 +1,5 @@
+
+
+This inspection reports entries of destructuring declarations that match the name of a different property of the destructured data class.
+
+
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index a86729baee0..ee733fb4bef 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -2051,6 +2051,14 @@
language="kotlin"
/>
+
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/DestructuringWrongNameInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/DestructuringWrongNameInspection.kt
new file mode 100644
index 00000000000..284bcd75faa
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/inspections/DestructuringWrongNameInspection.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010-2017 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.inspections
+
+import com.intellij.codeInsight.daemon.impl.quickfix.RenameElementFix
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.psi.PsiElementVisitor
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
+import org.jetbrains.kotlin.psi.KtVisitorVoid
+
+class DestructuringWrongNameInspection : AbstractKotlinInspection() {
+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+ return object : KtVisitorVoid() {
+ override fun visitDestructuringDeclaration(destructuringDeclaration: KtDestructuringDeclaration) {
+ super.visitDestructuringDeclaration(destructuringDeclaration)
+
+ val initializer = destructuringDeclaration.initializer ?: return
+ val type = initializer.analyze().getType(initializer) ?: return
+
+ val classDescriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return
+
+ val primaryParameterNames = classDescriptor.constructors
+ .firstOrNull { it.isPrimary }
+ ?.valueParameters
+ ?.map { it.name.asString() } ?: return
+
+ destructuringDeclaration.entries.forEachIndexed { entryIndex, entry ->
+ val variableName = entry.name
+ if (variableName != primaryParameterNames.getOrNull(entryIndex)) {
+ for ((parameterIndex, parameterName) in primaryParameterNames.withIndex()) {
+ if (parameterIndex == entryIndex) continue
+ if (variableName == parameterName) {
+ val fix = primaryParameterNames.getOrNull(entryIndex)?.let { RenameElementFix(entry, it) }
+ holder.registerProblem(
+ entry,
+ "Variable name '$variableName' matches the name of a different component",
+ *listOfNotNull(fix).toTypedArray())
+ break
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/destructuringWrongName/inspectionData/expected.xml b/idea/testData/inspections/destructuringWrongName/inspectionData/expected.xml
new file mode 100644
index 00000000000..292616a4c85
--- /dev/null
+++ b/idea/testData/inspections/destructuringWrongName/inspectionData/expected.xml
@@ -0,0 +1,12 @@
+
+
+ test.kt
+ 4
+ light_idea_test_case
+
+ Variable in destructuring declaration uses name of a wrong data
+ class property
+
+ Variable name 'c' matches the name of a different component
+
+
\ No newline at end of file
diff --git a/idea/testData/inspections/destructuringWrongName/inspectionData/inspections.test b/idea/testData/inspections/destructuringWrongName/inspectionData/inspections.test
new file mode 100644
index 00000000000..4cf05cb7c51
--- /dev/null
+++ b/idea/testData/inspections/destructuringWrongName/inspectionData/inspections.test
@@ -0,0 +1 @@
+// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.DestructuringWrongNameInspection
\ No newline at end of file
diff --git a/idea/testData/inspections/destructuringWrongName/test.kt b/idea/testData/inspections/destructuringWrongName/test.kt
new file mode 100644
index 00000000000..09920340200
--- /dev/null
+++ b/idea/testData/inspections/destructuringWrongName/test.kt
@@ -0,0 +1,5 @@
+data class Foo(val a: String, val b: Int, val c: String)
+
+fun bar(f: Foo) {
+ val (a, c) = f
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
index 3384700d62d..600319a993f 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
@@ -179,6 +179,13 @@ public class InspectionTestGenerated extends AbstractInspectionTest {
doTest(fileName);
}
+ @TestMetadata("destructuringWrongName/inspectionData/inspections.test")
+ public void testDestructuringWrongName_inspectionData_Inspections_test() throws Exception {
+ String fileName =
+ KotlinTestUtils.navigationMetadata("idea/testData/inspections/destructuringWrongName/inspectionData/inspections.test");
+ doTest(fileName);
+ }
+
@TestMetadata("dynamic/js/inspectionData/inspections.test")
public void testDynamic_js_inspectionData_Inspections_test() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/dynamic/js/inspectionData/inspections.test");