Skip to content

Commit 944b991

Browse files
committed
fix: references project finding logic incorrect
close #649
1 parent 6eaf333 commit 944b991

File tree

7 files changed

+465
-391
lines changed

7 files changed

+465
-391
lines changed

packages/server/src/features/customFeatures.ts

Lines changed: 49 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,37 +10,39 @@ export function register(
1010
documents: vscode.TextDocuments<TextDocument>,
1111
getProjects: () => Projects | undefined,
1212
) {
13-
connection.onRequest(shared.GetRefCompleteEditsRequest.type, handler => {
13+
connection.onRequest(shared.GetRefCompleteEditsRequest.type, async handler => {
1414
const document = documents.get(handler.textDocument.uri);
1515
if (!document) return;
16-
return getProjects()?.get(document.uri)?.service.__internal__.doRefAutoClose(document, handler.position);
16+
const languageService = await getLanguageService(document.uri);
17+
return languageService?.__internal__.doRefAutoClose(document, handler.position);
1718
});
1819
connection.onRequest(shared.D3Request.type, async handler => {
1920
const document = documents.get(handler.uri);
2021
if (!document) return;
21-
return await getProjects()?.get(document.uri)?.service.__internal__.getD3(document);
22+
const languageService = await getLanguageService(document.uri);
23+
return languageService?.__internal__.getD3(document);
2224
});
2325
connection.onRequest(shared.GetMatchTsConfigRequest.type, async handler => {
24-
const tsConfigs = getProjects()?.getTsConfigs(handler.uri);
25-
if (tsConfigs?.length) {
26-
return tsConfigs[0];
27-
}
26+
const projects = getProjects();
27+
return (await projects?.getProject(handler.uri))?.tsconfig;
2828
});
2929
connection.onNotification(shared.WriteVirtualFilesNotification.type, async ({ lsType }) => {
3030

3131
const projects = getProjects();
3232
if (!projects) return;
3333

34-
for (const [_, service] of projects.projects.size ? projects.projects : projects.inferredProjects) {
35-
const ls = service.getLanguageServiceDontCreate();
36-
if (!ls) continue;
37-
const localTypes = ls.__internal__.getLocalTypesFiles(lsType);
38-
for (const fileName of localTypes.fileNames) {
39-
fs.writeFile(fileName, localTypes.code, () => { });
40-
}
41-
const { sourceFiles } = await ls.__internal__.getContext();
42-
for (const [_, doc] of sourceFiles.getTsDocuments(lsType)) {
43-
fs.writeFile(shared.uriToFsPath(doc.uri), doc.getText(), () => { });
34+
for (const workspace of projects.workspaces.values()) {
35+
for (const project of workspace.projects.values()) {
36+
const ls = await (await project).getLanguageServiceDontCreate();
37+
if (!ls) continue;
38+
const localTypes = ls.__internal__.getLocalTypesFiles(lsType);
39+
for (const fileName of localTypes.fileNames) {
40+
fs.writeFile(fileName, localTypes.code, () => { });
41+
}
42+
const { sourceFiles } = await ls.__internal__.getContext();
43+
for (const [_, doc] of sourceFiles.getTsDocuments(lsType)) {
44+
fs.writeFile(shared.uriToFsPath(doc.uri), doc.getText(), () => { });
45+
}
4446
}
4547
}
4648
});
@@ -54,31 +56,42 @@ export function register(
5456

5557
const progress = await connection.window.createWorkDoneProgress();
5658
progress.begin('Verify', 0, '', true);
57-
for (const [_, service] of projects.projects.size ? projects.projects : projects.inferredProjects) {
58-
const ls = service.getLanguageServiceDontCreate();
59-
if (!ls) continue;
60-
const { sourceFiles } = await ls.__internal__.getContext();
61-
const allFiles = sourceFiles.getAll();
62-
let i = 0;
63-
for (const sourceFile of allFiles) {
64-
progress.report(i++ / allFiles.length * 100, path.relative(ls.__internal__.rootPath, shared.uriToFsPath(sourceFile.uri)));
65-
if (progress.token.isCancellationRequested) {
66-
continue;
59+
60+
for (const workspace of projects.workspaces.values()) {
61+
for (const project of workspace.projects.values()) {
62+
const ls = await (await project).getLanguageServiceDontCreate();
63+
if (!ls) continue;
64+
const { sourceFiles } = await ls.__internal__.getContext();
65+
const allFiles = sourceFiles.getAll();
66+
let i = 0;
67+
for (const sourceFile of allFiles) {
68+
progress.report(i++ / allFiles.length * 100, path.relative(ls.__internal__.rootPath, shared.uriToFsPath(sourceFile.uri)));
69+
if (progress.token.isCancellationRequested) {
70+
continue;
71+
}
72+
let _result: vscode.Diagnostic[] = [];
73+
await ls.doValidation(sourceFile.uri, result => {
74+
connection.sendDiagnostics({ uri: sourceFile.uri, diagnostics: result });
75+
_result = result;
76+
});
77+
errors += _result.filter(error => error.severity === vscode.DiagnosticSeverity.Error).length;
78+
warnings += _result.filter(error => error.severity === vscode.DiagnosticSeverity.Warning).length;
6779
}
68-
let _result: vscode.Diagnostic[] = [];
69-
await ls.doValidation(sourceFile.uri, result => {
70-
connection.sendDiagnostics({ uri: sourceFile.uri, diagnostics: result });
71-
_result = result;
72-
});
73-
errors += _result.filter(error => error.severity === vscode.DiagnosticSeverity.Error).length;
74-
warnings += _result.filter(error => error.severity === vscode.DiagnosticSeverity.Warning).length;
7580
}
7681
}
82+
7783
progress.done();
7884

7985
connection.window.showInformationMessage(`Verification complete. Found ${errors} errors and ${warnings} warnings.`);
8086
});
81-
connection.onRequest(shared.DetectDocumentNameCasesRequest.type, handler => {
82-
return getProjects()?.get(handler.uri)?.service.__internal__.detectTagNameCase(handler.uri);
87+
connection.onRequest(shared.DetectDocumentNameCasesRequest.type, async handler => {
88+
const languageService = await getLanguageService(handler.uri);
89+
return languageService?.__internal__.detectTagNameCase(handler.uri);
8390
});
91+
92+
async function getLanguageService(uri: string) {
93+
const projects = await getProjects();
94+
const project = (await projects?.getProject(uri))?.project;
95+
return project?.getLanguageService();
96+
}
8497
}

packages/server/src/features/languageFeatures.ts

Lines changed: 87 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,22 @@ export function register(
1818
params: vscode.InitializeParams,
1919
) {
2020
connection.onCompletion(async handler => {
21-
const list = await getProjects()
22-
?.get(handler.textDocument.uri)?.service
23-
.doComplete(
24-
handler.textDocument.uri,
25-
handler.position,
26-
handler.context,
27-
async () => await configuration?.getConfiguration('volar.completion.autoImportComponent') ?? true,
28-
async (uri) => {
29-
if (features.completion?.getDocumentNameCasesRequest) {
30-
return await connection.sendRequest(shared.GetDocumentNameCasesRequest.type, { uri });
31-
}
32-
return {
33-
tagNameCase: features.completion!.defaultTagNameCase,
34-
attrNameCase: features.completion!.defaultAttrNameCase,
35-
};
36-
},
37-
);
21+
const languageService = await getLanguageService(handler.textDocument.uri);
22+
const list = await languageService?.doComplete(
23+
handler.textDocument.uri,
24+
handler.position,
25+
handler.context,
26+
async () => await configuration?.getConfiguration('volar.completion.autoImportComponent') ?? true,
27+
async (uri) => {
28+
if (features.completion?.getDocumentNameCasesRequest) {
29+
return await connection.sendRequest(shared.GetDocumentNameCasesRequest.type, { uri });
30+
}
31+
return {
32+
tagNameCase: features.completion!.defaultTagNameCase,
33+
attrNameCase: features.completion!.defaultAttrNameCase,
34+
};
35+
},
36+
);
3837
const insertReplaceSupport = params.capabilities.textDocument?.completion?.completionItem?.insertReplaceSupport ?? false;
3938
if (!insertReplaceSupport && list) {
4039
for (const item of list.items) {
@@ -52,50 +51,44 @@ export function register(
5251
? await connection.sendRequest(shared.GetEditorSelectionRequest.type)
5352
: undefined;
5453
const newPosition = activeSel?.textDocument.uri.toLowerCase() === uri.toLowerCase() ? activeSel.position : undefined;
55-
return getProjects()?.get(uri)?.service.doCompletionResolve(item, newPosition) ?? item;
54+
const languageService = await getLanguageService(uri);
55+
return languageService?.doCompletionResolve(item, newPosition) ?? item;
5656
});
5757
connection.onHover(async handler => {
58-
return await getProjects()
59-
?.get(handler.textDocument.uri)?.service
60-
.doHover(handler.textDocument.uri, handler.position);
58+
const languageService = await getLanguageService(handler.textDocument.uri);
59+
return languageService?.doHover(handler.textDocument.uri, handler.position);
6160
});
62-
connection.onSignatureHelp(handler => {
63-
return getProjects()
64-
?.get(handler.textDocument.uri)?.service
65-
.getSignatureHelp(handler.textDocument.uri, handler.position, handler.context);
61+
connection.onSignatureHelp(async handler => {
62+
const languageService = await getLanguageService(handler.textDocument.uri);
63+
return languageService?.getSignatureHelp(handler.textDocument.uri, handler.position, handler.context);
6664
});
67-
connection.onPrepareRename(handler => {
68-
return getProjects()
69-
?.get(handler.textDocument.uri)?.service
70-
.prepareRename(handler.textDocument.uri, handler.position);
65+
connection.onPrepareRename(async handler => {
66+
const languageService = await getLanguageService(handler.textDocument.uri);
67+
return languageService?.prepareRename(handler.textDocument.uri, handler.position);
7168
});
7269
connection.onRenameRequest(async handler => {
73-
return await getProjects()
74-
?.get(handler.textDocument.uri)?.service
75-
.doRename(handler.textDocument.uri, handler.position, handler.newName);
70+
const languageService = await getLanguageService(handler.textDocument.uri);
71+
return languageService?.doRename(handler.textDocument.uri, handler.position, handler.newName);
7672
});
7773
connection.onCodeLens(async handler => {
78-
return getProjects()
79-
?.get(handler.textDocument.uri)?.service
80-
.getCodeLens(handler.textDocument.uri, await lsConfigs?.getCodeLensConfigs());
74+
const languageService = await getLanguageService(handler.textDocument.uri);
75+
return languageService?.getCodeLens(handler.textDocument.uri, await lsConfigs?.getCodeLensConfigs());
8176
});
82-
connection.onCodeLensResolve(codeLens => {
77+
connection.onCodeLensResolve(async codeLens => {
8378
const uri = codeLens.data?.uri;
84-
return getProjects()
85-
?.get(uri)?.service
86-
.doCodeLensResolve(codeLens, typeof features.codeLens === 'object' && features.codeLens.showReferencesNotification) ?? codeLens;
79+
const languageService = await getLanguageService(uri);
80+
return languageService?.doCodeLensResolve(codeLens, typeof features.codeLens === 'object' && features.codeLens.showReferencesNotification) ?? codeLens;
8781
});
88-
connection.onExecuteCommand(handler => {
82+
connection.onExecuteCommand(async handler => {
8983
const uri = handler.arguments?.[0];
90-
return getProjects()
91-
?.get(uri)?.service
92-
.__internal__.executeCommand(uri, handler.command, handler.arguments, connection);
84+
const languageService = await getLanguageService(uri);
85+
languageService?.__internal__.executeCommand(uri, handler.command, handler.arguments, connection);
9386
});
9487
connection.onCodeAction(async handler => {
9588
const uri = handler.textDocument.uri;
96-
const project = getProjects()?.get(uri);
97-
if (project) {
98-
const codeActions = await project.service.getCodeActions(uri, handler.range, handler.context);
89+
const languageService = await getLanguageService(uri);
90+
if (languageService) {
91+
const codeActions = await languageService.getCodeActions(uri, handler.range, handler.context);
9992
for (const codeAction of codeActions) {
10093
if (codeAction.data && typeof codeAction.data === 'object') {
10194
(codeAction.data as any).uri = uri;
@@ -109,59 +102,60 @@ export function register(
109102
});
110103
connection.onCodeActionResolve(async codeAction => {
111104
const uri: string | undefined = (codeAction.data as any)?.uri;
112-
const project = uri ? getProjects()?.get(uri) : undefined;
113-
if (project) {
114-
return await project.service.doCodeActionResolve(codeAction);
105+
if (uri) {
106+
const languageService = await getLanguageService(uri);
107+
if (languageService) {
108+
return languageService.doCodeActionResolve(codeAction);
109+
}
115110
}
116111
return codeAction;
117112
});
118113
connection.onReferences(async handler => {
119-
return await getProjects()
120-
?.get(handler.textDocument.uri)?.service
121-
.findReferences(handler.textDocument.uri, handler.position);
114+
const languageService = await getLanguageService(handler.textDocument.uri);
115+
return languageService?.findReferences(handler.textDocument.uri, handler.position);
122116
});
123117
connection.onDefinition(async handler => {
124-
return await getProjects()
125-
?.get(handler.textDocument.uri)?.service
126-
.findDefinition(handler.textDocument.uri, handler.position);
118+
const languageService = await getLanguageService(handler.textDocument.uri);
119+
return languageService?.findDefinition(handler.textDocument.uri, handler.position);
127120
});
128-
connection.onTypeDefinition(handler => {
129-
return getProjects()
130-
?.get(handler.textDocument.uri)?.service
131-
.findTypeDefinition(handler.textDocument.uri, handler.position);
121+
connection.onTypeDefinition(async handler => {
122+
const languageService = await getLanguageService(handler.textDocument.uri);
123+
return languageService?.findTypeDefinition(handler.textDocument.uri, handler.position);
132124
});
133-
connection.onDocumentHighlight(handler => {
134-
return getProjects()
135-
?.get(handler.textDocument.uri)?.service
136-
.findDocumentHighlights(handler.textDocument.uri, handler.position);
125+
connection.onDocumentHighlight(async handler => {
126+
const languageService = await getLanguageService(handler.textDocument.uri);
127+
return languageService?.findDocumentHighlights(handler.textDocument.uri, handler.position);
137128
});
138129
connection.onDocumentLinks(async handler => {
139-
return await getProjects()
140-
?.get(handler.textDocument.uri)?.service
141-
.findDocumentLinks(handler.textDocument.uri);
130+
const languageService = await getLanguageService(handler.textDocument.uri);
131+
return languageService?.findDocumentLinks(handler.textDocument.uri);
142132
});
143133
connection.onWorkspaceSymbol(async (handler, token) => {
144134
const projects = getProjects();
145135
if (projects) {
146136

147-
const _projects = projects.projects.size ? projects.projects : projects.inferredProjects;
148137
let results: vscode.SymbolInformation[] = [];
149138

150-
for (const [_, project] of _projects) {
139+
for (const workspace of projects.workspaces.values()) {
140+
let projects = [...workspace.projects.values()];
141+
projects = projects.length ? projects : [workspace.getInferredProject()];
142+
for (const project of projects) {
151143

152-
if (token.isCancellationRequested)
153-
return;
144+
if (token.isCancellationRequested)
145+
return;
154146

155-
results = results.concat(await project.getLanguageService().findWorkspaceSymbols(handler.query));
147+
const languageService = await (await project).getLanguageService();
148+
149+
results = results.concat(await languageService.findWorkspaceSymbols(handler.query));
150+
}
156151
}
157152

158153
return results;
159154
}
160155
});
161156
connection.languages.callHierarchy.onPrepare(async handler => {
162-
const items = await getProjects()
163-
?.get(handler.textDocument.uri)?.service
164-
.callHierarchy.doPrepare(handler.textDocument.uri, handler.position);
157+
const languageService = await getLanguageService(handler.textDocument.uri);
158+
const items = await languageService?.callHierarchy.doPrepare(handler.textDocument.uri, handler.position);
165159
if (items) {
166160
for (const item of items) {
167161
if (typeof item.data !== 'object') item.data = {};
@@ -170,33 +164,29 @@ export function register(
170164
}
171165
return items?.length ? items : null;
172166
});
173-
connection.languages.callHierarchy.onIncomingCalls(handler => {
167+
connection.languages.callHierarchy.onIncomingCalls(async handler => {
174168
const data = handler.item.data as { __uri?: string } | undefined;
175169
const uri = data?.__uri ?? handler.item.uri;
176-
return getProjects()
177-
?.get(uri)?.service
178-
.callHierarchy.getIncomingCalls(handler.item) ?? [];
170+
const languageService = await getLanguageService(uri);
171+
return languageService?.callHierarchy.getIncomingCalls(handler.item) ?? [];
179172
});
180-
connection.languages.callHierarchy.onOutgoingCalls(handler => {
173+
connection.languages.callHierarchy.onOutgoingCalls(async handler => {
181174
const data = handler.item.data as { __uri?: string } | undefined;
182175
const uri = data?.__uri ?? handler.item.uri;
183-
return getProjects()
184-
?.get(uri)?.service
185-
.callHierarchy.getOutgoingCalls(handler.item) ?? [];
176+
const languageService = await getLanguageService(uri);
177+
return languageService?.callHierarchy.getOutgoingCalls(handler.item) ?? [];
186178
});
187179
connection.languages.semanticTokens.on(async (handler, token, _, resultProgress) => {
188-
const result = await getProjects()
189-
?.get(handler.textDocument.uri)?.service
190-
.getSemanticTokens(handler.textDocument.uri, undefined, token, resultProgress);
180+
const languageService = await getLanguageService(handler.textDocument.uri);
181+
const result = await languageService?.getSemanticTokens(handler.textDocument.uri, undefined, token, resultProgress);
191182
return {
192183
resultId: result?.resultId,
193184
data: result?.data ?? [],
194185
};
195186
});
196187
connection.languages.semanticTokens.onRange(async (handler, token, _, resultProgress) => {
197-
const result = await getProjects()
198-
?.get(handler.textDocument.uri)?.service
199-
.getSemanticTokens(handler.textDocument.uri, handler.range, token, resultProgress);
188+
const languageService = await getLanguageService(handler.textDocument.uri);
189+
const result = await languageService?.getSemanticTokens(handler.textDocument.uri, handler.range, token, resultProgress);
200190
return {
201191
resultId: result?.resultId,
202192
data: result?.data ?? [],
@@ -210,7 +200,7 @@ export function register(
210200
if (config === 'always') {
211201
const renaming = new Promise<void>(async resolve => {
212202
for (const file of handler.files) {
213-
const renameFileContent = getScriptText(ts, documents, shared.uriToFsPath(file.oldUri));
203+
const renameFileContent = getScriptText(documents, shared.uriToFsPath(file.oldUri), ts.sys);
214204
if (renameFileContent) {
215205
renameFileContentCache.set(file.oldUri, renameFileContent);
216206
}
@@ -250,7 +240,8 @@ export function register(
250240
async function worker() {
251241
const edits = (await Promise.all(handler.files
252242
.map(async file => {
253-
return await getProjects()?.get(file.oldUri)?.service.getEditsForFileRename(file.oldUri, file.newUri);
243+
const languageService = await getLanguageService(file.oldUri);
244+
return languageService?.getEditsForFileRename(file.oldUri, file.newUri);
254245
}))).filter(shared.notEmpty);
255246
if (edits.length) {
256247
const result = edits[0];
@@ -260,4 +251,10 @@ export function register(
260251
return null;
261252
}
262253
});
254+
255+
async function getLanguageService(uri: string) {
256+
const projects = await getProjects();
257+
const project = (await projects?.getProject(uri))?.project;
258+
return project?.getLanguageService();
259+
}
263260
}

0 commit comments

Comments
 (0)