diff --git a/CHANGELOG.md b/CHANGELOG.md index 88db18f42..7afcebdf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ - Diagnostics related feature requests and improvements [#5951](https://github.com/dotnet/vscode-csharp/issues/5951) - Debug from .csproj and .sln [#5876](https://github.com/dotnet/vscode-csharp/issues/5876) +# Latest +* Update Roslyn to 4.13.0-1.24503.11 (PR: [#7618](https://github.com/dotnet/vscode-csharp/pull/7618)) + * LSP hover responses escape backticks within inline code (PR: [#75364](https://github.com/dotnet/roslyn/pull/75364)) + * Localize build host message output (PR: [#74910](https://github.com/dotnet/roslyn/pull/74910)) + * Log and report NFW when we fail to apply project system update (PR: [#75362](https://github.com/dotnet/roslyn/pull/75362)) + * Reduce allocations and UI thread CPU costs in WithDoNotCreateCreationPolicy (PR: [#75358](https://github.com/dotnet/roslyn/pull/75358)) + * Enable support for an LSP client to open source generated files (PR: [#75180](https://github.com/dotnet/roslyn/pull/75180)) + * Improve error reporting when reading bad metadata during EnC (PR: [#75304](https://github.com/dotnet/roslyn/pull/75304)) +* Suppress recoverable errors from razor LSP (PR: [#7624](https://github.com/dotnet/vscode-csharp/pull/7624)) + * NOTE: this can be re-enabled by setting `razor.languageServer.suppressLspErrorToasts = false` +* Update Roslyn to 4.13.0-1.24501.3 (PR: [#7618](https://github.com/dotnet/vscode-csharp/pull/7618)) + * Fix issue loading analyzers when using EnforceCodeStyleInBuild (PR: [#75250](https://github.com/dotnet/roslyn/pull/75250)) +* Update Razor to 9.0.0-preview.24480.1 (PR: [#7618](https://github.com/dotnet/vscode-csharp/pull/7618)) + * Fuse fix usings (PR: [#10925](https://github.com/dotnet/razor/pull/10925)) + * Fuse incorrect page directives (PR: [#10907](https://github.com/dotnet/razor/pull/10907)) + * Calculate SuppressAddComponentParameter in tooling (PR: [#10763](https://github.com/dotnet/razor/pull/10763)) + * Fix some `AssumeNotNull` assumptions (PR: [#10901](https://github.com/dotnet/razor/pull/10901)) + * Fixing HTML attribute commit (PR: [#10897](https://github.com/dotnet/razor/pull/10897)) + * Fix `FormattingContext` disposal (PR: [#10887](https://github.com/dotnet/razor/pull/10887)) + * Fix #10891 - Formatting does not respect indentation within Razor comment blocks (PR: [#10893](https://github.com/dotnet/razor/pull/10893)) + # 2.50.x * Update Roslyn to 4.13.0-1.24477.2 (PR: [#<>](https://github.com/dotnet/vscode-csharp/pull/<>)) * Use MSBuild globs to determine which file changes are relevant (PR: [#75139](https://github.com/dotnet/roslyn/pull/75139)) diff --git a/package.json b/package.json index 090a2cbcc..3ebf0521a 100644 --- a/package.json +++ b/package.json @@ -37,9 +37,9 @@ } }, "defaults": { - "roslyn": "4.13.0-1.24477.2", + "roslyn": "4.13.0-1.24503.11", "omniSharp": "1.39.11", - "razor": "9.0.0-preview.24467.1", + "razor": "9.0.0-preview.24480.1", "razorOmnisharp": "7.0.0-preview.23363.1", "xamlTools": "17.12.35326.17" }, @@ -1536,6 +1536,11 @@ "default": false, "description": "%configuration.razor.languageServer.forceRuntimeCodeGeneration%", "order": 90 + }, + "razor.languageServer.suppressLspErrorToasts": { + "type": "boolean", + "default": true, + "description": "%configuration.razor.languageServer.suppressLspErrorToasts%" } } }, diff --git a/package.nls.json b/package.nls.json index 2cd483130..80988e2f3 100644 --- a/package.nls.json +++ b/package.nls.json @@ -127,6 +127,7 @@ "configuration.razor.languageServer.debug": "Specifies whether to wait for debug attach when launching the language server.", "configuration.razor.server.trace": "Specifies the logging level to use for the Razor server.", "configuration.razor.languageServer.forceRuntimeCodeGeneration": "(EXPERIMENTAL) Enable combined design time/runtime code generation for Razor files", + "configuration.razor.languageServer.suppressLspErrorToasts": "Suppresses error toasts from showing up if the server encounters a recoverable error.", "debuggers.coreclr.configurationSnippets.label.console-local": ".NET: Launch Executable file (Console)", "debuggers.coreclr.configurationSnippets.label.web-local": ".NET: Launch Executable file (Web)", "debuggers.coreclr.configurationSnippets.label.attach-local": ".NET: Attach to a .NET process", diff --git a/src/lsptoolshost/copilot.ts b/src/lsptoolshost/copilot.ts index a3c6b3043..65c6519d4 100644 --- a/src/lsptoolshost/copilot.ts +++ b/src/lsptoolshost/copilot.ts @@ -11,13 +11,21 @@ import { UriConverter } from './uriConverter'; import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; import { languageServerOptions } from '../shared/options'; +interface CopilotTrait { + name: string; + value: string; + includeInPrompt?: boolean; + promptTextOverride?: string; +} + interface CopilotRelatedFilesProviderRegistration { registerRelatedFilesProvider( providerId: { extensionId: string; languageId: string }, callback: ( uri: vscode.Uri, + context: { flags: Record }, cancellationToken?: vscode.CancellationToken - ) => Promise<{ entries: vscode.Uri[]; traits?: { name: string; value: string }[] }> + ) => Promise<{ entries: vscode.Uri[]; traits?: CopilotTrait[] }> ): vscode.Disposable; } @@ -55,7 +63,7 @@ export function registerCopilotExtension(languageServer: RoslynLanguageServer, c languageId: 'csharp', }; - relatedAPI.registerRelatedFilesProvider(id, async (uri, token) => { + relatedAPI.registerRelatedFilesProvider(id, async (uri, _, token) => { const buildResult = (reports: CopilotRelatedDocumentsReport[], builder?: vscode.Uri[]) => { if (reports) { for (const report of reports) { diff --git a/src/lsptoolshost/roslynLanguageServer.ts b/src/lsptoolshost/roslynLanguageServer.ts index 023608c54..83f11799b 100644 --- a/src/lsptoolshost/roslynLanguageServer.ts +++ b/src/lsptoolshost/roslynLanguageServer.ts @@ -74,6 +74,7 @@ import { showErrorMessage, showInformationMessage, } from '../shared/observers/utils/showMessage'; +import { registerSourceGeneratedFilesContentProvider } from './sourceGeneratedFilesContentProvider'; let _channel: vscode.OutputChannel; let _traceChannel: vscode.OutputChannel; @@ -1068,6 +1069,8 @@ export async function activateRoslynLanguageServer( registerRestoreCommands(context, languageServer, dotnetChannel); + registerSourceGeneratedFilesContentProvider(context, languageServer); + context.subscriptions.push(registerLanguageServerOptionChanges(optionObservable)); return languageServer; diff --git a/src/lsptoolshost/roslynProtocol.ts b/src/lsptoolshost/roslynProtocol.ts index 9c612502b..9ba43d4af 100644 --- a/src/lsptoolshost/roslynProtocol.ts +++ b/src/lsptoolshost/roslynProtocol.ts @@ -230,6 +230,14 @@ export interface CopilotRelatedDocumentsReport { _vs_file_paths?: string[]; } +export interface SourceGeneratorGetRequestParams { + textDocument: lsp.TextDocumentIdentifier; +} + +export interface SourceGeneratedDocumentText { + text: string; +} + export namespace WorkspaceDebugConfigurationRequest { export const method = 'workspace/debugConfiguration'; export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer; @@ -351,3 +359,9 @@ export namespace CopilotRelatedDocumentsRequest { void >(method); } + +export namespace SourceGeneratorGetTextRequest { + export const method = 'sourceGeneratedDocument/_roslyn_getText'; + export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer; + export const type = new lsp.RequestType(method); +} diff --git a/src/lsptoolshost/sourceGeneratedFilesContentProvider.ts b/src/lsptoolshost/sourceGeneratedFilesContentProvider.ts new file mode 100644 index 000000000..6d070b590 --- /dev/null +++ b/src/lsptoolshost/sourceGeneratedFilesContentProvider.ts @@ -0,0 +1,31 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as vscode from 'vscode'; +import * as RoslynProtocol from './roslynProtocol'; +import { RoslynLanguageServer } from './roslynLanguageServer'; +import { UriConverter } from './uriConverter'; +import * as lsp from 'vscode-languageserver-protocol'; + +export function registerSourceGeneratedFilesContentProvider( + context: vscode.ExtensionContext, + languageServer: RoslynLanguageServer +) { + context.subscriptions.push( + vscode.workspace.registerTextDocumentContentProvider( + 'roslyn-source-generated', + new (class implements vscode.TextDocumentContentProvider { + async provideTextDocumentContent(uri: vscode.Uri, token: vscode.CancellationToken): Promise { + const result = await languageServer.sendRequest( + RoslynProtocol.SourceGeneratorGetTextRequest.type, + { textDocument: lsp.TextDocumentIdentifier.create(UriConverter.serialize(uri)) }, + token + ); + return result.text; + } + })() + ) + ); +} diff --git a/src/razor/src/razorLanguageClient.ts b/src/razor/src/razorLanguageClient.ts new file mode 100644 index 000000000..135f2e492 --- /dev/null +++ b/src/razor/src/razorLanguageClient.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { + CancellationToken, + LanguageClient, + LanguageClientOptions, + MessageSignature, + ServerOptions, +} from 'vscode-languageclient/node'; +import { RazorLanguageServerOptions } from './razorLanguageServerOptions'; + +export class RazorLanguageClient extends LanguageClient { + razorOptions: RazorLanguageServerOptions; + + constructor( + id: string, + name: string, + serverOptions: ServerOptions, + clientOptions: LanguageClientOptions, + razorOptions: RazorLanguageServerOptions, + forceDebug?: boolean + ) { + super(id, name, serverOptions, clientOptions, forceDebug); + this.razorOptions = razorOptions; + } + + override handleFailedRequest( + type: MessageSignature, + token: CancellationToken | undefined, + error: any, + defaultValue: T, + showNotification?: boolean + ) { + if (this.razorOptions.suppressErrorToasts) { + return super.handleFailedRequest(type, token, error, defaultValue, false); + } + + return super.handleFailedRequest(type, token, error, defaultValue, showNotification); + } +} diff --git a/src/razor/src/razorLanguageServerClient.ts b/src/razor/src/razorLanguageServerClient.ts index 141052c0e..9f73f4cf8 100644 --- a/src/razor/src/razorLanguageServerClient.ts +++ b/src/razor/src/razorLanguageServerClient.ts @@ -8,7 +8,7 @@ import { EventEmitter } from 'events'; import * as vscode from 'vscode'; import { RequestHandler, RequestType } from 'vscode-jsonrpc'; import { GenericNotificationHandler, InitializeResult, LanguageClientOptions, State } from 'vscode-languageclient'; -import { LanguageClient, ServerOptions } from 'vscode-languageclient/node'; +import { ServerOptions } from 'vscode-languageclient/node'; import { RazorLanguage } from './razorLanguage'; import { RazorLanguageServerOptions } from './razorLanguageServerOptions'; import { resolveRazorLanguageServerOptions } from './razorLanguageServerOptionsResolver'; @@ -18,6 +18,7 @@ import { TelemetryReporter as RazorTelemetryReporter } from './telemetryReporter import TelemetryReporter from '@vscode/extension-telemetry'; import { randomUUID } from 'crypto'; import { showErrorMessage } from '../../shared/observers/utils/showMessage'; +import { RazorLanguageClient } from './razorLanguageClient'; const events = { ServerStop: 'ServerStop', @@ -26,7 +27,7 @@ const events = { export class RazorLanguageServerClient implements vscode.Disposable { private clientOptions!: LanguageClientOptions; private serverOptions!: ServerOptions; - private client!: LanguageClient; + private client!: RazorLanguageClient; private onStartListeners: Array<() => Promise> = []; private onStartedListeners: Array<() => Promise> = []; private eventBus: EventEmitter; @@ -299,11 +300,12 @@ export class RazorLanguageServerClient implements vscode.Disposable { this.serverOptions = childProcess; - this.client = new LanguageClient( + this.client = new RazorLanguageClient( 'razorLanguageServer', 'Razor Language Server', this.serverOptions, - this.clientOptions + this.clientOptions, + options ); } } diff --git a/src/razor/src/razorLanguageServerOptions.ts b/src/razor/src/razorLanguageServerOptions.ts index 7cfe680c5..126798f16 100644 --- a/src/razor/src/razorLanguageServerOptions.ts +++ b/src/razor/src/razorLanguageServerOptions.ts @@ -13,4 +13,5 @@ export interface RazorLanguageServerOptions { logLevel: LogLevel; usingOmniSharp: boolean; forceRuntimeCodeGeneration: boolean; + suppressErrorToasts: boolean; } diff --git a/src/razor/src/razorLanguageServerOptionsResolver.ts b/src/razor/src/razorLanguageServerOptionsResolver.ts index 3b18aef3e..842f8f71b 100644 --- a/src/razor/src/razorLanguageServerOptionsResolver.ts +++ b/src/razor/src/razorLanguageServerOptionsResolver.ts @@ -25,6 +25,7 @@ export function resolveRazorLanguageServerOptions( const usingOmniSharp = !getCSharpDevKit() && vscodeApi.workspace.getConfiguration().get('dotnet.server.useOmnisharp'); const forceRuntimeCodeGeneration = serverConfig.get('forceRuntimeCodeGeneration'); + const suppressErrorToasts = serverConfig.get('suppressLspErrorToasts'); return { serverPath: languageServerExecutablePath, @@ -33,6 +34,7 @@ export function resolveRazorLanguageServerOptions( outputChannel: logger.outputChannel, usingOmniSharp, forceRuntimeCodeGeneration, + suppressErrorToasts, } as RazorLanguageServerOptions; } diff --git a/version.json b/version.json index 06cfa80ed..160c6958b 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "2.50", + "version": "2.51", "publicReleaseRefSpec": [ "^refs/heads/release$", "^refs/heads/prerelease$",