in src/main/kotlin/org/arend/search/proof/ProofSearchUtils.kt [41:111]
fun generateProofSearchResults(
project: Project,
pattern: String,
): Sequence<ProofSearchEntry?> = sequence {
val settings = ProofSearchUISettings(project)
val query = (ProofSearchQuery.fromString(pattern) as? ParsingResult.OK<ProofSearchQuery>)?.value
?: return@sequence
val matcher = ArendExpressionMatcher(query)
val listedIdentifiers = query.getAllIdentifiers()
val keys = DumbService.getInstance(project).runReadActionInSmartMode(Computable {
StubIndex.getInstance().getAllKeys(ArendDefinitionIndex.KEY, project)
})
val searchScope = if (listedIdentifiers.isNotEmpty()) {
val scopes = collectSearchScopes(listedIdentifiers, GlobalSearchScope.allScope(project).isSearchInLibraries, project)
runReadAction {
scopes.map { GlobalSearchScope.fileScope(project, it) }.reduce(GlobalSearchScope::union)
}
} else {
GlobalSearchScope.allScope(project)
}
val concreteProvider = PsiConcreteProvider(project, DummyErrorReporter.INSTANCE, null)
var idleCounter = 0
for (definitionName in keys) {
val list = SmartList<ProofSearchEntry>()
runReadAction {
StubIndex.getInstance().processElements(
ArendDefinitionIndex.KEY,
definitionName,
project,
searchScope,
PsiReferable::class.java
) { def ->
if (!settings.checkAllowed(def)) return@processElements true
if (def !is ReferableBase<*>) return@processElements true
val (parameters, codomain, info) = getSignature(concreteProvider, def, query.shouldConsiderParameters())
?: return@processElements true
val (parameterResults, codomainResults) = matcher.match(parameters, codomain, def.scope, def) ?: return@processElements true
val parameterRangesRegistry = mutableMapOf<Int, List<TextRange>>()
val rangeComputer = caching { e : Concrete.Expression -> if (e is Concrete.ReferenceExpression && e.referent is ArendDefData) (e.referent as ArendDefData).nameIdentifier!!.textRange else rangeOfConcrete(e) }
for ((parameterConcrete, ranges) in parameterResults) {
val index = parameters.indexOf(parameterConcrete)
val existing = parameterRangesRegistry.getOrDefault(index, emptyList())
parameterRangesRegistry[index] = existing + ranges.map { rangeComputer(it).shiftLeft(rangeComputer(parameterConcrete).startOffset) }
}
val codomainRange = codomainResults.map { rangeComputer(it).shiftLeft(rangeComputer(codomain).startOffset) }
list.add(ProofSearchEntry(def,
info.value.copy(
parameters = info.value.parameters.mapIndexedNotNull { index, data -> data.takeIf { index in parameterRangesRegistry }?.copy(match = parameterRangesRegistry[index]!!) },
codomain = info.value.codomain.copy(match = codomainRange))))
true
}
}
if (list.isNotEmpty()) {
for (def in list) {
yield(def)
}
} else {
idleCounter += 1
if (idleCounter >= 50) {
idleCounter = 0
yield(null)
}
}
}
}