Skip to content

Commit a5ac5f8

Browse files
author
automatic-merge
committed
Merge remote branch 'origin/master' into edge
2 parents f6d7795 + c1c9412 commit a5ac5f8

File tree

13 files changed

+161
-149
lines changed

13 files changed

+161
-149
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import * as vscode from 'vscode';
2+
import { Disposable, LanguageClient } from 'vscode-languageclient/node';
3+
import { createClient } from './clients';
4+
import GnatTaskProvider from './gnatTaskProvider';
5+
import GprTaskProvider from './gprTaskProvider';
6+
import { registerTaskProviders } from './taskProviders';
7+
8+
/**
9+
* This class encapsulates all state that should be maintained throughout the
10+
* lifecyle of the extension. This includes e.g. the Ada and GPR LSP clients,
11+
* task providers, etc...
12+
*
13+
* The intent is for there to be a global singleton instance of this class
14+
* created during the activation of the extension and referenced subsequently
15+
* wherever needed.
16+
*/
17+
export class ExtensionState {
18+
public readonly adaClient: LanguageClient;
19+
public readonly gprClient: LanguageClient;
20+
public readonly context: vscode.ExtensionContext;
21+
22+
private clientsDisposables: Disposable[];
23+
private registeredTaskProviders: Disposable[];
24+
25+
constructor(context: vscode.ExtensionContext) {
26+
this.context = context;
27+
this.gprClient = createClient(
28+
context,
29+
'gpr',
30+
'GPR Language Server',
31+
['--language-gpr'],
32+
'**/.{gpr}'
33+
);
34+
this.adaClient = createClient(
35+
context,
36+
'ada',
37+
'Ada Language Server',
38+
[],
39+
'**/.{adb,ads,adc,ada}'
40+
);
41+
this.clientsDisposables = [];
42+
this.registeredTaskProviders = [];
43+
}
44+
45+
public start = () => {
46+
this.clientsDisposables = [this.gprClient.start(), this.adaClient.start()];
47+
this.registerTaskProviders();
48+
};
49+
50+
public dispose = () => {
51+
this.unregisterTaskProviders();
52+
this.clientsDisposables.forEach((clientDisposable: Disposable) =>
53+
clientDisposable.dispose()
54+
);
55+
};
56+
57+
public registerTaskProviders = (): void => {
58+
this.registeredTaskProviders = [
59+
vscode.tasks.registerTaskProvider(GnatTaskProvider.gnatType, new GnatTaskProvider()),
60+
vscode.tasks.registerTaskProvider(
61+
GprTaskProvider.gprTaskType,
62+
new GprTaskProvider(this.adaClient)
63+
),
64+
].concat(registerTaskProviders());
65+
};
66+
67+
public unregisterTaskProviders = (): void => {
68+
for (const item of this.registeredTaskProviders) {
69+
item.dispose();
70+
}
71+
this.registeredTaskProviders = [];
72+
};
73+
74+
// React to changes in configuration to recompute predefined tasks if the user
75+
// changes scenario variables' values.
76+
public configChanged = (e: vscode.ConfigurationChangeEvent) => {
77+
if (
78+
e.affectsConfiguration('ada.scenarioVariables') ||
79+
e.affectsConfiguration('ada.projectFile')
80+
) {
81+
this.unregisterTaskProviders();
82+
this.registerTaskProviders();
83+
}
84+
};
85+
}

integration/vscode/ada/src/clients.ts

Lines changed: 2 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,10 @@
11
import { existsSync } from 'fs';
22
import * as vscode from 'vscode';
3-
import {
4-
Disposable,
5-
ExecuteCommandRequest,
6-
LanguageClient,
7-
LanguageClientOptions,
8-
ServerOptions,
9-
} from 'vscode-languageclient/node';
3+
import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';
104
import { logger } from './extension';
11-
import GnatTaskProvider from './gnatTaskProvider';
12-
import GprTaskProvider from './gprTaskProvider';
135
import { logErrorAndThrow, setCustomEnvironment } from './helpers';
14-
import { registerTaskProviders } from './taskProviders';
156

16-
export class ContextClients {
17-
public readonly gprClient: LanguageClient;
18-
public readonly adaClient: LanguageClient;
19-
20-
private clientsDisposables: Disposable[];
21-
private registeredTaskProviders: Disposable[];
22-
23-
constructor(context: vscode.ExtensionContext) {
24-
this.gprClient = createClient(
25-
context,
26-
'gpr',
27-
'GPR Language Server',
28-
['--language-gpr'],
29-
'**/.{gpr}'
30-
);
31-
this.adaClient = createClient(
32-
context,
33-
'ada',
34-
'Ada Language Server',
35-
[],
36-
'**/.{adb,ads,adc,ada}'
37-
);
38-
this.clientsDisposables = [];
39-
this.registeredTaskProviders = [];
40-
}
41-
42-
public start = () => {
43-
this.clientsDisposables = [this.gprClient.start(), this.adaClient.start()];
44-
this.registerTaskProviders();
45-
};
46-
47-
public dispose = () => {
48-
this.unregisterTaskProviders();
49-
this.clientsDisposables.forEach((clientDisposable: Disposable) =>
50-
clientDisposable.dispose()
51-
);
52-
};
53-
54-
public registerTaskProviders = (): void => {
55-
this.registeredTaskProviders = [
56-
vscode.tasks.registerTaskProvider(GnatTaskProvider.gnatType, new GnatTaskProvider()),
57-
vscode.tasks.registerTaskProvider(
58-
GprTaskProvider.gprTaskType,
59-
new GprTaskProvider(this.adaClient)
60-
),
61-
].concat(registerTaskProviders());
62-
};
63-
64-
public unregisterTaskProviders = (): void => {
65-
for (const item of this.registeredTaskProviders) {
66-
item.dispose();
67-
}
68-
this.registeredTaskProviders = [];
69-
};
70-
71-
// React to changes in configuration to recompute predefined tasks if the user
72-
// changes scenario variables' values.
73-
public configChanged = (e: vscode.ConfigurationChangeEvent) => {
74-
if (
75-
e.affectsConfiguration('ada.scenarioVariables') ||
76-
e.affectsConfiguration('ada.projectFile')
77-
) {
78-
this.unregisterTaskProviders();
79-
this.registerTaskProviders();
80-
}
81-
};
82-
83-
// Take active editor URI and call execute 'als-other-file' command in LSP
84-
public otherFileHandler = () => {
85-
const activeEditor = vscode.window.activeTextEditor;
86-
if (!activeEditor) {
87-
return;
88-
}
89-
void this.adaClient.sendRequest(ExecuteCommandRequest.type, {
90-
command: 'als-other-file',
91-
arguments: [
92-
{
93-
uri: activeEditor.document.uri.toString(),
94-
},
95-
],
96-
});
97-
};
98-
}
99-
100-
function createClient(
7+
export function createClient(
1018
context: vscode.ExtensionContext,
1029
id: string,
10310
name: string,

integration/vscode/ada/src/commands.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ import { existsSync } from 'fs';
33
import * as vscode from 'vscode';
44
import { SymbolKind } from 'vscode';
55
import { Disposable } from 'vscode-jsonrpc';
6-
import { ContextClients } from './clients';
6+
import { ExecuteCommandRequest } from 'vscode-languageclient';
7+
import { ExtensionState } from './ExtensionState';
78
import { getOrAskForProgram } from './debugConfigProvider';
8-
import { mainOutputChannel } from './extension';
9+
import { adaExtState, mainOutputChannel } from './extension';
910
import { getProjectFileRelPath } from './helpers';
1011
import { CustomTaskDefinition, getEnclosingSymbol } from './taskProviders';
1112

12-
export function registerCommands(context: vscode.ExtensionContext, clients: ContextClients) {
13-
context.subscriptions.push(
14-
vscode.commands.registerCommand('ada.otherFile', clients.otherFileHandler)
15-
);
13+
export function registerCommands(context: vscode.ExtensionContext, clients: ExtensionState) {
14+
context.subscriptions.push(vscode.commands.registerCommand('ada.otherFile', otherFileHandler));
1615
context.subscriptions.push(
1716
vscode.commands.registerCommand('ada.subprogramBox', addSupbrogramBoxCommand)
1817
);
@@ -320,3 +319,19 @@ async function getBuildAndRunTasks() {
320319
)
321320
);
322321
}
322+
323+
// Take active editor URI and call execute 'als-other-file' command in LSP
324+
const otherFileHandler = () => {
325+
const activeEditor = vscode.window.activeTextEditor;
326+
if (!activeEditor) {
327+
return;
328+
}
329+
void adaExtState.adaClient.sendRequest(ExecuteCommandRequest.type, {
330+
command: 'als-other-file',
331+
arguments: [
332+
{
333+
uri: activeEditor.document.uri.toString(),
334+
},
335+
],
336+
});
337+
};

integration/vscode/ada/src/debugConfigProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import assert from 'assert';
22
import * as vscode from 'vscode';
3-
import { contextClients } from './extension';
3+
import { adaExtState } from './extension';
44
import { AdaMain, getAdaMains, getProjectFile } from './helpers';
55

66
/**
@@ -284,7 +284,7 @@ async function assertProjectHasMains(mains?: AdaMain[]) {
284284
if (mains.length == 0) {
285285
const msg =
286286
`The Ada project '${await getProjectFile(
287-
contextClients.adaClient
287+
adaExtState.adaClient
288288
)}' does not define a 'Main' attribute. ` + 'Debugging is not possible without it.';
289289

290290
// Display a warning message

integration/vscode/ada/src/extension.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ import { MESSAGE } from 'triple-beam';
2323
import { ExecuteCommandRequest, LanguageClient, Middleware } from 'vscode-languageclient/node';
2424
import winston, { format, transports } from 'winston';
2525
import Transport from 'winston-transport';
26+
import { ExtensionState } from './ExtensionState';
2627
import { ALSClientFeatures } from './alsClientFeatures';
2728
import { alsCommandExecutor } from './alsExecuteCommand';
28-
import { ContextClients } from './clients';
2929
import { registerCommands } from './commands';
3030
import { initializeDebugging } from './debugConfigProvider';
3131
import { initializeTestView } from './gnattest';
@@ -37,7 +37,13 @@ import {
3737
} from './helpers';
3838

3939
const ADA_CONTEXT = 'ADA_PROJECT_CONTEXT';
40-
export let contextClients: ContextClients;
40+
41+
/**
42+
* A global object encapsulating extension state. This includes the Ada and GPR
43+
* LSP clients and other state used to provide tasks, commands and other
44+
* functionality.
45+
*/
46+
export let adaExtState: ExtensionState;
4147

4248
/**
4349
* The `vscode.OutputChannel` that hosts messages from the extension. This is
@@ -134,35 +140,34 @@ async function activateExtension(context: vscode.ExtensionContext) {
134140
}
135141

136142
// Create the Ada and GPR clients.
137-
contextClients = new ContextClients(context);
143+
adaExtState = new ExtensionState(context);
144+
context.subscriptions.push(adaExtState);
138145

139146
const alsMiddleware: Middleware = {
140-
executeCommand: alsCommandExecutor(contextClients.adaClient),
147+
executeCommand: alsCommandExecutor(adaExtState.adaClient),
141148
};
142-
contextClients.adaClient.clientOptions.middleware = alsMiddleware;
143-
contextClients.adaClient.registerFeature(new ALSClientFeatures());
144-
145-
contextClients.start();
149+
adaExtState.adaClient.clientOptions.middleware = alsMiddleware;
150+
adaExtState.adaClient.registerFeature(new ALSClientFeatures());
146151

147-
context.subscriptions.push(contextClients);
152+
adaExtState.start();
148153

149154
context.subscriptions.push(
150-
vscode.workspace.onDidChangeConfiguration(contextClients.configChanged)
155+
vscode.workspace.onDidChangeConfiguration(adaExtState.configChanged)
151156
);
152157

153-
await Promise.all([contextClients.adaClient.onReady(), contextClients.gprClient.onReady()]);
158+
await Promise.all([adaExtState.adaClient.onReady(), adaExtState.gprClient.onReady()]);
154159

155160
await vscode.commands.executeCommand('setContext', ADA_CONTEXT, true);
156161

157-
await checkSrcDirectories(contextClients.adaClient);
162+
await checkSrcDirectories(adaExtState.adaClient);
158163

159-
await initializeTestView(context, contextClients);
164+
await initializeTestView(context, adaExtState);
160165

161-
await Promise.all([contextClients.adaClient.onReady(), contextClients.gprClient.onReady()]);
166+
await Promise.all([adaExtState.adaClient.onReady(), adaExtState.gprClient.onReady()]);
162167

163168
initializeDebugging(context);
164169

165-
registerCommands(context, contextClients);
170+
registerCommands(context, adaExtState);
166171
}
167172

168173
function setUpLogging() {

integration/vscode/ada/src/gnattest.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import * as vscode from 'vscode';
2-
import * as path from 'path';
3-
import * as fs from 'fs';
41
import { XMLParser } from 'fast-xml-parser';
5-
import { ContextClients } from './clients';
6-
import { getProjectFile, getObjectDir } from './helpers';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
import * as vscode from 'vscode';
75
import { integer } from 'vscode-languageclient';
6+
import { ExtensionState } from './ExtensionState';
7+
import { getObjectDir, getProjectFile } from './helpers';
88

99
export let controller: vscode.TestController;
1010
export let testRunProfile: vscode.TestRunProfile;
@@ -54,7 +54,7 @@ type Test = {
5454
*/
5555
export async function initializeTestView(
5656
context: vscode.ExtensionContext,
57-
clients: ContextClients
57+
clients: ExtensionState
5858
) {
5959
if (vscode.workspace.workspaceFolders !== undefined) {
6060
controller = vscode.tests.createTestController(

integration/vscode/ada/src/helpers.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import * as path from 'path';
2020
import * as vscode from 'vscode';
2121
import { ExecuteCommandRequest, LanguageClient } from 'vscode-languageclient/node';
2222
import winston from 'winston';
23-
import { contextClients, logger } from './extension';
23+
import { adaExtState, logger } from './extension';
2424

2525
/**
2626
* Substitue any variable reference present in the given string. VS Code
@@ -239,7 +239,7 @@ export function logErrorAndThrow(msg: string, logger: winston.Logger) {
239239
*/
240240
export async function getProjectFile(client?: LanguageClient): Promise<string> {
241241
if (!client) {
242-
client = contextClients.adaClient;
242+
client = adaExtState.adaClient;
243243
}
244244
const result: string = (await client.sendRequest(ExecuteCommandRequest.type, {
245245
command: 'als-project-file',
@@ -294,8 +294,8 @@ export async function getExecutables(client: LanguageClient): Promise<string[]>
294294
* @returns The list of Mains defined for the current project as an array of AdaMains.
295295
*/
296296
export async function getAdaMains(): Promise<AdaMain[]> {
297-
const mains = await getMains(contextClients.adaClient);
298-
const execs = await getExecutables(contextClients.adaClient);
297+
const mains = await getMains(adaExtState.adaClient);
298+
const execs = await getExecutables(adaExtState.adaClient);
299299
assert(
300300
execs.length == mains.length,
301301
`The ALS returned mains.length = ${mains.length} and ` +

0 commit comments

Comments
 (0)