diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java
index 6bfb8439a2c..c50df4959b5 100644
--- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java
+++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRenderer
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest;
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest;
import org.jetbrains.jet.modules.xml.AbstractModuleXmlParserTest;
+import org.jetbrains.jet.plugin.codeInsight.unwrap.AbstractUnwrapRemoveTest;
import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest;
import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest;
import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest;
@@ -369,6 +370,16 @@ public class GenerateTests {
testModel("idea/testData/codeInsight/moveUpDown/closingBraces", "doTestExpression"),
testModel("idea/testData/codeInsight/moveUpDown/expressions", "doTestExpression")
);
+
+ generateTest(
+ "idea/tests/",
+ "UnwrapRemoveTestGenerated",
+ AbstractUnwrapRemoveTest.class,
+ testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapThen", "doTestThenUnwrapper"),
+ testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapElse", "doTestElseUnwrapper"),
+ testModel("idea/testData/codeInsight/unwrapAndRemove/removeElse", "doTestElseRemover"),
+ testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop", "doTestLoopUnwrapper")
+ );
}
private static SimpleTestClassModel testModel(@NotNull String rootPath) {
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index fcf0e0c2ae7..a2c7b3152d6 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -124,6 +124,7 @@
implementationClass="org.jetbrains.jet.plugin.codeInsight.surroundWith.expression.KotlinExpressionSurroundDescriptor"/>
+
diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties
index d5268f23f8b..3fd4c5848b8 100644
--- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties
+++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties
@@ -228,3 +228,8 @@ add.function.to.supertype.action.multiple=Add function to supertype...
add.function.to.type.action.single=Add ''{0}'' to ''{1}''
add.function.to.type.action=Add function to type
add.function.to.type.action.type.chooser=Choose type...
+
+remove.expression = Remove ''{0}''
+unwrap.expression = Unwrap ''{0}''
+remove.else = Remove else in ''{0}''
+unwrap.else = Unwrap else in ''{0}''
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java
new file mode 100644
index 00000000000..fe5c517be1c
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.psi.*;
+
+public class KoitlinUnwrappers {
+ private KoitlinUnwrappers() {
+ }
+
+ public static class KotlinElseUnwrapper extends KotlinComponentUnwrapper {
+ public KotlinElseUnwrapper(String key) {
+ super(key);
+ }
+
+ @Override
+ protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) {
+ return target instanceof JetIfExpression ? ((JetIfExpression) target).getElse() : null;
+ }
+ }
+
+ public static class KotlinThenUnwrapper extends KotlinComponentUnwrapper {
+ public KotlinThenUnwrapper(String key) {
+ super(key);
+ }
+
+ @Override
+ protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) {
+ return target instanceof JetIfExpression ? ((JetIfExpression) target).getThen() : null;
+ }
+ }
+
+ public static class KotlinElseRemover extends KotlinUnwrapRemoveBase {
+ public KotlinElseRemover(String key) {
+ super(key);
+ }
+
+ @Override
+ public boolean isApplicableTo(PsiElement e) {
+ return e instanceof JetIfExpression && ((JetIfExpression) e).getElse() != null;
+ }
+
+ @Override
+ protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException {
+ JetIfExpression ifExpr = (JetIfExpression) element;
+ context.replace(ifExpr, JetPsiFactory.createIf(ifExpr.getProject(), ifExpr.getCondition(), ifExpr.getThen(), null));
+ }
+ }
+
+ public static class KotlinLoopUnwrapper extends KotlinComponentUnwrapper {
+ public KotlinLoopUnwrapper(String key) {
+ super(key);
+ }
+
+ @Override
+ @Nullable
+ protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) {
+ return target instanceof JetLoopExpression ? ((JetLoopExpression) target).getBody() : null;
+ }
+ }
+}
diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java
new file mode 100644
index 00000000000..be72bcaf98a
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java
@@ -0,0 +1,51 @@
+/*
+ * 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;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.lang.psi.JetElement;
+import org.jetbrains.jet.lang.psi.JetExpression;
+
+public abstract class KotlinComponentUnwrapper extends KotlinUnwrapRemoveBase {
+ public KotlinComponentUnwrapper(String key) {
+ super(key);
+ }
+
+ @Nullable
+ protected abstract JetExpression getExpressionToUnwrap(@NotNull JetElement target);
+
+ @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());
+ }
+
+ @Override
+ protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException {
+ JetExpression targetExpression = (JetExpression) element;
+ JetExpression expressionToUnwrap = getExpressionToUnwrap(targetExpression);
+ assert expressionToUnwrap != null;
+
+ context.extractFromExpression(expressionToUnwrap, targetExpression);
+ context.delete(targetExpression);
+ }
+}
diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java
new file mode 100644
index 00000000000..337c33de3a0
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java
@@ -0,0 +1,32 @@
+/*
+ * 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.codeInsight.unwrap.UnwrapDescriptorBase;
+import com.intellij.codeInsight.unwrap.Unwrapper;
+
+public class KotlinUnwrapDescriptor extends UnwrapDescriptorBase {
+ @Override
+ protected Unwrapper[] createUnwrappers() {
+ return new Unwrapper[] {
+ new KoitlinUnwrappers.KotlinThenUnwrapper("unwrap.expression"),
+ new KoitlinUnwrappers.KotlinElseRemover("remove.else"),
+ new KoitlinUnwrappers.KotlinElseUnwrapper("unwrap.else"),
+ new KoitlinUnwrappers.KotlinLoopUnwrapper("unwrap.expression"),
+ };
+ }
+}
diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapRemoveBase.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapRemoveBase.java
new file mode 100644
index 00000000000..ac021d0880b
--- /dev/null
+++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapRemoveBase.java
@@ -0,0 +1,92 @@
+/*
+ * 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.codeInsight.unwrap.AbstractUnwrapper;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiWhiteSpace;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.psi.JetBlockExpression;
+import org.jetbrains.jet.lang.psi.JetElement;
+import org.jetbrains.jet.lang.psi.JetExpression;
+import org.jetbrains.jet.plugin.JetBundle;
+import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil;
+
+import java.util.List;
+
+public abstract class KotlinUnwrapRemoveBase extends AbstractUnwrapper {
+ private final String key;
+
+ protected KotlinUnwrapRemoveBase(@NotNull String key) {
+ /*
+ Pass empty description to superclass since actual description
+ is computed based on the Psi element at hand
+ */
+ super("");
+ this.key = key;
+ }
+
+ @Override
+ public String getDescription(PsiElement e) {
+ assert e instanceof JetElement;
+ return JetBundle.message(key, JetRefactoringUtil.getExpressionShortText((JetElement) e));
+ }
+
+ protected boolean canExtractExpression(@NotNull JetExpression expression, @NotNull JetElement parent) {
+ if (expression instanceof JetBlockExpression) {
+ JetBlockExpression block = (JetBlockExpression) expression;
+
+ return block.getStatements().size() <= 1 || parent instanceof JetBlockExpression;
+ }
+ return true;
+ }
+
+ protected static class Context extends AbstractUnwrapper.AbstractContext {
+ @Override
+ protected boolean isWhiteSpace(PsiElement element) {
+ return element instanceof PsiWhiteSpace;
+ }
+
+ public void extractFromBlock(@NotNull JetBlockExpression block, @NotNull JetElement from) throws IncorrectOperationException {
+ List expressions = block.getStatements();
+ if (!expressions.isEmpty()) {
+ extract(expressions.get(0), expressions.get(expressions.size() - 1), from);
+ }
+ }
+
+ public void extractFromExpression(@NotNull JetExpression expression, @NotNull JetElement from) throws IncorrectOperationException {
+ if (expression instanceof JetBlockExpression) {
+ extractFromBlock((JetBlockExpression) expression, from);
+ }
+ else {
+ extract(expression, expression, from);
+ }
+ }
+
+ public void replace(@NotNull JetElement originalElement, @NotNull JetElement newElement) {
+ if (myIsEffective) {
+ originalElement.replace(newElement);
+ }
+ }
+ }
+
+ @Override
+ protected Context createContext() {
+ return new Context();
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java
index 4414aecf145..c08c7aa94d1 100644
--- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java
+++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java
@@ -189,8 +189,8 @@ public class JetRefactoringUtil {
}
- public static String getExpressionShortText(@NotNull JetExpression expression) { //todo: write appropriate implementation
- String expressionText = expression.getText();
+ public static String getExpressionShortText(@NotNull JetElement element) { //todo: write appropriate implementation
+ String expressionText = element.getText();
if (expressionText.length() > 20) {
expressionText = expressionText.substring(0, 17) + "...";
}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt
new file mode 100644
index 00000000000..99d795908f0
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt
@@ -0,0 +1,8 @@
+// OPTION: 1
+fun foo(n: Int): Int {
+ return if (n > 0) {
+ n + 10
+ } else {
+ n - 10
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt.after
new file mode 100644
index 00000000000..129fc978d17
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt.after
@@ -0,0 +1,6 @@
+// OPTION: 1
+fun foo(n: Int): Int {
+ return if (n > 0) {
+ n + 10
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt
new file mode 100644
index 00000000000..271d5913dbf
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt
@@ -0,0 +1,12 @@
+// OPTION: 3
+fun foo(n: Int): Int {
+ if (n > 0) {
+ println("> 0")
+ n + 10
+ } else {
+ println("<= 0")
+ n - 10
+ }
+
+ return n
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt.after
new file mode 100644
index 00000000000..7b6f54d5da5
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt.after
@@ -0,0 +1,7 @@
+// OPTION: 3
+fun foo(n: Int): Int {
+ println("<= 0")
+ n - 10
+
+ return n
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt
new file mode 100644
index 00000000000..be9f48ed1ce
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt
@@ -0,0 +1,10 @@
+// IS_APPLICABLE: false
+fun foo(n: Int): Int {
+ return if (n > 0) {
+ println("> 0")
+ n + 10
+ } else {
+ println("<= 0")
+ n - 10
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt
new file mode 100644
index 00000000000..c7ab0d75ffc
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt
@@ -0,0 +1,8 @@
+// OPTION: 2
+fun foo(n: Int): Int {
+ return if (n > 0) {
+ n + 10
+ } else {
+ n - 10
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt.after
new file mode 100644
index 00000000000..d15dc9845b3
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt.after
@@ -0,0 +1,4 @@
+// OPTION: 2
+fun foo(n: Int): Int {
+ return n - 10
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt
new file mode 100644
index 00000000000..1436ff29b01
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt
@@ -0,0 +1,8 @@
+// OPTION: 1
+fun foo(n: Int) {
+ var m = n
+ do {
+ m--
+ println(m)
+ } while (m > 0)
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt.after
new file mode 100644
index 00000000000..f70074a7387
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt.after
@@ -0,0 +1,6 @@
+// OPTION: 1
+fun foo(n: Int) {
+ var m = n
+ m--
+ println(m)
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt
new file mode 100644
index 00000000000..2b8820078e9
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt
@@ -0,0 +1,6 @@
+// OPTION: 1
+fun foo(n: Int) {
+ for (k in 0..n) {
+ println(k)
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt.after
new file mode 100644
index 00000000000..73dec51eae0
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt.after
@@ -0,0 +1,4 @@
+// OPTION: 1
+fun foo(n: Int) {
+ println(k)
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt
new file mode 100644
index 00000000000..7ca52bb6790
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt
@@ -0,0 +1,8 @@
+// OPTION: 1
+fun foo(n: Int) {
+ var m = n
+ while (m > 0) {
+ m--
+ println(m)
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt.after
new file mode 100644
index 00000000000..f70074a7387
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt.after
@@ -0,0 +1,6 @@
+// OPTION: 1
+fun foo(n: Int) {
+ var m = n
+ m--
+ println(m)
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt
new file mode 100644
index 00000000000..9c7f402e5ad
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt
@@ -0,0 +1,12 @@
+// OPTION: 1
+fun foo(n: Int): Int {
+ if (n > 0) {
+ println("> 0")
+ n + 10
+ } else {
+ println("<= 0")
+ n - 10
+ }
+
+ return n
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt.after
new file mode 100644
index 00000000000..eeb88bdc504
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt.after
@@ -0,0 +1,7 @@
+// OPTION: 1
+fun foo(n: Int): Int {
+ println("> 0")
+ n + 10
+
+ return n
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt
new file mode 100644
index 00000000000..7a91c658fb3
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt
@@ -0,0 +1,10 @@
+// IS_APPLICABLE: false
+fun foo(n: Int): Int {
+ return if (n > 0) {
+ println("> 0")
+ n + 10
+ } else {
+ println("<= 0")
+ n - 10
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt
new file mode 100644
index 00000000000..340d3cf0916
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt
@@ -0,0 +1,8 @@
+// OPTION: 0
+fun foo(n: Int): Int {
+ return if (n > 0) {
+ n + 10
+ } else {
+ n - 10
+ }
+}
diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt.after
new file mode 100644
index 00000000000..fcb37fc6edb
--- /dev/null
+++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt.after
@@ -0,0 +1,4 @@
+// OPTION: 0
+fun foo(n: Int): Int {
+ return n + 10
+}
diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java
new file mode 100644
index 00000000000..c3a610bab7f
--- /dev/null
+++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.codeInsight.unwrap.Unwrapper;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.psi.PsiElement;
+import com.intellij.testFramework.LightCodeInsightTestCase;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.InTextDirectivesUtils;
+
+import java.io.File;
+import java.util.List;
+
+public abstract class AbstractUnwrapRemoveTest extends LightCodeInsightTestCase {
+ public void doTestThenUnwrapper(@NotNull String path) throws Exception {
+ doTest(path, KoitlinUnwrappers.KotlinThenUnwrapper.class);
+ }
+
+ public void doTestElseUnwrapper(@NotNull String path) throws Exception {
+ doTest(path, KoitlinUnwrappers.KotlinElseUnwrapper.class);
+ }
+
+ public void doTestElseRemover(@NotNull String path) throws Exception {
+ doTest(path, KoitlinUnwrappers.KotlinElseRemover.class);
+ }
+
+ public void doTestLoopUnwrapper(@NotNull String path) throws Exception {
+ doTest(path, KoitlinUnwrappers.KotlinLoopUnwrapper.class);
+ }
+
+ private void doTest(@NotNull String path, final Class extends Unwrapper> unwrapperClass) throws Exception {
+ configureByFile(path);
+
+ String fileText = FileUtil.loadFile(new File(path), true);
+
+ String isApplicableString = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// IS_APPLICABLE: ");
+ boolean isApplicableExpected = isApplicableString == null || isApplicableString.equals("true");
+
+ String option = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// OPTION: ");
+ Integer optionIndex = option != null ? Integer.parseInt(option) : 0;
+
+ List> unwrappersWithPsi =
+ new KotlinUnwrapDescriptor().collectUnwrappers(getProject(), getEditor(), getFile());
+
+ if (isApplicableExpected) {
+ Pair selectedUnwrapperWithPsi = unwrappersWithPsi.get(optionIndex);
+ assertEquals(unwrapperClass, selectedUnwrapperWithPsi.second.getClass());
+
+ selectedUnwrapperWithPsi.second.unwrap(getEditor(), selectedUnwrapperWithPsi.first);
+ checkResultByFile(path + ".after");
+ } else {
+ assertTrue(
+ ContainerUtil.and(unwrappersWithPsi, new Condition>() {
+ @Override
+ public boolean value(Pair pair) {
+ return pair.second.getClass() != unwrapperClass;
+ }
+ })
+ );
+ }
+ }
+
+ @NotNull
+ @Override
+ protected String getTestDataPath() {
+ return "";
+ }
+}
diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java
new file mode 100644
index 00000000000..f91dadce89a
--- /dev/null
+++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java
@@ -0,0 +1,125 @@
+/*
+ * 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 junit.framework.Assert;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import java.io.File;
+import java.util.regex.Pattern;
+import org.jetbrains.jet.JetTestUtils;
+import org.jetbrains.jet.test.InnerTestClasses;
+import org.jetbrains.jet.test.TestMetadata;
+
+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})
+public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest {
+ @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapThen")
+ public static class UnwrapThen extends AbstractUnwrapRemoveTest {
+ public void testAllFilesPresentInUnwrapThen() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapThen"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("thenCompoundInBlock.kt")
+ public void testThenCompoundInBlock() throws Exception {
+ doTestThenUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt");
+ }
+
+ @TestMetadata("thenCompoundInReturn.kt")
+ public void testThenCompoundInReturn() throws Exception {
+ doTestThenUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt");
+ }
+
+ @TestMetadata("thenSimpleInReturn.kt")
+ public void testThenSimpleInReturn() throws Exception {
+ doTestThenUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt");
+ }
+
+ }
+
+ @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapElse")
+ public static class UnwrapElse extends AbstractUnwrapRemoveTest {
+ public void testAllFilesPresentInUnwrapElse() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapElse"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("elseCompoundInBlock.kt")
+ public void testElseCompoundInBlock() throws Exception {
+ doTestElseUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt");
+ }
+
+ @TestMetadata("elseCompoundInReturn.kt")
+ public void testElseCompoundInReturn() throws Exception {
+ doTestElseUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt");
+ }
+
+ @TestMetadata("elseSimpleInReturn.kt")
+ public void testElseSimpleInReturn() throws Exception {
+ doTestElseUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt");
+ }
+
+ }
+
+ @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/removeElse")
+ public static class RemoveElse extends AbstractUnwrapRemoveTest {
+ public void testAllFilesPresentInRemoveElse() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/removeElse"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("else.kt")
+ public void testElse() throws Exception {
+ doTestElseRemover("idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt");
+ }
+
+ }
+
+ @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop")
+ public static class UnwrapLoop extends AbstractUnwrapRemoveTest {
+ public void testAllFilesPresentInUnwrapLoop() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("doWhile.kt")
+ public void testDoWhile() throws Exception {
+ doTestLoopUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt");
+ }
+
+ @TestMetadata("for.kt")
+ public void testFor() throws Exception {
+ doTestLoopUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt");
+ }
+
+ @TestMetadata("while.kt")
+ public void testWhile() throws Exception {
+ doTestLoopUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt");
+ }
+
+ }
+
+ public static Test suite() {
+ TestSuite suite = new TestSuite("UnwrapRemoveTestGenerated");
+ suite.addTestSuite(UnwrapThen.class);
+ suite.addTestSuite(UnwrapElse.class);
+ suite.addTestSuite(RemoveElse.class);
+ suite.addTestSuite(UnwrapLoop.class);
+ return suite;
+ }
+}