Skip to content

Commit 41aa7a5

Browse files
committed
Replace On_DidChange_Notification of the GPR handler
with a job. Refs #1141
1 parent c883006 commit 41aa7a5

8 files changed

+299
-39
lines changed

source/ada/lsp-ada_driver.adb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ with LSP.GNATCOLL_Trace_Streams;
6868
with LSP.GNATCOLL_Tracers;
6969
with LSP.GPR_Handlers;
7070
with LSP.GPR_External_Tools;
71+
with LSP.GPR_Did_Change_Document;
7172
with LSP.Memory_Statistics;
7273
with LSP.Predefined_Completion;
7374
with LSP.Secure_Message_Loggers;
@@ -179,6 +180,10 @@ procedure LSP.Ada_Driver is
179180
LSP.Ada_Did_Change_Document.Ada_Did_Change_Handler
180181
(Ada_Handler'Unchecked_Access);
181182

183+
GPR_Did_Change_Doc_Handler : aliased
184+
LSP.GPR_Did_Change_Document.GPR_Did_Change_Handler
185+
(GPR_Handler'Unchecked_Access);
186+
182187
Fuzzing_Activated : constant Boolean :=
183188
not VSS.Application.System_Environment.Value ("ALS_FUZZING").Is_Empty;
184189
pragma Unreferenced (Fuzzing_Activated);
@@ -356,6 +361,10 @@ begin
356361

357362
LSP.GPR_External_Tools.Initialize_Extra_Packages_Attributes;
358363

364+
Server.Register_Handler
365+
(LSP.Server_Notifications.DidChange.Notification'Tag,
366+
GPR_Did_Change_Doc_Handler'Unchecked_Access);
367+
359368
Server.Run
360369
(GPR_Handler'Unchecked_Access,
361370
Tracer'Unchecked_Access,
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 2018-2024, AdaCore --
5+
-- --
6+
-- This is free software; you can redistribute it and/or modify it under --
7+
-- terms of the GNU General Public License as published by the Free Soft- --
8+
-- ware Foundation; either version 3, or (at your option) any later ver- --
9+
-- sion. This software is distributed in the hope that it will be useful, --
10+
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
11+
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
12+
-- License for more details. You should have received a copy of the GNU --
13+
-- General Public License distributed with this software; see file --
14+
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy --
15+
-- of the license. --
16+
------------------------------------------------------------------------------
17+
18+
with GNATCOLL.VFS;
19+
20+
with LSP.GPR_Files;
21+
with LSP.GPR_Documents;
22+
with LSP.Client_Message_Receivers;
23+
with LSP.Structures;
24+
with LSP.Server_Notifications.DidChange;
25+
26+
package body LSP.GPR_Did_Change_Document is
27+
28+
type Did_Change_Job
29+
(Parent : not null access constant GPR_Did_Change_Handler)
30+
is limited new LSP.Server_Jobs.Server_Job with record
31+
Document : LSP.GPR_Documents.Document_Access;
32+
Message : LSP.Server_Messages.Server_Message_Access;
33+
Is_Done : Boolean := False;
34+
end record;
35+
36+
type Did_Change_Job_Access is access all Did_Change_Job;
37+
38+
overriding function Priority
39+
(Self : Did_Change_Job) return LSP.Server_Jobs.Job_Priority is
40+
(LSP.Server_Jobs.Fence);
41+
42+
overriding function Is_Done (Self : Did_Change_Job) return Boolean is
43+
(Self.Is_Done);
44+
45+
overriding procedure Execute
46+
(Self : in out Did_Change_Job;
47+
Client :
48+
in out LSP.Client_Message_Receivers.Client_Message_Receiver'Class);
49+
50+
overriding procedure Complete
51+
(Self : in out Did_Change_Job;
52+
Next : LSP.Server_Messages.Server_Message_Access);
53+
54+
overriding function Message (Self : Did_Change_Job)
55+
return LSP.Server_Messages.Server_Message_Access is (Self.Message);
56+
57+
function Is_Incremental
58+
(Changes : LSP.Structures.TextDocumentContentChangeEvent_Vector)
59+
return Boolean is
60+
(not Changes.Is_Empty and then Changes.First_Element.a_range.Is_Set);
61+
-- Changes has incrimental form (not just full text update)
62+
63+
--------------
64+
-- Complete --
65+
--------------
66+
67+
overriding procedure Complete
68+
(Self : in out Did_Change_Job;
69+
Next : LSP.Server_Messages.Server_Message_Access)
70+
is
71+
use type LSP.Server_Messages.Server_Message_Access;
72+
use type GNATCOLL.VFS.Virtual_File;
73+
74+
Message : LSP.Server_Notifications.DidChange.Notification renames
75+
LSP.Server_Notifications.DidChange.Notification (Self.Message.all);
76+
77+
Changes : LSP.Structures.TextDocumentContentChangeEvent_Vector renames
78+
Message.Params.contentChanges;
79+
80+
File : constant GNATCOLL.VFS.Virtual_File :=
81+
Self.Parent.Context.To_File (Message.Params.textDocument.uri);
82+
83+
begin
84+
if Next /= null and then
85+
Next.all in LSP.Server_Notifications.DidChange.Notification'Class
86+
then
87+
declare
88+
Change : LSP.Server_Notifications.DidChange.Notification renames
89+
LSP.Server_Notifications.DidChange.Notification (Next.all);
90+
91+
Next_File : constant GNATCOLL.VFS.Virtual_File :=
92+
Self.Parent.Context.To_File (Change.Params.textDocument.uri);
93+
begin
94+
if File = Next_File then
95+
-- However, we should skip the Indexing part (and
96+
-- non-incremental changes) if the next didChange message
97+
-- will re-change the text document.
98+
return;
99+
end if;
100+
end;
101+
end if;
102+
103+
if not Is_Incremental (Changes) then
104+
Self.Document.Apply_Changes
105+
(Message.Params.textDocument.version, Changes);
106+
end if;
107+
108+
-- Load gpr tree & prepare diagnostics
109+
110+
Self.Document.Load;
111+
112+
-- Build GPR file for LSP needs.
113+
114+
LSP.GPR_Files.Parse_Modified_Document
115+
(File_Provider => Self.Parent.Context,
116+
Path => Self.Parent.Context.To_File
117+
(Message.Params.textDocument.uri));
118+
119+
-- Emit diagnostics
120+
Self.Parent.Context.Publish_Diagnostics (Self.Document);
121+
end Complete;
122+
123+
----------------
124+
-- Create_Job --
125+
----------------
126+
127+
overriding function Create_Job
128+
(Self : GPR_Did_Change_Handler;
129+
Message : LSP.Server_Messages.Server_Message_Access)
130+
return LSP.Server_Jobs.Server_Job_Access
131+
is
132+
Value : LSP.Server_Notifications.DidChange.Notification renames
133+
LSP.Server_Notifications.DidChange.Notification (Message.all);
134+
135+
URI : LSP.Structures.DocumentUri renames
136+
Value.Params.textDocument.uri;
137+
138+
Document : constant LSP.GPR_Documents.Document_Access :=
139+
Self.Context.Get_Open_Document (URI);
140+
141+
Result : constant Did_Change_Job_Access :=
142+
new Did_Change_Job'
143+
(Parent => Self'Unchecked_Access,
144+
Document => Document,
145+
Message => Message,
146+
Is_Done => False);
147+
begin
148+
return LSP.Server_Jobs.Server_Job_Access (Result);
149+
end Create_Job;
150+
151+
-------------
152+
-- Execute --
153+
-------------
154+
155+
overriding procedure Execute
156+
(Self : in out Did_Change_Job;
157+
Client :
158+
in out LSP.Client_Message_Receivers.Client_Message_Receiver'Class)
159+
is
160+
use type LSP.GPR_Documents.Document_Access;
161+
162+
Message : LSP.Server_Notifications.DidChange.Notification renames
163+
LSP.Server_Notifications.DidChange.Notification (Self.Message.all);
164+
165+
Changes : LSP.Structures.TextDocumentContentChangeEvent_Vector renames
166+
Message.Params.contentChanges;
167+
begin
168+
Self.Is_Done := True;
169+
170+
if Self.Document = null then
171+
return;
172+
end if;
173+
174+
if Is_Incremental (Changes) then
175+
-- If we are applying incremental changes, we can't skip the
176+
-- call to Apply_Changes, since this would break synchronization.
177+
Self.Document.Apply_Changes
178+
(Message.Params.textDocument.version, Changes);
179+
180+
-- However, we should skip the Indexing part if the next didChange
181+
-- message will re-change the text document.
182+
end if;
183+
184+
-- Rest of the work in Complete routine
185+
end Execute;
186+
187+
end LSP.GPR_Did_Change_Document;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 2018-2024, AdaCore --
5+
-- --
6+
-- This is free software; you can redistribute it and/or modify it under --
7+
-- terms of the GNU General Public License as published by the Free Soft- --
8+
-- ware Foundation; either version 3, or (at your option) any later ver- --
9+
-- sion. This software is distributed in the hope that it will be useful, --
10+
-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- --
11+
-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public --
12+
-- License for more details. You should have received a copy of the GNU --
13+
-- General Public License distributed with this software; see file --
14+
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy --
15+
-- of the license. --
16+
------------------------------------------------------------------------------
17+
--
18+
-- This package provides handler and job type for didChange notifications.
19+
20+
with LSP.GPR_Job_Contexts;
21+
with LSP.Server_Message_Handlers;
22+
23+
private with LSP.Server_Jobs;
24+
private with LSP.Server_Messages;
25+
26+
package LSP.GPR_Did_Change_Document is
27+
28+
type GPR_Did_Change_Handler
29+
(Context : not null access LSP.GPR_Job_Contexts.GPR_Job_Context'Class) is
30+
limited new LSP.Server_Message_Handlers.Server_Message_Handler
31+
with private;
32+
33+
private
34+
35+
type GPR_Did_Change_Handler
36+
(Context : not null access LSP.GPR_Job_Contexts.GPR_Job_Context'Class) is
37+
limited new LSP.Server_Message_Handlers.Server_Message_Handler
38+
with null record;
39+
40+
overriding function Create_Job
41+
(Self : GPR_Did_Change_Handler;
42+
Message : LSP.Server_Messages.Server_Message_Access)
43+
return LSP.Server_Jobs.Server_Job_Access;
44+
45+
end LSP.GPR_Did_Change_Document;

source/gpr/lsp-gpr_documents.ads

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
------------------------------------------------------------------------------
22
-- Language Server Protocol --
33
-- --
4-
-- Copyright (C) 2023, AdaCore --
4+
-- Copyright (C) 2023-2024, AdaCore --
55
-- --
66
-- This is free software; you can redistribute it and/or modify it under --
77
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -109,13 +109,10 @@ package LSP.GPR_Documents is
109109

110110
function Get_Open_Document
111111
(Self : access Document_Provider;
112-
URI : LSP.Structures.DocumentUri;
113-
Force : Boolean := False)
112+
URI : LSP.Structures.DocumentUri)
114113
return Document_Access is abstract;
115114
-- Return the open document for the given URI.
116-
-- If the document is not opened, then if Force a new document
117-
-- will be created and must be freed by the user else null will be
118-
-- returned.
115+
-- If the document is not opened null will be returned.
119116

120117
function Get_Open_Document_Version
121118
(Self : access Document_Provider;

source/gpr/lsp-gpr_file_readers.adb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ package body LSP.GPR_File_Readers is
105105
begin
106106
-- First check if the file is an open document
107107

108-
Doc := Self.Handler.Get_Open_Document
109-
(URI => To_URI (Filename),
110-
Force => False);
108+
Doc := Self.Handler.Get_Open_Document (URI => To_URI (Filename));
111109

112110
-- Preprocess the document's contents if open, or the file contents if
113111
-- not.

source/gpr/lsp-gpr_handlers.adb

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,6 @@ package body LSP.GPR_Handlers is
4242
GNATCOLL.Traces.On);
4343
-- Trace to activate the support for incremental text changes.
4444

45-
procedure Publish_Diagnostics
46-
(Self : access Message_Handler'Class;
47-
Document : not null LSP.GPR_Documents.Document_Access);
48-
-- Publish diagnostic messages for given document if needed
49-
5045
procedure Log_Unexpected_Null_Document
5146
(Self : access Message_Handler;
5247
Where : String);
@@ -83,8 +78,8 @@ package body LSP.GPR_Handlers is
8378

8479
overriding function Get_Open_Document
8580
(Self : access Message_Handler;
86-
URI : LSP.Structures.DocumentUri;
87-
Force : Boolean := False) return LSP.GPR_Documents.Document_Access
81+
URI : LSP.Structures.DocumentUri)
82+
return LSP.GPR_Documents.Document_Access
8883
is
8984
File : constant GNATCOLL.VFS.Virtual_File := Self.To_File (URI);
9085

@@ -93,21 +88,6 @@ package body LSP.GPR_Handlers is
9388
return
9489
LSP.GPR_Documents.Document_Access
9590
(Self.Open_Documents.Element (File));
96-
97-
elsif Force then
98-
declare
99-
Document : constant Internal_Document_Access :=
100-
new LSP.GPR_Documents.Document (Self.Tracer);
101-
begin
102-
Document.Initialize
103-
(URI,
104-
GPR2.Path_Name.Create (File),
105-
VSS.Strings.Empty_Virtual_String,
106-
Self);
107-
108-
return LSP.GPR_Documents.Document_Access (Document);
109-
end;
110-
11191
else
11292
return null;
11393
end if;
@@ -654,8 +634,8 @@ package body LSP.GPR_Handlers is
654634
-- Publish_Diagnostics --
655635
-------------------------
656636

657-
procedure Publish_Diagnostics
658-
(Self : access Message_Handler'Class;
637+
overriding procedure Publish_Diagnostics
638+
(Self : in out Message_Handler;
659639
Document : not null LSP.GPR_Documents.Document_Access)
660640
is
661641
Changed : Boolean;

0 commit comments

Comments
 (0)