/
DiagnosticsService.kt
58 lines (51 loc) · 2.32 KB
/
DiagnosticsService.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package org.jetbrains.bsp.bazel.server.diagnostics
import ch.epfl.scala.bsp4j.BuildTargetIdentifier
import ch.epfl.scala.bsp4j.PublishDiagnosticsParams
import ch.epfl.scala.bsp4j.TextDocumentIdentifier
import java.nio.file.Path
import java.util.Collections
/**
* @property hasAnyProblems keeps track of problems in given file so BSP reporter
* can publish diagnostics with an empty array, to clear up former diagnostics.
* see: https://youtrack.jetbrains.com/issue/BAZEL-376
*/
class DiagnosticsService(workspaceRoot: Path, private val hasAnyProblems: MutableMap<String, Set<TextDocumentIdentifier>>) {
private val parser = DiagnosticsParser()
private val mapper = DiagnosticBspMapper(workspaceRoot)
/* Warnings are reported before the target completed event, when everything is cleared. so we want to avoid removing them */
private val updatedInThisRun = mutableSetOf<PublishDiagnosticsParams>()
fun getBspState() = Collections.unmodifiableMap(hasAnyProblems)
fun extractDiagnostics(
bazelOutput: String,
targetLabel: String,
originId: String?,
diagnosticsFromProgress: Boolean
): List<PublishDiagnosticsParams> {
val parsedDiagnostics = parser.parse(bazelOutput, targetLabel, diagnosticsFromProgress)
val events = mapper.createDiagnostics(parsedDiagnostics, originId)
if (diagnosticsFromProgress) updatedInThisRun.addAll(events)
updateProblemState(events)
return events
}
fun clearFormerDiagnostics(targetLabel: String): List<PublishDiagnosticsParams> {
val docs = hasAnyProblems[targetLabel]
hasAnyProblems.remove(targetLabel)
if (updatedInThisRun.isNotEmpty()) {
hasAnyProblems[targetLabel] = updatedInThisRun.map { it.textDocument }.toSet()
updatedInThisRun.clear()
}
return docs
?.map { PublishDiagnosticsParams(it, BuildTargetIdentifier(targetLabel), emptyList(), true)}
.orEmpty()
}
private fun updateProblemState(events: List<PublishDiagnosticsParams>) {
events
.groupBy { it.getBuildTarget().getUri() }
.forEach {
val buildTarget = it.key
val paramss = it.value
val docs = paramss.map { it.getTextDocument() }.toSet()
hasAnyProblems[buildTarget] = docs
}
}
}