Skip to content

Commit 8ec4bac

Browse files
author
Andrew Hall
committed
Add mapSpans
1 parent 3e6416b commit 8ec4bac

File tree

9 files changed

+128
-9
lines changed

9 files changed

+128
-9
lines changed

src/lsptoolshost/razor/razorEndpoints.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,18 @@ import { ColorPresentation } from 'vscode-html-languageservice';
2727
import { DynamicFileInfoHandler } from '../../razor/src/dynamicFile/dynamicFileInfoHandler';
2828
import { ProvideDynamicFileParams } from '../../razor/src/dynamicFile/provideDynamicFileParams';
2929
import { ProvideDynamicFileResponse } from '../../razor/src/dynamicFile/provideDynamicFileResponse';
30+
import { RazorMapSpansParams } from '../../razor/src/mapping/razorMapSpansParams';
31+
import { RazorMapSpansResponse } from '../../razor/src/mapping/razorMapSpansResponse';
32+
import { MappingHandler } from '../../razor/src/mapping/mappingHandler';
3033

3134
export function registerRazorEndpoints(
3235
context: vscode.ExtensionContext,
33-
languageServer: RoslynLanguageServer,
36+
roslynLanguageServer: RoslynLanguageServer,
3437
razorLogger: RazorLogger,
3538
platformInfo: PlatformInformation
3639
) {
3740
const logNotificationType = new NotificationType<LogMessageParams>('razor/log');
38-
languageServer.registerOnNotificationWithParams(logNotificationType, (params) =>
41+
roslynLanguageServer.registerOnNotificationWithParams(logNotificationType, (params) =>
3942
razorLogger.log(params.message, params.type)
4043
);
4144

@@ -78,8 +81,6 @@ export function registerRazorEndpoints(
7881
}
7982

8083
function registerNonCohostingEndpoints() {
81-
// When the Roslyn language server sends a request for Razor dynamic file info, we forward that request along to Razor via
82-
// a command.
8384
registerRequestHandler<ProvideDynamicFileParams, ProvideDynamicFileResponse>(
8485
'razor/provideDynamicFileInfo',
8586
async (params) =>
@@ -91,12 +92,15 @@ export function registerRazorEndpoints(
9192
async (params) =>
9293
vscode.commands.executeCommand(DynamicFileInfoHandler.provideDynamicFileInfoCommand, params)
9394
);
95+
registerRequestHandler<RazorMapSpansParams, RazorMapSpansResponse>('razor/mapSpans', async (params) => {
96+
return await vscode.commands.executeCommand<RazorMapSpansResponse>(MappingHandler.MapSpansCommand, params);
97+
});
9498
}
9599

96100
// Helper method that registers a request handler, and logs errors to the Razor logger.
97101
function registerRequestHandler<Params, Result>(method: string, invocation: (params: Params) => Promise<Result>) {
98102
const requestType = new RequestType<Params, Result, Error>(method);
99-
languageServer.registerOnRequest(requestType, async (params) => {
103+
roslynLanguageServer.registerOnRequest(requestType, async (params) => {
100104
try {
101105
return await invocation(params);
102106
} catch (error) {

src/razor/src/document/razorDocumentManager.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,16 @@ export class RazorDocumentManager implements IRazorDocumentManager {
5656
return document;
5757
}
5858

59+
public async getDocumentForCSharpUri(csharpUri: vscode.Uri): Promise<IRazorDocument | undefined> {
60+
return this.documents.find((document) => {
61+
if (this.platformInfo.isLinux()) {
62+
return document.csharpDocument.path === csharpUri.path;
63+
}
64+
65+
return document.csharpDocument.path.localeCompare(csharpUri.path, undefined, { sensitivity: 'base' }) === 0;
66+
});
67+
}
68+
5969
public async getActiveDocument(): Promise<IRazorDocument | null> {
6070
if (!vscode.window.activeTextEditor) {
6171
return null;

src/razor/src/extension.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { InlayHintHandler } from './inlayHint/inlayHintHandler';
5151
import { InlayHintResolveHandler } from './inlayHint/inlayHintResolveHandler';
5252
import { getComponentPaths } from '../../lsptoolshost/extensions/builtInComponents';
5353
import { BlazorDebugConfigurationProvider } from './blazorDebug/blazorDebugConfigurationProvider';
54+
import { MappingHandler } from './mapping/mappingHandler';
5455

5556
// We specifically need to take a reference to a particular instance of the vscode namespace,
5657
// otherwise providers attempt to operate on the null extension.
@@ -123,15 +124,15 @@ export async function activate(
123124
logger
124125
);
125126

126-
const languageServiceClient = new RazorLanguageServiceClient(languageServerClient);
127-
128127
const documentManager = new RazorDocumentManager(
129128
languageServerClient,
130129
logger,
131130
razorTelemetryReporter,
132131
platformInfo
133132
);
134133

134+
const languageServiceClient = new RazorLanguageServiceClient(languageServerClient, documentManager);
135+
135136
const documentSynchronizer = new RazorDocumentSynchronizer(documentManager, logger);
136137
reportTelemetryForDocuments(documentManager, razorTelemetryReporter);
137138
const languageConfiguration = new RazorLanguageConfiguration();
@@ -261,6 +262,8 @@ export async function activate(
261262
logger
262263
);
263264

265+
const mappingHandler = new MappingHandler(languageServiceClient);
266+
264267
localRegistrations.push(
265268
languageConfiguration.register(),
266269
vscodeType.languages.registerSignatureHelpProvider(RazorLanguage.id, signatureHelpProvider, '(', ','),
@@ -298,6 +301,7 @@ export async function activate(
298301
completionHandler.register(),
299302
razorSimplifyMethodHandler.register(),
300303
razorFormatNewFileHandler.register(),
304+
mappingHandler.register(),
301305
]);
302306
});
303307

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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 { RazorLanguageServiceClient } from '../razorLanguageServiceClient';
8+
import { RazorMapSpansParams } from './razorMapSpansParams';
9+
10+
export class MappingHandler {
11+
public static readonly MapSpansCommand = 'razor.mapSpansCommand';
12+
constructor(private readonly languageServiceClient: RazorLanguageServiceClient) {}
13+
14+
public async register(): Promise<void> {
15+
vscode.commands.registerCommand(MappingHandler.MapSpansCommand, async (params: RazorMapSpansParams) => {
16+
return this.languageServiceClient.mapSpans(params);
17+
});
18+
}
19+
}

src/razor/src/mapping/mappingHelpers.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import { RazorLanguageServiceClient } from '../razorLanguageServiceClient';
1010
import { RazorLogger } from '../razorLogger';
1111

1212
export class MappingHelpers {
13-
public readonly language = 'Razor';
13+
public static readonly language = 'Razor';
14+
public static readonly MapSpansCommand = 'razor.mapSpansCommand';
1415

1516
public static async remapGeneratedFileWorkspaceEdit(
1617
workspaceEdit: vscode.WorkspaceEdit,
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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, TextDocumentIdentifier } from 'vscode-languageserver-protocol';
7+
8+
// Matches https://github.com/dotnet/razor/blob/main/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansParams.cs
9+
export class RazorMapSpansParams {
10+
constructor(public readonly csharpDocument: TextDocumentIdentifier, public readonly ranges: Range[]) {}
11+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
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, TextDocumentIdentifier } from 'vscode-languageserver-types';
7+
import { razorTextSpan } from '../dynamicFile/razorTextSpan';
8+
9+
// matches https://github.com/dotnet/razor/blob/main/src/Razor/src/Microsoft.VisualStudioCode.RazorExtension/Services/RazorMapSpansResponse.cs
10+
export class RazorMapSpansResponse {
11+
static empty: RazorMapSpansResponse = new RazorMapSpansResponse([], [], { uri: '' });
12+
13+
constructor(
14+
public readonly ranges: Range[],
15+
public readonly spans: razorTextSpan[],
16+
public readonly razorDocument: TextDocumentIdentifier
17+
) {}
18+
}

src/razor/src/razorLanguageServiceClient.ts

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,16 @@ import { LanguageQueryResponse } from './rpc/languageQueryResponse';
1111
import { RazorMapToDocumentRangesRequest } from './rpc/razorMapToDocumentRangesRequest';
1212
import { RazorMapToDocumentRangesResponse } from './rpc/razorMapToDocumentRangesResponse';
1313
import { convertRangeFromSerializable, convertRangeToSerializable } from './rpc/serializableRange';
14+
import { RazorMapSpansParams } from './mapping/razorMapSpansParams';
15+
import { RazorMapSpansResponse } from './mapping/razorMapSpansResponse';
16+
import { UriConverter } from '../../lsptoolshost/utils/uriConverter';
17+
import { RazorDocumentManager } from './document/razorDocumentManager';
1418

1519
export class RazorLanguageServiceClient {
16-
constructor(private readonly serverClient: RazorLanguageServerClient) {}
20+
constructor(
21+
private readonly serverClient: RazorLanguageServerClient,
22+
private readonly documentManager: RazorDocumentManager
23+
) {}
1724

1825
public async languageQuery(position: vscode.Position, uri: vscode.Uri) {
1926
await this.ensureStarted();
@@ -50,6 +57,49 @@ export class RazorLanguageServiceClient {
5057
return response;
5158
}
5259

60+
public async mapSpans(params: RazorMapSpansParams): Promise<RazorMapSpansResponse> {
61+
const csharpUri = UriConverter.deserialize(params.csharpDocument.uri);
62+
63+
const request = new RazorMapToDocumentRangesRequest(
64+
LanguageKind.CSharp,
65+
params.ranges.map(
66+
(r) =>
67+
new vscode.Range(
68+
new vscode.Position(r.start.line, r.start.character),
69+
new vscode.Position(r.end.line, r.end.character)
70+
)
71+
),
72+
csharpUri
73+
);
74+
75+
const result = await this.serverClient.sendRequest<RazorMapToDocumentRangesResponse>(
76+
'razor/mapToDocumentRanges',
77+
request
78+
);
79+
80+
if (!result) {
81+
return RazorMapSpansResponse.empty;
82+
}
83+
84+
const document = await this.documentManager.getDocumentForCSharpUri(csharpUri);
85+
if (!document) {
86+
return RazorMapSpansResponse.empty;
87+
}
88+
89+
return new RazorMapSpansResponse(
90+
result.ranges.map((r) => {
91+
return {
92+
start: { line: r.start.line, character: r.start.character },
93+
end: { line: r.end.line, character: r.end.character },
94+
};
95+
}),
96+
result.spans,
97+
{
98+
uri: UriConverter.serialize(document.uri),
99+
}
100+
);
101+
}
102+
53103
private async ensureStarted() {
54104
// If the server is already started this will instantly return.
55105
await this.serverClient.start();

src/razor/src/rpc/razorMapToDocumentRangesResponse.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import * as vscode from 'vscode';
7+
import { razorTextSpan } from '../dynamicFile/razorTextSpan';
78

89
export interface RazorMapToDocumentRangesResponse {
910
ranges: vscode.Range[];
1011
hostDocumentVersion: number;
12+
spans: razorTextSpan[];
1113
}

0 commit comments

Comments
 (0)