Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c3e2032

Browse files
committedApr 4, 2024
Merge branch 'topic/merge_to_edge' into 'edge'
Rewrite `textDocument/declaration` as a job See merge request eng/ide/ada_language_server!1530
2 parents baf0cfa + f81b2e0 commit c3e2032

6 files changed

+309
-167
lines changed
 

‎Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ vscode-package:
160160
check: all
161161
set -e; \
162162
export PYTHON=$(PYTHON); \
163-
if [ `$(PYTHON) -c "import sys;print('e3' in sys.modules)"` = "True" ]; then\
163+
if [ `$(PYTHON) -c "import e3,sys;print('e3' in sys.modules)"` = "True" ]; then\
164164
(cd testsuite ; sh run.sh $(test)) ; \
165165
else \
166166
for a in testsuite/*_lsp/*/*.json; do \

‎source/ada/lsp-ada_declaration.adb

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 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.Traces;
19+
with GNATCOLL.VFS;
20+
21+
with Libadalang.Analysis;
22+
with Libadalang.Common;
23+
24+
with Laltools.Common;
25+
26+
with LSP.Ada_Context_Sets;
27+
with LSP.Ada_Handlers.Locations;
28+
with LSP.Client_Message_Receivers;
29+
with LSP.Enumerations;
30+
with LSP.Locations;
31+
with LSP.Server_Request_Jobs;
32+
with LSP.Server_Requests.Declaration;
33+
with LSP.Structures;
34+
35+
package body LSP.Ada_Declaration is
36+
37+
subtype AlsReferenceKind_Array is LSP.Structures.AlsReferenceKind_Set;
38+
39+
function Is_Parent return AlsReferenceKind_Array is
40+
([LSP.Enumerations.parent => True, others => False]);
41+
42+
function Is_Child return AlsReferenceKind_Array is
43+
([LSP.Enumerations.child => True, others => False]);
44+
45+
type Ada_Declaration_Job
46+
(Parent : not null access constant Ada_Declaration_Handler) is limited
47+
new LSP.Server_Request_Jobs.Server_Request_Job
48+
(Priority => LSP.Server_Jobs.High)
49+
with record
50+
Response : LSP.Structures.Location_Vector;
51+
Filter : LSP.Locations.File_Span_Sets.Set;
52+
Contexts : LSP.Ada_Context_Sets.Context_Lists.List;
53+
end record;
54+
55+
type Ada_Declaration_Job_Access is access all Ada_Declaration_Job;
56+
57+
overriding procedure Execute_Request
58+
(Self : in out Ada_Declaration_Job;
59+
Client :
60+
in out LSP.Client_Message_Receivers.Client_Message_Receiver'Class;
61+
Status : out LSP.Server_Jobs.Execution_Status);
62+
63+
function "or"
64+
(Left :
65+
LSP.Structures.AlsDisplayMethodAncestryOnNavigationPolicy_Optional;
66+
Right : LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy)
67+
return LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy is
68+
(if Left.Is_Set then Left.Value else Right);
69+
70+
----------------
71+
-- Create_Job --
72+
----------------
73+
74+
overriding function Create_Job
75+
(Self : Ada_Declaration_Handler;
76+
Message : LSP.Server_Messages.Server_Message_Access)
77+
return LSP.Server_Jobs.Server_Job_Access
78+
is
79+
Value : LSP.Server_Requests.Declaration.Request
80+
renames LSP.Server_Requests.Declaration.Request
81+
(Message.all);
82+
83+
File : constant GNATCOLL.VFS.Virtual_File :=
84+
Self.Context.To_File (Value.Params.textDocument.uri);
85+
86+
Result : constant Ada_Declaration_Job_Access :=
87+
new Ada_Declaration_Job'
88+
(Parent => Self'Unchecked_Access,
89+
Request => LSP.Server_Request_Jobs.Request_Access (Message),
90+
others => <>);
91+
begin
92+
Result.Contexts := Self.Context.Contexts_For_File (File);
93+
94+
return LSP.Server_Jobs.Server_Job_Access (Result);
95+
end Create_Job;
96+
97+
---------------------
98+
-- Execute_Request --
99+
---------------------
100+
101+
overriding procedure Execute_Request
102+
(Self : in out Ada_Declaration_Job;
103+
Client :
104+
in out LSP.Client_Message_Receivers.Client_Message_Receiver'Class;
105+
Status : out LSP.Server_Jobs.Execution_Status)
106+
is
107+
use type
108+
LSP.Structures.AlsDisplayMethodAncestryOnNavigationPolicy_Optional;
109+
110+
use all type LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy;
111+
112+
Message : LSP.Server_Requests.Declaration.Request
113+
renames LSP.Server_Requests.Declaration.Request (Self.Message.all);
114+
115+
Value : LSP.Structures.DeclarationParams renames Message.Params;
116+
117+
Context : LSP.Ada_Context_Sets.Context_Access;
118+
119+
Display_Method_Policy : constant
120+
LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy :=
121+
Value.alsDisplayMethodAncestryOnNavigation
122+
or
123+
Self.Parent.Context.Get_Configuration.Display_Method_Ancestry_Policy;
124+
125+
Trace : constant GNATCOLL.Traces.Trace_Handle :=
126+
Self.Parent.Context.Get_Trace_Handle;
127+
128+
Name_Node : Libadalang.Analysis.Name;
129+
130+
Definition : Libadalang.Analysis.Defining_Name;
131+
-- A defining name that corresponds to Name_Node
132+
First_Part : Libadalang.Analysis.Defining_Name;
133+
-- "Canonical part" of Definition
134+
Prev_Part : Libadalang.Analysis.Defining_Name;
135+
-- A previous name for Definition
136+
Decl_For_Find_Overrides : Libadalang.Analysis.Basic_Decl :=
137+
Libadalang.Analysis.No_Basic_Decl;
138+
139+
On_Defining_Name : Boolean := False;
140+
-- Set to True if we are on a denfining name node
141+
142+
Ignore : Boolean;
143+
begin
144+
if Self.Contexts.Is_Empty then
145+
-- No more contexts to process, sort and return collected results
146+
LSP.Ada_Handlers.Locations.Sort (Self.Response);
147+
148+
Client.On_Declaration_Response
149+
(Message.Id,
150+
(Kind => LSP.Structures.Variant_1,
151+
Variant_1 => Self.Response));
152+
153+
Status := LSP.Server_Jobs.Done;
154+
155+
return;
156+
else
157+
Status := LSP.Server_Jobs.Continue;
158+
end if;
159+
160+
Context := Self.Contexts.First_Element;
161+
Self.Contexts.Delete_First;
162+
163+
Name_Node := Laltools.Common.Get_Node_As_Name
164+
(Self.Parent.Context.Get_Node_At (Context.all, Value));
165+
166+
if Name_Node.Is_Null then
167+
return;
168+
end if;
169+
170+
-- Check if we are on some defining name
171+
Definition := Laltools.Common.Get_Name_As_Defining (Name_Node);
172+
173+
if Definition.Is_Null then
174+
-- If we aren't on a defining_name already then try to resolve
175+
Definition := Laltools.Common.Resolve_Name (Name_Node, Trace, Ignore);
176+
else
177+
On_Defining_Name := True;
178+
end if;
179+
180+
if Definition.Is_Null then
181+
return; -- Name resolution fails, nothing to do.
182+
end if;
183+
184+
-- Display the method ancestry in three cases:
185+
--
186+
-- . When the preference is set to Always
187+
--
188+
-- . When we are on a usage node (e.g: subprogram call) and if the
189+
-- preference is set to Usage_And_Abstract_Only
190+
--
191+
-- . When we are on a defining name node and if the preference is
192+
-- set to Definition_Only
193+
194+
if Display_Method_Policy = Always
195+
or else (Display_Method_Policy = Usage_And_Abstract_Only
196+
and then not On_Defining_Name)
197+
or else (Display_Method_Policy = Definition_Only
198+
and then On_Defining_Name)
199+
then
200+
First_Part := Laltools.Common.Find_Canonical_Part (Definition, Trace);
201+
202+
Decl_For_Find_Overrides :=
203+
(if First_Part.Is_Null then Definition.P_Basic_Decl
204+
else First_Part.P_Basic_Decl);
205+
end if;
206+
207+
begin
208+
Prev_Part := Definition.P_Previous_Part;
209+
exception
210+
when E : Libadalang.Common.Property_Error =>
211+
Self.Parent.Context.Trace_Exception (E);
212+
Prev_Part := Libadalang.Analysis.No_Defining_Name;
213+
end;
214+
215+
if not Prev_Part.Is_Null then
216+
-- We have found previous part, return it.
217+
Self.Parent.Context.Append_Location
218+
(Self.Response,
219+
Self.Filter,
220+
Prev_Part);
221+
elsif not Definition.Is_Null then
222+
-- No previous part, return definition itself.
223+
Self.Parent.Context.Append_Location
224+
(Self.Response,
225+
Self.Filter,
226+
Definition);
227+
end if;
228+
229+
if not Decl_For_Find_Overrides.Is_Null then
230+
declare
231+
Overridings : constant Libadalang.Analysis.Basic_Decl_Array :=
232+
Context.Find_All_Overrides
233+
(Decl_For_Find_Overrides,
234+
Imprecise_Results => Ignore);
235+
236+
Bases : constant Libadalang.Analysis.Basic_Decl_Array :=
237+
Context.Find_All_Base_Declarations
238+
(Decl_For_Find_Overrides,
239+
Imprecise_Results => Ignore);
240+
begin
241+
for Subp of Bases loop
242+
Self.Parent.Context.Append_Location
243+
(Self.Response,
244+
Self.Filter,
245+
Subp.P_Defining_Name,
246+
Is_Parent);
247+
end loop;
248+
249+
for Subp of Overridings loop
250+
Self.Parent.Context.Append_Location
251+
(Self.Response,
252+
Self.Filter,
253+
Subp.P_Defining_Name,
254+
Is_Child);
255+
end loop;
256+
end;
257+
end if;
258+
end Execute_Request;
259+
260+
end LSP.Ada_Declaration;

‎source/ada/lsp-ada_declaration.ads

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 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 types for textDocument/declaration
19+
-- requests.
20+
21+
with LSP.Ada_Job_Contexts;
22+
with LSP.Server_Jobs;
23+
with LSP.Server_Message_Handlers;
24+
with LSP.Server_Messages;
25+
26+
package LSP.Ada_Declaration is
27+
28+
type Ada_Declaration_Handler
29+
(Context : not null access LSP.Ada_Job_Contexts.Ada_Job_Context'Class) is
30+
limited new LSP.Server_Message_Handlers.Server_Message_Handler
31+
with null record;
32+
33+
overriding function Create_Job
34+
(Self : Ada_Declaration_Handler;
35+
Message : LSP.Server_Messages.Server_Message_Access)
36+
return LSP.Server_Jobs.Server_Job_Access;
37+
38+
end LSP.Ada_Declaration;

‎source/ada/lsp-ada_driver.adb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ with GNATCOLL.Utils;
3939

4040
with LSP.Ada_Commands;
4141
with LSP.Ada_Definition;
42+
with LSP.Ada_Declaration;
4243
with LSP.Ada_Did_Change_Configurations;
4344
with LSP.Ada_Did_Change_Document;
4445
with LSP.Ada_Hover;
@@ -78,6 +79,7 @@ with LSP.Secure_Message_Loggers;
7879
with LSP.Server_Notifications.DidChange;
7980
with LSP.Server_Notifications.DidChangeConfiguration;
8081
with LSP.Server_Requests.Definition;
82+
with LSP.Server_Requests.Declaration;
8183
with LSP.Server_Requests.Hover;
8284
with LSP.Server_Requests.References;
8385
with LSP.Servers;
@@ -195,6 +197,10 @@ procedure LSP.Ada_Driver is
195197
Ada_Definition_Handler : aliased LSP.Ada_Definition.Ada_Definition_Handler
196198
(Ada_Handler'Unchecked_Access);
197199

200+
Ada_Declaration_Handler : aliased
201+
LSP.Ada_Declaration.Ada_Declaration_Handler
202+
(Ada_Handler'Unchecked_Access);
203+
198204
GPR_Did_Change_Doc_Handler : aliased
199205
LSP.GPR_Did_Change_Document.GPR_Did_Change_Handler
200206
(GPR_Handler'Unchecked_Access);
@@ -411,6 +417,10 @@ begin
411417
(LSP.Server_Requests.Definition.Request'Tag,
412418
Ada_Definition_Handler'Unchecked_Access);
413419

420+
Server.Register_Handler
421+
(LSP.Server_Requests.Declaration.Request'Tag,
422+
Ada_Declaration_Handler'Unchecked_Access);
423+
414424
Server.Register_Handler
415425
(LSP.Server_Requests.References.Request'Tag,
416426
Ada_References_Handler'Unchecked_Access);

‎source/ada/lsp-ada_handlers.adb

Lines changed: 0 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,167 +1688,6 @@ package body LSP.Ada_Handlers is
16881688
Self.Sender.On_Completion_Resolve_Response (Id, Response);
16891689
end On_Completion_Resolve_Request;
16901690

1691-
----------------------------
1692-
-- On_Declaration_Request --
1693-
----------------------------
1694-
1695-
overriding procedure On_Declaration_Request
1696-
(Self : in out Message_Handler;
1697-
Id : LSP.Structures.Integer_Or_Virtual_String;
1698-
Value : LSP.Structures.DeclarationParams)
1699-
is
1700-
use Libadalang.Analysis;
1701-
use all type LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy;
1702-
1703-
procedure Resolve_In_Context (C : LSP.Ada_Context_Sets.Context_Access);
1704-
-- Utility function, appends to Vector all results of the
1705-
-- declaration requests found in context C.
1706-
1707-
Response : LSP.Structures.Declaration_Result (LSP.Structures.Variant_1);
1708-
Vector : LSP.Structures.Location_Vector renames Response.Variant_1;
1709-
Filter : LSP.Locations.File_Span_Sets.Set;
1710-
1711-
Display_Method_Policy : constant
1712-
LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy :=
1713-
(if Value.alsDisplayMethodAncestryOnNavigation.Is_Set
1714-
then Value.alsDisplayMethodAncestryOnNavigation.Value
1715-
else Self.Configuration.Display_Method_Ancestry_Policy);
1716-
1717-
------------------------
1718-
-- Resolve_In_Context --
1719-
------------------------
1720-
1721-
procedure Resolve_In_Context (C : LSP.Ada_Context_Sets.Context_Access) is
1722-
Trace : constant GNATCOLL.Traces.Trace_Handle :=
1723-
LSP.GNATCOLL_Tracers.Handle (Self.Tracer.all);
1724-
1725-
Name_Node : constant Name :=
1726-
Laltools.Common.Get_Node_As_Name (Self.Get_Node_At (C.all, Value));
1727-
1728-
Definition : Libadalang.Analysis.Defining_Name;
1729-
-- A defining name that corresponds to Name_Node
1730-
First_Part : Libadalang.Analysis.Defining_Name;
1731-
-- "Canonical part" of Definition
1732-
Prev_Part : Libadalang.Analysis.Defining_Name;
1733-
-- A previous name for Definition
1734-
Decl_For_Find_Overrides : Libadalang.Analysis.Basic_Decl :=
1735-
Libadalang.Analysis.No_Basic_Decl;
1736-
1737-
On_Defining_Name : Boolean := False;
1738-
-- Set to True if we are on a denfining name node
1739-
1740-
Imprecise_Ignore : Libadalang.Common.Ref_Result_Kind;
1741-
1742-
begin
1743-
if Name_Node.Is_Null then
1744-
return;
1745-
end if;
1746-
1747-
-- Check if we are on some defining name
1748-
Definition := Laltools.Common.Get_Name_As_Defining (Name_Node);
1749-
1750-
if Definition.Is_Null then
1751-
-- If we aren't on a defining_name already then try to resolve
1752-
Definition :=
1753-
Resolve_Name
1754-
(Self => Self,
1755-
Id => Id,
1756-
Context => C.all,
1757-
Name_Node => Name_Node,
1758-
Imprecise => Imprecise_Ignore);
1759-
else
1760-
On_Defining_Name := True;
1761-
end if;
1762-
1763-
if Definition.Is_Null then
1764-
return; -- Name resolution fails, nothing to do.
1765-
end if;
1766-
1767-
-- Display the method ancestry in three cases:
1768-
--
1769-
-- . When the preference is set to Always
1770-
--
1771-
-- . When we are on a usage node (e.g: subprogram call) and if the
1772-
-- preference is set to Usage_And_Abstract_Only
1773-
--
1774-
-- . When we are on a defining name node and if the preference is
1775-
-- set to Definition_Only
1776-
1777-
if Display_Method_Policy = Always
1778-
or else (Display_Method_Policy = Usage_And_Abstract_Only
1779-
and then not On_Defining_Name)
1780-
or else (Display_Method_Policy = Definition_Only
1781-
and then On_Defining_Name)
1782-
then
1783-
First_Part := Laltools.Common.Find_Canonical_Part (Definition, Trace);
1784-
1785-
if First_Part.Is_Null then
1786-
Decl_For_Find_Overrides := Definition.P_Basic_Decl;
1787-
else
1788-
Decl_For_Find_Overrides := First_Part.P_Basic_Decl;
1789-
end if;
1790-
end if;
1791-
1792-
begin
1793-
Prev_Part := Definition.P_Previous_Part;
1794-
exception
1795-
when E : Libadalang.Common.Property_Error =>
1796-
Self.Tracer.Trace_Exception (E);
1797-
Prev_Part := Libadalang.Analysis.No_Defining_Name;
1798-
end;
1799-
1800-
if not Prev_Part.Is_Null then
1801-
-- We have found previous part, return it.
1802-
Self.Append_Location (Vector, Filter, Prev_Part);
1803-
elsif not Definition.Is_Null then
1804-
-- No previous part, return definition itself.
1805-
Self.Append_Location (Vector, Filter, Definition);
1806-
end if;
1807-
1808-
if not Decl_For_Find_Overrides.Is_Null then
1809-
declare
1810-
Overridings : constant Libadalang.Analysis.Basic_Decl_Array :=
1811-
C.Find_All_Overrides
1812-
(Decl_For_Find_Overrides,
1813-
Imprecise_Results => Imprecise_Ignore);
1814-
1815-
Bases : constant Libadalang.Analysis.Basic_Decl_Array :=
1816-
C.Find_All_Base_Declarations
1817-
(Decl_For_Find_Overrides,
1818-
Imprecise_Results => Imprecise_Ignore);
1819-
begin
1820-
for Subp of Bases loop
1821-
Self.Append_Location
1822-
(Vector, Filter, Subp.P_Defining_Name, Is_Parent);
1823-
end loop;
1824-
1825-
for Subp of Overridings loop
1826-
Self.Append_Location
1827-
(Vector, Filter, Subp.P_Defining_Name, Is_Child);
1828-
end loop;
1829-
end;
1830-
end if;
1831-
end Resolve_In_Context;
1832-
1833-
begin
1834-
-- Override the displayMethodAncestryOnNavigation global configuration
1835-
-- flag if there is on embedded in the request.
1836-
-- if Value.alsDisplayMethodAncestryOnNavigation.Is_Set then
1837-
-- Display_Method_Ancestry_Policy :=
1838-
-- Value.alsDisplayMethodAncestryOnNavigation.Value;
1839-
-- end if;
1840-
1841-
for C of Self.Contexts_For_URI (Value.textDocument.uri) loop
1842-
Resolve_In_Context (C);
1843-
1844-
exit when Self.Is_Canceled.all;
1845-
end loop;
1846-
1847-
Locations.Sort (Vector);
1848-
1849-
Self.Sender.On_Declaration_Response (Id, Response);
1850-
end On_Declaration_Request;
1851-
18521691
-------------------------------------------
18531692
-- On_DidChangeWatchedFiles_Notification --
18541693
-------------------------------------------

‎source/ada/lsp-ada_handlers.ads

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -294,11 +294,6 @@ private
294294
Id : LSP.Structures.Integer_Or_Virtual_String;
295295
Value : LSP.Structures.AlsCheckSyntaxParams);
296296

297-
overriding procedure On_Declaration_Request
298-
(Self : in out Message_Handler;
299-
Id : LSP.Structures.Integer_Or_Virtual_String;
300-
Value : LSP.Structures.DeclarationParams);
301-
302297
overriding procedure On_DocumentHighlight_Request
303298
(Self : in out Message_Handler;
304299
Id : LSP.Structures.Integer_Or_Virtual_String;

0 commit comments

Comments
 (0)
Please sign in to comment.