Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include Roslyn devkit dependencies in C# extension to avoid versioning issues with devkit #6681

Merged
merged 3 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ obj
node_modules
out
.roslyn/
.roslynDevKit/
.omnisharp/
.omnisharp-*/
.vs/
Expand Down
1 change: 1 addition & 0 deletions .vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.logs/**
.nyc_output/**
!.roslyn/**
!.roslynDevKit/**
!.omnisharp/**
!.razor/**
!.razoromnisharp/**
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
}
},
"defaults": {
"roslyn": "4.9.0-2.23566.1",
"roslyn": "4.9.0-2.23571.2",
"omniSharp": "1.39.10",
"razor": "7.0.0-preview.23528.1",
"razorOmnisharp": "7.0.0-preview.23363.1",
Expand Down
36 changes: 11 additions & 25 deletions src/lsptoolshost/roslynLanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -510,8 +510,8 @@ export class RoslynLanguageServer {
_channel.appendLine('Activating C# + C# Dev Kit...');
}

const csharpDevkitArgs = await this.getCSharpDevkitExportArgs(csharpDevkitExtension);
args = args.concat(csharpDevkitArgs);
const csharpDevKitArgs = this.getCSharpDevKitExportArgs();
args = args.concat(csharpDevKitArgs);

await this.setupDevKitEnvironment(env, csharpDevkitExtension);
} else {
Expand Down Expand Up @@ -756,24 +756,17 @@ export class RoslynLanguageServer {
);
}

private static async getCSharpDevkitExportArgs(
csharpDevkitExtension: vscode.Extension<CSharpDevKitExports>
): Promise<string[]> {
const exports: CSharpDevKitExports = await csharpDevkitExtension.activate();

const extensionPaths = languageServerOptions.extensionsPaths || [
this.getLanguageServicesDevKitComponentPath(exports),
];

private static getCSharpDevKitExportArgs(): string[] {
const args: string[] = [];

args.push('--sharedDependencies');
args.push(exports.components['@microsoft/visualstudio-server-shared']);

for (const extensionPath of extensionPaths) {
args.push('--extension');
args.push(extensionPath);
}
const clientRoot = __dirname;
const devKitDepsPath = path.join(
clientRoot,
'..',
'.roslynDevKit',
'Microsoft.VisualStudio.LanguageServices.DevKit.dll'
);
args.push('--extension', devKitDepsPath);

args.push('--sessionId', getSessionId());
return args;
Expand Down Expand Up @@ -805,13 +798,6 @@ export class RoslynLanguageServer {
await exports.setupTelemetryEnvironmentAsync(env);
}

private static getLanguageServicesDevKitComponentPath(csharpDevKitExports: CSharpDevKitExports): string {
return path.join(
csharpDevKitExports.components['@microsoft/visualstudio-languageservices-devkit'],
'Microsoft.VisualStudio.LanguageServices.DevKit.dll'
);
}

private static GetTraceLevel(logLevel: string): Trace {
switch (logLevel) {
case 'Trace':
Expand Down
59 changes: 48 additions & 11 deletions tasks/offlinePackagingTasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
languageServerDirectory,
nugetTempPath,
rootPath,
devKitDependenciesDirectory,
} from '../tasks/projectPaths';
import { getPackageJSON } from '../tasks/packageJson';
import { createPackageAsync } from '../tasks/vsceTasks';
Expand Down Expand Up @@ -122,27 +123,46 @@ gulp.task(
for (const p of platformSpecificPackages) {
await acquireRoslyn(packageJSON, p.platformInfo, true);
}

// Also pull in the Roslyn DevKit dependencies nuget package.
await acquireRoslynDevKit(packageJSON, true);
}, 'installDependencies')
);

// Install Tasks
async function installRoslyn(packageJSON: any, platformInfo?: PlatformInformation) {
// Install the Roslyn language server bits.
const { packagePath, serverPlatform } = await acquireRoslyn(packageJSON, platformInfo, false);
await installNuGetPackage(
packagePath,
path.join('content', 'LanguageServer', serverPlatform),
languageServerDirectory
);

// Install Roslyn DevKit dependencies.
const roslynDevKitPackagePath = await acquireRoslynDevKit(packageJSON, false);
await installNuGetPackage(roslynDevKitPackagePath, 'content', devKitDependenciesDirectory);
}

// Get the directory containing the server executable for the current platform.
const serverExecutableDirectory = path.join(packagePath, 'content', 'LanguageServer', serverPlatform);
if (!fs.existsSync(serverExecutableDirectory)) {
throw new Error(`Failed to find server executable directory at ${serverExecutableDirectory}`);
async function installNuGetPackage(pathToPackage: string, contentPath: string, outputPath: string) {
// Get the directory containing the content.
const contentDirectory = path.join(pathToPackage, contentPath);
if (!fs.existsSync(contentDirectory)) {
throw new Error(`Failed to find NuGet package content at ${contentDirectory}`);
}

console.log(`Extracting Roslyn executables from ${serverExecutableDirectory}`);
const numFilesToCopy = fs.readdirSync(contentDirectory).length;

console.log(`Extracting content from ${contentDirectory}`);

// Copy the files to the language server directory.
fs.mkdirSync(languageServerDirectory);
fsextra.copySync(serverExecutableDirectory, languageServerDirectory);
const languageServerDll = path.join(languageServerDirectory, 'Microsoft.CodeAnalysis.LanguageServer.dll');
if (!fs.existsSync(languageServerDll)) {
throw new Error(`Failed to copy server executable`);
fs.mkdirSync(outputPath);
fsextra.copySync(contentDirectory, outputPath);
const numCopiedFiles = fs.readdirSync(outputPath).length;

// Not expected to ever happen, just a simple sanity check.
if (numFilesToCopy !== numCopiedFiles) {
throw new Error('Failed to copy all files from NuGet package');
}
}

Expand Down Expand Up @@ -173,6 +193,16 @@ async function acquireRoslyn(
return { packagePath, serverPlatform };
}

async function acquireRoslynDevKit(packageJSON: any, interactive: boolean): Promise<string> {
const roslynVersion = packageJSON.defaults.roslyn;
const packagePath = await acquireNugetPackage(
`Microsoft.VisualStudio.LanguageServices.DevKit`,
roslynVersion,
interactive
);
return packagePath;
}

async function installRazor(packageJSON: any, platformInfo: PlatformInformation) {
if (platformInfo === undefined) {
const platformNeutral = new PlatformInformation('neutral', 'neutral');
Expand Down Expand Up @@ -297,7 +327,14 @@ async function doPackageOffline(vsixPlatform: VSIXPlatformInfo | undefined) {
}

async function cleanAsync() {
await del(['install.*', '.omnisharp*', '.debugger', '.razor', languageServerDirectory]);
await del([
'install.*',
'.omnisharp*',
'.debugger',
'.razor',
languageServerDirectory,
devKitDependenciesDirectory,
]);
}

async function buildVsix(
Expand Down
1 change: 1 addition & 0 deletions tasks/projectPaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export const jestPath = path.join(nodeModulesPath, 'jest', 'bin', 'jest');
export const packedVsixOutputRoot = commandLineOptions.outputFolder || path.join(rootPath, 'vsix');
export const nugetTempPath = path.join(rootPath, 'out', '.nuget');
export const languageServerDirectory = path.join(rootPath, '.roslyn');
export const devKitDependenciesDirectory = path.join(rootPath, '.roslynDevKit');

export const codeExtensionPath = commandLineOptions.codeExtensionPath || rootPath;

Expand Down
Loading