Skip to content

Commit 1f84e72

Browse files
authored
Merge pull request #7039 from dibarbet/package_xaml_content
Package xaml content
2 parents 3d33d80 + 7cbc4fc commit 1f84e72

File tree

10 files changed

+216
-104
lines changed

10 files changed

+216
-104
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: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
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.34816.20"
4546
},
4647
"main": "./dist/extension",
4748
"l10n": "./l10n",
@@ -1621,6 +1622,21 @@
16211622
"scope": "machine-overridable",
16221623
"description": "%configuration.dotnet.server.path%"
16231624
},
1625+
"dotnet.server.componentPaths": {
1626+
"type": "object",
1627+
"description": "%configuration.dotnet.server.componentPaths%",
1628+
"properties": {
1629+
"roslynDevKit": {
1630+
"description": "%configuration.dotnet.server.componentPaths.roslynDevKit%",
1631+
"type": "string"
1632+
},
1633+
"xamlTools": {
1634+
"description": "%configuration.dotnet.server.componentPaths.xamlTools%",
1635+
"type": "string"
1636+
}
1637+
},
1638+
"default": {}
1639+
},
16241640
"dotnet.server.startTimeout": {
16251641
"type": "number",
16261642
"scope": "machine-overridable",
@@ -1666,6 +1682,12 @@
16661682
"default": null,
16671683
"description": "%configuration.dotnet.server.crashDumpPath%"
16681684
},
1685+
"dotnet.enableXamlToolsPreview": {
1686+
"scope": "machine-overridable",
1687+
"type": "boolean",
1688+
"default": false,
1689+
"description": "%configuration.dotnet.enableXamlToolsPreview%"
1690+
},
16691691
"dotnet.projects.binaryLogPath": {
16701692
"scope": "machine-overridable",
16711693
"type": "string",

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.projects.enableAutomaticRestore": "Enables automatic NuGet restore if the extension detects assets are missing.",
3539
"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)",
3640
"configuration.dotnet.implementType.insertionBehavior": "The insertion location of properties, events, and methods When implement interface or abstract class.",

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

6667
let _channel: vscode.OutputChannel;
6768
let _traceChannel: vscode.OutputChannel;
@@ -506,10 +507,6 @@ export class RoslynLanguageServer {
506507
args.push('--logLevel', logLevel);
507508
}
508509

509-
for (const extensionPath of additionalExtensionPaths) {
510-
args.push('--extension', extensionPath);
511-
}
512-
513510
args.push(
514511
'--razorSourceGenerator',
515512
path.join(context.extension.extensionPath, '.razor', 'Microsoft.CodeAnalysis.Razor.Compiler.dll')
@@ -540,7 +537,7 @@ export class RoslynLanguageServer {
540537
// Set command enablement as soon as we know devkit is available.
541538
vscode.commands.executeCommand('setContext', 'dotnet.server.activationContext', 'RoslynDevKit');
542539

543-
const csharpDevKitArgs = this.getCSharpDevKitExportArgs();
540+
const csharpDevKitArgs = this.getCSharpDevKitExportArgs(additionalExtensionPaths);
544541
args = args.concat(csharpDevKitArgs);
545542

546543
await this.setupDevKitEnvironment(dotnetInfo.env, csharpDevkitExtension);
@@ -553,6 +550,10 @@ export class RoslynLanguageServer {
553550
_wasActivatedWithCSharpDevkit = false;
554551
}
555552

553+
for (const extensionPath of additionalExtensionPaths) {
554+
args.push('--extension', extensionPath);
555+
}
556+
556557
if (logLevel && [Trace.Messages, Trace.Verbose].includes(this.GetTraceLevel(logLevel))) {
557558
_channel.appendLine(`Starting server at ${serverPath}`);
558559
}
@@ -806,19 +807,24 @@ export class RoslynLanguageServer {
806807
);
807808
}
808809

809-
private static getCSharpDevKitExportArgs(): string[] {
810+
private static getCSharpDevKitExportArgs(additionalExtensionPaths: string[]): string[] {
810811
const args: string[] = [];
811812

812-
const clientRoot = __dirname;
813-
const devKitDepsPath = path.join(
814-
clientRoot,
815-
'..',
816-
'.roslynDevKit',
817-
'Microsoft.VisualStudio.LanguageServices.DevKit.dll'
818-
);
819-
args.push('--devKitDependencyPath', devKitDepsPath);
813+
const devKitDepsPath = getComponentPaths('roslynDevKit', languageServerOptions);
814+
if (devKitDepsPath.length > 1) {
815+
throw new Error('Expected only one devkit deps path');
816+
}
817+
818+
args.push('--devKitDependencyPath', devKitDepsPath[0]);
820819

821820
args.push('--sessionId', getSessionId());
821+
822+
// Also include the Xaml Dev Kit extensions, if enabled.
823+
if (languageServerOptions.enableXamlToolsPreview) {
824+
getComponentPaths('xamlTools', languageServerOptions).forEach((path) =>
825+
additionalExtensionPaths.push(path)
826+
);
827+
}
822828
return args;
823829
}
824830

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
}
8183

8284
export interface RazorOptions {
@@ -397,6 +399,12 @@ class LanguageServerOptionsImpl implements LanguageServerOptions {
397399
public get compilerDiagnosticScope() {
398400
return readOption<string>('dotnet.backgroundAnalysis.compilerDiagnosticsScope', 'openFiles');
399401
}
402+
public get componentPaths() {
403+
return readOption<{ [key: string]: string }>('dotnet.server.componentPaths', {});
404+
}
405+
public get enableXamlToolsPreview() {
406+
return readOption<boolean>('dotnet.enableXamlToolsPreview', false);
407+
}
400408
}
401409

402410
class RazorOptionsImpl implements RazorOptions {
@@ -490,4 +498,6 @@ export const LanguageServerOptionsThatTriggerReload: ReadonlyArray<keyof Languag
490498
'logLevel',
491499
'documentSelector',
492500
'preferCSharpExtension',
501+
'componentPaths',
502+
'enableXamlToolsPreview',
493503
];

0 commit comments

Comments
 (0)