From 192adb0c4c81b77d98bb7fbec914b712e49e03d4 Mon Sep 17 00:00:00 2001 From: anna Date: Mon, 11 Feb 2013 10:25:28 +0100 Subject: [PATCH] introduce: allow to provide checks to filter unacceptable expressions before showing them to user (IDEA-100776) --- .../BaseExpressionToFieldHandler.java | 11 ++++++++--- .../introduceField/ElementToWorkOn.java | 17 +++++++++++++++-- .../IntroduceConstantHandler.java | 11 +++++++++++ .../introduceField/IntroduceFieldHandler.java | 5 +++++ .../IntroduceParameterHandler.java | 8 ++++++-- ...lingErrorUnacceptableWholeLineSelection.java | 6 ++++++ ...rorUnacceptableWholeLineSelection_after.java | 8 ++++++++ .../refactoring/IntroduceConstantTest.java | 6 ++++++ .../refactoring/IntroduceParameterTest.java | 8 ++++++-- 9 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection.java create mode 100644 java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java index 3a1347715e06..fa216113b276 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java @@ -44,7 +44,6 @@ import com.intellij.openapi.editor.markup.RangeHighlighter; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; @@ -446,9 +445,15 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase } } + protected abstract boolean accept(ElementToWorkOn elementToWorkOn); + + protected ElementToWorkOn.ElementsProcessor getElementProcessor(final Project project, final Editor editor) { + return new ElementToWorkOn.ElementsProcessor() { + @Override + public boolean accept(ElementToWorkOn el) { + return BaseExpressionToFieldHandler.this.accept(el); + } - protected Pass getElementProcessor(final Project project, final Editor editor) { - return new Pass() { @Override public void pass(final ElementToWorkOn elementToWorkOn) { if (elementToWorkOn == null) return; diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java index 3dab04d34b94..93e19e3581bc 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java @@ -29,6 +29,7 @@ import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.introduceVariable.IntroduceVariableBase; import com.intellij.refactoring.util.CommonRefactoringUtil; +import java.util.Iterator; import java.util.List; /** @@ -60,7 +61,7 @@ public class ElementToWorkOn { return myExpression == null; } - public static void processElementToWorkOn(final Editor editor, final PsiFile file, final String refactoringName, final String helpId, final Project project, final Pass processor) { + public static void processElementToWorkOn(final Editor editor, final PsiFile file, final String refactoringName, final String helpId, final Project project, final ElementsProcessor processor) { PsiLocalVariable localVar = null; PsiExpression expr = null; @@ -92,13 +93,20 @@ public class ElementToWorkOn { if (statementsInRange.length == 1 && (PsiUtilCore.hasErrorElementChild(statementsInRange[0]) || !PsiUtil.isStatement(statementsInRange[0]))) { editor.getSelectionModel().selectLineAtCaret(); final ElementToWorkOn elementToWorkOn = getElementToWorkOn(editor, file, refactoringName, helpId, project, localVar, expr); - if (elementToWorkOn == null || elementToWorkOn.getLocalVariable() == null && elementToWorkOn.getExpression() == null) { + if (elementToWorkOn == null || elementToWorkOn.getLocalVariable() == null && elementToWorkOn.getExpression() == null || !processor.accept(elementToWorkOn)) { editor.getSelectionModel().removeSelection(); } } if (!editor.getSelectionModel().hasSelection()){ final List expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange); + for (Iterator iterator = expressions.iterator(); iterator.hasNext(); ) { + PsiExpression expression = iterator.next(); + if (!processor.accept(new ElementToWorkOn(null, expression))) { + iterator.remove(); + } + } + if (expressions.isEmpty()) { editor.getSelectionModel().selectLineAtCaret(); } @@ -177,4 +185,9 @@ public class ElementToWorkOn { } return new ElementToWorkOn(localVar, expr); } + + public interface ElementsProcessor { + boolean accept(ElementToWorkOn el); + void pass(T t); + } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java index 31734bdb32e0..103777895cbc 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceConstantHandler.java @@ -296,6 +296,17 @@ public class IntroduceConstantHandler extends BaseExpressionToFieldHandler { return null; } + @Override + protected boolean accept(ElementToWorkOn elementToWorkOn) { + final PsiExpression expr = elementToWorkOn.getExpression(); + if (expr != null) { + return isStaticFinalInitializer(expr) == null; + } + final PsiLocalVariable localVariable = elementToWorkOn.getLocalVariable(); + final PsiExpression initializer = localVariable.getInitializer(); + return initializer != null && isStaticFinalInitializer(initializer) == null; + } + protected boolean validClass(PsiClass parentClass, Editor editor) { return true; } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java index c16fc9fbcdd8..a4338d463cc3 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceField/IntroduceFieldHandler.java @@ -157,6 +157,11 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler { dialog.getFieldType(), localVariable != null, (TargetDestination)null, false, false); } + @Override + protected boolean accept(ElementToWorkOn elementToWorkOn) { + return true; + } + private static PsiElement getElement(PsiExpression expr, PsiElement anchorElement) { PsiElement element = null; if (expr != null) { diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java index eaa5afffb0c4..52d9e3902bf0 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterHandler.java @@ -40,7 +40,6 @@ import com.intellij.openapi.ui.popup.JBPopupAdapter; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.LightweightWindowEvent; import com.intellij.openapi.util.Pair; -import com.intellij.openapi.util.Pass; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.psi.*; @@ -90,7 +89,12 @@ public class IntroduceParameterHandler extends IntroduceHandlerBase { public void invoke(@NotNull final Project project, final Editor editor, PsiFile file, DataContext dataContext) { PsiDocumentManager.getInstance(project).commitAllDocuments(); editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE); - ElementToWorkOn.processElementToWorkOn(editor, file, REFACTORING_NAME, HelpID.INTRODUCE_PARAMETER, project, new Pass() { + ElementToWorkOn.processElementToWorkOn(editor, file, REFACTORING_NAME, HelpID.INTRODUCE_PARAMETER, project, new ElementToWorkOn.ElementsProcessor() { + @Override + public boolean accept(ElementToWorkOn el) { + return true; + } + @Override public void pass(final ElementToWorkOn elementToWorkOn) { if (elementToWorkOn == null) return; diff --git a/java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection.java b/java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection.java new file mode 100644 index 000000000000..53b9769172ff --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection.java @@ -0,0 +1,6 @@ +public class Test { + + void foo(Integer i) { + i.compareTo(1) + } +} diff --git a/java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection_after.java b/java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection_after.java new file mode 100644 index 000000000000..fb9169bf04e7 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceConstant/TailingErrorUnacceptableWholeLineSelection_after.java @@ -0,0 +1,8 @@ +public class Test { + + public static final int xxx = 1; + + void foo(Integer i) { + i.compareTo(xxx) + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java index 5fa1a3f47961..370435173444 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceConstantTest.java @@ -58,6 +58,12 @@ public class IntroduceConstantTest extends LightCodeInsightTestCase { checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); } + public void testTailingErrorUnacceptableWholeLineSelection() throws Exception { + configureByFile(BASE_PATH + getTestName(false) + ".java"); + new MockIntroduceConstantHandler(null).invoke(getProject(), getEditor(), getFile(), null); + checkResultByFile(BASE_PATH + getTestName(false) + "_after.java"); + } + private static void convertLocal(final boolean makeEnumConstant) { PsiLocalVariable local = PsiTreeUtil.getParentOfType(getFile().findElementAt(getEditor().getCaretModel().getOffset()), PsiLocalVariable.class); new MockLocalToFieldHandler(getProject(), true, makeEnumConstant).convertLocalToField(local, getEditor()); diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java index 9af0a0089503..59d5ca1ad847 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterTest.java @@ -11,7 +11,6 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.codeInsight.CodeInsightUtil; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.util.Pass; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiExpression; @@ -365,7 +364,12 @@ public class IntroduceParameterTest extends LightRefactoringTestCase { int enclosingLevel) { final ElementToWorkOn[] elementToWorkOn = new ElementToWorkOn[1]; ElementToWorkOn - .processElementToWorkOn(myEditor, myFile, "INtr param", HelpID.INTRODUCE_PARAMETER, getProject(), new Pass() { + .processElementToWorkOn(myEditor, myFile, "INtr param", HelpID.INTRODUCE_PARAMETER, getProject(), new ElementToWorkOn.ElementsProcessor() { + @Override + public boolean accept(ElementToWorkOn el) { + return true; + } + @Override public void pass(final ElementToWorkOn e) { if (e == null) return;