Skip to content
← Back

src/analysis/diagnostics_collector.ghul

1
namespace Analysis is
2
use Collections.LIST
3
use Collections.Iterable
4
5
use Ghul.Pipes
6
7
use Logging.DiagnosticSeverity
8
use Logging.DIAGNOSTIC_MESSAGE
9
10
// Drains the analyser's diagnostics store into the given lists,
11
// walking the store's retained DIAGNOSTIC_MESSAGE objects directly.
12
// Every path the logger currently has a (possibly empty) diagnostics
13
// list for joins `checked_paths`, which the client uses to clear
14
// stale squiggles for files that came back clean. The lists are
15
// mutated rather than returned because every handler ultimately
16
// assembles a Response.DIAGNOSTICS variant at the write site, where
17
// it also has the per-handler phase / elapsed_ms / compile_needed
18
// values to pass to the constructor.
19
class DIAGNOSTICS_COLLECTOR is
20
collect_into(
21
logger: Logging.Logger,
22
diagnostics: LIST[Protocol.DIAGNOSTIC],
23
checked_paths: LIST[string]
24
) static is
25
for path in logger.diagnostic_paths do
26
checked_paths.add(path)
27
28
for diagnostic in logger.diagnostics_for(path) do
29
let location = diagnostic.location
30
31
// A fatal/exception frame is downgraded to hint
32
// severity on the wire rather than surfaced as a
33
// blocking error.
34
let severity =
35
if diagnostic.is_fatal then
36
cast int(DiagnosticSeverity.HINT)
37
else
38
cast int(diagnostic.severity)
39
fi
40
41
let dto = Protocol.DIAGNOSTIC(
42
path,
43
location.start_line,
44
location.start_column,
45
location.end_line,
46
location.end_column + 1,
47
severity,
48
diagnostic.text.replace('\n', ' '),
49
diagnostic.code ?? ""
50
)
51
52
if let related_locations = diagnostic.related then
53
let related = LIST[Protocol.RELATED_LOCATION_DTO]()
54
55
for r in related_locations do
56
related.add(Protocol.RELATED_LOCATION_DTO(_location_dto(r.location), r.message))
57
od
58
59
dto.related = related
60
fi
61
62
diagnostics.add(dto)
63
od
64
od
65
si
66
67
// Same end-column-exclusive convention as the diagnostic's own
68
// range (see collect_into), so a related location composes with
69
// it under one coordinate system.
70
_location_dto(location: Source.LOCATION) -> Protocol.LOCATION_DTO static is
71
return Protocol.LOCATION_DTO(
72
location.file_name,
73
location.start_line,
74
location.start_column,
75
location.end_line,
76
location.end_column + 1
77
)
78
si
79
si
80
si