Quick-fix for reassignment in try / catch (fold to assignment) #KT-13778 Fixed
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2016 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.quickfix
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFoldingUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
class LiftAssignmentOutOfTryFix(element: KtTryExpression): KotlinQuickFixAction<KtTryExpression>(element) {
|
||||
override fun getFamilyName() = text
|
||||
|
||||
override fun getText() = "Lift assignment out of 'try' expression"
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
val tryAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.tryBlock) ?: return
|
||||
|
||||
val op = tryAssignment.operationReference.text
|
||||
val leftText = tryAssignment.left?.text ?: return
|
||||
|
||||
tryAssignment.replace(tryAssignment.right ?: return)
|
||||
|
||||
for (catchClause in element.catchClauses) {
|
||||
val catchAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(catchClause.catchBody)
|
||||
catchAssignment?.replace(catchAssignment.right!!)
|
||||
}
|
||||
|
||||
element.replace(KtPsiFactory(element).createExpressionByPattern("$0 $1 $2", leftText, op, element))
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
|
||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||
val expression = diagnostic.psiElement as? KtExpression ?: return null
|
||||
val originalCatch = expression.parent?.parent?.parent as? KtCatchClause ?: return null
|
||||
val tryExpression = originalCatch.parent as? KtTryExpression ?: return null
|
||||
val tryAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(tryExpression.tryBlock) ?: return null
|
||||
for (catchClause in tryExpression.catchClauses) {
|
||||
val catchAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(catchClause.catchBody) ?: return null
|
||||
if (!BranchedFoldingUtils.checkAssignmentsMatch(tryAssignment, catchAssignment)) return null
|
||||
}
|
||||
return LiftAssignmentOutOfTryFix(tryExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,6 +176,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
VAL_WITH_SETTER.registerFactory(ChangeVariableMutabilityFix.VAL_WITH_SETTER_FACTORY)
|
||||
VAL_REASSIGNMENT.registerFactory(ChangeVariableMutabilityFix.VAL_REASSIGNMENT_FACTORY)
|
||||
VAL_REASSIGNMENT.registerFactory(LiftAssignmentOutOfTryFix)
|
||||
CAPTURED_VAL_INITIALIZATION.registerFactory(ChangeVariableMutabilityFix.CAPTURED_VAL_INITIALIZATION_FACTORY)
|
||||
VAR_OVERRIDDEN_BY_VAL.registerFactory(ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY)
|
||||
VAR_ANNOTATION_PARAMETER.registerFactory(ChangeVariableMutabilityFix.VAR_ANNOTATION_PARAMETER_FACTORY)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Lift assignment out of 'try' expression" "false"
|
||||
// ACTION: Make variable mutable
|
||||
// ERROR: Val cannot be reassigned
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo(arg: Boolean) {
|
||||
val x: Int
|
||||
try {
|
||||
if (arg) {
|
||||
x = 1
|
||||
}
|
||||
}
|
||||
catch (e: Exception) {
|
||||
<caret>x = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// "Lift assignment out of 'try' expression" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
val x: Int
|
||||
try {
|
||||
x = 1
|
||||
}
|
||||
catch (e: Exception) {
|
||||
<caret>x = 2
|
||||
}
|
||||
finally {}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Lift assignment out of 'try' expression" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
val x: Int
|
||||
x = try {
|
||||
1
|
||||
} catch (e: Exception) {
|
||||
2
|
||||
} finally {}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// "Lift assignment out of 'try' expression" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
val x: Int
|
||||
try {
|
||||
x = 1
|
||||
}
|
||||
catch (e: RuntimeException) {
|
||||
<caret>x = 2
|
||||
}
|
||||
catch (e: Exception) {
|
||||
x = 3
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
x = 4
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// "Lift assignment out of 'try' expression" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
val x: Int
|
||||
x = try {
|
||||
1
|
||||
} catch (e: RuntimeException) {
|
||||
2
|
||||
} catch (e: Exception) {
|
||||
3
|
||||
} catch (e: Throwable) {
|
||||
4
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// "Lift assignment out of 'try' expression" "false"
|
||||
// ACTION: Make variable mutable
|
||||
// ERROR: Val cannot be reassigned
|
||||
// ERROR: Val cannot be reassigned
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
val x = 1
|
||||
try {
|
||||
val x = 2
|
||||
x = 3
|
||||
}
|
||||
catch(e: Exception) {
|
||||
<caret>x = 4
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Lift assignment out of 'try' expression" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
val x: Int
|
||||
try {
|
||||
x = 1
|
||||
}
|
||||
catch (e: Exception) {
|
||||
<caret>x = 2
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// "Lift assignment out of 'try' expression" "true"
|
||||
// WITH_RUNTIME
|
||||
|
||||
fun foo() {
|
||||
val x: Int
|
||||
x = try {
|
||||
1
|
||||
} catch (e: Exception) {
|
||||
2
|
||||
}
|
||||
}
|
||||
@@ -5122,6 +5122,45 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/foldTryCatch")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FoldTryCatch extends AbstractQuickFixTest {
|
||||
public void testAllFilesPresentInFoldTryCatch() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/foldTryCatch"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("conditional.kt")
|
||||
public void testConditional() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/foldTryCatch/conditional.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("emptyFinally.kt")
|
||||
public void testEmptyFinally() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/foldTryCatch/emptyFinally.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("multipleExceptions.kt")
|
||||
public void testMultipleExceptions() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/foldTryCatch/multipleExceptions.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("shadow.kt")
|
||||
public void testShadow() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/foldTryCatch/shadow.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/foldTryCatch/simple.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/quickfix/implement")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user