| package com.intellij.codeInsight.intention; |
| |
| import com.intellij.openapi.editor.Editor; |
| import com.intellij.openapi.project.Project; |
| import com.intellij.psi.*; |
| import com.intellij.psi.codeStyle.CodeStyleManager; |
| import com.intellij.psi.util.PsiTreeUtil; |
| import com.intellij.util.IncorrectOperationException; |
| import org.jetbrains.annotations.NonNls; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| /** |
| * @author dsl |
| */ |
| @NonNls public class ConditionalOperatorConvertor extends PsiElementBaseIntentionAction implements IntentionAction { |
| |
| @NotNull |
| public String getText() { |
| return "Convert ternary operator to if statement"; |
| } |
| |
| @NotNull |
| public String getFamilyName() { |
| return getText(); |
| } |
| |
| public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) { |
| if (element == null) return false; |
| if (!element.isWritable()) return false; |
| |
| if (element instanceof PsiJavaToken) { |
| final PsiJavaToken token = (PsiJavaToken)element; |
| if (token.getTokenType() != JavaTokenType.QUEST) return false; |
| if (token.getParent() instanceof PsiConditionalExpression) { |
| final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)token.getParent(); |
| if (conditionalExpression.getThenExpression() == null |
| || conditionalExpression.getElseExpression() == null) { |
| return false; |
| } |
| return true; |
| } |
| return false; |
| } |
| return false; |
| } |
| |
| public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { |
| final int offset = editor.getCaretModel().getOffset(); |
| final PsiElement element = file.findElementAt(offset); |
| PsiConditionalExpression conditionalExpression = PsiTreeUtil.getParentOfType(element, |
| PsiConditionalExpression.class, false); |
| if (conditionalExpression == null) return; |
| if (conditionalExpression.getThenExpression() == null || conditionalExpression.getElseExpression() == null) return; |
| |
| final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); |
| |
| PsiElement originalStatement = PsiTreeUtil.getParentOfType(conditionalExpression, PsiStatement.class, false); |
| while (originalStatement instanceof PsiForStatement) { |
| originalStatement = PsiTreeUtil.getParentOfType(originalStatement, PsiStatement.class, true); |
| } |
| if (originalStatement == null) return; |
| |
| // Maintain declrations |
| if (originalStatement instanceof PsiDeclarationStatement) { |
| final PsiDeclarationStatement declaration = (PsiDeclarationStatement)originalStatement; |
| final PsiElement[] declaredElements = declaration.getDeclaredElements(); |
| PsiLocalVariable variable = null; |
| for (PsiElement declaredElement : declaredElements) { |
| if (declaredElement instanceof PsiLocalVariable && PsiTreeUtil.isAncestor(declaredElement, conditionalExpression, true)) { |
| variable = (PsiLocalVariable)declaredElement; |
| break; |
| } |
| } |
| if (variable == null) return; |
| variable.normalizeDeclaration(); |
| final Object marker = new Object(); |
| PsiTreeUtil.mark(conditionalExpression, marker); |
| PsiExpressionStatement statement = |
| (PsiExpressionStatement)factory.createStatementFromText(variable.getName() + " = 0;", null); |
| statement = (PsiExpressionStatement)CodeStyleManager.getInstance(project).reformat(statement); |
| ((PsiAssignmentExpression)statement.getExpression()).getRExpression().replace(variable.getInitializer()); |
| variable.getInitializer().delete(); |
| final PsiElement variableParent = variable.getParent(); |
| originalStatement = variableParent.getParent().addAfter(statement, variableParent); |
| conditionalExpression = (PsiConditionalExpression)PsiTreeUtil.releaseMark(originalStatement, marker); |
| } |
| |
| // create then and else branches |
| final PsiElement[] originalElements = new PsiElement[]{originalStatement, conditionalExpression}; |
| final PsiExpression condition = (PsiExpression)conditionalExpression.getCondition().copy(); |
| final PsiElement[] thenElements = PsiTreeUtil.copyElements(originalElements); |
| final PsiElement[] elseElements = PsiTreeUtil.copyElements(originalElements); |
| thenElements[1].replace(conditionalExpression.getThenExpression()); |
| elseElements[1].replace(conditionalExpression.getElseExpression()); |
| |
| PsiIfStatement statement = (PsiIfStatement)factory.createStatementFromText("if (true) { a = b } else { c = d }", |
| null); |
| statement = (PsiIfStatement)CodeStyleManager.getInstance(project).reformat(statement); |
| statement.getCondition().replace(condition); |
| statement = (PsiIfStatement)originalStatement.replace(statement); |
| |
| ((PsiBlockStatement)statement.getThenBranch()).getCodeBlock().getStatements()[0].replace(thenElements[0]); |
| ((PsiBlockStatement)statement.getElseBranch()).getCodeBlock().getStatements()[0].replace(elseElements[0]); |
| } |
| |
| public boolean startInWriteAction() { |
| return true; |
| } |
| } |