-
-
Notifications
You must be signed in to change notification settings - Fork 122
/
trace.ts
54 lines (46 loc) · 1.87 KB
/
trace.ts
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
import { groupByField } from '@internal/common-utils';
import { TextDocument } from 'vscode-languageserver-textdocument';
import type * as Api from './api.js';
import type { DocumentValidationController } from './DocumentValidationController.mjs';
import { readTextDocument, stat } from './vfs/index.mjs';
export async function traceWord(
docValidationController: DocumentValidationController,
doc: TextDocument,
word: string,
): Promise<Api.TraceWordResult> {
const docVal = await docValidationController.getDocumentValidator(doc);
const trace = docVal.traceWord(word);
const byWord = groupByField(trace, 'word');
const traces = [...byWord.entries()].map(([word, traces]) => ({
word,
found: isFound(traces),
traces: traces.map((t) => ({ ...t, errors: errorsToString(t.errors) })),
}));
const splits = trace.splits || traces.map(({ word, found }) => ({ word, found }));
return { word, traces, splits };
}
export async function handleTraceRequest(
docValidationController: DocumentValidationController,
req: Api.TraceWordRequest,
getCachedDoc: (uri: string) => TextDocument | undefined,
): Promise<Api.TraceWordResult> {
const { word, uri } = req;
let doc = getCachedDoc(uri);
if (!doc) {
try {
const s = await stat(uri);
doc = s.isDirectory() ? TextDocument.create(uri, 'plaintext', 0, '') : await readTextDocument(uri);
} catch {
doc = undefined;
}
}
if (!doc) return { word, errors: 'Document Not Found.' };
return traceWord(docValidationController, doc, word);
}
function errorsToString(errors: Error[] | undefined): string | undefined {
if (!errors || !errors.length) return undefined;
return errors.map((e) => e.message).join('\n');
}
function isFound(traces: { found: boolean }[]): boolean {
return traces.some((t) => t.found);
}