Refactoring: make "unnecessary variable" inspection applicability-based
This commit is contained in:
@@ -16,12 +16,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.inspections
|
package org.jetbrains.kotlin.idea.inspections
|
||||||
|
|
||||||
import com.intellij.codeInspection.LocalQuickFix
|
import com.intellij.codeInspection.*
|
||||||
import com.intellij.codeInspection.ProblemDescriptor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.codeInspection.ProblemHighlightType
|
|
||||||
import com.intellij.codeInspection.ProblemsHolder
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiElementVisitor
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.search.LocalSearchScope
|
import com.intellij.psi.search.LocalSearchScope
|
||||||
import com.intellij.psi.search.searches.ReferencesSearch
|
import com.intellij.psi.search.searches.ReferencesSearch
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
@@ -35,29 +33,37 @@ import org.jetbrains.kotlin.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
|
import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
|
||||||
class UnnecessaryVariableInspection : AbstractKotlinInspection() {
|
class UnnecessaryVariableInspection : AbstractApplicabilityBasedInspection<KtProperty>() {
|
||||||
|
|
||||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): KtVisitorVoid =
|
||||||
object : KtVisitorVoid() {
|
object : KtVisitorVoid() {
|
||||||
override fun visitProperty(property: KtProperty) {
|
override fun visitProperty(property: KtProperty) {
|
||||||
super.visitProperty(property)
|
super.visitProperty(property)
|
||||||
|
visitTargetElement(property, holder, isOnTheFly)
|
||||||
val nameIdentifier = property.nameIdentifier ?: return
|
|
||||||
val status = statusFor(property) ?: return
|
|
||||||
holder.registerProblem(
|
|
||||||
nameIdentifier,
|
|
||||||
when (status) {
|
|
||||||
Status.RETURN_ONLY ->
|
|
||||||
"Variable used only in following return and can be inlined"
|
|
||||||
Status.EXACT_COPY ->
|
|
||||||
"Variable is an exact copy of another variable and can be inlined"
|
|
||||||
},
|
|
||||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
|
||||||
InlineVariableFix()
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isApplicable(element: KtProperty) = statusFor(element) != null
|
||||||
|
|
||||||
|
override fun inspectionTarget(element: KtProperty) = element.nameIdentifier ?: element
|
||||||
|
|
||||||
|
override fun inspectionText(element: KtProperty) = when (statusFor(element)) {
|
||||||
|
Status.RETURN_ONLY ->
|
||||||
|
"Variable used only in following return and can be inlined"
|
||||||
|
Status.EXACT_COPY ->
|
||||||
|
"Variable is an exact copy of another variable and can be inlined"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
|
||||||
|
override val defaultFixText = "Inline variable"
|
||||||
|
|
||||||
|
override val startFixInWriteAction = false
|
||||||
|
|
||||||
|
override fun applyTo(element: PsiElement, project: Project, editor: Editor?) {
|
||||||
|
val property = element.getParentOfType<KtProperty>(strict = false) ?: return
|
||||||
|
KotlinInlineValHandler().inlineElement(project, editor, property)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private enum class Status {
|
private enum class Status {
|
||||||
RETURN_ONLY,
|
RETURN_ONLY,
|
||||||
@@ -108,21 +114,5 @@ class UnnecessaryVariableInspection : AbstractKotlinInspection() {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isActiveFor(property: KtProperty) = statusFor(property) != null
|
|
||||||
}
|
|
||||||
|
|
||||||
class InlineVariableFix : LocalQuickFix {
|
|
||||||
|
|
||||||
override fun getName() = "Inline variable"
|
|
||||||
|
|
||||||
override fun getFamilyName() = name
|
|
||||||
|
|
||||||
override fun startInWriteAction() = false
|
|
||||||
|
|
||||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
|
||||||
val property = descriptor.psiElement.getParentOfType<KtProperty>(strict = true) ?: return
|
|
||||||
KotlinInlineValHandler().inlineElement(project, property.findExistingEditor(), property)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.idea.intentions.branchedTransformations.intentions.I
|
|||||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isTrivialStatementBody
|
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isTrivialStatementBody
|
||||||
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
|
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
|
||||||
import org.jetbrains.kotlin.idea.quickfix.RemoveUselessCastFix
|
import org.jetbrains.kotlin.idea.quickfix.RemoveUselessCastFix
|
||||||
import org.jetbrains.kotlin.idea.refactoring.inline.KotlinInlineValHandler
|
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -80,7 +79,7 @@ object J2KPostProcessingRegistrar {
|
|||||||
_processings.add(RemoveRedundantCastToNullableProcessing())
|
_processings.add(RemoveRedundantCastToNullableProcessing())
|
||||||
registerInspectionBasedProcessing(ReplacePutWithAssignmentInspection())
|
registerInspectionBasedProcessing(ReplacePutWithAssignmentInspection())
|
||||||
_processings.add(UseExpressionBodyProcessing())
|
_processings.add(UseExpressionBodyProcessing())
|
||||||
_processings.add(UnnecessaryVariableProcessing())
|
registerInspectionBasedProcessing(UnnecessaryVariableInspection())
|
||||||
|
|
||||||
registerIntentionBasedProcessing(FoldInitializerAndIfToElvisIntention())
|
registerIntentionBasedProcessing(FoldInitializerAndIfToElvisIntention())
|
||||||
|
|
||||||
@@ -317,21 +316,6 @@ object J2KPostProcessingRegistrar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UnnecessaryVariableProcessing : J2kPostProcessing {
|
|
||||||
// Refactoring
|
|
||||||
override val writeActionNeeded = false
|
|
||||||
|
|
||||||
override fun createAction(element: KtElement, diagnostics: Diagnostics): (() -> Unit)? {
|
|
||||||
if (element !is KtProperty) return null
|
|
||||||
|
|
||||||
if (!UnnecessaryVariableInspection.isActiveFor(element)) return null
|
|
||||||
|
|
||||||
return {
|
|
||||||
KotlinInlineValHandler(withPrompt = false).inlineElement(element.project, element.findExistingEditor(), element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RemoveRedundantCastToNullableProcessing : J2kPostProcessing {
|
private class RemoveRedundantCastToNullableProcessing : J2kPostProcessing {
|
||||||
override val writeActionNeeded = true
|
override val writeActionNeeded = true
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user