Skip to content

Commit 3bbc319

Browse files
committed
Merge branch 'topic/def' into 'master'
Add to `definition` response See merge request eng/ide/ada_language_server!2049
2 parents 9576f08 + 9211fc6 commit 3bbc319

File tree

18 files changed

+1491
-516
lines changed

18 files changed

+1491
-516
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ section below it for the last release. -->
55
## \<next>
66

77
* Added a `Ada: Report Issue` command that opens the [VS Code Issue Reporter](https://code.visualstudio.com/docs/supporting/FAQ#_report-an-issue-with-a-vs-code-extension) with an extension-specific template
8+
* Add `begin` and `private` destinations to `texDocument/definition` response triggered
9+
respectively on subprograms and packages (e.g: ctrl-click on a subprogram name will
10+
jump to `begin` in the subprogram body, while ctrl-clicking on a package spec name will
11+
jump to its private part, if any).
812

913
## 26.0.202507021
1014

source/ada/lsp-ada_declaration.adb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,8 @@ package body LSP.Ada_Declaration is
219219
(Self.Response,
220220
Self.Filter,
221221
Prev_Part);
222-
elsif not Definition.Is_Null then
223-
-- No previous part, return definition itself.
222+
else
223+
-- No previous part, return definition itself, if not null.
224224
Self.Parent.Context.Append_Location
225225
(Self.Response,
226226
Self.Filter,

source/ada/lsp-ada_definition.adb

Lines changed: 180 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,15 @@ package body LSP.Ada_Definition is
9999
is
100100
use all type LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy;
101101

102+
procedure Append_Accept_Statements (Decl : Libadalang.Analysis.Basic_Decl);
103+
-- Search for accept statements if we are on an entry
104+
105+
procedure Append_Overrides (Decl : Libadalang.Analysis.Basic_Decl);
106+
-- Append overloaded subprograms for given declaration
107+
108+
procedure Append_Prev_Token (Node : Libadalang.Analysis.Ada_Node'Class);
109+
-- Find a token before Node and append its location to Result
110+
102111
Message : LSP.Server_Requests.Definition.Request
103112
renames LSP.Server_Requests.Definition.Request (Self.Message.all);
104113

@@ -119,11 +128,102 @@ package body LSP.Ada_Definition is
119128
Name_Node : Libadalang.Analysis.Name;
120129
Definition : Libadalang.Analysis.Defining_Name;
121130
Other_Part : Libadalang.Analysis.Defining_Name;
122-
Manual_Fallback : Libadalang.Analysis.Defining_Name;
123-
Definition_Node : Libadalang.Analysis.Basic_Decl;
131+
Declaration : Libadalang.Analysis.Basic_Decl;
124132
Decl_For_Find_Overrides : Libadalang.Analysis.Basic_Decl;
125133

126134
Ignore : Boolean;
135+
136+
------------------------------
137+
-- Append_Accept_Statements --
138+
------------------------------
139+
140+
procedure Append_Accept_Statements
141+
(Decl : Libadalang.Analysis.Basic_Decl) is
142+
begin
143+
-- Search for accept statements only if we are on an entry
144+
if not Decl.Is_Null
145+
and then Decl.Kind in Libadalang.Common.Ada_Entry_Decl_Range
146+
then
147+
declare
148+
Entry_Decl_Node : constant Libadalang.Analysis.Entry_Decl :=
149+
Decl.As_Entry_Decl;
150+
Entry_Parent_Node : constant Libadalang.Analysis.Basic_Decl :=
151+
Entry_Decl_Node.P_Parent_Basic_Decl;
152+
begin
153+
-- P_Accept_Stmts is only valid for entries declared in tasks
154+
if Entry_Parent_Node.Kind in
155+
Libadalang.Common.Ada_Task_Type_Decl_Range
156+
then
157+
for Accept_Node of Entry_Decl_Node.P_Accept_Stmts loop
158+
Self.Parent.Context.Append_Location
159+
(Self.Response,
160+
Self.Filter,
161+
Accept_Node.F_Body_Decl.F_Name);
162+
end loop;
163+
end if;
164+
end;
165+
end if;
166+
end Append_Accept_Statements;
167+
168+
----------------------
169+
-- Append_Overrides --
170+
----------------------
171+
172+
procedure Append_Overrides (Decl : Libadalang.Analysis.Basic_Decl) is
173+
begin
174+
if not Decl.Is_Null then
175+
declare
176+
Overridings : constant Libadalang.Analysis.Basic_Decl_Array :=
177+
Context.Find_All_Overrides
178+
(Decl,
179+
Imprecise_Results => Ignore);
180+
181+
Bases : constant Libadalang.Analysis.Basic_Decl_Array :=
182+
Context.Find_All_Base_Declarations
183+
(Decl,
184+
Imprecise_Results => Ignore);
185+
begin
186+
for Subp of Bases loop
187+
Self.Parent.Context.Append_Location
188+
(Self.Response,
189+
Self.Filter,
190+
Subp.P_Defining_Name,
191+
Is_Parent);
192+
end loop;
193+
194+
for Subp of Overridings loop
195+
Self.Parent.Context.Append_Location
196+
(Self.Response,
197+
Self.Filter,
198+
Subp.P_Defining_Name,
199+
Is_Child);
200+
end loop;
201+
end;
202+
end if;
203+
end Append_Overrides;
204+
205+
-----------------------
206+
-- Append_Prev_Token --
207+
-----------------------
208+
209+
procedure Append_Prev_Token
210+
(Node : Libadalang.Analysis.Ada_Node'Class) is
211+
begin
212+
if not Node.Is_Null then
213+
declare
214+
Prev : constant Libadalang.Common.Token_Reference :=
215+
Libadalang.Common.Previous (Node.Token_Start, True);
216+
217+
begin
218+
Self.Parent.Context.Append_Location
219+
(Result => Self.Response,
220+
Filter => Self.Filter,
221+
Unit => Node.Unit,
222+
Token => Prev);
223+
end;
224+
end if;
225+
end Append_Prev_Token;
226+
127227
begin
128228
if Self.Contexts.Is_Empty then
129229
-- No more contexts to process, sort and return collected results
@@ -151,10 +251,16 @@ package body LSP.Ada_Definition is
151251
return;
152252
end if;
153253

254+
-- We distinguish two cases here. When we navigate from the usage_name,
255+
-- we simply go to the defining_name. When we are already at the
256+
-- defining_name, we try to go to completion and add additional
257+
-- destinations, such as overrides, accept_statements, etc.
258+
154259
-- Check if we are on some defining name
155260
Definition := Laltools.Common.Get_Name_As_Defining (Name_Node);
156261

157262
if Definition.Is_Null then
263+
-- If we are on a usage_name, go to defining_name
158264
Definition := Self.Parent.Context.Imprecise_Resolve_Name (Name_Node);
159265

160266
if not Definition.Is_Null then
@@ -167,72 +273,22 @@ package body LSP.Ada_Definition is
167273
Decl_For_Find_Overrides := Definition.P_Basic_Decl;
168274
end if;
169275
end if;
170-
else -- If we are on a defining_name already
171-
Other_Part := Laltools.Common.Find_Next_Part (Definition, Trace);
276+
else -- If we are on a defining_name already, find other_part
172277

173-
Definition_Node := Definition.P_Basic_Decl;
278+
Declaration := Definition.P_Basic_Decl;
174279

175-
-- Search for overriding subprograms only if we are on an
176-
-- abstract subprogram.
177-
if Display_Method_Policy /= Never
178-
and then
179-
(Display_Method_Policy /= Usage_And_Abstract_Only
180-
or else Definition_Node.Kind in
181-
Libadalang.Common.Ada_Abstract_Subp_Decl_Range)
182-
then
183-
Decl_For_Find_Overrides := Definition_Node;
184-
end if;
185-
186-
-- Search for accept statements only if we are on an entry
187-
if Definition_Node.Kind in Libadalang.Common.Ada_Entry_Decl_Range then
188-
declare
189-
Entry_Decl_Node : constant Libadalang.Analysis.Entry_Decl :=
190-
Definition_Node.As_Entry_Decl;
191-
Entry_Parent_Node : constant Libadalang.Analysis.Basic_Decl :=
192-
Entry_Decl_Node.P_Parent_Basic_Decl;
193-
begin
194-
-- P_Accept_Stmts is only valid for entries declared in tasks
195-
if Entry_Parent_Node.Kind in
196-
Libadalang.Common.Ada_Task_Type_Decl_Range
197-
then
198-
for Accept_Node of Entry_Decl_Node.P_Accept_Stmts loop
199-
Self.Parent.Context.Append_Location
200-
(Self.Response,
201-
Self.Filter,
202-
Accept_Node.F_Body_Decl.F_Name);
203-
end loop;
204-
205-
-- Others entries are are handled as simple subprograms
206-
else
207-
declare
208-
Other_Part_For_Decl : constant
209-
Libadalang.Analysis.Basic_Decl :=
210-
Laltools.Common.Find_Next_Part_For_Decl
211-
(Definition_Node, Trace);
212-
begin
213-
if not Other_Part_For_Decl.Is_Null then
214-
Other_Part := Other_Part_For_Decl.P_Defining_Name;
215-
end if;
216-
end;
217-
end if;
218-
end;
219-
220-
elsif Definition_Node.Kind in
221-
Libadalang.Common.Ada_Single_Task_Type_Decl_Range |
222-
Libadalang.Common.Ada_Protected_Type_Decl_Range
223-
then
224-
-- These node types are not handled by Find_Next_Part
225-
-- (LAL design limitations)
226-
declare
227-
Other_Part_For_Decl : constant Libadalang.Analysis.Basic_Decl :=
228-
Laltools.Common.Find_Next_Part_For_Decl
229-
(Definition_Node, Trace);
230-
begin
231-
if not Other_Part_For_Decl.Is_Null then
232-
Other_Part := Other_Part_For_Decl.P_Defining_Name;
233-
end if;
234-
end;
235-
end if;
280+
-- Some node types are not handled by Find_Next_Part
281+
-- (LAL design limitations), so we use Find_Next_Part_For_Decl
282+
-- instead.
283+
declare
284+
Other_Part_For_Decl : constant Libadalang.Analysis.Basic_Decl :=
285+
Laltools.Common.Find_Next_Part_For_Decl
286+
(Declaration, Trace);
287+
begin
288+
if not Other_Part_For_Decl.Is_Null then
289+
Other_Part := Other_Part_For_Decl.P_Defining_Name;
290+
end if;
291+
end;
236292

237293
if Other_Part.Is_Null then
238294
-- No next part is found. Check first defining name
@@ -245,55 +301,75 @@ package body LSP.Ada_Definition is
245301
-- an answer using Find_Next_Part / Find_Canonical_Part.
246302
-- Use the manual fallback to attempt to find a good enough
247303
-- result.
248-
Manual_Fallback := Laltools.Common.Find_Other_Part_Fallback
304+
Other_Part := Laltools.Common.Find_Other_Part_Fallback
249305
(Definition, Trace);
306+
end if;
250307

251-
if not Manual_Fallback.Is_Null then
252-
-- We have found a result using the imprecise heuristics.
253-
-- We'll warn the user and send the result.
254-
Self.Parent.Context.Append_Location
255-
(Self.Response,
256-
Self.Filter,
257-
Manual_Fallback);
258-
end if;
259-
else
308+
if not Other_Part.Is_Null then
260309
Self.Parent.Context.Append_Location
261310
(Self.Response,
262311
Self.Filter,
263312
Other_Part);
313+
end if;
314+
315+
Append_Accept_Statements (Declaration);
264316

317+
-- Search for overriding subprograms only if we are on an
318+
-- abstract subprogram.
319+
if Display_Method_Policy /= Never
320+
and then
321+
(Display_Method_Policy /= Usage_And_Abstract_Only
322+
or else Declaration.Kind in
323+
Libadalang.Common.Ada_Abstract_Subp_Decl_Range)
324+
then
325+
Decl_For_Find_Overrides := Declaration;
265326
end if;
266-
end if;
267327

268-
if not Decl_For_Find_Overrides.Is_Null then
269-
declare
270-
Overridings : constant Libadalang.Analysis.Basic_Decl_Array :=
271-
Context.Find_All_Overrides
272-
(Decl_For_Find_Overrides,
273-
Imprecise_Results => Ignore);
274-
275-
Bases : constant Libadalang.Analysis.Basic_Decl_Array :=
276-
Context.Find_All_Base_Declarations
277-
(Decl_For_Find_Overrides,
278-
Imprecise_Results => Ignore);
279-
begin
280-
for Subp of Bases loop
281-
Self.Parent.Context.Append_Location
282-
(Self.Response,
283-
Self.Filter,
284-
Subp.P_Defining_Name,
285-
Is_Parent);
286-
end loop;
328+
-- Append private part, begin destinations to result
329+
for Part of Definition.P_Basic_Decl.P_All_Parts loop
330+
case Part.Kind is
287331

288-
for Subp of Overridings loop
289-
Self.Parent.Context.Append_Location
290-
(Self.Response,
291-
Self.Filter,
292-
Subp.P_Defining_Name,
293-
Is_Child);
294-
end loop;
295-
end;
332+
when Libadalang.Common.Ada_Package_Body_Range =>
333+
Append_Prev_Token
334+
(Part.As_Package_Body.F_Stmts);
335+
336+
when Libadalang.Common.Ada_Subp_Body_Range =>
337+
Append_Prev_Token
338+
(Part.As_Subp_Body.F_Stmts);
339+
340+
when Libadalang.Common.Ada_Task_Body_Range =>
341+
Append_Prev_Token
342+
(Part.As_Task_Body.F_Stmts);
343+
344+
when Libadalang.Common.Ada_Base_Package_Decl =>
345+
Append_Prev_Token
346+
(Part.As_Base_Package_Decl.F_Private_Part);
347+
348+
when Libadalang.Common.Ada_Protected_Type_Decl_Range =>
349+
Append_Prev_Token
350+
(Part.As_Protected_Type_Decl.F_Definition.F_Private_Part);
351+
352+
when Libadalang.Common.Ada_Single_Protected_Decl_Range =>
353+
Append_Prev_Token
354+
(Part.As_Single_Protected_Decl.F_Definition.
355+
F_Private_Part);
356+
357+
when Libadalang.Common.Ada_Task_Type_Decl_Range =>
358+
Append_Prev_Token
359+
(Part.As_Task_Type_Decl.F_Definition.F_Private_Part);
360+
361+
when Libadalang.Common.Ada_Single_Task_Decl_Range =>
362+
Append_Prev_Token
363+
(Part.As_Single_Task_Decl.F_Task_Type.F_Definition.
364+
F_Private_Part);
365+
366+
when others =>
367+
null;
368+
end case;
369+
end loop;
296370
end if;
371+
372+
Append_Overrides (Decl_For_Find_Overrides);
297373
end Execute_Ada_Request;
298374

299375
end LSP.Ada_Definition;

0 commit comments

Comments
 (0)