Skip to content

Commit ff424d1

Browse files
authored
Support more things in VS Code cohosting (#8218)
2 parents 61265d9 + ba62755 commit ff424d1

17 files changed

+200
-72
lines changed

src/lsptoolshost/razor/htmlDocumentContentProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export class HtmlDocumentContentProvider implements vscode.TextDocumentContentPr
2828
if (!document) {
2929
// Document was removed from the document manager, meaning there's no more content for this
3030
// file. Report an empty document.
31-
this.logger.logVerbose(
31+
this.logger.logTrace(
3232
`Could not find document '${getUriPath(
3333
uri
3434
)}' when updating the HTML buffer. This typically happens when a document is removed.`

src/lsptoolshost/razor/htmlDocumentManager.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,13 @@ export class HtmlDocumentManager {
2727
const didCloseRegistration = vscode.workspace.onDidCloseTextDocument(async (document) => {
2828
// We log when a virtual document is closed just in case it helps track down future bugs
2929
if (document.uri.scheme === HtmlDocumentContentProvider.scheme) {
30-
this.logger.logVerbose(`Virtual document '${document.uri}' timed out.`);
30+
this.logger.logTrace(`Virtual document '${document.uri}' timed out.`);
3131
return;
3232
}
3333

3434
// When a Razor document is closed, only then can we be sure its okay to remove the virtual document.
3535
if (document.languageId === 'aspnetcorerazor') {
36-
this.logger.logVerbose(`Document '${document.uri}' was closed.`);
36+
this.logger.logTrace(`Document '${document.uri}' was closed.`);
3737

3838
await this.closeDocument(document.uri);
3939

@@ -52,7 +52,7 @@ export class HtmlDocumentManager {
5252
public async updateDocumentText(uri: vscode.Uri, text: string) {
5353
const document = await this.getDocument(uri);
5454

55-
this.logger.logVerbose(`New content for '${uri}', updating '${document.path}'.`);
55+
this.logger.logTrace(`New content for '${uri}', updating '${document.path}'.`);
5656

5757
document.setContent(text);
5858

@@ -63,7 +63,7 @@ export class HtmlDocumentManager {
6363
const document = await this.findDocument(uri);
6464

6565
if (document) {
66-
this.logger.logVerbose(`Removing '${document.uri}' from the document manager.`);
66+
this.logger.logTrace(`Removing '${document.uri}' from the document manager.`);
6767

6868
delete this.htmlDocuments[document.path];
6969
}
@@ -74,7 +74,7 @@ export class HtmlDocumentManager {
7474

7575
// This might happen in the case that a file is opened outside the workspace
7676
if (!document) {
77-
this.logger.logMessage(
77+
this.logger.logInfo(
7878
`File '${uri}' didn't exist in the Razor document list. This is likely because it's from outside the workspace.`
7979
);
8080
document = this.addDocument(uri);
@@ -88,7 +88,7 @@ export class HtmlDocumentManager {
8888
private addDocument(uri: vscode.Uri): HtmlDocument {
8989
let document = this.findDocument(uri);
9090
if (document) {
91-
this.logger.logMessage(`Skipping document creation for '${document.path}' because it already exists.`);
91+
this.logger.logInfo(`Skipping document creation for '${document.path}' because it already exists.`);
9292
return document;
9393
}
9494

src/lsptoolshost/razor/razorEndpoints.ts

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,29 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { RoslynLanguageServer } from '../server/roslynLanguageServer';
76
import * as vscode from 'vscode';
7+
import { RoslynLanguageServer } from '../server/roslynLanguageServer';
88
import {
99
ColorInformation,
1010
ColorPresentationParams,
1111
ColorPresentationRequest,
12+
CompletionList,
13+
CompletionParams,
14+
CompletionRequest,
1215
DocumentColorParams,
1316
DocumentColorRequest,
17+
DocumentHighlight,
18+
DocumentHighlightKind,
19+
DocumentHighlightParams,
20+
DocumentHighlightRequest,
21+
FoldingRange,
22+
FoldingRangeParams,
23+
FoldingRangeRequest,
24+
Hover,
25+
HoverParams,
26+
HoverRequest,
1427
LogMessageParams,
28+
MarkupKind,
1529
NotificationType,
1630
RequestType,
1731
} from 'vscode-languageclient';
@@ -24,6 +38,9 @@ import { DocumentColorHandler } from '../../razor/src/documentColor/documentColo
2438
import { razorOptions } from '../../shared/options';
2539
import { ColorPresentationHandler } from '../../razor/src/colorPresentation/colorPresentationHandler';
2640
import { ColorPresentation } from 'vscode-html-languageservice';
41+
import { convertRangeToSerializable } from '../../razor/src/rpc/serializableRange';
42+
import { FoldingRangeHandler } from '../../razor/src/folding/foldingRangeHandler';
43+
import { CompletionHandler } from '../../razor/src/completion/completionHandler';
2744
import { DynamicFileInfoHandler } from '../../razor/src/dynamicFile/dynamicFileInfoHandler';
2845
import { ProvideDynamicFileParams } from '../../razor/src/dynamicFile/provideDynamicFileParams';
2946
import { ProvideDynamicFileResponse } from '../../razor/src/dynamicFile/provideDynamicFileResponse';
@@ -80,6 +97,59 @@ export function registerRazorEndpoints(
8097
return await ColorPresentationHandler.doColorPresentationRequest(document.uri, params);
8198
}
8299
);
100+
101+
registerRequestHandler<FoldingRangeParams, FoldingRange[]>(FoldingRangeRequest.method, async (params) => {
102+
const uri = UriConverter.deserialize(params.textDocument.uri);
103+
const document = await documentManager.getDocument(uri);
104+
105+
const results = await vscode.commands.executeCommand<vscode.FoldingRange[]>(
106+
'vscode.executeFoldingRangeProvider',
107+
document.uri
108+
);
109+
110+
return FoldingRangeHandler.convertFoldingRanges(results, razorLogger);
111+
});
112+
113+
registerRequestHandler<HoverParams, Hover | undefined>(HoverRequest.method, async (params) => {
114+
const uri = UriConverter.deserialize(params.textDocument.uri);
115+
const document = await documentManager.getDocument(uri);
116+
117+
const results = await vscode.commands.executeCommand<vscode.Hover[]>(
118+
'vscode.executeHoverProvider',
119+
document.uri,
120+
params.position
121+
);
122+
const applicableHover = results.filter((item) => item.range)[0];
123+
124+
return rewriteHover(applicableHover);
125+
});
126+
127+
registerRequestHandler<DocumentHighlightParams, DocumentHighlight[]>(
128+
DocumentHighlightRequest.method,
129+
async (params) => {
130+
const uri = UriConverter.deserialize(params.textDocument.uri);
131+
const document = await documentManager.getDocument(uri);
132+
133+
const results = await vscode.commands.executeCommand<vscode.DocumentHighlight[]>(
134+
'vscode.executeDocumentHighlights',
135+
document.uri,
136+
params.position
137+
);
138+
139+
return rewriteHighlight(results);
140+
}
141+
);
142+
143+
registerRequestHandler<CompletionParams, CompletionList>(CompletionRequest.method, async (params) => {
144+
const uri = UriConverter.deserialize(params.textDocument.uri);
145+
const document = await documentManager.getDocument(uri);
146+
147+
return CompletionHandler.provideVscodeCompletions(
148+
document.uri,
149+
params.position,
150+
params.context?.triggerCharacter
151+
);
152+
});
83153
}
84154

85155
function registerNonCohostingEndpoints() {
@@ -121,3 +191,47 @@ export function registerRazorEndpoints(
121191
});
122192
}
123193
}
194+
195+
function rewriteHover(hover: vscode.Hover): Hover | undefined {
196+
if (!hover) {
197+
return undefined;
198+
}
199+
200+
const markdownString = new vscode.MarkdownString();
201+
for (const content of hover.contents) {
202+
if ((content as { language: string; value: string }).language) {
203+
const contentObject = content as { language: string; value: string };
204+
markdownString.appendCodeblock(contentObject.value, contentObject.language);
205+
} else {
206+
const contentValue = (content as vscode.MarkdownString).value;
207+
markdownString.appendMarkdown(contentValue);
208+
}
209+
}
210+
211+
return {
212+
contents: { kind: MarkupKind.Markdown, value: markdownString.value },
213+
range: hover.range ? convertRangeToSerializable(hover.range) : undefined,
214+
};
215+
}
216+
217+
function rewriteHighlight(highlights: vscode.DocumentHighlight[]): DocumentHighlight[] {
218+
return highlights.map((highlight) => {
219+
return {
220+
range: convertRangeToSerializable(highlight.range),
221+
kind: convertHighlightKind(highlight.kind),
222+
};
223+
});
224+
}
225+
226+
function convertHighlightKind(kind: vscode.DocumentHighlightKind | undefined): DocumentHighlightKind | undefined {
227+
switch (kind) {
228+
case vscode.DocumentHighlightKind.Text:
229+
return DocumentHighlightKind.Text;
230+
case vscode.DocumentHighlightKind.Read:
231+
return DocumentHighlightKind.Read;
232+
case vscode.DocumentHighlightKind.Write:
233+
return DocumentHighlightKind.Write;
234+
default:
235+
return undefined;
236+
}
237+
}

src/razor/src/blazorDebug/terminateDebugHandler.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const killProcess = (targetPid: number | undefined, logger: RazorLogger) => {
2121
}
2222

2323
try {
24-
logger.logVerbose(`[DEBUGGER] Terminating debugging session with PID ${targetPid}...`);
24+
logger.logTrace(`[DEBUGGER] Terminating debugging session with PID ${targetPid}...`);
2525
process.kill(targetPid);
2626
} catch (error) {
2727
logger.logError(`[DEBUGGER] Error terminating debug processes with PID ${targetPid}: `, error as Error);

src/razor/src/completion/completionHandler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export class CompletionHandler {
137137
}
138138

139139
// HTML completion - provided via vscode command
140-
return this.provideVscodeCompletions(
140+
return CompletionHandler.provideVscodeCompletions(
141141
virtualDocument.uri,
142142
delegatedCompletionParams.projectedPosition,
143143
modifiedTriggerCharacter
@@ -372,7 +372,7 @@ export class CompletionHandler {
372372

373373
// Provide completions using standard vscode executeCompletionItemProvider command
374374
// Used in HTML context
375-
private async provideVscodeCompletions(
375+
public static async provideVscodeCompletions(
376376
virtualDocumentUri: vscode.Uri,
377377
projectedPosition: Position,
378378
triggerCharacter: string | undefined

src/razor/src/csharp/csharpProjectedDocumentContentProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ export class CSharpProjectedDocumentContentProvider implements vscode.TextDocume
3535
// Document was removed from the document manager, meaning there's no more content for this
3636
// file. Report an empty document.
3737

38-
if (this.logger.verboseEnabled) {
39-
this.logger.logVerbose(
38+
if (this.logger.traceEnabled) {
39+
this.logger.logTrace(
4040
`Could not find document '${getUriPath(
4141
uri
4242
)}' when updating the C# buffer. This typically happens when a document is removed.`

src/razor/src/document/razorDocumentManager.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export class RazorDocumentManager implements IRazorDocumentManager {
160160

161161
// This might happen in the case that a file is opened outside the workspace
162162
if (!document) {
163-
this.logger.logMessage(
163+
this.logger.logInfo(
164164
`File '${path}' didn't exist in the Razor document list. This is likely because it's from outside the workspace.`
165165
);
166166
document = this.addDocument(uri);
@@ -216,7 +216,7 @@ export class RazorDocumentManager implements IRazorDocumentManager {
216216
const path = getUriPath(uri);
217217
let document = this.findDocument(path);
218218
if (document) {
219-
this.logger.logMessage(`Skipping document creation for '${path}' because it already exists.`);
219+
this.logger.logInfo(`Skipping document creation for '${path}' because it already exists.`);
220220
return document;
221221
}
222222

@@ -250,8 +250,8 @@ export class RazorDocumentManager implements IRazorDocumentManager {
250250
}
251251

252252
private async updateCSharpBuffer(updateBufferRequest: UpdateBufferRequest) {
253-
if (this.logger.verboseEnabled) {
254-
this.logger.logVerbose(
253+
if (this.logger.traceEnabled) {
254+
this.logger.logTrace(
255255
`Updating the C# document for Razor file '${updateBufferRequest.hostDocumentFilePath}' ` +
256256
`(${updateBufferRequest.hostDocumentVersion})`
257257
);
@@ -296,8 +296,8 @@ export class RazorDocumentManager implements IRazorDocumentManager {
296296
}
297297

298298
private async updateHtmlBuffer(updateBufferRequest: UpdateBufferRequest) {
299-
if (this.logger.verboseEnabled) {
300-
this.logger.logVerbose(
299+
if (this.logger.traceEnabled) {
300+
this.logger.logTrace(
301301
`Updating the HTML document for Razor file '${updateBufferRequest.hostDocumentFilePath}' ` +
302302
`(${updateBufferRequest.hostDocumentVersion})`
303303
);
@@ -339,8 +339,8 @@ export class RazorDocumentManager implements IRazorDocumentManager {
339339
}
340340

341341
private notifyDocumentChange(document: IRazorDocument, kind: RazorDocumentChangeKind, changes: ServerTextChange[]) {
342-
if (this.logger.verboseEnabled) {
343-
this.logger.logVerbose(
342+
if (this.logger.traceEnabled) {
343+
this.logger.logTrace(
344344
`Notifying document '${getUriPath(document.uri)}' changed '${RazorDocumentChangeKind[kind]}' with '${
345345
changes.length
346346
}' changes.`

src/razor/src/document/razorDocumentSynchronizer.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ export class RazorDocumentSynchronizer {
3737
const logId = ++this.synchronizationIdentifier;
3838

3939
const documentKey = getUriPath(projectedDocument.uri);
40-
if (this.logger.verboseEnabled) {
40+
if (this.logger.traceEnabled) {
4141
const ehdv = expectedHostDocumentVersion;
42-
this.logger.logVerbose(
42+
this.logger.logTrace(
4343
`${logId} - Synchronizing '${documentKey}':
4444
Currently at ${projectedDocument.hostDocumentSyncVersion}, synchronizing to version '${ehdv}'.'`
4545
);
@@ -55,52 +55,52 @@ export class RazorDocumentSynchronizer {
5555

5656
try {
5757
if (projectedDocument.hostDocumentSyncVersion !== expectedHostDocumentVersion) {
58-
if (this.logger.verboseEnabled) {
59-
this.logger.logVerbose(
58+
if (this.logger.traceEnabled) {
59+
this.logger.logTrace(
6060
`${logId} - Projected document not in sync with host document, waiting for update...
6161
Current host document sync version: ${projectedDocument.hostDocumentSyncVersion}`
6262
);
6363
}
6464
await context.onProjectedDocumentSynchronized;
6565
}
6666

67-
if (this.logger.verboseEnabled) {
68-
this.logger.logVerbose(`${logId} - Projected document in sync with host document`);
67+
if (this.logger.traceEnabled) {
68+
this.logger.logTrace(`${logId} - Projected document in sync with host document`);
6969
}
7070

7171
// Projected document is the one we expect.
7272

7373
const projectedTextDocument = await vscode.workspace.openTextDocument(projectedDocument.uri);
7474
const projectedTextDocumentVersion = this.getProjectedTextDocumentVersion(projectedTextDocument);
7575
if (projectedDocument.hostDocumentSyncVersion !== projectedTextDocumentVersion) {
76-
if (this.logger.verboseEnabled) {
77-
this.logger.logVerbose(
76+
if (this.logger.traceEnabled) {
77+
this.logger.logTrace(
7878
`${logId} - Projected text document not in sync with data type, waiting for update...
7979
Current projected text document sync version: ${projectedTextDocumentVersion}`
8080
);
8181
}
8282
await context.onProjectedTextDocumentSynchronized;
8383
}
8484

85-
if (this.logger.verboseEnabled) {
86-
this.logger.logVerbose(`${logId} - Projected text document in sync with data type`);
85+
if (this.logger.traceEnabled) {
86+
this.logger.logTrace(`${logId} - Projected text document in sync with data type`);
8787
}
8888

8989
// Projected text document is the one we expect
9090
} catch (cancellationReason) {
9191
this.removeSynchronization(context);
9292

93-
if (this.logger.verboseEnabled) {
94-
this.logger.logVerbose(`${logId} - Synchronization failed: ${cancellationReason}`);
93+
if (this.logger.traceEnabled) {
94+
this.logger.logTrace(`${logId} - Synchronization failed: ${cancellationReason}`);
9595
}
9696

9797
return false;
9898
}
9999

100100
this.removeSynchronization(context);
101101

102-
if (this.logger.verboseEnabled) {
103-
this.logger.logVerbose(`${logId} - Synchronization successful!`);
102+
if (this.logger.traceEnabled) {
103+
this.logger.logTrace(`${logId} - Synchronization successful!`);
104104
}
105105

106106
return true;
@@ -198,10 +198,10 @@ export class RazorDocumentSynchronizer {
198198

199199
for (const context of synchronizationContexts) {
200200
if (context.projectedDocument.hostDocumentSyncVersion === projectedTextDocumentVersion) {
201-
if (this.logger.verboseEnabled) {
201+
if (this.logger.traceEnabled) {
202202
const li = context.logIdentifier;
203203
const ptdv = projectedTextDocumentVersion;
204-
this.logger.logVerbose(`${li} - Projected text document synchronized to ${ptdv}.`);
204+
this.logger.logTrace(`${li} - Projected text document synchronized to ${ptdv}.`);
205205
}
206206
context.projectedTextDocumentSynchronized();
207207
}

src/razor/src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export async function activate(
8282
// TODO: We still need a document manager for Html, so need to do _some_ of the below, just not sure what yet,
8383
// and it needs to be able to take a roslynLanguageServerClient instead of a razorLanguageServerClient I guess.
8484

85-
logger.logVerbose(
85+
logger.logTrace(
8686
'Razor cohosting is enabled, skipping language server activation. No rzls process will be created.'
8787
);
8888

0 commit comments

Comments
 (0)