Implement Unwrap/Remove for conditionals and loops

This commit is contained in:
Alexey Sedunov
2013-06-18 17:21:50 +04:00
parent fa01d59ef8
commit 8964e0e152
28 changed files with 618 additions and 2 deletions
@@ -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) {
+1
View File
@@ -124,6 +124,7 @@
implementationClass="org.jetbrains.jet.plugin.codeInsight.surroundWith.expression.KotlinExpressionSurroundDescriptor"/>
<lang.surroundDescriptor language="jet"
implementationClass="org.jetbrains.jet.plugin.codeInsight.surroundWith.statement.KotlinStatementSurroundDescriptor"/>
<lang.unwrapDescriptor language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.unwrap.KotlinUnwrapDescriptor"/>
<quoteHandler fileType="Kotlin" className="org.jetbrains.jet.plugin.editor.KotlinQuoteHandler"/>
<refactoring.moveHandler implementation="org.jetbrains.jet.plugin.refactoring.move.JetMoveFilesOrDirectoriesHandler"/>
<refactoring.copyHandler implementation="org.jetbrains.jet.plugin.refactoring.copy.JetCopyClassHandler"/>
@@ -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}''
@@ -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;
}
}
}
@@ -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);
}
}
@@ -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"),
};
}
}
@@ -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<KotlinUnwrapRemoveBase.Context> {
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<JetElement> 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();
}
}
@@ -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) + "...";
}
@@ -0,0 +1,8 @@
// OPTION: 1
fun foo(n: Int): Int {
return if (n > 0) {
n + 10
} <caret>else {
n - 10
}
}
@@ -0,0 +1,6 @@
// OPTION: 1
fun foo(n: Int): Int {
return if (n > 0) {
n + 10
<caret> }
}
@@ -0,0 +1,12 @@
// OPTION: 3
fun foo(n: Int): Int {
if (n > 0) {
println("> 0")
n + 10
} <caret>else {
println("<= 0")
n - 10
}
return n
}
@@ -0,0 +1,7 @@
// OPTION: 3
fun foo(n: Int): Int {
println("<= 0")
n - 10<caret>
return n
}
@@ -0,0 +1,10 @@
// IS_APPLICABLE: false
fun foo(n: Int): Int {
return if (n > 0) {
println("> 0")
n + 10
} <caret>else {
println("<= 0")
n - 10
}
}
@@ -0,0 +1,8 @@
// OPTION: 2
fun foo(n: Int): Int {
return if (n > 0) {
n + 10
} <caret>else {
n - 10
}
}
@@ -0,0 +1,4 @@
// OPTION: 2
fun foo(n: Int): Int {
return n - 10<caret>
}
@@ -0,0 +1,8 @@
// OPTION: 1
fun foo(n: Int) {
var m = n
<caret>do {
m--
println(m)
} while (m > 0)
}
@@ -0,0 +1,6 @@
// OPTION: 1
fun foo(n: Int) {
var m = n
<caret>m--
println(m)
}
@@ -0,0 +1,6 @@
// OPTION: 1
fun foo(n: Int) {
<caret>for (k in 0..n) {
println(k)
}
}
@@ -0,0 +1,4 @@
// OPTION: 1
fun foo(n: Int) {
<caret>println(k)
}
@@ -0,0 +1,8 @@
// OPTION: 1
fun foo(n: Int) {
var m = n
<caret>while (m > 0) {
m--
println(m)
}
}
@@ -0,0 +1,6 @@
// OPTION: 1
fun foo(n: Int) {
var m = n
<caret>m--
println(m)
}
@@ -0,0 +1,12 @@
// OPTION: 1
fun foo(n: Int): Int {
<caret>if (n > 0) {
println("> 0")
n + 10
} else {
println("<= 0")
n - 10
}
return n
}
@@ -0,0 +1,7 @@
// OPTION: 1
fun foo(n: Int): Int {
<caret>println("> 0")
n + 10
return n
}
@@ -0,0 +1,10 @@
// IS_APPLICABLE: false
fun foo(n: Int): Int {
return <caret>if (n > 0) {
println("> 0")
n + 10
} else {
println("<= 0")
n - 10
}
}
@@ -0,0 +1,8 @@
// OPTION: 0
fun foo(n: Int): Int {
return <caret>if (n > 0) {
n + 10
} else {
n - 10
}
}
@@ -0,0 +1,4 @@
// OPTION: 0
fun foo(n: Int): Int {
return <caret>n + 10
}
@@ -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<Pair<PsiElement, Unwrapper>> unwrappersWithPsi =
new KotlinUnwrapDescriptor().collectUnwrappers(getProject(), getEditor(), getFile());
if (isApplicableExpected) {
Pair<PsiElement, Unwrapper> 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<Pair<PsiElement, Unwrapper>>() {
@Override
public boolean value(Pair<PsiElement, Unwrapper> pair) {
return pair.second.getClass() != unwrapperClass;
}
})
);
}
}
@NotNull
@Override
protected String getTestDataPath() {
return "";
}
}
@@ -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;
}
}