Skip to content

Commit 670554a

Browse files
committed
Merge branch 'topic/rm-proc' into 'master'
Add "Delete Entity" refactoring. See merge request eng/ide/ada_language_server!2083
2 parents 98ff13b + 5f39179 commit 670554a

File tree

13 files changed

+836
-0
lines changed

13 files changed

+836
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ section below it for the last release. -->
88
* 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
99
* `Go to Definition` now jumps respectively on the `begin`, `private` and `body` keywords
1010
for subprograms, packages and tasks when clicking on the `is` keyword following their declarations
11+
* New refactoring: [Delete Entity](https://github.com/AdaCore/ada_language_server/blob/master/doc/refactoring_tools.md#delete-entity)
1112

1213
## 26.0.202507021
1314

doc/media/delete_entity.gif

81.7 KB
Loading

doc/refactoring_tools.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
* [Extract Variable](#extract-variable)
1616
* [Pull Up Declaration](#pull-up-declaration)
1717
* [Suppress Separate](#suppress-separate)
18+
* [Delete Entity](#delete-entity)
1819
* [Introduce Parameter](#introduce-parameter)
1920
* [Replace Type](#replace-type)
2021
* [Auto Import](#auto-import)
@@ -170,6 +171,24 @@ Demo source is `suppress_separate/` in [Code Samples](https://github.com/AdaCore
170171

171172
![suppress_separate](media/suppress_separate.gif)
172173

174+
## Delete Entity
175+
176+
**Command name:** `als-refactor-delete-entiry`
177+
178+
* Currently works only for procedures.
179+
* Any procedure call is also deleted.
180+
* If call statement is the only one in the statement list, then
181+
- if it is inside a declare/block/end then the block statement is deleted
182+
even if there are exception handlers and declarations in it.
183+
- otherwise it will be replaced with `null;` to keep source correct.
184+
* Non-call references will be reported and prevent the deletion.
185+
186+
See `src/lal_refactor-delete_entity.ads` in [LAL Refactor repository](https://github.com/AdaCore/lal-refactor).
187+
188+
Demo source is `delete_entity/` in [Code Samples](https://github.com/AdaCore/ada_language_server/blob/master/integration/vscode/Code%20Samples/refactoring_demos/).
189+
190+
![delete_entity](media/delete_entity.gif)
191+
173192
## Introduce Parameter
174193

175194
**Command name:** `als-refactor-introduce-parameter`
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
project Default is
2+
for Source_Dirs use ("src");
3+
for Object_Dir use "obj";
4+
for Main use ("main.adb");
5+
end Default;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
procedure Main is
2+
procedure To_Be_Deleted (Value : Float);
3+
4+
Ref : access procedure (Value : Float) := To_Be_Deleted'Access;
5+
-- A "not-a-call" reference to the procedure --------^
6+
7+
procedure To_Be_Deleted (Value : Float) is
8+
begin
9+
if Value > 0.0 then
10+
To_Be_Deleted (Value - 1.0);
11+
end if;
12+
end To_Be_Deleted;
13+
14+
procedure Another is
15+
begin
16+
To_Be_Deleted (9.0); -- We replace this call with null;
17+
end Another;
18+
begin
19+
To_Be_Deleted (9.0);
20+
-- ^ We delete this call
21+
begin
22+
-- We delete whole begin/end block
23+
To_Be_Deleted (9.0);
24+
exception
25+
when others =>
26+
null;
27+
end;
28+
29+
return;
30+
end Main;

source/ada/lsp-ada_driver.adb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ with LSP.Ada_Handlers.Refactor.Add_Parameter;
6767
with LSP.Ada_Handlers.Refactor.Change_Parameter_Mode;
6868
with LSP.Ada_Handlers.Refactor.Change_Parameters_Default_Value;
6969
with LSP.Ada_Handlers.Refactor.Change_Parameters_Type;
70+
with LSP.Ada_Handlers.Refactor.Delete_Entity;
7071
with LSP.Ada_Handlers.Refactor.Extract_Subprogram;
7172
with LSP.Ada_Handlers.Refactor.Extract_Variable;
7273
with LSP.Ada_Handlers.Refactor.Auto_Import;
@@ -217,6 +218,8 @@ procedure LSP.Ada_Driver is
217218
(LSP.Ada_Handlers.Refactor.Auto_Import.Command'Tag);
218219
LSP.Ada_Commands.Register
219220
(LSP.Ada_Handlers.Refactor.Suppress_Seperate.Command'Tag);
221+
LSP.Ada_Commands.Register
222+
(LSP.Ada_Handlers.Refactor.Delete_Entity.Command'Tag);
220223
LSP.Ada_Commands.Register
221224
(LSP.Ada_Handlers.Refactor.Extract_Subprogram.Command'Tag);
222225
LSP.Ada_Commands.Register
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 2022-2025, 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 Langkit_Support.Slocs;
19+
20+
with Libadalang.Analysis;
21+
22+
with LAL_Refactor.Delete_Entity;
23+
24+
with VSS.JSON.Streams;
25+
26+
with LSP.Enumerations;
27+
with LSP.Structures.LSPAny_Vectors; use LSP.Structures.LSPAny_Vectors;
28+
29+
package body LSP.Ada_Handlers.Refactor.Delete_Entity is
30+
31+
------------------------
32+
-- Append_Code_Action --
33+
------------------------
34+
35+
procedure Append_Code_Action
36+
(Self : in out Command;
37+
Context : LSP.Ada_Context_Sets.Context_Access;
38+
Commands_Vector : in out LSP.Structures.Command_Or_CodeAction_Vector;
39+
Where : LSP.Structures.Location)
40+
is
41+
Code_Action : LSP.Structures.CodeAction;
42+
43+
begin
44+
Self.Initialize
45+
(Context => Context.all,
46+
Where => Where);
47+
48+
Code_Action :=
49+
(title => "Delete Entity and all references",
50+
kind =>
51+
(Is_Set => True,
52+
Value => LSP.Enumerations.Refactor),
53+
diagnostics => <>,
54+
edit => (Is_Set => False),
55+
isPreferred => (Is_Set => False),
56+
disabled => (Is_Set => False),
57+
command =>
58+
(Is_Set => True,
59+
Value =>
60+
(title => <>,
61+
command => VSS.Strings.Conversions.To_Virtual_String
62+
(Command'External_Tag),
63+
arguments => Self.Write_Command)),
64+
data => <>);
65+
66+
Commands_Vector.Append
67+
(LSP.Structures.Command_Or_CodeAction'
68+
(Is_Command => False, CodeAction => Code_Action));
69+
end Append_Code_Action;
70+
71+
------------
72+
-- Create --
73+
------------
74+
75+
overriding function Create
76+
(Any : not null access LSP.Structures.LSPAny_Vector)
77+
return Command
78+
is
79+
use VSS.JSON.Streams;
80+
use VSS.Strings;
81+
use LSP.Structures.JSON_Event_Vectors;
82+
83+
C : Cursor := Any.First;
84+
begin
85+
return Self : Command do
86+
pragma Assert (Element (C).Kind = Start_Array);
87+
Next (C);
88+
pragma Assert (Element (C).Kind = Start_Object);
89+
Next (C);
90+
91+
while Has_Element (C)
92+
and then Element (C).Kind /= End_Object
93+
loop
94+
pragma Assert (Element (C).Kind = Key_Name);
95+
declare
96+
Key : constant Virtual_String := Element (C).Key_Name;
97+
begin
98+
Next (C);
99+
100+
if Key = "context" then
101+
Self.Context := Element (C).String_Value;
102+
103+
elsif Key = "where" then
104+
Self.Where := From_Any (C);
105+
106+
else
107+
Skip_Value (C);
108+
end if;
109+
end;
110+
111+
Next (C);
112+
end loop;
113+
end return;
114+
end Create;
115+
116+
--------------
117+
-- Refactor --
118+
--------------
119+
120+
overriding
121+
procedure Refactor
122+
(Self : Command;
123+
Handler : not null access LSP.Ada_Handlers.Message_Handler'Class;
124+
Edits : out LAL_Refactor.Refactoring_Edits)
125+
is
126+
use Langkit_Support.Slocs;
127+
use Libadalang.Analysis;
128+
use LAL_Refactor;
129+
use LAL_Refactor.Delete_Entity;
130+
131+
Message_Handler : LSP.Ada_Handlers.Message_Handler renames
132+
LSP.Ada_Handlers.Message_Handler (Handler.all);
133+
Context : LSP.Ada_Contexts.Context renames
134+
Message_Handler.Contexts.Get (Self.Context).all;
135+
136+
File : constant GNATCOLL.VFS.Virtual_File :=
137+
Message_Handler.To_File (Self.Where.uri);
138+
139+
Unit : constant Analysis_Unit := Context.Get_AU (File);
140+
141+
Declaration_SLOC : constant Source_Location :=
142+
(Langkit_Support.Slocs.Line_Number
143+
(Self.Where.a_range.start.line) + 1,
144+
Langkit_Support.Slocs.Column_Number
145+
(Self.Where.a_range.start.character)
146+
+ 1);
147+
148+
function Analysis_Units return Analysis_Unit_Array is
149+
(Context.Analysis_Units);
150+
-- Provides the Context Analysis_Unit_Array to the Deleteper
151+
152+
Remover : constant Entity_Remover :=
153+
Create_Entity_Deleter (Unit, Declaration_SLOC);
154+
155+
begin
156+
Edits := Remover.Refactor (Analysis_Units'Access);
157+
158+
if not Edits.Diagnostics.Is_Empty then
159+
-- If we have diagnostic then drop any action to make GS report err
160+
Edits.Text_Edits.Clear;
161+
Edits.File_Creations.Clear;
162+
Edits.File_Deletions.Clear;
163+
Edits.File_Renames.Clear;
164+
end if;
165+
end Refactor;
166+
167+
----------------
168+
-- Initialize --
169+
----------------
170+
171+
procedure Initialize
172+
(Self : in out Command'Class;
173+
Context : LSP.Ada_Contexts.Context;
174+
Where : LSP.Structures.Location) is
175+
begin
176+
Self.Context := Context.Id;
177+
Self.Where := Where;
178+
end Initialize;
179+
180+
-------------------
181+
-- Write_Command --
182+
-------------------
183+
184+
function Write_Command
185+
(Self : Command) return LSP.Structures.LSPAny_Vector
186+
is
187+
use VSS.JSON.Streams;
188+
189+
Result : LSP.Structures.LSPAny_Vector;
190+
begin
191+
Result.Append (JSON_Stream_Element'(Kind => Start_Array));
192+
Result.Append (JSON_Stream_Element'(Kind => Start_Object));
193+
194+
-- "context"
195+
Add_Key ("context", Result);
196+
To_Any (Self.Context, Result);
197+
198+
-- "where"
199+
Add_Key ("where", Result);
200+
To_Any (Self.Where, Result);
201+
202+
Result.Append (JSON_Stream_Element'(Kind => End_Object));
203+
Result.Append (JSON_Stream_Element'(Kind => End_Array));
204+
205+
return Result;
206+
end Write_Command;
207+
208+
end LSP.Ada_Handlers.Refactor.Delete_Entity;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 2022-2025, 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+
-- Implementation of the refactoring command to delete an entity and refs
19+
20+
with LSP.Ada_Contexts;
21+
with LSP.Server_Jobs;
22+
23+
private with VSS.Strings;
24+
25+
package LSP.Ada_Handlers.Refactor.Delete_Entity is
26+
27+
type Command is new LSP.Ada_Handlers.Refactor.Command with private;
28+
29+
overriding function Name (Self : Command) return String
30+
is
31+
("Delete Entity and all references");
32+
33+
procedure Append_Code_Action
34+
(Self : in out Command;
35+
Context : LSP.Ada_Context_Sets.Context_Access;
36+
Commands_Vector : in out LSP.Structures.Command_Or_CodeAction_Vector;
37+
Where : LSP.Structures.Location);
38+
-- Initializes Self and appends it to Commands_Vector
39+
40+
private
41+
42+
type Command is new LSP.Ada_Handlers.Refactor.Command with record
43+
Context : VSS.Strings.Virtual_String;
44+
Where : LSP.Structures.Location;
45+
end record;
46+
47+
overriding
48+
function Create
49+
(Any : not null access LSP.Structures.LSPAny_Vector)
50+
return Command;
51+
-- Reads JS and creates a new Command
52+
53+
overriding
54+
procedure Refactor
55+
(Self : Command;
56+
Handler : not null access LSP.Ada_Handlers.Message_Handler'Class;
57+
Edits : out LAL_Refactor.Refactoring_Edits);
58+
-- Executes Self by computing the necessary refactorings
59+
60+
overriding function Priority (Self : Command)
61+
return LSP.Server_Jobs.Job_Priority
62+
is (LSP.Server_Jobs.Low);
63+
64+
procedure Initialize
65+
(Self : in out Command'Class;
66+
Context : LSP.Ada_Contexts.Context;
67+
Where : LSP.Structures.Location);
68+
-- Initializes Self
69+
70+
function Write_Command
71+
(Self : Command) return LSP.Structures.LSPAny_Vector;
72+
73+
for Command'External_Tag use "als-refactor-delete-entity";
74+
75+
end LSP.Ada_Handlers.Refactor.Delete_Entity;

0 commit comments

Comments
 (0)