Skip to content

Commit 5ed5f74

Browse files
committed
Merge branch 'topic/alire-race-condition' into 'master'
Perform Alire workspace sync in initialize request See merge request eng/ide/ada_language_server!2009
2 parents e4996a5 + e406e04 commit 5ed5f74

File tree

28 files changed

+366
-122
lines changed

28 files changed

+366
-122
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ section below it for the last release. -->
77

88
* Added `onEnterRules` for Ada/GPR files to split long comments by adding automatically a comment tag to the next line
99
* Added support for new LSP request `textDocument/inlineValue`
10+
* Resolved a bug where the Ada and GPR language servers made concurrent Alire
11+
invocations in the same workspace, causing sporadic errors. Alire invocations
12+
are now made sequentially using file-based synchronization across ALS
13+
processes.
1014

1115
## 26.0.202504171
1216

integration/vscode/ada/src/ExtensionState.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ export class ExtensionState {
122122

123123
public start = async () => {
124124
await Promise.all([this.gprClient.start(), this.adaClient.start()]);
125+
125126
this.registerTaskDisposables();
126127
this.context.subscriptions.push(
127128
vscode.languages.registerCodeLensProvider('ada', this.codelensProvider),

integration/vscode/ada/src/clients.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,11 @@ export function createClient(
136136
* from .als.json or other applicable configuration files.
137137
*/
138138
({ ada: getExplicitlySetConfiguration() }),
139+
/**
140+
* Include a workDoneToken property in the 'initialize' request for the
141+
* server to report progress.
142+
*/
143+
progressOnInitialization: true,
139144
};
140145

141146
// Create the language client

integration/vscode/ada/src/extension.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,14 @@ async function activateExtension(context: vscode.ExtensionContext) {
168168
adaExtState.adaClient.clientOptions.middleware = alsMiddleware;
169169
adaExtState.adaClient.registerFeature(new ALSClientFeatures());
170170

171-
await adaExtState.start();
172-
173171
/**
174172
* Register commands first so that commands such as displaying the extension
175173
* Output become available even if the language servers fail to start.
176174
*/
177175
registerCommands(context, adaExtState);
178176

177+
await adaExtState.start();
178+
179179
await vscode.commands.executeCommand('setContext', ADA_CONTEXT, true);
180180

181181
/**

source/ada/lsp-ada_handlers-project_loading.adb

Lines changed: 53 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ package body LSP.Ada_Handlers.Project_Loading is
6363
GNATCOLL.Traces.Create ("ALS.RUNTIME_INDEXING", GNATCOLL.Traces.On);
6464
-- Trace to enable/disable runtime indexing. Useful for the testsuite.
6565

66+
Fallback_Msg : constant VSS.Strings.Virtual_String :=
67+
"Falling back to other methods to load a project";
68+
6669
type GPR2_Reporter is new GPR2.Reporter.Object with record
6770
Log : GPR2.Log.Object;
6871
end record;
@@ -136,8 +139,8 @@ package body LSP.Ada_Handlers.Project_Loading is
136139

137140
C : constant Context_Access := new Context (Self.Tracer);
138141

139-
Reader : LSP.Ada_Handlers.File_Readers.LSP_File_Reader
140-
(Self'Unchecked_Access);
142+
Reader :
143+
LSP.Ada_Handlers.File_Readers.LSP_File_Reader (Self'Unchecked_Access);
141144

142145
Dirs : File_Sets.Set;
143146

@@ -160,17 +163,17 @@ package body LSP.Ada_Handlers.Project_Loading is
160163
Create_In_Memory_Project
161164
("fallback_context", Dirs, Project_Tree, Success);
162165

163-
pragma Assert
164-
(Success, "Can't create an empty project for the fallback context");
166+
pragma
167+
Assert
168+
(Success, "Can't create an empty project for the fallback context");
165169

166170
-- Create a basic GPR2_Provider_And_Projects containing only the
167171
-- implicit project and load it.
168172
declare
169173
Provider : Libadalang.Project_Provider.GPR2_Provider_And_Projects :=
170174
(Provider =>
171175
Libadalang.Project_Provider.Create_Project_Unit_Provider
172-
(Tree => Project_Tree,
173-
Project => Project_Tree.Root_Project),
176+
(Tree => Project_Tree, Project => Project_Tree.Root_Project),
174177
Projects => <>);
175178
begin
176179
Provider.Projects.Append (Project_Tree.Root_Project);
@@ -224,34 +227,54 @@ package body LSP.Ada_Handlers.Project_Loading is
224227
(LSP.Ada_Project_Loading.Configured_Project);
225228

226229
elsif Is_Alire_Crate then
227-
Tracer.Trace ("Workspace is an Alire crate");
228-
229-
Tracer.Trace ("Performing minimal Alire sync");
230-
LSP.Alire.Conservative_Alire_Sync
231-
(Self.Client.Root_Directory.Display_Full_Name, Alire_Error);
230+
declare
232231

233-
if not Alire_Error.Is_Empty then
234-
Tracer.Trace_Text ("Encountered errors: " & Alire_Error);
235-
Self.Project_Status.Set_Alire_Messages ([Alire_Error]);
236-
else
237-
Tracer.Trace ("Determining project from 'alr show' output");
232+
procedure Report_Alire_Errors;
238233

239-
LSP.Alire.Determine_Alire_Project
240-
(Root => Self.Client.Root_Directory.Display_Full_Name,
241-
Error => Alire_Error,
242-
Project => Project_File);
234+
procedure Report_Alire_Errors is
235+
begin
236+
-- If the error is multi-line, use a separate line for the
237+
-- fallback message. Otherwise, keep a single line.
238+
if Alire_Error.Split_Lines.Length > 1 then
239+
Alire_Error.Append (VSS.Characters.Latin.Line_Feed);
240+
else
241+
Alire_Error.Append (": ");
242+
end if;
243+
Alire_Error.Append (Fallback_Msg);
243244

244-
if not Alire_Error.Is_Empty then
245245
Tracer.Trace_Text ("Encountered errors: " & Alire_Error);
246246
Self.Project_Status.Set_Alire_Messages ([Alire_Error]);
247+
end Report_Alire_Errors;
248+
249+
begin
250+
251+
Tracer.Trace ("Workspace is an Alire crate");
252+
253+
Tracer.Trace ("Performing minimal Alire sync");
254+
LSP.Alire.Conservative_Alire_Sync
255+
(Self.Client.Root_Directory.Display_Full_Name, Alire_Error);
256+
257+
if not Alire_Error.Is_Empty then
258+
Report_Alire_Errors;
247259
else
248-
-- Report how we found the project
249-
Self.Project_Status.Set_Project_Type
250-
(LSP.Ada_Project_Loading.Alire_Project);
251-
Self.Project_Status.Set_Alire_Messages ([]);
252-
end if;
260+
Tracer.Trace ("Determining project from 'alr show' output");
253261

254-
end if;
262+
LSP.Alire.Determine_Alire_Project
263+
(Root => Self.Client.Root_Directory.Display_Full_Name,
264+
Error => Alire_Error,
265+
Project => Project_File);
266+
267+
if not Alire_Error.Is_Empty then
268+
Report_Alire_Errors;
269+
else
270+
-- Report how we found the project
271+
Self.Project_Status.Set_Project_Type
272+
(LSP.Ada_Project_Loading.Alire_Project);
273+
Self.Project_Status.Set_Alire_Messages ([]);
274+
end if;
275+
276+
end if;
277+
end;
255278

256279
end if;
257280

@@ -354,7 +377,8 @@ package body LSP.Ada_Handlers.Project_Loading is
354377

355378
Load_Implicit_Project
356379
(Self,
357-
(if Candidates.Length = 0 then LSP.Ada_Project_Loading.No_Project
380+
(if Candidates.Length = 0
381+
then LSP.Ada_Project_Loading.No_Project
358382
elsif Candidates.Length > 1
359383
then LSP.Ada_Project_Loading.Multiple_Projects
360384
else LSP.Ada_Project_Loading.Project_Not_Found));
@@ -857,8 +881,7 @@ package body LSP.Ada_Handlers.Project_Loading is
857881
is
858882
Project : GPR2.Project.Tree.View_Builder.Object :=
859883
GPR2.Project.Tree.View_Builder.Create
860-
(Project_Dir => GPR2.Path_Name.Create_Directory ("."),
861-
Name => Name);
884+
(Project_Dir => GPR2.Path_Name.Create_Directory ("."), Name => Name);
862885
Values : GPR2.Containers.Value_List;
863886
Opts : GPR2.Options.Object;
864887
Reporter : GPR2_Reporter;

source/ada/lsp-ada_handlers.adb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2485,6 +2485,15 @@ package body LSP.Ada_Handlers is
24852485
Token_Types : LSP.Structures.Virtual_String_Vector;
24862486
Token_Motifiers : LSP.Structures.Virtual_String_Vector;
24872487
begin
2488+
if Value.workDoneToken.Is_Set then
2489+
Self.Sender.On_ProgressBegin_Work_Done
2490+
(Value.workDoneToken.Value,
2491+
(title => "Initializing Ada Language Server",
2492+
cancellable => (Is_Set => True, Value => False),
2493+
message => VSS.Strings.Empty_Virtual_String,
2494+
percentage => (Is_Set => False)));
2495+
end if;
2496+
24882497
Self.Client.Initialize (Value);
24892498

24902499
Self.Highlighter.Initialize
@@ -2550,6 +2559,12 @@ package body LSP.Ada_Handlers is
25502559
-- notification. See On_Initialized_Notification.
25512560
end if;
25522561

2562+
if Value.workDoneToken.Is_Set then
2563+
Self.Sender.On_ProgressEnd_Work_Done
2564+
(Value.workDoneToken.Value,
2565+
(message => VSS.Strings.Empty_Virtual_String));
2566+
end if;
2567+
25532568
Self.Sender.On_Initialize_Response (Id, Response);
25542569

25552570
Log_Info.a_type := LSP.Enumerations.Log;

0 commit comments

Comments
 (0)