Skip to content

Commit ba62755

Browse files
committed
Merge remote-tracking branch 'upstream/main' into MoreCohosting
2 parents d0e2e95 + a1d442e commit ba62755

16 files changed

+333
-77
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
# 2.76.x
77

88
# 2.75.x
9+
* Bump Razor to 10.0.0-preview.25228.4 (PR: [#8225](https://github.com/dotnet/vscode-csharp/pull/8225))
10+
* Don't return null if we couldn't sync the document for breakpoint validation (PR: [#11790](https://github.com/dotnet/razor/pull/11790))
11+
* Add VS Code IMappingService (PR: [#11760](https://github.com/dotnet/razor/pull/11760))
12+
* Fix cases where there is a space in the URI (PR: [#11745](https://github.com/dotnet/razor/pull/11745))
913
* Bump Roslyn to 5.0.0-1.25224.9 (PR: [#8211](https://github.com/dotnet/vscode-csharp/pull/8211))
1014
* Update ICSharpCode.Decompiler to 9.1.0.7988(PR: [#78270](https://github.com/dotnet/roslyn/pull/78270))
1115
* Reduce allocations in NamespaceSymbol.GetExtensionContainers(PR: [#78243](https://github.com/dotnet/roslyn/pull/78243))

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"defaults": {
4343
"roslyn": "5.0.0-1.25224.9",
4444
"omniSharp": "1.39.12",
45-
"razor": "10.0.0-preview.25228.3",
45+
"razor": "10.0.0-preview.25228.4",
4646
"razorOmnisharp": "7.0.0-preview.23363.1",
4747
"xamlTools": "17.14.36010.33"
4848
},

src/lsptoolshost/razor/razorEndpoints.ts

Lines changed: 102 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -41,104 +41,147 @@ import { ColorPresentation } from 'vscode-html-languageservice';
4141
import { convertRangeToSerializable } from '../../razor/src/rpc/serializableRange';
4242
import { FoldingRangeHandler } from '../../razor/src/folding/foldingRangeHandler';
4343
import { CompletionHandler } from '../../razor/src/completion/completionHandler';
44+
import { DynamicFileInfoHandler } from '../../razor/src/dynamicFile/dynamicFileInfoHandler';
45+
import { ProvideDynamicFileParams } from '../../razor/src/dynamicFile/provideDynamicFileParams';
46+
import { ProvideDynamicFileResponse } from '../../razor/src/dynamicFile/provideDynamicFileResponse';
47+
import { RazorMapSpansParams } from '../../razor/src/mapping/razorMapSpansParams';
48+
import { RazorMapSpansResponse } from '../../razor/src/mapping/razorMapSpansResponse';
49+
import { MappingHandler } from '../../razor/src/mapping/mappingHandler';
50+
import { RazorMapTextChangesParams } from '../../razor/src/mapping/razorMapTextChangesParams';
51+
import { RazorMapTextChangesResponse } from '../../razor/src/mapping/razorMapTextChangesResponse';
4452

4553
export function registerRazorEndpoints(
4654
context: vscode.ExtensionContext,
47-
languageServer: RoslynLanguageServer,
55+
roslynLanguageServer: RoslynLanguageServer,
4856
razorLogger: RazorLogger,
4957
platformInfo: PlatformInformation
5058
) {
5159
const logNotificationType = new NotificationType<LogMessageParams>('razor/log');
52-
languageServer.registerOnNotificationWithParams(logNotificationType, (params) =>
60+
roslynLanguageServer.registerOnNotificationWithParams(logNotificationType, (params) =>
5361
razorLogger.log(params.message, params.type)
5462
);
5563

56-
if (!razorOptions.cohostingEnabled) {
57-
return;
64+
if (razorOptions.cohostingEnabled) {
65+
registerCohostingEndpoints();
66+
} else {
67+
registerNonCohostingEndpoints();
5868
}
5969

60-
const documentManager = new HtmlDocumentManager(platformInfo, razorLogger);
61-
context.subscriptions.push(documentManager.register());
70+
return;
6271

63-
registerRequestHandler<HtmlUpdateParameters, void>('razor/updateHtml', async (params) => {
64-
const uri = UriConverter.deserialize(params.textDocument.uri);
65-
await documentManager.updateDocumentText(uri, params.text);
66-
});
67-
68-
registerRequestHandler<DocumentColorParams, ColorInformation[]>(DocumentColorRequest.method, async (params) => {
69-
const uri = UriConverter.deserialize(params.textDocument.uri);
70-
const document = await documentManager.getDocument(uri);
72+
//
73+
// Local Functions
74+
//
75+
function registerCohostingEndpoints() {
76+
const documentManager = new HtmlDocumentManager(platformInfo, razorLogger);
77+
context.subscriptions.push(documentManager.register());
7178

72-
return await DocumentColorHandler.doDocumentColorRequest(document.uri);
73-
});
79+
registerRequestHandler<HtmlUpdateParameters, void>('razor/updateHtml', async (params) => {
80+
const uri = UriConverter.deserialize(params.textDocument.uri);
81+
await documentManager.updateDocumentText(uri, params.text);
82+
});
7483

75-
registerRequestHandler<ColorPresentationParams, ColorPresentation[]>(
76-
ColorPresentationRequest.method,
77-
async (params) => {
84+
registerRequestHandler<DocumentColorParams, ColorInformation[]>(DocumentColorRequest.method, async (params) => {
7885
const uri = UriConverter.deserialize(params.textDocument.uri);
7986
const document = await documentManager.getDocument(uri);
8087

81-
return await ColorPresentationHandler.doColorPresentationRequest(document.uri, params);
82-
}
83-
);
88+
return await DocumentColorHandler.doDocumentColorRequest(document.uri);
89+
});
8490

85-
registerRequestHandler<FoldingRangeParams, FoldingRange[]>(FoldingRangeRequest.method, async (params) => {
86-
const uri = UriConverter.deserialize(params.textDocument.uri);
87-
const document = await documentManager.getDocument(uri);
91+
registerRequestHandler<ColorPresentationParams, ColorPresentation[]>(
92+
ColorPresentationRequest.method,
93+
async (params) => {
94+
const uri = UriConverter.deserialize(params.textDocument.uri);
95+
const document = await documentManager.getDocument(uri);
8896

89-
const results = await vscode.commands.executeCommand<vscode.FoldingRange[]>(
90-
'vscode.executeFoldingRangeProvider',
91-
document.uri
97+
return await ColorPresentationHandler.doColorPresentationRequest(document.uri, params);
98+
}
9299
);
93100

94-
return FoldingRangeHandler.convertFoldingRanges(results, razorLogger);
95-
});
96-
97-
registerRequestHandler<HoverParams, Hover | undefined>(HoverRequest.method, async (params) => {
98-
const uri = UriConverter.deserialize(params.textDocument.uri);
99-
const document = await documentManager.getDocument(uri);
101+
registerRequestHandler<FoldingRangeParams, FoldingRange[]>(FoldingRangeRequest.method, async (params) => {
102+
const uri = UriConverter.deserialize(params.textDocument.uri);
103+
const document = await documentManager.getDocument(uri);
100104

101-
const results = await vscode.commands.executeCommand<vscode.Hover[]>(
102-
'vscode.executeHoverProvider',
103-
document.uri,
104-
params.position
105-
);
106-
const applicableHover = results.filter((item) => item.range)[0];
105+
const results = await vscode.commands.executeCommand<vscode.FoldingRange[]>(
106+
'vscode.executeFoldingRangeProvider',
107+
document.uri
108+
);
107109

108-
return rewriteHover(applicableHover);
109-
});
110+
return FoldingRangeHandler.convertFoldingRanges(results, razorLogger);
111+
});
110112

111-
registerRequestHandler<DocumentHighlightParams, DocumentHighlight[]>(
112-
DocumentHighlightRequest.method,
113-
async (params) => {
113+
registerRequestHandler<HoverParams, Hover | undefined>(HoverRequest.method, async (params) => {
114114
const uri = UriConverter.deserialize(params.textDocument.uri);
115115
const document = await documentManager.getDocument(uri);
116116

117-
const results = await vscode.commands.executeCommand<vscode.DocumentHighlight[]>(
118-
'vscode.executeDocumentHighlights',
117+
const results = await vscode.commands.executeCommand<vscode.Hover[]>(
118+
'vscode.executeHoverProvider',
119119
document.uri,
120120
params.position
121121
);
122+
const applicableHover = results.filter((item) => item.range)[0];
122123

123-
return rewriteHighlight(results);
124-
}
125-
);
124+
return rewriteHover(applicableHover);
125+
});
126126

127-
registerRequestHandler<CompletionParams, CompletionList>(CompletionRequest.method, async (params) => {
128-
const uri = UriConverter.deserialize(params.textDocument.uri);
129-
const document = await documentManager.getDocument(uri);
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);
130132

131-
return CompletionHandler.provideVscodeCompletions(
132-
document.uri,
133-
params.position,
134-
params.context?.triggerCharacter
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+
}
135141
);
136-
});
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+
});
153+
}
154+
155+
function registerNonCohostingEndpoints() {
156+
registerRequestHandler<ProvideDynamicFileParams, ProvideDynamicFileResponse>(
157+
'razor/provideDynamicFileInfo',
158+
async (params) =>
159+
vscode.commands.executeCommand(DynamicFileInfoHandler.provideDynamicFileInfoCommand, params)
160+
);
161+
162+
registerRequestHandler<ProvideDynamicFileParams, ProvideDynamicFileResponse>(
163+
'razor/removeDynamicFileInfo',
164+
async (params) =>
165+
vscode.commands.executeCommand(DynamicFileInfoHandler.provideDynamicFileInfoCommand, params)
166+
);
167+
registerRequestHandler<RazorMapSpansParams, RazorMapSpansResponse>('razor/mapSpans', async (params) => {
168+
return await vscode.commands.executeCommand<RazorMapSpansResponse>(MappingHandler.MapSpansCommand, params);
169+
});
170+
registerRequestHandler<RazorMapTextChangesParams, RazorMapTextChangesResponse>(
171+
'razor/mapTextChanges',
172+
async (params) => {
173+
return await vscode.commands.executeCommand<RazorMapTextChangesResponse>(
174+
MappingHandler.MapChangesCommand,
175+
params
176+
);
177+
}
178+
);
179+
}
137180

138181
// Helper method that registers a request handler, and logs errors to the Razor logger.
139182
function registerRequestHandler<Params, Result>(method: string, invocation: (params: Params) => Promise<Result>) {
140183
const requestType = new RequestType<Params, Result, Error>(method);
141-
languageServer.registerOnRequest(requestType, async (params) => {
184+
roslynLanguageServer.registerOnRequest(requestType, async (params) => {
142185
try {
143186
return await invocation(params);
144187
} catch (error) {

src/razor/src/document/razorDocumentManager.ts

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

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

src/razor/src/dynamicFile/dynamicFileInfoHandler.ts

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { RazorDynamicFileChangedParams } from './dynamicFileUpdatedParams';
1616
import { TextDocumentIdentifier } from 'vscode-languageserver-protocol';
1717
import { razorTextChange } from './razorTextChange';
1818
import { razorTextSpan } from './razorTextSpan';
19+
import { razorOptions } from '../../../shared/options';
1920

2021
// Handles Razor generated doc communication between the Roslyn workspace and Razor.
2122
// didChange behavior for Razor generated docs is handled in the RazorDocumentManager.
@@ -39,18 +40,21 @@ export class DynamicFileInfoHandler {
3940
await this.removeDynamicFileInfo(request);
4041
}
4142
);
42-
this.documentManager.onChange(async (e) => {
43-
// Ignore any updates without text changes. This is important for perf since sending an update to roslyn does
44-
// a round trip for producing nothing new and causes a lot of churn in solution updates.
45-
if (e.kind == RazorDocumentChangeKind.csharpChanged && !e.document.isOpen && e.changes.length > 0) {
46-
const uriString = UriConverter.serialize(e.document.uri);
47-
const identifier = TextDocumentIdentifier.create(uriString);
48-
await vscode.commands.executeCommand(
49-
DynamicFileInfoHandler.dynamicFileUpdatedCommand,
50-
new RazorDynamicFileChangedParams(identifier)
51-
);
52-
}
53-
});
43+
44+
if (!razorOptions.cohostingEnabled) {
45+
this.documentManager.onChange(async (e) => {
46+
// Ignore any updates without text changes. This is important for perf since sending an update to roslyn does
47+
// a round trip for producing nothing new and causes a lot of churn in solution updates.
48+
if (e.kind == RazorDocumentChangeKind.csharpChanged && !e.document.isOpen && e.changes.length > 0) {
49+
const uriString = UriConverter.serialize(e.document.uri);
50+
const identifier = TextDocumentIdentifier.create(uriString);
51+
await vscode.commands.executeCommand(
52+
DynamicFileInfoHandler.dynamicFileUpdatedCommand,
53+
new RazorDynamicFileChangedParams(identifier)
54+
);
55+
}
56+
});
57+
}
5458
}
5559

5660
// Given Razor document URIs, returns associated generated doc URIs

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: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
import { RazorMapTextChangesParams } from './razorMapTextChangesParams';
10+
11+
export class MappingHandler {
12+
public static readonly MapSpansCommand = 'razor.mapSpansCommand';
13+
public static readonly MapChangesCommand = 'razor.mapChangesCommand';
14+
15+
constructor(private readonly languageServiceClient: RazorLanguageServiceClient) {}
16+
17+
public async register(): Promise<vscode.Disposable> {
18+
return vscode.Disposable.from(
19+
...[
20+
vscode.commands.registerCommand(MappingHandler.MapSpansCommand, async (params: RazorMapSpansParams) => {
21+
return this.languageServiceClient.mapSpans(params);
22+
}),
23+
vscode.commands.registerCommand(
24+
MappingHandler.MapChangesCommand,
25+
async (params: RazorMapTextChangesParams) => {
26+
return this.languageServiceClient.mapTextChanges(params);
27+
}
28+
),
29+
]
30+
);
31+
}
32+
}

src/razor/src/mapping/mappingHelpers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ 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';
1414

1515
public static async remapGeneratedFileWorkspaceEdit(
1616
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+
}

0 commit comments

Comments
 (0)