List<OperationChain> (CompilerReferenceServiceEx referenceServiceEx, SearchInitializer initializer, int chainMaxLength, int maxResultSize, ChainCompletionContext context) { LinkedList<OperationChain> q = initializer.getChainQueue(); List<OperationChain> result = new ArrayList<>(); while (!q.isEmpty()) { OperationChain currentChain = q.poll(); ProgressManager.checkCanceled(); RefChainOperation head = currentChain.getHead(); if (addChainIfTerminal(currentChain, result, chainMaxLength, context)) continue; // otherwise try to find chain continuation boolean updated = false; SortedSet<ChainOpAndOccurrences<MethodCall>> candidates = referenceServiceEx.findMethodReferenceOccurrences(head.getQualifierRawName(), SignatureData.ZERO_DIM, context); CompilerRef ref = head.getCompilerRef(); for (ChainOpAndOccurrences<MethodCall> candidate : candidates) { if (candidate.getOccurrenceCount() * ChainSearchMagicConstants.FILTER_RATIO < currentChain.getChainWeight()) { break; } MethodCall sign = candidate.getOperation(); if ((sign.isStatic() || !sign.getQualifierRawName().equals(context.getTarget().getClassQName())) && (!(ref instanceof CompilerRef.JavaCompilerMethodRef) || referenceServiceEx.mayHappen(candidate.getOperation().getCompilerRef(), ref, ChainSearchMagicConstants.METHOD_PROBABILITY_THRESHOLD))) { OperationChain continuation = currentChain.continuationWithMethod(candidate.getOperation(), candidate.getOccurrenceCount(), context); if (continuation != null) { boolean stopChain = candidate.getOperation().isStatic() || context.hasQualifier(context.resolvePsiClass(candidate.getOperation().getQualifierDef())); if (stopChain) { addChainIfNotPresent(continuation, result); } else { q.addFirst(continuation); } updated = true; } } } if (ref instanceof CompilerRef.JavaCompilerMethodRef) { CompilerRef.CompilerClassHierarchyElementDef def = referenceServiceEx.mayCallOfTypeCast((CompilerRef.JavaCompilerMethodRef)ref, ChainSearchMagicConstants.METHOD_PROBABILITY_THRESHOLD); if (def != null) { OperationChain continuation = currentChain.continuationWithCast(new TypeCast(def, head.getQualifierDef(), referenceServiceEx), context); if (continuation != null) { q.addFirst(continuation); updated = true; } } } if (!updated) { addChainIfQualifierCanBeOccurredInContext(currentChain, result, context, referenceServiceEx); } if (result.size() > maxResultSize) { return result; } } return result; }