[java-slices] Avoid walking through inheritance when starting from parameter (IDEA-154777)

GitOrigin-RevId: 327559f0649b3bb66b04b056627966b6a0e1618f
This commit is contained in:
Tagir Valeev
2021-05-28 10:51:17 +00:00
committed by intellij-monorepo-bot
parent 090b19388c
commit 19141f3dbc
11 changed files with 113 additions and 30 deletions
@@ -21,7 +21,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
final class SliceForwardUtil {
@@ -92,29 +91,16 @@ final class SliceForwardUtil {
PsiParameter parameter = (PsiParameter)from;
PsiElement scope = parameter.getDeclarationScope();
Collection<PsiParameter> parametersToAnalyze = new HashSet<>();
if (scope instanceof PsiMethod) {
if (scope instanceof PsiMethod && ((PsiMethod)scope).hasModifierProperty(PsiModifier.ABSTRACT)) {
final PsiMethod method = (PsiMethod)scope;
int index = method.getParameterList().getParameterIndex(parameter);
final Set<PsiMethod> implementors = new HashSet<>();
Collection<PsiMethod> superMethods = ContainerUtil.set(method.findDeepestSuperMethods());
superMethods.add(method);
for (Iterator<PsiMethod> iterator = superMethods.iterator(); iterator.hasNext(); ) {
if (!OverridingMethodsSearch.search(method, parent.getScope().toSearchScope(), true).forEach(sub -> {
ProgressManager.checkCanceled();
PsiMethod superMethod = iterator.next();
if (!parent.params.scope.contains(superMethod)) {
iterator.remove();
}
}
final Set<PsiMethod> implementors = new HashSet<>(superMethods);
for (PsiMethod superMethod : superMethods) {
ProgressManager.checkCanceled();
if (!OverridingMethodsSearch.search(superMethod, parent.getScope().toSearchScope(), true).forEach(sub -> {
ProgressManager.checkCanceled();
implementors.add(sub);
return true;
})) return false;
}
implementors.add(sub);
return true;
})) return false;
for (PsiMethod implementor : implementors) {
ProgressManager.checkCanceled();
if (!parent.params.scope.contains(implementor)) continue;
@@ -131,12 +117,11 @@ final class SliceForwardUtil {
}
for (final PsiParameter psiParameter : parametersToAnalyze) {
ProgressManager.checkCanceled();
if (!searchReferencesAndProcessAssignmentTarget(psiParameter, null, parent, processor)) return false;
}
return true;
}
if (from instanceof PsiField) {
else if (from instanceof PsiField) {
return searchReferencesAndProcessAssignmentTarget(from, null, parent, processor);
}
@@ -0,0 +1,17 @@
interface JavaInterface {
void foo(Object p);
}
class JavaClass1 implements JavaInterface {
@Override
public void foo(Object <caret>p) {
System.out.println(<flown1>p);
}
}
class JavaClass2 implements JavaInterface {
@Override
public void foo(Object p) {
System.err.println(p);
}
}
@@ -0,0 +1,17 @@
interface JavaInterface {
void foo(Object <caret>p);
}
class JavaClass1 implements JavaInterface {
@Override
public void foo(Object p) {
System.out.println(<flown1>p);
}
}
class JavaClass2 implements JavaInterface {
@Override
public void foo(Object p) {
System.err.println(<flown2>p);
}
}
@@ -0,0 +1,18 @@
public class OverloadedMember {
static class Base {
void method(int param) {
helloBase(param);
}
private void helloBase(int param) {
}
}
static class Impl extends Base {
void method(int param<caret>) {
helloImpl(<flown1>param);
System.out.println("param = " + param);
}
private void helloImpl(int <flown11>param) {
}
}
}
@@ -0,0 +1,18 @@
public class OverloadedMember2 {
class C1 {
void f(String s) {
System.err.println(s);
}
}
class C2 extends C1 {
@Override
void f(String <flown1>s) {
System.out.println(<flown11>s);
}
void g() {
f(<caret>"A");
}
}
}
@@ -0,0 +1,25 @@
public class OverloadedMember3 {
class C1 {
void f(String s) {
System.err.println(s);
}
}
class C2 extends C1 {
@Override
void f(String <flown1>s) {
System.out.println(<flown11>s);
}
void g() {
f(<caret>"A");
}
}
class C3 extends C2 {
@Override
void f(String <flown2>s) {
System.out.println(<flown21>s);
}
}
}
@@ -47,4 +47,9 @@ public class SliceForwardTest extends SliceTestCase {
public void testParameters() throws Exception { dotest();}
public void testRequireNonNull() throws Exception { dotest();}
public void testAppend() throws Exception { dotest();}
public void testOverloadedMember() throws Exception { dotest();}
public void testOverloadedMember2() throws Exception { dotest();}
public void testOverloadedMember3() throws Exception { dotest();}
public void testOneInterfaceTwoImplementations() throws Exception { dotest();}
public void testOneInterfaceTwoImplementations2() throws Exception { dotest();}
}
@@ -6,7 +6,7 @@ interface I {
class C1 : I {
override fun Int.foo(p: Any) {
val v = p // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958
val v = p
}
}
@@ -2,7 +2,6 @@
4 fun Int.foo(<bold>p: Any</bold>) (in foo(Any) on Int)
3 public void foo(int receiver, Object <bold>p</bold>) {
4 System.out.println(<bold>p</bold>);
9 val v = <bold>p</bold> // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958 (in foo(Any) on Int)
9 <bold>val v</bold> = p // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958 (in foo(Any) on Int)
8 override fun Int.foo(<bold>p: Any</bold>) { (in foo(Any) on Int)
9 DUPLICATE: val v = <bold>p</bold> // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958 (in foo(Any) on Int)
9 val v = <bold>p</bold> (in foo(Any) on Int)
9 <bold>val v</bold> = p (in foo(Any) on Int)
@@ -6,7 +6,7 @@ interface I {
class C : I {
override fun foo(p: Any) {
val v = p // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958
val v = p
}
}
@@ -2,7 +2,6 @@
4 fun foo(<bold>p: Any</bold>) (in I.foo(Any))
2 public void foo(Object <bold>p</bold>) {
3 System.out.println(<bold>p</bold>);
9 val v = <bold>p</bold> // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958 (in C.foo(Any))
9 <bold>val v</bold> = p // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958 (in C.foo(Any))
8 override fun foo(<bold>p: Any</bold>) { (in C.foo(Any))
9 DUPLICATE: val v = <bold>p</bold> // this usage will be shown twice due to bug in Java implementation: https://youtrack.jetbrains.com/issue/IDEA-236958 (in C.foo(Any))
9 val v = <bold>p</bold> (in C.foo(Any))
9 <bold>val v</bold> = p (in C.foo(Any))