-
-
Notifications
You must be signed in to change notification settings - Fork 366
/
vue-codelens-references.ts
70 lines (52 loc) · 1.97 KB
/
vue-codelens-references.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
import { Service } from '@volar/language-service';
import { VueFile } from '@vue/language-core';
import type * as vscode from 'vscode-languageserver-protocol';
export default function (): Service {
return (context): ReturnType<Service> => {
if (!context)
return {};
return {
provideReferencesCodeLensRanges(document) {
return worker(document.uri, async () => {
const result: vscode.Range[] = [];
for (const [_, map] of context.documents.getMapsBySourceFileUri(document.uri)?.maps ?? []) {
for (const mapping of map.map.mappings) {
if (!mapping.data.referencesCodeLens)
continue;
result.push({
start: document.positionAt(mapping.sourceRange[0]),
end: document.positionAt(mapping.sourceRange[1]),
});
}
}
return result;
});
},
async resolveReferencesCodeLensLocations(document, range, references) {
await worker(document.uri, async (vueFile) => {
const document = context.documents.getDocumentByFileName(vueFile.snapshot, vueFile.fileName);
const offset = document.offsetAt(range.start);
const blocks = [
vueFile.sfc.script,
vueFile.sfc.scriptSetup,
vueFile.sfc.template,
...vueFile.sfc.styles,
...vueFile.sfc.customBlocks,
];
const sourceBlock = blocks.find(block => block && offset >= block.startTagEnd && offset <= block.endTagStart);
references = references.filter(reference =>
reference.uri !== document.uri // different file
|| sourceBlock !== blocks.find(block => block && document.offsetAt(reference.range.start) >= block.startTagEnd && document.offsetAt(reference.range.end) <= block.endTagStart) // different block
);
});
return references;
},
};
function worker<T>(uri: string, callback: (vueSourceFile: VueFile) => T) {
const [virtualFile] = context!.documents.getVirtualFileByUri(uri);
if (!(virtualFile instanceof VueFile))
return;
return callback(virtualFile);
}
};
}