diff --git a/.vscode/launch.json b/.vscode/launch.json index 377cb83ac..d88a00df5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -24,7 +24,9 @@ "csharp-test-profile", "${workspaceRoot}/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/slnWithCsproj.code-workspace", "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test/lsptoolshost/integrationTests" + "--extensionTestsPath=${workspaceRoot}/out/test/lsptoolshost/integrationTests", + "--log", + "ms-dotnettools.csharp:trace" ], "env": { "CODE_EXTENSIONS_PATH": "${workspaceRoot}", @@ -49,7 +51,9 @@ "csharp-test-profile", "${workspaceRoot}/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/devkit_slnWithCsproj.code-workspace", "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test/lsptoolshost/integrationTests" + "--extensionTestsPath=${workspaceRoot}/out/test/lsptoolshost/integrationTests", + "--log", + "ms-dotnettools.csharp:trace" ], "env": { "CODE_EXTENSIONS_PATH": "${workspaceRoot}", @@ -74,7 +78,9 @@ "csharp-test-profile", "${workspaceRoot}/test/razor/razorIntegrationTests/testAssets/BasicRazorApp2_1/.vscode/lsp_tools_host_BasicRazorApp2_1.code-workspace", "--extensionDevelopmentPath=${workspaceRoot}", - "--extensionTestsPath=${workspaceRoot}/out/test/razor/razorIntegrationTests" + "--extensionTestsPath=${workspaceRoot}/out/test/razor/razorIntegrationTests", + "--log", + "ms-dotnettools.csharp:trace" ], "env": { "CODE_EXTENSIONS_PATH": "${workspaceRoot}", diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d8713336..fe7651332 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,34 @@ - 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) +# 2.55.x +* Update Roslyn to 4.13.0-2.24531.3 (PR: [#7722](https://github.com/dotnet/vscode-csharp/pull/7722)) + * Proffer project system query service (PR: [#75682](https://github.com/dotnet/roslyn/pull/75682)) + * Ensure discards are initially soft selected in VSCode (PR: [#75655](https://github.com/dotnet/roslyn/pull/75655)) + * Reduce allocations in VirtualCharService.CreateVirtualCharSequence (PR: [#75654](https://github.com/dotnet/roslyn/pull/75654)) + * Reduce allocations in TextDocumentStates.AddRange (PR: [#75640](https://github.com/dotnet/roslyn/pull/75640)) +* Update Razor to 9.0.0-preview.24531.4 (PR: [#7723](https://github.com/dotnet/vscode-csharp/pull/7723)) + * Fix aggregate telemetry reliability (PR: [#11134](https://github.com/dotnet/razor/pull/11134)) + * [FUSE] Fix OnAutoInsert and override completion and possible others (PR: [#11122](https://github.com/dotnet/razor/pull/11122)) +* Update Roslyn to 4.13.0-2.24529.3 (PR: [#7705](https://github.com/dotnet/vscode-csharp/pull/7705)) +* Update Razor to 9.0.0-preview.24528.3 (PR: [#7705](https://github.com/dotnet/vscode-csharp/pull/7705)) + * Update project configuration from Roslyn info (#11092) (PR: [#11092](https://github.com/dotnet/razor/pull/11092)) + * Reduce the amount of telemetry emitted (#11094) (PR: [#11094](https://github.com/dotnet/razor/pull/11094)) + * Remove tooling MvcShims (#11088) (PR: [#11088](https://github.com/dotnet/razor/pull/11088)) +* Switch to new log output window API and remove `dotnet.server.trace` (PR: [#7688](https://github.com/dotnet/vscode-csharp/pull/7688)) +* Update Roslyn to 4.13.0-1.24528.3 (PR: [#7688](https://github.com/dotnet/vscode-csharp/pull/7688)) + * Fix crash when 'add await' analyzers binding expressions (PR: [#75644](https://github.com/dotnet/roslyn/pull/75644)) + * Shorten names shown in 'pull member up' (PR: [#75643](https://github.com/dotnet/roslyn/pull/75643)) + * Fix inaccessible constructors shown in sighelp (PR: [#75642](https://github.com/dotnet/roslyn/pull/75642)) + * Allow the client to update the server logging level dynamically (PR: [#75615](https://github.com/dotnet/roslyn/pull/75615)) +* Bumped xamlTools to 17.13.35431.11 (PR: [#7719](https://github.com/dotnet/vscode-csharp/pull/7719)) + * XAML validation improvements + * Validating properties of Setters, Triggers, Conditions. + * Validating text values like ` Red ` + * Warnings for obsolete values like LayoutOptions.CenterAndExpand + * XAML IntelliseSense completions for ResourceDictionary.Source + * XAML IntelliseSense completions for name properties like Setter.TargetName + # 2.54.x * Update debugger packages to v2.54.0 (PR: [#7691](https://github.com/dotnet/vscode-csharp/pull/7691)) * Only show misc files warning toast after delay. (PR: [#7689](https://github.com/dotnet/vscode-csharp/pull/7689)) @@ -23,6 +51,7 @@ * Report a better error for void components (#11041) (PR: [#11041](https://github.com/dotnet/razor/pull/11041)) * Ensure model directives are mapped at runtime (#11007) (PR: [#11007](https://github.com/dotnet/razor/pull/11007)) * Including @using for Out-of-Scope Razor Component References (#10651) (PR: [#10651](https://github.com/dotnet/razor/pull/10651)) +* Make checkDevCert a modal dialogue (PR: [#7704](https://github.com/dotnet/vscode-csharp/pull/7704)) # 2.53.x * Update Roslyn to 4.13.0-1.24518.1 (PR: [#7670](https://github.com/dotnet/vscode-csharp/pull/7670)) diff --git a/SUPPORT.md b/SUPPORT.md index 6a60ce364..291b9e650 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -19,15 +19,25 @@ We highly recommend using the C# extension's built-in command, `CSharp: Report a The template has a section to include the `C#` output window logs. These logs are not automatically included as they may contain personal information (such as full file paths and project names), but they are key to resolving problems. -1. First, set `dotnet.server.trace` to `Trace` in VSCode settings - ![settings window showing trace option](./docs/trace_logs.png) -2. Reload the window via the `Developer: Reload Window` (`workbench.action.reloadWindow`) command +1. Find the `C#` output window (`View` -> `Output`) and set the log level to `Trace` + ![c# output window showing trace option](./docs/csharp_trace.png) +2. Reproduce the issue +3. In the `C#` output window, select all (e.g. `cntrl+a`) and copy paste into the issue template under the 'C# Log' section. If you need to redact file paths and other information, please do so at this time. +4. Once the logs are collected, reset the window log level to `Info` + +If the issue only reproduces on extension startup, you can set `Trace` as the default (see screenshot above), reload the window, and trace logs will be captured on startup. + +##### C# LSP Trace Logs +Sometimes we need to know exactly what requests were sent to the Roslyn language server. To capture these logs: + +1. Set the log level to `Trace` for the `C#` output window as described above. +2. Find the `C# LSP Trace Logs` output window 3. Reproduce the issue -4. Open the output window via `View` -> `Output` and change to the `C#` output window. -5. Select all (e.g. cntrl+a) and copy paste into the issue template under the 'C# Log' section. If you need to redact file paths and other information, please do so at this time. -6. Once the logs are collected, reset `dotnet.server.trace` back to `Information` +4. Copy the contents of the `C# LSP Trace Logs` output window. -Oftentimes the C# logs are enough, but sometimes when dealing with LSP server issues, the LSP trace logs are required. These can be found by following the same steps as above, but using the `C# LSP Trace Logs` output window instead. +##### Other ways to set the log level +1. When launching VSCode from the CLI, pass the `--log ms-dotnettools.csharp:trace` parameter. +2. Invoke the `Developer: Set Log Level` command from the VSCode command palette, find the `C#` entry and set the level. #### Project loading problems diff --git a/docs/csharp_trace.png b/docs/csharp_trace.png new file mode 100644 index 000000000..215b8185b Binary files /dev/null and b/docs/csharp_trace.png differ diff --git a/docs/trace_logs.png b/docs/trace_logs.png deleted file mode 100644 index c1a72d0ed..000000000 Binary files a/docs/trace_logs.png and /dev/null differ diff --git a/l10n/bundle.l10n.json b/l10n/bundle.l10n.json index 2c1332f49..64885d6e5 100644 --- a/l10n/bundle.l10n.json +++ b/l10n/bundle.l10n.json @@ -29,13 +29,13 @@ "Can't parse envFile {0} because of {1}": "Can't parse envFile {0} because of {1}", "Open envFile": "Open envFile", "Yes": "Yes", + "More Information": "More Information", + "Security Warning": "Security Warning", + "The selected launch configuration is configured to launch a web browser but no trusted development certificate was found. Create a trusted self-signed certificate?": "The selected launch configuration is configured to launch a web browser but no trusted development certificate was found. Create a trusted self-signed certificate?", "Self-signed certificate sucessfully {0}": "Self-signed certificate sucessfully {0}", "Couldn't create self-signed certificate. {0}\ncode: {1}\nstdout: {2}": "Couldn't create self-signed certificate. {0}\ncode: {1}\nstdout: {2}", "Show Output": "Show Output", "Couldn't create self-signed certificate. See output for more information.": "Couldn't create self-signed certificate. See output for more information.", - "Not Now": "Not Now", - "More Information": "More Information", - "The selected launch configuration is configured to launch a web browser but no trusted development certificate was found. Create a trusted self-signed certificate?": "The selected launch configuration is configured to launch a web browser but no trusted development certificate was found. Create a trusted self-signed certificate?", "No executable projects": "No executable projects", "Select the project to launch": "Select the project to launch", "Invalid project index": "Invalid project index", @@ -50,6 +50,7 @@ "WARNING": "WARNING", "The C# extension was unable to automatically decode projects in the current workspace to create a runnable launch.json file. A template launch.json file has been created as a placeholder.\n\nIf the server is currently unable to load your project, you can attempt to resolve this by restoring any missing project dependencies (example: run 'dotnet restore') and by fixing any reported errors from building the projects in your workspace.\nIf this allows the server to now load your project then --\n * Delete this file\n * Open the Visual Studio Code command palette (View->Command Palette)\n * run the command: '.NET: Generate Assets for Build and Debug'.\n\nIf your project requires a more complex launch configuration, you may wish to delete this configuration and pick a different template using the 'Add Configuration...' button at the bottom of this file.": "The C# extension was unable to automatically decode projects in the current workspace to create a runnable launch.json file. A template launch.json file has been created as a placeholder.\n\nIf the server is currently unable to load your project, you can attempt to resolve this by restoring any missing project dependencies (example: run 'dotnet restore') and by fixing any reported errors from building the projects in your workspace.\nIf this allows the server to now load your project then --\n * Delete this file\n * Open the Visual Studio Code command palette (View->Command Palette)\n * run the command: '.NET: Generate Assets for Build and Debug'.\n\nIf your project requires a more complex launch configuration, you may wish to delete this configuration and pick a different template using the 'Add Configuration...' button at the bottom of this file.", "Failed to parse tasks.json file: {0}": "Failed to parse tasks.json file: {0}", + "Not Now": "Not Now", "Don't Ask Again": "Don't Ask Again", "Required assets to build and debug are missing from '{0}'. Add them?": "Required assets to build and debug are missing from '{0}'. Add them?", "Cancel": "Cancel", @@ -147,6 +148,7 @@ "project.json is no longer a supported project format for .NET Core applications.": "project.json is no longer a supported project format for .NET Core applications.", "More Detail": "More Detail", "Some projects have trouble loading. Please review the output for more details.": "Some projects have trouble loading. Please review the output for more details.", + "Select project": "Select project", "There are unresolved dependencies. Please execute the restore command to continue.": "There are unresolved dependencies. Please execute the restore command to continue.", "Restore": "Restore", "Package {0} download from {1} failed integrity check. Some features may not work as expected. Please restart Visual Studio Code to retrigger the download": "Package {0} download from {1} failed integrity check. Some features may not work as expected. Please restart Visual Studio Code to retrigger the download", diff --git a/package-lock.json b/package-lock.json index c77e54d1f..105bc1546 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,7 +54,7 @@ "@types/tmp": "0.0.33", "@types/unzipper": "^0.9.1", "@types/uuid": "^9.0.1", - "@types/vscode": "1.73.0", + "@types/vscode": "1.93.0", "@types/yauzl": "2.10.0", "@typescript-eslint/eslint-plugin": "^8.5.0", "@typescript-eslint/parser": "^8.5.0", @@ -97,7 +97,7 @@ "webpack-cli": "4.6.0" }, "engines": { - "vscode": "^1.75.0" + "vscode": "^1.93.0" } }, "node_modules/@ampproject/remapping": { @@ -3191,10 +3191,11 @@ } }, "node_modules/@types/vscode": { - "version": "1.73.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/vscode/-/vscode-1.73.0.tgz", - "integrity": "sha512-FhkfF7V3fj7S3WqXu7AxFesBLO3uMkdCPJJPbwyZXezv2xJ6xBWHYM2CmkkbO8wT9Fr3KipwxGGOoQRrYq7mHg==", - "dev": true + "version": "1.93.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/vscode/-/vscode-1.93.0.tgz", + "integrity": "sha1-HNdXPgJyrvnDV7r8Y1thd8FUAT4=", + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { "version": "17.0.24", @@ -18288,9 +18289,9 @@ } }, "@types/vscode": { - "version": "1.73.0", - "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/vscode/-/vscode-1.73.0.tgz", - "integrity": "sha512-FhkfF7V3fj7S3WqXu7AxFesBLO3uMkdCPJJPbwyZXezv2xJ6xBWHYM2CmkkbO8wT9Fr3KipwxGGOoQRrYq7mHg==", + "version": "1.93.0", + "resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/vscode/-/vscode-1.93.0.tgz", + "integrity": "sha1-HNdXPgJyrvnDV7r8Y1thd8FUAT4=", "dev": true }, "@types/yargs": { diff --git a/package.json b/package.json index 6cf827002..810a0799b 100644 --- a/package.json +++ b/package.json @@ -37,11 +37,11 @@ } }, "defaults": { - "roslyn": "4.13.0-1.24525.2", + "roslyn": "4.13.0-2.24531.3", "omniSharp": "1.39.11", - "razor": "9.0.0-preview.24524.4", + "razor": "9.0.0-preview.24531.4", "razorOmnisharp": "7.0.0-preview.23363.1", - "xamlTools": "17.13.35422.31" + "xamlTools": "17.13.35431.11" }, "main": "./dist/extension", "l10n": "./l10n", @@ -132,7 +132,7 @@ "@types/tmp": "0.0.33", "@types/unzipper": "^0.9.1", "@types/uuid": "^9.0.1", - "@types/vscode": "1.73.0", + "@types/vscode": "1.93.0", "@types/yauzl": "2.10.0", "@typescript-eslint/eslint-plugin": "^8.5.0", "@typescript-eslint/parser": "^8.5.0", @@ -689,7 +689,7 @@ } ], "engines": { - "vscode": "^1.75.0" + "vscode": "^1.93.0" }, "activationEvents": [ "onDebugInitialConfigurations", @@ -1441,21 +1441,6 @@ "default": false, "description": "%configuration.dotnet.server.waitForDebugger%" }, - "dotnet.server.trace": { - "scope": "window", - "type": "string", - "enum": [ - "Trace", - "Debug", - "Information", - "Warning", - "Error", - "Critical", - "None" - ], - "default": "Information", - "description": "%configuration.dotnet.server.trace%" - }, "dotnet.server.extensionPaths": { "scope": "machine-overridable", "type": [ @@ -5602,4 +5587,4 @@ } } } -} \ No newline at end of file +} diff --git a/package.nls.cs.json b/package.nls.cs.json index 2c45f5e71..44cd5323a 100644 --- a/package.nls.cs.json +++ b/package.nls.cs.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Určuje časový limit (v ms), aby se klient úspěšně spustil a připojil k jazykovému serveru.", "configuration.dotnet.server.suppressLspErrorToasts": "Potlačí zobrazování informačních zpráv o chybách, pokud na serveru dojde k chybě, ze které se dá zotavit.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Potlačí zobrazování informačních upozornění, pokud je aktivní dokument mimo otevřený pracovní prostor.", - "configuration.dotnet.server.trace": "Nastaví úroveň protokolování pro jazykový server", "configuration.dotnet.server.useServerGC": "Nakonfigurujte jazykový server tak, aby používal uvolňování paměti serveru .NET. Uvolňování paměti serveru obecně přináší vyšší výkon za cenu vyšší spotřeby paměti.", "configuration.dotnet.server.waitForDebugger": "Při spuštění serveru předá příznak --debug, aby bylo možné připojit ladicí program. (Dříve omnisharp.waitForDebugger)", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Hledat symboly v referenčních sestaveních Ovlivňuje funkce, které vyžadují vyhledávání symbolů, například přidání importů.", diff --git a/package.nls.de.json b/package.nls.de.json index c23da7875..fd24a3009 100644 --- a/package.nls.de.json +++ b/package.nls.de.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Gibt ein Timeout (in ms) an, mit dem der Client erfolgreich gestartet und eine Verbindung mit dem Sprachserver hergestellt werden kann.", "configuration.dotnet.server.suppressLspErrorToasts": "Unterdrückt, dass Fehler-Popups angezeigt werden, wenn auf dem Server ein wiederherstellbarer Fehler auftritt.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Hiermit wird die Anzeige von Popupwarnungen unterdrückt, wenn sich das aktive Dokument außerhalb des geöffneten Arbeitsbereichs befindet.", - "configuration.dotnet.server.trace": "Legt den Protokolliergrad für den Sprachserver fest.", "configuration.dotnet.server.useServerGC": "Konfigurieren Sie den Sprachserver für die Verwendung der GC des .NET-Servers. Die GC auf dem Server bietet im Allgemeinen eine bessere Leistung bei einem höheren Arbeitsspeicherverbrauch.", "configuration.dotnet.server.waitForDebugger": "Übergibt das Flag \"--debug\" beim Starten des Servers, damit ein Debugger angefügt werden kann. (Zuvor \"omnisharp.waitForDebugger\")", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Symbole in Verweisassemblys suchen. Dies wirkt sich auf Features aus, die eine Symbolsuche erfordern, z. B. Importe hinzufügen.", diff --git a/package.nls.es.json b/package.nls.es.json index 96374d049..1809d421a 100644 --- a/package.nls.es.json +++ b/package.nls.es.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Especifica un tiempo de espera (en ms) para que el cliente se inicie correctamente y se conecte al servidor de lenguaje.", "configuration.dotnet.server.suppressLspErrorToasts": "Suprime la visualización de notificaciones del sistema de error si el servidor encuentra un error recuperable.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Impida que aparezcan notificaciones de advertencia si el documento activo se encuentra fuera del área de trabajo abierta.", - "configuration.dotnet.server.trace": "Establece el nivel de registro para el servidor de lenguaje", "configuration.dotnet.server.useServerGC": "Configure el servidor de idiomas para usar la recolección de elementos no utilizados del servidor de .NET. La recolección de elementos no utilizados del servidor suele proporcionar un mejor rendimiento a costa de un mayor consumo de memoria.", "configuration.dotnet.server.waitForDebugger": "Pasa la marca --debug al iniciar el servidor para permitir que se adjunte un depurador. (Anteriormente \"omnisharp.waitForDebugger\")", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Buscar símbolos en ensamblados de referencia. Afecta a las características y requiere la búsqueda de símbolos, como agregar importaciones.", diff --git a/package.nls.fr.json b/package.nls.fr.json index c75bb555f..d0cab959e 100644 --- a/package.nls.fr.json +++ b/package.nls.fr.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Spécifie un délai d'attente (en ms) pour que le client démarre et se connecte avec succès au serveur de langue.", "configuration.dotnet.server.suppressLspErrorToasts": "Supprime l’affichage des notifications toast d’erreur si le serveur a rencontré une erreur récupérable.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Supprimez l’affichage des toasts d’avertissement si le document actif se situe en dehors de l’espace de travail ouvert.", - "configuration.dotnet.server.trace": "Définit le niveau de journalisation pour le serveur de langage", "configuration.dotnet.server.useServerGC": "Configurez le serveur de langue pour qu’il utilise le serveur .NET GC. Le serveur GC offre généralement un meilleur niveau de performance au prix d’une consommation de mémoire plus élevée.", "configuration.dotnet.server.waitForDebugger": "Passe le drapeau – debug lors du lancement du serveur pour permettre à un débogueur d’être attaché. (Précédemment `omnisharp.waitForDebugger`)", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Rechercher des symboles dans les assemblys de référence. Elle affecte les fonctionnalités nécessitant une recherche de symboles, comme l’ajout d’importations.", diff --git a/package.nls.it.json b/package.nls.it.json index 78f65609f..a931793d7 100644 --- a/package.nls.it.json +++ b/package.nls.it.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Specifica un timeout (in ms) per l'avvio del client e la sua connessione al server di linguaggio.", "configuration.dotnet.server.suppressLspErrorToasts": "Impedisce la visualizzazione degli avvisi popup di errore se il server rileva un errore reversibile.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Non visualizzare avvisi popup se il documento attivo si trova all'esterno dell'area di lavoro aperta.", - "configuration.dotnet.server.trace": "Imposta il livello di registrazione per il server di linguaggio", "configuration.dotnet.server.useServerGC": "Configurare il server del linguaggio per l'utilizzo di Garbage Collection del server .NET. Garbage Collection del server offre in genere prestazioni migliori a spese di un consumo di memoria più elevato.", "configuration.dotnet.server.waitForDebugger": "Passa il flag --debug all'avvio del server per consentire il collegamento di un debugger. (In precedenza “omnisharp.waitForDebugger”)", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Cerca simboli negli assembly di riferimento. Influisce sulle funzionalità che richiedono la ricerca di simboli, ad esempio l'aggiunta di importazioni.", diff --git a/package.nls.ja.json b/package.nls.ja.json index c5410124c..214ccb506 100644 --- a/package.nls.ja.json +++ b/package.nls.ja.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "クライアントが正常に起動して言語サーバーに接続するためのタイムアウト (ミリ秒) を指定します。", "configuration.dotnet.server.suppressLspErrorToasts": "サーバーで回復可能なエラーが発生した場合に、エラー トーストが表示されないようにします。", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "開いているワークスペースに属さないドキュメントがアクティブである場合に、警告トーストを表示しないようにします。", - "configuration.dotnet.server.trace": "言語サーバーのログ記録レベルを設定する", "configuration.dotnet.server.useServerGC": ".NET サーバーのガベージ コレクションを使用するように言語サーバーを構成します。サーバー GC は一般に、メモリ消費量が高いことをコストにパフォーマンスを向上させます。", "configuration.dotnet.server.waitForDebugger": "デバッガーのアタッチを許可するために、サーバーを起動するときに --debug フラグを渡します。(以前の `omnisharp.waitForDebugger`)", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "参照アセンブリ内のシンボルを検索します。影響を受ける機能には、インポートの追加などのシンボル検索が必要です。", diff --git a/package.nls.json b/package.nls.json index addcc8d7e..d751ee61c 100644 --- a/package.nls.json +++ b/package.nls.json @@ -31,7 +31,6 @@ "configuration.dotnet.server.componentPaths.xamlTools": "Overrides the folder path for the .xamlTools component of the language server", "configuration.dotnet.server.startTimeout": "Specifies a timeout (in ms) for the client to successfully start and connect to the language server.", "configuration.dotnet.server.waitForDebugger": "Passes the --debug flag when launching the server to allow a debugger to be attached. (Previously `omnisharp.waitForDebugger`)", - "configuration.dotnet.server.trace": "Sets the logging level for the language server", "configuration.dotnet.server.extensionPaths": "Override for path to language server --extension arguments", "configuration.dotnet.server.crashDumpPath": "Sets a folder path where crash dumps are written to if the language server crashes. Must be writeable by the user.", "configuration.dotnet.server.suppressLspErrorToasts": "Suppresses error toasts from showing up if the server encounters a recoverable error.", diff --git a/package.nls.ko.json b/package.nls.ko.json index 57c87595d..ca0efe054 100644 --- a/package.nls.ko.json +++ b/package.nls.ko.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "클라이언트가 언어 서버를 시작하고 연결하기 위한 시간 제한(밀리초)을 지정합니다.", "configuration.dotnet.server.suppressLspErrorToasts": "서버에서 복구 가능한 오류가 발생하는 경우 오류 알림이 표시되지 않도록 합니다.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "활성 문서가 열려 있는 작업 영역 밖에 있는 경우 경고 알림이 표시되지 않도록 합니다.", - "configuration.dotnet.server.trace": "언어 서버의 로깅 수준을 설정합니다.", "configuration.dotnet.server.useServerGC": ".NET 서버 가비지 수집을 사용하도록 언어 서버를 구성합니다. 서버 가비지 수집은 일반적으로 메모리 사용량이 많을수록 성능이 향상됩니다.", "configuration.dotnet.server.waitForDebugger": "디버거 연결을 허용하기 위해 서버를 시작할 때 --debug 플래그를 전달합니다(이전 `omnisharp.waitForDebugger`).", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "참조 어셈블리에서 기호를 검색합니다. 가져오기 추가와 같은 기호 검색이 필요한 기능에 영향을 줍니다.", diff --git a/package.nls.pl.json b/package.nls.pl.json index 3dc25006b..6ba979a59 100644 --- a/package.nls.pl.json +++ b/package.nls.pl.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Określa limit czasu (w ms) dla pomyślnego uruchomienia klienta i nawiązania połączenia z serwerem języka.", "configuration.dotnet.server.suppressLspErrorToasts": "Pomija wyświetlanie wyskakujących powiadomień o błędach, jeśli serwer napotka błąd do odzyskania.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Pomiń wyświetlanie wyskakujących powiadomień ostrzegawczych, jeśli dokument aktywny znajduje się poza otwartym obszarem roboczym.", - "configuration.dotnet.server.trace": "Ustawia poziom rejestrowania dla serwera języka", "configuration.dotnet.server.useServerGC": "Skonfiguruj serwer językowy do używania funkcji odzyskiwania pamięci serwera .NET. Odzyskiwanie pamięci serwera zasadniczo zapewnia lepszą wydajność przy wyższym zużyciu pamięci.", "configuration.dotnet.server.waitForDebugger": "Przekazuje flagę --debug podczas uruchamiania serwera, aby umożliwić dołączenie debugera. (Wcześniej „omnisharp.waitForDebugger”)", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Wyszukaj symbole w zestawach odwołań. Ma to wpływ na funkcje wymagające wyszukiwania symboli, takie jak dodawanie importów.", diff --git a/package.nls.pt-br.json b/package.nls.pt-br.json index b2d572c40..bdb3b6257 100644 --- a/package.nls.pt-br.json +++ b/package.nls.pt-br.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Especifica um tempo limite (em ms) para o cliente iniciar e conectar-se com êxito ao servidor de idioma.", "configuration.dotnet.server.suppressLspErrorToasts": "Suprime a exibição de notificações do erro se o servidor encontrar um erro recuperável.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Suprima a exibição de notificações de aviso do sistema se o documento ativo estiver fora do workspace aberto.", - "configuration.dotnet.server.trace": "Define o nível de log para o servidor de idiomas", "configuration.dotnet.server.useServerGC": "Configure o servidor de linguagem para usar a coleta de lixo do servidor do .NET. A coleta de lixo do servidor geralmente fornece um melhor desempenho às custas de um consumo de memória mais alto.", "configuration.dotnet.server.waitForDebugger": "Passa o sinalizador --debug ao iniciar o servidor para permitir que um depurador seja anexado. (Anteriormente `omnisharp.waitForDebugger`)", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Pesquisar símbolos em montagens de referência. Afeta os recursos que exigem pesquisa de símbolos, como adicionar importações.", diff --git a/package.nls.ru.json b/package.nls.ru.json index 55ce3a09b..f9c1c1d59 100644 --- a/package.nls.ru.json +++ b/package.nls.ru.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "Указывает время ожидания (в миллисекундах) для запуска клиента и его подключения к языковому серверу.", "configuration.dotnet.server.suppressLspErrorToasts": "Подавляет появление всплывающих сообщений об ошибках, если сервер обнаруживает устранимую ошибку.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Скрывать всплывающие предупреждения, если активный документ находится за пределами открытого рабочего пространства.", - "configuration.dotnet.server.trace": "Задает уровень ведения журнала для языкового сервера", "configuration.dotnet.server.useServerGC": "Настройте языковой сервер для использования сборки мусора сервера .NET. Сборка мусора сервера обычно обеспечивает более высокую производительность за счет более высокого потребления памяти.", "configuration.dotnet.server.waitForDebugger": "Передает флаг --debug при запуске сервера, чтобы разрешить подключение отладчика. (Ранее — \"omnisharp.waitForDebugger\")", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Поиск символов в эталонных сборках. Он влияет на функции, для которых требуется поиск символов, например добавление импортов.", diff --git a/package.nls.tr.json b/package.nls.tr.json index 84a727765..70d2d3ec7 100644 --- a/package.nls.tr.json +++ b/package.nls.tr.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "İstemcinin başarılı bir şekilde başlatılması ve dil sunucusuna bağlanması için zaman aşımını (ms cinsinden) belirtir.", "configuration.dotnet.server.suppressLspErrorToasts": "Sunucu kurtarılabilir bir hatayla karşılaştığında hata bildirimlerinin görünmesini engeller.", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "Etkin belge açık çalışma alanının dışındaysa, uyarı bildirimlerini göstermeyi durdur.", - "configuration.dotnet.server.trace": "Dil sunucusu için günlük düzeyini ayarlar", "configuration.dotnet.server.useServerGC": "Dil sunucusunu .NET sunucusu atık toplamayı kullanmak üzere yapılandırın. Sunucu atık toplama, genellikle yüksek bellek tüketimi pahasına daha iyi performans sağlar.", "configuration.dotnet.server.waitForDebugger": "Bir hata ayıklayıcının eklenmesine izin vermek için sunucuyu başlatırken --debug bayrağını iletir. (Önceden 'omnisharp.waitForDebugger')", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "Başvuru derlemeleri içinde sembolleri arama. İçeri aktarma ekleme gibi sembol arama gerektiren özellikleri etkiler.", diff --git a/package.nls.zh-cn.json b/package.nls.zh-cn.json index c3b576236..07acc3c48 100644 --- a/package.nls.zh-cn.json +++ b/package.nls.zh-cn.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "为客户端指定一个超时 (以毫秒为单位),以成功启动并连接到语言服务器。", "configuration.dotnet.server.suppressLspErrorToasts": "当服务器遇到可恢复错误时,禁止显示错误 toast。", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "如果活动文档在打开的工作区之外,则禁止显示警告 toast。", - "configuration.dotnet.server.trace": "设置语言服务器的日志记录级别", "configuration.dotnet.server.useServerGC": "将语言服务器配置为使用 .NET 服务器垃圾回收。服务器垃圾回收在提供更好的性能时通常需要消耗更多内存。", "configuration.dotnet.server.waitForDebugger": "启动服务器时传递 --debug 标志,以允许附加调试器。(之前为 \"omnisharp.waitForDebugger\")", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "在引用程序集中搜索符号。它会影响需要符号搜索的功能,例如添加导入。", diff --git a/package.nls.zh-tw.json b/package.nls.zh-tw.json index d5baa322b..1ff2d493f 100644 --- a/package.nls.zh-tw.json +++ b/package.nls.zh-tw.json @@ -69,7 +69,6 @@ "configuration.dotnet.server.startTimeout": "指定用戶端順利啟動並連接到語言伺服器的逾時 (毫秒)。", "configuration.dotnet.server.suppressLspErrorToasts": "如果伺服器發生可復原的錯誤,隱藏不顯示錯誤快顯通知。", "configuration.dotnet.server.suppressMiscellaneousFilesToasts": "如果使用中文件在開啟中工作區之外,則抑制顯示警告快顯通知。", - "configuration.dotnet.server.trace": "設定語言伺服器的記錄層次", "configuration.dotnet.server.useServerGC": "設定語言伺服器以使用 .NET 伺服器垃圾收集。伺服器垃圾收集通常會在耗用較高的記憶體時提供較佳的效能。", "configuration.dotnet.server.waitForDebugger": "啟動伺服器時傳遞 --debug 旗標,以允許附加偵錯工具。(先前為 `omnisharp.waitForDebugger`)", "configuration.dotnet.symbolSearch.searchReferenceAssemblies": "在參考組件中搜尋符號。這會影響需要符號搜尋的功能,例如新增匯入。", diff --git a/src/lsptoolshost/commands.ts b/src/lsptoolshost/commands.ts index 387e35d22..5d8d1edf3 100644 --- a/src/lsptoolshost/commands.ts +++ b/src/lsptoolshost/commands.ts @@ -11,12 +11,13 @@ import { createLaunchTargetForSolution } from '../shared/launchTarget'; import reportIssue from '../shared/reportIssue'; import { getDotnetInfo } from '../shared/utils/getDotnetInfo'; import { IHostExecutableResolver } from '../shared/constants/IHostExecutableResolver'; +import { getCSharpDevKit } from '../utils/getCSharpDevKit'; export function registerCommands( context: vscode.ExtensionContext, languageServer: RoslynLanguageServer, hostExecutableResolver: IHostExecutableResolver, - outputChannel: vscode.OutputChannel + outputChannel: vscode.LogOutputChannel ) { // It is very important to be careful about the types used as parameters for these command callbacks. // If the arguments are coming from the server as json, it is NOT appropriate to use type definitions @@ -38,9 +39,11 @@ export function registerCommands( context.subscriptions.push( vscode.commands.registerCommand('dotnet.restartServer', async () => restartServer(languageServer)) ); - context.subscriptions.push( - vscode.commands.registerCommand('dotnet.openSolution', async () => openSolution(languageServer)) - ); + if (!getCSharpDevKit()) { + context.subscriptions.push( + vscode.commands.registerCommand('dotnet.openSolution', async () => openSolution(languageServer)) + ); + } context.subscriptions.push( vscode.commands.registerCommand('csharp.reportIssue', async () => reportIssue( @@ -101,7 +104,7 @@ async function completionComplexEdit( textEdit: vscode.TextEdit, isSnippetString: boolean, newOffset: number, - outputChannel: vscode.OutputChannel + outputChannel: vscode.LogOutputChannel ): Promise { const componentName = '[roslyn.client.completionComplexEdit]'; @@ -167,9 +170,9 @@ async function completionComplexEdit( } } -function outputAndThrow(outputChannel: vscode.OutputChannel, message: string): void { +function outputAndThrow(outputChannel: vscode.LogOutputChannel, message: string): void { outputChannel.show(); - outputChannel.appendLine(message); + outputChannel.error(message); throw new Error(message); } diff --git a/src/lsptoolshost/copilot.ts b/src/lsptoolshost/copilot.ts index 65c6519d4..a9c1780f8 100644 --- a/src/lsptoolshost/copilot.ts +++ b/src/lsptoolshost/copilot.ts @@ -9,7 +9,6 @@ import { CopilotRelatedDocumentsReport, CopilotRelatedDocumentsRequest } from '. import { RoslynLanguageServer } from './roslynLanguageServer'; import { UriConverter } from './uriConverter'; import { TextDocumentIdentifier } from 'vscode-languageserver-protocol'; -import { languageServerOptions } from '../shared/options'; interface CopilotTrait { name: string; @@ -29,34 +28,22 @@ interface CopilotRelatedFilesProviderRegistration { ): vscode.Disposable; } -export function registerCopilotExtension(languageServer: RoslynLanguageServer, channel: vscode.OutputChannel) { - const isTraceLogLevel = - languageServerOptions.logLevel && - (languageServerOptions.logLevel === 'Trace' || languageServerOptions.logLevel === 'Debug'); - +export function registerCopilotExtension(languageServer: RoslynLanguageServer, channel: vscode.LogOutputChannel) { const ext = vscode.extensions.getExtension('github.copilot'); if (!ext) { - if (isTraceLogLevel) { - channel.appendLine( - 'GitHub Copilot extension not installed. Skip registeration of C# related files provider.' - ); - } + channel.debug('GitHub Copilot extension not installed. Skip registeration of C# related files provider.'); return; } ext.activate().then(() => { const relatedAPI = ext.exports as CopilotRelatedFilesProviderRegistration | undefined; if (!relatedAPI) { - if (isTraceLogLevel) { - channel.appendLine( - 'Incompatible GitHub Copilot extension installed. Skip registeration of C# related files provider.' - ); - } + channel.debug( + 'Incompatible GitHub Copilot extension installed. Skip registeration of C# related files provider.' + ); return; } - if (isTraceLogLevel) { - channel.appendLine('registration of C# related files provider for GitHub Copilot extension succeeded.'); - } + channel.debug('registration of C# related files provider for GitHub Copilot extension succeeded.'); const id = { extensionId: CSharpExtensionId, diff --git a/src/lsptoolshost/debugger.ts b/src/lsptoolshost/debugger.ts index f9fbcf57d..c7d2a3bc0 100644 --- a/src/lsptoolshost/debugger.ts +++ b/src/lsptoolshost/debugger.ts @@ -20,7 +20,7 @@ export function registerDebugger( languageServer: RoslynLanguageServer, languageServerEvents: RoslynLanguageServerEvents, platformInfo: PlatformInformation, - csharpOutputChannel: vscode.OutputChannel + csharpOutputChannel: vscode.LogOutputChannel ) { const workspaceInformationProvider: IWorkspaceDebugInformationProvider = new RoslynWorkspaceDebugInformationProvider(languageServer, csharpOutputChannel); diff --git a/src/lsptoolshost/fixAllCodeAction.ts b/src/lsptoolshost/fixAllCodeAction.ts index d4a510f94..429b8ad9e 100644 --- a/src/lsptoolshost/fixAllCodeAction.ts +++ b/src/lsptoolshost/fixAllCodeAction.ts @@ -13,7 +13,7 @@ import { UriConverter } from './uriConverter'; export function registerCodeActionFixAllCommands( context: vscode.ExtensionContext, languageServer: RoslynLanguageServer, - outputChannel: vscode.OutputChannel + outputChannel: vscode.LogOutputChannel ) { context.subscriptions.push( vscode.commands.registerCommand( @@ -26,7 +26,7 @@ export function registerCodeActionFixAllCommands( export async function getFixAllResponse( data: RoslynProtocol.CodeActionResolveData, languageServer: RoslynLanguageServer, - outputChannel: vscode.OutputChannel + outputChannel: vscode.LogOutputChannel ) { if (!data.FixAllFlavors) { throw new Error(`FixAllFlavors is missing from data ${JSON.stringify(data)}`); @@ -64,7 +64,7 @@ export async function getFixAllResponse( const componentName = '[roslyn.client.fixAllCodeAction]'; const errorMessage = 'Failed to make a fix all edit for completion.'; outputChannel.show(); - outputChannel.appendLine(`${componentName} ${errorMessage}`); + outputChannel.error(`${componentName} ${errorMessage}`); throw new Error('Tried to insert multiple code action edits, but an error occurred.'); } } @@ -76,7 +76,7 @@ export async function getFixAllResponse( async function registerFixAllResolveCodeAction( languageServer: RoslynLanguageServer, codeActionData: RoslynProtocol.CodeActionResolveData, - outputChannel: vscode.OutputChannel + outputChannel: vscode.LogOutputChannel ) { if (codeActionData) { const data = codeActionData; diff --git a/src/lsptoolshost/nestedCodeAction.ts b/src/lsptoolshost/nestedCodeAction.ts index 39bc22db7..633d6f19c 100644 --- a/src/lsptoolshost/nestedCodeAction.ts +++ b/src/lsptoolshost/nestedCodeAction.ts @@ -13,7 +13,7 @@ import { getFixAllResponse } from './fixAllCodeAction'; export function registerNestedCodeActionCommands( context: vscode.ExtensionContext, languageServer: RoslynLanguageServer, - outputChannel: vscode.OutputChannel + outputChannel: vscode.LogOutputChannel ) { context.subscriptions.push( vscode.commands.registerCommand( @@ -26,7 +26,7 @@ export function registerNestedCodeActionCommands( async function registerNestedResolveCodeAction( languageServer: RoslynLanguageServer, codeActionData: any, - outputChannel: vscode.OutputChannel + outputChannel: vscode.LogOutputChannel ): Promise { if (codeActionData) { const data = codeActionData; @@ -69,7 +69,7 @@ async function registerNestedResolveCodeAction( if (!response.edit) { outputChannel.show(); - outputChannel.appendLine(`Failed to make an edit for completion.`); + outputChannel.error(`Failed to make an edit for completion.`); throw new Error('Tried to retrieve a code action edit, but an error occurred.'); } @@ -81,7 +81,7 @@ async function registerNestedResolveCodeAction( const componentName = '[roslyn.client.nestedCodeAction]'; const errorMessage = 'Failed to make am edit for completion.'; outputChannel.show(); - outputChannel.appendLine(`${componentName} ${errorMessage}`); + outputChannel.error(`${componentName} ${errorMessage}`); throw new Error('Tried to insert code action edit, but an error occurred.'); } } diff --git a/src/lsptoolshost/restore.ts b/src/lsptoolshost/restore.ts index 4ea9f8599..5153becaa 100644 --- a/src/lsptoolshost/restore.ts +++ b/src/lsptoolshost/restore.ts @@ -14,14 +14,16 @@ import { } from './roslynProtocol'; import path = require('path'); import { showErrorMessage } from '../shared/observers/utils/showMessage'; +import { getCSharpDevKit } from '../utils/getCSharpDevKit'; let _restoreInProgress = false; -export function registerRestoreCommands( - context: vscode.ExtensionContext, - languageServer: RoslynLanguageServer, - restoreChannel: vscode.OutputChannel -) { +export function registerRestoreCommands(context: vscode.ExtensionContext, languageServer: RoslynLanguageServer) { + if (getCSharpDevKit()) { + // We do not need to register restore commands if using C# devkit. + return; + } + const restoreChannel = vscode.window.createOutputChannel('.NET NuGet Restore'); context.subscriptions.push( vscode.commands.registerCommand('dotnet.restore.project', async (_request): Promise => { return chooseProjectAndRestore(languageServer, restoreChannel); diff --git a/src/lsptoolshost/roslynLanguageServer.ts b/src/lsptoolshost/roslynLanguageServer.ts index 817321b9d..9e7adf6b2 100644 --- a/src/lsptoolshost/roslynLanguageServer.ts +++ b/src/lsptoolshost/roslynLanguageServer.ts @@ -77,7 +77,7 @@ import { import { registerSourceGeneratedFilesContentProvider } from './sourceGeneratedFilesContentProvider'; import { registerMiscellaneousFileNotifier } from './miscellaneousFileNotifier'; -let _channel: vscode.OutputChannel; +let _channel: vscode.LogOutputChannel; let _traceChannel: vscode.OutputChannel; // Flag indicating if C# Devkit was installed the last time we activated. @@ -164,11 +164,25 @@ export class RoslynLanguageServer { // setTrace only works after the client is already running. this._languageClient.onDidChangeState(async (state) => { if (state.newState === State.Running) { - const languageClientTraceLevel = RoslynLanguageServer.GetTraceLevel(languageServerOptions.logLevel); - - await this._languageClient.setTrace(languageClientTraceLevel); + await this.updateLogLevel(); } }); + // Register for changes to the log level. + _channel.onDidChangeLogLevel(async () => { + await this.updateLogLevel(); + }); + } + + private async updateLogLevel(): Promise { + if (this._languageClient.state === State.Running) { + const languageClientTraceLevel = RoslynLanguageServer.GetTraceLevel(_channel.logLevel); + // Update the server's log level. + await this.sendNotification('roslyn/updateLogLevel', { + logLevel: RoslynLanguageServer.GetServerLogLevel(_channel.logLevel), + }); + // Update the trace level that the client uses to log trace messages. + await this._languageClient.setTrace(languageClientTraceLevel); + } } private registerServerStateChanged() { @@ -467,7 +481,7 @@ export class RoslynLanguageServer { } if (!(error instanceof vscode.CancellationError)) { - _channel.appendLine(`Error making ${request} request: ${error.message}`); + _channel.error(`Error making ${request} request`, error); } return error; } @@ -565,7 +579,7 @@ export class RoslynLanguageServer { const dotnetInfo = await hostExecutableResolver.getHostExecutableInfo(); const dotnetExecutablePath = dotnetInfo.path; - _channel.appendLine('Dotnet path: ' + dotnetExecutablePath); + _channel.info('Dotnet path: ' + dotnetExecutablePath); let args: string[] = []; @@ -573,7 +587,10 @@ export class RoslynLanguageServer { args.push('--debug'); } - const logLevel = languageServerOptions.logLevel; + // Get the initial log level from the channel. + // Changes to the channel log level will be picked up by the server after + // LSP finishes initializing and we're able to pick up the new value. + const logLevel = this.GetServerLogLevel(_channel.logLevel); if (logLevel) { args.push('--logLevel', logLevel); } @@ -602,14 +619,14 @@ export class RoslynLanguageServer { csharpDevkitIntelliCodeExtensionId ); if (csharpDevkitIntelliCodeExtension) { - _channel.appendLine('Activating C# + C# Dev Kit + C# IntelliCode...'); + _channel.info('Activating C# + C# Dev Kit + C# IntelliCode...'); const csharpDevkitIntelliCodeArgs = await this.getCSharpDevkitIntelliCodeExportArgs( csharpDevkitIntelliCodeExtension, context ); args = args.concat(csharpDevkitIntelliCodeArgs); } else { - _channel.appendLine('Activating C# + C# Dev Kit...'); + _channel.info('Activating C# + C# Dev Kit...'); } // Set command enablement as soon as we know devkit is available. @@ -621,7 +638,7 @@ export class RoslynLanguageServer { await this.setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension); } else { // C# Dev Kit is not installed - continue C#-only activation. - _channel.appendLine('Activating C# standalone...'); + _channel.info('Activating C# standalone...'); // Set command enablement to use roslyn standalone commands. await vscode.commands.executeCommand('setContext', 'dotnet.server.activationContext', 'Roslyn'); @@ -632,11 +649,7 @@ export class RoslynLanguageServer { args.push('--extension', extensionPath); } - const isTraceLogLevel = logLevel && [Trace.Messages, Trace.Verbose].includes(this.GetTraceLevel(logLevel)); - - if (isTraceLogLevel) { - _channel.appendLine(`Starting server at ${serverPath}`); - } + _channel.debug(`Starting server at ${serverPath}`); // shouldn't this arg only be set if it's running with CSDevKit? args.push('--telemetryLevel', telemetryReporter.telemetryLevel); @@ -647,9 +660,7 @@ export class RoslynLanguageServer { if (!languageServerOptions.useServerGC) { // The server by default uses serverGC, if the user opts out we need to set the environment variable to disable it. env.DOTNET_gcServer = '0'; - if (isTraceLogLevel) { - _channel.appendLine('ServerGC disabled'); - } + _channel.debug('ServerGC disabled'); } let childProcess: cp.ChildProcessWithoutNullStreams; @@ -663,16 +674,12 @@ export class RoslynLanguageServer { // If we were given a path to a dll, launch that via dotnet. const argsWithPath = [serverPath].concat(args); - if (logLevel && [Trace.Messages, Trace.Verbose].includes(this.GetTraceLevel(logLevel))) { - _channel.appendLine(`Server arguments ${argsWithPath.join(' ')}`); - } + _channel.debug(`Server arguments ${argsWithPath.join(' ')}`); childProcess = cp.spawn(dotnetExecutablePath, argsWithPath, cpOptions); } else { // Otherwise assume we were given a path to an executable. - if (logLevel && [Trace.Messages, Trace.Verbose].includes(this.GetTraceLevel(logLevel))) { - _channel.appendLine(`Server arguments ${args.join(' ')}`); - } + _channel.debug(`Server arguments ${args.join(' ')}`); childProcess = cp.spawn(serverPath, args, cpOptions); } @@ -680,14 +687,14 @@ export class RoslynLanguageServer { // Record the stdout and stderr streams from the server process. childProcess.stdout.on('data', (data: { toString: (arg0: any) => any }) => { const result: string = isString(data) ? data : data.toString(RoslynLanguageServer.encoding); - _channel.append('[stdout] ' + result); + _channel.info('[stdout] ' + result); }); childProcess.stderr.on('data', (data: { toString: (arg0: any) => any }) => { const result: string = isString(data) ? data : data.toString(RoslynLanguageServer.encoding); - _channel.append('[stderr] ' + result); + _channel.error('[stderr] ' + result); }); childProcess.on('exit', (code) => { - _channel.appendLine(`Language server process exited with ${code}`); + _channel.info(`Language server process exited with ${code}`); }); // Timeout promise used to time out the connection process if it takes too long. @@ -707,14 +714,14 @@ export class RoslynLanguageServer { // The server process will create the named pipe used for communication. Wait for it to be created, // and listen for the server to pass back the connection information via stdout. const namedPipePromise = new Promise((resolve) => { - _channel.appendLine('waiting for named pipe information from server...'); + _channel.debug('waiting for named pipe information from server...'); childProcess.stdout.on('data', (data: { toString: (arg0: any) => any }) => { const result: string = isString(data) ? data : data.toString(RoslynLanguageServer.encoding); // Use the regular expression to find all JSON lines const jsonLines = result.match(RoslynLanguageServer.namedPipeKeyRegex); if (jsonLines) { const transmittedPipeNameInfo: NamedPipeInformation = JSON.parse(jsonLines[0]); - _channel.appendLine('received named pipe information from server'); + _channel.info('received named pipe information from server'); resolve(transmittedPipeNameInfo); } }); @@ -722,9 +729,9 @@ export class RoslynLanguageServer { const socketPromise = namedPipePromise.then(async (pipeConnectionInfo) => { return new Promise((resolve, reject) => { - _channel.appendLine('attempting to connect client to server...'); + _channel.debug('attempting to connect client to server...'); const socket = net.createConnection(pipeConnectionInfo.pipeName, () => { - _channel.appendLine('client has connected to server'); + _channel.info('client has connected to server'); resolve(socket); }); @@ -879,7 +886,7 @@ export class RoslynLanguageServer { if (csharpDevkitExtension && !_wasActivatedWithCSharpDevkit) { // We previously started without C# Dev Kit and its now installed. // Offer a prompt to restart the server to use C# Dev Kit. - _channel.appendLine(`Detected new installation of ${csharpDevkitExtensionId}`); + _channel.info(`Detected new installation of ${csharpDevkitExtensionId}`); const message = `Detected installation of ${csharpDevkitExtensionId}. Would you like to relaunch the language server for added features?`; showInformationMessage(vscode, message, title); } else { @@ -942,10 +949,9 @@ export class RoslynLanguageServer { ]; return csharpIntelliCodeArgs; } catch (e) { - _channel.appendLine(`Activation of ${csharpDevkitIntelliCodeExtensionId} failed`); - _channel.appendLine(e instanceof Error ? e.message : (e as string)); + _channel.error(`Activation of ${csharpDevkitIntelliCodeExtensionId} failed`, e); if (e instanceof Error && e.stack) { - _channel.appendLine(e.stack); + _channel.info(e.stack); } const stateKey = 'disableIntellicodeFailedPopup'; @@ -991,26 +997,44 @@ export class RoslynLanguageServer { await exports.setupTelemetryEnvironmentAsync(env); } - private static GetTraceLevel(logLevel: string): Trace { + /** + * Returns the C# Microsoft.Extensions.Logging.LogLevel enum string value + * corresponding to the given vscode.LogLevel. + */ + private static GetServerLogLevel(logLevel: vscode.LogLevel): string { + switch (logLevel) { + case vscode.LogLevel.Trace: + return 'Trace'; + case vscode.LogLevel.Debug: + return 'Debug'; + case vscode.LogLevel.Info: + return 'Information'; + case vscode.LogLevel.Warning: + return 'Warning'; + case vscode.LogLevel.Error: + return 'Error'; + case vscode.LogLevel.Off: + return 'None'; + default: + throw new Error(`Invalid log level ${logLevel}`); + } + } + + private static GetTraceLevel(logLevel: vscode.LogLevel): Trace { switch (logLevel) { - case 'Trace': + case vscode.LogLevel.Trace: return Trace.Verbose; - case 'Debug': + case vscode.LogLevel.Debug: return Trace.Messages; - case 'Information': + case vscode.LogLevel.Info: return Trace.Off; - case 'Warning': + case vscode.LogLevel.Warning: return Trace.Off; - case 'Error': + case vscode.LogLevel.Error: return Trace.Off; - case 'Critical': - return Trace.Off; - case 'None': + case vscode.LogLevel.Off: return Trace.Off; default: - _channel.appendLine( - `Invalid log level ${logLevel}, server will not start. Please set the 'dotnet.server.trace' configuration to a valid value` - ); throw new Error(`Invalid log level ${logLevel}`); } } @@ -1038,15 +1062,14 @@ export async function activateRoslynLanguageServer( context: vscode.ExtensionContext, platformInfo: PlatformInformation, optionObservable: Observable, - outputChannel: vscode.OutputChannel, - dotnetTestChannel: vscode.OutputChannel, - dotnetChannel: vscode.OutputChannel, + outputChannel: vscode.LogOutputChannel, reporter: TelemetryReporter, languageServerEvents: RoslynLanguageServerEvents ): Promise { // Create a channel for outputting general logs from the language server. _channel = outputChannel; // Create a separate channel for outputting trace logs - these are incredibly verbose and make other logs very difficult to see. + // The trace channel verbosity is controlled by the _channel verbosity. _traceChannel = vscode.window.createOutputChannel('C# LSP Trace Logs'); const hostExecutableResolver = new DotnetRuntimeExtensionResolver( @@ -1077,12 +1100,12 @@ export async function activateRoslynLanguageServer( registerRazorCommands(context, languageServer); - registerUnitTestingCommands(context, languageServer, dotnetTestChannel); + registerUnitTestingCommands(context, languageServer); // Register any needed debugger components that need to communicate with the language server. registerDebugger(context, languageServer, languageServerEvents, platformInfo, _channel); - registerRestoreCommands(context, languageServer, dotnetChannel); + registerRestoreCommands(context, languageServer); registerSourceGeneratedFilesContentProvider(context, languageServer); @@ -1094,19 +1117,19 @@ export async function activateRoslynLanguageServer( const extensionsFromPackageJson = vscode.extensions.all.flatMap((extension) => { let loadPaths = extension.packageJSON.contributes?.['csharpExtensionLoadPaths']; if (loadPaths === undefined || loadPaths === null) { - _traceChannel.appendLine(`Extension ${extension.id} does not contribute csharpExtensionLoadPaths`); + _channel.debug(`Extension ${extension.id} does not contribute csharpExtensionLoadPaths`); return []; } if (!Array.isArray(loadPaths) || loadPaths.some((loadPath) => typeof loadPath !== 'string')) { - _channel.appendLine( + _channel.warn( `Extension ${extension.id} has invalid csharpExtensionLoadPaths. Expected string array, found ${loadPaths}` ); return []; } loadPaths = loadPaths.map((loadPath) => path.join(extension.extensionPath, loadPath)); - _traceChannel.appendLine(`Extension ${extension.id} contributes csharpExtensionLoadPaths: ${loadPaths}`); + _channel.trace(`Extension ${extension.id} contributes csharpExtensionLoadPaths: ${loadPaths}`); return loadPaths; }); const extensionsFromOptions = languageServerOptions.extensionsPaths ?? []; diff --git a/src/lsptoolshost/roslynWorkspaceDebugConfigurationProvider.ts b/src/lsptoolshost/roslynWorkspaceDebugConfigurationProvider.ts index 9e820c656..2b5666c83 100644 --- a/src/lsptoolshost/roslynWorkspaceDebugConfigurationProvider.ts +++ b/src/lsptoolshost/roslynWorkspaceDebugConfigurationProvider.ts @@ -19,7 +19,7 @@ import { import { UriConverter } from './uriConverter'; export class RoslynWorkspaceDebugInformationProvider implements IWorkspaceDebugInformationProvider { - constructor(private server: RoslynLanguageServer, private outputChannel: vscode.OutputChannel) {} + constructor(private server: RoslynLanguageServer, private outputChannel: vscode.LogOutputChannel) {} public async getWorkspaceDebugInformation( workspaceFolder: vscode.Uri @@ -43,7 +43,7 @@ export class RoslynWorkspaceDebugInformationProvider implements IWorkspaceDebugI // Server errors are already logged by the language client, but its totally possible // that we fail because the server is restarting or a process got killed, etc. // Catch the error and log to the correct output (instead of going to the extension host output). - this.outputChannel.appendLine(`Failed to get debug configuration: ${e}`); + this.outputChannel.error(`Failed to get debug configuration`, e); return; } diff --git a/src/lsptoolshost/unitTesting.ts b/src/lsptoolshost/unitTesting.ts index 27da8f892..956be85fc 100644 --- a/src/lsptoolshost/unitTesting.ts +++ b/src/lsptoolshost/unitTesting.ts @@ -12,12 +12,14 @@ import { RunTestsParams, RunTestsPartialResult, RunTestsRequest, TestProgress } import { commonOptions } from '../shared/options'; import { UriConverter } from './uriConverter'; import { showErrorMessage } from '../shared/observers/utils/showMessage'; +import { getCSharpDevKit } from '../utils/getCSharpDevKit'; -export function registerUnitTestingCommands( - context: vscode.ExtensionContext, - languageServer: RoslynLanguageServer, - dotnetTestChannel: vscode.OutputChannel -) { +export function registerUnitTestingCommands(context: vscode.ExtensionContext, languageServer: RoslynLanguageServer) { + if (getCSharpDevKit()) { + // If using C# devkit, we don't need to register any test commands. + return; + } + const dotnetTestChannel = vscode.window.createOutputChannel('.NET Test Log'); context.subscriptions.push( vscode.commands.registerCommand( 'dotnet.test.run', diff --git a/src/main.ts b/src/main.ts index 3e560dc32..1f7eaa7f8 100644 --- a/src/main.ts +++ b/src/main.ts @@ -65,9 +65,7 @@ export async function activate( // ensure it gets properly disposed. Upon disposal the events will be flushed. context.subscriptions.push(reporter); - const dotnetTestChannel = vscode.window.createOutputChannel('.NET Test Log'); - const dotnetChannel = vscode.window.createOutputChannel('.NET NuGet Restore'); - const csharpChannel = vscode.window.createOutputChannel('C#'); + const csharpChannel = vscode.window.createOutputChannel('C#', { log: true }); const csharpchannelObserver = new CsharpChannelObserver(csharpChannel); const csharpLogObserver = new CsharpLoggerObserver(csharpChannel); eventStream.subscribe(csharpchannelObserver.post); @@ -141,13 +139,13 @@ export async function activate( platformInfo, optionStream, csharpChannel, - dotnetTestChannel, - dotnetChannel, reporter, roslynLanguageServerEvents ); } else { // activate language services + const dotnetTestChannel = vscode.window.createOutputChannel('.NET Test Log'); + const dotnetChannel = vscode.window.createOutputChannel('.NET NuGet Restore'); omnisharpLangServicePromise = activateOmniSharpLanguageServer( context, platformInfo, diff --git a/src/omnisharp/observers/projectStatusBarObserver.ts b/src/omnisharp/observers/projectStatusBarObserver.ts index b79167daa..419bd4e23 100644 --- a/src/omnisharp/observers/projectStatusBarObserver.ts +++ b/src/omnisharp/observers/projectStatusBarObserver.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as vscode from 'vscode'; import { basename } from 'path'; import { BaseEvent } from '../../shared/loggingEvents'; import { WorkspaceInformationUpdated } from '../omnisharpLoggingEvents'; @@ -14,7 +15,7 @@ export class ProjectStatusBarObserver extends BaseStatusBarItemObserver { switch (event.type) { case EventType.OmnisharpOnMultipleLaunchTargets: this.SetAndShowStatusBar( - '$(file-submodule) Select project', + '$(file-submodule) ' + vscode.l10n.t('Select project'), 'o.pickProjectAndStart', 'rgb(90, 218, 90)' ); diff --git a/src/shared/configurationProvider.ts b/src/shared/configurationProvider.ts index 8c4360ef6..fdd2e773d 100644 --- a/src/shared/configurationProvider.ts +++ b/src/shared/configurationProvider.ts @@ -150,7 +150,9 @@ export class BaseVsDbgConfigurationProvider implements vscode.DebugConfiguration } if (debugConfiguration.checkForDevCert) { - await this.checkForDevCerts(commonOptions.dotnetPath); + if (!(await this.checkForDevCerts(commonOptions.dotnetPath))) { + return undefined; + } } } @@ -233,70 +235,78 @@ export class BaseVsDbgConfigurationProvider implements vscode.DebugConfiguration } } - private async checkForDevCerts(dotnetPath: string) { - await hasDotnetDevCertsHttps(dotnetPath).then(async (returnData) => { + private async checkForDevCerts(dotnetPath: string): Promise { + let result: boolean | undefined = undefined; + + while (result === undefined) { + const returnData = await hasDotnetDevCertsHttps(dotnetPath); const errorCode = returnData.error?.code; if ( errorCode === CertToolStatusCodes.CertificateNotTrusted || errorCode === CertToolStatusCodes.ErrorNoValidCertificateFound ) { - const labelYes: ActionOption = { - title: vscode.l10n.t('Yes'), - action: async () => { - const returnData = await createSelfSignedCert(dotnetPath); - if (returnData.error === null) { - // if the process returns 0, returnData.error is null, otherwise the return code can be accessed in returnData.error.code - const message = - errorCode === CertToolStatusCodes.CertificateNotTrusted ? 'trusted' : 'created'; - showInformationMessage( - vscode, - vscode.l10n.t('Self-signed certificate sucessfully {0}', message) - ); - } else { - this.csharpOutputChannel.appendLine( - vscode.l10n.t( - `Couldn't create self-signed certificate. {0}\ncode: {1}\nstdout: {2}`, - returnData.error.message, - `${returnData.error.code}`, - returnData.stdout - ) - ); - - const labelShowOutput: ActionOption = { - title: vscode.l10n.t('Show Output'), - action: async () => { - this.csharpOutputChannel.show(); - }, - }; - showWarningMessage( - vscode, - vscode.l10n.t( - "Couldn't create self-signed certificate. See output for more information." - ), - labelShowOutput - ); - } - }, - }; - const labelNotNow = vscode.l10n.t('Not Now'); - const labelMoreInfo: ActionOption = { - title: vscode.l10n.t('More Information'), - action: async () => { - const launchjsonDescriptionURL = 'https://aka.ms/VSCode-CS-CheckForDevCert'; - await vscode.env.openExternal(vscode.Uri.parse(launchjsonDescriptionURL)); - await this.checkForDevCerts(dotnetPath); + const labelYes = vscode.l10n.t('Yes'); + const labelMoreInfo = vscode.l10n.t('More Information'); + + const dialogResult = await vscode.window.showWarningMessage( + vscode.l10n.t('Security Warning'), + { + modal: true, + detail: vscode.l10n.t( + 'The selected launch configuration is configured to launch a web browser but no trusted development certificate was found. Create a trusted self-signed certificate?' + ), }, - }; - showInformationMessage( - vscode, - vscode.l10n.t( - 'The selected launch configuration is configured to launch a web browser but no trusted development certificate was found. Create a trusted self-signed certificate?' - ), labelYes, - labelNotNow, labelMoreInfo ); + + if (dialogResult === labelYes) { + const returnData = await createSelfSignedCert(dotnetPath); + if (returnData.error === null) { + // if the process returns 0, returnData.error is null, otherwise the return code can be accessed in returnData.error.code + const message = errorCode === CertToolStatusCodes.CertificateNotTrusted ? 'trusted' : 'created'; + showInformationMessage( + vscode, + vscode.l10n.t('Self-signed certificate sucessfully {0}', message) + ); + + result = true; + } else { + this.csharpOutputChannel.appendLine( + vscode.l10n.t( + `Couldn't create self-signed certificate. {0}\ncode: {1}\nstdout: {2}`, + returnData.error.message, + `${returnData.error.code}`, + returnData.stdout + ) + ); + + const labelShowOutput: ActionOption = { + title: vscode.l10n.t('Show Output'), + action: async () => { + this.csharpOutputChannel.show(); + }, + }; + showWarningMessage( + vscode, + vscode.l10n.t("Couldn't create self-signed certificate. See output for more information."), + labelShowOutput + ); + + result = false; + } + } else if (dialogResult === labelMoreInfo) { + const launchjsonDescriptionURL = 'https://aka.ms/VSCode-CS-CheckForDevCert'; + await vscode.env.openExternal(vscode.Uri.parse(launchjsonDescriptionURL)); + } else if (dialogResult === undefined) { + // User cancelled dialog and wishes to continue debugging. + result = true; + } + } else { + result = true; } - }); + } + + return result; } } diff --git a/src/shared/options.ts b/src/shared/options.ts index 469c01124..3ed6a19f5 100644 --- a/src/shared/options.ts +++ b/src/shared/options.ts @@ -69,7 +69,6 @@ export interface OmnisharpServerOptions { } export interface LanguageServerOptions { - readonly logLevel: string; readonly documentSelector: DocumentSelector; readonly extensionsPaths: string[] | null; readonly preferCSharpExtension: boolean; @@ -379,9 +378,6 @@ class OmnisharpOptionsImpl implements OmnisharpServerOptions { } class LanguageServerOptionsImpl implements LanguageServerOptions { - public get logLevel() { - return readOption('dotnet.server.trace', 'Information'); - } public get documentSelector() { return readOption('dotnet.server.documentSelector', ['csharp']); } @@ -511,7 +507,6 @@ export const OmnisharpOptionsThatTriggerReload: ReadonlyArray = [ - 'logLevel', 'documentSelector', 'preferCSharpExtension', 'componentPaths', diff --git a/src/shared/reportIssue.ts b/src/shared/reportIssue.ts index 16345aaf5..a818423b1 100644 --- a/src/shared/reportIssue.ts +++ b/src/shared/reportIssue.ts @@ -125,14 +125,14 @@ function getLogInfo(useOmnisharp: boolean): string { return ` ### C# log ###
Post the output from Output-->C# here
### C# LSP Trace Logs ### -
Post the output from Output-->C# LSP Trace Logs here. Requires \`dotnet.server.trace\` to be set to \`Trace\`
`; +
Post the output from Output-->C# LSP Trace Logs here. Requires the \`C#\` output window log level to be set to \`Trace\`
`; } } diff --git a/test/lsptoolshost/integrationTests/commandEnablement.integration.test.ts b/test/lsptoolshost/integrationTests/commandEnablement.integration.test.ts index 167f59aba..c84d995fb 100644 --- a/test/lsptoolshost/integrationTests/commandEnablement.integration.test.ts +++ b/test/lsptoolshost/integrationTests/commandEnablement.integration.test.ts @@ -3,11 +3,16 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { expect, test, beforeAll, afterAll, describe } from '@jest/globals'; +import { expect, beforeAll, afterAll, describe } from '@jest/globals'; import * as vscode from 'vscode'; -import { activateCSharpExtension } from './integrationHelpers'; +import { activateCSharpExtension, testIfCSharp, testIfDevKit } from './integrationHelpers'; import testAssetWorkspace from './testAssets/testAssetWorkspace'; -import { CommonCommands, OmniSharpCommands, RoslynCommands } from './expectedCommands'; +import { + RoslynDevKitCommands, + RoslynStandaloneCommands, + UnexpectedRoslynDevKitCommands, + UnexpectedRoslynStandaloneCommands, +} from './expectedCommands'; describe(`Command Enablement Tests`, () => { beforeAll(async () => { @@ -18,19 +23,30 @@ describe(`Command Enablement Tests`, () => { await testAssetWorkspace.cleanupWorkspace(); }); - test('Roslyn commands are available', async () => { + testIfCSharp('Roslyn standalone commands are available', async () => { const commands = await vscode.commands.getCommands(true); // Ensure the standalone Roslyn commands are available. - RoslynCommands.forEach((command) => { + RoslynStandaloneCommands.forEach((command) => { expect(commands).toContain(command); }); - CommonCommands.forEach((command) => { + + // Ensure other commands are not available. + UnexpectedRoslynStandaloneCommands.forEach((command) => { + expect(commands).not.toContain(command); + }); + }); + + testIfDevKit('Roslyn + C# Dev Kit commands are available', async () => { + const commands = await vscode.commands.getCommands(true); + + // Ensure the Roslyn + C# Dev Kit commands are available + RoslynDevKitCommands.forEach((command) => { expect(commands).toContain(command); }); - // Ensure O# commands are not available. - OmniSharpCommands.forEach((command) => { + // Ensure other commands are not available. + UnexpectedRoslynDevKitCommands.forEach((command) => { expect(commands).not.toContain(command); }); }); diff --git a/test/lsptoolshost/integrationTests/expectedCommands.ts b/test/lsptoolshost/integrationTests/expectedCommands.ts index f8f0d6b61..26efe1214 100644 --- a/test/lsptoolshost/integrationTests/expectedCommands.ts +++ b/test/lsptoolshost/integrationTests/expectedCommands.ts @@ -3,7 +3,26 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -export const OmniSharpCommands = [ +// Commands used by all activation contexts of the extension. +const CommonCommands = [ + 'dotnet.generateAssets', + 'csharp.listProcess', + 'csharp.listRemoteProcess', + 'csharp.listRemoteDockerProcess', + 'csharp.attachToProcess', + 'csharp.reportIssue', +]; + +// Commands used by both O# and Roslyn standalone activation contexts. +const CommonStandaloneCommands = [ + 'dotnet.restore.project', + 'dotnet.restore.all', + 'dotnet.test.runTestsInContext', + 'dotnet.test.debugTestsInContext', +]; + +// Commands used only in an O# activation context. +const OmniSharpOnlyCommands = [ 'o.restart', 'o.pickProjectAndStart', 'o.fixAll.solution', @@ -13,17 +32,35 @@ export const OmniSharpCommands = [ 'o.reanalyze.currentProject', ]; -export const RoslynCommands = ['dotnet.openSolution', 'dotnet.restartServer']; +// All commands used in the O# activation context. +export const OmniSharpCommands = [...OmniSharpOnlyCommands, ...CommonCommands, ...CommonStandaloneCommands]; -export const CommonCommands = [ - 'dotnet.generateAssets', - 'dotnet.restore.project', - 'dotnet.restore.all', - 'dotnet.test.runTestsInContext', - 'dotnet.test.debugTestsInContext', - 'csharp.listProcess', - 'csharp.listRemoteProcess', - 'csharp.listRemoteDockerProcess', - 'csharp.attachToProcess', - 'csharp.reportIssue', +// Commands used only in a Roslyn activation context. +const RoslynCommonCommands = ['dotnet.restartServer']; + +// Commands used only in a Roslyn standalone activation context. +const RoslynStandaloneOnlyCommands = ['dotnet.openSolution']; + +// All commands used in a Roslyn standalone activation context. +export const RoslynStandaloneCommands = [ + ...CommonCommands, + ...CommonStandaloneCommands, + ...RoslynCommonCommands, + ...RoslynStandaloneOnlyCommands, +]; + +// All commands used in a Roslyn + C# Dev Kit activation context. +export const RoslynDevKitCommands = [...CommonCommands, ...RoslynCommonCommands]; + +// All commands that should not be available in an O# activation context. +export const UnexpectedOmniSharpCommands = [...RoslynStandaloneOnlyCommands, ...RoslynCommonCommands]; + +// All commands that should not be available in a Roslyn standalone activation context. +export const UnexpectedRoslynStandaloneCommands = [...OmniSharpOnlyCommands]; + +// All commands that should not be available in a Roslyn + C# Dev Kit activation context. +export const UnexpectedRoslynDevKitCommands = [ + ...CommonStandaloneCommands, + ...OmniSharpOnlyCommands, + ...RoslynStandaloneOnlyCommands, ]; diff --git a/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/devkit_slnWithCsproj.code-workspace b/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/devkit_slnWithCsproj.code-workspace index cb1af05bd..e045c4670 100644 --- a/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/devkit_slnWithCsproj.code-workspace +++ b/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/devkit_slnWithCsproj.code-workspace @@ -6,7 +6,6 @@ ], "settings": { "dotnet.defaultSolution": "b_SecondInOrder_SlnFile.sln", - "dotnet.server.trace": "Trace", "dotnet.server.useOmnisharp": false, "dotnet.preferCSharpExtension": false, } diff --git a/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/slnWithCsproj.code-workspace b/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/slnWithCsproj.code-workspace index 6da609d8b..06c4a6bea 100644 --- a/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/slnWithCsproj.code-workspace +++ b/test/lsptoolshost/integrationTests/testAssets/slnWithCsproj/.vscode/slnWithCsproj.code-workspace @@ -6,7 +6,6 @@ ], "settings": { "dotnet.defaultSolution": "b_SecondInOrder_SlnFile.sln", - "dotnet.server.trace": "Trace", "dotnet.server.useOmnisharp": false, "dotnet.preferCSharpExtension": true, } diff --git a/test/lsptoolshost/unitTests/languageServerConfigChangeObserver.test.ts b/test/lsptoolshost/unitTests/languageServerConfigChangeObserver.test.ts index 6b8ef6750..e8bf2928d 100644 --- a/test/lsptoolshost/unitTests/languageServerConfigChangeObserver.test.ts +++ b/test/lsptoolshost/unitTests/languageServerConfigChangeObserver.test.ts @@ -35,7 +35,6 @@ describe('Option changes observer', () => { [ { config: 'dotnet', section: 'server.documentSelector', value: ['other'] }, - { config: 'dotnet', section: 'server.trace', value: 'trace' }, { config: 'dotnet', section: 'preferCSharpExtension', value: true }, ].forEach((elem) => { describe(`When the ${elem.config}.${elem.section} changes`, () => { @@ -99,10 +98,7 @@ describe('Option changes observer', () => { }); }); - [ - { config: 'dotnet', section: 'server.documentSelector', value: ['csharp'] }, - { config: 'dotnet', section: 'server.trace', value: 'Information' }, - ].forEach((elem) => { + [{ config: 'dotnet', section: 'server.documentSelector', value: ['csharp'] }].forEach((elem) => { test(`Information Message is not shown if no change in value for ${elem.config}.${elem.section}`, async () => { expect(infoMessage).toBe(undefined); expect(invokedCommand).toBe(undefined); diff --git a/test/omnisharp/omnisharpIntegrationTests/omnisharpCommands.integration.test.ts b/test/omnisharp/omnisharpIntegrationTests/omnisharpCommands.integration.test.ts index efad59c9a..f3d567ee5 100644 --- a/test/omnisharp/omnisharpIntegrationTests/omnisharpCommands.integration.test.ts +++ b/test/omnisharp/omnisharpIntegrationTests/omnisharpCommands.integration.test.ts @@ -7,11 +7,7 @@ import { expect, test, beforeAll, afterAll, describe } from '@jest/globals'; import * as vscode from 'vscode'; import { activateCSharpExtension } from './integrationHelpers'; import testAssetWorkspace from './testAssets/activeTestAssetWorkspace'; -import { - CommonCommands, - OmniSharpCommands, - RoslynCommands, -} from '../../lsptoolshost/integrationTests/expectedCommands'; +import { OmniSharpCommands, UnexpectedOmniSharpCommands } from '../../lsptoolshost/integrationTests/expectedCommands'; describe(`Command Enablement: ${testAssetWorkspace.description}`, function () { beforeAll(async function () { @@ -31,12 +27,9 @@ describe(`Command Enablement: ${testAssetWorkspace.description}`, function () { OmniSharpCommands.forEach((command) => { expect(commands).toContain(command); }); - CommonCommands.forEach((command) => { - expect(commands).toContain(command); - }); - // Ensure Roslyn standalone commands are not available. - RoslynCommands.forEach((command) => { + // Ensure other commands are not available. + UnexpectedOmniSharpCommands.forEach((command) => { expect(commands).not.toContain(command); }); }); diff --git a/test/omnisharp/omnisharpIntegrationTests/testAssets/slnWithCsproj/.vscode/lsp_tools_host_slnWithCsproj.code-workspace b/test/omnisharp/omnisharpIntegrationTests/testAssets/slnWithCsproj/.vscode/lsp_tools_host_slnWithCsproj.code-workspace index 46ef8b6ed..767f2bb63 100644 --- a/test/omnisharp/omnisharpIntegrationTests/testAssets/slnWithCsproj/.vscode/lsp_tools_host_slnWithCsproj.code-workspace +++ b/test/omnisharp/omnisharpIntegrationTests/testAssets/slnWithCsproj/.vscode/lsp_tools_host_slnWithCsproj.code-workspace @@ -6,7 +6,6 @@ ], "settings": { "dotnet.defaultSolution": "b_SecondInOrder_SlnFile.sln", - "dotnet.server.trace": "Trace", "dotnet.server.useOmnisharp": false, "omnisharp.enableLspDriver": false, "dotnet.preferCSharpExtension": true, diff --git a/test/razor/razorIntegrationTests/testAssets/BasicRazorApp2_1/.vscode/BasicRazorApp2_1.code-workspace b/test/razor/razorIntegrationTests/testAssets/BasicRazorApp2_1/.vscode/BasicRazorApp2_1.code-workspace index 805d62e7e..7df1142a2 100644 --- a/test/razor/razorIntegrationTests/testAssets/BasicRazorApp2_1/.vscode/BasicRazorApp2_1.code-workspace +++ b/test/razor/razorIntegrationTests/testAssets/BasicRazorApp2_1/.vscode/BasicRazorApp2_1.code-workspace @@ -6,7 +6,6 @@ ], "settings": { "dotnet.defaultSolution": "BasicRazorApp2_1.sln", - "dotnet.server.trace": "Trace", "dotnet.server.useOmnisharp": false, "omnisharp.enableLspDriver": false, "razor.server.trace": "Trace", diff --git a/test/vscodeLauncher.ts b/test/vscodeLauncher.ts index 13e6798aa..11b343e26 100644 --- a/test/vscodeLauncher.ts +++ b/test/vscodeLauncher.ts @@ -15,7 +15,7 @@ export async function prepareVSCodeAndExecuteTests( userDataDir: string, env: NodeJS.ProcessEnv ): Promise { - const vscodeExecutablePath = await downloadAndUnzipVSCode('stable'); + const vscodeExecutablePath = await downloadAndUnzipVSCode('1.94.2'); const [cli, ...args] = resolveCliArgsFromVSCodeExecutablePath(vscodeExecutablePath); console.log('Display: ' + env.DISPLAY); @@ -54,7 +54,7 @@ export async function prepareVSCodeAndExecuteTests( extensionDevelopmentPath: extensionDevelopmentPath, extensionTestsPath: extensionTestsPath, // Launch with info logging as anything else is way too verbose and will hide test results. - launchArgs: [workspacePath, '-n', '--log', 'info', '--user-data-dir', userDataDir], + launchArgs: [workspacePath, '-n', '--user-data-dir', userDataDir, '--log', 'ms-dotnettools.csharp:trace'], extensionTestsEnv: env, }); diff --git a/version.json b/version.json index a0d2dfb02..4aeb56e77 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.54", + "version": "2.55", "publicReleaseRefSpec": [ "^refs/heads/release$", "^refs/heads/prerelease$",