Refactored ConvertIfWithThrowToAssertIntention
This commit is contained in:
@@ -286,8 +286,6 @@ add.name.to.argument.action=Add name to argument...
|
||||
add.name.to.parameter.name.chooser.title=Choose parameter name
|
||||
remove.explicit.type.arguments=Remove explicit type arguments
|
||||
remove.explicit.type.arguments.family=Remove Explicit Type Arguments
|
||||
convert.if.with.throw.to.assert=Replace 'if' with 'assert' statement
|
||||
convert.if.with.throw.to.assert.family=Replace 'if' with 'assert' Statement
|
||||
|
||||
replace.java.class.argument=Replace javaClass<T>() with T::class
|
||||
replace.java.class.argument.family=Replace javaClass<T>() with T::class
|
||||
|
||||
+21
-42
@@ -17,75 +17,54 @@
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.psi.JetCallExpression
|
||||
import org.jetbrains.kotlin.psi.JetPsiFactory
|
||||
import org.jetbrains.kotlin.psi.JetPrefixExpression
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.psi.JetIfExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.extractExpressionIfSingle
|
||||
import org.jetbrains.kotlin.psi.JetThrowExpression
|
||||
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.JetExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.unwrapBlock
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.copied
|
||||
import org.jetbrains.kotlin.psi.psiUtil.replaced
|
||||
|
||||
public class ConvertIfWithThrowToAssertIntention :
|
||||
JetSelfTargetingOffsetIndependentIntention<JetIfExpression>("convert.if.with.throw.to.assert", javaClass()) {
|
||||
public class ConvertIfWithThrowToAssertIntention : JetSelfTargetingOffsetIndependentIntention<JetIfExpression>(javaClass(), "Replace 'if' with 'assert' statement") {
|
||||
|
||||
override fun isApplicableTo(element: JetIfExpression): Boolean {
|
||||
if (element.getElse() != null) return false
|
||||
|
||||
val thenExpr = element.getThen()?.extractExpressionIfSingle()
|
||||
if (thenExpr !is JetThrowExpression) return false
|
||||
|
||||
val thrownExpr = getSelector(thenExpr.getThrownExpression())
|
||||
val throwExpr = element.getThen()?.unwrapBlock() as? JetThrowExpression
|
||||
val thrownExpr = getSelector(throwExpr?.getThrownExpression())
|
||||
if (thrownExpr !is JetCallExpression) return false
|
||||
|
||||
if (thrownExpr.getCalleeExpression()?.getText() != "AssertionError") return false
|
||||
|
||||
val paramAmount = thrownExpr.getValueArguments().size
|
||||
if (paramAmount > 1) return false
|
||||
|
||||
val context = thenExpr.analyze()
|
||||
val resolvedCall = thrownExpr.getResolvedCall(context)
|
||||
if (resolvedCall == null) return false
|
||||
if (thrownExpr.getValueArguments().size() > 1) return false
|
||||
|
||||
val resolvedCall = thrownExpr.getResolvedCall(thrownExpr.analyze()) ?: return false
|
||||
return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() == "java.lang.AssertionError.<init>"
|
||||
}
|
||||
|
||||
override fun applyTo(element: JetIfExpression, editor: Editor) {
|
||||
val condition = element.getCondition()
|
||||
if (condition == null) return
|
||||
val condition = element.getCondition() ?: return
|
||||
|
||||
val thenExpr = element.getThen()?.extractExpressionIfSingle() as JetThrowExpression
|
||||
val thenExpr = element.getThen()?.unwrapBlock() as JetThrowExpression
|
||||
val thrownExpr = getSelector(thenExpr.getThrownExpression()) as JetCallExpression
|
||||
|
||||
val args = thrownExpr.getValueArguments()
|
||||
val paramText =
|
||||
if (args.isNotEmpty()) {
|
||||
val param = args.first!!.getArgumentExpression()!!
|
||||
if (param.isNullExpression()) "" else ", ${param.getText()}"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
val psiFactory = JetPsiFactory(element)
|
||||
val negatedCondition = psiFactory.createExpression("!true") as JetPrefixExpression
|
||||
negatedCondition.getBaseExpression()!!.replace(condition)
|
||||
condition.replace(negatedCondition)
|
||||
condition.replace(psiFactory.createExpressionByPattern("!$0", condition))
|
||||
|
||||
val newCondition = element.getCondition() as JetPrefixExpression
|
||||
var newCondition = element.getCondition()!!
|
||||
val simplifier = SimplifyNegatedBinaryExpressionIntention()
|
||||
if (simplifier.isApplicableTo(newCondition)) {
|
||||
if (simplifier.isApplicableTo(newCondition as JetPrefixExpression)) {
|
||||
simplifier.applyTo(newCondition, editor)
|
||||
newCondition = element.getCondition()!!
|
||||
}
|
||||
|
||||
val assertText = "kotlin.assert(${element.getCondition()?.getText()} $paramText)"
|
||||
val assertExpr = psiFactory.createExpression(assertText)
|
||||
val arg = thrownExpr.getValueArguments().singleOrNull()?.getArgumentExpression()
|
||||
val assertExpr = if (arg != null && !arg.isNullExpression())
|
||||
psiFactory.createExpressionByPattern("kotlin.assert($0, $1)", newCondition, arg)
|
||||
else
|
||||
psiFactory.createExpressionByPattern("kotlin.assert($0)", newCondition)
|
||||
|
||||
val newExpr = element.replace(assertExpr) as JetExpression
|
||||
val newExpr = element.replaced(assertExpr)
|
||||
ShortenReferences.DEFAULT.process(newExpr)
|
||||
}
|
||||
|
||||
|
||||
+6
-16
@@ -48,15 +48,12 @@ fun JetBinaryExpression.comparesNonNullToNull(): Boolean {
|
||||
return leftIsNull != rightIsNull && (operationToken == JetTokens.EQEQ || operationToken == JetTokens.EXCLEQ)
|
||||
}
|
||||
|
||||
fun JetExpression.extractExpressionIfSingle(): JetExpression? {
|
||||
val innerExpression = JetPsiUtil.deparenthesize(this)
|
||||
fun JetExpression.unwrapBlock(): JetExpression {
|
||||
val innerExpression = JetPsiUtil.safeDeparenthesize(this)
|
||||
if (innerExpression is JetBlockExpression) {
|
||||
return if (innerExpression.getStatements().size() == 1)
|
||||
JetPsiUtil.deparenthesize(innerExpression.getStatements().firstOrNull() as? JetExpression)
|
||||
else
|
||||
null
|
||||
val statement = innerExpression.getStatements().singleOrNull() as? JetExpression ?: return this
|
||||
return JetPsiUtil.safeDeparenthesize(statement)
|
||||
}
|
||||
|
||||
return innerExpression
|
||||
}
|
||||
|
||||
@@ -71,12 +68,10 @@ fun JetBinaryExpression.getNonNullExpression(): JetExpression? = when {
|
||||
null
|
||||
}
|
||||
|
||||
fun JetExpression.isNullExpression(): Boolean = this.extractExpressionIfSingle()?.getText() == "null"
|
||||
fun JetExpression.isNullExpression(): Boolean = this.unwrapBlock().getText() == "null"
|
||||
|
||||
fun JetExpression.isNullExpressionOrEmptyBlock(): Boolean = this.isNullExpression() || this is JetBlockExpression && this.getStatements().isEmpty()
|
||||
|
||||
fun JetExpression.isThrowExpression(): Boolean = this.extractExpressionIfSingle() is JetThrowExpression
|
||||
|
||||
fun JetThrowExpression.throwsNullPointerExceptionWithNoArguments(): Boolean {
|
||||
val thrownExpression = this.getThrownExpression()
|
||||
if (thrownExpression !is JetCallExpression) return false
|
||||
@@ -90,13 +85,8 @@ fun JetThrowExpression.throwsNullPointerExceptionWithNoArguments(): Boolean {
|
||||
return (exceptionName == NULL_PTR_EXCEPTION_FQ || exceptionName == KOTLIN_NULL_PTR_EXCEPTION_FQ) && thrownExpression.getValueArguments().isEmpty()
|
||||
}
|
||||
|
||||
fun JetExpression.isNotNullExpression(): Boolean {
|
||||
val innerExpression = this.extractExpressionIfSingle()
|
||||
return innerExpression != null && innerExpression.getText() != "null"
|
||||
}
|
||||
|
||||
fun JetExpression.evaluatesTo(other: JetExpression): Boolean {
|
||||
return this.extractExpressionIfSingle()?.getText() == other.getText()
|
||||
return this.unwrapBlock().getText() == other.getText()
|
||||
}
|
||||
|
||||
fun JetExpression.convertToIfNotNullExpression(conditionLhs: JetExpression, thenClause: JetExpression, elseClause: JetExpression?): JetIfExpression {
|
||||
|
||||
+3
-5
@@ -44,12 +44,10 @@ public class IfThenToDoubleBangIntention : JetSelfTargetingOffsetIndependentInte
|
||||
|
||||
val throwExpression =
|
||||
when (token) {
|
||||
JetTokens.EQEQ -> thenClause?.extractExpressionIfSingle()
|
||||
JetTokens.EXCLEQ -> elseClause?.extractExpressionIfSingle()
|
||||
JetTokens.EQEQ -> thenClause?.unwrapBlock()
|
||||
JetTokens.EXCLEQ -> elseClause?.unwrapBlock()
|
||||
else -> throw IllegalStateException("Token must be either '!=' or '==' ")
|
||||
} as? JetThrowExpression
|
||||
|
||||
if (throwExpression == null) return false
|
||||
} as? JetThrowExpression ?: return false
|
||||
|
||||
val matchingClause =
|
||||
when (token) {
|
||||
|
||||
+7
-2
@@ -47,6 +47,11 @@ public class IfThenToElvisIntention : JetSelfTargetingOffsetIndependentIntention
|
||||
}
|
||||
}
|
||||
|
||||
private fun JetExpression.isNotNullExpression(): Boolean {
|
||||
val innerExpression = this.unwrapBlock()
|
||||
return innerExpression !is JetBlockExpression && innerExpression.getText() != "null"
|
||||
}
|
||||
|
||||
override fun applyTo(element: JetIfExpression, editor: Editor) {
|
||||
val elvis = applyTo(element)
|
||||
elvis.inlineLeftSideIfApplicableWithPrompt(editor)
|
||||
@@ -57,8 +62,8 @@ public class IfThenToElvisIntention : JetSelfTargetingOffsetIndependentIntention
|
||||
|
||||
val thenClause = checkNotNull(element.getThen(), "The then clause cannot be null")
|
||||
val elseClause = checkNotNull(element.getElse(), "The else clause cannot be null")
|
||||
val thenExpression = checkNotNull(thenClause.extractExpressionIfSingle(), "Then clause must contain expression")
|
||||
val elseExpression = checkNotNull(elseClause.extractExpressionIfSingle(), "Else clause must contain expression")
|
||||
val thenExpression = thenClause.unwrapBlock()
|
||||
val elseExpression = elseClause.unwrapBlock()
|
||||
|
||||
val (left, right) =
|
||||
when(condition.getOperationToken()) {
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ public class IfThenToSafeAccessIntention : JetSelfTargetingOffsetIndependentInte
|
||||
findSelectorExpressionInClause(clause, receiverExpression) != null
|
||||
|
||||
fun findSelectorExpressionInClause(clause: JetExpression, receiverExpression: JetExpression): JetExpression? {
|
||||
val expression = clause.extractExpressionIfSingle() as? JetDotQualifiedExpression
|
||||
val expression = clause.unwrapBlock() as? JetDotQualifiedExpression
|
||||
|
||||
if (expression?.getReceiverExpression()?.getText() != receiverExpression.getText()) return null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user