Added Incomplete destructuring inspection
#KT-21223 Fixed
This commit is contained in:
committed by
Vladimir Dolzhenko
parent
e6bca819d4
commit
5b1d019bb0
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection reports incomplete destructuring declaration.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1926,6 +1926,8 @@ open.moved.members.in.editor=Open moved members in editor
|
||||
to.fully.qualified.name=To (fully qualified name):
|
||||
toggle.library.to.source.dependency.support=Toggle library to source dependency support
|
||||
enable.components.for.library.to.source.analysis.in.kotlin=Enable components for analyzing libraries depending on project source files in Kotlin
|
||||
incomplete.destructuring.declaration.text=Incomplete destructuring declaration
|
||||
incomplete.destructuring.fix.family.name=Add missing variables to destructuring declaration
|
||||
|
||||
action.Kotlin.StopScratch.text=Stop Scratch Execution
|
||||
action.Kotlin.StopScratch.description=Stop scratch execution
|
||||
@@ -1984,6 +1986,7 @@ action.KotlinConsoleREPL.text=Kotlin REPL
|
||||
action.LibraryToSourceDependencySupportToggleAction.text=Toggle library to source dependency support
|
||||
|
||||
inspection.unused.unary.operator.display.name=Unused unary operator
|
||||
inspection.incomplete.destructuring.declaration.display.name=Incomplete destructuring declaration
|
||||
inspection.replace.guard.clause.with.function.call.display.name=Replace guard clause with kotlin's function call
|
||||
inspection.lateinit.var.overrides.lateinit.var.display.name=lateinit var property overrides lateinit var property
|
||||
inspection.kotlin.equals.between.inconvertible.types.display.name='equals()' between objects of inconvertible types
|
||||
|
||||
@@ -2493,6 +2493,14 @@
|
||||
language="kotlin"
|
||||
key="inspection.unused.unary.operator.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.IncompleteDestructuringInspection"
|
||||
groupPath="Kotlin"
|
||||
groupName="Probable bugs"
|
||||
enabledByDefault="true"
|
||||
level="WARNING"
|
||||
language="kotlin"
|
||||
key="inspection.incomplete.destructuring.declaration.display.name" bundle="messages.KotlinBundle"/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.RedundantInnerClassModifierInspection"
|
||||
groupPath="Kotlin"
|
||||
groupName="Redundant constructs"
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.inspections
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
import com.intellij.codeInspection.ProblemDescriptor
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.createDestructuringDeclarationByPattern
|
||||
import org.jetbrains.kotlin.psi.destructuringDeclarationVisitor
|
||||
|
||||
class IncompleteDestructuringInspection : AbstractKotlinInspection() {
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||
return destructuringDeclarationVisitor(fun(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
|
||||
|
||||
if (destructuringDeclaration.entries.size < primaryParameterNames.size) {
|
||||
val rPar = destructuringDeclaration.rPar ?: return
|
||||
holder.registerProblem(
|
||||
rPar,
|
||||
KotlinBundle.message("incomplete.destructuring.declaration.text"),
|
||||
IncompleteDestructuringQuickfix(primaryParameterNames)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class IncompleteDestructuringQuickfix(private val primaryParameterNames: List<String>) : LocalQuickFix {
|
||||
override fun getFamilyName() = KotlinBundle.message("incomplete.destructuring.fix.family.name")
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement
|
||||
val destructuringDeclaration = element.parent as? KtDestructuringDeclaration ?: return
|
||||
if (destructuringDeclaration.entries.size >= primaryParameterNames.size) return
|
||||
|
||||
val namesToAdd =
|
||||
primaryParameterNames.subList(destructuringDeclaration.entries.size, primaryParameterNames.size)
|
||||
val names = destructuringDeclaration.entries.mapNotNull { it.name }.toMutableList() + namesToAdd
|
||||
val joinedNames = names.joinToString()
|
||||
|
||||
val initializer = destructuringDeclaration.initializer ?: return
|
||||
val factory = KtPsiFactory(destructuringDeclaration)
|
||||
|
||||
val newDestructuringDeclaration = factory.createDestructuringDeclarationByPattern(
|
||||
if (destructuringDeclaration.isVar) "var ($0) = $1" else "val ($0) = $1",
|
||||
joinedNames, initializer
|
||||
)
|
||||
|
||||
element.parent.replace(newDestructuringDeclaration)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.inspections.IncompleteDestructuringInspection
|
||||
@@ -0,0 +1,6 @@
|
||||
data class Person(val name: String, val age: Int)
|
||||
|
||||
fun test() {
|
||||
val person = Person("", 0)
|
||||
val (name)<caret> = person
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
data class Person(val name: String, val age: Int)
|
||||
|
||||
fun test() {
|
||||
val person = Person("", 0)
|
||||
val (name, age) = person
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// PROBLEM: none
|
||||
data class Person(val name: String, val age: Int)
|
||||
|
||||
fun test() {
|
||||
val person = Person("", 0)
|
||||
val (name, age)<caret> = person
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
data class Person(val name: String, val age: Int, val location: String)
|
||||
|
||||
fun test() {
|
||||
val (_, age)<caret> = Person("", 0, "")
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
data class Person(val name: String, val age: Int, val location: String)
|
||||
|
||||
fun test() {
|
||||
val (_, age, location)<caret> = Person("", 0, "")
|
||||
}
|
||||
+28
@@ -5139,6 +5139,34 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/incompleteDestructuringInspection")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IncompleteDestructuringInspection extends AbstractLocalInspectionTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInIncompleteDestructuringInspection() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/inspectionsLocal/incompleteDestructuringInspection"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("basic.kt")
|
||||
public void testBasic() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/incompleteDestructuringInspection/basic.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("negative.kt")
|
||||
public void testNegative() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/incompleteDestructuringInspection/negative.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscore.kt")
|
||||
public void testUnderscore() throws Exception {
|
||||
runTest("idea/testData/inspectionsLocal/incompleteDestructuringInspection/underscore.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/javaCollectionsStaticMethod")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user