Skip to content

Commit cb0aaf8

Browse files
committed
Organize LSP Host files into feature folders.
1 parent d121ddd commit cb0aaf8

File tree

66 files changed

+710
-615
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+710
-615
lines changed

l10n/bundle.l10n.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,14 @@
162162
"Text editor must be focused to fix all issues": "Text editor must be focused to fix all issues",
163163
"Fix all issues": "Fix all issues",
164164
"Select fix all action": "Select fix all action",
165+
"C# LSP Trace Logs": "C# LSP Trace Logs",
166+
"Open solution": "Open solution",
167+
"Restart server": "Restart server",
168+
"C# Workspace Status": "C# Workspace Status",
169+
"The active document is not part of the open workspace. Not all language features will be available.": "The active document is not part of the open workspace. Not all language features will be available.",
170+
"Dismiss": "Dismiss",
171+
"Do not show for this workspace": "Do not show for this workspace",
165172
"Test run already in progress": "Test run already in progress",
166-
"Generated document not found": "Generated document not found",
167173
"Server stopped": "Server stopped",
168174
"Workspace projects": "Workspace projects",
169175
"Your workspace has multiple Visual Studio Solution files; please select one to get full IntelliSense.": "Your workspace has multiple Visual Studio Solution files; please select one to get full IntelliSense.",
@@ -174,21 +180,15 @@
174180
"IntelliCode features will not be available, {0} failed to activate.": "IntelliCode features will not be available, {0} failed to activate.",
175181
"Go to output": "Go to output",
176182
"Suppress notification": "Suppress notification",
177-
"C# LSP Trace Logs": "C# LSP Trace Logs",
178183
"Restore {0}": "Restore {0}",
179184
"Restore already in progress": "Restore already in progress",
180185
"Sending request": "Sending request",
186+
"C# Project Context Status": "C# Project Context Status",
187+
"Active File Context": "Active File Context",
181188
"C# configuration has changed. Would you like to reload the window to apply your changes?": "C# configuration has changed. Would you like to reload the window to apply your changes?",
189+
"Generated document not found": "Generated document not found",
182190
"Nested Code Action": "Nested Code Action",
183191
"Fix All: ": "Fix All: ",
184-
"The active document is not part of the open workspace. Not all language features will be available.": "The active document is not part of the open workspace. Not all language features will be available.",
185-
"Dismiss": "Dismiss",
186-
"Do not show for this workspace": "Do not show for this workspace",
187-
"Open solution": "Open solution",
188-
"Restart server": "Restart server",
189-
"C# Workspace Status": "C# Workspace Status",
190-
"C# Project Context Status": "C# Project Context Status",
191-
"Active File Context": "Active File Context",
192192
"Pick a fix all scope": "Pick a fix all scope",
193193
"Fix All Code Action": "Fix All Code Action",
194194
"Failed to set extension directory": "Failed to set extension directory",

src/csharpExtensionExports.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { EventStream } from './eventStream';
99
import TestManager from './omnisharp/features/dotnetTest';
1010
import { GlobalBrokeredServiceContainer } from '@microsoft/servicehub-framework';
1111
import { RequestType } from 'vscode-languageclient/node';
12-
import { LanguageServerEvents } from './lsptoolshost/languageServerEvents';
12+
import { LanguageServerEvents } from './lsptoolshost/server/languageServerEvents';
1313

1414
export interface OmnisharpExtensionExports {
1515
initializationFinished: () => Promise<void>;

src/lsptoolshost/activate.ts

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
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 vscode from 'vscode';
7+
import * as fs from 'fs';
8+
import * as path from 'path';
9+
import { registerCommands } from './commands';
10+
import { registerDebugger } from './debugger/debugger';
11+
import { PlatformInformation } from '../shared/platform';
12+
import TelemetryReporter from '@vscode/extension-telemetry';
13+
import { getCSharpDevKit } from '../utils/getCSharpDevKit';
14+
import { DotnetRuntimeExtensionResolver } from './dotnetRuntime/dotnetRuntimeExtensionResolver';
15+
import { registerUnitTestingCommands } from './testing/unitTesting';
16+
import { registerLanguageServerOptionChanges } from './options/optionChanges';
17+
import { Observable } from 'rxjs';
18+
import { RoslynLanguageServerEvents } from './server/languageServerEvents';
19+
import { registerRazorCommands } from './razor/razorCommands';
20+
import { registerCodeActionFixAllCommands } from './diagnostics/fixAllCodeAction';
21+
import { commonOptions, languageServerOptions } from '../shared/options';
22+
import { registerNestedCodeActionCommands } from './diagnostics/nestedCodeAction';
23+
import { registerRestoreCommands } from './projectRestore/restore';
24+
import { registerCopilotExtension } from './copilot/copilot';
25+
import { registerSourceGeneratedFilesContentProvider } from './generators/sourceGeneratedFilesContentProvider';
26+
import { registerMiscellaneousFileNotifier } from './workspace/miscellaneousFileNotifier';
27+
import { TelemetryEventNames } from '../shared/telemetryEventNames';
28+
import { WorkspaceStatus } from './workspace/workspaceStatus';
29+
import { ProjectContextStatus } from './projectContext/projectContextStatus';
30+
import { RoslynLanguageServer } from './server/roslynLanguageServer';
31+
32+
let _channel: vscode.LogOutputChannel;
33+
let _traceChannel: vscode.OutputChannel;
34+
35+
/**
36+
* Creates and activates the Roslyn language server.
37+
* The returned promise will complete when the server starts.
38+
*/
39+
export async function activateRoslynLanguageServer(
40+
context: vscode.ExtensionContext,
41+
platformInfo: PlatformInformation,
42+
optionObservable: Observable<void>,
43+
outputChannel: vscode.LogOutputChannel,
44+
reporter: TelemetryReporter,
45+
languageServerEvents: RoslynLanguageServerEvents
46+
): Promise<RoslynLanguageServer> {
47+
// Create a channel for outputting general logs from the language server.
48+
_channel = outputChannel;
49+
// Create a separate channel for outputting trace logs - these are incredibly verbose and make other logs very difficult to see.
50+
// The trace channel verbosity is controlled by the _channel verbosity.
51+
_traceChannel = vscode.window.createOutputChannel(vscode.l10n.t('C# LSP Trace Logs'));
52+
53+
reporter.sendTelemetryEvent(TelemetryEventNames.ClientInitialize);
54+
55+
const hostExecutableResolver = new DotnetRuntimeExtensionResolver(
56+
platformInfo,
57+
getServerPath,
58+
outputChannel,
59+
context.extensionPath
60+
);
61+
const additionalExtensionPaths = scanExtensionPlugins();
62+
63+
const languageServer = await RoslynLanguageServer.initializeAsync(
64+
platformInfo,
65+
hostExecutableResolver,
66+
context,
67+
reporter,
68+
additionalExtensionPaths,
69+
languageServerEvents,
70+
_channel,
71+
_traceChannel
72+
);
73+
74+
registerLanguageStatusItems(context, languageServer, languageServerEvents);
75+
registerMiscellaneousFileNotifier(context, languageServer);
76+
registerCopilotExtension(languageServer, _channel);
77+
78+
// Register any commands that need to be handled by the extension.
79+
registerCommands(context, languageServer, hostExecutableResolver, _channel);
80+
registerNestedCodeActionCommands(context, languageServer, _channel);
81+
registerCodeActionFixAllCommands(context, languageServer, _channel);
82+
83+
registerRazorCommands(context, languageServer);
84+
85+
registerUnitTestingCommands(context, languageServer);
86+
87+
// Register any needed debugger components that need to communicate with the language server.
88+
registerDebugger(context, languageServer, languageServerEvents, platformInfo, _channel);
89+
90+
registerRestoreCommands(context, languageServer);
91+
92+
registerSourceGeneratedFilesContentProvider(context, languageServer);
93+
94+
context.subscriptions.push(registerLanguageServerOptionChanges(optionObservable));
95+
96+
return languageServer;
97+
98+
function scanExtensionPlugins(): string[] {
99+
const extensionsFromPackageJson = vscode.extensions.all.flatMap((extension) => {
100+
let loadPaths = extension.packageJSON.contributes?.['csharpExtensionLoadPaths'];
101+
if (loadPaths === undefined || loadPaths === null) {
102+
_channel.debug(`Extension ${extension.id} does not contribute csharpExtensionLoadPaths`);
103+
return [];
104+
}
105+
106+
if (!Array.isArray(loadPaths) || loadPaths.some((loadPath) => typeof loadPath !== 'string')) {
107+
_channel.warn(
108+
`Extension ${extension.id} has invalid csharpExtensionLoadPaths. Expected string array, found ${loadPaths}`
109+
);
110+
return [];
111+
}
112+
113+
loadPaths = loadPaths.map((loadPath) => path.join(extension.extensionPath, loadPath));
114+
_channel.trace(`Extension ${extension.id} contributes csharpExtensionLoadPaths: ${loadPaths}`);
115+
return loadPaths;
116+
});
117+
const extensionsFromOptions = languageServerOptions.extensionsPaths ?? [];
118+
return extensionsFromPackageJson.concat(extensionsFromOptions);
119+
}
120+
}
121+
122+
function registerLanguageStatusItems(
123+
context: vscode.ExtensionContext,
124+
languageServer: RoslynLanguageServer,
125+
languageServerEvents: RoslynLanguageServerEvents
126+
) {
127+
// DevKit will provide an equivalent workspace status item.
128+
if (!getCSharpDevKit()) {
129+
WorkspaceStatus.createStatusItem(context, languageServerEvents);
130+
}
131+
ProjectContextStatus.createStatusItem(context, languageServer);
132+
}
133+
134+
export function getServerPath(platformInfo: PlatformInformation) {
135+
let serverPath = process.env.DOTNET_ROSLYN_SERVER_PATH;
136+
137+
if (serverPath) {
138+
_channel.appendLine(`Using server path override from DOTNET_ROSLYN_SERVER_PATH: ${serverPath}`);
139+
} else {
140+
serverPath = commonOptions.serverPath;
141+
if (!serverPath) {
142+
// Option not set, use the path from the extension.
143+
serverPath = getInstalledServerPath(platformInfo);
144+
}
145+
}
146+
147+
if (!fs.existsSync(serverPath)) {
148+
throw new Error(`Cannot find language server in path '${serverPath}'`);
149+
}
150+
151+
return serverPath;
152+
}
153+
154+
function getInstalledServerPath(platformInfo: PlatformInformation): string {
155+
const clientRoot = __dirname;
156+
const serverFilePath = path.join(clientRoot, '..', '.roslyn', 'Microsoft.CodeAnalysis.LanguageServer');
157+
158+
let extension = '';
159+
if (platformInfo.isWindows()) {
160+
extension = '.exe';
161+
} else if (platformInfo.isMacOS()) {
162+
// MacOS executables must be signed with codesign. Currently all Roslyn server executables are built on windows
163+
// and therefore dotnet publish does not automatically sign them.
164+
// Tracking bug - https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1767519/
165+
extension = '.dll';
166+
}
167+
168+
let pathWithExtension = `${serverFilePath}${extension}`;
169+
if (!fs.existsSync(pathWithExtension)) {
170+
// We might be running a platform neutral vsix which has no executable, instead we run the dll directly.
171+
pathWithExtension = `${serverFilePath}.dll`;
172+
}
173+
174+
return pathWithExtension;
175+
}

src/lsptoolshost/onAutoInsert.ts renamed to src/lsptoolshost/autoInsert/onAutoInsert.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import * as vscode from 'vscode';
77

88
import { FormattingOptions, LanguageClient, TextDocumentIdentifier } from 'vscode-languageclient/node';
9-
import * as RoslynProtocol from './roslynProtocol';
10-
import { RoslynLanguageServer } from './roslynLanguageServer';
9+
import * as RoslynProtocol from '../server/roslynProtocol';
10+
import { RoslynLanguageServer } from '../server/roslynLanguageServer';
1111

1212
export function registerOnAutoInsert(languageServer: RoslynLanguageServer, languageClient: LanguageClient) {
1313
let source = new vscode.CancellationTokenSource();

src/lsptoolshost/onAutoInsertFeature.ts renamed to src/lsptoolshost/autoInsert/onAutoInsertFeature.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
ServerCapabilities,
2222
} from 'vscode-languageserver-protocol';
2323

24-
import * as RoslynProtocol from './roslynProtocol';
24+
import * as RoslynProtocol from '../server/roslynProtocol';
2525
import { generateUuid } from 'vscode-languageclient/lib/common/utils/uuid';
2626

2727
export class OnAutoInsertFeature implements DynamicFeature<RoslynProtocol.OnAutoInsertRegistrationOptions> {

0 commit comments

Comments
 (0)