mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-07 05:09:37 +07:00
Correct implementation for context-dependent Move action name (IDEA-CR-46897)
GitOrigin-RevId: 1cdaf70c4ec305b3aa63e974e1fc672036887864
This commit is contained in:
committed by
intellij-monorepo-bot
parent
57d5f321f2
commit
c98d0e5526
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.refactoring.anonymousToInner;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.jvm.JvmLanguage;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -23,6 +25,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNewExpression;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -30,11 +33,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
*/
|
||||
public class MoveAnonymousToInnerHandler extends MoveHandlerDelegate {
|
||||
@Override
|
||||
public boolean canMove(PsiElement[] elements, @Nullable PsiElement targetContainer) {
|
||||
public boolean canMove(PsiElement[] elements, @Nullable PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
for (PsiElement element : elements) {
|
||||
if (!(element instanceof PsiAnonymousClass)) return false;
|
||||
}
|
||||
return targetContainer == null || super.canMove(elements, targetContainer);
|
||||
return targetContainer == null || super.canMove(elements, targetContainer, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -46,4 +49,15 @@ public class MoveAnonymousToInnerHandler extends MoveHandlerDelegate {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return language instanceof JvmLanguage;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
return "Convert Anonymous to Inner...";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,16 +72,17 @@ public class JavaMoveClassesOrPackagesHandler extends MoveHandlerDelegate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove(PsiElement[] elements, @Nullable PsiElement targetContainer) {
|
||||
public boolean canMove(PsiElement[] elements, @Nullable PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
for (PsiElement element : elements) {
|
||||
if (!isPackageOrDirectory(element) && invalid4Move(element)) return false;
|
||||
}
|
||||
return targetContainer == null || super.canMove(elements, targetContainer);
|
||||
if (isReferenceInAnonymousClass(reference)) return false;
|
||||
return targetContainer == null || super.canMove(elements, targetContainer, reference);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getActionName(PsiElement[] elements) {
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
int classCount = 0, directoryCount = 0;
|
||||
for (PsiElement element : elements) {
|
||||
if (element instanceof PsiClass) classCount++;
|
||||
|
||||
@@ -49,15 +49,16 @@ public class JavaMoveFilesOrDirectoriesHandler extends MoveFilesOrDirectoriesHan
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove(PsiElement[] elements, PsiElement targetContainer) {
|
||||
if (elements.length > 0) {
|
||||
public boolean canMove(PsiElement[] elements, PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
if (reference != null) return false;
|
||||
if (elements.length > 1) {
|
||||
final Project project = elements[0].getProject();
|
||||
final PsiElement[] adjustForMove = adjustForMove(project, elements, targetContainer);
|
||||
if (adjustForMove != null) {
|
||||
return super.canMove(adjustForMove, targetContainer);
|
||||
return super.canMove(adjustForMove, targetContainer, reference);
|
||||
}
|
||||
}
|
||||
return super.canMove(elements, targetContainer);
|
||||
return super.canMove(elements, targetContainer, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.refactoring.move.moveInner;
|
||||
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.jvm.JvmLanguage;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -30,11 +32,12 @@ import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.JavaMoveClassesOrPackagesHandler;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class MoveInnerToUpperHandler extends MoveHandlerDelegate {
|
||||
@Override
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer) {
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
if (elements.length != 1) return false;
|
||||
PsiElement element = elements [0];
|
||||
return isNonStaticInnerClass(element);
|
||||
@@ -70,7 +73,12 @@ public class MoveInnerToUpperHandler extends MoveHandlerDelegate {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getActionName(PsiElement[] elements) {
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
return "Move Inner Class to Upper Level...";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return language instanceof JvmLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.refactoring.move.moveInner;
|
||||
|
||||
import com.intellij.featureStatistics.FeatureUsageTracker;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.jvm.JvmLanguage;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -31,6 +33,7 @@ import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.JavaMoveClassesOrPackagesHandler;
|
||||
import com.intellij.refactoring.move.moveMembers.MoveMembersHandler;
|
||||
import com.intellij.refactoring.util.RadioUpDownListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -38,7 +41,7 @@ import java.awt.*;
|
||||
|
||||
public class MoveInnerToUpperOrMembersHandler extends MoveHandlerDelegate {
|
||||
@Override
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer) {
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
if (elements.length != 1) return false;
|
||||
PsiElement element = elements [0];
|
||||
return isStaticInnerClass(element);
|
||||
@@ -80,6 +83,17 @@ public class MoveInnerToUpperOrMembersHandler extends MoveHandlerDelegate {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return language instanceof JvmLanguage;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
return "Move Inner Class...";
|
||||
}
|
||||
|
||||
private static class SelectInnerOrMembersRefactoringDialog extends DialogWrapper {
|
||||
private JRadioButton myRbMoveInner;
|
||||
private JRadioButton myRbMoveMembers;
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.intellij.refactoring.move.moveInstanceMethod;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -22,18 +24,19 @@ import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import com.intellij.refactoring.move.moveClassesOrPackages.JavaMoveClassesOrPackagesHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class MoveInstanceMethodHandlerDelegate extends MoveHandlerDelegate {
|
||||
@Override
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer) {
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
if (elements.length != 1) return false;
|
||||
PsiElement element = elements [0];
|
||||
if (!(element instanceof PsiMethod)) return false;
|
||||
if (element instanceof SyntheticElement) return false;
|
||||
PsiMethod method = (PsiMethod) element;
|
||||
if (method.hasModifierProperty(PsiModifier.STATIC)) return false;
|
||||
return targetContainer == null || super.canMove(elements, targetContainer);
|
||||
return targetContainer == null || super.canMove(elements, targetContainer, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -64,7 +67,12 @@ public class MoveInstanceMethodHandlerDelegate extends MoveHandlerDelegate {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getActionName(PsiElement[] elements) {
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
return "Move Instance Method...";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return language == JavaLanguage.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,21 +15,24 @@
|
||||
*/
|
||||
package com.intellij.refactoring.move.moveMembers;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.jvm.JvmLanguage;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class MoveMembersHandler extends MoveHandlerDelegate {
|
||||
@Override
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer) {
|
||||
public boolean canMove(final PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
for(PsiElement element: elements) {
|
||||
if (!isFieldOrStaticMethod(element)) return false;
|
||||
}
|
||||
return targetContainer == null || super.canMove(elements, targetContainer);
|
||||
return targetContainer == null || super.canMove(elements, targetContainer, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -63,10 +66,12 @@ public class MoveMembersHandler extends MoveHandlerDelegate {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getActionName(PsiElement[] elements) {
|
||||
if (elements.length == 1) {
|
||||
return "Move Member...";
|
||||
}
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
return "Move Members...";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return language instanceof JvmLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
void foo() {
|
||||
new Ru<caret>nnable() {
|
||||
public void run() { }
|
||||
}.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
class Foo {
|
||||
public static class Ba<caret>r {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
class C {
|
||||
public void f<caret>oo() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class C {
|
||||
public void foo() {
|
||||
}
|
||||
<caret>
|
||||
public void bar() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class C {
|
||||
public static void foo() {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.java.refactoring
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.refactoring.move.MoveHandler
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
class MoveActionNameTest : LightCodeInsightFixtureTestCase() {
|
||||
private val TEST_ROOT = "/refactoring/moveActionName/"
|
||||
|
||||
override fun getTestDataPath(): String {
|
||||
return JavaTestUtil.getJavaTestDataPath()
|
||||
}
|
||||
|
||||
fun testStaticMethod() {
|
||||
assertEquals("Move Members...", doTest())
|
||||
}
|
||||
|
||||
fun testInstanceMethod() {
|
||||
assertEquals("Move Instance Method...", doTest())
|
||||
}
|
||||
|
||||
fun testMoveClass() {
|
||||
assertEquals("Move Class...", doTest())
|
||||
}
|
||||
|
||||
fun testInnerClass() {
|
||||
assertEquals("Move Inner Class...", doTest())
|
||||
}
|
||||
|
||||
fun testAnonymousToInner() {
|
||||
assertEquals("Convert Anonymous to Inner...", doTest())
|
||||
}
|
||||
|
||||
private fun doTest(): String? {
|
||||
myFixture.configureByFile(TEST_ROOT + getTestName(true) + ".java")
|
||||
return MoveHandler.getActionName((myFixture.editor as EditorEx).dataContext)
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ public class MoveClassAndFileTest extends LightMultiFileTestCase {
|
||||
assertEquals(1, dirs.length);
|
||||
|
||||
final JavaMoveFilesOrDirectoriesHandler handler = new JavaMoveFilesOrDirectoriesHandler();
|
||||
assertTrue(handler.canMove(elements, dirs[0]));
|
||||
assertTrue(handler.canMove(elements, dirs[0], null));
|
||||
handler.doMove(getProject(), elements, dirs[0], null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ public abstract class BaseRefactoringAction extends AnAction implements UpdateIn
|
||||
disableAction(e);
|
||||
}
|
||||
else {
|
||||
updateActionText(e, elements);
|
||||
updateActionText(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -189,7 +189,7 @@ public abstract class BaseRefactoringAction extends AnAction implements UpdateIn
|
||||
disableAction(e);
|
||||
}
|
||||
else {
|
||||
updateActionText(e, new PsiElement[] { element });
|
||||
updateActionText(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -198,15 +198,15 @@ public abstract class BaseRefactoringAction extends AnAction implements UpdateIn
|
||||
}
|
||||
}
|
||||
|
||||
private void updateActionText(AnActionEvent e, PsiElement[] elements) {
|
||||
String actionText = getActionName(elements);
|
||||
private void updateActionText(AnActionEvent e) {
|
||||
String actionText = getActionName(e.getDataContext());
|
||||
if (actionText != null) {
|
||||
e.getPresentation().setText(actionText);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getActionName(@NotNull PsiElement[] elements) {
|
||||
protected String getActionName(@NotNull DataContext dataContext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ public class MoveAction extends BaseRefactoringAction {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String getActionName(@NotNull PsiElement[] elements) {
|
||||
return MoveHandler.getActionName(elements);
|
||||
protected String getActionName(@NotNull DataContext dataContext) {
|
||||
return MoveHandler.getActionName(dataContext);
|
||||
}
|
||||
}
|
||||
@@ -2,25 +2,26 @@
|
||||
|
||||
package com.intellij.refactoring.move;
|
||||
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.actions.BaseRefactoringAction;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesUtil;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MoveHandler implements RefactoringActionHandler {
|
||||
@@ -38,40 +39,41 @@ public class MoveHandler implements RefactoringActionHandler {
|
||||
element = file;
|
||||
}
|
||||
|
||||
final TextRange range = element.getTextRange();
|
||||
if (range != null) {
|
||||
int relative = offset - range.getStartOffset();
|
||||
final PsiReference reference = element.findReferenceAt(relative);
|
||||
if (reference != null) {
|
||||
final PsiElement refElement = reference.resolve();
|
||||
if (refElement != null && tryToMoveElement(refElement, project, dataContext, reference, editor)) return;
|
||||
PsiReference reference = findReferenceAtCaret(element, offset);
|
||||
if (reference != null) {
|
||||
PsiElement refElement = reference.resolve();
|
||||
for(MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
if (delegate.tryToMove(refElement, project, dataContext, reference, editor)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(true){
|
||||
List<MoveHandlerDelegate> candidateHandlers = findHandlersForLanguage(element);
|
||||
while (true) {
|
||||
if (element == null) {
|
||||
String message = RefactoringBundle.getCannotRefactorMessage(RefactoringBundle.message("the.caret.should.be.positioned.at.the.class.method.or.field.to.be.refactored"));
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tryToMoveElement(element, project, dataContext, null, editor)) {
|
||||
return;
|
||||
for(MoveHandlerDelegate delegate: candidateHandlers) {
|
||||
if (delegate.tryToMove(element, project, dataContext, null, editor)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
element = element.getParent();
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean tryToMoveElement(final PsiElement element, final Project project, final DataContext dataContext,
|
||||
final PsiReference reference, final Editor editor) {
|
||||
for(MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
if (delegate.tryToMove(element, project, dataContext, reference, editor)) {
|
||||
return true;
|
||||
}
|
||||
private static PsiReference findReferenceAtCaret(PsiElement element, int caretOffset) {
|
||||
final TextRange range = element.getTextRange();
|
||||
if (range != null) {
|
||||
int relative = caretOffset - range.getStartOffset();
|
||||
return element.findReferenceAt(relative);
|
||||
}
|
||||
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -112,7 +114,7 @@ public class MoveHandler implements RefactoringActionHandler {
|
||||
if (elements.length == 0) return;
|
||||
|
||||
for(MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
if (delegate.canMove(elements, targetContainer)) {
|
||||
if (delegate.canMove(elements, targetContainer, null)) {
|
||||
delegate.doMove(project, elements, delegate.adjustTargetForMove(dataContext, targetContainer), callback);
|
||||
break;
|
||||
}
|
||||
@@ -126,7 +128,7 @@ public class MoveHandler implements RefactoringActionHandler {
|
||||
@Nullable
|
||||
public static PsiElement[] adjustForMove(Project project, final PsiElement[] sourceElements, final PsiElement targetElement) {
|
||||
for(MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
if (delegate.canMove(sourceElements, targetElement)) {
|
||||
if (delegate.canMove(sourceElements, targetElement, null)) {
|
||||
return delegate.adjustForMove(project, sourceElements, targetElement);
|
||||
}
|
||||
}
|
||||
@@ -138,24 +140,69 @@ public class MoveHandler implements RefactoringActionHandler {
|
||||
* target container can be null => means that container is not determined yet and must be spacify by the user
|
||||
*/
|
||||
public static boolean canMove(@NotNull PsiElement[] elements, PsiElement targetContainer) {
|
||||
for(MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
if (delegate.canMove(elements, targetContainer)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return findDelegate(elements, targetContainer, null) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getActionName(@NotNull PsiElement[] elements) {
|
||||
for(MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
if (delegate.canMove(elements, null)) return delegate.getActionName(elements);
|
||||
private static MoveHandlerDelegate findDelegate(@NotNull PsiElement[] elements, @Nullable PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
for (MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
if (delegate.canMove(elements, targetContainer, reference)) {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getActionName(@NotNull DataContext dataContext) {
|
||||
Editor editor = dataContext.getData(CommonDataKeys.EDITOR);
|
||||
if (editor != null) {
|
||||
Project project = dataContext.getData(CommonDataKeys.PROJECT);
|
||||
if (project == null) return null;
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (file == null) return null;
|
||||
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
if (element == null) element = file;
|
||||
|
||||
PsiReference reference = findReferenceAtCaret(element, editor.getCaretModel().getOffset());
|
||||
if (reference != null) {
|
||||
PsiElement refElement = reference.resolve();
|
||||
MoveHandlerDelegate refDelegate = findDelegate(new PsiElement[]{refElement}, null, reference);
|
||||
if (refDelegate != null) {
|
||||
return refDelegate.getActionName(new PsiElement[] { refElement });
|
||||
}
|
||||
}
|
||||
|
||||
// invoke() uses regular findElementAtCaret() instead of BaseRefactoringAction.getElementAtCaret(), match it
|
||||
List<MoveHandlerDelegate> candidateHandlers = findHandlersForLanguage(element);
|
||||
while (element != null) {
|
||||
PsiElement[] elementArray = {element};
|
||||
for (MoveHandlerDelegate handler : candidateHandlers) {
|
||||
if (handler.canMove(elementArray, null, reference)) {
|
||||
return handler.getActionName(elementArray);
|
||||
}
|
||||
}
|
||||
element = element.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
PsiElement[] elements = BaseRefactoringAction.getPsiElementArray(dataContext);
|
||||
List<MoveHandlerDelegate> delegates = MoveHandlerDelegate.EP_NAME.getExtensionList();
|
||||
for(MoveHandlerDelegate delegate: delegates) {
|
||||
if (delegate.canMove(elements, null, null)) return delegate.getActionName(elements);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<MoveHandlerDelegate> findHandlersForLanguage(@NotNull PsiElement element) {
|
||||
return ContainerUtil.filter(MoveHandlerDelegate.EP_NAME.getExtensionList(),
|
||||
(delegate) -> delegate.supportsLanguage(element.getLanguage()));
|
||||
}
|
||||
|
||||
public static boolean isValidTarget(final PsiElement psiElement, PsiElement[] elements) {
|
||||
if (psiElement != null) {
|
||||
for(MoveHandlerDelegate delegate: MoveHandlerDelegate.EP_NAME.getExtensionList()) {
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
package com.intellij.refactoring.move;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -32,6 +34,14 @@ import java.util.Set;
|
||||
public abstract class MoveHandlerDelegate {
|
||||
public static final ExtensionPointName<MoveHandlerDelegate> EP_NAME = ExtensionPointName.create("com.intellij.refactoring.moveHandler");
|
||||
|
||||
public boolean canMove(PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
return canMove(elements, targetContainer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please overload the method with 'reference' parameter instead
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean canMove(PsiElement[] elements, @Nullable final PsiElement targetContainer) {
|
||||
return isValidTarget(targetContainer, elements);
|
||||
}
|
||||
@@ -72,9 +82,12 @@ public abstract class MoveHandlerDelegate {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String getActionName(PsiElement[] elements) {
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.refactoring.move.MoveCallback;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -37,7 +38,7 @@ public class MoveFilesOrDirectoriesHandler extends MoveHandlerDelegate {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesHandler");
|
||||
|
||||
@Override
|
||||
public boolean canMove(final PsiElement[] elements, final PsiElement targetContainer) {
|
||||
public boolean canMove(final PsiElement[] elements, final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
HashSet<String> names = new HashSet<>();
|
||||
for (PsiElement element : elements) {
|
||||
if (element instanceof PsiFile) {
|
||||
@@ -53,7 +54,7 @@ public class MoveFilesOrDirectoriesHandler extends MoveHandlerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
return super.canMove(elements, targetContainer);
|
||||
return super.canMove(elements, targetContainer, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,4 +111,25 @@ public class MoveFilesOrDirectoriesHandler extends MoveHandlerDelegate {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getActionName(@NotNull PsiElement[] elements) {
|
||||
int fileCount = 0, directoryCount = 0;
|
||||
for (PsiElement element : elements) {
|
||||
if (element instanceof PsiFile) {
|
||||
fileCount++;
|
||||
}
|
||||
else if (element instanceof PsiDirectory) {
|
||||
directoryCount++;
|
||||
}
|
||||
}
|
||||
if (directoryCount == 0) {
|
||||
return fileCount == 1 ? "Move File..." : "Move Files...";
|
||||
}
|
||||
if (fileCount == 0) {
|
||||
return directoryCount == 1 ? "Move Directory..." : "Move Directories...";
|
||||
}
|
||||
return "Move Files and Directories...";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import gnu.trove.THashSet;
|
||||
@@ -35,8 +36,8 @@ import java.util.Set;
|
||||
|
||||
public class MoveRelatedFilesHandler extends MoveFilesOrDirectoriesHandler {
|
||||
@Override
|
||||
public boolean canMove(PsiElement[] elements, PsiElement targetContainer) {
|
||||
if (!super.canMove(elements, targetContainer)) return false;
|
||||
public boolean canMove(PsiElement[] elements, PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
if (!super.canMove(elements, targetContainer, reference)) return false;
|
||||
|
||||
for (PsiElement element : elements) {
|
||||
if (element instanceof PsiFile &&
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
// found in the LICENSE file.
|
||||
package com.intellij.lang.properties.projectView;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.properties.ResourceBundle;
|
||||
import com.intellij.lang.properties.psi.PropertiesFile;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
@@ -25,7 +28,7 @@ public class ResourceBundleMoveProvider extends MoveHandlerDelegate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove(PsiElement[] elements, @Nullable final PsiElement targetContainer) {
|
||||
public boolean canMove(PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -54,4 +57,9 @@ public class ResourceBundleMoveProvider extends MoveHandlerDelegate {
|
||||
}
|
||||
return super.isMoveRedundant(source, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return false; // only available in project view
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,15 +2,18 @@
|
||||
|
||||
package com.intellij.uiDesigner.projectView;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate;
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesHandler;
|
||||
import com.intellij.uiDesigner.GuiFormFileType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -33,7 +36,7 @@ public class FormMoveProvider extends MoveHandlerDelegate {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canMove(PsiElement[] elements, @Nullable final PsiElement targetContainer) {
|
||||
public boolean canMove(PsiElement[] elements, @Nullable final PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -69,4 +72,9 @@ public class FormMoveProvider extends MoveHandlerDelegate {
|
||||
}
|
||||
return super.isMoveRedundant(source, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return false; // only available in project view
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.jetbrains.python.refactoring.move;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -37,6 +38,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
@@ -65,8 +67,8 @@ import static com.jetbrains.python.psi.PyUtil.as;
|
||||
*/
|
||||
public class PyMoveSymbolDelegate extends MoveHandlerDelegate {
|
||||
@Override
|
||||
public boolean canMove(PsiElement[] elements, @Nullable PsiElement targetContainer) {
|
||||
if (targetContainer != null && !super.canMove(elements, targetContainer)) {
|
||||
public boolean canMove(PsiElement[] elements, @Nullable PsiElement targetContainer, @Nullable PsiReference reference) {
|
||||
if (targetContainer != null && !super.canMove(elements, targetContainer, reference)) {
|
||||
return false;
|
||||
}
|
||||
// Local function or method
|
||||
@@ -211,4 +213,11 @@ public class PyMoveSymbolDelegate extends MoveHandlerDelegate {
|
||||
private static boolean isLocalFunction(@Nullable PsiElement resolved) {
|
||||
return resolved instanceof PyFunction && PsiTreeUtil.getParentOfType(resolved, ScopeOwner.class, true) instanceof PyFunction;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean supportsLanguage(@NotNull Language language) {
|
||||
return language.isKindOf(PythonLanguage.getInstance());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -397,7 +397,6 @@
|
||||
<action id="RemoveMiddleman" class="com.intellij.refactoring.actions.RemoveMiddlemanAction"/>
|
||||
<action id="WrapReturnValue" class="com.intellij.refactoring.wrapreturnvalue.WrapReturnValueAction"/>
|
||||
<separator/>
|
||||
<action id="AnonymousToInner" class="com.intellij.refactoring.actions.AnonymousToInnerAction"/>
|
||||
<action id="EncapsulateFields" class="com.intellij.refactoring.actions.EncapsulateFieldsAction"/>
|
||||
<action id="ReplaceTempWithQuery" class="com.intellij.refactoring.actions.TempWithQueryAction"/>
|
||||
<action id="ReplaceConstructorWithFactory" class="com.intellij.refactoring.actions.ReplaceConstructorWithFactoryAction"/>
|
||||
@@ -410,6 +409,10 @@
|
||||
<add-to-group group-id="RefactoringMenu" anchor="after" relative-to-action="MemberPushDown"/>
|
||||
</group>
|
||||
|
||||
<!-- The action remains for compabitility but is not added to menus because it does the same thing as Move, which is now
|
||||
correctly labeled -->
|
||||
<action id="AnonymousToInner" class="com.intellij.refactoring.actions.AnonymousToInnerAction"/>
|
||||
|
||||
<action id="Hotswap" class="com.intellij.debugger.actions.HotSwapAction">
|
||||
<add-to-group group-id="DebugMainMenu" anchor="after" relative-to-action="UpdateRunningApplication"/>
|
||||
</action>
|
||||
|
||||
Reference in New Issue
Block a user