diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index e2657f13115..77918af1f81 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -254,17 +254,9 @@ public class JetPsiFactory { return (JetBinaryExpression) createExpression(project, lhs + " " + op + " " + rhs); } - @SuppressWarnings("ConstantConditions") @NotNull public static JetBinaryExpression createBinaryExpression(Project project, @NotNull JetExpression lhs, @NotNull String op, @NotNull JetExpression rhs) { - JetBinaryExpression assignment = createBinaryExpression(project, "_", op, "_"); - - assert assignment.getRight() != null; - - assignment = (JetBinaryExpression)assignment.getLeft().replace(lhs).getParent(); - assignment = (JetBinaryExpression)assignment.getRight().replace(rhs).getParent(); - - return assignment; + return createBinaryExpression(project, lhs.getText(), op, rhs.getText()); } public static JetTypeCodeFragment createTypeCodeFragment(Project project, String text, PsiElement context) { @@ -280,15 +272,9 @@ public class JetPsiFactory { return (JetIsExpression) createExpression(project, lhs + " " + (negated ? "!is" : "is") + " " + rhs); } - @SuppressWarnings("ConstantConditions") @NotNull public static JetIsExpression createIsExpression(Project project, @NotNull JetExpression lhs, @NotNull JetTypeReference rhs, boolean negated) { - JetIsExpression isExpression = createIsExpression(project, "_", "_", negated); - - isExpression = (JetIsExpression)isExpression.getLeftHandSide().replace(lhs).getParent(); - isExpression = (JetIsExpression)isExpression.getTypeRef().replace(rhs).getParent(); - - return isExpression; + return createIsExpression(project, lhs.getText(), rhs.getText(), negated); } @NotNull @@ -296,65 +282,84 @@ public class JetPsiFactory { return (JetReturnExpression) createExpression(project, "return " + text); } - @SuppressWarnings("ConstantConditions") @NotNull public static JetReturnExpression createReturn(Project project, @NotNull JetExpression expression) { - JetReturnExpression returnExpr = createReturn(project, "_"); - - assert returnExpr.getReturnedExpression() != null; - - return (JetReturnExpression)returnExpr.getReturnedExpression().replace(expression).getParent(); + return createReturn(project, expression.getText()); } @NotNull - public static JetIfExpression createIf( - Project project, - @NotNull String condText, @NotNull String thenText, @Nullable String elseText, - boolean thenNewLine, boolean elseNewLine) { - String thenSpace = thenNewLine ? "\n" : " "; - String elseSpace = elseNewLine ? "\n" : " "; - return (JetIfExpression) createExpression(project, "if (" + condText + ")" + thenSpace + thenText + (elseText != null ? elseSpace + "else " + elseText : "")); + public static JetIfExpression createIf(Project project, + @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr) { + return (JetIfExpression) createExpression(project, JetPsiUnparsingUtils.toIf(condition, thenExpr, elseExpr)); } - @SuppressWarnings("ConstantConditions") - @NotNull - public static JetIfExpression createIf( - Project project, - @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr, - boolean thenNewLine, boolean elseNewLine) { - JetIfExpression ifExpr = createIf(project, "_", "_", elseExpr != null ? "_" : null, thenNewLine, elseNewLine); + public static class IfChainBuilder { + private final StringBuilder sb = new StringBuilder(); + private boolean first = true; + private boolean frozen = false; - assert ifExpr.getCondition() != null; - assert ifExpr.getThen() != null; - assert elseExpr == null || ifExpr.getElse() != null; - - ifExpr = (JetIfExpression)ifExpr.getCondition().replace(condition).getParent().getParent(); - ifExpr = (JetIfExpression)ifExpr.getThen().replace(thenExpr).getParent().getParent(); - if (elseExpr != null) { - ifExpr = (JetIfExpression)ifExpr.getElse().replace(elseExpr).getParent().getParent(); + public IfChainBuilder() { } - return ifExpr; + @NotNull + public IfChainBuilder ifBranch(@NotNull String conditionText, @NotNull String expressionText) { + if (first) { + first = false; + } else { + sb.append("else "); + } + + sb.append("if (").append(conditionText).append(") ").append(expressionText).append("\n"); + return this; + } + + @NotNull + public IfChainBuilder ifBranch(@NotNull JetExpression condition, @NotNull JetExpression expression) { + return ifBranch(condition.getText(), expression.getText()); + } + + @NotNull + public IfChainBuilder elseBranch(@NotNull String expressionText) { + sb.append("else ").append(expressionText); + return this; + } + + @NotNull + public IfChainBuilder elseBranch(@NotNull JetExpression expression) { + return elseBranch(expression.getText()); + } + + @NotNull + public JetIfExpression toExpression(Project project) { + if (!frozen) { + frozen = true; + } + return (JetIfExpression) createExpression(project, sb.toString()); + } } - public static class WhenTemplateBuilder { + public static class WhenBuilder { private final StringBuilder sb = new StringBuilder("when "); private boolean frozen = false; private boolean inCondition = false; - public WhenTemplateBuilder(boolean addSubject) { - if (addSubject) { - sb.append("(_) "); + public WhenBuilder() { + this((String)null); + } + + public WhenBuilder(@Nullable String subjectText) { + if (subjectText != null) { + sb.append("(").append(subjectText).append(") "); } sb.append("{\n"); } - private void finishAndFreeze() { - sb.append("else -> _\n}"); - frozen = true; + public WhenBuilder(@Nullable JetExpression subject) { + this(subject != null ? subject.getText() : null); } - private WhenTemplateBuilder addCondition(String text) { + @NotNull + public WhenBuilder condition(@NotNull String text) { assert !frozen; if (!inCondition) { @@ -367,84 +372,95 @@ public class JetPsiFactory { return this; } - public WhenTemplateBuilder addBranchWithSingleCondition() { - assert !frozen; - - sb.append("_ -> _\n"); - - return this; + @NotNull + public WhenBuilder condition(@NotNull JetExpression expression) { + return condition(expression.getText()); } - public WhenTemplateBuilder addBranchesWithSingleCondition(int count) { - for (int i = 0; i < count; i++) { - addBranchWithSingleCondition(); - } - - return this; + @NotNull + public WhenBuilder pattern(@NotNull String typeReferenceText, boolean negated) { + return condition((negated ? "!is" : "is") + " " + typeReferenceText); } - public WhenTemplateBuilder addBranchWithMultiCondition(int conditionCount) { - assert !frozen; - assert conditionCount > 0; - - sb.append("_"); - for (int i = 0; i < conditionCount - 1; i++) { - sb.append(", _"); - } - sb.append(" -> _\n"); - - return this; + @NotNull + public WhenBuilder pattern(@NotNull JetTypeReference typeReference, boolean negated) { + return pattern(typeReference.getText(), negated); } - public WhenTemplateBuilder addExpressionCondition() { - return addCondition("_"); + @NotNull + public WhenBuilder range(@NotNull String argumentText, boolean negated) { + return condition((negated ? "!in" : "in") + " " + argumentText); } - public WhenTemplateBuilder addIsCondition(boolean negated) { - return addCondition((negated ? "!is" : "is") + " _"); + @NotNull + public WhenBuilder range(@NotNull JetExpression argument, boolean negated) { + return range(argument.getText(), negated); } - public WhenTemplateBuilder addInCondition(boolean negated) { - return addCondition((negated ? "!in" : "in") + " _"); - } - - public WhenTemplateBuilder finishBranch() { + @NotNull + public WhenBuilder branchExpression(@NotNull String expressionText) { assert !frozen; assert inCondition; inCondition = false; - sb.append(" -> _\n"); + sb.append(" -> ").append(expressionText).append("\n"); return this; } + @NotNull + public WhenBuilder branchExpression(@NotNull JetExpression expression) { + return branchExpression(expression.getText()); + } + + @NotNull + public WhenBuilder entry(@NotNull String entryText) { + assert !frozen; + assert !inCondition; + + sb.append(entryText).append("\n"); + + return this; + } + + @NotNull + public WhenBuilder entry(@NotNull JetWhenEntry whenEntry) { + return entry(whenEntry.getText()); + } + + @NotNull + public WhenBuilder elseEntry(@NotNull String text) { + return entry("else -> " + text); + } + + @NotNull + public WhenBuilder elseEntry(@NotNull JetExpression expression) { + return elseEntry(expression.getText()); + } + + @NotNull public JetWhenExpression toExpression(Project project) { if (!frozen) { - finishAndFreeze(); + sb.append("}"); + frozen = true; } return (JetWhenExpression) createExpression(project, sb.toString()); } } - public static JetWhenExpression createWhenWithoutSubject(Project project, int positiveBranchCount) { - return new WhenTemplateBuilder(false).addBranchesWithSingleCondition(positiveBranchCount).toExpression(project); - } - + @NotNull public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull String text) { - return (JetParenthesizedExpression)createExpression(project, "(" + text + ")"); + return (JetParenthesizedExpression) createExpression(project, "(" + text + ")"); } - @SuppressWarnings("ConstantConditions") + @NotNull public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull JetExpression expression) { - JetParenthesizedExpression parenthesizedExpression = createParenthesizedExpression(project, "_"); - parenthesizedExpression.getExpression().replace(expression); - - return parenthesizedExpression; + return createParenthesizedExpression(project, expression.getText()); } + @NotNull public static JetParenthesizedExpression createParenthesizedExpressionIfNeeded(Project project, @NotNull JetExpression expression) { return (expression instanceof JetParenthesizedExpression) ? - (JetParenthesizedExpression) expression : - createParenthesizedExpression(project, expression); + (JetParenthesizedExpression) expression : createParenthesizedExpression(project, expression); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java new file mode 100644 index 00000000000..7995a3fbab2 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java @@ -0,0 +1,59 @@ +/* + * 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.lang.psi; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class JetPsiUnparsingUtils { + private JetPsiUnparsingUtils() { + } + + @NotNull + public static String toIf(@NotNull JetExpression condition, @NotNull JetExpression thenExpression, @Nullable JetExpression elseExpression) { + return toIf(condition.getText(), thenExpression.getText(), elseExpression != null ? elseExpression.getText() : null); + } + + @NotNull + public static String toIf(@NotNull String condition, @NotNull String thenExpression, @Nullable String elseExpression) { + return "if " + parenthesizeTextIfNeeded(condition) + " " + thenExpression + (elseExpression != null ? " else " + elseExpression : ""); + } + + @NotNull + public static String toBinaryExpression(@NotNull JetExpression left, @NotNull String op, @NotNull JetElement right) { + return toBinaryExpression(left.getText(), op, right.getText()); + } + + @NotNull + public static String toBinaryExpression(@NotNull String left, @NotNull String op, @NotNull String right) { + return left + " " + op + " " + right; + } + + @NotNull + public static String parenthesizeIfNeeded(@NotNull JetExpression expression) { + String text = expression.getText(); + return (expression instanceof JetParenthesizedExpression || + expression instanceof JetConstantExpression || + expression instanceof JetSimpleNameExpression) + ? text : "(" + text + ")"; + } + + @NotNull + public static String parenthesizeTextIfNeeded(@NotNull String expressionText) { + return (expressionText.startsWith("(") && expressionText.endsWith(")")) ? expressionText : "(" + expressionText + ")"; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index e5c880dc45b..5d5612fa35e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -683,6 +683,16 @@ public class JetPsiUtil { return false; } + public static > C getBlockVariableDeclarations(@NotNull JetBlockExpression block, @NotNull C collection) { + for (JetElement element : block.getStatements()) { + if (element instanceof JetVariableDeclaration) { + collection.add((JetVariableDeclaration) element); + } + } + + return collection; + } + public static boolean checkWhenExpressionHasSingleElse(JetWhenExpression whenExpression) { int elseCount = 0; for (JetWhenEntry entry : whenExpression.getEntries()) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index 402a4094cae..ca8dc54d57f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -47,6 +47,7 @@ public class BranchedFoldingUtils { } if (assignment.getParent() instanceof JetBlockExpression) { + //noinspection ConstantConditions return !JetPsiUtil.checkVariableDeclarationInBlock((JetBlockExpression) assignment.getParent(), assignment.getLeft().getText()); } @@ -239,7 +240,7 @@ public class BranchedFoldingUtils { assertNotNull(elseRoot); //noinspection ConstantConditions - JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot, false, false); + JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, newIfExpression); newIfExpression = (JetIfExpression)newReturnExpression.getReturnedExpression(); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index f680d7524ac..e713c50468a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -35,11 +35,10 @@ public class BranchedUnfoldingUtils { if (JetPsiUtil.isAssignment(root)) { JetBinaryExpression assignment = (JetBinaryExpression)root; - JetExpression lhs = assignment.getLeft(); + + assertNotNull(assignment.getLeft()); + JetExpression rhs = assignment.getRight(); - - if (!(lhs instanceof JetSimpleNameExpression)) return null; - if (rhs instanceof JetIfExpression) return UnfoldableKind.ASSIGNMENT_TO_IF; if (rhs instanceof JetWhenExpression) return UnfoldableKind.ASSIGNMENT_TO_WHEN; } else if (root instanceof JetReturnExpression) { @@ -75,6 +74,7 @@ public class BranchedUnfoldingUtils { assertNotNull(thenExpr); assertNotNull(elseExpr); + //noinspection ConstantConditions thenExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, thenExpr)); elseExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, elseExpr)); @@ -97,6 +97,7 @@ public class BranchedUnfoldingUtils { assertNotNull(currExpr); + //noinspection ConstantConditions currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java deleted file mode 100644 index 73a94d72bc5..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetExpression; - -public class GuardedExpression { - @NotNull - private final JetExpression condition; - - @NotNull - private final JetExpression baseExpression; - - public GuardedExpression(@NotNull JetExpression condition, @NotNull JetExpression baseExpression) { - this.condition = condition; - this.baseExpression = baseExpression; - } - - @NotNull - public JetExpression getCondition() { - return condition; - } - - @NotNull - public JetExpression getBaseExpression() { - return baseExpression; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java index 08e220ee152..020a7076f0b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java @@ -1,6 +1,5 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; -import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; @@ -8,6 +7,8 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.ArrayList; import java.util.List; +import static org.jetbrains.jet.lang.psi.JetPsiUnparsingUtils.*; + public class IfWhenUtils { public static final String TRANSFORM_WITHOUT_CHECK = @@ -71,8 +72,7 @@ public class IfWhenUtils { } public static void transformIfToWhen(@NotNull JetIfExpression ifExpression) { - List positiveBranches = new ArrayList(); - JetExpression elseExpression = null; + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(); JetIfExpression currIfExpression = ifExpression; do { @@ -84,123 +84,73 @@ public class IfWhenUtils { assertNotNull(thenBranch); assertNotNull(elseBranch); + List orBranches = splitExpressionToOrBranches(condition); + for (JetExpression orBranch : orBranches) { + builder.condition(orBranch); + } //noinspection ConstantConditions - positiveBranches.add(new MultiGuardedExpression(splitExpressionToOrBranches(condition), thenBranch)); + builder.branchExpression(thenBranch); if (elseBranch instanceof JetIfExpression) { currIfExpression = (JetIfExpression) elseBranch; } else { currIfExpression = null; - elseExpression = elseBranch; + //noinspection ConstantConditions + builder.elseEntry(elseBranch); } } while (currIfExpression != null); - JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(false); - for (MultiGuardedExpression positiveBranch : positiveBranches) { - builder.addBranchWithMultiCondition(positiveBranch.getConditions().size()); - } - - JetWhenExpression whenExpression = builder.toExpression(ifExpression.getProject()); - - int i = 0; - List entries = whenExpression.getEntries(); - for (JetWhenEntry entry : entries) { - if (entry.isElse()) { - //noinspection ConstantConditions - entry.getExpression().replace(elseExpression); - break; - } - - MultiGuardedExpression branch = positiveBranches.get(i++); - - //noinspection ConstantConditions - entry.getExpression().replace(branch.getBaseExpression()); - - int j = 0; - JetWhenCondition[] conditions = entry.getConditions(); - for (JetWhenCondition condition : conditions) { - assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; - - JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); - assertNotNull(conditionExpression); - - //noinspection ConstantConditions - conditionExpression.replace(branch.getConditions().get(j++)); - } - } - - ifExpression.replace(whenExpression); + ifExpression.replace(builder.toExpression(ifExpression.getProject())); } - @SuppressWarnings("ConstantConditions") - private static JetExpression combineWhenConditions(Project project, JetWhenCondition[] conditions, JetExpression subject) { + private static String combineWhenConditions(JetWhenCondition[] conditions, JetExpression subject) { int n = conditions.length; - assert n > 0 : TRANSFORM_WITHOUT_CHECK; + if (n == 0) return ""; - JetWhenCondition condition = conditions[n - 1]; + JetWhenCondition condition = conditions[0]; assert condition != null : TRANSFORM_WITHOUT_CHECK; - JetExpression resultExpr = WhenUtils.whenConditionToExpression(condition, subject); + StringBuilder sb = new StringBuilder(); + + String text = WhenUtils.whenConditionToExpressionText(condition, subject); if (n > 1) { - resultExpr = JetPsiFactory.createParenthesizedExpressionIfNeeded(project, resultExpr); + text = parenthesizeTextIfNeeded(text); } + sb.append(text); - for (int i = n - 2; i >= 0; i--) { + for (int i = 1; i < n; i++) { JetWhenCondition currCondition = conditions[i]; - assert currCondition != null : TRANSFORM_WITHOUT_CHECK; - resultExpr = JetPsiFactory.createBinaryExpression( - project, - JetPsiFactory.createParenthesizedExpressionIfNeeded(project, WhenUtils.whenConditionToExpression(currCondition, subject)), - "||", - resultExpr); + sb.append(" || ").append(parenthesizeTextIfNeeded(WhenUtils.whenConditionToExpressionText(currCondition, subject))); } - return resultExpr; + return sb.toString(); } public static void transformWhenToIf(@NotNull JetWhenExpression whenExpression) { - Project project = whenExpression.getProject(); - - JetExpression elseExpression = null; - List positiveBranches = new ArrayList(); + JetPsiFactory.IfChainBuilder builder = new JetPsiFactory.IfChainBuilder(); List entries = whenExpression.getEntries(); for (JetWhenEntry entry : entries) { JetExpression branch = entry.getExpression(); - assertNotNull(branch); if (entry.isElse()) { - elseExpression = branch; + //noinspection ConstantConditions + builder.elseBranch(branch); } else { - JetExpression branchCondition = combineWhenConditions(project, entry.getConditions(), whenExpression.getSubjectExpression()); - JetExpression branchExpression = entry.getExpression(); + String branchConditionText = combineWhenConditions(entry.getConditions(), whenExpression.getSubjectExpression()); + JetExpression branchExpression = entry.getExpression(); assertNotNull(branchExpression); //noinspection ConstantConditions - positiveBranches.add(new GuardedExpression(branchCondition, branchExpression)); + builder.ifBranch(branchConditionText, branchExpression.getText()); } } - assertNotNull(elseExpression); - assert !positiveBranches.isEmpty() : TRANSFORM_WITHOUT_CHECK; - - JetExpression outerExpression = elseExpression; - - for (int i = positiveBranches.size() - 1; i >= 0; i--) { - GuardedExpression branch = positiveBranches.get(i); - - outerExpression = JetPsiFactory.createIf( - project, - branch.getCondition(), branch.getBaseExpression(), outerExpression, - !(branch.getBaseExpression() instanceof JetBlockExpression), !(outerExpression instanceof JetBlockExpression)); - } - - //noinspection ConstantConditions - whenExpression.replace(outerExpression); + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java deleted file mode 100644 index 7e7c312cbfd..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetExpression; - -import java.util.List; - -public class MultiGuardedExpression { - @NotNull - private final List conditions; - - @NotNull - private final JetExpression baseExpression; - - public MultiGuardedExpression(@NotNull List conditions, @NotNull JetExpression baseExpression) { - this.conditions = conditions; - this.baseExpression = baseExpression; - } - - @NotNull - public List getConditions() { - return conditions; - } - - @NotNull - public JetExpression getBaseExpression() { - return baseExpression; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index a40291df86f..b17bd974abc 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -1,11 +1,12 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; -import com.intellij.openapi.project.Project; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; +import static org.jetbrains.jet.lang.psi.JetPsiUnparsingUtils.*; + import java.util.List; public class WhenUtils { @@ -87,7 +88,6 @@ public class WhenUtils { public static void flattenWhen(@NotNull JetWhenExpression whenExpression) { JetExpression subjectExpression = whenExpression.getSubjectExpression(); - boolean hasSubject = subjectExpression != null; JetExpression elseBranch = JetPsiUtil.getWhenElseBranch(whenExpression); assert elseBranch instanceof JetWhenExpression : TRANSFORM_WITHOUT_CHECK; @@ -97,38 +97,36 @@ public class WhenUtils { List outerEntries = whenExpression.getEntries(); List innerEntries = nestedWhenExpression.getEntries(); - JetWhenExpression newWhenExpression = new JetPsiFactory.WhenTemplateBuilder(hasSubject) - .addBranchesWithSingleCondition(outerEntries.size() + innerEntries.size() - 2) - .toExpression(whenExpression.getProject()); + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(subjectExpression); - if (hasSubject) { - JetExpression dummySubjectExpression = newWhenExpression.getSubjectExpression(); - assertNotNull(dummySubjectExpression); - - //noinspection ConstantConditions - dummySubjectExpression.replace(subjectExpression); - } - - List newEntries = newWhenExpression.getEntries(); - - int i = 0; for (JetWhenEntry entry : outerEntries) { - if (!entry.isElse()) { - newEntries.get(i++).replace(entry); - } - } - for (JetWhenEntry entry : innerEntries) { - newEntries.get(i++).replace(entry); + if (entry.isElse()) continue; + + builder.entry(entry); } - whenExpression.replace(newWhenExpression); + for (JetWhenEntry entry : innerEntries) { + builder.entry(entry); + } + + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } - private static JetWhenExpression createWhenTemplateWithSubject(@NotNull JetWhenExpression whenExpression) { - JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(true); + public static void introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { + JetExpression subject = getWhenSubjectCandidate(whenExpression); + assertNotNull(subject); + + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(subject); for (JetWhenEntry entry : whenExpression.getEntries()) { - if (entry.isElse()) continue; + JetExpression branchExpression = entry.getExpression(); + assertNotNull(branchExpression); + + if (entry.isElse()) { + //noinspection ConstantConditions + builder.elseEntry(branchExpression); + continue; + } for (JetWhenCondition condition : entry.getConditions()) { assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; @@ -136,81 +134,13 @@ public class WhenUtils { JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); if (conditionExpression instanceof JetIsExpression) { - builder.addIsCondition(((JetIsExpression) conditionExpression).isNegated()); - } - else if (conditionExpression instanceof JetBinaryExpression) { - JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; + JetIsExpression isExpression = (JetIsExpression) conditionExpression; - IElementType op = binaryExpression.getOperationToken(); - if (op == JetTokens.IN_KEYWORD) { - builder.addInCondition(false); - } - else if (op == JetTokens.NOT_IN) { - builder.addInCondition(true); - } - else if (op == JetTokens.EQEQ) { - builder.addExpressionCondition(); - } - else assert false : TRANSFORM_WITHOUT_CHECK; - } - else assert false : TRANSFORM_WITHOUT_CHECK; - } - - builder.finishBranch(); - } - - return builder.toExpression(whenExpression.getProject()); - } - - public static void introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { - JetExpression subject = getWhenSubjectCandidate(whenExpression); - assertNotNull(subject); - - JetWhenExpression newWhenExpression = createWhenTemplateWithSubject(whenExpression); - - JetExpression newSubject = newWhenExpression.getSubjectExpression(); - assertNotNull(newSubject); - - //noinspection ConstantConditions - newSubject.replace(subject); - - int i = 0; - List entries = whenExpression.getEntries(); - List newEntries = newWhenExpression.getEntries(); - for (JetWhenEntry newEntry : newEntries) { - JetWhenEntry entry = entries.get(i++); - - JetExpression branchExpression = entry.getExpression(); - assertNotNull(branchExpression); - - JetExpression newBranchExpression = newEntry.getExpression(); - assertNotNull(newBranchExpression); - - //noinspection ConstantConditions - newBranchExpression.replace(branchExpression); - - int j = 0; - JetWhenCondition[] conditions = entry.getConditions(); - JetWhenCondition[] newConditions = newEntry.getConditions(); - - for (JetWhenCondition newCondition : newConditions) { - JetWhenCondition condition = conditions[j++]; - - assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; - - JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); - - if (conditionExpression instanceof JetIsExpression) { - assert newCondition instanceof JetWhenConditionIsPattern : TRANSFORM_WITHOUT_CHECK; - - JetTypeReference typeReference = ((JetIsExpression) conditionExpression).getTypeRef(); + JetTypeReference typeReference = isExpression.getTypeRef(); assertNotNull(typeReference); - JetTypeReference newTypeReference = ((JetWhenConditionIsPattern) newCondition).getTypeRef(); - assertNotNull(newTypeReference); - //noinspection ConstantConditions - newTypeReference.replace(typeReference); + builder.pattern(typeReference, isExpression.isNegated()); } else if (conditionExpression instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; @@ -219,48 +149,31 @@ public class WhenUtils { assertNotNull(rhs); IElementType op = binaryExpression.getOperationToken(); - if (op == JetTokens.IN_KEYWORD || op == JetTokens.NOT_IN) { - assert newCondition instanceof JetWhenConditionInRange : TRANSFORM_WITHOUT_CHECK; - - JetExpression newRangeExpression = ((JetWhenConditionInRange) newCondition).getRangeExpression(); - assertNotNull(newRangeExpression); - + if (op == JetTokens.IN_KEYWORD) { //noinspection ConstantConditions - newRangeExpression.replace(rhs); + builder.range(rhs, false); + } + else if (op == JetTokens.NOT_IN) { + //noinspection ConstantConditions + builder.range(rhs, true); } else if (op == JetTokens.EQEQ) { - assert newCondition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; - - JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); - assertNotNull(newConditionExpression); - //noinspection ConstantConditions - newConditionExpression.replace(rhs); + builder.condition(rhs); } else assert false : TRANSFORM_WITHOUT_CHECK; } else assert false : TRANSFORM_WITHOUT_CHECK; } + + //noinspection ConstantConditions + builder.branchExpression(branchExpression); } - whenExpression.replace(newWhenExpression); + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } - private static JetWhenExpression createWhenTemplateWithoutSubject(@NotNull JetWhenExpression whenExpression) { - JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(false); - - for (JetWhenEntry entry : whenExpression.getEntries()) { - if (!entry.isElse()) { - builder.addBranchWithMultiCondition(entry.getConditions().length); - } - } - - return builder.toExpression(whenExpression.getProject()); - } - - static JetExpression whenConditionToExpression(@NotNull JetWhenCondition condition, JetExpression subject) { - Project project = condition.getProject(); - + static String whenConditionToExpressionText(@NotNull JetWhenCondition condition, JetExpression subject) { if (condition instanceof JetWhenConditionIsPattern) { JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition; @@ -270,7 +183,7 @@ public class WhenUtils { assertNotNull(subject); //noinspection ConstantConditions - return JetPsiFactory.createIsExpression(project, subject, typeReference, patternCondition.isNegated()); + return toBinaryExpression(subject, (patternCondition.isNegated() ? "!is" : "is"), typeReference); } if (condition instanceof JetWhenConditionInRange) { @@ -282,7 +195,7 @@ public class WhenUtils { assertNotNull(subject); //noinspection ConstantConditions - return JetPsiFactory.createBinaryExpression(project, subject, rangeCondition.getOperationReference().getText(), rangeExpression); + return toBinaryExpression(subject, rangeCondition.getOperationReference().getText(), rangeExpression); } assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; @@ -291,45 +204,36 @@ public class WhenUtils { assertNotNull(conditionExpression); //noinspection ConstantConditions - return subject != null ? JetPsiFactory.createBinaryExpression(project, subject, "==", conditionExpression) : conditionExpression; + return subject != null ? + toBinaryExpression(parenthesizeIfNeeded(subject), "==", parenthesizeIfNeeded(conditionExpression)) + : conditionExpression.getText(); } public static void eliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { JetExpression subject = whenExpression.getSubjectExpression(); assertNotNull(subject); - JetWhenExpression newWhenExpression = createWhenTemplateWithoutSubject(whenExpression); - - int i = 0; - List entries = whenExpression.getEntries(); - List newEntries = newWhenExpression.getEntries(); - for (JetWhenEntry newEntry : newEntries) { - JetWhenEntry entry = entries.get(i++); + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(); + for (JetWhenEntry entry : whenExpression.getEntries()) { JetExpression branchExpression = entry.getExpression(); assertNotNull(branchExpression); - JetExpression newBranchExpression = newEntry.getExpression(); - assertNotNull(newBranchExpression); + if (entry.isElse()) { + //noinspection ConstantConditions + builder.elseEntry(branchExpression); + + continue; + } + + for (JetWhenCondition condition : entry.getConditions()) { + builder.condition(whenConditionToExpressionText(condition, subject)); + } //noinspection ConstantConditions - newBranchExpression.replace(branchExpression); - - int j = 0; - JetWhenCondition[] conditions = entry.getConditions(); - JetWhenCondition[] newConditions = newEntry.getConditions(); - - for (JetWhenCondition newCondition : newConditions) { - JetWhenCondition condition = conditions[j++]; - - JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); - assertNotNull(newConditionExpression); - - //noinspection ConstantConditions - newConditionExpression.replace(whenConditionToExpression(condition, subject)); - } + builder.branchExpression(branchExpression); } - whenExpression.replace(newWhenExpression); + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } } diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after index 83a1dee18ec..d31b98306dd 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { return when (n) { - 1 -> "one" - else -> "two" + 1 -> "one" + else -> "two" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt index 1c9b980257f..73a8c4fa415 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt @@ -1,11 +1,12 @@ fun test(n: Int): String { when(n) { - 1 -> { - println("***") - return "one" - } - else -> { - println("***") - return "two" + 1 -> { + println("***") + return "one" + } + else -> { + println("***") + return "two" + } } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after index 5565cdc2ecd..e90363e53dd 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after @@ -1,11 +1,12 @@ fun test(n: Int): String { return when(n) { - 1 -> { - println("***") - "one" - } - else -> { - println("***") - "two" + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after index 47fca307d3c..6a8e28bb851 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n == 0) - "zero" - else if (n == 1) - "one" - else if (n == 2) - "two" + return if (n == 0) "zero" + else if (n == 1) "one" + else if (n == 2) "two" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after index 1b1e1a0b2b8..677a6a448e5 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if ((n < 0) || (n > 1000)) - "unknown" - else if (n <= 10) - "small" - else if (n <= 100) - "average" + return if ((n < 0) || (n > 1000)) "unknown" + else if (n <= 10) "small" + else if (n <= 100) "average" else "big" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after index 0fbe8294ffb..4abebde0ef2 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after @@ -1,9 +1,6 @@ fun test(obj: Any): String { - return if (obj !is Iterable<*>) - "not iterable" - else if (obj !is Collection<*>) - "not collection" - else if (obj !is MutableCollection<*>) - "not mutable collection" + return if (obj !is Iterable<*>) "not iterable" + else if (obj !is Collection<*>) "not collection" + else if (obj !is MutableCollection<*>) "not mutable collection" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after index 9e02b8d24f7..d550d564769 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n !in 0..1000) - "unknown" - else if (n !in 0..100) - "big" - else if (n !in 0..10) - "average" + return if (n !in 0..1000) "unknown" + else if (n !in 0..100) "big" + else if (n !in 0..10) "average" else "small" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after index af99f2543d2..ac6b419228f 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after @@ -1,9 +1,6 @@ fun test(obj: Any): String { - return if (obj is String) - "string" - else if (obj is Int) - "int" - else if (obj is Class<*>) - "class" + return if (obj is String) "string" + else if (obj is Int) "int" + else if (obj is Class<*>) "class" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after index d2d1cb0f735..9e5e951468e 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n in 0..10) - "small" - else if (n in 10..100) - "average" - else if (n in 100..1000) - "big" + return if (n in 0..10) "small" + else if (n in 10..100) "average" + else if (n in 100..1000) "big" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after index 41ed971402b..9e918445401 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if ((n in 0..5) || (n in 5..10)) - "small" - else if ((n in 10..50) || (n in 50..100)) - "average" - else if ((n in 100..500) || (n in 500..1000)) - "big" + return if ((n in 0..5) || (n in 5..10)) "small" + else if ((n in 10..50) || (n in 50..100)) "average" + else if ((n in 100..500) || (n in 500..1000)) "big" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after index d2d1cb0f735..9e5e951468e 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n in 0..10) - "small" - else if (n in 10..100) - "average" - else if (n in 100..1000) - "big" + return if (n in 0..10) "small" + else if (n in 10..100) "average" + else if (n in 100..1000) "big" else "unknown" } \ No newline at end of file