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 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