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