Skip to content

Commit 861cedc

Browse files
authored
Merge pull request #7112 from dibarbet/merge_xaml_tools
Merge feature/xamlTools into main
2 parents 4d3c647 + 27cd24f commit 861cedc

File tree

10 files changed

+217
-105
lines changed

10 files changed

+217
-105
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ node_modules
44
out
55
.roslyn/
66
.roslynDevKit/
7+
.xamlTools/
78
.omnisharp/
89
.omnisharp-*/
910
.vs/

package.json

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,12 @@
3737
}
3838
},
3939
"defaults": {
40-
"roslyn": "4.11.0-1.24226.4",
40+
"roslyn": "4.11.0-2.24229.10",
4141
"omniSharp": "1.39.11",
4242
"razor": "7.0.0-preview.24178.4",
4343
"razorOmnisharp": "7.0.0-preview.23363.1",
44-
"razorTelemetry": "7.0.0-preview.24178.4"
44+
"razorTelemetry": "7.0.0-preview.24178.4",
45+
"xamlTools": "17.11.34907.35"
4546
},
4647
"main": "./dist/extension",
4748
"l10n": "./l10n",
@@ -1658,6 +1659,21 @@
16581659
"scope": "machine-overridable",
16591660
"description": "%configuration.dotnet.server.path%"
16601661
},
1662+
"dotnet.server.componentPaths": {
1663+
"type": "object",
1664+
"description": "%configuration.dotnet.server.componentPaths%",
1665+
"properties": {
1666+
"roslynDevKit": {
1667+
"description": "%configuration.dotnet.server.componentPaths.roslynDevKit%",
1668+
"type": "string"
1669+
},
1670+
"xamlTools": {
1671+
"description": "%configuration.dotnet.server.componentPaths.xamlTools%",
1672+
"type": "string"
1673+
}
1674+
},
1675+
"default": {}
1676+
},
16611677
"dotnet.server.startTimeout": {
16621678
"type": "number",
16631679
"scope": "machine-overridable",
@@ -1703,6 +1719,12 @@
17031719
"default": null,
17041720
"description": "%configuration.dotnet.server.crashDumpPath%"
17051721
},
1722+
"dotnet.enableXamlToolsPreview": {
1723+
"scope": "machine-overridable",
1724+
"type": "boolean",
1725+
"default": true,
1726+
"description": "%configuration.dotnet.enableXamlToolsPreview%"
1727+
},
17061728
"dotnet.server.suppressLspErrorToasts": {
17071729
"type": "boolean",
17081730
"default": false,

package.nls.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,15 @@
2626
"configuration.dotnet.defaultSolution.description": "The path of the default solution to be opened in the workspace, or set to 'disable' to skip it. (Previously `omnisharp.defaultLaunchSolution`)",
2727
"configuration.dotnet.dotnetPath": "Specifies the path to a dotnet installation directory to use instead of the default system one. This only influences the dotnet installation to use for hosting the language server itself. Example: \"/home/username/mycustomdotnetdirectory\".",
2828
"configuration.dotnet.server.path": "Specifies the absolute path to the server (LSP or O#) executable. When left empty the version pinned to the C# Extension is used. (Previously `omnisharp.path`)",
29+
"configuration.dotnet.server.componentPaths": "Allows overriding the folder path for built in components of the language server (for example, override the .roslynDevKit path in the extension directory to use locally built components)",
30+
"configuration.dotnet.server.componentPaths.roslynDevKit": "Overrides the folder path for the .roslynDevKit component of the language server",
31+
"configuration.dotnet.server.componentPaths.xamlTools": "Overrides the folder path for the .xamlTools component of the language server",
2932
"configuration.dotnet.server.startTimeout": "Specifies a timeout (in ms) for the client to successfully start and connect to the language server.",
3033
"configuration.dotnet.server.waitForDebugger": "Passes the --debug flag when launching the server to allow a debugger to be attached. (Previously `omnisharp.waitForDebugger`)",
3134
"configuration.dotnet.server.trace": "Sets the logging level for the language server",
3235
"configuration.dotnet.server.extensionPaths": "Override for path to language server --extension arguments",
3336
"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.",
37+
"configuration.dotnet.enableXamlToolsPreview": "[Experimental] Enables XAML tools when using C# Dev Kit",
3438
"configuration.dotnet.server.suppressLspErrorToasts": "Suppresses error toasts from showing up if the server encounters a recoverable error.",
3539
"configuration.dotnet.projects.enableAutomaticRestore": "Enables automatic NuGet restore if the extension detects assets are missing.",
3640
"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 window reload)",

src/csharpExtensionExports.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export interface CSharpExtensionExports {
2525
profferBrokeredServices: (container: GlobalBrokeredServiceContainer) => void;
2626
determineBrowserType: () => Promise<string | undefined>;
2727
experimental: CSharpExtensionExperimentalExports;
28+
getComponentFolder: (componentName: string) => string;
2829
}
2930

3031
export interface CSharpExtensionExperimentalExports {

src/lsptoolshost/builtInComponents.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as fs from 'fs';
7+
import * as path from 'path';
8+
import { LanguageServerOptions } from '../shared/options';
9+
10+
interface ComponentInfo {
11+
defaultFolderName: string;
12+
optionName: string;
13+
componentDllPaths: string[];
14+
}
15+
16+
export const componentInfo: { [key: string]: ComponentInfo } = {
17+
roslynDevKit: {
18+
defaultFolderName: '.roslynDevKit',
19+
optionName: 'roslynDevKit',
20+
componentDllPaths: ['Microsoft.VisualStudio.LanguageServices.DevKit.dll'],
21+
},
22+
xamlTools: {
23+
defaultFolderName: '.xamlTools',
24+
optionName: 'xamlTools',
25+
componentDllPaths: [
26+
'Microsoft.VisualStudio.DesignTools.CodeAnalysis.dll',
27+
'Microsoft.VisualStudio.DesignTools.CodeAnalysis.Diagnostics.dll',
28+
],
29+
},
30+
};
31+
32+
export function getComponentPaths(componentName: string, options: LanguageServerOptions): string[] {
33+
const component = componentInfo[componentName];
34+
const baseFolder = getComponentFolderPath(component, options);
35+
const paths = component.componentDllPaths.map((dllPath) => path.join(baseFolder, dllPath));
36+
for (const dllPath of paths) {
37+
if (!fs.existsSync(dllPath)) {
38+
throw new Error(`Component DLL not found: ${dllPath}`);
39+
}
40+
}
41+
42+
return paths;
43+
}
44+
45+
export function getComponentFolder(componentName: string, options: LanguageServerOptions): string {
46+
const component = componentInfo[componentName];
47+
return getComponentFolderPath(component, options);
48+
}
49+
50+
function getComponentFolderPath(component: ComponentInfo, options: LanguageServerOptions): string {
51+
if (options.componentPaths) {
52+
const optionValue = options.componentPaths[component.optionName];
53+
if (optionValue) {
54+
return optionValue;
55+
}
56+
}
57+
58+
return path.join(__dirname, '..', component.defaultFolderName);
59+
}

src/lsptoolshost/roslynLanguageServer.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import { IDisposable } from '../disposable';
6262
import { registerNestedCodeActionCommands } from './nestedCodeAction';
6363
import { registerRestoreCommands } from './restore';
6464
import { BuildDiagnosticsService } from './buildDiagnosticsService';
65+
import { getComponentPaths } from './builtInComponents';
6566
import { OnAutoInsertFeature } from './onAutoInsertFeature';
6667

6768
let _channel: vscode.OutputChannel;
@@ -512,10 +513,6 @@ export class RoslynLanguageServer {
512513
args.push('--logLevel', logLevel);
513514
}
514515

515-
for (const extensionPath of additionalExtensionPaths) {
516-
args.push('--extension', extensionPath);
517-
}
518-
519516
args.push(
520517
'--razorSourceGenerator',
521518
path.join(context.extension.extensionPath, '.razor', 'Microsoft.CodeAnalysis.Razor.Compiler.dll')
@@ -546,7 +543,7 @@ export class RoslynLanguageServer {
546543
// Set command enablement as soon as we know devkit is available.
547544
vscode.commands.executeCommand('setContext', 'dotnet.server.activationContext', 'RoslynDevKit');
548545

549-
const csharpDevKitArgs = this.getCSharpDevKitExportArgs();
546+
const csharpDevKitArgs = this.getCSharpDevKitExportArgs(additionalExtensionPaths);
550547
args = args.concat(csharpDevKitArgs);
551548

552549
await this.setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension);
@@ -559,6 +556,10 @@ export class RoslynLanguageServer {
559556
_wasActivatedWithCSharpDevkit = false;
560557
}
561558

559+
for (const extensionPath of additionalExtensionPaths) {
560+
args.push('--extension', extensionPath);
561+
}
562+
562563
if (logLevel && [Trace.Messages, Trace.Verbose].includes(this.GetTraceLevel(logLevel))) {
563564
_channel.appendLine(`Starting server at ${serverPath}`);
564565
}
@@ -812,19 +813,24 @@ export class RoslynLanguageServer {
812813
);
813814
}
814815

815-
private static getCSharpDevKitExportArgs(): string[] {
816+
private static getCSharpDevKitExportArgs(additionalExtensionPaths: string[]): string[] {
816817
const args: string[] = [];
817818

818-
const clientRoot = __dirname;
819-
const devKitDepsPath = path.join(
820-
clientRoot,
821-
'..',
822-
'.roslynDevKit',
823-
'Microsoft.VisualStudio.LanguageServices.DevKit.dll'
824-
);
825-
args.push('--devKitDependencyPath', devKitDepsPath);
819+
const devKitDepsPath = getComponentPaths('roslynDevKit', languageServerOptions);
820+
if (devKitDepsPath.length > 1) {
821+
throw new Error('Expected only one devkit deps path');
822+
}
823+
824+
args.push('--devKitDependencyPath', devKitDepsPath[0]);
826825

827826
args.push('--sessionId', getSessionId());
827+
828+
// Also include the Xaml Dev Kit extensions, if enabled.
829+
if (languageServerOptions.enableXamlToolsPreview) {
830+
getComponentPaths('xamlTools', languageServerOptions).forEach((path) =>
831+
additionalExtensionPaths.push(path)
832+
);
833+
}
828834
return args;
829835
}
830836

src/main.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ import { RoslynLanguageServerEvents } from './lsptoolshost/languageServerEvents'
5656
import { ServerStateChange } from './lsptoolshost/serverStateChange';
5757
import { SolutionSnapshotProvider } from './lsptoolshost/services/solutionSnapshotProvider';
5858
import { RazorTelemetryDownloader } from './razor/razorTelemetryDownloader';
59-
import { commonOptions, omnisharpOptions, razorOptions } from './shared/options';
59+
import { commonOptions, languageServerOptions, omnisharpOptions, razorOptions } from './shared/options';
6060
import { BuildResultDiagnostics } from './lsptoolshost/services/buildResultReporterService';
6161
import { debugSessionTracker } from './coreclrDebug/provisionalDebugSessionTracker';
62+
import { getComponentFolder } from './lsptoolshost/builtInComponents';
6263

6364
export async function activate(
6465
context: vscode.ExtensionContext
@@ -367,6 +368,9 @@ export async function activate(
367368
sendServerRequest: async (t, p, ct) => await languageServerExport.sendRequest(t, p, ct),
368369
languageServerEvents: roslynLanguageServerEvents,
369370
},
371+
getComponentFolder: (componentName) => {
372+
return getComponentFolder(componentName, languageServerOptions);
373+
},
370374
};
371375
} else {
372376
return {

src/shared/options.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ export interface LanguageServerOptions {
7777
readonly crashDumpPath: string | undefined;
7878
readonly analyzerDiagnosticScope: string;
7979
readonly compilerDiagnosticScope: string;
80+
readonly componentPaths: { [key: string]: string } | null;
81+
readonly enableXamlToolsPreview: boolean;
8082
readonly suppressLspErrorToasts: boolean;
8183
}
8284

@@ -398,6 +400,12 @@ class LanguageServerOptionsImpl implements LanguageServerOptions {
398400
public get compilerDiagnosticScope() {
399401
return readOption<string>('dotnet.backgroundAnalysis.compilerDiagnosticsScope', 'openFiles');
400402
}
403+
public get componentPaths() {
404+
return readOption<{ [key: string]: string }>('dotnet.server.componentPaths', {});
405+
}
406+
public get enableXamlToolsPreview() {
407+
return readOption<boolean>('dotnet.enableXamlToolsPreview', true);
408+
}
401409
public get suppressLspErrorToasts() {
402410
return readOption<boolean>('dotnet.server.suppressLspErrorToasts', false);
403411
}
@@ -494,4 +502,6 @@ export const LanguageServerOptionsThatTriggerReload: ReadonlyArray<keyof Languag
494502
'logLevel',
495503
'documentSelector',
496504
'preferCSharpExtension',
505+
'componentPaths',
506+
'enableXamlToolsPreview',
497507
];

0 commit comments

Comments
 (0)