Skip to content

Commit 3393e96

Browse files
committed
Allow option overrides for components and export function to get component paths from extension
1 parent 3697383 commit 3393e96

File tree

8 files changed

+100
-17
lines changed

8 files changed

+100
-17
lines changed

package.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"razor": "7.0.0-preview.24178.4",
4343
"razorOmnisharp": "7.0.0-preview.23363.1",
4444
"razorTelemetry": "7.0.0-preview.24178.4",
45-
"xamlDesignTools": "17.11.34810.23"
45+
"xamlDesignTools": "17.11.34811.206"
4646
},
4747
"main": "./dist/extension",
4848
"l10n": "./l10n",
@@ -1622,6 +1622,21 @@
16221622
"scope": "machine-overridable",
16231623
"description": "%configuration.dotnet.server.path%"
16241624
},
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+
"xamlDesignTools": {
1634+
"description": "%configuration.dotnet.server.componentPaths.xamlDesignTools%",
1635+
"type": "string"
1636+
}
1637+
},
1638+
"default": {}
1639+
},
16251640
"dotnet.server.startTimeout": {
16261641
"type": "number",
16271642
"scope": "machine-overridable",

package.nls.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
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.xamlDesignTools": "Overrides the folder path for the .xamlDesignTools 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",

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+
xamlDesignTools: {
23+
defaultFolderName: '.xamlDesignTools',
24+
optionName: 'xamlDesignTools',
25+
componentDllPaths: [
26+
path.join('lib', 'netstandard2.0', 'Microsoft.VisualStudio.DesignTools.CodeAnalysis.dll'),
27+
path.join('lib', 'netstandard2.0', '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: 9 additions & 13 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;
@@ -809,24 +810,19 @@ export class RoslynLanguageServer {
809810
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());
822821

823822
// Also include the Xaml Dev Kit extensions
824-
const xamlBasePath = path.join(clientRoot, '..', '.xamlDesignTools', 'lib', 'netstandard2.0');
825-
additionalExtensionPaths.push(path.join(xamlBasePath, 'Microsoft.VisualStudio.DesignTools.CodeAnalysis.dll'));
826-
additionalExtensionPaths.push(
827-
path.join(xamlBasePath, 'Microsoft.VisualStudio.DesignTools.CodeAnalysis.Diagnostics.dll')
823+
getComponentPaths('xamlDesignTools', languageServerOptions).forEach((path) =>
824+
additionalExtensionPaths.push(path)
828825
);
829-
830826
return args;
831827
}
832828

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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ export interface LanguageServerOptions {
7777
readonly crashDumpPath: string | undefined;
7878
readonly analyzerDiagnosticScope: string;
7979
readonly compilerDiagnosticScope: string;
80+
readonly componentPaths: { [key: string]: string } | null;
8081
}
8182

8283
export interface RazorOptions {
@@ -397,6 +398,9 @@ class LanguageServerOptionsImpl implements LanguageServerOptions {
397398
public get compilerDiagnosticScope() {
398399
return readOption<string>('dotnet.backgroundAnalysis.compilerDiagnosticsScope', 'openFiles');
399400
}
401+
public get componentPaths() {
402+
return readOption<{ [key: string]: string }>('dotnet.server.componentPaths', {});
403+
}
400404
}
401405

402406
class RazorOptionsImpl implements RazorOptions {

tasks/projectPaths.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import * as path from 'path';
77
import { commandLineOptions } from './commandLineArguments';
8+
import { componentInfo } from '../src/lsptoolshost/builtInComponents';
89

910
export const rootPath = path.resolve(__dirname, '..');
1011

@@ -15,8 +16,8 @@ export const jestPath = path.join(nodeModulesPath, 'jest', 'bin', 'jest');
1516
export const packedVsixOutputRoot = commandLineOptions.outputFolder || path.join(rootPath, 'vsix');
1617
export const nugetTempPath = path.join(rootPath, 'out', '.nuget');
1718
export const languageServerDirectory = path.join(rootPath, '.roslyn');
18-
export const devKitDependenciesDirectory = path.join(rootPath, '.roslynDevKit');
19-
export const xamlDesignToolsDirectory = path.join(rootPath, '.xamlDesignTools');
19+
export const devKitDependenciesDirectory = path.join(rootPath, componentInfo.roslynDevKit.defaultFolderName);
20+
export const xamlDesignToolsDirectory = path.join(rootPath, componentInfo.xamlDesignTools.defaultFolderName);
2021

2122
export const codeExtensionPath = commandLineOptions.codeExtensionPath || rootPath;
2223

0 commit comments

Comments
 (0)