fix finding lambdas implementing JDK interfaces

This commit is contained in:
peter
2015-09-23 13:48:55 +02:00
parent 4d2d29c11b
commit c70ab42653
4 changed files with 35 additions and 6 deletions
@@ -14,6 +14,6 @@
<orderEntry type="module" module-name="projectModel-api" exported="" />
<orderEntry type="module" module-name="projectModel-impl" />
<orderEntry type="module" module-name="java-indexing-api" exported="" />
<orderEntry type="library" name="Guava" level="project" />
</component>
</module>
</module>
@@ -15,11 +15,11 @@
*/
package com.intellij.psi.impl.search;
import com.google.common.annotations.VisibleForTesting;
import com.intellij.openapi.application.*;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.module.impl.scopes.ModulesScope;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.LanguageLevelModuleExtension;
import com.intellij.openapi.roots.ModuleRootManager;
@@ -53,6 +53,13 @@ import static com.intellij.util.containers.ContainerUtilRt.newHashSet;
public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunctionalExpression, FunctionalExpressionSearch.SearchParameters> {
private static final Logger LOG = Logger.getInstance("#" + JavaFunctionalExpressionSearcher.class.getName());
/**
* The least number of candidate files with functional expressions that directly scanning them becomes expensive
* and more advanced ways of searching become necessary: e.g. first searching for methods where the functional interface class is used
* and then for their usages,
*/
@VisibleForTesting
public static final int SMART_SEARCH_THRESHOLD = 5;
@Override
public void processQuery(@NotNull FunctionalExpressionSearch.SearchParameters queryParameters,
@@ -71,7 +78,7 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
final Set<Module> highLevelModules = getJava8Modules(project);
if (highLevelModules.isEmpty()) return;
useScope = new JavaSourceFilterScope(new ModulesScope(highLevelModules, project).intersectWith(convertToGlobalScope(project, queryParameters.getEffectiveSearchScope())));
useScope = convertToGlobalScope(project, queryParameters.getEffectiveSearchScope());
final MethodSignature functionalInterfaceMethod = LambdaUtil.getFunction(aClass);
LOG.assertTrue(functionalInterfaceMethod != null);
@@ -81,8 +88,8 @@ public class JavaFunctionalExpressionSearcher extends QueryExecutorBase<PsiFunct
}
//collect all files with '::' and '->' in useScope
Set<VirtualFile> candidateFiles = getFilesWithFunctionalExpressionsScope(project, useScope);
if (candidateFiles.size() < 5) {
Set<VirtualFile> candidateFiles = getFilesWithFunctionalExpressionsScope(project, new JavaSourceFilterScope(useScope));
if (candidateFiles.size() < SMART_SEARCH_THRESHOLD) {
searchInFiles(aClass, consumer, candidateFiles, expectedFunExprParamsCount);
return;
}
@@ -0,0 +1,6 @@
class Test{
public static void main(java.util.List<String> list) {
list.stream().filter((e) -> true)
}
}
@@ -17,6 +17,8 @@ package com.intellij.codeInsight.daemon.lambda;
import com.intellij.JavaTestUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.search.JavaFunctionalExpressionSearcher;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PsiTreeUtil;
@@ -25,6 +27,7 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
import java.util.function.Predicate;
public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase {
public void testMethodArgument() throws Exception {
@@ -66,6 +69,19 @@ public class FindFunctionalInterfaceTest extends LightCodeInsightFixtureTestCase
assertEquals(1, references.size());
}
public void testClassFromJdk() {
myFixture.configureByFile(getTestName(false) + ".java");
for (int i = 0; i < JavaFunctionalExpressionSearcher.SMART_SEARCH_THRESHOLD + 5; i++) {
myFixture.addFileToProject("a" + i + ".java", "class Goo {{ Runnable r = () -> {} }}");
}
PsiClass predicate = JavaPsiFacade.getInstance(getProject()).findClass(Predicate.class.getName(), GlobalSearchScope.allScope(getProject()));
assert predicate != null;
final PsiFunctionalExpression next = assertOneElement(FunctionalExpressionSearch.search(predicate).findAll());
assertEquals("(e) -> true", next.getText());
}
@Override
protected String getBasePath() {
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/lambda/findUsages/";