Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
- Debug from .csproj and .sln [#5876](https://github.com/dotnet/vscode-csharp/issues/5876)

# 2.122.x
* Update Roslyn to 5.5.0-2.26103.6 (PR: [#8956](https://github.com/dotnet/vscode-csharp/pull/8956))
* Enable and switch to `Balanced` source generator execution (PR: [#8970](https://github.com/dotnet/vscode-csharp/pull/8970))
* `Balanced` mode improves language server performance by only running source generators on explicit actions like file save, build task execution, or the `csharp.rerunSourceGenerators` command. This is in contrast to the previous default, `Automatic`, which ran source generators on every keystroke.
* The `dotnet.server.sourceGeneratorExecution` option allows you to switch between `Balanced` and `Automatic` source generator execution (requires restart).
* Update Roslyn to 5.5.0-2.26103.6 5.5.0-2.26109.12 (PR: [#8970](https://github.com/dotnet/vscode-csharp/pull/8970))
* Add LSP server support for balanced source generator execution with refresh (PR: [#82330](https://github.com/dotnet/roslyn/pull/82330))
* Handle change in enableFileBasedPrograms setting in the editor (PR: [#82214](https://github.com/dotnet/roslyn/pull/82214))
* No longer recommend 'this' inside nameof in an attribute (PR: [#82299](https://github.com/dotnet/roslyn/pull/82299))
* Fix workspace search always returning no results for first query (PR: [#82276](https://github.com/dotnet/roslyn/pull/82276))
* Improve elimination of redundant evaluations during pattern matching operation (PR: [#82142](https://github.com/dotnet/roslyn/pull/82142))
* Limit the FileSystemWatchers to one per drive root for DefaultFileChangeWatcher (PR: [#82211](https://github.com/dotnet/roslyn/pull/82211))
Expand Down
21 changes: 20 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"workspace"
],
"defaults": {
"roslyn": "5.5.0-2.26103.6",
"roslyn": "5.5.0-2.26109.12",
"omniSharp": "1.39.14",
"razor": "10.0.0-preview.26081.1",
"razorOmnisharp": "7.0.0-preview.23363.1",
Expand Down Expand Up @@ -1503,6 +1503,19 @@
"default": {},
"description": "%configuration.dotnet.server.environmentVariables%"
},
"dotnet.server.sourceGeneratorExecution": {
"type": "string",
"enum": [
"Balanced",
"Automatic"
],
"default": "Balanced",
"markdownEnumDescriptions": [
"%configuration.dotnet.server.sourceGeneratorExecution.balanced%",
"%configuration.dotnet.server.sourceGeneratorExecution.automatic%"
],
"markdownDescription": "%configuration.dotnet.server.sourceGeneratorExecution%"
},
"dotnet.enableXamlTools": {
"scope": "machine-overridable",
"type": "boolean",
Expand Down Expand Up @@ -1885,6 +1898,12 @@
"enablement": "dotnet.server.activationContext == 'Roslyn' || dotnet.server.activationContext == 'RoslynDevKit'",
"when": "false"
},
{
"command": "csharp.rerunSourceGenerators",
"title": "%command.csharp.rerunSourceGenerators%",
"category": "CSharp",
"enablement": "dotnet.server.activationContext == 'Roslyn' || dotnet.server.activationContext == 'RoslynDevKit'"
},
{
"command": "csharp.listProcess",
"title": "%command.csharp.listProcess%",
Expand Down
4 changes: 4 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"command.csharp.listRemoteDockerProcess": "List processes on Docker connection",
"command.csharp.attachToProcess": "Attach to a .NET 5+ or .NET Core process",
"command.csharp.reportIssue": "Report an issue",
"command.csharp.rerunSourceGenerators": "Rerun Source Generators",
"command.csharp.showDecompilationTerms": "Show the decompiler terms agreement",
"command.csharp.recordLanguageServerTrace": "Record a performance trace of the C# Language Server",
"command.csharp.captureLogs": "Capture C# Log Output",
Expand Down Expand Up @@ -51,6 +52,9 @@
"configuration.dotnet.projects.enableFileBasedPrograms": "Enables the \"file-based programs\" (dotnet run app.cs) experience.",
"configuration.dotnet.projects.enableFileBasedProgramsWhenAmbiguous": "Enables the \"file-based programs\" (dotnet run app.cs) experience in files where the editor is unable to determine with certainty whether the file is a file-based program. Only respected when `dotnet.projects.enableFileBasedPrograms` is `true`.",
"configuration.dotnet.projects.binaryLogPath": "Sets a path where MSBuild binary logs are written to when loading projects, to help diagnose loading errors.",
"configuration.dotnet.server.sourceGeneratorExecution": "Controls when source generators are executed. (Requires extension restart)",
"configuration.dotnet.server.sourceGeneratorExecution.balanced": "Source generators are executed after an explicit user action, including save, build, or the [Rerun source generators](command:csharp.rerunSourceGenerators) command.",
"configuration.dotnet.server.sourceGeneratorExecution.automatic": "Source generators are executed automatically as the user types.",
"configuration.dotnet.preferCSharpExtension": "Forces projects to load with the C# extension only. This can be useful when using legacy project types that are not supported by C# Dev Kit. (Requires extension restart)",
"configuration.dotnet.typeMembers.memberInsertionLocation": "The insertion location of properties, events, and methods When implement interface or abstract class.",
"configuration.dotnet.typeMembers.memberInsertionLocation.withOtherMembersOfTheSameKind": "Place them with other members of the same kind.",
Expand Down
2 changes: 2 additions & 0 deletions src/lsptoolshost/activate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { registerCopilotContextProviders } from './copilot/contextProviders';
import { RazorLogger } from '../razor/src/razorLogger';
import { registerRazorEndpoints } from './razor/razorEndpoints';
import { ObservableLogOutputChannel } from './logging/observableLogOutputChannel';
import { registerSourceGeneratorRefresh } from './generators/sourceGeneratorsRefresh';

let _channel: ObservableLogOutputChannel;
let _traceChannel: ObservableLogOutputChannel;
Expand Down Expand Up @@ -94,6 +95,7 @@ export async function activateRoslynLanguageServer(
registerRestoreCommands(context, languageServer, _channel);

registerSourceGeneratedFilesContentProvider(context, languageServer);
registerSourceGeneratorRefresh(context, languageServer, _channel);

context.subscriptions.push(registerLanguageServerOptionChanges(optionObservable));

Expand Down
47 changes: 47 additions & 0 deletions src/lsptoolshost/generators/sourceGeneratorsRefresh.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*---------------------------------------------------------------------------------------------
* 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 { RoslynLanguageServer } from '../server/roslynLanguageServer';
import { ObservableLogOutputChannel } from '../logging/observableLogOutputChannel';
import { RefreshSourceGeneratorsNotification } from '../server/roslynProtocol';

export function registerSourceGeneratorRefresh(
context: vscode.ExtensionContext,
languageServer: RoslynLanguageServer,
outputChannel: ObservableLogOutputChannel
) {
// Register the explicit rerun source generators command with force regeneration.
context.subscriptions.push(
vscode.commands.registerCommand('csharp.rerunSourceGenerators', async () => {
await languageServer.sendNotification(RefreshSourceGeneratorsNotification.method, {
forceRegeneration: true,
});
})
);

// After a build task completes, refresh source generators without force regeneration.
context.subscriptions.push(
vscode.tasks.onDidEndTask(async (e) => {
if (e.execution.task.group === vscode.TaskGroup.Build) {
outputChannel.trace('Refreshing source generators on build end');
await languageServer.sendNotification(RefreshSourceGeneratorsNotification.method, {
forceRegeneration: false,
});
}
})
);

context.subscriptions.push(
vscode.tasks.onDidStartTask(async (e) => {
if (e.execution.task.group === vscode.TaskGroup.Build) {
outputChannel.trace('Refreshing source generators on build start');
await languageServer.sendNotification(RefreshSourceGeneratorsNotification.method, {
forceRegeneration: false,
});
}
})
);
}
5 changes: 5 additions & 0 deletions src/lsptoolshost/server/roslynLanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,11 @@ export class RoslynLanguageServer {
args.push('--logLevel', logLevel);
}

const sourceGeneratorExecution = languageServerOptions.sourceGeneratorExecution;
if (sourceGeneratorExecution) {
args.push('--sourceGeneratorExecutionPreference', sourceGeneratorExecution);
}

let razorComponentPath = '';
getComponentPaths('razorExtension', languageServerOptions, channel).forEach((extPath) => {
additionalExtensionPaths.push(extPath);
Expand Down
10 changes: 10 additions & 0 deletions src/lsptoolshost/server/roslynProtocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ export interface SourceGeneratedDocumentText {
resultId?: string;
}

export interface RefreshSourceGeneratorsParams {
forceRegeneration: boolean;
}

export namespace WorkspaceDebugConfigurationRequest {
export const method = 'workspace/debugConfiguration';
export const messageDirection: MessageDirection = MessageDirection.clientToServer;
Expand Down Expand Up @@ -371,6 +375,12 @@ export namespace RefreshSourceGeneratedDocumentNotification {
export const type = new NotificationType(method);
}

export namespace RefreshSourceGeneratorsNotification {
export const method = 'workspace/_roslyn_refreshSourceGenerators';
export const messageDirection: MessageDirection = MessageDirection.clientToServer;
export const type = new NotificationType<RefreshSourceGeneratorsParams>(method);
}

export namespace RoslynLspErrorCodes {
/**
* Indicates that the server could not process the request, but that the failure shouldn't be surfaced to the user.
Expand Down
5 changes: 5 additions & 0 deletions src/shared/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export interface LanguageServerOptions {
readonly useServerGC: boolean;
readonly reportInformationAsHint: boolean;
readonly environmentVariables: { [key: string]: string };
readonly sourceGeneratorExecution: string;
}

export interface RazorOptions {
Expand Down Expand Up @@ -421,6 +422,9 @@ class LanguageServerOptionsImpl implements LanguageServerOptions {
public get environmentVariables() {
return readOption<{ [key: string]: string }>('dotnet.server.environmentVariables', {});
}
public get sourceGeneratorExecution() {
return readOption<string>('dotnet.server.sourceGeneratorExecution', 'Balanced');
}
}

class RazorOptionsImpl implements RazorOptions {
Expand Down Expand Up @@ -517,5 +521,6 @@ export const LanguageServerOptionsThatTriggerReload: ReadonlyArray<keyof Languag
'useServerGC',
'reportInformationAsHint',
'environmentVariables',
'sourceGeneratorExecution',
'crashDumpPath',
];