diff options
Diffstat (limited to 'java')
9 files changed, 220 insertions, 69 deletions
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java index bf0fc63be2a2..ca214aa5010c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java @@ -998,14 +998,20 @@ class ControlFlowAnalyzer extends JavaElementVisitor { } PsiType type = expression.getType(); if (op == JavaTokenType.ANDAND) { - generateAndExpression(operands, type); + generateAndExpression(operands, type, true); } else if (op == JavaTokenType.OROR) { - generateOrExpression(operands, type); + generateOrExpression(operands, type, true); } else if (op == JavaTokenType.XOR && PsiType.BOOLEAN.equals(type)) { generateXorExpression(expression, operands, type); } + else if (op == JavaTokenType.AND && PsiType.BOOLEAN.equals(type)) { + generateAndExpression(operands, type, false); + } + else if (op == JavaTokenType.OR && PsiType.BOOLEAN.equals(type)) { + generateOrExpression(operands, type, false); + } else { generateOther(expression, op, operands, type); } @@ -1104,11 +1110,18 @@ class ControlFlowAnalyzer extends JavaElementVisitor { } } - private void generateOrExpression(PsiExpression[] operands, final PsiType exprType) { + private void generateOrExpression(PsiExpression[] operands, final PsiType exprType, boolean shortCircuit) { for (int i = 0; i < operands.length; i++) { PsiExpression operand = operands[i]; operand.accept(this); generateBoxingUnboxingInstructionFor(operand, exprType); + if (!shortCircuit) { + if (i > 0) { + combineStackBooleans(false, operand); + } + continue; + } + PsiExpression nextOperand = i == operands.length - 1 ? null : operands[i + 1]; if (nextOperand != null) { addInstruction(new ConditionalGotoInstruction(getStartOffset(nextOperand), true, operand)); @@ -1125,7 +1138,11 @@ class ControlFlowAnalyzer extends JavaElementVisitor { lExpression.accept(this); generateBoxingUnboxingInstructionFor(lExpression, exprType); - ConditionalGotoInstruction toPopAndPushSuccess = new ConditionalGotoInstruction(-1, and, lExpression); + combineStackBooleans(and, lExpression); + } + + private void combineStackBooleans(boolean and, PsiExpression anchor) { + ConditionalGotoInstruction toPopAndPushSuccess = new ConditionalGotoInstruction(-1, and, anchor); addInstruction(toPopAndPushSuccess); GotoInstruction overPushSuccess = new GotoInstruction(-1); addInstruction(overPushSuccess); @@ -1140,17 +1157,29 @@ class ControlFlowAnalyzer extends JavaElementVisitor { overPushSuccess.setOffset(pushSuccess.getIndex() + 1); } - private void generateAndExpression(PsiExpression[] operands, final PsiType exprType) { + private void generateAndExpression(PsiExpression[] operands, final PsiType exprType, boolean shortCircuit) { List<ConditionalGotoInstruction> branchToFail = new ArrayList<ConditionalGotoInstruction>(); - for (PsiExpression operand : operands) { + for (int i = 0; i < operands.length; i++) { + PsiExpression operand = operands[i]; operand.accept(this); generateBoxingUnboxingInstructionFor(operand, exprType); + if (!shortCircuit) { + if (i > 0) { + combineStackBooleans(false, operand); + } + continue; + } + ConditionalGotoInstruction onFail = new ConditionalGotoInstruction(-1, true, operand); branchToFail.add(onFail); addInstruction(onFail); } + if (!shortCircuit) { + return; + } + addInstruction(new PushInstruction(myFactory.getConstFactory().getTrue(), null)); GotoInstruction toSuccess = new GotoInstruction(-1); addInstruction(toSuccess); diff --git a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java index f9efd108ed48..a95d4985b12e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/TargetElementUtil.java @@ -15,15 +15,17 @@ */ package com.intellij.codeInsight; +import com.intellij.ide.IdeBundle; import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.Computable; import com.intellij.psi.*; +import com.intellij.psi.presentation.java.ClassPresentationUtil; +import com.intellij.psi.search.LocalSearchScope; +import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.*; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.psi.xml.XmlTag; @@ -32,10 +34,7 @@ import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedHashSet; -import java.util.List; +import java.util.*; public class TargetElementUtil extends TargetElementUtilBase { public static final int NEW_AS_CONSTRUCTOR = 0x04; @@ -261,43 +260,74 @@ public class TargetElementUtil extends TargetElementUtilBase { @Override public boolean acceptImplementationForReference(final PsiReference reference, final PsiElement element) { if (reference instanceof PsiReferenceExpression && element instanceof PsiMember) { - return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() { - @Override - public Boolean compute() { - PsiClass containingClass = ((PsiMember)element).getContainingClass(); - final PsiExpression expression = ((PsiReferenceExpression)reference).getQualifierExpression(); - PsiClass psiClass; - if (expression != null) { - psiClass = PsiUtil.resolveClassInType(expression.getType()); - } else { - if (element instanceof PsiClass) { - psiClass = (PsiClass)element; - final PsiElement resolve = reference.resolve(); - if (resolve instanceof PsiClass) { - containingClass = (PsiClass)resolve; - } - } else { - psiClass = PsiTreeUtil.getParentOfType((PsiReferenceExpression)reference, PsiClass.class); + return getMemberClass(reference, element) != null; + } + return super.acceptImplementationForReference(reference, element); + } + + private static PsiClass[] getMemberClass(final PsiReference reference, final PsiElement element) { + return ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() { + @Override + public PsiClass[] compute() { + PsiClass containingClass = ((PsiMember)element).getContainingClass(); + final PsiExpression expression = ((PsiReferenceExpression)reference).getQualifierExpression(); + PsiClass psiClass; + if (expression != null) { + psiClass = PsiUtil.resolveClassInType(expression.getType()); + } else { + if (element instanceof PsiClass) { + psiClass = (PsiClass)element; + final PsiElement resolve = reference.resolve(); + if (resolve instanceof PsiClass) { + containingClass = (PsiClass)resolve; } + } else { + psiClass = PsiTreeUtil.getParentOfType((PsiReferenceExpression)reference, PsiClass.class); } + } - if (containingClass == null && psiClass == null) return true; - if (containingClass != null) { - PsiElementFindProcessor<PsiClass> processor1 = new PsiElementFindProcessor<PsiClass>(containingClass); - while (psiClass != null) { - if (!processor1.process(psiClass) || - !ClassInheritorsSearch.search(containingClass).forEach(new PsiElementFindProcessor<PsiClass>(psiClass)) || - !ClassInheritorsSearch.search(psiClass).forEach(processor1)) { - return true; - } - psiClass = psiClass.getContainingClass(); + if (containingClass == null && psiClass == null) return PsiClass.EMPTY_ARRAY; + if (containingClass != null) { + PsiElementFindProcessor<PsiClass> processor1 = new PsiElementFindProcessor<PsiClass>(containingClass); + while (psiClass != null) { + if (!processor1.process(psiClass) || + !ClassInheritorsSearch.search(containingClass).forEach(new PsiElementFindProcessor<PsiClass>(psiClass)) || + !ClassInheritorsSearch.search(psiClass).forEach(processor1)) { + return new PsiClass[] {psiClass}; } + psiClass = psiClass.getContainingClass(); } - return false; } - }); + return null; + } + }); + } + + @Override + public SearchScope getSearchScope(Editor editor, PsiElement element) { + final PsiReferenceExpression referenceExpression = editor != null ? findReferenceExpression(editor) : null; + if (referenceExpression != null && element instanceof PsiMethod) { + final PsiClass[] memberClass = getMemberClass(referenceExpression, element); + if (memberClass != null && memberClass.length == 1) { + final List<PsiClass> classesToSearch = new ArrayList<PsiClass>(); + classesToSearch.addAll(ClassInheritorsSearch.search(memberClass[0], true).findAll()); + + final Set<PsiClass> supers = new HashSet<PsiClass>(); + for (PsiClass psiClass : classesToSearch) { + supers.addAll(InheritanceUtil.getSuperClasses(psiClass)); + } + classesToSearch.addAll(supers); + + return CachedValuesManager.getManager(element.getProject()).createCachedValue(new CachedValueProvider<SearchScope>() { + @Nullable + @Override + public Result<SearchScope> compute() { + return new Result<SearchScope>(new LocalSearchScope(PsiUtilCore.toPsiElementArray(classesToSearch))); + } + }, false).getValue(); + } } - return super.acceptImplementationForReference(reference, element); + return super.getSearchScope(editor, element); } private static class PsiElementFindProcessor<T extends PsiClass> implements Processor<T> { diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/ClassImplementationsSearch.java b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/ClassImplementationsSearch.java index a19630dad65c..128cf27ed3c4 100644 --- a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/ClassImplementationsSearch.java +++ b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/ClassImplementationsSearch.java @@ -15,8 +15,6 @@ */ package com.intellij.codeInsight.navigation; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.registry.Registry; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; @@ -24,23 +22,21 @@ import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.search.PsiElementProcessorAdapter; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.ClassInheritorsSearch; +import com.intellij.psi.search.searches.DefinitionsScopedSearch; import com.intellij.util.Processor; import com.intellij.util.QueryExecutor; import org.jetbrains.annotations.NotNull; -public class ClassImplementationsSearch implements QueryExecutor<PsiElement, PsiElement> { - public boolean execute(@NotNull final PsiElement sourceElement, @NotNull final Processor<PsiElement> consumer) { - return !(sourceElement instanceof PsiClass) || processImplementations((PsiClass)sourceElement, consumer); +public class ClassImplementationsSearch implements QueryExecutor<PsiElement, DefinitionsScopedSearch.SearchParameters> { + @Override + public boolean execute(@NotNull DefinitionsScopedSearch.SearchParameters queryParameters, @NotNull Processor<PsiElement> consumer) { + final PsiElement sourceElement = queryParameters.getElement(); + return !(sourceElement instanceof PsiClass) || processImplementations((PsiClass)sourceElement, consumer, queryParameters.getScope()); } - public static boolean processImplementations(final PsiClass psiClass, final Processor<? super PsiClass> processor) { + public static boolean processImplementations(final PsiClass psiClass, final Processor<? super PsiClass> processor, SearchScope scope) { final boolean showInterfaces = Registry.is("ide.goto.implementation.show.interfaces"); - return ClassInheritorsSearch.search(psiClass, ApplicationManager.getApplication().runReadAction(new Computable<SearchScope>() { - @Override - public SearchScope compute() { - return psiClass.getUseScope(); - } - }), true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { + return ClassInheritorsSearch.search(psiClass, scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() { public boolean execute(@NotNull PsiClass element) { if (!showInterfaces && element.isInterface()) { return true; diff --git a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java index dfe436afade2..fd73976f86c5 100644 --- a/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java +++ b/java/java-indexing-impl/src/com/intellij/codeInsight/navigation/MethodImplementationsSearch.java @@ -17,6 +17,8 @@ package com.intellij.codeInsight.navigation; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; +import com.intellij.psi.search.SearchScope; +import com.intellij.psi.search.searches.DefinitionsScopedSearch; import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.util.QueryExecutor; import com.intellij.util.Processor; @@ -25,25 +27,27 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -public class MethodImplementationsSearch implements QueryExecutor<PsiElement, PsiElement> { - public boolean execute(@NotNull final PsiElement sourceElement, @NotNull final Processor<PsiElement> consumer) { +public class MethodImplementationsSearch implements QueryExecutor<PsiElement, DefinitionsScopedSearch.SearchParameters> { + @Override + public boolean execute(@NotNull DefinitionsScopedSearch.SearchParameters queryParameters, @NotNull Processor<PsiElement> consumer) { + final PsiElement sourceElement = queryParameters.getElement(); if (sourceElement instanceof PsiMethod) { - PsiMethod[] implementations = getMethodImplementations((PsiMethod)sourceElement); + PsiMethod[] implementations = getMethodImplementations((PsiMethod)sourceElement, queryParameters.getScope()); return ContainerUtil.process(implementations, consumer); } return true; } - public static void getOverridingMethods(PsiMethod method, ArrayList<PsiMethod> list) { - for (PsiMethod psiMethod : OverridingMethodsSearch.search(method)) { + public static void getOverridingMethods(PsiMethod method, ArrayList<PsiMethod> list, SearchScope scope) { + for (PsiMethod psiMethod : OverridingMethodsSearch.search(method, scope, true)) { list.add(psiMethod); } } - public static PsiMethod[] getMethodImplementations(final PsiMethod method) { + public static PsiMethod[] getMethodImplementations(final PsiMethod method, SearchScope scope) { ArrayList<PsiMethod> result = new ArrayList<PsiMethod>(); - getOverridingMethods(method, result); + getOverridingMethods(method, result, scope); return result.toArray(new PsiMethod[result.size()]); } } diff --git a/java/java-tests/testData/inspection/dataFlow/boxingBoolean/expected.xml b/java/java-tests/testData/inspection/dataFlow/boxingBoolean/expected.xml index d04ea2815d43..eb4d42c5bf86 100644 --- a/java/java-tests/testData/inspection/dataFlow/boxingBoolean/expected.xml +++ b/java/java-tests/testData/inspection/dataFlow/boxingBoolean/expected.xml @@ -36,4 +36,9 @@ <description>Condition <code>o</code> at the left side of assignment expression is always <code>false</code>. Can be simplified to normal assignment.</description> </problem> + <problem> + <file>Test.java</file> + <line>52</line> + <description>Condition <code>o</code> is always <code>true</code></description> + </problem> </problems> diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/LongCircuitOperations.java b/java/java-tests/testData/inspection/dataFlow/fixture/LongCircuitOperations.java new file mode 100644 index 000000000000..e05c670be6af --- /dev/null +++ b/java/java-tests/testData/inspection/dataFlow/fixture/LongCircuitOperations.java @@ -0,0 +1,19 @@ +class X { + + int foo(String d1, String d2) { + if(d1 == null | d2 == null) + return 0; + return d1.compareTo(d2); + + } + void foo2(String d1, String d2) { + if(<warning descr="Condition 'd1 == null & d1 != null' is always 'true'">d1 == null & d1 != null</warning>) + System.out.println("impossible"); + + } + void foo3(String d1, String d2) { + if(d1 == null | <warning descr="Method invocation 'd1.compareTo(d2)' may produce 'java.lang.NullPointerException'">d1.compareTo(d2)</warning> > 0) + System.out.println("impossible"); + } +} + diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java index 6f9c7b089386..9ee62d0bb51b 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java @@ -286,4 +286,5 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase { public void testBoxingImpliesNotNull() { doTest(); } public void testLargeIntegersAreNotEqualWhenBoxed() { doTest(); } public void testNoGenericCCE() { doTest(); } + public void testLongCircuitOperations() { doTest(); } } diff --git a/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationHandlerTest.java b/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationHandlerTest.java index bf9f09fafa9d..3d41cdc77d6e 100644 --- a/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationHandlerTest.java +++ b/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationHandlerTest.java @@ -17,12 +17,18 @@ package com.intellij.navigation; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.daemon.impl.HighlightInfo; import com.intellij.codeInsight.navigation.GotoImplementationHandler; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiMethod; +import com.intellij.testFramework.PlatformTestUtil; import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase; +import com.intellij.util.ThrowableRunnable; + +import java.util.List; public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCase { @@ -49,6 +55,66 @@ public class GotoImplementationHandlerTest extends JavaCodeInsightFixtureTestCas assertEquals(2, impls.length); } + public void testToStringOnUnqualified() throws Throwable { + final PsiFile file = myFixture.addFileToProject("Foo.java", "public class Fix {\n" + + " {\n" + + " <caret>toString();\n" + + " }\n" + + "}\n" + + "class FixImpl1 extends Fix {\n" + + " @Override\n" + + " public String toString() {\n" + + " return \"Impl1\";\n" + + " }\n" + + "}\n" + + "class FixImpl2 extends Fix {\n" + + " @Override\n" + + " public String toString() {\n" + + " return \"Impl2\";\n" + + " }\n" + + "}\n"); + myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); + + PlatformTestUtil.startPerformanceTest(getTestName(false), 50, new ThrowableRunnable() { + @Override + public void run() throws Exception { + final PsiElement[] impls = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), file).targets; + assertEquals(3, impls.length); + } + }).cpuBound().usesAllCPUCores().assertTiming(); + } + + public void testToStringOnQualified() throws Throwable { + final PsiFile file = myFixture.addFileToProject("Foo.java", "public class Fix {\n" + + " {\n" + + " Fix ff = new FixImpl1();\n" + + " ff.<caret>toString();\n" + + " }\n" + + "}\n" + + "class FixImpl1 extends Fix {\n" + + " @Override\n" + + " public String toString() {\n" + + " return \"Impl1\";\n" + + " }\n" + + "}\n" + + "class FixImpl2 extends Fix {\n" + + " @Override\n" + + " public String toString() {\n" + + " return \"Impl2\";\n" + + " }\n" + + "}\n"); + myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); + + PlatformTestUtil.startPerformanceTest(getTestName(false), 50, new ThrowableRunnable() { + @Override + public void run() throws Exception { + final PsiElement[] impls = new GotoImplementationHandler().getSourceAndTargetElements(myFixture.getEditor(), file).targets; + assertEquals(3, impls.length); + } + }).cpuBound().usesAllCPUCores().assertTiming(); + + } + public void testShowSelfNonAbstract() throws Throwable { //fails if groovy plugin is enabled: org.jetbrains.plugins.groovy.codeInsight.JavaClsMethodElementEvaluator PsiFile file = myFixture.addFileToProject("Foo.java", "public class Hello {\n" + diff --git a/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationTest.java b/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationTest.java index d36f9ead9e07..da1de928d58a 100644 --- a/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationTest.java +++ b/java/java-tests/testSrc/com/intellij/navigation/GotoImplementationTest.java @@ -28,7 +28,7 @@ public class GotoImplementationTest extends CodeInsightTestCase { private static Collection<PsiClass> getClassImplementations(final PsiClass psiClass) { CommonProcessors.CollectProcessor<PsiClass> processor = new CommonProcessors.CollectProcessor<PsiClass>(); - ClassImplementationsSearch.processImplementations(psiClass, processor); + ClassImplementationsSearch.processImplementations(psiClass, processor, psiClass.getUseScope()); return processor.getResults(); } @@ -60,21 +60,22 @@ public class GotoImplementationTest extends CodeInsightTestCase { Module module1 = moduleManager.findModuleByName("test1"); Module module2 = moduleManager.findModuleByName("test2"); Module module3 = moduleManager.findModuleByName("test3"); - PsiClass test1 = myJavaFacade.findClass("com.test.TestI", GlobalSearchScope.moduleScope(module1)); + final GlobalSearchScope moduleScope = GlobalSearchScope.moduleScope(module1); + PsiClass test1 = myJavaFacade.findClass("com.test.TestI", moduleScope); PsiClass test2 = myJavaFacade.findClass("com.test.TestI", GlobalSearchScope.moduleScope(module2)); PsiClass test3 = myJavaFacade.findClass("com.test.TestI", GlobalSearchScope.moduleScope(module3)); HashSet<PsiClass> expectedImpls1 = new HashSet<PsiClass>(Arrays.asList( - myJavaFacade.findClass("com.test.TestIImpl1", GlobalSearchScope.moduleScope(module1)), - myJavaFacade.findClass("com.test.TestIImpl2", GlobalSearchScope.moduleScope(module1)) + myJavaFacade.findClass("com.test.TestIImpl1", moduleScope), + myJavaFacade.findClass("com.test.TestIImpl2", moduleScope) )); assertEquals(expectedImpls1, new HashSet<PsiClass>(getClassImplementations(test1))); PsiMethod psiMethod = test1.findMethodsByName("test", false)[0]; Set<PsiMethod> expectedMethodImpl1 = new HashSet<PsiMethod>(Arrays.asList( - myJavaFacade.findClass("com.test.TestIImpl1", GlobalSearchScope.moduleScope(module1)).findMethodsByName("test",false)[0], - myJavaFacade.findClass("com.test.TestIImpl2", GlobalSearchScope.moduleScope(module1)).findMethodsByName("test",false)[0] + myJavaFacade.findClass("com.test.TestIImpl1", moduleScope).findMethodsByName("test",false)[0], + myJavaFacade.findClass("com.test.TestIImpl2", moduleScope).findMethodsByName("test",false)[0] )); - assertEquals(expectedMethodImpl1, new HashSet<PsiMethod>(Arrays.asList(MethodImplementationsSearch.getMethodImplementations(psiMethod)))); + assertEquals(expectedMethodImpl1, new HashSet<PsiMethod>(Arrays.asList(MethodImplementationsSearch.getMethodImplementations(psiMethod, moduleScope)))); HashSet<PsiClass> expectedImpls2 = new HashSet<PsiClass>(Arrays.asList( myJavaFacade.findClass("com.test.TestIImpl1", GlobalSearchScope.moduleScope(module2)), |