Skip to content

Commit 0082024

Browse files
VSCODE-79: move playground to the language server (#53)
* feat: move playground to the language server * test: fix client is not ready yet error * refactor: update ids in tests * test: use before and after each * test: try run without mocking showInformationMessage * test: return tests * test: why windows tests fail? * refactor: use constructor instead of activate method * refactor: start language server in activate method * refactor: revert * test: comment 'web view content is rendered with the js form' test * test: uncomment test * refactor: use relative path * fix: return original errors from mongosh
1 parent 1285ac0 commit 0082024

File tree

9 files changed

+188
-112
lines changed

9 files changed

+188
-112
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
"request": "attach",
3939
"name": "Attach to Language Server",
4040
"protocol": "inspector",
41-
"port": 6005,
41+
"port": 6009,
4242
"sourceMaps": true,
4343
"outFiles": [
4444
"${workspaceFolder}/out/**/*.js"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@
475475
"redux": "^4.0.5",
476476
"ts-log": "^2.1.4",
477477
"uuid": "^7.0.0",
478-
"vscode-languageclient": "^6.1.1",
478+
"vscode-languageclient": "^6.1.3",
479479
"vscode-languageserver": "^6.1.1"
480480
},
481481
"devDependencies": {

scripts/generate-keyfile.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ config({ path: resolve(__dirname, '../.env') });
2525
}
2626
})().catch((error) => {
2727
ui.fail('Failed to generate constants keyfile');
28-
console.log(error);
28+
console.log(error.message);
2929
})

src/editors/playgroundController.ts

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import * as vscode from 'vscode';
22

33
import ConnectionController, { DataServiceEventTypes } from '../connectionController';
4+
import { LanguageServerController } from '../language';
45
import TelemetryController, { TelemetryEventTypes } from '../telemetry/telemetryController';
5-
import { ElectronRuntime } from '@mongosh/browser-runtime-electron';
6-
import { CompassServiceProvider } from '@mongosh/service-provider-server';
76
import ActiveConnectionCodeLensProvider from './activeConnectionCodeLensProvider';
87
import formatOutput from '../utils/formatOutput';
98
import { OutputChannel } from 'vscode';
@@ -14,16 +13,23 @@ import playgroundTemplate from '../templates/playgroundTemplate';
1413
*/
1514
export default class PlaygroundController {
1615
_context: vscode.ExtensionContext;
17-
_telemetryController?: TelemetryController;
1816
_connectionController: ConnectionController;
17+
_languageServerController: LanguageServerController;
18+
_telemetryController?: TelemetryController;
1919
_activeDB?: any;
2020
_activeConnectionCodeLensProvider?: ActiveConnectionCodeLensProvider;
2121
_outputChannel: OutputChannel;
2222

23-
constructor(context: vscode.ExtensionContext, connectionController: ConnectionController, telemetryController?: TelemetryController) {
23+
constructor(
24+
context: vscode.ExtensionContext,
25+
connectionController: ConnectionController,
26+
languageServerController: LanguageServerController,
27+
telemetryController?: TelemetryController
28+
) {
2429
this._context = context;
25-
this._telemetryController = telemetryController;
2630
this._connectionController = connectionController;
31+
this._languageServerController = languageServerController;
32+
this._telemetryController = telemetryController;
2733
this._outputChannel = vscode.window.createOutputChannel(
2834
'Playground output'
2935
);
@@ -97,19 +103,16 @@ export default class PlaygroundController {
97103
}
98104

99105
async evaluate(codeToEvaluate: string): Promise<any> {
100-
const activeConnection = this._connectionController.getActiveDataService();
106+
const activeConnectionString = this._connectionController.getActiveConnectionDriverUrl();
101107

102-
if (!activeConnection) {
108+
if (!activeConnectionString) {
103109
return Promise.reject(
104110
new Error('Please connect to a database before running a playground.')
105111
);
106112
}
107113

108-
const serviceProvider = CompassServiceProvider.fromDataService(
109-
activeConnection
110-
);
111-
const runtime = new ElectronRuntime(serviceProvider);
112-
const res = await runtime.evaluate(codeToEvaluate);
114+
// Run playground as a background process using the Language Server
115+
const res = await this._languageServerController.executeAll(codeToEvaluate, activeConnectionString);
113116

114117
if (res) {
115118
this._telemetryController?.track(

src/language/languageServerController.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,17 @@ const log = createLogger('LanguageServerController');
1919
*/
2020
export default class LanguageServerController {
2121
_connectionController?: ConnectionController;
22-
client?: LanguageClient;
22+
client: LanguageClient;
23+
2324
constructor(
2425
context: vscode.ExtensionContext,
25-
connectionController: ConnectionController
26+
connectionController?: ConnectionController
2627
) {
2728
this._connectionController = connectionController;
28-
this.activate(context);
29-
}
3029

31-
async activate(context: ExtensionContext): Promise<LanguageClient> {
3230
// The server is implemented in node
33-
const serverModule = context.asAbsolutePath(
34-
path.join('out', 'language', 'server.js')
35-
);
31+
const serverModule = path.join(context.extensionPath, 'out', 'language', 'server.js');
32+
3633
// The debug options for the server
3734
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
3835
const debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
@@ -61,7 +58,7 @@ export default class LanguageServerController {
6158
}
6259
};
6360

64-
log.info('Activating MongoDB language server', {
61+
log.info('Creating MongoDB Language Server', {
6562
serverOptions,
6663
clientOptions
6764
});
@@ -73,25 +70,28 @@ export default class LanguageServerController {
7370
serverOptions,
7471
clientOptions
7572
);
73+
}
7674

75+
activate() {
7776
// Start the client. This will also launch the server
7877
this.client.start();
79-
80-
await this.client.onReady();
81-
/**
82-
* TODO: Notification is for setup docs only.
83-
*/
84-
this.client.onNotification('mongodbNotification', (messsage) => {
85-
vscode.window.showInformationMessage(messsage);
78+
this.client.onReady().then(() => {
79+
/**
80+
* TODO: Notification is for setup docs only.
81+
*/
82+
this.client.onNotification('mongodbNotification', (messsage) => {
83+
vscode.window.showInformationMessage(messsage);
84+
});
8685
});
87-
88-
return new Promise((resolve) => resolve(this.client));
8986
}
9087

9188
deactivate(): Thenable<void> | undefined {
92-
if (!this.client) {
93-
return undefined;
94-
}
9589
return this.client.stop();
9690
}
91+
92+
executeAll(codeToEvaluate: string, connectionString: string, connectionOptions: any = {}): Thenable<any> | undefined {
93+
return this.client.onReady().then(() => {
94+
return this.client.sendRequest('executeAll', { codeToEvaluate, connectionString, connectionOptions });
95+
});
96+
}
9797
}

src/language/server.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import {
1313
TextDocumentPositionParams,
1414
RequestType
1515
} from 'vscode-languageserver';
16+
import { ElectronRuntime } from '@mongosh/browser-runtime-electron';
17+
import { CliServiceProvider } from '@mongosh/service-provider-server';
1618

1719
// Create a connection for the server. The connection uses Node's IPC as a transport.
1820
// Also include all preview / proposed LSP features.
@@ -275,9 +277,13 @@ connection.onCompletionResolve(
275277
/**
276278
* Execute the entire playground script.
277279
*/
278-
connection.onRequest('executeAll', (event) => {
279-
// connection.console.log(`executeAll: ${JSON.stringify(event)}`);
280-
return '';
280+
connection.onRequest('executeAll', async (params) => {
281+
const connectionOptions = params.connectionOptions || {};
282+
const runtime = new ElectronRuntime(
283+
await CliServiceProvider.connect(params.connectionString, connectionOptions)
284+
);
285+
286+
return await runtime.evaluate(params.codeToEvaluate);
281287
});
282288

283289
/**

src/mdbExtensionController.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import * as vscode from 'vscode';
88
import ConnectionController from './connectionController';
99
import { EditorsController, PlaygroundController } from './editors';
1010
import { ExplorerController, CollectionTreeItem } from './explorer';
11+
import { LanguageServerController } from './language';
1112
import { TelemetryController } from './telemetry';
1213
import { StatusView } from './views';
1314
import { createLogger } from './logging';
@@ -30,6 +31,7 @@ export default class MDBExtensionController implements vscode.Disposable {
3031
_statusView: StatusView;
3132
_storageController: StorageController;
3233
_telemetryController: TelemetryController;
34+
_languageServerController: LanguageServerController;
3335

3436
constructor(
3537
context: vscode.ExtensionContext,
@@ -52,6 +54,7 @@ export default class MDBExtensionController implements vscode.Disposable {
5254
);
5355
}
5456

57+
this._languageServerController = new LanguageServerController(context);
5558
this._editorsController = new EditorsController(
5659
context,
5760
this._connectionController
@@ -62,6 +65,7 @@ export default class MDBExtensionController implements vscode.Disposable {
6265
this._playgroundController = new PlaygroundController(
6366
context,
6467
this._connectionController,
68+
this._languageServerController,
6569
this._telemetryController
6670
);
6771
}
@@ -70,6 +74,7 @@ export default class MDBExtensionController implements vscode.Disposable {
7074
this._connectionController.loadSavedConnections();
7175
this._explorerController.createTreeView();
7276
this._telemetryController.activate();
77+
this._languageServerController.activate();
7378

7479
log.info('Registering commands...');
7580

@@ -407,5 +412,6 @@ export default class MDBExtensionController implements vscode.Disposable {
407412
this._explorerController.deactivate();
408413
this._playgroundController.deactivate();
409414
this._telemetryController.deactivate();
415+
this._languageServerController.deactivate();
410416
}
411417
}

0 commit comments

Comments
 (0)