Skip to content
← Back

src/analysis/diagnostics_collector.ghul

1
namespace Analysis is
2
use Collections.SET;
3
use Collections.LIST;
4
5
// Drains the analyser's diagnostics store into the given lists. Rather
6
// than re-implement the store's cascade-filtering, severity remapping
7
// and exclusive-end-column conventions, this renders diagnostics through
8
// the existing TAB_DELIMITED_DIAGNOSTIC_FORMATTER into an in-memory
9
// buffer and parses the rows back into typed DTOs. The tab rendering
10
// never reaches the wire — it is a faithful internal translation, so
11
// the JSON the client sees carries exactly the numbers the text
12
// protocol used to.
13
//
14
// An 8-field row is one diagnostic (field 8 is the suppressable code, empty
15
// when the diagnostic was raised without one); a bare 1-field row is the
16
// store's "this file was checked and is clean" signal. Either way the path
17
// joins `checked_paths`, which the client uses to clear stale squiggles.
18
// The lists are mutated rather than returned because every handler
19
// ultimately assembles a Response.DIAGNOSTICS variant at the write site,
20
// where it also has the per-handler phase / elapsed_ms / compile_needed
21
// values to pass to the constructor.
22
class DIAGNOSTICS_COLLECTOR is
23
collect_into(
24
logger: Logging.Logger,
25
diagnostics: LIST[Protocol.DIAGNOSTIC],
26
checked_paths: LIST[string]
27
) static is
28
let buffer = IO.StringWriter();
29
30
logger.write_all_diagnostics(buffer, Logging.TAB_DELIMITED_DIAGNOSTIC_FORMATTER());
31
32
let checked = SET[string]();
33
34
for line in buffer.to_string().split(['\n']) do
35
if line.length == 0 then
36
continue;
37
fi
38
39
let fields = line.split(['\t']);
40
41
if fields.count == 1 then
42
checked.add(fields[0]);
43
elif fields.count == 8 then
44
let path = fields[0];
45
let code: string = if fields[7].length > 0 then fields[7]; else ""; fi;
46
47
checked.add(path);
48
49
diagnostics.add(
50
Protocol.DIAGNOSTIC(
51
path,
52
System.Convert.to_int32(fields[1]),
53
System.Convert.to_int32(fields[2]),
54
System.Convert.to_int32(fields[3]),
55
System.Convert.to_int32(fields[4]),
56
System.Convert.to_int32(fields[5]),
57
fields[6],
58
code
59
)
60
);
61
fi
62
od
63
64
for path in checked do
65
checked_paths.add(path);
66
od
67
si
68
si
69
si