Refactoring: make "unnecessary variable" inspection applicability-based

This commit is contained in:
Mikhail Glukhikh
2017-12-21 11:34:25 +03:00
parent 221aac9820
commit f44fba746e
2 changed files with 28 additions and 54 deletions
@@ -16,12 +16,10 @@
package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.codeInspection.*
import com.intellij.openapi.editor.Editor
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.searches.ReferencesSearch
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.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() {
override fun visitProperty(property: KtProperty) {
super.visitProperty(property)
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()
)
visitTargetElement(property, holder, isOnTheFly)
}
}
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 {
private enum class Status {
RETURN_ONLY,
@@ -108,21 +114,5 @@ class UnnecessaryVariableInspection : AbstractKotlinInspection() {
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.quickfix.RemoveModifierFix
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.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -80,7 +79,7 @@ object J2KPostProcessingRegistrar {
_processings.add(RemoveRedundantCastToNullableProcessing())
registerInspectionBasedProcessing(ReplacePutWithAssignmentInspection())
_processings.add(UseExpressionBodyProcessing())
_processings.add(UnnecessaryVariableProcessing())
registerInspectionBasedProcessing(UnnecessaryVariableInspection())
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 {
override val writeActionNeeded = true