Fix ConvertAssertToIfWithThrowIntention to avoid shortening more references than intended

This commit is contained in:
Pavel V. Talanov
2014-07-21 14:38:36 +04:00
parent f44ba60d51
commit 740fe70b22
3 changed files with 44 additions and 35 deletions
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
import org.jetbrains.jet.lang.resolve.bindingContextUtil.getResolvedCall import org.jetbrains.jet.lang.resolve.bindingContextUtil.getResolvedCall
import org.jetbrains.jet.lang.psi.JetBlockExpression import org.jetbrains.jet.lang.psi.JetBlockExpression
import org.jetbrains.jet.lang.psi.JetThrowExpression import org.jetbrains.jet.lang.psi.JetThrowExpression
import org.jetbrains.jet.lang.psi.psiUtil.replaced
public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<JetCallExpression>( public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<JetCallExpression>(
"convert.assert.to.if.with.throw", javaClass()) { "convert.assert.to.if.with.throw", javaClass()) {
@@ -55,19 +56,12 @@ public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<Jet
messageIsAFunction = false messageIsAFunction = false
} }
return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() == "kotlin.assert" return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).asString() == "kotlin.assert"
} }
override fun applyTo(element: JetCallExpression, editor: Editor) { override fun applyTo(element: JetCallExpression, editor: Editor) {
val replacementIfExpression = createReplacementExpression(element) ?: return
val replaced = replaceExpression(element, replacementIfExpression)
ShortenReferences.process(replaced.getThen()!!)
simplifyConditionIfPossible(editor, replaced)
}
private fun createReplacementExpression(element: JetCallExpression): JetIfExpression? {
val args = element.getValueArguments() val args = element.getValueArguments()
val condition = args[0]?.getArgumentExpression() val conditionText = args[0]?.getArgumentExpression()?.getText() ?: return
val lambdas = element.getFunctionLiteralArguments() val lambdas = element.getFunctionLiteralArguments()
val psiFactory = JetPsiFactory(element) val psiFactory = JetPsiFactory(element)
@@ -82,25 +76,44 @@ public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<Jet
psiFactory.createExpression("\"Assertion failed\"") psiFactory.createExpression("\"Assertion failed\"")
} }
if (condition == null || messageExpr == null) return null if (messageExpr == null) return
val message = val replaced = replaceWithIfThenThrowExpression(element)
if (messageIsAFunction && messageExpr is JetCallableReferenceExpression) {
"${messageExpr.getCallableReference().getText()}()"
}
else if (messageIsAFunction) {
"${messageExpr.getText()}()"
}
else {
"${messageExpr.getText()}"
}
val text = "if (!true) { throw java.lang.AssertionError(${message}) }" ShortenReferences.process(replaced.getThen()!!)
val ifExpression = psiFactory.createExpression(text) as JetIfExpression
val ifCondition = ifExpression.getCondition() as JetPrefixExpression fun replaceMessage() {
ifCondition.getBaseExpression()?.replace(condition) val thrownExpression = ((replaced.getThen() as JetBlockExpression).getStatements().first() as JetThrowExpression).getThrownExpression()
return ifExpression val assertionErrorCall = if (thrownExpression is JetCallExpression) {
thrownExpression: JetCallExpression
}
else {
(thrownExpression as JetDotQualifiedExpression).getSelectorExpression() as JetCallExpression
}
val message = psiFactory.createExpression(
if (messageIsAFunction && messageExpr is JetCallableReferenceExpression) {
"${messageExpr.getCallableReference().getText()}()"
}
else if (messageIsAFunction) {
"${messageExpr.getText()}()"
}
else {
"${messageExpr.getText()}"
}
)
assertionErrorCall.getValueArguments().single()!!.getArgumentExpression()!!.replace(message)
}
fun replaceCondition() {
val ifCondition = replaced.getCondition() as JetPrefixExpression
ifCondition.getBaseExpression()!!.replace(psiFactory.createExpression(conditionText))
}
replaceCondition()
replaceMessage()
simplifyConditionIfPossible(editor, replaced)
} }
private fun simplifyConditionIfPossible(editor: Editor, replaced: JetIfExpression) { private fun simplifyConditionIfPossible(editor: Editor, replaced: JetIfExpression) {
@@ -111,14 +124,14 @@ public class ConvertAssertToIfWithThrowIntention : JetSelfTargetingIntention<Jet
} }
} }
private fun replaceExpression(original: JetCallExpression, replacement: JetIfExpression): JetIfExpression { private fun replaceWithIfThenThrowExpression(original: JetCallExpression): JetIfExpression {
val replacement = JetPsiFactory(original).createExpression("if (!true) { throw java.lang.AssertionError(\"\") }") as JetIfExpression
val parent = original.getParent() val parent = original.getParent()
val result = if (parent is JetDotQualifiedExpression) { return if (parent is JetDotQualifiedExpression) {
parent.replace(replacement) parent.replaced(replacement)
} }
else { else {
original.replace(replacement) original.replaced(replacement)
} }
return result as JetIfExpression
} }
} }
@@ -1,5 +1,3 @@
//TODO: should not shorten references here
fun main(args: Array<String>) { fun main(args: Array<String>) {
asse<caret>rt(false, "mess": kotlin.String) asse<caret>rt(false, "mess": kotlin.String)
} }
@@ -1,8 +1,6 @@
//TODO: should not shorten references here
fun main(args: Array<String>) { fun main(args: Array<String>) {
if (!false) { if (!false) {
throw AssertionError("mess": String) throw AssertionError("mess": kotlin.String)
} }
} }