surround expression with: support for expression's parts (IDEA-73868)

This commit is contained in:
anna
2011-09-08 11:21:17 +02:00
parent d5b25c8bc5
commit 0eb2875056
14 changed files with 90 additions and 9 deletions
@@ -50,6 +50,7 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
}
public boolean isApplicable(PsiExpression expr) {
if (!expr.isPhysical()) return false;
PsiFile file = expr.getContainingFile();
if (!(file instanceof PsiCodeFragment)) return false;
if (file.getUserData(DebuggerExpressionComboBox.KEY) == null) {
@@ -23,6 +23,7 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiFile;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -44,8 +45,13 @@ public class JavaExpressionSurroundDescriptor implements SurroundDescriptor {
};
@NotNull public PsiElement[] getElementsToSurround(PsiFile file, int startOffset, int endOffset) {
final PsiExpression expr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset);
if (expr == null) return PsiElement.EMPTY_ARRAY;
PsiExpression expr = CodeInsightUtil.findExpressionInRange(file, startOffset, endOffset);
if (expr == null) {
expr = IntroduceVariableBase.getSelectedExpression(file.getProject(), file, startOffset, endOffset);
if (expr == null) {
return PsiElement.EMPTY_ARRAY;
}
}
FeatureUsageTracker.getInstance().triggerFeatureUsed("codeassists.surroundwith.expression");
return new PsiElement[] {expr};
}
@@ -21,11 +21,13 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.codeInsight.template.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.RangeMarker;
import com.intellij.openapi.editor.ScrollType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.refactoring.introduceField.ElementToWorkOn;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
@@ -43,7 +45,14 @@ class JavaWithCastSurrounder extends JavaExpressionSurrounder {
assert expr.isValid();
PsiType[] types = GuessManager.getInstance(project).guessTypeToCast(expr);
final Template template = generateTemplate(project, expr.getText(), types);
TextRange range = expr.getTextRange();
TextRange range;
if (expr.isPhysical()) {
range = expr.getTextRange();
} else {
final RangeMarker rangeMarker = expr.getUserData(ElementToWorkOn.TEXT_RANGE);
if (rangeMarker == null) return null;
range = new TextRange(rangeMarker.getStartOffset(), rangeMarker.getEndOffset());
}
editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
editor.getCaretModel().moveToOffset(range.getStartOffset());
editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
@@ -30,6 +30,7 @@ class JavaWithIfExpressionSurrounder extends JavaExpressionSurrounder{
public boolean isApplicable(PsiExpression expr) {
PsiType type = expr.getType();
if (PsiType.BOOLEAN != type) return false;
if (!expr.isPhysical()) return false;
PsiElement parent = expr.getParent();
if (!(parent instanceof PsiExpressionStatement)) return false;
final PsiElement element = parent.getParent();
@@ -23,12 +23,14 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.util.IncorrectOperationException;
class JavaWithNotInstanceofSurrounder extends JavaExpressionSurrounder{
public boolean isApplicable(PsiExpression expr) {
PsiType type = expr.getType();
if (type == null) return false;
if (!expr.isPhysical()) return false;
return !(type instanceof PsiPrimitiveType);
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.util.IncorrectOperationException;
class JavaWithNotSurrounder extends JavaExpressionSurrounder{
@@ -37,7 +38,7 @@ class JavaWithNotSurrounder extends JavaExpressionSurrounder{
PsiPrefixExpression prefixExpr = (PsiPrefixExpression)factory.createExpressionFromText("!(a)", null);
prefixExpr = (PsiPrefixExpression)codeStyleManager.reformat(prefixExpr);
((PsiParenthesizedExpression)prefixExpr.getOperand()).getExpression().replace(expr);
expr = (PsiExpression)expr.replace(prefixExpr);
expr = (PsiExpression)IntroduceVariableBase.replace(expr, prefixExpr, project);
int offset = expr.getTextRange().getEndOffset();
return new TextRange(offset, offset);
}
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.util.IncorrectOperationException;
class JavaWithParenthesesSurrounder extends JavaExpressionSurrounder{
@@ -37,7 +38,7 @@ class JavaWithParenthesesSurrounder extends JavaExpressionSurrounder{
PsiParenthesizedExpression parenthExpr = (PsiParenthesizedExpression)factory.createExpressionFromText("(a)", null);
parenthExpr = (PsiParenthesizedExpression)codeStyleManager.reformat(parenthExpr);
parenthExpr.getExpression().replace(expr);
expr = (PsiExpression)expr.replace(parenthExpr);
expr = (PsiExpression)IntroduceVariableBase.replace(expr, parenthExpr, project);
int offset = expr.getTextRange().getEndOffset();
return new TextRange(offset, offset);
}
@@ -0,0 +1,8 @@
class Test {
void foo() {
String a = "", b = "", c = "";
if (a + <selection>b + c</selection>) {
}
}
}
@@ -0,0 +1,8 @@
class Test {
void foo() {
String a = "", b = "", c = "";
if (a + (() b + c)) {
}
}
}
@@ -0,0 +1,8 @@
class Test {
void foo() {
boolean a = false, b = false, c = false;
if (a && <selection>b && c</selection>) {
}
}
}
@@ -0,0 +1,8 @@
class Test {
void foo() {
boolean a = false, b = false, c = false;
if (a && !(b && c)) {
}
}
}
@@ -0,0 +1,8 @@
class Test {
void foo() {
int a = 0, b = 0, c = 0;
if (a + <selection>b + c</selection>) {
}
}
}
@@ -0,0 +1,8 @@
class Test {
void foo() {
int a = 0, b = 0, c = 0;
if (a + (b + c)) {
}
}
}
@@ -78,13 +78,25 @@ public class JavaSurroundWithTest extends LightCodeInsightTestCase {
public void testCommentAsFirstSurroundStatement() throws Exception {
String template = "CommentAsFirst%sSurroundStatement";
for (SurroundType type : SurroundType.values()) {
doTest(type, String.format(template, StringUtil.capitalize(type.toFileName())));
doTest(String.format(template, StringUtil.capitalize(type.toFileName())), type.getSurrounder());
}
}
private void doTest(@NotNull SurroundType surroundType, @NotNull String fileName) throws Exception {
public void testSurroundNonExpressionWithParenthesis() throws Exception {
doTest(getTestName(false), new JavaWithParenthesesSurrounder());
}
public void testSurroundNonExpressionWithCast() throws Exception {
doTest(getTestName(false), new JavaWithCastSurrounder());
}
public void testSurroundNonExpressionWithNot() throws Exception {
doTest(getTestName(false), new JavaWithNotSurrounder());
}
private void doTest(@NotNull String fileName, final Surrounder surrounder) throws Exception {
configureByFile(BASE_PATH + fileName + ".java");
SurroundWithHandler.invoke(getProject(), getEditor(), getFile(), surroundType.getSurrounder());
SurroundWithHandler.invoke(getProject(), getEditor(), getFile(), surrounder);
checkResultByFile(BASE_PATH + fileName + "_after.java");
}
}