Search in sources :

Example 1 with ChainCompletionContext

use of com.intellij.compiler.classFilesIndex.chainsSearch.context.ChainCompletionContext in project intellij-community by JetBrains.

the class ChainsSearcher method search.

@NotNull
private static List<MethodsChain> search(final MethodsUsageIndexReader indexReader, final SearchInitializer initializer, final Set<String> toSet, final int pathMaximalLength, final int maxResultSize, final String targetQName, final ChainCompletionContext context) {
    final Set<String> allExcludedNames = MethodChainsSearchUtil.joinToHashSet(context.getExcludedQNames(), targetQName);
    final SearchInitializer.InitResult initResult = initializer.init(Collections.<String>emptySet());
    final Map<MethodIncompleteSignature, MethodsChain> knownDistance = initResult.getChains();
    final List<WeightAware<MethodIncompleteSignature>> allInitialVertexes = initResult.getVertexes();
    final LinkedList<WeightAware<Pair<MethodIncompleteSignature, MethodsChain>>> q = new LinkedList<>(ContainerUtil.map(allInitialVertexes, methodIncompleteSignatureWeightAware -> {
        final MethodIncompleteSignature underlying = methodIncompleteSignatureWeightAware.getUnderlying();
        return new WeightAware<>(Pair.create(underlying, new MethodsChain(context.resolveNotDeprecated(underlying), methodIncompleteSignatureWeightAware.getWeight(), underlying.getOwner())), methodIncompleteSignatureWeightAware.getWeight());
    }));
    int maxWeight = 0;
    for (final MethodsChain methodsChain : knownDistance.values()) {
        if (methodsChain.getChainWeight() > maxWeight) {
            maxWeight = methodsChain.getChainWeight();
        }
    }
    final ResultHolder result = new ResultHolder(context.getPsiManager());
    while (!q.isEmpty()) {
        ProgressManager.checkCanceled();
        final WeightAware<Pair<MethodIncompleteSignature, MethodsChain>> currentVertex = q.poll();
        final int currentVertexDistance = currentVertex.getWeight();
        final Pair<MethodIncompleteSignature, MethodsChain> currentVertexUnderlying = currentVertex.getUnderlying();
        final MethodsChain currentVertexMethodsChain = knownDistance.get(currentVertexUnderlying.getFirst());
        if (currentVertexDistance != currentVertexMethodsChain.getChainWeight()) {
            continue;
        }
        if (currentVertex.getUnderlying().getFirst().isStatic() || toSet.contains(currentVertex.getUnderlying().getFirst().getOwner())) {
            result.add(currentVertex.getUnderlying().getSecond());
            continue;
        }
        final String currentReturnType = currentVertexUnderlying.getFirst().getOwner();
        final SortedSet<UsageIndexValue> nextMethods = indexReader.getMethods(currentReturnType);
        final MaxSizeTreeSet<WeightAware<MethodIncompleteSignature>> currentSignatures = new MaxSizeTreeSet<>(maxResultSize);
        for (final UsageIndexValue indexValue : nextMethods) {
            final MethodIncompleteSignature vertex = indexValue.getMethodIncompleteSignature();
            final int occurrences = indexValue.getOccurrences();
            if (vertex.isStatic() || !vertex.getOwner().equals(targetQName)) {
                final int vertexDistance = Math.min(currentVertexDistance, occurrences);
                final MethodsChain knownVertexMethodsChain = knownDistance.get(vertex);
                if ((knownVertexMethodsChain == null || knownVertexMethodsChain.getChainWeight() < vertexDistance)) {
                    if (currentSignatures.isEmpty() || currentSignatures.last().getWeight() < vertexDistance) {
                        if (currentVertexMethodsChain.size() < pathMaximalLength - 1) {
                            final MethodIncompleteSignature methodInvocation = indexValue.getMethodIncompleteSignature();
                            final PsiMethod[] psiMethods = context.resolveNotDeprecated(methodInvocation);
                            if (psiMethods.length != 0 && MethodChainsSearchUtil.checkParametersForTypesQNames(psiMethods, allExcludedNames)) {
                                final MethodsChain newBestMethodsChain = currentVertexMethodsChain.addEdge(psiMethods, indexValue.getMethodIncompleteSignature().getOwner(), vertexDistance);
                                currentSignatures.add(new WeightAware<>(indexValue.getMethodIncompleteSignature(), vertexDistance));
                                knownDistance.put(vertex, newBestMethodsChain);
                            }
                        }
                    }
                } else {
                    break;
                }
            }
        }
        boolean updated = false;
        if (!currentSignatures.isEmpty()) {
            boolean isBreak = false;
            for (final WeightAware<MethodIncompleteSignature> sign : currentSignatures) {
                final PsiMethod[] resolved = context.resolveNotDeprecated(sign.getUnderlying());
                if (!isBreak) {
                    if (sign.getWeight() * NEXT_METHOD_IN_CHAIN_RATIO > currentVertex.getWeight()) {
                        final boolean stopChain = sign.getUnderlying().isStatic() || toSet.contains(sign.getUnderlying().getOwner());
                        if (stopChain) {
                            updated = true;
                            result.add(currentVertex.getUnderlying().getSecond().addEdge(resolved, sign.getUnderlying().getOwner(), sign.getWeight()));
                            continue;
                        } else {
                            updated = true;
                            final MethodsChain methodsChain = currentVertexUnderlying.second.addEdge(resolved, sign.getUnderlying().getOwner(), sign.getWeight());
                            q.add(new WeightAware<>(Pair.create(sign.getUnderlying(), methodsChain), sign.getWeight()));
                            continue;
                        }
                    }
                }
                final MethodsChain methodsChain = currentVertexUnderlying.second.addEdge(resolved, sign.getUnderlying().getOwner(), sign.getWeight());
                final ParametersMatcher.MatchResult parametersMatchResult = ParametersMatcher.matchParameters(methodsChain, context);
                if (parametersMatchResult.noUnmatchedAndHasMatched() && parametersMatchResult.hasTarget()) {
                    updated = true;
                    q.addFirst(new WeightAware<>(Pair.create(sign.getUnderlying(), methodsChain), sign.getWeight()));
                }
                isBreak = true;
            }
        }
        if (!updated && (currentVertex.getUnderlying().getFirst().isStatic() || !targetQName.equals(currentVertex.getUnderlying().getFirst().getOwner()))) {
            result.add(currentVertex.getUnderlying().getSecond());
        }
        if (result.size() > maxResultSize) {
            return result.getResult();
        }
    }
    return result.getResult();
}
Also used : ProgressManager(com.intellij.openapi.progress.ProgressManager) java.util(java.util) PsiMethod(com.intellij.psi.PsiMethod) MethodsUsageIndexReader(com.intellij.compiler.classFilesIndex.impl.MethodsUsageIndexReader) ContainerUtil(com.intellij.util.containers.ContainerUtil) UsageIndexValue(com.intellij.compiler.classFilesIndex.impl.UsageIndexValue) MethodIncompleteSignature(com.intellij.compiler.classFilesIndex.impl.MethodIncompleteSignature) PsiManager(com.intellij.psi.PsiManager) PsiModifier(com.intellij.psi.PsiModifier) Nullable(org.jetbrains.annotations.Nullable) PsiClass(com.intellij.psi.PsiClass) ChainCompletionContext(com.intellij.compiler.classFilesIndex.chainsSearch.context.ChainCompletionContext) TargetType(com.intellij.compiler.classFilesIndex.chainsSearch.context.TargetType) Function(com.intellij.util.Function) Pair(com.intellij.openapi.util.Pair) Logger(com.intellij.openapi.diagnostic.Logger) NotNull(org.jetbrains.annotations.NotNull) PsiMethod(com.intellij.psi.PsiMethod) UsageIndexValue(com.intellij.compiler.classFilesIndex.impl.UsageIndexValue) Pair(com.intellij.openapi.util.Pair) MethodIncompleteSignature(com.intellij.compiler.classFilesIndex.impl.MethodIncompleteSignature) NotNull(org.jetbrains.annotations.NotNull)

Example 2 with ChainCompletionContext

use of com.intellij.compiler.classFilesIndex.chainsSearch.context.ChainCompletionContext in project intellij-community by JetBrains.

the class MethodsChainsCompletionContributor method searchForLookups.

private static List<LookupElement> searchForLookups(final TargetType target, final Set<String> contextRelevantTypes, final ChainCompletionContext completionContext) {
    final Project project = completionContext.getProject();
    final MethodsUsageIndexReader methodsUsageIndexReader = MethodsUsageIndexReader.getInstance(project);
    final List<MethodsChain> searchResult = searchChains(target, contextRelevantTypes, MAX_SEARCH_RESULT_SIZE, MAX_CHAIN_SIZE, completionContext, methodsUsageIndexReader);
    if (searchResult.size() < MAX_SEARCH_RESULT_SIZE) {
        if (!target.isArray()) {
            final List<MethodsChain> inheritorFilteredSearchResult = new SmartList<>();
            final Processor<TargetType> consumer = targetType -> {
                for (final MethodsChain chain : searchChains(targetType, contextRelevantTypes, MAX_SEARCH_RESULT_SIZE, MAX_CHAIN_SIZE, completionContext, methodsUsageIndexReader)) {
                    boolean insert = true;
                    for (final MethodsChain baseChain : searchResult) {
                        final MethodsChain.CompareResult r = MethodsChain.compare(baseChain, chain, completionContext.getPsiManager());
                        if (r != MethodsChain.CompareResult.NOT_EQUAL) {
                            insert = false;
                            break;
                        }
                    }
                    if (insert) {
                        inheritorFilteredSearchResult.add(chain);
                    }
                }
                searchResult.addAll(inheritorFilteredSearchResult);
                return searchResult.size() < MAX_SEARCH_RESULT_SIZE;
            };
            DirectClassInheritorsSearch.search(((PsiClassType) target.getPsiType()).resolve()).forEach(psiClass -> {
                final String inheritorQName = psiClass.getQualifiedName();
                if (inheritorQName == null) {
                    return true;
                }
                return consumer.process(new TargetType(inheritorQName, false, new PsiImmediateClassType(psiClass, PsiSubstitutor.EMPTY)));
            });
        }
    }
    final List<MethodsChain> chains = searchResult.size() > MAX_CHAIN_SIZE ? chooseHead(searchResult) : searchResult;
    return MethodsChainLookupRangingHelper.chainsToWeightableLookupElements(filterTailAndGetSumLastMethodOccurrence(chains), completionContext);
}
Also used : PsiImmediateClassType(com.intellij.psi.impl.source.PsiImmediateClassType) java.util(java.util) ModuleUtilCore(com.intellij.openapi.module.ModuleUtilCore) LookupElement(com.intellij.codeInsight.lookup.LookupElement) com.intellij.compiler.classFilesIndex.chainsSearch(com.intellij.compiler.classFilesIndex.chainsSearch) MethodsUsageIndexReader(com.intellij.compiler.classFilesIndex.impl.MethodsUsageIndexReader) ElementPattern(com.intellij.patterns.ElementPattern) com.intellij.codeInsight.completion(com.intellij.codeInsight.completion) ClassFilesIndexFeaturesHolder(com.intellij.compiler.classFilesIndex.api.index.ClassFilesIndexFeaturesHolder) ContextUtil(com.intellij.compiler.classFilesIndex.chainsSearch.context.ContextUtil) Nullable(org.jetbrains.annotations.Nullable) PsiTreeUtil(com.intellij.psi.util.PsiTreeUtil) ChainCompletionContext(com.intellij.compiler.classFilesIndex.chainsSearch.context.ChainCompletionContext) TargetType(com.intellij.compiler.classFilesIndex.chainsSearch.context.TargetType) ApplicationManager(com.intellij.openapi.application.ApplicationManager) Project(com.intellij.openapi.project.Project) CompletionContributorPatternUtil(com.intellij.compiler.classFilesIndex.chainsSearch.completion.CompletionContributorPatternUtil) com.intellij.psi(com.intellij.psi) com.intellij.util(com.intellij.util) NotNull(org.jetbrains.annotations.NotNull) DirectClassInheritorsSearch(com.intellij.psi.search.searches.DirectClassInheritorsSearch) ClassFilesIndexFeature(com.intellij.compiler.classFilesIndex.api.index.ClassFilesIndexFeature) PsiJavaPatterns.or(com.intellij.patterns.PsiJavaPatterns.or) Project(com.intellij.openapi.project.Project) PsiImmediateClassType(com.intellij.psi.impl.source.PsiImmediateClassType) TargetType(com.intellij.compiler.classFilesIndex.chainsSearch.context.TargetType) MethodsUsageIndexReader(com.intellij.compiler.classFilesIndex.impl.MethodsUsageIndexReader)

Aggregations

ChainCompletionContext (com.intellij.compiler.classFilesIndex.chainsSearch.context.ChainCompletionContext)2 TargetType (com.intellij.compiler.classFilesIndex.chainsSearch.context.TargetType)2 MethodsUsageIndexReader (com.intellij.compiler.classFilesIndex.impl.MethodsUsageIndexReader)2 java.util (java.util)2 NotNull (org.jetbrains.annotations.NotNull)2 Nullable (org.jetbrains.annotations.Nullable)2 com.intellij.codeInsight.completion (com.intellij.codeInsight.completion)1 LookupElement (com.intellij.codeInsight.lookup.LookupElement)1 ClassFilesIndexFeature (com.intellij.compiler.classFilesIndex.api.index.ClassFilesIndexFeature)1 ClassFilesIndexFeaturesHolder (com.intellij.compiler.classFilesIndex.api.index.ClassFilesIndexFeaturesHolder)1 com.intellij.compiler.classFilesIndex.chainsSearch (com.intellij.compiler.classFilesIndex.chainsSearch)1 CompletionContributorPatternUtil (com.intellij.compiler.classFilesIndex.chainsSearch.completion.CompletionContributorPatternUtil)1 ContextUtil (com.intellij.compiler.classFilesIndex.chainsSearch.context.ContextUtil)1 MethodIncompleteSignature (com.intellij.compiler.classFilesIndex.impl.MethodIncompleteSignature)1 UsageIndexValue (com.intellij.compiler.classFilesIndex.impl.UsageIndexValue)1 ApplicationManager (com.intellij.openapi.application.ApplicationManager)1 Logger (com.intellij.openapi.diagnostic.Logger)1 ModuleUtilCore (com.intellij.openapi.module.ModuleUtilCore)1 ProgressManager (com.intellij.openapi.progress.ProgressManager)1 Project (com.intellij.openapi.project.Project)1