mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
method refs: fix qualifier when static method is moved; show conflict if instance method is moved
This commit is contained in:
+5
-4
@@ -15,7 +15,8 @@
|
||||
*/
|
||||
package com.intellij.refactoring.move.moveInstanceMethod;
|
||||
|
||||
import com.intellij.psi.PsiMethodCallExpression;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethodReferenceExpression;
|
||||
import com.intellij.psi.PsiReferenceExpression;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
|
||||
@@ -23,16 +24,16 @@ import com.intellij.usageView.UsageInfo;
|
||||
* @author ven
|
||||
*/
|
||||
public class MethodCallUsageInfo extends UsageInfo {
|
||||
private final PsiMethodCallExpression myMethodCallExpression;
|
||||
private final PsiElement myMethodCallExpression;
|
||||
private final boolean myIsInternal;
|
||||
|
||||
public MethodCallUsageInfo(final PsiReferenceExpression referenceExpression, final boolean internal) {
|
||||
super(referenceExpression);
|
||||
myIsInternal = internal;
|
||||
myMethodCallExpression = (PsiMethodCallExpression)referenceExpression.getParent();
|
||||
myMethodCallExpression = referenceExpression instanceof PsiMethodReferenceExpression ? referenceExpression : referenceExpression.getParent();
|
||||
}
|
||||
|
||||
public PsiMethodCallExpression getMethodCallExpression() {
|
||||
public PsiElement getMethodCallExpression() {
|
||||
return myMethodCallExpression;
|
||||
}
|
||||
|
||||
|
||||
+22
-12
@@ -107,18 +107,22 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
|
||||
PsiParameter parameter = (PsiParameter)myTargetVariable;
|
||||
for (final UsageInfo usageInfo : usages) {
|
||||
if (usageInfo instanceof MethodCallUsageInfo) {
|
||||
final PsiMethodCallExpression methodCall = ((MethodCallUsageInfo)usageInfo).getMethodCallExpression();
|
||||
final PsiExpression[] expressions = methodCall.getArgumentList().getExpressions();
|
||||
final int index = myMethod.getParameterList().getParameterIndex(parameter);
|
||||
if (index < expressions.length) {
|
||||
PsiExpression instanceValue = expressions[index];
|
||||
instanceValue = RefactoringUtil.unparenthesizeExpression(instanceValue);
|
||||
if (instanceValue instanceof PsiLiteralExpression && ((PsiLiteralExpression)instanceValue).getValue() == null) {
|
||||
String message = RefactoringBundle.message("0.contains.call.with.null.argument.for.parameter.1",
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(methodCall), true),
|
||||
CommonRefactoringUtil.htmlEmphasize(parameter.getName()));
|
||||
conflicts.putValue(instanceValue, message);
|
||||
final PsiElement methodCall = ((MethodCallUsageInfo)usageInfo).getMethodCallExpression();
|
||||
if (methodCall instanceof PsiMethodCallExpression) {
|
||||
final PsiExpression[] expressions = ((PsiMethodCallExpression)methodCall).getArgumentList().getExpressions();
|
||||
final int index = myMethod.getParameterList().getParameterIndex(parameter);
|
||||
if (index < expressions.length) {
|
||||
PsiExpression instanceValue = expressions[index];
|
||||
instanceValue = RefactoringUtil.unparenthesizeExpression(instanceValue);
|
||||
if (instanceValue instanceof PsiLiteralExpression && ((PsiLiteralExpression)instanceValue).getValue() == null) {
|
||||
String message = RefactoringBundle.message("0.contains.call.with.null.argument.for.parameter.1",
|
||||
RefactoringUIUtil.getDescription(ConflictsUtil.getContainer(methodCall), true),
|
||||
CommonRefactoringUtil.htmlEmphasize(parameter.getName()));
|
||||
conflicts.putValue(instanceValue, message);
|
||||
}
|
||||
}
|
||||
} else if (methodCall instanceof PsiMethodReferenceExpression) {
|
||||
conflicts.putValue(methodCall, "Method reference would be broken after move");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,7 +224,13 @@ public class MoveInstanceMethodProcessor extends BaseRefactoringProcessor{
|
||||
addMethodToClass(inheritor, patternMethod, true);
|
||||
}
|
||||
else if (usage instanceof MethodCallUsageInfo && !((MethodCallUsageInfo)usage).isInternal()) {
|
||||
correctMethodCall(((MethodCallUsageInfo)usage).getMethodCallExpression(), false);
|
||||
final PsiElement expression = ((MethodCallUsageInfo)usage).getMethodCallExpression();
|
||||
if (expression instanceof PsiMethodCallExpression) {
|
||||
correctMethodCall((PsiMethodCallExpression)expression, false);
|
||||
} else if (expression instanceof PsiMethodReferenceExpression) {
|
||||
PsiExpression newQualifier = JavaPsiFacade.getInstance(myProject).getElementFactory().createExpressionFromText(myTargetVariable.getType().getCanonicalText(), null);
|
||||
((PsiMethodReferenceExpression)expression).setQualifierExpression(newQualifier);
|
||||
}
|
||||
}
|
||||
else if (usage instanceof JavadocUsageInfo) {
|
||||
docRefs.add(usage.getElement().getReference());
|
||||
|
||||
+17
@@ -94,6 +94,23 @@ public class PsiMethodReferenceExpressionImpl extends PsiReferenceExpressionBase
|
||||
PsiScopesUtil.resolveAndWalk(proc, this, null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setQualifierExpression(@Nullable PsiExpression newQualifier) throws IncorrectOperationException {
|
||||
if (newQualifier == null) {
|
||||
super.setQualifierExpression(newQualifier);
|
||||
return;
|
||||
}
|
||||
final PsiExpression expression = getQualifierExpression();
|
||||
if (expression != null) {
|
||||
expression.replace(newQualifier);
|
||||
} else {
|
||||
final PsiElement qualifier = getQualifier();
|
||||
if (qualifier != null) {
|
||||
qualifier.replace(newQualifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildRole(ASTNode child) {
|
||||
final IElementType elType = child.getElementType();
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
interface SAM {
|
||||
String m(MethodReference<String> f, F f1);
|
||||
}
|
||||
|
||||
|
||||
class F {}
|
||||
|
||||
class MethodReference<X> {
|
||||
String ge<caret>tX(F f1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
static void test() {
|
||||
SAM s = MethodReference<String>::getX;
|
||||
}
|
||||
}
|
||||
+11
@@ -5,6 +5,7 @@ import com.intellij.codeInsight.TargetElementUtilBase;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiVariable;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
import com.intellij.refactoring.LightRefactoringTestCase;
|
||||
import com.intellij.refactoring.move.moveInstanceMethod.MoveInstanceMethodHandler;
|
||||
import com.intellij.refactoring.move.moveInstanceMethod.MoveInstanceMethodProcessor;
|
||||
@@ -81,6 +82,16 @@ public class MoveInstanceMethodTest extends LightRefactoringTestCase {
|
||||
doTest(false, 0);
|
||||
}
|
||||
|
||||
public void testMethodReference() throws Exception {
|
||||
try {
|
||||
doTest(true, 0);
|
||||
fail("Conflict was not detected");
|
||||
}
|
||||
catch (BaseRefactoringProcessor.ConflictsInTestsException e) {
|
||||
assertEquals("Method reference would be broken after move", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void doTest(boolean isTargetParameter, final int targetIndex) throws Exception {
|
||||
doTest(isTargetParameter, targetIndex, null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user