Skip to content

Commit

Permalink
Include Roslyn devkit dependencies in C# extension to avoid versionin…
Browse files Browse the repository at this point in the history
…g issues with devkit
  • Loading branch information
dibarbet committed Nov 17, 2023
1 parent 1755b7b commit 577735a
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 36 deletions.
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.23563.2",
"roslyn": "4.9.0-dev",
"omniSharp": "1.39.10",
"razor": "7.0.0-preview.23528.1",
"razorOmnisharp": "7.0.0-preview.23363.1",
Expand Down
34 changes: 10 additions & 24 deletions src/lsptoolshost/roslynLanguageServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ export class RoslynLanguageServer {
_channel.appendLine('Activating C# + C# Dev Kit...');
}

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

await this.setupDevKitEnvironment(env, csharpDevkitExtension);
Expand Down Expand Up @@ -755,24 +755,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 @@ -804,13 +797,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

0 comments on commit 577735a

Please sign in to comment.