refactor expression postfix template with chooser

This commit is contained in:
Andrey Starovoyt
2014-05-18 18:38:41 +04:00
parent cae5144e12
commit be8ee4ffb5
9 changed files with 160 additions and 59 deletions
@@ -17,16 +17,16 @@ package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.generation.surroundWith.JavaWithCastSurrounder;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
public class CastExpressionPostfixTemplate extends ExpressionPostfixTemplateWithChooser {
public class CastExpressionPostfixTemplate extends JavaPostfixTemplateWithChooser {
public CastExpressionPostfixTemplate() {
super("cast", "((SomeType) expr)");
}
@Override
protected void doIt(@NotNull final Editor editor, @NotNull final PsiExpression expression) {
protected void doIt(@NotNull final Editor editor, @NotNull final PsiElement expression) {
PostfixTemplatesUtils.surround(new JavaWithCastSurrounder(), editor, expression);
}
}
@@ -23,19 +23,20 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.introduceField.IntroduceFieldHandler;
import org.jetbrains.annotations.NotNull;
public class IntroduceFieldPostfixTemplate extends ExpressionPostfixTemplateWithChooser {
public class IntroduceFieldPostfixTemplate extends JavaPostfixTemplateWithChooser {
public IntroduceFieldPostfixTemplate() {
super("field", "myField = expr;");
}
@Override
protected void doIt(@NotNull Editor editor, @NotNull PsiExpression expression) {
IntroduceFieldHandler handler = ApplicationManager.getApplication().isUnitTestMode() ? getMockHandler(expression) : new IntroduceFieldHandler();
protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
IntroduceFieldHandler handler =
ApplicationManager.getApplication().isUnitTestMode() ? getMockHandler(expression) : new IntroduceFieldHandler();
handler.invoke(expression.getProject(), new PsiElement[]{expression}, null);
}
@NotNull
private static IntroduceFieldHandler getMockHandler(@NotNull final PsiExpression expression) {
private static IntroduceFieldHandler getMockHandler(@NotNull final PsiElement expression) {
final PsiClass containingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class);
assert containingClass != null;
@@ -46,7 +47,7 @@ public class IntroduceFieldPostfixTemplate extends ExpressionPostfixTemplateWith
PsiExpression expr, PsiType type, PsiExpression[] occurrences,
PsiElement anchorElement, PsiElement anchorElementIfAll) {
return new Settings(
"foo", expression, PsiExpression.EMPTY_ARRAY, false, false, false,
"foo", (PsiExpression)expression, PsiExpression.EMPTY_ARRAY, false, false, false,
InitializationPlace.IN_CURRENT_METHOD, PsiModifier.PRIVATE, null,
null, false, containingClass, false, false);
}
@@ -29,16 +29,17 @@ import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
import org.jetbrains.annotations.NotNull;
// todo: support for int[].var (parses as .class access!)
public class IntroduceVariablePostfixTemplate extends ExpressionPostfixTemplateWithChooser {
public class IntroduceVariablePostfixTemplate extends JavaPostfixTemplateWithChooser {
public IntroduceVariablePostfixTemplate() {
super("var", "T name = expr;");
}
@Override
protected void doIt(@NotNull Editor editor, @NotNull PsiExpression expression) {
protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
// for advanced stuff use ((PsiJavaCodeReferenceElement)expression).advancedResolve(true).getElement();
IntroduceVariableHandler handler = ApplicationManager.getApplication().isUnitTestMode() ? getMockHandler() : new IntroduceVariableHandler();
handler.invoke(expression.getProject(), editor, expression);
IntroduceVariableHandler handler =
ApplicationManager.getApplication().isUnitTestMode() ? getMockHandler() : new IntroduceVariableHandler();
handler.invoke(expression.getProject(), editor, (PsiExpression)expression);
}
@NotNull
@@ -0,0 +1,42 @@
/*
* Copyright 2000-2014 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 com.intellij.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import static com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils.JAVA_PSI_INFO;
public abstract class JavaPostfixTemplateWithChooser extends ExpressionPostfixTemplateWithChooser {
protected JavaPostfixTemplateWithChooser(@NotNull String name, @NotNull String example) {
super(name, example, JAVA_PSI_INFO);
}
protected JavaPostfixTemplateWithChooser(@NotNull String name, @NotNull String key, @NotNull String example) {
super(name, key, example, JAVA_PSI_INFO);
}
@NotNull
@Override
protected Condition<PsiElement> getTypeCondition() {
return JavaPostfixTemplatesUtils.IS_NON_VOID;
}
}
@@ -19,19 +19,14 @@ import com.intellij.codeInsight.CodeInsightServicesUtil;
import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import org.jetbrains.annotations.NotNull;
public class NotExpressionPostfixTemplate extends ExpressionPostfixTemplateWithChooser {
private static final Condition<PsiExpression> BOOLEAN_TYPE_CONDITION = new Condition<PsiExpression>() {
@Override
public boolean value(PsiExpression expression) {
return JavaPostfixTemplatesUtils.isBoolean(expression.getType());
}
};
public class NotExpressionPostfixTemplate extends JavaPostfixTemplateWithChooser {
public NotExpressionPostfixTemplate() {
super("not", "!expr");
super("not", "!expr");
}
public NotExpressionPostfixTemplate(String alias) {
@@ -39,13 +34,13 @@ public class NotExpressionPostfixTemplate extends ExpressionPostfixTemplateWithC
}
@Override
protected void doIt(@NotNull Editor editor, @NotNull PsiExpression expression) {
expression.replace(CodeInsightServicesUtil.invertCondition(expression));
protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
expression.replace(CodeInsightServicesUtil.invertCondition((PsiExpression)expression));
}
@NotNull
@Override
protected Condition<PsiExpression> getTypeCondition() {
return BOOLEAN_TYPE_CONDITION;
protected Condition<PsiElement> getTypeCondition() {
return JavaPostfixTemplatesUtils.IS_BOOLEAN;
}
}
@@ -16,19 +16,16 @@
package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiParenthesizedExpression;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
public class ParenthesizedExpressionPostfixTemplate extends ExpressionPostfixTemplateWithChooser {
public class ParenthesizedExpressionPostfixTemplate extends JavaPostfixTemplateWithChooser {
public ParenthesizedExpressionPostfixTemplate() {
super("par", "(expression)");
}
@Override
protected void doIt(@NotNull Editor editor, @NotNull PsiExpression expression) {
protected void doIt(@NotNull Editor editor, @NotNull PsiElement expression) {
PsiElementFactory factory = JavaPsiFacade.getInstance(expression.getProject()).getElementFactory();
PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)factory.createExpressionFromText("(expr)", expression.getParent());
PsiExpression operand = parenthesizedExpression.getExpression();
@@ -17,23 +17,30 @@ package com.intellij.codeInsight.template.postfix.util;
import com.intellij.codeInsight.CodeInsightServicesUtil;
import com.intellij.codeInsight.CodeInsightUtilCore;
import com.intellij.codeInsight.template.postfix.templates.PostfixTemplatePsiInfo;
import com.intellij.codeInsight.template.postfix.templates.PostfixTemplatePsiInfoBase;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiExpressionTrimRenderer;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public abstract class JavaPostfixTemplatesUtils {
private JavaPostfixTemplatesUtils() {
}
public static PostfixTemplatePsiInfo JAVA_PSI_INFO = new PostfixTemplatePsiInfo() {
public static final PostfixTemplatePsiInfoBase JAVA_PSI_INFO = new PostfixTemplatePsiInfoBase() {
@NotNull
@Override
@@ -60,8 +67,28 @@ public abstract class JavaPostfixTemplatesUtils {
@NotNull
@Override
public PsiExpression getNegatedExpression(@NotNull PsiElement element) {
assert element instanceof PsiExpression;
return CodeInsightServicesUtil.invertCondition((PsiExpression)element);
}
@NotNull
@Override
public List<PsiElement> getExpressions(@NotNull PsiElement context, @NotNull Document document, int newOffset) {
return ContainerUtil.<PsiElement>newArrayList(IntroduceVariableBase.collectExpressions(context.getContainingFile(), document,
Math.max(newOffset - 1, 0), false));
}
@NotNull
@Override
public Function<PsiElement, String> getRenderer() {
return new Function<PsiElement, String>() {
@Override
public String fun(PsiElement element) {
assert element instanceof PsiExpression;
return new PsiExpressionTrimRenderer.RenderFunction().fun((PsiExpression)element);
}
};
}
};
public static Condition<PsiElement> IS_BOOLEAN = new Condition<PsiElement>() {
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.template.postfix.templates;
import com.intellij.codeInsight.template.postfix.util.JavaPostfixTemplatesUtils;
import com.intellij.codeInsight.unwrap.ScopeHighlighter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -24,11 +23,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Pass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.PsiExpressionTrimRenderer;
import com.intellij.refactoring.IntroduceTargetChooser;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -38,14 +33,21 @@ import java.util.List;
* @author ignatov
*/
public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTemplate {
protected ExpressionPostfixTemplateWithChooser(@NotNull String name, @NotNull String example) {
@NotNull
protected final PostfixTemplatePsiInfoBase myInfo;
protected ExpressionPostfixTemplateWithChooser(@NotNull String name, @NotNull String example, @NotNull PostfixTemplatePsiInfoBase info) {
super(name, example);
myInfo = info;
}
protected ExpressionPostfixTemplateWithChooser(@NotNull String name,
@NotNull String key,
@NotNull String example) {
@NotNull String example,
@NotNull PostfixTemplatePsiInfoBase info) {
super(name, key, example);
myInfo = info;
}
@Override
@@ -55,7 +57,7 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
@Override
public void expand(@NotNull PsiElement context, @NotNull final Editor editor) {
List<PsiExpression> expressions = getExpressions(context, editor.getDocument(), editor.getCaretModel().getOffset());
List<PsiElement> expressions = getExpressions(context, editor.getDocument(), editor.getCaretModel().getOffset());
if (expressions.isEmpty()) {
PostfixTemplatesUtils.showErrorHint(context.getProject(), editor);
@@ -66,8 +68,8 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
else {
IntroduceTargetChooser.showChooser(
editor, expressions,
new Pass<PsiExpression>() {
public void pass(@NotNull final PsiExpression e) {
new Pass<PsiElement>() {
public void pass(@NotNull final PsiElement e) {
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
@@ -80,39 +82,36 @@ public abstract class ExpressionPostfixTemplateWithChooser extends PostfixTempla
});
}
},
new PsiExpressionTrimRenderer.RenderFunction(),
myInfo.getRenderer(),
"Expressions", 0, ScopeHighlighter.NATURAL_RANGER
);
}
}
@NotNull
protected List<PsiExpression> getExpressions(@NotNull PsiElement context, @NotNull Document document, final int offset) {
List<PsiExpression> expressions = ContainerUtil.filter(IntroduceVariableBase.collectExpressions(context.getContainingFile(), document,
Math.max(offset - 1, 0), false),
new Condition<PsiExpression>() {
@Override
public boolean value(PsiExpression expression) {
return expression.getTextRange().getEndOffset() == offset;
}
}
protected List<PsiElement> getExpressions(@NotNull PsiElement context, @NotNull Document document, final int offset) {
List<PsiElement> possibleExpressions = myInfo.getExpressions(context, document, offset);
List<PsiElement> expressions = ContainerUtil.filter(possibleExpressions,
new Condition<PsiElement>() {
@Override
public boolean value(PsiElement expression) {
return expression.getTextRange().getEndOffset() == offset;
}
}
);
return ContainerUtil.filter(expressions.isEmpty() ? maybeTopmostExpression(context) : expressions, getTypeCondition());
}
@NotNull
@SuppressWarnings("unchecked")
protected Condition<PsiExpression> getTypeCondition() {
protected Condition<PsiElement> getTypeCondition() {
return Condition.TRUE;
}
@NotNull
private static List<PsiExpression> maybeTopmostExpression(@NotNull PsiElement context) {
PsiExpression expression = JavaPostfixTemplatesUtils.getTopmostExpression(context);
PsiType type = expression != null ? expression.getType() : null;
if (type == null || PsiType.VOID.equals(type)) return ContainerUtil.emptyList();
return ContainerUtil.createMaybeSingletonList(expression);
private List<PsiElement> maybeTopmostExpression(@NotNull PsiElement context) {
return ContainerUtil.createMaybeSingletonList(myInfo.getTopmostExpression(context));
}
protected abstract void doIt(@NotNull Editor editor, @NotNull PsiExpression expression);
protected abstract void doIt(@NotNull Editor editor, @NotNull PsiElement expression);
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2014 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 com.intellij.codeInsight.template.postfix.templates;
import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiElement;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public abstract class PostfixTemplatePsiInfoBase implements PostfixTemplatePsiInfo {
@NotNull
public abstract List<PsiElement> getExpressions(@NotNull PsiElement context, @NotNull Document document, int newOffset);
@NotNull
public Function<PsiElement, String> getRenderer() {
return new Function<PsiElement, String>() {
@Override
public String fun(@NotNull PsiElement element) {
return element.getText();
}
};
}
}