mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
javac ast indices: inheritor/lambda search: cache only candidate's ids (in read action) and restore psi-elements only when a search client asks
This commit is contained in:
+48
-15
@@ -16,38 +16,75 @@
|
||||
package com.intellij.compiler.backwardRefs;
|
||||
|
||||
import com.intellij.compiler.CompilerDirectHierarchyInfo;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
class CompilerHierarchyInfoImpl implements CompilerDirectHierarchyInfo {
|
||||
private final static Logger LOG = Logger.getInstance(CompilerHierarchyInfoImpl.class);
|
||||
|
||||
private final PsiNamedElement myBaseClass;
|
||||
private final GlobalSearchScope myDirtyScope;
|
||||
private final GlobalSearchScope mySearchScope;
|
||||
private final Couple<Map<VirtualFile, PsiElement[]>> myCandidatePerFile;
|
||||
private final Project myProject;
|
||||
private final FileType mySearchFileType;
|
||||
private final CompilerHierarchySearchType mySearchType;
|
||||
private final Map<VirtualFile, Object[]> myCandidatePerFile;
|
||||
|
||||
CompilerHierarchyInfoImpl(Couple<Map<VirtualFile, PsiElement[]>> candidatePerFile,
|
||||
CompilerHierarchyInfoImpl(Map<VirtualFile, Object[]> candidatesPerFile,
|
||||
PsiNamedElement baseClass,
|
||||
GlobalSearchScope dirtyScope,
|
||||
GlobalSearchScope searchScope) {
|
||||
myCandidatePerFile = candidatePerFile;
|
||||
GlobalSearchScope searchScope,
|
||||
Project project,
|
||||
FileType searchFileType,
|
||||
CompilerHierarchySearchType searchType) {
|
||||
myCandidatePerFile = candidatesPerFile;
|
||||
myBaseClass = baseClass;
|
||||
myDirtyScope = dirtyScope;
|
||||
mySearchScope = searchScope;
|
||||
myProject = project;
|
||||
mySearchFileType = searchFileType;
|
||||
mySearchType = searchType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Stream<PsiElement> getHierarchyChildren() {
|
||||
return selectClassesInScope(myCandidatePerFile.getFirst(), mySearchScope);
|
||||
}
|
||||
PsiManager psiManager = PsiManager.getInstance(myProject);
|
||||
final LanguageLightRefAdapter adapter = ObjectUtils.notNull(CompilerReferenceServiceImpl.findAdapterForFileType(mySearchFileType));
|
||||
return myCandidatePerFile
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(e -> mySearchScope.contains(e.getKey()))
|
||||
.flatMap(e -> {
|
||||
final VirtualFile file = e.getKey();
|
||||
final Object[] definitions = e.getValue();
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Stream<PsiElement> getHierarchyChildCandidates() {
|
||||
return selectClassesInScope(myCandidatePerFile.getSecond(), mySearchScope);
|
||||
final PsiElement[] hierarchyChildren = ReadAction.compute(() -> {
|
||||
final PsiFileWithStubSupport psiFile = (PsiFileWithStubSupport)psiManager.findFile(file);
|
||||
return mySearchType.performSearchInFile(definitions, myBaseClass, psiFile, adapter);
|
||||
});
|
||||
|
||||
if (hierarchyChildren.length == definitions.length) {
|
||||
return Stream.of(hierarchyChildren);
|
||||
}
|
||||
else {
|
||||
LOG.assertTrue(mySearchType == CompilerHierarchySearchType.DIRECT_INHERITOR, "Should not happens for functional expression search");
|
||||
return Stream.of(hierarchyChildren).filter(c -> ReadAction.compute(() -> adapter.isDirectInheritor(c, myBaseClass)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,8 +92,4 @@ class CompilerHierarchyInfoImpl implements CompilerDirectHierarchyInfo {
|
||||
public GlobalSearchScope getDirtyScope() {
|
||||
return myDirtyScope;
|
||||
}
|
||||
|
||||
private static <T extends PsiElement> Stream<T> selectClassesInScope(Map<VirtualFile, T[]> classesPerFile, GlobalSearchScope searchScope) {
|
||||
return classesPerFile.entrySet().stream().filter(e -> searchScope.contains(e.getKey())).flatMap(e -> Stream.of(e.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
+17
-8
@@ -26,40 +26,49 @@ import java.util.Collection;
|
||||
enum CompilerHierarchySearchType {
|
||||
DIRECT_INHERITOR {
|
||||
@Override
|
||||
PsiElement[] performSearchInFile(Collection<? extends LightRef> definitions,
|
||||
PsiElement[] performSearchInFile(Object[] definitions,
|
||||
PsiNamedElement baseElement,
|
||||
ByteArrayEnumerator nameEnumerator,
|
||||
PsiFileWithStubSupport file,
|
||||
LanguageLightRefAdapter adapter) {
|
||||
return adapter.findDirectInheritorCandidatesInFile((Collection<LightRef.LightClassHierarchyElementDef>)definitions, nameEnumerator, file, baseElement);
|
||||
return adapter.findDirectInheritorCandidatesInFile((String[])definitions, file, baseElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<? extends LightRef> getRequiredClass(LanguageLightRefAdapter adapter) {
|
||||
return adapter.getHierarchyObjectClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
Object[] convertIdToSearchableArray(Collection<LightRef> lightRef, ByteArrayEnumerator byteArrayEnumerator) {
|
||||
return lightRef.stream().map(r -> byteArrayEnumerator.getName(((LightRef.LightClassHierarchyElementDef)r).getName())).toArray(String[]::new);
|
||||
}
|
||||
},
|
||||
FUNCTIONAL_EXPRESSION {
|
||||
@Override
|
||||
PsiElement[] performSearchInFile(Collection<? extends LightRef> definitions,
|
||||
PsiElement[] performSearchInFile(Object[] definitions,
|
||||
PsiNamedElement baseElement,
|
||||
ByteArrayEnumerator nameEnumerator,
|
||||
PsiFileWithStubSupport file,
|
||||
LanguageLightRefAdapter adapter) {
|
||||
return adapter.findFunExpressionsInFile((Collection<LightRef.LightFunExprDef>)definitions, file);
|
||||
return adapter.findFunExpressionsInFile((Integer[])definitions, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
Class<? extends LightRef> getRequiredClass(LanguageLightRefAdapter adapter) {
|
||||
return adapter.getFunExprClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
Object[] convertIdToSearchableArray(Collection<LightRef> lightRef, ByteArrayEnumerator byteArrayEnumerator) {
|
||||
return lightRef.stream().map(r -> ((LightRef.LightFunExprDef) r).getId()).toArray(Integer[]::new);
|
||||
}
|
||||
};
|
||||
|
||||
abstract PsiElement[] performSearchInFile(Collection<? extends LightRef> definitions,
|
||||
abstract PsiElement[] performSearchInFile(Object[] definitions,
|
||||
PsiNamedElement baseElement,
|
||||
ByteArrayEnumerator nameEnumerator,
|
||||
PsiFileWithStubSupport file,
|
||||
LanguageLightRefAdapter adapter);
|
||||
|
||||
abstract Class<? extends LightRef> getRequiredClass(LanguageLightRefAdapter adapter);
|
||||
|
||||
abstract Object[] convertIdToSearchableArray(Collection<LightRef> lightRef, ByteArrayEnumerator byteArrayEnumerator);
|
||||
}
|
||||
|
||||
+10
-37
@@ -16,21 +16,14 @@
|
||||
package com.intellij.compiler.backwardRefs;
|
||||
|
||||
import com.intellij.compiler.server.BuildManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import com.intellij.psi.impl.source.PsiFileWithStubSupport;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.containers.Queue;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import gnu.trove.TIntHashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -78,25 +71,23 @@ class CompilerReferenceReader {
|
||||
* 1st map: inheritors. Can be used without explicit inheritance verification
|
||||
* 2nd map: candidates. One need to check that these classes are really direct inheritors
|
||||
*/
|
||||
@Nullable
|
||||
Couple<Map<VirtualFile, PsiElement[]>> getDirectInheritors(@NotNull PsiNamedElement baseClass,
|
||||
@NotNull LightRef searchElement,
|
||||
@NotNull GlobalSearchScope searchScope,
|
||||
@NotNull GlobalSearchScope dirtyScope,
|
||||
@NotNull Project project,
|
||||
@NotNull FileType fileType,
|
||||
@NotNull CompilerHierarchySearchType searchType) {
|
||||
@NotNull
|
||||
Map<VirtualFile, Object[]> getDirectInheritors(@NotNull LightRef searchElement,
|
||||
@NotNull GlobalSearchScope searchScope,
|
||||
@NotNull GlobalSearchScope dirtyScope,
|
||||
@NotNull FileType fileType,
|
||||
@NotNull CompilerHierarchySearchType searchType) {
|
||||
Collection<CompilerBackwardReferenceIndex.LightDefinition> candidates;
|
||||
synchronized (myHierarchyLock) {
|
||||
candidates = myIndex.getBackwardHierarchyMap().get(searchElement);
|
||||
}
|
||||
if (candidates == null) return Couple.of(Collections.emptyMap(), Collections.emptyMap());
|
||||
if (candidates == null) return Collections.emptyMap();
|
||||
|
||||
GlobalSearchScope effectiveSearchScope = GlobalSearchScope.notScope(dirtyScope).intersectWith(searchScope);
|
||||
LanguageLightRefAdapter adapter = CompilerReferenceServiceImpl.findAdapterForFileType(fileType);
|
||||
LOG.assertTrue(adapter != null, "adapter is null for file type: " + fileType);
|
||||
Class<? extends LightRef> requiredLightRefClass = searchType.getRequiredClass(adapter);
|
||||
Map<VirtualFile, List<LightRef>> candidatesPerFile;
|
||||
Map<VirtualFile, Object[]> candidatesPerFile;
|
||||
synchronized (myReferenceLock) {
|
||||
candidatesPerFile = candidates
|
||||
.stream()
|
||||
@@ -114,28 +105,10 @@ class CompilerReferenceReader {
|
||||
}
|
||||
})
|
||||
.filter(Objects::nonNull)
|
||||
.collect(groupingBy(x -> x.containingFile, mapping(x -> x.def, toList())));
|
||||
.collect(groupingBy(x -> x.containingFile, mapping(x -> x.def, collectingAndThen(toList(), l -> searchType.convertIdToSearchableArray(l, myIndex.getByteSeqEum())))));
|
||||
}
|
||||
|
||||
if (candidatesPerFile.isEmpty()) return Couple.of(Collections.emptyMap(), Collections.emptyMap());
|
||||
|
||||
Map<VirtualFile, PsiElement[]> inheritors = new THashMap<>(candidatesPerFile.size());
|
||||
Map<VirtualFile, PsiElement[]> inheritorCandidates = new THashMap<>();
|
||||
|
||||
final PsiManager psiManager = ReadAction.compute(() -> PsiManager.getInstance(project));
|
||||
|
||||
candidatesPerFile.forEach((file, directInheritors) -> ReadAction.run(() -> {
|
||||
final PsiFileWithStubSupport psiFile = (PsiFileWithStubSupport) psiManager.findFile(file);
|
||||
final PsiElement[] currInheritors = searchType.performSearchInFile(directInheritors, baseClass, myIndex.getByteSeqEum(), psiFile, adapter);
|
||||
if (currInheritors.length == directInheritors.size()) {
|
||||
inheritors.put(file, currInheritors);
|
||||
}
|
||||
else {
|
||||
inheritorCandidates.put(file, currInheritors);
|
||||
}
|
||||
}));
|
||||
|
||||
return Couple.of(inheritors, inheritorCandidates);
|
||||
return candidatesPerFile.isEmpty() ? Collections.emptyMap() : candidatesPerFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+23
-23
@@ -30,7 +30,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.roots.impl.LibraryScopeCache;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.ModificationTracker;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.VirtualFileWithId;
|
||||
@@ -185,32 +184,31 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private CompilerDirectHierarchyInfo getHierarchyInfo(@NotNull PsiNamedElement aClass,
|
||||
@NotNull GlobalSearchScope useScope,
|
||||
@NotNull GlobalSearchScope searchScope,
|
||||
@NotNull FileType searchFileType,
|
||||
@NotNull CompilerHierarchySearchType searchType) {
|
||||
private CompilerHierarchyInfoImpl getHierarchyInfo(@NotNull PsiNamedElement aClass,
|
||||
@NotNull GlobalSearchScope useScope,
|
||||
@NotNull GlobalSearchScope searchScope,
|
||||
@NotNull FileType searchFileType,
|
||||
@NotNull CompilerHierarchySearchType searchType) {
|
||||
if (!isServiceEnabledFor(aClass) || searchScope == LibraryScopeCache.getInstance(myProject).getLibrariesOnlyScope()) return null;
|
||||
|
||||
Couple<Map<VirtualFile, PsiElement[]>> directInheritorsAndCandidates =
|
||||
CachedValuesManager.getCachedValue(aClass, () -> CachedValueProvider.Result.create(
|
||||
new ConcurrentFactoryMap<HierarchySearchKey, Couple<Map<VirtualFile, PsiElement[]>>>() {
|
||||
Map<VirtualFile, Object[]> candidatesPerFile = ReadAction.compute(() -> CachedValuesManager.getCachedValue(aClass, () -> CachedValueProvider.Result.create(
|
||||
new ConcurrentFactoryMap<HierarchySearchKey, Map<VirtualFile, Object[]>>() {
|
||||
@Nullable
|
||||
@Override
|
||||
protected Couple<Map<VirtualFile, PsiElement[]>> create(HierarchySearchKey key) {
|
||||
protected Map<VirtualFile, Object[]> create(HierarchySearchKey key) {
|
||||
return calculateDirectInheritors(aClass,
|
||||
useScope,
|
||||
key.mySearchFileType,
|
||||
key.mySearchType);
|
||||
}
|
||||
}, PsiModificationTracker.MODIFICATION_COUNT, this)).get(new HierarchySearchKey(searchType, searchFileType));
|
||||
}, PsiModificationTracker.MODIFICATION_COUNT, this)).get(new HierarchySearchKey(searchType, searchFileType)));
|
||||
|
||||
if (directInheritorsAndCandidates == null) return null;
|
||||
if (candidatesPerFile == null) return null;
|
||||
GlobalSearchScope dirtyScope = myDirtyModulesHolder.getDirtyScope();
|
||||
if (ElementPlace.LIB == ReadAction.compute(() -> ElementPlace.get(aClass.getContainingFile().getVirtualFile(), myProjectFileIndex))) {
|
||||
dirtyScope = dirtyScope.union(LibraryScopeCache.getInstance(myProject).getLibrariesOnlyScope());
|
||||
}
|
||||
return new CompilerHierarchyInfoImpl(directInheritorsAndCandidates, dirtyScope, searchScope);
|
||||
return new CompilerHierarchyInfoImpl(candidatesPerFile, aClass, dirtyScope, searchScope, myProject, searchFileType, searchType);
|
||||
}
|
||||
|
||||
private boolean isServiceEnabledFor(PsiElement element) {
|
||||
@@ -223,11 +221,10 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
return myReader != null && isEnabled();
|
||||
}
|
||||
|
||||
private Couple<Map<VirtualFile, PsiElement[]>> calculateDirectInheritors(@NotNull PsiNamedElement aClass,
|
||||
@NotNull GlobalSearchScope useScope,
|
||||
@NotNull FileType searchFileType,
|
||||
@NotNull CompilerHierarchySearchType searchType) {
|
||||
|
||||
private Map<VirtualFile, Object[]> calculateDirectInheritors(@NotNull PsiNamedElement aClass,
|
||||
@NotNull GlobalSearchScope useScope,
|
||||
@NotNull FileType searchFileType,
|
||||
@NotNull CompilerHierarchySearchType searchType) {
|
||||
final CompilerElementInfo searchElementInfo = asCompilerElements(aClass, false);
|
||||
if (searchElementInfo == null) return null;
|
||||
LightRef searchElement = searchElementInfo.searchElements[0];
|
||||
@@ -235,7 +232,7 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
myReadDataLock.lock();
|
||||
try {
|
||||
if (myReader == null) return null;
|
||||
return myReader.getDirectInheritors(aClass, searchElement, useScope, myDirtyModulesHolder.getDirtyScope(), myProject, searchFileType, searchType);
|
||||
return myReader.getDirectInheritors(searchElement, useScope, myDirtyModulesHolder.getDirtyScope(), searchFileType, searchType);
|
||||
} finally {
|
||||
myReadDataLock.unlock();
|
||||
}
|
||||
@@ -276,14 +273,15 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
myReadDataLock.lock();
|
||||
try {
|
||||
if (myReader == null) return null;
|
||||
VirtualFile file = ReadAction.compute(() -> PsiUtilCore.getVirtualFile(psiElement));
|
||||
VirtualFile file = PsiUtilCore.getVirtualFile(psiElement);
|
||||
if (file == null) return null;
|
||||
ElementPlace place = ElementPlace.get(file, myProjectFileIndex);
|
||||
if (place == null || (place == ElementPlace.SRC && myDirtyModulesHolder.contains(file))) {
|
||||
return null;
|
||||
}
|
||||
final LanguageLightRefAdapter adapter = findAdapterForFileType(file.getFileType());
|
||||
if (adapter == null) return null;
|
||||
final LightRef ref = ReadAction.compute(() -> adapter.asLightUsage(psiElement, myReader.getNameEnumerator()));
|
||||
final LightRef ref = adapter.asLightUsage(psiElement, myReader.getNameEnumerator());
|
||||
if (ref == null) return null;
|
||||
if (place == ElementPlace.LIB && buildHierarchyForLibraryElements) {
|
||||
final List<LightRef> elements = adapter.getHierarchyRestrictedToLibraryScope(ref,
|
||||
@@ -304,8 +302,6 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
} finally {
|
||||
myReadDataLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void closeReaderIfNeed() {
|
||||
@@ -454,4 +450,8 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
return 31 * mySearchType.hashCode() + mySearchFileType.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private static class RawSearchResult {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
@@ -70,23 +71,27 @@ class DirtyModulesHolder extends UserDataHolderBase {
|
||||
}
|
||||
|
||||
GlobalSearchScope getDirtyScope() {
|
||||
return CachedValuesManager.getManager(myService.getProject()).getCachedValue(this, () ->
|
||||
CachedValueProvider.Result.create(calculateDirtyModules(), PsiModificationTracker.MODIFICATION_COUNT, VirtualFileManager.getInstance(), myService));
|
||||
final Project project = myService.getProject();
|
||||
synchronized (myLock) {
|
||||
if (myCompilationPhase) {
|
||||
return GlobalSearchScope.allScope(project);
|
||||
}
|
||||
return ReadAction.compute(() -> CachedValuesManager.getManager(project).getCachedValue(this, () ->
|
||||
CachedValueProvider.Result.create(calculateDirtyModules(), PsiModificationTracker.MODIFICATION_COUNT, VirtualFileManager.getInstance(), myService)));
|
||||
}
|
||||
}
|
||||
|
||||
private GlobalSearchScope calculateDirtyModules() {
|
||||
synchronized (myLock) {
|
||||
final Set<Module> dirtyModules = new THashSet<>(myVFSChangedModules);
|
||||
for (Document document : myFileDocManager.getUnsavedDocuments()) {
|
||||
final Module m = getModuleForSourceContentFile(myFileDocManager.getFile(document));
|
||||
if (m != null) dirtyModules.add(m);
|
||||
}
|
||||
for (Document document : ReadAction.compute(() -> myPsiDocManager.getUncommittedDocuments())) {
|
||||
final Module m = getModuleForSourceContentFile(ObjectUtils.notNull(myPsiDocManager.getPsiFile(document)).getVirtualFile());
|
||||
if (m != null) dirtyModules.add(m);
|
||||
}
|
||||
return dirtyModules.stream().map(Module::getModuleWithDependentsScope).reduce(GlobalSearchScope.EMPTY_SCOPE, (s1, s2) -> s1.union(s2));
|
||||
final Set<Module> dirtyModules = new THashSet<>(myVFSChangedModules);
|
||||
for (Document document : myFileDocManager.getUnsavedDocuments()) {
|
||||
final Module m = getModuleForSourceContentFile(myFileDocManager.getFile(document));
|
||||
if (m != null) dirtyModules.add(m);
|
||||
}
|
||||
for (Document document : myPsiDocManager.getUncommittedDocuments()) {
|
||||
final Module m = getModuleForSourceContentFile(ObjectUtils.notNull(myPsiDocManager.getPsiFile(document)).getVirtualFile());
|
||||
if (m != null) dirtyModules.add(m);
|
||||
}
|
||||
return dirtyModules.stream().map(Module::getModuleWithDependentsScope).reduce(GlobalSearchScope.EMPTY_SCOPE, (s1, s2) -> s1.union(s2));
|
||||
}
|
||||
|
||||
boolean contains(VirtualFile file) {
|
||||
|
||||
+10
-8
@@ -35,7 +35,6 @@ import org.jetbrains.jps.backwardRefs.ByteArrayEnumerator;
|
||||
import org.jetbrains.jps.backwardRefs.LightRef;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -113,25 +112,28 @@ public class JavaLightUsageAdapter implements LanguageLightRefAdapter {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiClass[] findDirectInheritorCandidatesInFile(@NotNull Collection<LightRef.LightClassHierarchyElementDef> classes,
|
||||
@NotNull ByteArrayEnumerator byteArrayEnumerator,
|
||||
public PsiClass[] findDirectInheritorCandidatesInFile(@NotNull String[] internalNames,
|
||||
@NotNull PsiFileWithStubSupport file,
|
||||
@NotNull PsiNamedElement superClass) {
|
||||
String[] internalNames = classes.stream().map(LightRef.NamedLightRef::getName).map(byteArrayEnumerator::getName).toArray(String[]::new);
|
||||
return JavaCompilerElementRetriever.retrieveClassesByInternalNames(internalNames, superClass, file);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiFunctionalExpression[] findFunExpressionsInFile(@NotNull Collection<LightRef.LightFunExprDef> funExpressions,
|
||||
public PsiFunctionalExpression[] findFunExpressionsInFile(@NotNull Integer[] funExpressions,
|
||||
@NotNull PsiFileWithStubSupport file) {
|
||||
TIntHashSet requiredIndices = new TIntHashSet(funExpressions.size());
|
||||
for (LightRef.LightFunExprDef funExpr : funExpressions) {
|
||||
requiredIndices.add(funExpr.getId());
|
||||
TIntHashSet requiredIndices = new TIntHashSet(funExpressions.length);
|
||||
for (int funExpr : funExpressions) {
|
||||
requiredIndices.add(funExpr);
|
||||
}
|
||||
return JavaCompilerElementRetriever.retrieveFunExpressionsByIndices(requiredIndices, file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectInheritor(PsiElement candidate, PsiNamedElement baseClass) {
|
||||
return ((PsiClass) candidate).isInheritor((PsiClass) baseClass, false);
|
||||
}
|
||||
|
||||
private static boolean mayBeVisibleOutsideOwnerFile(@NotNull PsiElement element) {
|
||||
if (!(element instanceof PsiModifierListOwner)) return true;
|
||||
if (((PsiModifierListOwner)element).hasModifierProperty(PsiModifier.PRIVATE)) return false;
|
||||
|
||||
+4
-4
@@ -25,7 +25,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jps.backwardRefs.ByteArrayEnumerator;
|
||||
import org.jetbrains.jps.backwardRefs.LightRef;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -77,8 +76,7 @@ public interface LanguageLightRefAdapter {
|
||||
* found elements really inheritors.
|
||||
*/
|
||||
@NotNull
|
||||
PsiElement[] findDirectInheritorCandidatesInFile(@NotNull Collection<LightRef.LightClassHierarchyElementDef> internalNames,
|
||||
@NotNull ByteArrayEnumerator byteArrayEnumerator,
|
||||
PsiElement[] findDirectInheritorCandidatesInFile(@NotNull String[] internalNames,
|
||||
@NotNull PsiFileWithStubSupport file,
|
||||
@NotNull PsiNamedElement superClass);
|
||||
|
||||
@@ -87,6 +85,8 @@ public interface LanguageLightRefAdapter {
|
||||
* @return functional expressions for given functional type. Should return
|
||||
*/
|
||||
@NotNull
|
||||
PsiElement[] findFunExpressionsInFile(@NotNull Collection<LightRef.LightFunExprDef> indices,
|
||||
PsiElement[] findFunExpressionsInFile(@NotNull Integer[] indices,
|
||||
@NotNull PsiFileWithStubSupport file);
|
||||
|
||||
boolean isDirectInheritor(PsiElement candidate, PsiNamedElement baseClass);
|
||||
}
|
||||
|
||||
@@ -31,12 +31,6 @@ public interface CompilerDirectHierarchyInfo {
|
||||
@NotNull
|
||||
Stream<PsiElement> getHierarchyChildren();
|
||||
|
||||
/**
|
||||
* Must be explicitly checked do they are really direct children in hierarchy of classes or functional expressions
|
||||
*/
|
||||
@NotNull
|
||||
Stream<PsiElement> getHierarchyChildCandidates();
|
||||
|
||||
/**
|
||||
* A scope where compiler based index search was not performed
|
||||
*/
|
||||
|
||||
+2
-6
@@ -81,8 +81,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
|
||||
CompilerDirectHierarchyInfo info = performSearchUsingCompilerIndices(parameters, scope, project);
|
||||
if (info != null) {
|
||||
if (!processInheritorCandidates(info.getHierarchyChildren(), consumer, parameters.includeAnonymous(), false, baseClass)) return false;
|
||||
if (!processInheritorCandidates(info.getHierarchyChildCandidates(), consumer, parameters.includeAnonymous(), true, baseClass)) return false;
|
||||
if (!processInheritorCandidates(info.getHierarchyChildren(), consumer, parameters.includeAnonymous())) return false;
|
||||
scope = scope.intersectWith(info.getDirtyScope());
|
||||
useScope = useScope.intersectWith(info.getDirtyScope());
|
||||
}
|
||||
@@ -294,16 +293,13 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor<PsiClass, Dir
|
||||
|
||||
private static boolean processInheritorCandidates(@NotNull Stream<PsiElement> classStream,
|
||||
@NotNull Processor<PsiClass> consumer,
|
||||
boolean acceptAnonymous,
|
||||
boolean checkInheritance,
|
||||
PsiClass baseClass) {
|
||||
boolean acceptAnonymous) {
|
||||
if (!acceptAnonymous) {
|
||||
classStream = classStream.filter(c -> !(c instanceof PsiAnonymousClass));
|
||||
}
|
||||
return ContainerUtil.process(classStream.iterator(), e -> {
|
||||
ProgressManager.checkCanceled();
|
||||
PsiClass c = (PsiClass) e;
|
||||
if (checkInheritance && ReadAction.compute(() -> !c.isInheritor(baseClass, false))) return true;
|
||||
return consumer.process(c);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.intellij.compiler;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.completion.AbstractCompilerAwareTest;
|
||||
import com.intellij.compiler.backwardRefs.CompilerReferenceServiceImpl;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -104,9 +103,6 @@ public class CompilerReferencesTest extends CompilerReferencesTestBase {
|
||||
assertOneOf(inheritor.getName(), "FooImpl", "FooImpl2", "FooInsideMethodImpl");
|
||||
}
|
||||
}
|
||||
|
||||
Collection<PsiClass> candidates = directInheritorInfo.getHierarchyChildCandidates().map(PsiClass.class::cast).collect(Collectors.toList());
|
||||
assertEmpty(candidates);
|
||||
}
|
||||
|
||||
public void testHierarchyOfLibClass() {
|
||||
|
||||
Reference in New Issue
Block a user