Remove ConvertAssertToIfWithThrowIntention

Relates to #KT-31502
This commit is contained in:
Dmitry Gridin
2019-05-27 17:07:46 +07:00
parent fe9bd9ee20
commit 1adc2ae4c8
46 changed files with 0 additions and 514 deletions
@@ -1143,11 +1143,6 @@
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.ConvertAssertToIfWithThrowIntention</className>
<category>Kotlin</category>
</intentionAction>
<intentionAction>
<className>org.jetbrains.kotlin.idea.intentions.ConvertIfWithThrowToAssertIntention</className>
<category>Kotlin</category>
@@ -1,5 +0,0 @@
fun foo() {
<spot>if (!true) {
throw AssertionError("text")
}</spot>
}
@@ -1,3 +0,0 @@
fun foo() {
<spot>assert(true, "text")</spot>
}
@@ -1,5 +0,0 @@
<html>
<body>
This intention converts an <b>assert</b> into an <b>if</b> statement that throws an exception if the condition is false.
</body>
</html>
@@ -1,120 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.intentions
import com.intellij.codeInsight.intention.LowPriorityAction
import com.intellij.openapi.editor.Editor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.inspections.SimplifyNegatedBinaryExpressionInspection
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCallExpression>(KtCallExpression::class.java, "Replace 'assert' with 'if' statement"), LowPriorityAction {
override fun isApplicableTo(element: KtCallExpression, caretOffset: Int): Boolean {
val callee = element.calleeExpression ?: return false
if (!callee.textRange.containsOffset(caretOffset)) return false
val argumentSize = element.valueArguments.size
if (argumentSize !in 1..2) return false
val functionLiterals = element.lambdaArguments
if (functionLiterals.size > 1) return false
if (functionLiterals.size == 1 && argumentSize == 1) return false // "assert {...}" is incorrect
val resolvedCall = element.resolveToCall() ?: return false
return DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).asString() == "kotlin.assert"
}
override fun applyTo(element: KtCallExpression, editor: Editor?) {
val args = element.valueArguments
val conditionText = args[0]?.getArgumentExpression()?.text ?: return
val functionLiteralArgument = element.lambdaArguments.singleOrNull()
val bindingContext = element.analyze(BodyResolveMode.PARTIAL_WITH_CFA)
val psiFactory = KtPsiFactory(element)
val messageFunctionExpr = when {
args.size == 2 -> args[1]?.getArgumentExpression() ?: return
functionLiteralArgument != null -> functionLiteralArgument.getLambdaExpression()
else -> null
}
val extractedMessageSingleExpr = (messageFunctionExpr as? KtLambdaExpression)?.let { extractMessageSingleExpression(it, bindingContext) }
val messageIsFunction = extractedMessageSingleExpr == null && messageIsFunction(element, bindingContext)
val messageExpr = extractedMessageSingleExpr ?: messageFunctionExpr ?: psiFactory.createExpression("\"Assertion failed\"")
val ifExpression = replaceWithIfThenThrowExpression(element)
// shorten java.lang.AssertionError
ShortenReferences.DEFAULT.process(ifExpression.then!!)
val ifCondition = ifExpression.condition as KtPrefixExpression
ifCondition.baseExpression!!.replace(psiFactory.createExpression(conditionText))
val thrownExpression = ((ifExpression.then as KtBlockExpression).statements.single() as KtThrowExpression).thrownExpression
val assertionErrorCall = thrownExpression as? KtCallExpression
?: (thrownExpression as KtDotQualifiedExpression).selectorExpression as KtCallExpression
val message = psiFactory.createExpression(
if (messageIsFunction && messageExpr is KtCallableReferenceExpression) {
messageExpr.callableReference.text + "()"
}
else if (messageIsFunction) {
messageExpr.text + "()"
}
else {
messageExpr.text
}
)
assertionErrorCall.valueArguments.single().getArgumentExpression()!!.replace(message)
simplifyConditionIfPossible(ifExpression, editor)
}
private fun extractMessageSingleExpression(functionLiteral: KtLambdaExpression, bindingContext: BindingContext): KtExpression? {
return functionLiteral.bodyExpression?.statements?.singleOrNull()?.let { singleStatement ->
singleStatement.takeIf { it.isUsedAsExpression(bindingContext) }
}
}
private fun messageIsFunction(callExpr: KtCallExpression, bindingContext: BindingContext): Boolean {
val resolvedCall = callExpr.getResolvedCall(bindingContext) ?: return false
val valParameters = resolvedCall.resultingDescriptor.valueParameters
return valParameters.size > 1 && !KotlinBuiltIns.isAny(valParameters[1].type)
}
private fun simplifyConditionIfPossible(ifExpression: KtIfExpression, editor: Editor?) {
val condition = ifExpression.condition as KtPrefixExpression
val simplifier = SimplifyNegatedBinaryExpressionInspection()
if (simplifier.isApplicable(condition)) {
simplifier.applyTo(condition.operationReference, editor = editor)
}
}
private fun replaceWithIfThenThrowExpression(original: KtCallExpression): KtIfExpression {
val replacement = KtPsiFactory(original).createExpression("if (!true) { throw kotlin.AssertionError(\"\") }") as KtIfExpression
val parent = original.parent
return (parent as? KtDotQualifiedExpression)?.replaced(replacement) ?: original.replaced(replacement)
}
}
-1
View File
@@ -1 +0,0 @@
org.jetbrains.kotlin.idea.intentions.ConvertAssertToIfWithThrowIntention
@@ -1,9 +0,0 @@
package a
fun foo() {
<caret>assert(true, { "text" })
}
class AssertionError
// WITH_RUNTIME
@@ -1,11 +0,0 @@
package a
fun foo() {
if (!true) {
throw AssertionError("text")
}
}
class AssertionError
// WITH_RUNTIME
@@ -1,4 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(true && false, { "text" })
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!(true && false)) {
throw AssertionError("text")
}
}
@@ -1,4 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(1 > 0) { "text" }
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (1 <= 0) {
throw AssertionError("text")
}
}
@@ -1,4 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(0 != 1) { "text" }
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (0 == 1) {
throw AssertionError("text")
}
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
val x = true
val y = false
<caret>assert(x || y) { "text" }
}
@@ -1,8 +0,0 @@
// WITH_RUNTIME
fun foo() {
val x = true
val y = false
if (!(x || y)) {
throw AssertionError("text")
}
}
@@ -1,5 +0,0 @@
fun main(args: Array<String>) {
asse<caret>rt(false) { "mess" as kotlin.String }
}
// WITH_RUNTIME
@@ -1,7 +0,0 @@
fun main(args: Array<String>) {
if (!false) {
throw AssertionError("mess" as kotlin.String)
}
}
// WITH_RUNTIME
@@ -1,4 +0,0 @@
// WITH_RUNTIME
fun foo() {
kotlin.<caret>assert(true) {"text"}
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!true) {
throw AssertionError("text")
}
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(bar()) { "text" }
}
fun bar(): Boolean = true
@@ -1,8 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!bar()) {
throw AssertionError("text")
}
}
fun bar(): Boolean = true
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(true, ::message)
}
fun message(): String = "text"
@@ -1,8 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!true) {
throw AssertionError(message())
}
}
fun message(): String = "text"
@@ -1,7 +0,0 @@
// IS_APPLICABLE: false
// WITH_RUNTIME
fun foo() {
<caret>assert(true, "")
}
fun assert(b: Boolean, s: String) {}
@@ -1,9 +0,0 @@
// IS_APPLICABLE: false
// WITH_RUNTIME
package pr442.kotlin
fun foo() {
<caret>assert(true, "")
}
fun assert(b: Boolean, s: String) {}
@@ -1,7 +0,0 @@
// IS_APPLICABLE: false
// WITH_RUNTIME
// ERROR: None of the following functions can be called with the arguments supplied: <br>@InlineOnly public inline fun assert(value: Boolean): Unit defined in kotlin<br>@InlineOnly public inline fun assert(value: Boolean, lazyMessage: () -> Any): Unit defined in kotlin
fun foo() {
<caret>assert()
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(true, {
if (true) "text" else return
})
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!true) {
throw AssertionError(if (true) "text" else return)
}
}
@@ -1,8 +0,0 @@
// WITH_RUNTIME
// SKIP_ERRORS_AFTER
// TODO: 'return' is not allowed here
fun foo() {
<caret>assert(true) {
return
}
}
@@ -1,10 +0,0 @@
// WITH_RUNTIME
// SKIP_ERRORS_AFTER
// TODO: 'return' is not allowed here
fun foo() {
if (!true) {
throw AssertionError({
return
}())
}
}
@@ -1,7 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(true, {
val value = 1
"text and $value"
})
}
@@ -1,9 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!true) {
throw AssertionError({
val value = 1
"text and $value"
}())
}
}
@@ -1,9 +0,0 @@
// WITH_RUNTIME
// SKIP_ERRORS_AFTER
// TODO: 'return' is not allowed here
fun foo() {
<caret>assert(true) {
if (false) return
"text"
}
}
@@ -1,11 +0,0 @@
// WITH_RUNTIME
// SKIP_ERRORS_AFTER
// TODO: 'return' is not allowed here
fun foo() {
if (!true) {
throw AssertionError({
if (false) return
"text"
}())
}
}
@@ -1,5 +0,0 @@
// WITH_RUNTIME
fun foo() {
val f = { "text" }
<caret>assert(true, f)
}
@@ -1,7 +0,0 @@
// WITH_RUNTIME
fun foo() {
val f = { "text" }
if (!true) {
throw AssertionError(f())
}
}
@@ -1,4 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(true)
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!true) {
throw AssertionError("Assertion failed")
}
}
@@ -1,4 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert((true && false)) { "text" }
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!(true && false)) {
throw AssertionError("text")
}
}
@@ -1,4 +0,0 @@
// WITH_RUNTIME
fun foo() {
<caret>assert(true) { "text" }
}
@@ -1,6 +0,0 @@
// WITH_RUNTIME
fun foo() {
if (!true) {
throw AssertionError("text")
}
}
@@ -1,5 +0,0 @@
// WITH_RUNTIME
fun foo() {
val f = "text"
<caret>assert(true) { f }
}
@@ -1,7 +0,0 @@
// WITH_RUNTIME
fun foo() {
val f = "text"
if (!true) {
throw AssertionError(f)
}
}
@@ -4651,124 +4651,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
@TestMetadata("idea/testData/intentions/convertAssertToIf")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class ConvertAssertToIf extends AbstractIntentionTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInConvertAssertToIf() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/convertAssertToIf"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("assertErrorOverloaded.kt")
public void testAssertErrorOverloaded() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/assertErrorOverloaded.kt");
}
@TestMetadata("booleanCondition.kt")
public void testBooleanCondition() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/booleanCondition.kt");
}
@TestMetadata("booleanConditionSimplified.kt")
public void testBooleanConditionSimplified() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/booleanConditionSimplified.kt");
}
@TestMetadata("booleanConditionSimplified2.kt")
public void testBooleanConditionSimplified2() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/booleanConditionSimplified2.kt");
}
@TestMetadata("booleanConditionWithVariables.kt")
public void testBooleanConditionWithVariables() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/booleanConditionWithVariables.kt");
}
@TestMetadata("doNotShortenReferenceInsideMessage.kt")
public void testDoNotShortenReferenceInsideMessage() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/doNotShortenReferenceInsideMessage.kt");
}
@TestMetadata("dotQualifiedCall.kt")
public void testDotQualifiedCall() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/dotQualifiedCall.kt");
}
@TestMetadata("functionCallCondition.kt")
public void testFunctionCallCondition() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/functionCallCondition.kt");
}
@TestMetadata("functionMessageInsideParentheses.kt")
public void testFunctionMessageInsideParentheses() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/functionMessageInsideParentheses.kt");
}
@TestMetadata("inapplicableAssertOverloaded.kt")
public void testInapplicableAssertOverloaded() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/inapplicableAssertOverloaded.kt");
}
@TestMetadata("inapplicableAssertOverloadedWithPackage.kt")
public void testInapplicableAssertOverloadedWithPackage() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/inapplicableAssertOverloadedWithPackage.kt");
}
@TestMetadata("inapplicableNoCondition.kt")
public void testInapplicableNoCondition() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/inapplicableNoCondition.kt");
}
@TestMetadata("lambdaMessageInsideParentheses.kt")
public void testLambdaMessageInsideParentheses() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/lambdaMessageInsideParentheses.kt");
}
@TestMetadata("lambdaMessageOutsideParentheses.kt")
public void testLambdaMessageOutsideParentheses() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/lambdaMessageOutsideParentheses.kt");
}
@TestMetadata("lambdaMultiStatementMessageInsideParentheses.kt")
public void testLambdaMultiStatementMessageInsideParentheses() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/lambdaMultiStatementMessageInsideParentheses.kt");
}
@TestMetadata("lambdaMultiStatementMessageOutsideParentheses.kt")
public void testLambdaMultiStatementMessageOutsideParentheses() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/lambdaMultiStatementMessageOutsideParentheses.kt");
}
@TestMetadata("lambdaVariable.kt")
public void testLambdaVariable() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/lambdaVariable.kt");
}
@TestMetadata("noMessage.kt")
public void testNoMessage() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/noMessage.kt");
}
@TestMetadata("parenthesizedCondition.kt")
public void testParenthesizedCondition() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/parenthesizedCondition.kt");
}
@TestMetadata("simpleConvert.kt")
public void testSimpleConvert() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/simpleConvert.kt");
}
@TestMetadata("stringVariable.kt")
public void testStringVariable() throws Exception {
runTest("idea/testData/intentions/convertAssertToIf/stringVariable.kt");
}
}
@TestMetadata("idea/testData/intentions/convertBinaryExpressionWithDemorgansLaw")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)