-
-
Notifications
You must be signed in to change notification settings - Fork 371
/
references.ts
100 lines (72 loc) · 2.87 KB
/
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import * as vscode from 'vscode-languageserver-protocol';
import type { LanguageServiceRuntimeContext } from '../types';
import * as shared from '@volar/shared';
import { languageFeatureWorker } from '../utils/featureWorkers';
import * as dedupe from '../utils/dedupe';
import { TextDocument } from 'vscode-languageserver-textdocument';
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.Location[] = [];
await withTeleports(document, position);
return result;
async function withTeleports(document: TextDocument, position: vscode.Position) {
if (!plugin.findReferences)
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.findReferences(document, position) ?? [];
for (const reference of references) {
let foundTeleport = false;
if (sourceMap?.embeddedFile.lsType !== 'nonTs') {
recursiveChecker.add({ uri: reference.uri, range: { start: reference.range.start, end: reference.range.start } });
const teleport = context.vueDocuments.teleportfromEmbeddedDocumentUri(sourceMap?.embeddedFile.lsType ?? 'script', reference.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(reference => {
const referenceSourceMap = context.vueDocuments.sourceMapFromEmbeddedDocumentUri(sourceMap?.embeddedFile.lsType ?? 'script', reference.uri);
if (referenceSourceMap) {
const range = referenceSourceMap.getSourceRange(reference.range.start, reference.range.end)?.[0];
if (!range)
return;
reference.uri = referenceSourceMap.sourceDocument.uri;
reference.range = range;
}
return reference;
}).filter(shared.notEmpty),
arr => dedupe.withLocations(arr.flat()),
);
}
}