Search in sources :

Example 1 with CompilerDirectHierarchyInfo

use of com.intellij.compiler.CompilerDirectHierarchyInfo in project intellij-community by JetBrains.

the class JavaDirectInheritorsSearcher method execute.

@Override
public boolean execute(@NotNull final DirectClassInheritorsSearch.SearchParameters parameters, @NotNull final Processor<PsiClass> consumer) {
    final PsiClass baseClass = parameters.getClassToProcess();
    assert parameters.isCheckInheritance();
    final Project project = PsiUtilCore.getProjectInReadAction(baseClass);
    if (JavaClassInheritorsSearcher.isJavaLangObject(baseClass)) {
        SearchScope useScope = ReadAction.compute(baseClass::getUseScope);
        return AllClassesSearch.search(useScope, project).forEach(psiClass -> {
            ProgressManager.checkCanceled();
            if (psiClass.isInterface()) {
                return consumer.process(psiClass);
            }
            final PsiClass superClass = psiClass.getSuperClass();
            return superClass == null || !JavaClassInheritorsSearcher.isJavaLangObject(superClass) || consumer.process(psiClass);
        });
    }
    SearchScope scope;
    SearchScope useScope;
    CompilerDirectHierarchyInfo info = performSearchUsingCompilerIndices(parameters, parameters.getScope(), project);
    if (info == null) {
        scope = parameters.getScope();
        useScope = ReadAction.compute(baseClass::getUseScope);
    } else {
        if (!processInheritorCandidates(info.getHierarchyChildren(), consumer, parameters.includeAnonymous()))
            return false;
        scope = ReadAction.compute(() -> parameters.getScope().intersectWith(info.getDirtyScope()));
        useScope = ReadAction.compute(() -> baseClass.getUseScope().intersectWith(info.getDirtyScope()));
    }
    PsiClass[] cache = getOrCalculateDirectSubClasses(project, baseClass, useScope);
    if (cache.length == 0) {
        return true;
    }
    VirtualFile baseClassJarFile = null;
    // iterate by same-FQN groups. For each group process only same-jar subclasses, or all of them if they are all outside the jarFile.
    int groupStart = 0;
    boolean sameJarClassFound = false;
    String currentFQN = null;
    // here we cache results of isInScope(scope, subClass) to avoid calculating it twice
    boolean[] isOutOfScope = new boolean[cache.length];
    for (int i = 0; i <= cache.length; i++) {
        ProgressManager.checkCanceled();
        PsiClass subClass = i == cache.length ? null : cache[i];
        if (subClass instanceof PsiAnonymousClass) {
            // we reached anonymous classes tail, process them all and exit
            if (!parameters.includeAnonymous()) {
                return true;
            }
        }
        if (i != cache.length && !isInScope(scope, subClass)) {
            isOutOfScope[i] = true;
            continue;
        }
        String fqn = i == cache.length ? null : ReadAction.compute(subClass::getQualifiedName);
        if (currentFQN != null && Comparing.equal(fqn, currentFQN)) {
            VirtualFile currentJarFile = getJarFile(subClass);
            if (baseClassJarFile == null) {
                baseClassJarFile = getJarFile(baseClass);
            }
            boolean fromSameJar = Comparing.equal(currentJarFile, baseClassJarFile);
            if (fromSameJar) {
                if (!consumer.process(subClass))
                    return false;
                sameJarClassFound = true;
            }
        } else {
            currentFQN = fqn;
            // the end of the same-FQN group. Process only same-jar classes in subClasses[groupStart..i-1] group or the whole group if there were none.
            if (!sameJarClassFound) {
                for (int g = groupStart; g < i; g++) {
                    ProgressManager.checkCanceled();
                    if (isOutOfScope[g])
                        continue;
                    PsiClass subClassCandidate = cache[g];
                    if (!consumer.process(subClassCandidate))
                        return false;
                }
            }
            groupStart = i;
            sameJarClassFound = false;
        }
    }
    return true;
}
Also used : VirtualFile(com.intellij.openapi.vfs.VirtualFile) Project(com.intellij.openapi.project.Project) SearchScope(com.intellij.psi.search.SearchScope) GlobalSearchScope(com.intellij.psi.search.GlobalSearchScope) CompilerDirectHierarchyInfo(com.intellij.compiler.CompilerDirectHierarchyInfo)

Aggregations

CompilerDirectHierarchyInfo (com.intellij.compiler.CompilerDirectHierarchyInfo)1 Project (com.intellij.openapi.project.Project)1 VirtualFile (com.intellij.openapi.vfs.VirtualFile)1 GlobalSearchScope (com.intellij.psi.search.GlobalSearchScope)1 SearchScope (com.intellij.psi.search.SearchScope)1