mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Quick Fix: Create Abstract Method from Usage
This commit is contained in:
+2
@@ -350,6 +350,7 @@ public class HighlightMethodUtil {
|
||||
else {
|
||||
TextRange range = getFixRange(methodCall);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, new CreateMethodFromUsageFix(methodCall), null);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, new CreateAbstractMethodFromUsageFix(methodCall), null);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, range, new CreatePropertyFromUsageFix(methodCall), null);
|
||||
}
|
||||
}
|
||||
@@ -461,6 +462,7 @@ public class HighlightMethodUtil {
|
||||
PsiExpressionList list, PsiResolveHelper resolveHelper) {
|
||||
TextRange fixRange = getFixRange(methodCall);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new CreateMethodFromUsageFix(methodCall), null);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new CreateAbstractMethodFromUsageFix(methodCall), null);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new CreateConstructorFromSuperFix(methodCall), null);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new CreateConstructorFromThisFix(methodCall), null);
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, fixRange, new CreatePropertyFromUsageFix(methodCall), null);
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CreateAbstractMethodFromUsageFix extends CreateMethodFromUsageFix {
|
||||
public CreateAbstractMethodFromUsageFix(PsiMethodCallExpression methodCall) {
|
||||
super(methodCall);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDisplayString(String name) {
|
||||
return QuickFixBundle.message("create.abstract.method.from.usage.text", name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected List<PsiClass> getTargetClasses(PsiElement element) {
|
||||
List<PsiClass> result = new ArrayList<PsiClass>();
|
||||
PsiReferenceExpression expr = getMethodCall().getMethodExpression();
|
||||
for (PsiClass each : super.getTargetClasses(element)) {
|
||||
if (PsiUtil.isAbstractClass(each) && !each.isInterface() && !shouldCreateStaticMember(expr, each)) result.add(each);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getVisibility(PsiClass parentClass, PsiClass targetClass) {
|
||||
String result = super.getVisibility(parentClass, targetClass);
|
||||
return PsiModifier.PUBLIC.equals(result) ? result : PsiModifier.PROTECTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldBeAbstract(PsiClass targetClass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+7
-3
@@ -20,6 +20,7 @@ import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -134,16 +135,19 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
|
||||
return FileEditorManager.getInstance(project).openTextEditor(descriptor, true);
|
||||
}
|
||||
|
||||
protected static void setupVisibility(PsiClass parentClass, PsiClass targetClass, PsiModifierList list) throws IncorrectOperationException {
|
||||
protected void setupVisibility(PsiClass parentClass, PsiClass targetClass, PsiModifierList list) throws IncorrectOperationException {
|
||||
if (targetClass.isInterface()) {
|
||||
list.deleteChildRange(list.getFirstChild(), list.getLastChild());
|
||||
return;
|
||||
}
|
||||
RefactoringUtil.setVisibility(list, getVisibility(parentClass, targetClass));
|
||||
}
|
||||
|
||||
protected String getVisibility(PsiClass parentClass, PsiClass targetClass) {
|
||||
if (parentClass != null && (parentClass.equals(targetClass) || PsiTreeUtil.isAncestor(targetClass, parentClass, true))) {
|
||||
list.setModifierProperty(PsiModifier.PRIVATE, true);
|
||||
return PsiModifier.PRIVATE;
|
||||
} else {
|
||||
list.setModifierProperty(PsiModifier.PUBLIC, true);
|
||||
return PsiModifier.PUBLIC;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+33
-7
@@ -50,10 +50,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
|
||||
if (name == null || !JavaPsiFacade.getInstance(ref.getProject()).getNameHelper().isIdentifier(name)) return false;
|
||||
if (hasErrorsInArgumentList(call)) return false;
|
||||
setText(QuickFixBundle.message("create.method.from.usage.text", name));
|
||||
setText(getDisplayString(name));
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String getDisplayString(String name) {
|
||||
return QuickFixBundle.message("create.method.from.usage.text", name);
|
||||
}
|
||||
|
||||
private static boolean isMethodSignatureExists(PsiMethodCallExpression call, PsiClass target) {
|
||||
String name = call.getMethodExpression().getReferenceName();
|
||||
PsiExpressionList list = call.getArgumentList();
|
||||
@@ -142,20 +146,24 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
|
||||
PsiCodeBlock body = method.getBody();
|
||||
assert body != null;
|
||||
if (targetClass.isInterface()) {
|
||||
if (shouldBeAbstract(targetClass)) {
|
||||
body.delete();
|
||||
if (!targetClass.isInterface()) {
|
||||
method.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, true);
|
||||
}
|
||||
}
|
||||
|
||||
setupVisibility(parentClass, targetClass, method.getModifierList());
|
||||
|
||||
if (shouldCreateStaticMember(expression.getMethodExpression(), targetClass) && !targetClass.isInterface()) {
|
||||
if (shouldCreateStaticMember(expression.getMethodExpression(), targetClass) && !shouldBeAbstract(targetClass)) {
|
||||
PsiUtil.setModifierProperty(method, PsiModifier.STATIC, true);
|
||||
}
|
||||
|
||||
final PsiElement context = PsiTreeUtil.getParentOfType(expression, PsiClass.class, PsiMethod.class);
|
||||
|
||||
PsiExpression[] arguments = expression.getArgumentList().getExpressions();
|
||||
doCreate(targetClass, method, ContainerUtil.map2List(arguments, new Function<PsiExpression, Pair<PsiExpression, PsiType>>() {
|
||||
doCreate(targetClass, method, shouldBeAbstract(targetClass),
|
||||
ContainerUtil.map2List(arguments, new Function<PsiExpression, Pair<PsiExpression, PsiType>>() {
|
||||
public Pair<PsiExpression, PsiType> fun(PsiExpression psiExpression) {
|
||||
return Pair.create(psiExpression, null);
|
||||
}
|
||||
@@ -169,6 +177,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
|
||||
public static void doCreate(PsiClass targetClass, PsiMethod method, List<Pair<PsiExpression, PsiType>> arguments, PsiSubstitutor substitutor,
|
||||
ExpectedTypeInfo[] expectedTypes, @Nullable PsiElement context) {
|
||||
doCreate(targetClass, method, shouldBeAbstractImpl(targetClass), arguments, substitutor, expectedTypes, context);
|
||||
}
|
||||
|
||||
private static void doCreate(PsiClass targetClass,
|
||||
PsiMethod method,
|
||||
boolean shouldBeAbstract,
|
||||
List<Pair<PsiExpression, PsiType>> arguments,
|
||||
PsiSubstitutor substitutor,
|
||||
ExpectedTypeInfo[] expectedTypes,
|
||||
@Nullable PsiElement context) {
|
||||
|
||||
method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method);
|
||||
|
||||
@@ -185,7 +203,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
new GuessTypeParameters(JavaPsiFacade.getInstance(project).getElementFactory())
|
||||
.setupTypeElement(method.getReturnTypeElement(), expectedTypes, substitutor, builder, context, targetClass);
|
||||
PsiCodeBlock body = method.getBody();
|
||||
builder.setEndVariableAfter(targetClass.isInterface() || body == null ? method : body.getLBrace());
|
||||
builder.setEndVariableAfter(shouldBeAbstract || body == null ? method : body.getLBrace());
|
||||
method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method);
|
||||
if (method == null) return;
|
||||
|
||||
@@ -196,7 +214,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
newEditor.getCaretModel().moveToOffset(rangeMarker.getStartOffset());
|
||||
newEditor.getDocument().deleteString(rangeMarker.getStartOffset(), rangeMarker.getEndOffset());
|
||||
|
||||
if (!targetClass.isInterface()) {
|
||||
if (!shouldBeAbstract) {
|
||||
startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
|
||||
public void templateFinished(Template template) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@@ -225,6 +243,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean shouldBeAbstract(PsiClass targetClass) {
|
||||
return shouldBeAbstractImpl(targetClass);
|
||||
}
|
||||
|
||||
private static boolean shouldBeAbstractImpl(PsiClass targetClass) {
|
||||
return targetClass.isInterface();
|
||||
}
|
||||
|
||||
protected boolean isValidElement(PsiElement element) {
|
||||
PsiMethodCallExpression callExpression = (PsiMethodCallExpression) element;
|
||||
PsiReferenceExpression referenceExpression = callExpression.getMethodExpression();
|
||||
@@ -238,7 +264,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageBaseFix {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiMethodCallExpression getMethodCall() {
|
||||
protected PsiMethodCallExpression getMethodCall() {
|
||||
return (PsiMethodCallExpression)myMethodCall.getElement();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,6 +220,11 @@ public final class PsiUtil extends PsiUtilBase {
|
||||
return parent instanceof PsiDeclarationStatement && parent.getParent() instanceof PsiCodeBlock;
|
||||
}
|
||||
|
||||
public static boolean isAbstractClass(PsiClass clazz) {
|
||||
PsiModifierList modifierList = clazz.getModifierList();
|
||||
return modifierList != null && modifierList.hasModifierProperty(PsiModifier.ABSTRACT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return codeblock topmost codeblock where variable makes sense
|
||||
*/
|
||||
|
||||
@@ -84,6 +84,7 @@ create.local.from.instanceof.usage.family=Create Local Var from instanceof Usage
|
||||
create.local.from.instanceof.usage.text=Insert ''({0}){1}'' declaration
|
||||
create.method.from.usage.family=Create Method from Usage
|
||||
create.method.from.usage.text=Create Method ''{0}''
|
||||
create.abstract.method.from.usage.text=Create Abstract Method ''{0}''
|
||||
create.parameter.from.usage.family=Create Parameter from Usage
|
||||
create.parameter.from.usage.text=Create Parameter ''{0}''
|
||||
create.property.from.usage.family=Create Property From Usage
|
||||
|
||||
Reference in New Issue
Block a user