Implement Unwrap/Remove for try expressions

This commit is contained in:
Alexey Sedunov
2013-06-19 16:08:53 +04:00
parent 9d46c90165
commit 0b634cc918
27 changed files with 494 additions and 6 deletions
@@ -379,6 +379,11 @@ public class GenerateTests {
testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapElse", "doTestElseUnwrapper"),
testModel("idea/testData/codeInsight/unwrapAndRemove/removeElse", "doTestElseRemover"),
testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop", "doTestLoopUnwrapper"),
testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapTry", "doTestTryUnwrapper"),
testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch", "doTestCatchUnwrapper"),
testModel("idea/testData/codeInsight/unwrapAndRemove/removeCatch", "doTestCatchRemover"),
testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally", "doTestFinallyUnwrapper"),
testModel("idea/testData/codeInsight/unwrapAndRemove/removeFinally", "doTestFinallyRemover"),
testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda", "doTestLambdaUnwrapper")
);
}
@@ -76,4 +76,77 @@ public class KoitlinUnwrappers {
return target instanceof JetLoopExpression ? ((JetLoopExpression) target).getBody() : null;
}
}
public static class KotlinTryUnwrapper extends KotlinComponentUnwrapper {
public KotlinTryUnwrapper(String key) {
super(key);
}
@Override
@Nullable
protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) {
return target instanceof JetTryExpression ? ((JetTryExpression) target).getTryBlock() : null;
}
}
public static class KotlinCatchUnwrapper extends KotlinComponentUnwrapper {
public KotlinCatchUnwrapper(String key) {
super(key);
}
@NotNull
@Override
protected JetElement getEnclosingElement(@NotNull JetElement element) {
return (JetElement)element.getParent();
}
@Override
protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) {
return target instanceof JetCatchClause ? ((JetCatchClause) target).getCatchBody() : null;
}
}
public static class KotlinCatchRemover extends KotlinRemover {
public KotlinCatchRemover(String key) {
super(key);
}
@Override
public boolean isApplicableTo(PsiElement e) {
return e instanceof JetCatchClause;
}
}
public static class KotlinFinallyUnwrapper extends KotlinComponentUnwrapper {
public KotlinFinallyUnwrapper(String key) {
super(key);
}
@Override
public boolean isApplicableTo(PsiElement e) {
return super.isApplicableTo(e) && getEnclosingElement((JetElement)e).getParent() instanceof JetBlockExpression;
}
@NotNull
@Override
protected JetElement getEnclosingElement(@NotNull JetElement element) {
return (JetElement)element.getParent();
}
@Override
protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) {
return target instanceof JetFinallySection ? ((JetFinallySection) target).getFinalExpression() : null;
}
}
public static class KotlinFinallyRemover extends KotlinRemover {
public KotlinFinallyRemover(String key) {
super(key);
}
@Override
public boolean isApplicableTo(PsiElement e) {
return e instanceof JetFinallySection;
}
}
}
@@ -31,21 +31,28 @@ public abstract class KotlinComponentUnwrapper extends KotlinUnwrapRemoveBase {
@Nullable
protected abstract JetExpression getExpressionToUnwrap(@NotNull JetElement target);
@NotNull
protected JetElement getEnclosingElement(@NotNull JetElement element) {
return element;
}
@Override
public boolean isApplicableTo(PsiElement e) {
if (!(e instanceof JetElement)) return false;
JetExpression expressionToUnwrap = getExpressionToUnwrap((JetElement) e);
return expressionToUnwrap != null && canExtractExpression(expressionToUnwrap, (JetElement) e.getParent());
return expressionToUnwrap != null && canExtractExpression(expressionToUnwrap,
(JetElement) getEnclosingElement((JetElement) e).getParent());
}
@Override
protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException {
JetExpression targetExpression = (JetExpression) element;
JetExpression expressionToUnwrap = getExpressionToUnwrap(targetExpression);
JetElement targetElement = (JetElement) element;
JetExpression expressionToUnwrap = getExpressionToUnwrap(targetElement);
assert expressionToUnwrap != null;
context.extractFromExpression(expressionToUnwrap, targetExpression);
context.delete(targetExpression);
JetElement enclosingElement = getEnclosingElement(targetElement);
context.extractFromExpression(expressionToUnwrap, enclosingElement);
context.delete(enclosingElement);
}
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2013 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.jet.plugin.codeInsight.unwrap;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
public abstract class KotlinRemover extends KotlinUnwrapRemoveBase {
public KotlinRemover(String key) {
super(key);
}
@Override
protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException {
context.delete(element);
}
}
@@ -27,6 +27,11 @@ public class KotlinUnwrapDescriptor extends UnwrapDescriptorBase {
new KoitlinUnwrappers.KotlinElseRemover("remove.else"),
new KoitlinUnwrappers.KotlinElseUnwrapper("unwrap.else"),
new KoitlinUnwrappers.KotlinLoopUnwrapper("unwrap.expression"),
new KoitlinUnwrappers.KotlinTryUnwrapper("unwrap.expression"),
new KoitlinUnwrappers.KotlinCatchUnwrapper("unwrap.expression"),
new KoitlinUnwrappers.KotlinCatchRemover("remove.expression"),
new KoitlinUnwrappers.KotlinFinallyUnwrapper("unwrap.expression"),
new KoitlinUnwrappers.KotlinFinallyRemover("remove.expression"),
new KotlinLambdaUnwrapper("unwrap.expression"),
};
}
@@ -0,0 +1,15 @@
// OPTION: 1
fun foo(n: Int): Int {
return try {
n / 0
}
<caret>catch (e: ArithmeticException) {
-1
}
catch (e: Exception) {
-2
}
finally {
}
}
@@ -0,0 +1,12 @@
// OPTION: 1
fun foo(n: Int): Int {
return try {
n / 0
}
<caret>catch (e: Exception) {
-2
}
finally {
}
}
@@ -0,0 +1,18 @@
// OPTION: 1
fun foo(n: Int): Int {
try {
n / 0
}
catch (e: ArithmeticException) {
val m = -1
m
}
catch (e: Exception) {
-2
}
<caret>finally {
println("finally")
}
return 0
}
@@ -0,0 +1,15 @@
// OPTION: 1
fun foo(n: Int): Int {
try {
n / 0
}
catch (e: ArithmeticException) {
val m = -1
m
}
catch (e: Exception) {
-2
}<caret>
return 0
}
@@ -0,0 +1,15 @@
// OPTION: 0
fun foo(n: Int): Int {
return try {
n / 0
}
catch (e: ArithmeticException) {
-1
}
catch (e: Exception) {
-2
}
<caret>finally {
println("finally")
}
}
@@ -0,0 +1,12 @@
// OPTION: 0
fun foo(n: Int): Int {
return try {
n / 0
}
catch (e: ArithmeticException) {
-1
}
catch (e: Exception) {
-2
}<caret>
}
@@ -0,0 +1,18 @@
// OPTION: 0
fun foo(n: Int): Int {
try {
n / 0
}
<caret>catch (e: ArithmeticException) {
val m = -1
m
}
catch (e: Exception) {
-2
}
finally {
}
return 0
}
@@ -0,0 +1,7 @@
// OPTION: 0
fun foo(n: Int): Int {
val m = -1
m<caret>
return 0
}
@@ -0,0 +1,16 @@
// IS_APPLICABLE: false
fun foo(n: Int): Int {
return try {
n / 0
}
<caret>catch (e: ArithmeticException) {
val m = -1
m
}
catch (e: Exception) {
-2
}
finally {
}
}
@@ -0,0 +1,15 @@
// OPTION: 0
fun foo(n: Int): Int {
return try {
n / 0
}
<caret>catch (e: ArithmeticException) {
-1
}
catch (e: Exception) {
-2
}
finally {
}
}
@@ -0,0 +1,4 @@
// OPTION: 0
fun foo(n: Int): Int {
return -1<caret>
}
@@ -0,0 +1,18 @@
// OPTION: 0
fun foo(n: Int): Int {
try {
n / 0
}
catch (e: ArithmeticException) {
-1
}
catch (e: Exception) {
-2
}
<caret>finally {
val s = "finally"
println(s)
}
return 0
}
@@ -0,0 +1,7 @@
// OPTION: 0
fun foo(n: Int): Int {
val s = "finally"
println(s)<caret>
return 0
}
@@ -0,0 +1,16 @@
// IS_APPLICABLE: false
fun foo(n: Int): Int {
return try {
n / 0
}
catch (e: ArithmeticException) {
-1
}
catch (e: Exception) {
-2
}
<caret>finally {
val s = "finally"
println(s)
}
}
@@ -0,0 +1,15 @@
// IS_APPLICABLE: false
fun foo(n: Int): Int {
return try {
n / 0
}
catch (e: ArithmeticException) {
-1
}
catch (e: Exception) {
-2
}
<caret>finally {
println("finally")
}
}
@@ -0,0 +1,11 @@
// OPTION: 1
fun foo(n : Int): Int {
<caret>try {
val m = n + 1
m/0
} catch (e: Exception) {
-1
}
return 0
}
@@ -0,0 +1,7 @@
// OPTION: 1
fun foo(n : Int): Int {
val m = n + 1
m/0
return 0
}
@@ -0,0 +1,9 @@
// IS_APPLICABLE: false
fun foo(n : Int): Int {
return <caret>try {
val m = n + 1
m/0
} catch (e: Exception) {
-1
}
}
@@ -0,0 +1,8 @@
// OPTION: 0
fun foo(n : Int): Int {
return try {
n/0<caret>
} catch (e: Exception) {
-1
}
}
@@ -0,0 +1,4 @@
// OPTION: 0
fun foo(n : Int): Int {
return n/0
}
@@ -46,6 +46,26 @@ public abstract class AbstractUnwrapRemoveTest extends LightCodeInsightTestCase
doTest(path, KoitlinUnwrappers.KotlinLoopUnwrapper.class);
}
public void doTestTryUnwrapper(@NotNull String path) throws Exception {
doTest(path, KoitlinUnwrappers.KotlinTryUnwrapper.class);
}
public void doTestCatchUnwrapper(@NotNull String path) throws Exception {
doTest(path, KoitlinUnwrappers.KotlinCatchUnwrapper.class);
}
public void doTestCatchRemover(@NotNull String path) throws Exception {
doTest(path, KoitlinUnwrappers.KotlinCatchRemover.class);
}
public void doTestFinallyUnwrapper(@NotNull String path) throws Exception {
doTest(path, KoitlinUnwrappers.KotlinFinallyUnwrapper.class);
}
public void doTestFinallyRemover(@NotNull String path) throws Exception {
doTest(path, KoitlinUnwrappers.KotlinFinallyRemover.class);
}
public void doTestLambdaUnwrapper(@NotNull String path) throws Exception {
doTest(path, KotlinLambdaUnwrapper.class);
}
@@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.unwrap.AbstractUnwrapRemoveTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class, UnwrapRemoveTestGenerated.UnwrapLambda.class})
@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class, UnwrapRemoveTestGenerated.UnwrapTry.class, UnwrapRemoveTestGenerated.UnwrapCatch.class, UnwrapRemoveTestGenerated.RemoveCatch.class, UnwrapRemoveTestGenerated.UnwrapFinally.class, UnwrapRemoveTestGenerated.RemoveFinally.class, UnwrapRemoveTestGenerated.UnwrapLambda.class})
public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest {
@TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapThen")
public static class UnwrapThen extends AbstractUnwrapRemoveTest {
@@ -114,6 +114,106 @@ public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest {
}
@TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapTry")
public static class UnwrapTry extends AbstractUnwrapRemoveTest {
public void testAllFilesPresentInUnwrapTry() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapTry"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("tryCompoundInBlock.kt")
public void testTryCompoundInBlock() throws Exception {
doTestTryUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt");
}
@TestMetadata("tryCompoundInReturn.kt")
public void testTryCompoundInReturn() throws Exception {
doTestTryUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInReturn.kt");
}
@TestMetadata("trySimpleInReturn.kt")
public void testTrySimpleInReturn() throws Exception {
doTestTryUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt");
}
}
@TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch")
public static class UnwrapCatch extends AbstractUnwrapRemoveTest {
public void testAllFilesPresentInUnwrapCatch() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("catchCompoundInBlock.kt")
public void testCatchCompoundInBlock() throws Exception {
doTestCatchUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt");
}
@TestMetadata("catchCompoundInReturn.kt")
public void testCatchCompoundInReturn() throws Exception {
doTestCatchUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInReturn.kt");
}
@TestMetadata("catchSimpleInReturn.kt")
public void testCatchSimpleInReturn() throws Exception {
doTestCatchUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt");
}
}
@TestMetadata("idea/testData/codeInsight/unwrapAndRemove/removeCatch")
public static class RemoveCatch extends AbstractUnwrapRemoveTest {
public void testAllFilesPresentInRemoveCatch() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/removeCatch"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("catch.kt")
public void testCatch() throws Exception {
doTestCatchRemover("idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt");
}
}
@TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally")
public static class UnwrapFinally extends AbstractUnwrapRemoveTest {
public void testAllFilesPresentInUnwrapFinally() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("finallyCompoundInBlock.kt")
public void testFinallyCompoundInBlock() throws Exception {
doTestFinallyUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt");
}
@TestMetadata("finallyCompoundInReturn.kt")
public void testFinallyCompoundInReturn() throws Exception {
doTestFinallyUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInReturn.kt");
}
@TestMetadata("finallySimpleInReturn.kt")
public void testFinallySimpleInReturn() throws Exception {
doTestFinallyUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallySimpleInReturn.kt");
}
}
@TestMetadata("idea/testData/codeInsight/unwrapAndRemove/removeFinally")
public static class RemoveFinally extends AbstractUnwrapRemoveTest {
public void testAllFilesPresentInRemoveFinally() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/removeFinally"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("finallyInBlock.kt")
public void testFinallyInBlock() throws Exception {
doTestFinallyRemover("idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt");
}
@TestMetadata("finallyInReturn.kt")
public void testFinallyInReturn() throws Exception {
doTestFinallyRemover("idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt");
}
}
@TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda")
public static class UnwrapLambda extends AbstractUnwrapRemoveTest {
public void testAllFilesPresentInUnwrapLambda() throws Exception {
@@ -178,6 +278,11 @@ public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest {
suite.addTestSuite(UnwrapElse.class);
suite.addTestSuite(RemoveElse.class);
suite.addTestSuite(UnwrapLoop.class);
suite.addTestSuite(UnwrapTry.class);
suite.addTestSuite(UnwrapCatch.class);
suite.addTestSuite(RemoveCatch.class);
suite.addTestSuite(UnwrapFinally.class);
suite.addTestSuite(RemoveFinally.class);
suite.addTestSuite(UnwrapLambda.class);
return suite;
}