Skip to content

Commit 3db59a7

Browse files
committedMar 1, 2023
Fix broken early configuration
when Self.Root hasn't been set yet by Initialize request, but Change_Configuration relies on it. Refs #1108
1 parent f923373 commit 3db59a7

File tree

3 files changed

+139
-109
lines changed

3 files changed

+139
-109
lines changed
 

‎source/ada/lsp-ada_driver.adb

+3-1
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,9 @@ begin
354354
GNAT.OS_Lib.OS_Exit (1);
355355
end if;
356356

357-
Ada_Handler.Change_Configuration (Parse_Result.Value);
357+
Ada_Handler.Change_Configuration_Before_Init
358+
(Options => Parse_Result.Value,
359+
Root => Config_File.Dir);
358360
end;
359361
end if;
360362

‎source/ada/lsp-ada_handlers.adb

+122-104
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ with Libadalang.Preprocessing;
108108
with URIs;
109109

110110
package body LSP.Ada_Handlers is
111+
use GNATCOLL.VFS;
111112

112113
type Cancel_Countdown is mod 128;
113114
-- Counter to restrict frequency of Request.Canceled checks
@@ -4307,11 +4308,16 @@ package body LSP.Ada_Handlers is
43074308
(Name : String;
43084309
Default : VSS.Strings.Virtual_String)
43094310
return VSS.Strings.Virtual_String is
4310-
(if Options.Has_Field (Name)
4311+
(if Options.Kind = GNATCOLL.JSON.JSON_Object_Type
4312+
and then Options.Has_Field (Name)
43114313
then VSS.Strings.Conversions.To_Virtual_String
43124314
(String'(Options.Get (Name)))
43134315
else Default);
43144316

4317+
function Has_Field (Name : String) return Boolean is
4318+
(Options.Kind = GNATCOLL.JSON.JSON_Object_Type
4319+
and then Options.Has_Field (Name));
4320+
43154321
------------------
43164322
-- Add_Variable --
43174323
------------------
@@ -4336,110 +4342,100 @@ package body LSP.Ada_Handlers is
43364342

43374343
Has_Variables : Boolean := False; -- settings has scenarioVariables
43384344

4339-
-- Is client capable of dynamically registering file operations?
4340-
Dynamically_Register_File_Operations : constant Boolean :=
4341-
Self.Client.capabilities.workspace.fileOperations.Is_Set
4342-
and then Self.Client.capabilities.workspace.fileOperations.
4343-
Value.dynamicRegistration.Is_Set = True;
4344-
43454345
begin
4346-
if Options.Kind = GNATCOLL.JSON.JSON_Object_Type then
4347-
Variables.Names.Clear;
4348-
Variables.Values.Clear;
4349-
Relocate_Build_Tree :=
4350-
Property (relocateBuildTree, Self.Relocate_Build_Tree);
4351-
4352-
Relocate_Root := Property (rootDir, Self.Relocate_Root_Dir);
4353-
Charset := Property (defaultCharset, Self.Charset);
4354-
File := Property (projectFile, Self.Project_File);
4355-
4356-
-- Drop uri scheme if present
4357-
if File.Starts_With ("file:") then
4358-
File := Self.URI_To_File (File);
4359-
end if;
4346+
Relocate_Build_Tree :=
4347+
Property (relocateBuildTree, Self.Relocate_Build_Tree);
43604348

4361-
if Options.Has_Field (scenarioVariables) and then
4362-
Options.Get
4363-
(scenarioVariables).Kind = GNATCOLL.JSON.JSON_Object_Type
4364-
then
4365-
Options.Get
4366-
(scenarioVariables).Map_JSON_Object (Add_Variable'Access);
4367-
Has_Variables := True;
4368-
end if;
4349+
Relocate_Root := Property (rootDir, Self.Relocate_Root_Dir);
4350+
Charset := Property (defaultCharset, Self.Charset);
4351+
File := Property (projectFile, Self.Project_File);
43694352

4370-
-- It looks like the protocol does not allow clients to say whether
4371-
-- or not they want diagnostics as part of
4372-
-- InitializeParams.capabilities.textDocument. So we support
4373-
-- deactivating of diagnostics via a setting here.
4374-
if Options.Has_Field (enableDiagnostics) then
4375-
Self.Diagnostics_Enabled := Options.Get (enableDiagnostics);
4376-
end if;
4353+
-- Drop uri scheme if present
4354+
if File.Starts_With ("file:") then
4355+
File := Self.URI_To_File (File);
4356+
end if;
43774357

4378-
-- Similarly to diagnostics, we support selectively activating
4379-
-- indexing in the parameters to this request.
4380-
if Options.Has_Field (enableIndexing) then
4381-
Self.Indexing_Enabled := Options.Get (enableIndexing);
4382-
end if;
4358+
if Has_Field (scenarioVariables) and then
4359+
Options.Get
4360+
(scenarioVariables).Kind = GNATCOLL.JSON.JSON_Object_Type
4361+
then
4362+
Options.Get
4363+
(scenarioVariables).Map_JSON_Object (Add_Variable'Access);
4364+
Has_Variables := True;
4365+
end if;
43834366

4384-
-- Retrieve the different textDocument/rename options if specified
4367+
-- It looks like the protocol does not allow clients to say whether
4368+
-- or not they want diagnostics as part of
4369+
-- InitializeParams.capabilities.textDocument. So we support
4370+
-- deactivating of diagnostics via a setting here.
4371+
if Has_Field (enableDiagnostics) then
4372+
Self.Diagnostics_Enabled := Options.Get (enableDiagnostics);
4373+
end if;
43854374

4386-
if Options.Has_Field (renameInComments) then
4387-
Self.Options.Refactoring.Renaming.In_Comments :=
4388-
Options.Get (renameInComments);
4389-
end if;
4375+
-- Similarly to diagnostics, we support selectively activating
4376+
-- indexing in the parameters to this request.
4377+
if Has_Field (enableIndexing) then
4378+
Self.Indexing_Enabled := Options.Get (enableIndexing);
4379+
end if;
43904380

4391-
if Options.Has_Field (foldComments) then
4392-
Self.Options.Folding.Comments := Options.Get (foldComments);
4393-
end if;
4381+
-- Retrieve the different textDocument/rename options if specified
43944382

4395-
-- Retrieve the number of parameters / components at which point
4396-
-- named notation is used for subprogram/aggregate completion
4397-
-- snippets.
4383+
if Has_Field (renameInComments) then
4384+
Self.Options.Refactoring.Renaming.In_Comments :=
4385+
Options.Get (renameInComments);
4386+
end if;
43984387

4399-
if Options.Has_Field (namedNotationThreshold) then
4400-
Self.Named_Notation_Threshold :=
4401-
Options.Get (namedNotationThreshold);
4402-
end if;
4388+
if Has_Field (foldComments) then
4389+
Self.Options.Folding.Comments := Options.Get (foldComments);
4390+
end if;
44034391

4404-
if Options.Has_Field (logThreshold) then
4405-
Self.Log_Threshold := Options.Get (logThreshold);
4406-
end if;
4392+
-- Retrieve the number of parameters / components at which point
4393+
-- named notation is used for subprogram/aggregate completion
4394+
-- snippets.
44074395

4408-
-- Check the 'useCompletionSnippets' flag to see if we should use
4409-
-- snippets in completion (if the client supports it).
4410-
if not Self.Completion_Snippets_Enabled then
4411-
Self.Use_Completion_Snippets := False;
4412-
elsif Options.Has_Field (useCompletionSnippets) then
4413-
Self.Use_Completion_Snippets :=
4414-
Options.Get (useCompletionSnippets);
4415-
end if;
4396+
if Has_Field (namedNotationThreshold) then
4397+
Self.Named_Notation_Threshold :=
4398+
Options.Get (namedNotationThreshold);
4399+
end if;
44164400

4417-
-- Retrieve the policy for displaying type hierarchy on navigation
4418-
-- requests.
4419-
if Options.Has_Field (displayMethodAncestryOnNavigation) then
4420-
Self.Display_Method_Ancestry_Policy :=
4421-
LSP.Messages.AlsDisplayMethodAncestryOnNavigationPolicy'Value
4422-
(Options.Get (displayMethodAncestryOnNavigation));
4423-
end if;
4401+
if Has_Field (logThreshold) then
4402+
Self.Log_Threshold := Options.Get (logThreshold);
4403+
end if;
44244404

4425-
-- Retrieve the follow symlinks policy.
4405+
-- Check the 'useCompletionSnippets' flag to see if we should use
4406+
-- snippets in completion (if the client supports it).
4407+
if not Self.Completion_Snippets_Enabled then
4408+
Self.Use_Completion_Snippets := False;
4409+
elsif Has_Field (useCompletionSnippets) then
4410+
Self.Use_Completion_Snippets :=
4411+
Options.Get (useCompletionSnippets);
4412+
end if;
44264413

4427-
if Options.Has_Field (followSymlinks) then
4428-
Self.Follow_Symlinks := Options.Get (followSymlinks);
4429-
end if;
4414+
-- Retrieve the policy for displaying type hierarchy on navigation
4415+
-- requests.
4416+
if Has_Field (displayMethodAncestryOnNavigation) then
4417+
Self.Display_Method_Ancestry_Policy :=
4418+
LSP.Messages.AlsDisplayMethodAncestryOnNavigationPolicy'Value
4419+
(Options.Get (displayMethodAncestryOnNavigation));
4420+
end if;
44304421

4431-
if Options.Has_Field (documentationStyle) then
4432-
begin
4433-
Self.Options.Documentation.Style :=
4434-
GNATdoc.Comments.Options.Documentation_Style'Value
4435-
(Options.Get (documentationStyle));
4422+
-- Retrieve the follow symlinks policy.
44364423

4437-
exception
4438-
when Constraint_Error =>
4439-
Self.Options.Documentation.Style :=
4440-
GNATdoc.Comments.Options.GNAT;
4441-
end;
4442-
end if;
4424+
if Has_Field (followSymlinks) then
4425+
Self.Follow_Symlinks := Options.Get (followSymlinks);
4426+
end if;
4427+
4428+
if Has_Field (documentationStyle) then
4429+
begin
4430+
Self.Options.Documentation.Style :=
4431+
GNATdoc.Comments.Options.Documentation_Style'Value
4432+
(Options.Get (documentationStyle));
4433+
4434+
exception
4435+
when Constraint_Error =>
4436+
Self.Options.Documentation.Style :=
4437+
GNATdoc.Comments.Options.GNAT;
4438+
end;
44434439
end if;
44444440

44454441
if Self.Project_File = File
@@ -4464,6 +4460,43 @@ package body LSP.Ada_Handlers is
44644460
Self.Project_Status := Valid_Project_Configured;
44654461
Self.Reload_Project;
44664462
end if;
4463+
end Change_Configuration;
4464+
4465+
--------------------------------------
4466+
-- Change_Configuration_Before_Init --
4467+
--------------------------------------
4468+
4469+
procedure Change_Configuration_Before_Init
4470+
(Self : access Message_Handler;
4471+
Options : GNATCOLL.JSON.JSON_Value'Class;
4472+
Root : GNATCOLL.VFS.Virtual_File)
4473+
is
4474+
Saved_Root : constant GNATCOLL.VFS.Virtual_File := Self.Root;
4475+
begin
4476+
Self.Root := Root;
4477+
Self.Change_Configuration (Options);
4478+
Self.Root := Saved_Root;
4479+
end Change_Configuration_Before_Init;
4480+
4481+
--------------------------------------------
4482+
-- On_DidChangeConfiguration_Notification --
4483+
--------------------------------------------
4484+
4485+
overriding procedure On_DidChangeConfiguration_Notification
4486+
(Self : access Message_Handler;
4487+
Value : LSP.Messages.DidChangeConfigurationParams)
4488+
is
4489+
4490+
Ada : constant LSP.Types.LSP_Any := Value.settings.Get ("ada");
4491+
4492+
-- Is client capable of dynamically registering file operations?
4493+
Dynamically_Register_File_Operations : constant Boolean :=
4494+
Self.Client.capabilities.workspace.fileOperations.Is_Set
4495+
and then Self.Client.capabilities.workspace.fileOperations.
4496+
Value.dynamicRegistration.Is_Set = True;
4497+
4498+
begin
4499+
Self.Change_Configuration (Ada);
44674500

44684501
-- Register rangeFormatting provider is the client supports
44694502
-- dynamic registration for it (and we haven't done it before).
@@ -4550,21 +4583,6 @@ package body LSP.Ada_Handlers is
45504583
Self.Server.On_RegisterCapability_Request (Request);
45514584
end;
45524585
end if;
4553-
end Change_Configuration;
4554-
4555-
--------------------------------------------
4556-
-- On_DidChangeConfiguration_Notification --
4557-
--------------------------------------------
4558-
4559-
overriding procedure On_DidChangeConfiguration_Notification
4560-
(Self : access Message_Handler;
4561-
Value : LSP.Messages.DidChangeConfigurationParams)
4562-
is
4563-
4564-
Ada : constant LSP.Types.LSP_Any := Value.settings.Get ("ada");
4565-
4566-
begin
4567-
Self.Change_Configuration (Ada);
45684586
end On_DidChangeConfiguration_Notification;
45694587

45704588
-------------------------------------------

‎source/ada/lsp-ada_handlers.ads

+14-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ with Ada.Strings.Unbounded;
2424
with VSS.String_Vectors;
2525

2626
with GNATCOLL.JSON;
27-
with GNATCOLL.VFS; use GNATCOLL.VFS;
27+
with GNATCOLL.VFS;
2828
with GNATCOLL.Traces;
2929

3030
with VSS.Strings;
@@ -77,19 +77,29 @@ package LSP.Ada_Handlers is
7777
Options : GNATCOLL.JSON.JSON_Value'Class);
7878
-- Change server configuration with settings from Ada JSON object.
7979

80+
procedure Change_Configuration_Before_Init
81+
(Self : access Message_Handler;
82+
Options : GNATCOLL.JSON.JSON_Value'Class;
83+
Root : GNATCOLL.VFS.Virtual_File);
84+
-- Change server configuration with settings from Ada JSON object, taking
85+
-- Root to resolve all relative references. This is expected to work
86+
-- before the server get initialize request and find root folder.
87+
8088
procedure Stop_File_Monitoring (Self : access Message_Handler);
8189

8290
procedure Cleanup (Self : access Message_Handler);
8391
-- Free memory referenced by Self
8492

85-
procedure Clean_Logs (Self : access Message_Handler; Dir : Virtual_File);
93+
procedure Clean_Logs
94+
(Self : access Message_Handler;
95+
Dir : GNATCOLL.VFS.Virtual_File);
8696
-- Remove the oldest logs in Dir
8797

8898
subtype Context_Access is LSP.Ada_Context_Sets.Context_Access;
8999

90100
function From_File
91101
(Self : Message_Handler'Class;
92-
File : Virtual_File) return LSP.Messages.DocumentUri;
102+
File : GNATCOLL.VFS.Virtual_File) return LSP.Messages.DocumentUri;
93103
-- Turn Virtual_File to URI
94104

95105
function To_File
@@ -260,7 +270,7 @@ private
260270
Client : LSP.Messages.InitializeParams;
261271
-- Client settings got during initialization request
262272

263-
Root : Virtual_File;
273+
Root : GNATCOLL.VFS.Virtual_File;
264274
-- The directory passed under rootURI/rootPath during the initialize
265275
-- request.
266276

0 commit comments

Comments
 (0)