diff --git a/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/after.groovy.template b/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/after.groovy.template
new file mode 100644
index 000000000000..0f413f682b3d
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/after.groovy.template
@@ -0,0 +1 @@
+return cond() : first() : second()
\ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/before.groovy.template b/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/before.groovy.template
new file mode 100644
index 000000000000..c9bf0d66b7d4
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/before.groovy.template
@@ -0,0 +1,6 @@
+if (cond()) {
+ return first()
+}
+else {
+ return second()
+}
\ No newline at end of file
diff --git a/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/description.html b/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/description.html
new file mode 100644
index 000000000000..e7e00ed842d9
--- /dev/null
+++ b/plugins/groovy/resources/intentionDescriptions/ReplaceIfWithTernaryIntention/description.html
@@ -0,0 +1,7 @@
+
+
+This intention replaces if-statement with equivalent ternary operator
+
+Text after this comment will not be shown in tooltips.
+
+
\ No newline at end of file
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 3fe8e1036cbf..c214cd7266aa 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -1019,6 +1019,11 @@
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
+ org.jetbrains.plugins.groovy.intentions.control.ReplaceIfWithTernaryIntention
+
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 61fc76ce81fe..6843488e0f99 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties
@@ -198,4 +198,6 @@ cannot.create.class=Cannot create class
gr.introduce.local.variable.intention.name=Introduce local variable
gr.introduce.local.variable.intention.family.name=Groovy Introduce local variable
flip.if.intention.name=Flip if statements
-flip.if.intention.family.name=Flip if statements
\ No newline at end of file
+flip.if.intention.family.name=Flip if statements
+replace.if.with.ternary.intention.name=Replace with ?:
+replace.if.with.ternary.intention.family.name=Replace if-statement with ternary operator
\ No newline at end of file
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ReplaceIfWithTernaryIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ReplaceIfWithTernaryIntention.java
new file mode 100644
index 000000000000..1ea8ce2d681a
--- /dev/null
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/ReplaceIfWithTernaryIntention.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2000-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.plugins.groovy.intentions.control;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.groovy.codeInspection.utils.EquivalenceChecker;
+import org.jetbrains.plugins.groovy.intentions.base.Intention;
+import org.jetbrains.plugins.groovy.intentions.base.PsiElementPredicate;
+import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
+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.branch.GrReturnStatement;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrAssignmentExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConditionalExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
+
+/**
+ * @author Max Medvedev
+ */
+public class ReplaceIfWithTernaryIntention extends Intention {
+ @Override
+ protected void processIntention(@NotNull PsiElement element, Project project, Editor editor) throws IncorrectOperationException {
+ final GrIfStatement ifStatement = (GrIfStatement)element.getParent();
+
+ final PsiElement thenBranch = skipBlock(ifStatement.getThenBranch());
+ final PsiElement elseBranch = skipBlock(ifStatement.getElseBranch());
+
+ if (thenBranch instanceof GrAssignmentExpression && elseBranch instanceof GrAssignmentExpression) {
+ final GrAssignmentExpression assignment = (GrAssignmentExpression)GroovyPsiElementFactory.getInstance(project).createStatementFromText("a = b ? c : d");
+
+ assignment.getLValue().replaceWithExpression(((GrAssignmentExpression)thenBranch).getLValue(), true);
+
+ final GrConditionalExpression conditional = (GrConditionalExpression)assignment.getRValue();
+ replaceConditional(conditional, ifStatement.getCondition(), ((GrAssignmentExpression)thenBranch).getRValue(), ((GrAssignmentExpression)elseBranch).getRValue());
+ ifStatement.replaceWithStatement(assignment);
+ }
+
+
+ if (thenBranch instanceof GrReturnStatement && elseBranch instanceof GrReturnStatement) {
+ final GrReturnStatement returnSt = (GrReturnStatement)GroovyPsiElementFactory.getInstance(project).createStatementFromText("return a ? b : c");
+ final GrConditionalExpression conditional = (GrConditionalExpression)returnSt.getReturnValue();
+ replaceConditional(conditional, ifStatement.getCondition(), ((GrReturnStatement)thenBranch).getReturnValue(), ((GrReturnStatement)elseBranch).getReturnValue());
+
+ ifStatement.replaceWithStatement(returnSt);
+ }
+ }
+
+ @SuppressWarnings("ConstantConditions")
+ private static void replaceConditional(GrConditionalExpression conditional,
+ GrExpression condition,
+ GrExpression then,
+ GrExpression elze) {
+ conditional.getCondition().replaceWithExpression(condition, true);
+ conditional.getThenBranch().replaceWithExpression(then, true);
+ conditional.getElseBranch().replaceWithExpression(elze, true);
+ }
+
+ @NotNull
+ @Override
+ protected PsiElementPredicate getElementPredicate() {
+ return new PsiElementPredicate() {
+ @Override
+ public boolean satisfiedBy(PsiElement e) {
+ if (!e.getNode().getElementType().equals(GroovyTokenTypes.kIF)) return false;
+
+ final GrIfStatement ifStatement = (GrIfStatement)e.getParent();
+ final PsiElement thenBranch = skipBlock(ifStatement.getThenBranch());
+ final PsiElement elseBranch = skipBlock(ifStatement.getElseBranch());
+
+ if (thenBranch instanceof GrAssignmentExpression &&
+ elseBranch instanceof GrAssignmentExpression &&
+ ((GrAssignmentExpression)thenBranch).getRValue() != null &&
+ ((GrAssignmentExpression)elseBranch).getRValue() != null) {
+ final GrExpression lvalue1 = ((GrAssignmentExpression)thenBranch).getLValue();
+ final GrExpression lvalue2 = ((GrAssignmentExpression)elseBranch).getLValue();
+ return EquivalenceChecker.expressionsAreEquivalent(lvalue1, lvalue2);
+ }
+
+ if (thenBranch instanceof GrReturnStatement &&
+ elseBranch instanceof GrReturnStatement &&
+ ((GrReturnStatement)thenBranch).getReturnValue() != null &&
+ ((GrReturnStatement)elseBranch).getReturnValue() != null) {
+ return true;
+ }
+
+ return false;
+ }
+ };
+ }
+
+ private static PsiElement skipBlock(PsiElement e) {
+ if (e instanceof GrBlockStatement && ((GrBlockStatement)e).getBlock().getStatements().length == 1) {
+ return ((GrBlockStatement)e).getBlock().getStatements()[0];
+ }
+ else {
+ return e;
+ }
+ }
+}
diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ReplaceifWithTernaryTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ReplaceifWithTernaryTest.groovy
new file mode 100644
index 000000000000..034db1e55d02
--- /dev/null
+++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/intentions/ReplaceifWithTernaryTest.groovy
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-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.plugins.groovy.intentions
+
+/**
+ * @author Max Medvedev
+ */
+class ReplaceIfWithTernaryTest extends GrIntentionTestCase {
+ ReplaceIfWithTernaryTest() {
+ super('Replace with ?:')
+ }
+
+ public void testReturn() throws Exception {
+ doTextTest('''\
+def foo() {
+ if (cond()) {
+ return 'a'
+ }
+ else return 'b'
+}
+''', '''\
+def foo() {
+ return cond() ? 'a' : 'b'
+}
+''')
+ }
+
+ public void testAssign() throws Exception {
+ doTextTest('''\
+def a
+
+if (cond()) {
+ a = 'a'
+}
+else {
+ a = 'b'
+}
+''', '''\
+def a
+
+a = cond() ? 'a' : 'b'
+''')
+ }
+
+ public void testAntiAssign() throws Exception {
+ doAntiTest('''\
+def a
+def b
+
+if (cond) {
+ a = 'a'
+}
+else {
+ b = 'b'
+}
+''')
+ }
+
+}