|
| 1 | +import { locate } from "../../../../tools/locate/index.mjs" |
| 2 | + |
1 | 3 | import { formatCommand } from "./commands.mjs" |
2 | 4 |
|
3 | 5 | /** |
4 | 6 | * Turn one FTS `Diagnostic` (see src/diagnostics.ts: `{ code, message, |
5 | 7 | * severity, path?, span? }`) into a GitHub workflow-command annotation line. |
6 | 8 | * |
7 | | - * Two different notions of "path" collide here and must be told apart: |
| 9 | + * Where the diagnostic belongs is not decided here: `tools/locate` decides it, |
| 10 | + * the same module the language server uses, so an annotation on a pull request |
| 11 | + * and a squiggle in the editor land on the same character. This function only |
| 12 | + * formats what it is given. |
| 13 | + * |
| 14 | + * `spot` is the result of `locate(...)` — `{ line, column, endLine, endColumn }` |
| 15 | + * or `null`. The default resolves what can be resolved without the document |
| 16 | + * text (that is: a `span`, and nothing else), which is what a caller that has |
| 17 | + * only the diagnostic in hand can honestly offer. |
8 | 18 | * |
9 | | - * - `file` (this function's second argument) is a real filesystem path, |
10 | | - * supplied by the caller, that GitHub can point an annotation at. |
11 | | - * - `diagnostic.path`, when core `fts` produces it, is a JSON-pointer-style |
12 | | - * locator *inside the document* (e.g. "$.utilities[0].examples[1].expected"), |
13 | | - * not a filesystem path — the parser's own diagnostics use `span` for real |
14 | | - * source coordinates, and only the *validator* (which only ever sees an |
15 | | - * already-parsed document, not source text) falls back to a JSON pointer. |
16 | | - * ftsc/ftspec diagnostics, by contrast, put a real module file path in |
17 | | - * `diagnostic.path` — the caller resolves that distinction before calling |
18 | | - * us and passes the result through as `file`. |
| 19 | + * Two different notions of "path" collide in `diagnostic.path` and must be told |
| 20 | + * apart — a JSON pointer into the document (core `fts`) versus a real file path |
| 21 | + * (`ftsc`/`ftspec`). `locate` makes that distinction; see its `classifyPath`. |
| 22 | + * The `file` argument here is always a real filesystem path, resolved by the |
| 23 | + * caller, that GitHub can point an annotation at. |
19 | 24 | * |
20 | | - * When there is no `span`, the annotation is pinned to line 1 of `file` (per |
21 | | - * spec) and `diagnostic.path`, if present, is folded into the message text so |
22 | | - * the location information is not silently dropped. |
| 25 | + * When nothing located the diagnostic, the annotation is pinned to line 1 of |
| 26 | + * `file` (per spec) and `diagnostic.path`, if present, is folded into the |
| 27 | + * message text so the location information is not silently dropped. |
23 | 28 | */ |
24 | | -export function diagnosticToAnnotation(diagnostic, file) { |
| 29 | +export function diagnosticToAnnotation(diagnostic, file, spot = locate(diagnostic, null, { fallback: "none" })) { |
25 | 30 | const severity = diagnostic.severity === "warning" ? "warning" : "error" |
26 | 31 | const properties = {} |
27 | 32 | if (file !== undefined) properties.file = file |
28 | 33 |
|
29 | | - const span = diagnostic.span |
30 | | - if (span) { |
31 | | - properties.line = span.start.line |
32 | | - properties.col = span.start.column |
33 | | - if (span.end.line !== span.start.line) properties.endLine = span.end.line |
34 | | - if (span.end.line !== span.start.line || span.end.column !== span.start.column) { |
35 | | - properties.endColumn = span.end.column |
36 | | - } |
| 34 | + if (spot) { |
| 35 | + properties.line = spot.line |
| 36 | + properties.col = spot.column |
| 37 | + if (spot.endLine !== spot.line) properties.endLine = spot.endLine |
| 38 | + if (spot.endLine !== spot.line || spot.endColumn !== spot.column) properties.endColumn = spot.endColumn |
37 | 39 | } else if (file !== undefined) { |
38 | 40 | properties.line = 1 |
39 | 41 | properties.col = 1 |
40 | 42 | } |
41 | 43 | if (diagnostic.code) properties.title = diagnostic.code |
42 | 44 |
|
43 | | - const message = span || !diagnostic.path ? diagnostic.message : `${diagnostic.message} (${diagnostic.path})` |
| 45 | + const message = spot || !diagnostic.path ? diagnostic.message : `${diagnostic.message} (${diagnostic.path})` |
44 | 46 |
|
45 | 47 | return formatCommand(severity, properties, message) |
46 | 48 | } |
0 commit comments