@@ -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
299375end LSP.Ada_Definition ;
0 commit comments