From 33fe3beffbcec70c42403d0988c7b0243dd7feaa Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 6 Jun 2012 22:17:10 +0200 Subject: [PATCH] IDEA-87069 Intentions: Convert ternary operator to if-else --- .../after.groovy.template | 5 + .../before.groovy.template | 1 + .../description.html | 8 + plugins/groovy/src/META-INF/plugin.xml | 5 + .../GroovyIntentionsBundle.properties | 2 + .../ReplaceTernaryWithIfElseIntention.java | 89 +++++++++++ .../ReplaceTernaryWithIfElseTest.groovy | 139 ++++++++++++++++++ 7 files changed, 249 insertions(+) create mode 100644 plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/after.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/before.groovy.template create mode 100644 plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/description.html create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ReplaceTernaryWithIfElseIntention.java create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ReplaceTernaryWithIfElseTest.groovy diff --git a/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/after.groovy.template new file mode 100644 index 000000000000..dbb65a09a183 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/after.groovy.template @@ -0,0 +1,5 @@ +if (a) { + return b +} else { + return c +} diff --git a/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/before.groovy.template new file mode 100644 index 000000000000..a608261b9224 --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/before.groovy.template @@ -0,0 +1 @@ +return a ? b : c diff --git a/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/description.html new file mode 100644 index 000000000000..4aa6efcca01c --- /dev/null +++ b/plugins/groovy/resources/intentionDescriptions/ReplaceTernaryWithIfElseIntention/description.html @@ -0,0 +1,8 @@ + + + +This intention replaces ternary statement with +an if else statement. + + + diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 55b29dccf347..7799ebd9c2c7 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -764,6 +764,11 @@ intention.category.groovy/intention.category.control.flow org.jetbrains.plugins.groovy.intentions.control.InvertIfIntention + + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle + intention.category.groovy/intention.category.control.flow + org.jetbrains.plugins.groovy.intentions.control.ReplaceTernaryWithIfElseIntention + org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle intention.category.groovy/intention.category.control.flow diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties index d6ad7e92ace5..8be6ee7e7993 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties @@ -45,6 +45,8 @@ split.if.intention.name=Split into 2 if's split.if.intention.family.name=Split into 2 if's invert.if.intention.name=Invert If Condition invert.if.intention.family.name=Invert If Condition +replace.ternary.with.if.else.intention.name=Replace ''?:'' with if else +replace.ternary.with.if.else.intention.family.name=Replace ''?:'' with if else flip.conditional.intention.name=Flip ''?:'' flip.conditional.intention.family.name=Flip Conditional conditional.to.elvis.intention.name=Convert Conditional to Elvis diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ReplaceTernaryWithIfElseIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ReplaceTernaryWithIfElseIntention.java new file mode 100644 index 000000000000..23d9c104f8cc --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ReplaceTernaryWithIfElseIntention.java @@ -0,0 +1,89 @@ +/* + * Copyright 2000-2012 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.plugins.groovy.intentions.control; + +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.intentions.base.Intention; +import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrBlockStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrIfStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression; + +/** + * @author Andreas Arledal + */ +public class ReplaceTernaryWithIfElseIntention extends Intention { + + @Override + protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException { + + GrConditionalExpression parentTernary = findTernary(element); + GroovyPsiElementFactory groovyPsiElementFactory = GroovyPsiElementFactory.getInstance(project); + + GrReturnStatement parentReturn = (GrReturnStatement)parentTernary.getParent(); + + GrIfStatement ifStatement = (GrIfStatement)groovyPsiElementFactory.createStatementFromText("if (" + + parentTernary.getCondition().getText() + + ") { \nreturn " + + parentTernary.getThenBranch().getText() + + "\n} else {\n return " + + parentTernary.getElseBranch().getText() + + "\n}"); + ifStatement = parentReturn.replaceWithStatement(ifStatement); + editor.getCaretModel().moveToOffset(ifStatement.getRParenth().getTextRange().getEndOffset()); + + + } + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new PsiElementPredicate() { + @Override + public boolean satisfiedBy(PsiElement element) { + GrConditionalExpression ternary = findTernary(element); + if (ternary == null || element == null || ternary.getThenBranch() == null || ternary.getElseBranch() == null) { + return false; + } + if (!(ternary.getParent() instanceof GrReturnStatement)) { + return false; + } + return true; + } + }; + } + + private static GrConditionalExpression findTernary(PsiElement element) { + GrConditionalExpression ternary = PsiTreeUtil.getParentOfType(element, GrConditionalExpression.class); + if (ternary == null) { + GrReturnStatement ret = PsiTreeUtil.getParentOfType(element, GrReturnStatement.class); + if (ret != null && ret.getReturnValue() instanceof GrConditionalExpression) { + ternary = (GrConditionalExpression)ret.getReturnValue(); + } + } + return ternary; + } +} diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ReplaceTernaryWithIfElseTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ReplaceTernaryWithIfElseTest.groovy new file mode 100644 index 000000000000..76ebf65914d2 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ReplaceTernaryWithIfElseTest.groovy @@ -0,0 +1,139 @@ +/* + * Copyright 2000-2012 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.plugins.groovy.intentions + +/** + * @author Andreas Arledal + */ +class ReplaceTernaryWithIfElseTest extends GrIntentionTestCase { + + String intentionName = GroovyIntentionsBundle.message("replace.ternary.with.if.else.intention.name") + +// public void testDoNotTriggerOnIncompleteIf() throws Exception { +// doAntiTest ''' +//if () { +// succes +//} else { +// no_succes +//} +//''', intentionName +// +// } + + public void testDoNotTriggerOnIncompleteTernary() throws Exception { + doAntiTest ''' +return aaa ? bbb +''', intentionName + } + + private void doTest(String before, String after) { + + doTextTest before, intentionName, after + } + + public void testSimpleCondition() throws Exception { + + doTest ''' +return aaa ? bbb : ccc +''', '''\ +if (aaa) { + return bbb +} else { + return ccc +} +''' + } + + public void testCaretAfterQuestionMark() throws Exception { + + doTest ''' +return aaa ? bbb : ccc +''', '''\ +if (aaa) { + return bbb +} else { + return ccc +} +''' + } + + public void testCaretInfrontOfConditional() throws Exception { + + doTest ''' +return aaa ? bbb : ccc +''', '''\ +if (aaa) { + return bbb +} else { + return ccc +} +''' + } + + public void testCaretInfrontOfElse() throws Exception { + + doTest ''' +return aaa ? bbb : ccc +''', '''\ +if (aaa) { + return bbb +} else { + return ccc +} +''' + } + + public void testCaretAfterElse() throws Exception { + + doTest ''' +return aaa ? bbb : ccc +''', '''\ +if (aaa) { + return bbb +} else { + return ccc +} +''' + } + + public void testCaretBeforeElseReturn() throws Exception { + + doTest ''' +return aaa ? bbb : ccc +''', '''\ +if (aaa) { + return bbb +} else { + return ccc +} +''' + } + + public void testCaretBeforeReturnStatement() throws Exception { + + doTest ''' +return aaa ? bbb : ccc +''', '''\ +if (aaa) { + return bbb +} else { + return ccc +} +''' + } + + +}