mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
take into account use scope enlarger while inheritors/functional expression searches
GitOrigin-RevId: 8b62d47f2aef69308f891e2e537c76ece7d5e5ca
This commit is contained in:
committed by
intellij-monorepo-bot
parent
278f96df51
commit
ca35b63d33
@@ -19,6 +19,7 @@ import com.intellij.psi.impl.FindSuperElementsHelper;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.PsiElementProcessorAdapter;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
@@ -391,7 +392,7 @@ public class MarkerType {
|
||||
@Override
|
||||
public void run(@NotNull final ProgressIndicator indicator) {
|
||||
super.run(indicator);
|
||||
ClassInheritorsSearch.search(myClass, ReadAction.compute(myClass::getUseScope), true).forEach(
|
||||
ClassInheritorsSearch.search(myClass, ReadAction.compute(() -> PsiSearchHelper.getInstance(myProject).getUseScope(myClass)), true).forEach(
|
||||
new CommonProcessors.CollectProcessor<>() {
|
||||
@Override
|
||||
public boolean process(final PsiClass o) {
|
||||
|
||||
+2
-1
@@ -10,6 +10,7 @@ import com.intellij.openapi.util.Conditions;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.search.PsiSearchHelper;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.*;
|
||||
@@ -159,7 +160,7 @@ public final class ClassInheritorsSearch extends ExtensibleQueryFactory<PsiClass
|
||||
throw new ProcessCanceledException();
|
||||
}
|
||||
PsiFile file = aClass.getContainingFile();
|
||||
return (file != null ? file : aClass).getUseScope();
|
||||
return PsiSearchHelper.getInstance(aClass.getProject()).getUseScope(file != null ? file : aClass);
|
||||
}), checkDeep);
|
||||
}
|
||||
|
||||
|
||||
+8
-6
@@ -20,11 +20,11 @@ import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.lang.LighterAST;
|
||||
import com.intellij.lang.LighterASTNode;
|
||||
import com.intellij.lang.LighterASTTokenNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.io.DataInputOutputUtilRt;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.PsiBinaryExpression;
|
||||
import com.intellij.psi.impl.java.stubs.FunctionalExpressionKey;
|
||||
@@ -58,7 +58,6 @@ import java.util.function.BiConsumer;
|
||||
import static com.intellij.psi.impl.source.tree.JavaElementType.*;
|
||||
|
||||
public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<FunctionalExpressionKey, List<JavaFunctionalExpressionIndex.IndexEntry>> {
|
||||
private static final Logger LOG = Logger.getInstance(JavaFunctionalExpressionIndex.class);
|
||||
public static final ID<FunctionalExpressionKey, List<IndexEntry>> INDEX_ID = ID.create("java.fun.expression");
|
||||
private static final KeyDescriptor<FunctionalExpressionKey> KEY_DESCRIPTOR = new KeyDescriptor<>() {
|
||||
@Override
|
||||
@@ -452,10 +451,13 @@ public class JavaFunctionalExpressionIndex extends FileBasedIndexExtension<Funct
|
||||
@NotNull
|
||||
@Override
|
||||
public FileBasedIndex.InputFilter getInputFilter() {
|
||||
return new DefaultFileTypeSpecificInputFilter(JavaFileType.INSTANCE) {
|
||||
return new DefaultFileTypeSpecificWithProjectInputFilter(JavaFileType.INSTANCE) {
|
||||
@Override
|
||||
public boolean acceptInput(@NotNull VirtualFile file) {
|
||||
return super.acceptInput(file) && JavaFileElementType.isInSourceContent(file);
|
||||
public boolean acceptInput(@NotNull IndexedFile file) {
|
||||
Project project = file.getProject();
|
||||
return super.acceptInput(file) &&
|
||||
(JavaFileElementType.isInSourceContent(file.getFile())) ||
|
||||
(project != null && FileIndexFacade.getInstance(project).isInSource(file.getFile()));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
+3
-2
@@ -81,6 +81,7 @@ public final class JavaFunctionalExpressionSearcher extends QueryExecutorBase<Ps
|
||||
if (InjectedLanguageManager.getInstance(project).isInjectedFragment(aClass.getContainingFile()) || !hasJava8Modules(project)) {
|
||||
return;
|
||||
}
|
||||
PsiSearchHelper psiSearchHelper = PsiSearchHelper.getInstance(project);
|
||||
|
||||
Set<PsiClass> visited = new HashSet<>();
|
||||
processSubInterfaces(aClass, visited);
|
||||
@@ -90,7 +91,7 @@ public final class JavaFunctionalExpressionSearcher extends QueryExecutorBase<Ps
|
||||
PsiType samType = saMethod.getReturnType();
|
||||
if (samType == null) continue;
|
||||
|
||||
SearchScope scope = samClass.getUseScope().intersectWith(session.scope);
|
||||
SearchScope scope = psiSearchHelper.getUseScope(samClass).intersectWith(session.scope);
|
||||
descriptors.add(new SamDescriptor(samClass, saMethod, samType, GlobalSearchScopeUtil.toGlobalSearchScope(scope, project)));
|
||||
}
|
||||
}
|
||||
@@ -111,7 +112,7 @@ public final class JavaFunctionalExpressionSearcher extends QueryExecutorBase<Ps
|
||||
MultiMap<VirtualFile, FunExprOccurrence> result = MultiMap.createLinkedSet();
|
||||
descriptors.get(0).dumbService.runReadActionInSmartMode(() -> {
|
||||
for (SamDescriptor descriptor : descriptors) {
|
||||
GlobalSearchScope scope = new JavaSourceFilterScope(descriptor.effectiveUseScope);
|
||||
GlobalSearchScope scope = new JavaSourceFilterScope(descriptor.effectiveUseScope, false, true);
|
||||
for (FunctionalExpressionKey key : descriptor.keys) {
|
||||
FileBasedIndex.getInstance().processValues(JavaFunctionalExpressionIndex.INDEX_ID, key, null, (file, infos) -> {
|
||||
result.putValues(file, ContainerUtil.map(infos, entry -> entry.occurrence));
|
||||
|
||||
@@ -17,21 +17,27 @@ import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
|
||||
public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
|
||||
private final @Nullable ProjectFileIndex myIndex;
|
||||
private final boolean myIncludeVersions;
|
||||
private final boolean myIncludeLibrarySources;
|
||||
|
||||
public JavaSourceFilterScope(@NotNull GlobalSearchScope delegate) {
|
||||
this(delegate, false);
|
||||
}
|
||||
|
||||
public JavaSourceFilterScope(@NotNull GlobalSearchScope delegate, boolean includeVersions) {
|
||||
this(delegate, includeVersions, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* By default, the scope excludes version-specific classes of multi-release .jar files
|
||||
* (i.e. *.class files located under META-INF/versions/ directory).
|
||||
* Setting {@code includeVersions} parameter to {@code true} allows such files to pass the filter.
|
||||
*/
|
||||
public JavaSourceFilterScope(@NotNull GlobalSearchScope delegate, boolean includeVersions) {
|
||||
public JavaSourceFilterScope(@NotNull GlobalSearchScope delegate, boolean includeVersions, boolean includeLibrarySources) {
|
||||
super(delegate);
|
||||
Project project = getProject();
|
||||
myIndex = project == null ? null : ProjectRootManager.getInstance(project).getFileIndex();
|
||||
myIncludeVersions = includeVersions;
|
||||
myIncludeLibrarySources = includeLibrarySources;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,7 +55,7 @@ public class JavaSourceFilterScope extends DelegatingGlobalSearchScope {
|
||||
}
|
||||
|
||||
return myIndex.isUnderSourceRootOfType(file, JavaModuleSourceRootTypes.SOURCES) ||
|
||||
myBaseScope.isForceSearchingInLibrarySources() && myIndex.isInLibrarySource(file);
|
||||
(myIncludeLibrarySources || myBaseScope.isForceSearchingInLibrarySources()) && myIndex.isInLibrarySource(file);
|
||||
}
|
||||
|
||||
private static boolean isVersioned(VirtualFile file, ProjectFileIndex index) {
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,5 @@
|
||||
public class TestClass {
|
||||
TestSrcInterface lambdaImpl = () -> {
|
||||
return "";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
public class TestInterfaceImpl implements TestSrcInterface {
|
||||
@Override
|
||||
public String testMethod() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public interface TestSrcInterface {
|
||||
public String testMethod();
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.scopes;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.daemon.LineMarkerInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
|
||||
import com.intellij.codeInsight.daemon.impl.MarkerType;
|
||||
import com.intellij.ide.plugins.DynamicPluginsTestUtil;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.roots.OrderRootType;
|
||||
import com.intellij.openapi.roots.impl.LibraryScopeCache;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.UseScopeEnlarger;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.OverridingMethodsSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Test ensuring searchers use {@link com.intellij.psi.search.PsiSearchHelper} to enable enlarging use scopes in plugins.
|
||||
* For this test, we will enlarge the use scope to include libraries.
|
||||
*/
|
||||
public class LibraryUseSearchUsingScopeEnlargerTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Disposer.register(getTestRootDisposable(), DynamicPluginsTestUtil.loadExtensionWithText(
|
||||
"<useScopeEnlarger implementation=\"com.intellij.scopes.LibraryUseSearchUsingScopeEnlargerTest$LibraryUseScopeEnlarger\"/>",
|
||||
getClass().getClassLoader()));
|
||||
//bug? Test seems to use stale data.
|
||||
LocalFileSystem.getInstance().refreshIoFiles(Collections.singleton(new File(getTestDataPath())), false, true, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tuneFixture(JavaModuleFixtureBuilder<?> moduleBuilder) throws Exception {
|
||||
super.tuneFixture(moduleBuilder);
|
||||
moduleBuilder.addLibrary("lib", Map.of(OrderRootType.CLASSES, new String[]{getTestDataPath() + "lib/classes"},
|
||||
OrderRootType.SOURCES, new String[]{getTestDataPath() + "lib/src"}));
|
||||
moduleBuilder.addSourceContentRoot(getTestDataPath() + "src");
|
||||
moduleBuilder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15);
|
||||
moduleBuilder.setLanguageLevel(LanguageLevel.JDK_1_8);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchFromScourceLooksInLibrary() {
|
||||
PsiClass sourceClass = myFixture.findClass("TestSrcInterface");
|
||||
PsiClass libImpl = myFixture.findClass("TestInterfaceImpl");
|
||||
Collection<PsiClass> classInheritors = ClassInheritorsSearch.search(sourceClass).findAll();
|
||||
|
||||
assertContainsElements(classInheritors, libImpl);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLineMarkersUseEnlarger() {
|
||||
PsiClass sourceClass = myFixture.findClass("TestSrcInterface");
|
||||
|
||||
myFixture.openFileInEditor(sourceClass.getContainingFile().getVirtualFile());
|
||||
myFixture.doHighlighting();
|
||||
Document document = myFixture.getDocument(sourceClass.getContainingFile());
|
||||
|
||||
List<LineMarkerInfo<?>> lineMarkers = DaemonCodeAnalyzerImpl.getLineMarkers(document, getProject());
|
||||
assertSize(2, lineMarkers);
|
||||
|
||||
assertEquals(MarkerType.SUBCLASSED_CLASS.getNavigationHandler(), lineMarkers.get(0).getNavigationHandler());
|
||||
assertEquals(MarkerType.OVERRIDDEN_METHOD.getNavigationHandler(), lineMarkers.get(1).getNavigationHandler());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverridingMethodSearcherUsesEnlarger() {
|
||||
PsiClass sourceClass = myFixture.findClass("TestSrcInterface");
|
||||
PsiMethod testMethod = PsiTreeUtil.findChildOfType(sourceClass, PsiMethod.class);
|
||||
|
||||
Collection<PsiMethod> methods = OverridingMethodsSearch.search(testMethod, GlobalSearchScope.allScope(getProject()), false).findAll();
|
||||
assertSize(1, methods);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNls String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/libraryScopeEnlarger/";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean toAddSourceRoot() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class LibraryUseScopeEnlarger extends UseScopeEnlarger {
|
||||
@Override
|
||||
public @Nullable SearchScope getAdditionalUseScope(@NotNull PsiElement element) {
|
||||
return LibraryScopeCache.getInstance(element.getProject()).getLibrariesOnlyScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.util.indexing;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.util.Consumer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public class DefaultFileTypeSpecificWithProjectInputFilter implements FileBasedIndex.FileTypeSpecificInputFilter,
|
||||
FileBasedIndex.ProjectSpecificInputFilter {
|
||||
private final FileType[] myFileTypes;
|
||||
|
||||
public DefaultFileTypeSpecificWithProjectInputFilter(FileType @NotNull ... fileTypes) {
|
||||
myFileTypes = fileTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean acceptInput(@NotNull IndexedFile file) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerFileTypesUsedForIndexing(@NotNull Consumer<? super FileType> fileTypeSink) {
|
||||
for (FileType ft : myFileTypes) {
|
||||
fileTypeSink.consume(ft);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user