Skip to content

Commit 6922fb5

Browse files
jasonmalinowskidibarbetarunchndr
authored
Tell the language server to open projects if no solution exists (#6062)
* Tell the language server to open projects if no solution exists Fixes #5923 * Move openSolutionParams and openProjectParams into roslynProtocol.ts * update server --------- Co-authored-by: David Barbet <[email protected]> Co-authored-by: Arun Chander <[email protected]>
1 parent 8dc2b9c commit 6922fb5

File tree

4 files changed

+66
-27
lines changed

4 files changed

+66
-27
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
}
3737
},
3838
"defaults": {
39-
"roslyn": "4.8.0-1.23407.6",
39+
"roslyn": "4.8.0-1.23407.9",
4040
"omniSharp": "1.39.7",
4141
"razor": "7.0.0-preview.23405.1",
4242
"razorOmnisharp": "7.0.0-preview.23363.1"

src/lsptoolshost/openSolutionParams.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/lsptoolshost/roslynLanguageServer.ts

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ import ShowInformationMessage from '../shared/observers/utils/showInformationMes
4949
import EventEmitter = require('events');
5050
import Disposable from '../disposable';
5151
import * as RoslynProtocol from './roslynProtocol';
52-
import { OpenSolutionParams } from './openSolutionParams';
5352
import { CSharpDevKitExports } from '../csharpDevKitExports';
5453
import { ISolutionSnapshotProvider, SolutionSnapshotId } from './services/ISolutionSnapshotProvider';
5554
import { Options } from '../shared/options';
@@ -115,6 +114,9 @@ export class RoslynLanguageServer {
115114
*/
116115
private _solutionFile: vscode.Uri | undefined;
117116

117+
/** The project files previously opened; we hold onto this for the same reason as _solutionFile. */
118+
private _projectFiles: vscode.Uri[] = new Array<vscode.Uri>();
119+
118120
constructor(
119121
private platformInfo: PlatformInformation,
120122
private hostExecutableResolver: IHostExecutableResolver,
@@ -182,10 +184,10 @@ export class RoslynLanguageServer {
182184
this._languageClient.onDidChangeState(async (state) => {
183185
if (state.newState === State.Running) {
184186
await this._languageClient!.setTrace(languageClientTraceLevel);
185-
if (this._solutionFile) {
186-
await this.sendOpenSolutionNotification();
187+
if (this._solutionFile || this._projectFiles.length > 0) {
188+
await this.sendOpenSolutionAndProjectsNotifications();
187189
} else {
188-
await this.openDefaultSolution();
190+
await this.openDefaultSolutionOrProjects();
189191
}
190192
await this.sendOrSubscribeForServiceBrokerConnection();
191193
this._eventBus.emit(RoslynLanguageServer.serverStateChangeEvent, ServerStateChange.Started);
@@ -372,21 +374,37 @@ export class RoslynLanguageServer {
372374

373375
public async openSolution(solutionFile: vscode.Uri): Promise<void> {
374376
this._solutionFile = solutionFile;
375-
await this.sendOpenSolutionNotification();
377+
this._projectFiles = [];
378+
await this.sendOpenSolutionAndProjectsNotifications();
376379
}
377380

378-
private async sendOpenSolutionNotification(): Promise<void> {
379-
if (
380-
this._solutionFile !== undefined &&
381-
this._languageClient !== undefined &&
382-
this._languageClient.isRunning()
383-
) {
384-
const protocolUri = this._languageClient.clientOptions.uriConverters!.code2Protocol(this._solutionFile);
385-
await this._languageClient.sendNotification('solution/open', new OpenSolutionParams(protocolUri));
381+
public async openProjects(projectFiles: vscode.Uri[]): Promise<void> {
382+
this._solutionFile = undefined;
383+
this._projectFiles = projectFiles;
384+
await this.sendOpenSolutionAndProjectsNotifications();
385+
}
386+
387+
private async sendOpenSolutionAndProjectsNotifications(): Promise<void> {
388+
if (this._languageClient !== undefined && this._languageClient.isRunning()) {
389+
if (this._solutionFile !== undefined) {
390+
const protocolUri = this._languageClient.clientOptions.uriConverters!.code2Protocol(this._solutionFile);
391+
await this._languageClient.sendNotification(RoslynProtocol.OpenSolutionNotification.type, {
392+
solution: protocolUri,
393+
});
394+
}
395+
396+
if (this._projectFiles.length > 0) {
397+
const projectProtocolUris = this._projectFiles.map((uri) =>
398+
this._languageClient!.clientOptions.uriConverters!.code2Protocol(uri)
399+
);
400+
await this._languageClient.sendNotification(RoslynProtocol.OpenProjectNotification.type, {
401+
projects: projectProtocolUris,
402+
});
403+
}
386404
}
387405
}
388406

389-
private async openDefaultSolution(): Promise<void> {
407+
private async openDefaultSolutionOrProjects(): Promise<void> {
390408
const options = this.optionProvider.GetLatestOptions();
391409

392410
// If Dev Kit isn't installed, then we are responsible for picking the solution to open, assuming the user hasn't explicitly
@@ -401,8 +419,19 @@ export class RoslynLanguageServer {
401419
} else {
402420
// Auto open if there is just one solution target; if there's more the one we'll just let the user pick with the picker.
403421
const solutionUris = await vscode.workspace.findFiles('**/*.sln', '**/node_modules/**', 2);
404-
if (solutionUris && solutionUris.length === 1) {
405-
this.openSolution(solutionUris[0]);
422+
if (solutionUris) {
423+
if (solutionUris.length === 1) {
424+
this.openSolution(solutionUris[0]);
425+
} else if (solutionUris.length === 0) {
426+
// We have no solutions, so we'll enumerate what project files we have and just use those.
427+
const projectUris = await vscode.workspace.findFiles(
428+
'**/*.csproj',
429+
'**/node_modules/**',
430+
options.omnisharpOptions.maxProjectResults
431+
);
432+
433+
this.openProjects(projectUris);
434+
}
406435
}
407436
}
408437
}

src/lsptoolshost/roslynProtocol.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ export interface DebugAttachResult {
117117
didAttach: boolean;
118118
}
119119

120+
export interface OpenSolutionParams {
121+
solution: lsp.DocumentUri;
122+
}
123+
124+
export interface OpenProjectParams {
125+
projects: lsp.DocumentUri[];
126+
}
127+
120128
export interface ShowToastNotificationParams {
121129
messageType: lsp.MessageType;
122130
message: string;
@@ -172,3 +180,15 @@ export namespace DebugAttachRequest {
172180
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.serverToClient;
173181
export const type = new lsp.RequestType<DebugAttachParams, DebugAttachResult, void>(method);
174182
}
183+
184+
export namespace OpenSolutionNotification {
185+
export const method = 'solution/open';
186+
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
187+
export const type = new lsp.NotificationType<OpenSolutionParams>(method);
188+
}
189+
190+
export namespace OpenProjectNotification {
191+
export const method = 'project/open';
192+
export const messageDirection: lsp.MessageDirection = lsp.MessageDirection.clientToServer;
193+
export const type = new lsp.NotificationType<OpenProjectParams>(method);
194+
}

0 commit comments

Comments
 (0)