mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-169269 "Analyze dataflow to here" should process only implementations of current class when analyzing return values for a method call in instance method
This commit is contained in:
@@ -35,6 +35,7 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.util.RefactoringChangeUtil;
|
||||
import com.intellij.util.ArrayUtilRt;
|
||||
import com.intellij.util.Processor;
|
||||
import gnu.trove.THashMap;
|
||||
@@ -244,7 +245,10 @@ class SliceUtil {
|
||||
@NotNull final Processor<SliceUsage> processor,
|
||||
@NotNull final JavaSliceUsage parent,
|
||||
@NotNull final PsiSubstitutor parentSubstitutor) {
|
||||
final JavaResolveResult resolved = methodCallExpr.resolveMethodGenerics();
|
||||
// if the call looks like 'otherClassObject.methodFromInterface()'
|
||||
// we can narrow down the overridden methods scan to inheritors of OtherClass only
|
||||
PsiClass qualifierClass = resolveQualifier(methodCallExpr);
|
||||
JavaResolveResult resolved = methodCallExpr.resolveMethodGenerics();
|
||||
PsiElement r = resolved.getElement();
|
||||
if (r instanceof PsiCompiledElement) {
|
||||
r = r.getNavigationElement();
|
||||
@@ -257,8 +261,15 @@ class SliceUtil {
|
||||
|
||||
final PsiType parentType = parentSubstitutor.substitute(methodCallExpr.getType());
|
||||
final PsiSubstitutor substitutor = resolved.getSubstitutor().putAll(parentSubstitutor);
|
||||
Collection<PsiMethod> overrides =
|
||||
new THashSet<>(OverridingMethodsSearch.search(methodCalled, parent.getScope().toSearchScope(), true).findAll());
|
||||
Collection<PsiMethod> overrides = new THashSet<>();
|
||||
OverridingMethodsSearch.search(methodCalled, parent.getScope().toSearchScope(), true).forEach((PsiMethod override) -> {
|
||||
PsiClass containingClass = override.getContainingClass();
|
||||
if (containingClass == null) return true;
|
||||
if (qualifierClass == null || containingClass.isInheritor(qualifierClass, true)) {
|
||||
overrides.add(override);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
overrides.add(methodCalled);
|
||||
|
||||
final boolean[] result = {true};
|
||||
@@ -300,6 +311,31 @@ class SliceUtil {
|
||||
return result[0];
|
||||
}
|
||||
|
||||
private static PsiClass resolveQualifier(@NotNull PsiMethodCallExpression expr) {
|
||||
PsiExpression qualifier = expr.getMethodExpression().getQualifierExpression();
|
||||
if (qualifier == null) {
|
||||
PsiMethodCallExpression copy = (PsiMethodCallExpression)expr.copy();
|
||||
PsiReferenceExpression methodExpression = copy.getMethodExpression();
|
||||
|
||||
PsiThisExpression thisExpression = RefactoringChangeUtil.createThisExpression(expr.getManager(), null);
|
||||
methodExpression.setQualifierExpression(thisExpression);
|
||||
qualifier = methodExpression.getQualifierExpression();
|
||||
}
|
||||
if (qualifier != null) {
|
||||
if (qualifier instanceof PsiReferenceExpression) {
|
||||
PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve();
|
||||
if (resolved instanceof PsiClass) return (PsiClass)resolved;
|
||||
}
|
||||
else if (qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) {
|
||||
PsiType type = qualifier.getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
return ((PsiClassType)type).resolve();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean processFieldUsages(@NotNull final PsiField field,
|
||||
@NotNull final JavaSliceUsage parent,
|
||||
@NotNull final PsiSubstitutor parentSubstitutor,
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
interface I {
|
||||
String getValue();
|
||||
}
|
||||
|
||||
abstract class X implements I {
|
||||
void foo() {
|
||||
String <caret>s = <flown1>getValue();
|
||||
}
|
||||
}
|
||||
|
||||
class Y implements I {
|
||||
public String getValue() {
|
||||
return "Y";
|
||||
}
|
||||
}
|
||||
|
||||
class Impl extends X {
|
||||
public String getValue() {
|
||||
return <flown11>"Impl";
|
||||
}
|
||||
}
|
||||
@@ -83,4 +83,5 @@ public class SliceBackwardTest extends SliceTestCase {
|
||||
public void testTryCatchFinally() throws Exception { doTest();}
|
||||
public void testFinalVarAssignedBeforePassingToAnonymous() throws Exception { doTest();}
|
||||
public void testLocalVarDeclarationAndAssignment() throws Exception { doTest();}
|
||||
public void testSearchOverriddenMethodsInThisClassHierarchy() throws Exception { doTest();}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user