/
documentHighlights.ts
94 lines (70 loc) · 2.54 KB
/
documentHighlights.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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceRuntimeContext } from '../types';
import * as shared from '@volar/shared';
import { languageFeatureWorker } from '../utils/featureWorkers';
import { TextDocument } from 'vscode-languageserver-textdocument';
import * as dedupe from '../utils/dedupe';
export function register(context: LanguageServiceRuntimeContext) {
return (uri: string, position: vscode.Position) => {
return languageFeatureWorker(
context,
uri,
position,
function* (position, sourceMap) {
for (const [mappedRange] of sourceMap.getMappedRanges(
position,
position,
data => !!data.capabilities.references,
)) {
yield mappedRange.start;
}
},
async (plugin, document, position, sourceMap, vueDocument) => {
const recursiveChecker = dedupe.createLocationSet();
const result: vscode.DocumentHighlight[] = [];
await withTeleports(document, position);
return result;
async function withTeleports(document: TextDocument, position: vscode.Position) {
if (!plugin.findDocumentHighlights)
return;
if (recursiveChecker.has({ uri: document.uri, range: { start: position, end: position } }))
return;
recursiveChecker.add({ uri: document.uri, range: { start: position, end: position } });
const references = await plugin.findDocumentHighlights(document, position) ?? [];
for (const reference of references) {
let foundTeleport = false;
recursiveChecker.add({ uri: document.uri, range: { start: reference.range.start, end: reference.range.start } });
const teleport = context.vueDocuments.teleportfromEmbeddedDocumentUri(document.uri);
if (teleport) {
for (const [teleRange] of teleport.findTeleports(
reference.range.start,
reference.range.end,
sideData => !!sideData.capabilities.references,
)) {
if (recursiveChecker.has({ uri: teleport.document.uri, range: { start: teleRange.start, end: teleRange.start } }))
continue;
foundTeleport = true;
await withTeleports(teleport.document, teleRange.start);
}
}
if (!foundTeleport) {
result.push(reference);
}
}
}
},
(data, sourceMap) => data.map(highlisht => {
if (!sourceMap)
return highlisht;
const range = sourceMap.getSourceRange(highlisht.range.start, highlisht.range.end)?.[0];
if (range) {
return {
...highlisht,
range,
};
}
}).filter(shared.notEmpty),
arr => arr.flat(),
);
};
}