Skip to content

Commit 1bf0848

Browse files
authored
Merge pull request #6857 from davidwengier/RazorInlayHint
Add Razor inlay hint and inlay hint resolve handlers
2 parents ecc6e81 + 6374179 commit 1bf0848

File tree

6 files changed

+185
-0
lines changed

6 files changed

+185
-0
lines changed

src/lsptoolshost/razorCommands.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ import {
2323
CompletionRequest,
2424
CompletionResolveRequest,
2525
CompletionItem,
26+
InlayHint,
27+
InlayHintResolveRequest,
28+
InlayHintParams,
29+
InlayHintRequest,
2630
} from 'vscode-languageclient/node';
2731
import SerializableSimplifyMethodParams from '../razor/src/simplify/serializableSimplifyMethodParams';
2832
import { TextEdit } from 'vscode-html-languageservice';
@@ -40,6 +44,8 @@ export const provideSemanticTokensRangeCommand = 'roslyn.provideSemanticTokensRa
4044
export const roslynSimplifyMethodCommand = 'roslyn.simplifyMethod';
4145
export const roslynFormatNewFileCommand = 'roslyn.formatNewFile';
4246
export const razorInitializeCommand = 'razor.initialize';
47+
export const provideInlayHintsCommand = 'roslyn.provideInlayHints';
48+
export const resolveInlayHintCommand = 'roslyn.resolveInlayHint';
4349

4450
export function registerRazorCommands(context: vscode.ExtensionContext, languageServer: RoslynLanguageServer) {
4551
// Razor will call into us (via command) for generated file didChange/didClose notifications. We'll then forward these
@@ -100,6 +106,18 @@ export function registerRazorCommands(context: vscode.ExtensionContext, language
100106
})
101107
);
102108

109+
context.subscriptions.push(
110+
vscode.commands.registerCommand(provideInlayHintsCommand, async (request: InlayHintParams) => {
111+
return await languageServer.sendRequest(InlayHintRequest.type, request, CancellationToken.None);
112+
})
113+
);
114+
115+
context.subscriptions.push(
116+
vscode.commands.registerCommand(resolveInlayHintCommand, async (request: InlayHint) => {
117+
return await languageServer.sendRequest(InlayHintResolveRequest.type, request, CancellationToken.None);
118+
})
119+
);
120+
103121
context.subscriptions.push(
104122
vscode.commands.registerCommand(provideCompletionsCommand, async (request: CompletionParams) => {
105123
return await languageServer.sendRequest(CompletionRequest.type, request, CancellationToken.None);

src/razor/src/extension.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ import { PlatformInformation } from '../../shared/platform';
5353
import { RazorLanguageServerOptions } from './razorLanguageServerOptions';
5454
import { resolveRazorLanguageServerOptions } from './razorLanguageServerOptionsResolver';
5555
import { RazorFormatNewFileHandler } from './formatNewFile/razorFormatNewFileHandler';
56+
import { InlayHintHandler } from './inlayHint/inlayHintHandler';
57+
import { InlayHintResolveHandler } from './inlayHint/inlayHintResolveHandler';
5658

5759
// We specifically need to take a reference to a particular instance of the vscode namespace,
5860
// otherwise providers attempt to operate on the null extension.
@@ -170,6 +172,13 @@ export async function activate(
170172
logger
171173
);
172174
const foldingRangeHandler = new FoldingRangeHandler(languageServerClient, documentManager, logger);
175+
const inlayHintHandler = new InlayHintHandler(
176+
languageServerClient,
177+
documentManager,
178+
documentSynchronizer,
179+
logger
180+
);
181+
const inlayHintResolveHandler = new InlayHintResolveHandler(languageServerClient, documentManager, logger);
173182
const formattingHandler = new FormattingHandler(
174183
documentManager,
175184
documentSynchronizer,
@@ -292,6 +301,8 @@ export async function activate(
292301
colorPresentationHandler.register(),
293302
documentColorHandler.register(),
294303
foldingRangeHandler.register(),
304+
inlayHintHandler.register(),
305+
inlayHintResolveHandler.register(),
295306
formattingHandler.register(),
296307
semanticTokenHandler.register(),
297308
razorDiagnosticHandler.register(),
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import { InlayHint, InlayHintParams, RequestType, TextDocumentIdentifier } from 'vscode-languageclient';
8+
import { RazorDocumentManager } from '../document/razorDocumentManager';
9+
import { RazorLanguageServerClient } from '../razorLanguageServerClient';
10+
import { RazorLogger } from '../razorLogger';
11+
import { SerializableInlayHintParams } from './serializableInlayHintParams';
12+
import { provideInlayHintsCommand } from '../../../lsptoolshost/razorCommands';
13+
import { UriConverter } from '../../../lsptoolshost/uriConverter';
14+
import { RazorDocumentSynchronizer } from '../document/razorDocumentSynchronizer';
15+
16+
export class InlayHintHandler {
17+
private static readonly provideInlayHint = 'razor/inlayHint';
18+
private InlayHintRequestType: RequestType<SerializableInlayHintParams, InlayHint[], any> = new RequestType(
19+
InlayHintHandler.provideInlayHint
20+
);
21+
private emptyInlayHintResponse = new Array<InlayHint>();
22+
23+
constructor(
24+
private readonly serverClient: RazorLanguageServerClient,
25+
private readonly documentManager: RazorDocumentManager,
26+
private readonly documentSynchronizer: RazorDocumentSynchronizer,
27+
private readonly logger: RazorLogger
28+
) {}
29+
30+
public async register() {
31+
await this.serverClient.onRequestWithParams<SerializableInlayHintParams, InlayHint[], any>(
32+
this.InlayHintRequestType,
33+
async (request, token) => this.provideInlayHints(request, token)
34+
);
35+
}
36+
37+
private async provideInlayHints(inlayHintParams: SerializableInlayHintParams, token: vscode.CancellationToken) {
38+
try {
39+
const razorDocumentUri = vscode.Uri.parse(inlayHintParams.identifier.textDocumentIdentifier.uri, true);
40+
const razorDocument = await this.documentManager.getDocument(razorDocumentUri);
41+
if (razorDocument === undefined) {
42+
return this.emptyInlayHintResponse;
43+
}
44+
45+
if (!this.documentManager.roslynActivated) {
46+
// Unlike most other handlers, inlay hints works by directly sending an LSP request to Roslyn, so if Roslyn isn't
47+
// activated we need to catch that here.
48+
return this.emptyInlayHintResponse;
49+
}
50+
51+
const textDocument = await vscode.workspace.openTextDocument(razorDocumentUri);
52+
const synchronized = await this.documentSynchronizer.trySynchronizeProjectedDocument(
53+
textDocument,
54+
razorDocument.csharpDocument,
55+
inlayHintParams.identifier.version,
56+
token
57+
);
58+
if (!synchronized) {
59+
return this.emptyInlayHintResponse;
60+
}
61+
62+
const virtualCSharpUri = UriConverter.serialize(razorDocument.csharpDocument.uri);
63+
64+
const roslynInlayHintParams = <InlayHintParams>{
65+
textDocument: TextDocumentIdentifier.create(virtualCSharpUri),
66+
range: inlayHintParams.projectedRange,
67+
};
68+
const csharpInlayHints = await vscode.commands.executeCommand<InlayHint[]>(
69+
provideInlayHintsCommand,
70+
roslynInlayHintParams
71+
);
72+
73+
return csharpInlayHints;
74+
} catch (error) {
75+
this.logger.logWarning(`${InlayHintHandler.provideInlayHint} failed with ${error}`);
76+
}
77+
78+
return this.emptyInlayHintResponse;
79+
}
80+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as vscode from 'vscode';
7+
import { InlayHint, RequestType } from 'vscode-languageclient';
8+
import { RazorDocumentManager } from '../document/razorDocumentManager';
9+
import { RazorLanguageServerClient } from '../razorLanguageServerClient';
10+
import { RazorLogger } from '../razorLogger';
11+
import { SerializableInlayHintResolveParams } from './serializableInlayHintResolveParams';
12+
import { resolveInlayHintCommand } from '../../../lsptoolshost/razorCommands';
13+
14+
export class InlayHintResolveHandler {
15+
private static readonly resolveInlayHint = 'razor/inlayHintResolve';
16+
private InlayHintResolveRequestType: RequestType<SerializableInlayHintResolveParams, InlayHint | null, any> =
17+
new RequestType(InlayHintResolveHandler.resolveInlayHint);
18+
19+
constructor(
20+
private readonly serverClient: RazorLanguageServerClient,
21+
private readonly documentManager: RazorDocumentManager,
22+
private readonly logger: RazorLogger
23+
) {}
24+
25+
public async register() {
26+
await this.serverClient.onRequestWithParams<SerializableInlayHintResolveParams, InlayHint | null, any>(
27+
this.InlayHintResolveRequestType,
28+
async (request, token) => this.resolveInlayHint(request, token)
29+
);
30+
}
31+
32+
private async resolveInlayHint(InlayHintParams: SerializableInlayHintResolveParams, _: vscode.CancellationToken) {
33+
try {
34+
const razorDocumentUri = vscode.Uri.parse(InlayHintParams.identifier.textDocumentIdentifier.uri, true);
35+
const razorDocument = await this.documentManager.getDocument(razorDocumentUri);
36+
if (razorDocument === undefined) {
37+
return null;
38+
}
39+
40+
const response = await vscode.commands.executeCommand<InlayHint>(
41+
resolveInlayHintCommand,
42+
InlayHintParams.inlayHint
43+
);
44+
45+
return response;
46+
} catch (error) {
47+
this.logger.logWarning(`${InlayHintResolveHandler.resolveInlayHint} failed with ${error}`);
48+
}
49+
50+
return null;
51+
}
52+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { Range } from 'vscode-languageserver-protocol';
7+
import { SerializableTextDocumentIdentifierAndVersion } from '../simplify/serializableTextDocumentIdentifierAndVersion';
8+
9+
export interface SerializableInlayHintParams {
10+
identifier: SerializableTextDocumentIdentifierAndVersion;
11+
projectedRange: Range;
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { InlayHint } from 'vscode-languageserver-protocol';
7+
import { SerializableTextDocumentIdentifierAndVersion } from '../simplify/serializableTextDocumentIdentifierAndVersion';
8+
9+
export interface SerializableInlayHintResolveParams {
10+
identifier: SerializableTextDocumentIdentifierAndVersion;
11+
inlayHint: InlayHint;
12+
}

0 commit comments

Comments
 (0)