Skip to content

Commit 750c8e2

Browse files
committed
Merge branch 'config_file' into 'master'
Support gprbuild's configuration file See merge request eng/ide/ada_language_server!1846
2 parents 19ed0d6 + 3c50186 commit 750c8e2

13 files changed

+199
-27
lines changed

doc/settings.md

+11
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ Settings taken into account only from the Ada & SPARK VS Code extension:
101101
Settings understood by the Ada Language Server itself, independently from the LSP client:
102102

103103
* [projectFile](#projectfile)
104+
* [gprConfigurationFile](#gprconfigurationfile)
104105
* [scenarioVariables](#scenariovariables)
105106
* [defaultCharset](#defaultcharset)
106107
* [relocateBuildTree](#relocatebuildtree)
@@ -156,6 +157,16 @@ root folder, then ALS will use it.
156157
'projectFile': 'gnat/lsp_server.gpr'
157158
```
158159

160+
### gprConfigurationFile
161+
162+
You can configure the GPRBuild configuration file via the
163+
`gprConfigurationFile` key. The setting has a string value, that points to
164+
the `.cgpr` file. It could be a full path or relative path.
165+
166+
```javascript
167+
'gprConfigurationFile': 'gnat/lsp_server.cgpr'
168+
```
169+
159170
### scenarioVariables
160171

161172
You can configure scenario variables via the `scenarioVariables` key.

integration/vscode/ada/package.json

+7
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@
285285
"description": "GPR project file (*.gpr) for this workspace.\n\nIt is recommended to set this to a relative path starting at the root of the workspace.",
286286
"order": 0
287287
},
288+
"ada.gprConfigurationFile": {
289+
"scope": "window",
290+
"type": "string",
291+
"default": null,
292+
"description": "GPR configuration file (*.cgpr) for this workspace.\n\nIt is recommended to set this to a relative path starting at the root of the workspace.",
293+
"order": 0
294+
},
288295
"ada.scenarioVariables": {
289296
"scope": "window",
290297
"type": "object",

integration/vscode/ada/schemas/als-settings-schema.json

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
"type": "string",
88
"description": "GPR project file (*.gpr) for this workspace.\n\nIt is recommended to set this to a relative path starting at the root of the workspace."
99
},
10+
"gprConfigurationFile": {
11+
"type": "string",
12+
"default": null,
13+
"description": "GPR configuration file (*.cgpr) for this workspace.\n\nIt is recommended to set this to a relative path starting at the root of the workspace."
14+
},
1015
"scenarioVariables": {
1116
"type": "object",
1217
"default": {},

source/ada/lsp-ada_client_capabilities.adb

+12-5
Original file line numberDiff line numberDiff line change
@@ -608,13 +608,20 @@ package body LSP.Ada_Client_Capabilities is
608608
return GNATCOLL.VFS.Virtual_File
609609
is
610610
Value : constant VSS.Strings.Virtual_String := Client.Root;
611-
Root : constant String :=
612-
VSS.Strings.Conversions.To_UTF_8_String (Value);
613611
begin
614-
return GNATCOLL.VFS.Create_From_UTF8
615-
(if Value.Starts_With ("file://")
616-
then URIs.Conversions.To_File (Root, True)
612+
if Value.Is_Empty then
613+
return GNATCOLL.VFS.No_File;
614+
else
615+
declare
616+
Root : constant String :=
617+
VSS.Strings.Conversions.To_UTF_8_String (Value);
618+
begin
619+
return GNATCOLL.VFS.Create_From_UTF8
620+
(if Value.Starts_With ("file://")
621+
then URIs.Conversions.To_File (Root, True)
617622
else Root);
623+
end;
624+
end if;
618625
end Root_Directory;
619626

620627
end LSP.Ada_Client_Capabilities;

source/ada/lsp-ada_configurations.adb

+5
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,11 @@ package body LSP.Ada_Configurations is
227227
then
228228
Self.Project_File := JSON (Index).String_Value;
229229

230+
elsif Name = "gprConfigurationFile"
231+
and then JSON (Index).Kind = String_Value
232+
then
233+
Self.GPR_Configuration_File := JSON (Index).String_Value;
234+
230235
elsif Name = "projectDiagnostics"
231236
and then JSON (Index).Kind = Boolean_Value
232237
then

source/ada/lsp-ada_configurations.ads

+9
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ package LSP.Ada_Configurations is
6060
(Self : Configuration'Class) return VSS.Strings.Virtual_String;
6161
-- The project file, if provided by the user on Configuration/Init
6262

63+
function GPR_Configuration_File
64+
(Self : Configuration'Class) return VSS.Strings.Virtual_String;
65+
-- The configuration file, if provided by the user on Configuration/Init
66+
6367
function Charset
6468
(Self : Configuration'Class) return VSS.Strings.Virtual_String;
6569
-- A character set for Libadalang
@@ -149,6 +153,7 @@ private
149153

150154
type Configuration is tagged record
151155
Project_File : VSS.Strings.Virtual_String;
156+
GPR_Configuration_File : VSS.Strings.Virtual_String;
152157
Charset : VSS.Strings.Virtual_String;
153158
Relocate_Build_Tree : VSS.Strings.Virtual_String;
154159
Relocate_Root : VSS.Strings.Virtual_String;
@@ -182,6 +187,10 @@ private
182187
(Self : Configuration'Class) return VSS.Strings.Virtual_String is
183188
(Self.Project_File);
184189

190+
function GPR_Configuration_File
191+
(Self : Configuration'Class) return VSS.Strings.Virtual_String is
192+
(Self.GPR_Configuration_File);
193+
185194
function Charset
186195
(Self : Configuration'Class) return VSS.Strings.Virtual_String is
187196
(Self.Charset);

source/ada/lsp-ada_handlers-project_loading.adb

+61-22
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@ package body LSP.Ada_Handlers.Project_Loading is
7777
LF : VSS.Characters.Virtual_Character renames VSS.Characters.Latin.Line_Feed;
7878

7979
procedure Load_Project
80-
(Self : in out Message_Handler'Class;
81-
Project_Path : VSS.Strings.Virtual_String;
82-
Context : GPR2.Context.Object;
83-
Environment : GPR2.Environment.Object;
84-
Charset : VSS.Strings.Virtual_String);
80+
(Self : in out Message_Handler'Class;
81+
Project_Path : VSS.Strings.Virtual_String;
82+
GPR_Config_Path : VSS.Strings.Virtual_String;
83+
Context : GPR2.Context.Object;
84+
Environment : GPR2.Environment.Object;
85+
Charset : VSS.Strings.Virtual_String);
8586
-- Attempt to load the given project file, with the scenario provided.
8687
-- This unloads all currently loaded project contexts. This factorizes code
8788
-- between Load_Project_With_Alire and Ensure_Project_Loaded.
@@ -149,7 +150,10 @@ package body LSP.Ada_Handlers.Project_Loading is
149150
use type VSS.Strings.Virtual_String;
150151

151152
GPRs_Found : Natural := 0;
152-
Project_File : VSS.Strings.Virtual_String := Self.Configuration.Project_File;
153+
Project_File : VSS.Strings.Virtual_String :=
154+
Self.Configuration.Project_File;
155+
GPR_Configuration_File : VSS.Strings.Virtual_String :=
156+
Self.Configuration.GPR_Configuration_File;
153157
Is_Alire_Crate : constant Boolean := Alire.Is_Alire_Crate (Self.Client);
154158
Has_Alire : Boolean;
155159
Alire_Errors : VSS.Strings.Virtual_String;
@@ -276,12 +280,21 @@ package body LSP.Ada_Handlers.Project_Loading is
276280
end if;
277281
end if;
278282

283+
if GPR_Configuration_File.Starts_With ("file://") then
284+
GPR_Configuration_File :=
285+
VSS.Strings.Conversions.To_Virtual_String
286+
(URIs.Conversions.To_File
287+
(VSS.Strings.Conversions.To_UTF_8_String
288+
(GPR_Configuration_File), True));
289+
end if;
290+
279291
Load_Project
280-
(Self => Self,
281-
Project_Path => Project_File,
282-
Context => Self.Configuration.Context,
283-
Environment => Environment,
284-
Charset => Charset);
292+
(Self => Self,
293+
Project_Path => Project_File,
294+
GPR_Config_Path => GPR_Configuration_File,
295+
Context => Self.Configuration.Context,
296+
Environment => Environment,
297+
Charset => Charset);
285298
end;
286299
else
287300
-- We didn't find a project file. Let's load an implicit project. We
@@ -328,11 +341,13 @@ package body LSP.Ada_Handlers.Project_Loading is
328341
is
329342
use LSP.Ada_Context_Sets;
330343
use LSP.Ada_Contexts;
344+
use type GNATCOLL.VFS.Virtual_File;
331345

332346
C : constant Context_Access := new Context (Self.Tracer);
333347

334348
Reader : LSP.Ada_Handlers.File_Readers.LSP_File_Reader
335349
(Self'Unchecked_Access);
350+
Root : GNATCOLL.VFS.Virtual_File;
336351
begin
337352
Tracer.Trace
338353
("Loading the implicit project because " & Status'Image);
@@ -362,8 +377,9 @@ package body LSP.Ada_Handlers.Project_Loading is
362377
-- When there is no .gpr, create a project which loads the
363378
-- root directory in the workspace.
364379

365-
if not Self.Client.Root.Is_Empty then
366-
Self.Project_Dirs_Loaded.Include (Self.Client.Root_Directory);
380+
Root := Self.Client.Root_Directory;
381+
if Root /= GNATCOLL.VFS.No_File then
382+
Self.Project_Dirs_Loaded.Include (Root);
367383
end if;
368384

369385
Reload_Implicit_Project_Dirs (Self);
@@ -384,17 +400,23 @@ package body LSP.Ada_Handlers.Project_Loading is
384400
------------------
385401

386402
procedure Load_Project
387-
(Self : in out Message_Handler'Class;
388-
Project_Path : VSS.Strings.Virtual_String;
389-
Context : GPR2.Context.Object;
390-
Environment : GPR2.Environment.Object;
391-
Charset : VSS.Strings.Virtual_String)
403+
(Self : in out Message_Handler'Class;
404+
Project_Path : VSS.Strings.Virtual_String;
405+
GPR_Config_Path : VSS.Strings.Virtual_String;
406+
Context : GPR2.Context.Object;
407+
Environment : GPR2.Environment.Object;
408+
Charset : VSS.Strings.Virtual_String)
392409
is
393410
use type VSS.Strings.Virtual_String;
411+
use type GNATCOLL.VFS.Virtual_File;
394412

395-
Project_File : GNATCOLL.VFS.Virtual_File :=
413+
Project_File : GNATCOLL.VFS.Virtual_File :=
396414
LSP.Utils.To_Virtual_File (Project_Path);
397415

416+
GPR_Config_File : GNATCOLL.VFS.Virtual_File;
417+
418+
Root : GNATCOLL.VFS.Virtual_File;
419+
398420
procedure Create_Context_For_Non_Aggregate
399421
(View : GPR2.Project.View.Object);
400422
-- Create a new context for the given project view.
@@ -504,11 +526,22 @@ package body LSP.Ada_Handlers.Project_Loading is
504526
-- relative path; if so, we're assuming it's relative
505527
-- to Self.Root.
506528

529+
Root := Self.Client.Root_Directory;
530+
507531
if not Project_File.Is_Absolute_Path
508-
and then not Self.Client.Root.Is_Empty
532+
and then Root /= GNATCOLL.VFS.No_File
509533
then
510-
Project_File := GNATCOLL.VFS.Join (Self.Client.Root_Directory,
511-
Project_File);
534+
Project_File := GNATCOLL.VFS.Join (Root, Project_File);
535+
end if;
536+
537+
if not GPR_Config_Path.Is_Empty then
538+
GPR_Config_File := LSP.Utils.To_Virtual_File (GPR_Config_Path);
539+
540+
if not GPR_Config_File.Is_Absolute_Path
541+
and then Root /= GNATCOLL.VFS.No_File
542+
then
543+
GPR_Config_File := GNATCOLL.VFS.Join (Root, GPR_Config_File);
544+
end if;
512545
end if;
513546

514547
-- Unload the project tree and the project environment
@@ -540,6 +573,12 @@ package body LSP.Ada_Handlers.Project_Loading is
540573
begin
541574
-- Load the project
542575
Opts.Add_Switch (GPR2.Options.P, Project_File.Display_Full_Name);
576+
577+
if GPR_Config_File /= GNATCOLL.VFS.No_File then
578+
Opts.Add_Switch
579+
(GPR2.Options.Config, GPR_Config_File.Display_Full_Name);
580+
end if;
581+
543582
Opts.Add_Context (Context);
544583

545584
Tracer.Trace ("Loading project with GPR2");
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
with Ada.Characters.Latin_1;
3+
4+
procedure Main is
5+
Char : Character := Ada.Characters.Latin_1.BEL;
6+
begin
7+
null;
8+
end Main;
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
project Main is
2+
3+
for Languages use ("Ada");
4+
for Source_Dirs use (".");
5+
for Main use ("main.adb");
6+
7+
end Main;
+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
project Main1 is
2+
3+
for Languages use ("Ada");
4+
for Source_Dirs use (".");
5+
for Main use ("main.adb");
6+
7+
end Main1;

testsuite/ada_lsp/config_file/test.py

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""
2+
The goal of this test is to check that we take in account
3+
configurationFile configuration option and have proper navigation
4+
"""
5+
6+
import subprocess
7+
from drivers.pylsp import (
8+
ALSLanguageClient,
9+
URI,
10+
didOpenTextDocumentParams,
11+
assertEqual,
12+
test,
13+
)
14+
from lsprotocol.types import (
15+
DeclarationParams,
16+
TextDocumentIdentifier,
17+
Position,
18+
Location,
19+
)
20+
21+
# create default.cgpr configuration file that will use sjlj runtime
22+
subprocess.check_call(["gprconfig", "--batch", "--config=Ada,,sjlj,,GNAT"])
23+
24+
25+
@test()
26+
async def do_testing(lsp: ALSLanguageClient) -> None:
27+
# Set configuration file
28+
lsp.didChangeConfig(
29+
{"projectFile": URI("main.gpr"), "gprConfigurationFile": URI("default.cgpr")}
30+
)
31+
await lsp.awaitIndexingEnd()
32+
33+
# Send a didOpen for main.adb
34+
open_params, main_adb_uri = didOpenTextDocumentParams("main.adb")
35+
lsp.text_document_did_open(open_params)
36+
37+
# Send `goto declaration` request
38+
result = await lsp.text_document_declaration_async(
39+
DeclarationParams(TextDocumentIdentifier(main_adb_uri), Position(4, 48))
40+
)
41+
42+
# Check result
43+
assert result
44+
assert isinstance(result, Location)
45+
assertEqual("sjlj" in result.uri, True)
46+
47+
# Check relative to root paths
48+
lsp.didChangeConfig(
49+
{"projectFile": "main1.gpr", "gprConfigurationFile": "default.cgpr"}
50+
)
51+
await lsp.awaitIndexingEnd()
52+
53+
# Send a didOpen for main.adb
54+
open_params, main_adb_uri = didOpenTextDocumentParams("main.adb")
55+
lsp.text_document_did_open(open_params)
56+
57+
# Send `goto declaration` request
58+
result = await lsp.text_document_declaration_async(
59+
DeclarationParams(TextDocumentIdentifier(main_adb_uri), Position(4, 48))
60+
)
61+
62+
# Check result
63+
assert result
64+
assert isinstance(result, Location)
65+
assertEqual("sjlj" in result.uri, True)
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
driver: pylsp

testsuite/drivers/pylsp.py

+1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ class ALSSettings(
232232
onTypeFormatting: OnTypeFormattingSetting | None
233233
projectDiagnostics: bool | None
234234
projectFile: str | None
235+
gprConfigurationFile: str | None
235236
relocateBuildTree: str | None
236237
renameInComments: bool | None
237238
rootDir: str | None

0 commit comments

Comments
 (0)