1 package com.intellij.codeInsight.intention;
3 import com.intellij.openapi.editor.Editor;
4 import com.intellij.openapi.project.Project;
5 import com.intellij.psi.*;
6 import com.intellij.psi.codeStyle.CodeStyleManager;
7 import com.intellij.psi.util.PsiTreeUtil;
8 import com.intellij.util.IncorrectOperationException;
9 import org.jetbrains.annotations.NonNls;
10 import org.jetbrains.annotations.NotNull;
11 import org.jetbrains.annotations.Nullable;
16 @NonNls public class ConditionalOperatorConvertor extends PsiElementBaseIntentionAction implements IntentionAction {
19 public String getText() {
20 return "Convert ternary operator to if statement";
24 public String getFamilyName() {
28 public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) {
29 if (element == null) return false;
30 if (!element.isWritable()) return false;
32 if (element instanceof PsiJavaToken) {
33 final PsiJavaToken token = (PsiJavaToken)element;
34 if (token.getTokenType() != JavaTokenType.QUEST) return false;
35 if (token.getParent() instanceof PsiConditionalExpression) {
36 final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)token.getParent();
37 if (conditionalExpression.getThenExpression() == null
38 || conditionalExpression.getElseExpression() == null) {
48 public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
49 final int offset = editor.getCaretModel().getOffset();
50 final PsiElement element = file.findElementAt(offset);
51 PsiConditionalExpression conditionalExpression = PsiTreeUtil.getParentOfType(element,
52 PsiConditionalExpression.class, false);
53 if (conditionalExpression == null) return;
54 if (conditionalExpression.getThenExpression() == null || conditionalExpression.getElseExpression() == null) return;
56 final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
58 PsiElement originalStatement = PsiTreeUtil.getParentOfType(conditionalExpression, PsiStatement.class, false);
59 while (originalStatement instanceof PsiForStatement) {
60 originalStatement = PsiTreeUtil.getParentOfType(originalStatement, PsiStatement.class, true);
62 if (originalStatement == null) return;
64 // Maintain declrations
65 if (originalStatement instanceof PsiDeclarationStatement) {
66 final PsiDeclarationStatement declaration = (PsiDeclarationStatement)originalStatement;
67 final PsiElement[] declaredElements = declaration.getDeclaredElements();
68 PsiLocalVariable variable = null;
69 for (PsiElement declaredElement : declaredElements) {
70 if (declaredElement instanceof PsiLocalVariable && PsiTreeUtil.isAncestor(declaredElement, conditionalExpression, true)) {
71 variable = (PsiLocalVariable)declaredElement;
75 if (variable == null) return;
76 variable.normalizeDeclaration();
77 final Object marker = new Object();
78 PsiTreeUtil.mark(conditionalExpression, marker);
79 PsiExpressionStatement statement =
80 (PsiExpressionStatement)factory.createStatementFromText(variable.getName() + " = 0;", null);
81 statement = (PsiExpressionStatement)CodeStyleManager.getInstance(project).reformat(statement);
82 ((PsiAssignmentExpression)statement.getExpression()).getRExpression().replace(variable.getInitializer());
83 variable.getInitializer().delete();
84 final PsiElement variableParent = variable.getParent();
85 originalStatement = variableParent.getParent().addAfter(statement, variableParent);
86 conditionalExpression = (PsiConditionalExpression)PsiTreeUtil.releaseMark(originalStatement, marker);
89 // create then and else branches
90 final PsiElement[] originalElements = new PsiElement[]{originalStatement, conditionalExpression};
91 final PsiExpression condition = (PsiExpression)conditionalExpression.getCondition().copy();
92 final PsiElement[] thenElements = PsiTreeUtil.copyElements(originalElements);
93 final PsiElement[] elseElements = PsiTreeUtil.copyElements(originalElements);
94 thenElements[1].replace(conditionalExpression.getThenExpression());
95 elseElements[1].replace(conditionalExpression.getElseExpression());
97 PsiIfStatement statement = (PsiIfStatement)factory.createStatementFromText("if (true) { a = b } else { c = d }",
99 statement = (PsiIfStatement)CodeStyleManager.getInstance(project).reformat(statement);
100 statement.getCondition().replace(condition);
101 statement = (PsiIfStatement)originalStatement.replace(statement);
103 ((PsiBlockStatement)statement.getThenBranch()).getCodeBlock().getStatements()[0].replace(thenElements[0]);
104 ((PsiBlockStatement)statement.getElseBranch()).getCodeBlock().getStatements()[0].replace(elseElements[0]);
107 public boolean startInWriteAction() {