Inspection "MoveVariableDeclarationIntoWhen" should inline variable declaration
This commit is contained in:
+36
-8
@@ -23,33 +23,61 @@ class MoveVariableDeclarationIntoWhenInspection : AbstractKotlinInspection(), Cl
|
|||||||
whenExpressionVisitor(fun(expression: KtWhenExpression) {
|
whenExpressionVisitor(fun(expression: KtWhenExpression) {
|
||||||
val subjectExpression = expression.subjectExpression ?: return
|
val subjectExpression = expression.subjectExpression ?: return
|
||||||
val property = expression.findDeclarationNear() ?: return
|
val property = expression.findDeclarationNear() ?: return
|
||||||
if (!property.isUsedOnlyIn(expression)) return
|
val action = property.action(expression)
|
||||||
|
if (action == Action.NOTHING) return
|
||||||
|
|
||||||
val identifier = property.nameIdentifier ?: return
|
val identifier = property.nameIdentifier ?: return
|
||||||
holder.registerProblem(
|
holder.registerProblem(
|
||||||
property,
|
property,
|
||||||
TextRange.from(identifier.startOffsetInParent, identifier.textLength),
|
TextRange.from(identifier.startOffsetInParent, identifier.textLength),
|
||||||
"Variable declaration could be moved inside `when`",
|
action.description, action.createFix(subjectExpression.createSmartPointer())
|
||||||
MoveVariableDeclarationIntoWhenFix(subjectExpression.createSmartPointer())
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtProperty.isUsedOnlyIn(element: KtElement): Boolean = countUsages() == countUsages(element)
|
private enum class Action {
|
||||||
|
NOTHING,
|
||||||
|
MOVE,
|
||||||
|
INLINE;
|
||||||
|
|
||||||
|
val description: String
|
||||||
|
get() = when (this) {
|
||||||
|
MOVE -> "Variable declaration could be moved into `when`"
|
||||||
|
INLINE -> "Variable declaration could be inlined"
|
||||||
|
NOTHING -> "Nothing to do"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFix(subjectExpressionPointer: SmartPsiElementPointer<KtExpression>): VariableDeclarationIntoWhenFix = when (this) {
|
||||||
|
MOVE -> VariableDeclarationIntoWhenFix("Move variable declaration into `when`", subjectExpressionPointer) { it }
|
||||||
|
INLINE -> VariableDeclarationIntoWhenFix("Inline variable", subjectExpressionPointer) { it.initializer }
|
||||||
|
else -> error("Illegal action")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KtProperty.action(element: KtElement): Action = when (val elementUsages = countUsages(element)) {
|
||||||
|
countUsages() -> if (elementUsages == 1) Action.INLINE else Action.MOVE
|
||||||
|
else -> Action.NOTHING
|
||||||
|
}
|
||||||
|
|
||||||
private fun KtWhenExpression.findDeclarationNear(): KtProperty? {
|
private fun KtWhenExpression.findDeclarationNear(): KtProperty? {
|
||||||
val previousProperty = previousStatement() as? KtProperty ?: return null
|
val previousProperty = previousStatement() as? KtProperty ?: return null
|
||||||
return previousProperty.takeIf { !it.isVar && it.hasInitializer() && it.nameIdentifier?.text == subjectExpression?.text }
|
return previousProperty.takeIf { !it.isVar && it.hasInitializer() && it.nameIdentifier?.text == subjectExpression?.text }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MoveVariableDeclarationIntoWhenFix(val subjectExpressionPointer: SmartPsiElementPointer<KtExpression>) : LocalQuickFix {
|
private class VariableDeclarationIntoWhenFix(
|
||||||
override fun getName() = "Move the variable into `when`"
|
private val actionName: String,
|
||||||
|
private val subjectExpressionPointer: SmartPsiElementPointer<KtExpression>,
|
||||||
|
private val transform: (KtProperty) -> KtExpression?
|
||||||
|
) : LocalQuickFix {
|
||||||
|
override fun getName() = actionName
|
||||||
|
|
||||||
override fun getFamilyName() = name
|
override fun getFamilyName() = name
|
||||||
|
|
||||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||||
val property = descriptor.psiElement as? KtProperty ?: return
|
val property = descriptor.psiElement as? KtProperty ?: return
|
||||||
val subjectExpression = subjectExpressionPointer.element ?: return
|
val subjectExpression = subjectExpressionPointer.element ?: return
|
||||||
subjectExpression.replace(property.copy())
|
val newElement = transform(property)?.copy() ?: return
|
||||||
|
subjectExpression.replace(newElement)
|
||||||
property.delete()
|
property.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
|
|
||||||
// comment
|
// comment
|
||||||
when (val a = 1) {
|
when (1) {
|
||||||
1 -> {
|
1 -> {
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
|
|
||||||
|
|
||||||
when (val a = 1) {
|
when (1) {
|
||||||
1 -> {
|
1 -> {
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user