mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Generate delegate methods action moved to lang-impl: take 2
This commit is contained in:
+79
-22
@@ -15,11 +15,13 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.ide.util.MemberChooser;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
@@ -28,6 +30,8 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
@@ -43,27 +47,62 @@ import java.util.Set;
|
||||
/**
|
||||
* @author mike
|
||||
*/
|
||||
public class GenerateDelegateHandler implements CodeInsightActionHandler {
|
||||
public class GenerateDelegateHandler implements ElementsHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.GenerateDelegateHandler");
|
||||
|
||||
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
|
||||
if (!FileDocumentManager.getInstance().requestWriting(editor.getDocument(), project)) {
|
||||
@Override
|
||||
public boolean isEnabledOnElements(PsiElement[] elements) {
|
||||
if (elements.length != 1) return false;
|
||||
if (!(elements[0].getContainingFile() instanceof PsiJavaFile)) return false;
|
||||
return OverrideImplementUtil.getContextClass(elements[0], false) != null && isApplicable(elements[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, @NotNull PsiElement[] elements, DataContext dataContext) {
|
||||
doInvoke(project, null, elements[0].getContainingFile(), elements[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, final Editor editor, final PsiFile file, DataContext dataContext) {
|
||||
doInvoke(project, editor, file, null);
|
||||
}
|
||||
|
||||
private void doInvoke(@NotNull Project project, @Nullable final Editor editor, final PsiFile file, @Nullable PsiElement element) {
|
||||
Document document;
|
||||
if (editor != null) {
|
||||
document = editor.getDocument();
|
||||
}
|
||||
else {
|
||||
document = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
}
|
||||
if (!FileDocumentManager.getInstance().requestWriting(document, project)) {
|
||||
return;
|
||||
}
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
|
||||
final PsiElement target = chooseTarget(file, editor, project);
|
||||
final PsiElement target;
|
||||
if (editor != null) {
|
||||
target = chooseTarget(file, editor, project);
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
element = file.findElementAt(offset);
|
||||
} else {
|
||||
target = chooseTarget(element);
|
||||
}
|
||||
if (target == null) return;
|
||||
|
||||
final PsiMethodMember[] candidates = chooseMethods(target, file, editor, project);
|
||||
final PsiMethodMember[] candidates = chooseMethods(target, element, project);
|
||||
if (candidates == null || candidates.length == 0) return;
|
||||
|
||||
final int offset;
|
||||
if (editor != null) {
|
||||
offset = editor.getCaretModel().getOffset();
|
||||
} else {
|
||||
offset = element.getTextRange().getStartOffset();
|
||||
}
|
||||
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
final Runnable r = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
|
||||
List<PsiGenerationInfo<PsiMethod>> prototypes = new ArrayList<PsiGenerationInfo<PsiMethod>>(candidates.length);
|
||||
for (PsiMethodMember candidate : candidates) {
|
||||
prototypes.add(generateDelegatePrototype(candidate, target));
|
||||
@@ -71,7 +110,7 @@ public class GenerateDelegateHandler implements CodeInsightActionHandler {
|
||||
|
||||
List<PsiGenerationInfo<PsiMethod>> results = GenerateMembersUtil.insertMembersAtOffset(file, offset, prototypes);
|
||||
|
||||
if (!results.isEmpty()) {
|
||||
if (!results.isEmpty() && editor != null) {
|
||||
PsiMethod firstMethod = results.get(0).getPsiMember();
|
||||
final PsiCodeBlock block = firstMethod.getBody();
|
||||
assert block != null;
|
||||
@@ -86,11 +125,15 @@ public class GenerateDelegateHandler implements CodeInsightActionHandler {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
public void run() {
|
||||
ApplicationManager.getApplication().runWriteAction(r);
|
||||
}
|
||||
}, RefactoringBundle.message("delegate.methods.refactoring.name"), null);
|
||||
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static PsiGenerationInfo<PsiMethod> generateDelegatePrototype(PsiMethodMember methodCandidate, PsiElement target) throws IncorrectOperationException {
|
||||
@@ -190,7 +233,7 @@ public class GenerateDelegateHandler implements CodeInsightActionHandler {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethodMember[] chooseMethods(PsiElement target, PsiFile file, Editor editor, Project project) {
|
||||
private static PsiMethodMember[] chooseMethods(PsiElement target, PsiElement element, Project project) {
|
||||
PsiClassType.ClassResolveResult resolveResult = null;
|
||||
|
||||
if (target instanceof PsiField) {
|
||||
@@ -204,10 +247,8 @@ public class GenerateDelegateHandler implements CodeInsightActionHandler {
|
||||
PsiClass targetClass = resolveResult.getElement();
|
||||
PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element == null) return null;
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
|
||||
if (aClass == null) return null;
|
||||
|
||||
List<PsiMethodMember> methodInstances = new ArrayList<PsiMethodMember>();
|
||||
@@ -254,16 +295,28 @@ public class GenerateDelegateHandler implements CodeInsightActionHandler {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean isApplicable(PsiFile file, Editor editor) {
|
||||
ClassMember[] targetElements = getTargetElements(file, editor);
|
||||
private static boolean isApplicable(PsiElement element) {
|
||||
ClassMember[] targetElements = getTargetElements(element);
|
||||
return targetElements != null && targetElements.length > 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement chooseTarget(PsiFile file, Editor editor, Project project) {
|
||||
PsiElement target = null;
|
||||
final PsiElementClassMember[] targetElements = getTargetElements(file, editor);
|
||||
return doChooseTarget(project, targetElements);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement chooseTarget(PsiElement element) {
|
||||
final PsiElementClassMember[] targetElements = getTargetElements(element);
|
||||
return doChooseTarget(element.getProject(), targetElements);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiElement doChooseTarget(Project project, PsiElementClassMember[] targetElements) {
|
||||
if (targetElements == null || targetElements.length == 0) return null;
|
||||
|
||||
PsiElement target = null;
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
MemberChooser<PsiElementClassMember> chooser = new MemberChooser<PsiElementClassMember>(targetElements, false, false, project);
|
||||
chooser.setTitle(CodeInsightBundle.message("generate.delegate.target.chooser.title"));
|
||||
@@ -287,7 +340,11 @@ public class GenerateDelegateHandler implements CodeInsightActionHandler {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
if (element == null) return null;
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
return getTargetElements(element);
|
||||
}
|
||||
|
||||
private static PsiElementClassMember[] getTargetElements(PsiElement element) {
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
|
||||
if (aClass == null) return null;
|
||||
|
||||
List<PsiElementClassMember> result = new ArrayList<PsiElementClassMember>();
|
||||
|
||||
@@ -696,8 +696,12 @@ public class OverrideImplementUtil {
|
||||
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
PsiElement element = file.findElementAt(offset);
|
||||
return getContextClass(element, allowInterface);
|
||||
}
|
||||
|
||||
public static PsiClass getContextClass(PsiElement element, boolean allowInterface) {
|
||||
do {
|
||||
element = PsiTreeUtil.getParentOfType(element, PsiClass.class);
|
||||
element = PsiTreeUtil.getParentOfType(element, PsiClass.class, false);
|
||||
}
|
||||
while (element instanceof PsiTypeParameter);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.lang.java;
|
||||
|
||||
import com.intellij.codeInsight.generation.GenerateDelegateHandler;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
@@ -97,6 +98,11 @@ public class JavaRefactoringSupportProvider extends RefactoringSupportProvider {
|
||||
return new ExtractClassHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefactoringActionHandler getGenerateDelegateHander() {
|
||||
return new GenerateDelegateHandler();
|
||||
}
|
||||
|
||||
public static boolean mayRenameInplace(PsiElement elementToRename, final PsiElement nameSuggestionContext) {
|
||||
if (!(elementToRename instanceof PsiVariable)) return false;
|
||||
if (nameSuggestionContext != null && nameSuggestionContext.getContainingFile() != elementToRename.getContainingFile()) return false;
|
||||
|
||||
@@ -133,4 +133,13 @@ public abstract class RefactoringSupportProvider {
|
||||
public RefactoringActionHandler getExtractClassHandler() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return handler for generating delegate methods in this language
|
||||
* @see com.intellij.refactoring.RefactoringActionHandler
|
||||
*/
|
||||
@Nullable
|
||||
public RefactoringActionHandler getGenerateDelegateHander() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+30
-17
@@ -13,30 +13,43 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.generation.actions;
|
||||
package com.intellij.refactoring.actions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.actions.BaseCodeInsightAction;
|
||||
import com.intellij.codeInsight.generation.GenerateDelegateHandler;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.refactoring.RefactoringActionHandler;
|
||||
import com.intellij.refactoring.lang.ElementsHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author mike
|
||||
*/
|
||||
public class GenerateDelegateAction extends BaseCodeInsightAction {
|
||||
private final GenerateDelegateHandler myHandler = new GenerateDelegateHandler();
|
||||
public class GenerateDelegateAction extends BasePlatformRefactoringAction {
|
||||
|
||||
protected CodeInsightActionHandler getHandler() {
|
||||
return myHandler;
|
||||
public GenerateDelegateAction() {
|
||||
setInjectedContext(true);
|
||||
}
|
||||
|
||||
protected boolean isValidForFile(Project project, Editor editor, PsiFile file) {
|
||||
if (!(file instanceof PsiJavaFile)) return false;
|
||||
return OverrideImplementUtil.getContextClass(project, editor, file, false) != null &&
|
||||
myHandler.isApplicable(file, editor);
|
||||
@Override
|
||||
protected boolean isAvailableInEditorOnly() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledOnElements(PsiElement[] elements) {
|
||||
if (elements.length > 0) {
|
||||
final Language language = elements[0].getLanguage();
|
||||
final RefactoringActionHandler handler = getRefactoringHandler(LanguageRefactoringSupport.INSTANCE.forLanguage(language));
|
||||
return handler instanceof ElementsHandler && ((ElementsHandler)handler).isEnabledOnElements(elements);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RefactoringActionHandler getRefactoringHandler(@NotNull RefactoringSupportProvider provider) {
|
||||
return provider.getGenerateDelegateHander();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -742,3 +742,4 @@ refactoring.extract.method.dialog.empty=Empty
|
||||
change.signature.leave.blank.default.value=Leave &blank
|
||||
change.signature.feel.lucky=Feel &lucky
|
||||
change.signature.use.selected.value=Use selected &value
|
||||
delegate.methods.refactoring.name=Delegate methods
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<group id="GenerateGroup">
|
||||
<action id="OverrideMethods" class="com.intellij.codeInsight.generation.actions.OverrideMethodsAction"/>
|
||||
<action id="ImplementMethods" class="com.intellij.codeInsight.generation.actions.ImplementMethodsAction"/>
|
||||
<action id="DelegateMethods" class="com.intellij.refactoring.actions.GenerateDelegateAction"/>
|
||||
</group>
|
||||
|
||||
<action id="ShowIntentionActions" class="com.intellij.codeInsight.intention.actions.ShowIntentionActionsAction"/>
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
</group>
|
||||
|
||||
<group id="JavaGenerateGroup2">
|
||||
<action id="DelegateMethods" class="com.intellij.codeInsight.generation.actions.GenerateDelegateAction"/>
|
||||
<action id="GenerateSuperMethodCall" class="com.intellij.codeInsight.generation.actions.GenerateSuperMethodCallAction"/>
|
||||
|
||||
<add-to-group group-id="GenerateGroup" anchor="last"/>
|
||||
|
||||
Reference in New Issue
Block a user