Skip to content

Commit 14fb47e

Browse files
committed
Support Inline variable refactoring tool
For eng/ide/lal-refactor#35
1 parent 9df2f60 commit 14fb47e

File tree

8 files changed

+612
-0
lines changed

8 files changed

+612
-0
lines changed

source/ada/lsp-ada_driver.adb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ with LSP.Ada_Handlers.Refactor.Delete_Entity;
7171
with LSP.Ada_Handlers.Refactor.Extract_Subprogram;
7272
with LSP.Ada_Handlers.Refactor.Extract_Variable;
7373
with LSP.Ada_Handlers.Refactor.Auto_Import;
74+
with LSP.Ada_Handlers.Refactor.Inline_Variable;
7475
with LSP.Ada_Handlers.Refactor.Introduce_Parameter;
7576
with LSP.Ada_Handlers.Refactor.Move_Parameter;
7677
with LSP.Ada_Handlers.Refactor.Pull_Up_Declaration;
@@ -226,6 +227,8 @@ procedure LSP.Ada_Driver is
226227
(LSP.Ada_Handlers.Refactor.Extract_Subprogram.Command'Tag);
227228
LSP.Ada_Commands.Register
228229
(LSP.Ada_Handlers.Refactor.Extract_Variable.Command'Tag);
230+
LSP.Ada_Commands.Register
231+
(LSP.Ada_Handlers.Refactor.Inline_Variable.Command'Tag);
229232
LSP.Ada_Commands.Register
230233
(LSP.Ada_Handlers.Refactor.Introduce_Parameter.Command'Tag);
231234
LSP.Ada_Commands.Register
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 2022-2023, 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 LAL_Refactor; use LAL_Refactor;
19+
with LAL_Refactor.Inline_Variable;
20+
use LAL_Refactor.Inline_Variable;
21+
22+
with VSS.JSON.Streams;
23+
24+
with LSP.Enumerations;
25+
with LSP.Structures.LSPAny_Vectors; use LSP.Structures.LSPAny_Vectors;
26+
27+
package body LSP.Ada_Handlers.Refactor.Inline_Variable is
28+
29+
----------------
30+
-- Initialize --
31+
----------------
32+
33+
procedure Initialize
34+
(Self : in out Command'Class;
35+
Context : LSP.Ada_Contexts.Context;
36+
Where : LSP.Structures.Location) is
37+
begin
38+
Self.Context_Id := Context.Id;
39+
Self.Location := Where;
40+
end Initialize;
41+
42+
------------------------
43+
-- Append_Code_Action --
44+
------------------------
45+
46+
procedure Append_Code_Action
47+
(Self : in out Command;
48+
Context : LSP.Ada_Context_Sets.Context_Access;
49+
Commands_Vector : in out LSP.Structures.Command_Or_CodeAction_Vector;
50+
Where : LSP.Structures.Location)
51+
is
52+
Code_Action : LSP.Structures.CodeAction;
53+
54+
begin
55+
Self.Initialize
56+
(Context => Context.all,
57+
Where => Where);
58+
59+
Code_Action :=
60+
(title => VSS.Strings.Conversions.To_Virtual_String (Self.Name),
61+
kind =>
62+
(Is_Set => True,
63+
Value => LSP.Enumerations.RefactorExtract),
64+
diagnostics => <>,
65+
edit => (Is_Set => False),
66+
isPreferred => (Is_Set => False),
67+
disabled => (Is_Set => False),
68+
command =>
69+
(Is_Set => True,
70+
Value =>
71+
(title => "",
72+
command => VSS.Strings.Conversions.To_Virtual_String
73+
(Command'External_Tag),
74+
arguments => Self.Write_Command)),
75+
data => <>);
76+
77+
Commands_Vector.Append
78+
(LSP.Structures.Command_Or_CodeAction'
79+
(Is_Command => False, CodeAction => Code_Action));
80+
end Append_Code_Action;
81+
82+
------------
83+
-- Create --
84+
------------
85+
86+
overriding function Create
87+
(Any : not null access LSP.Structures.LSPAny_Vector)
88+
return Command
89+
is
90+
use VSS.JSON.Streams;
91+
use VSS.Strings;
92+
use LSP.Structures.JSON_Event_Vectors;
93+
94+
C : Cursor := Any.First;
95+
begin
96+
return Self : Command do
97+
pragma Assert (Element (C).Kind = Start_Array);
98+
Next (C);
99+
pragma Assert (Element (C).Kind = Start_Object);
100+
Next (C);
101+
102+
while Has_Element (C)
103+
and then Element (C).Kind /= End_Object
104+
loop
105+
pragma Assert (Element (C).Kind = Key_Name);
106+
declare
107+
Key : constant Virtual_String := Element (C).Key_Name;
108+
begin
109+
Next (C);
110+
111+
if Key = "context_id" then
112+
Self.Context_Id := Element (C).String_Value;
113+
114+
elsif Key = "location" then
115+
Self.Location := From_Any (C);
116+
117+
else
118+
Skip_Value (C);
119+
end if;
120+
end;
121+
122+
Next (C);
123+
end loop;
124+
end return;
125+
end Create;
126+
127+
--------------
128+
-- Refactor --
129+
--------------
130+
131+
overriding procedure Refactor
132+
(Self : Command;
133+
Handler : not null access LSP.Ada_Handlers.Message_Handler'Class;
134+
Edits : out LAL_Refactor.Refactoring_Edits)
135+
is
136+
Message_Handler : LSP.Ada_Handlers.Message_Handler renames
137+
LSP.Ada_Handlers.Message_Handler (Handler.all);
138+
Context : LSP.Ada_Contexts.Context renames
139+
Message_Handler.Contexts.Get (Self.Context_Id).all;
140+
141+
function Analysis_Units return Analysis_Unit_Array is
142+
(Context.Analysis_Units);
143+
-- Provides the Context Analysis_Unit_Array to the Mode_Changer
144+
145+
File : constant GNATCOLL.VFS.Virtual_File :=
146+
Message_Handler.To_File (Self.Location.uri);
147+
148+
Unit : constant Analysis_Unit := Context.Get_AU (File);
149+
Location : constant Source_Location :=
150+
(Langkit_Support.Slocs.Line_Number
151+
(Self.Location.a_range.start.line) + 1,
152+
Column_Number
153+
(Self.Location.a_range.start.character) + 1);
154+
155+
Inliner : constant Variable_Inliner :=
156+
Create_Variable_Inliner
157+
(Unit => Unit,
158+
Location => Location);
159+
begin
160+
Edits := Inliner.Refactor (Analysis_Units'Access);
161+
end Refactor;
162+
163+
-------------------
164+
-- Write_Command --
165+
-------------------
166+
167+
function Write_Command
168+
(Self : Command) return LSP.Structures.LSPAny_Vector
169+
is
170+
use VSS.JSON.Streams;
171+
172+
Result : LSP.Structures.LSPAny_Vector;
173+
begin
174+
Result.Append (JSON_Stream_Element'(Kind => Start_Array));
175+
Result.Append (JSON_Stream_Element'(Kind => Start_Object));
176+
177+
-- "context_id"
178+
Add_Key ("context_id", Result);
179+
To_Any (Self.Context_Id, Result);
180+
181+
-- "section_to_extract_sloc"
182+
Add_Key ("location", Result);
183+
To_Any (Self.Location, Result);
184+
185+
Result.Append (JSON_Stream_Element'(Kind => End_Object));
186+
Result.Append (JSON_Stream_Element'(Kind => End_Array));
187+
188+
return Result;
189+
end Write_Command;
190+
191+
end LSP.Ada_Handlers.Refactor.Inline_Variable;
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
------------------------------------------------------------------------------
2+
-- Language Server Protocol --
3+
-- --
4+
-- Copyright (C) 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 inline variable
19+
20+
with VSS.Strings;
21+
22+
with LSP.Ada_Contexts;
23+
with LSP.Server_Jobs;
24+
25+
with Libadalang.Analysis; use Libadalang.Analysis;
26+
with Langkit_Support.Slocs; use Langkit_Support.Slocs;
27+
28+
package LSP.Ada_Handlers.Refactor.Inline_Variable is
29+
30+
type Command is new LSP.Ada_Handlers.Refactor.Command with private;
31+
32+
overriding function Name (Self : Command) return String
33+
is ("Inline variable");
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+
-- Initializes Self and appends it to Commands_Vector
41+
42+
private
43+
44+
type Command is new LSP.Ada_Handlers.Refactor.Command with record
45+
Context_Id : VSS.Strings.Virtual_String;
46+
Location : LSP.Structures.Location;
47+
end record;
48+
49+
overriding
50+
function Create
51+
(Any : not null access LSP.Structures.LSPAny_Vector)
52+
return Command;
53+
-- Reads Any and creates a new Command
54+
55+
overriding
56+
procedure Refactor
57+
(Self : Command;
58+
Handler : not null access LSP.Ada_Handlers.Message_Handler'Class;
59+
Edits : out LAL_Refactor.Refactoring_Edits);
60+
-- Executes Self by computing the necessary refactorings
61+
62+
overriding function Priority (Self : Command)
63+
return LSP.Server_Jobs.Job_Priority
64+
is (LSP.Server_Jobs.Low);
65+
66+
procedure Initialize
67+
(Self : in out Command'Class;
68+
Context : LSP.Ada_Contexts.Context;
69+
Where : LSP.Structures.Location);
70+
-- Initializes Self
71+
72+
function Write_Command
73+
(Self : Command) return LSP.Structures.LSPAny_Vector;
74+
75+
for Command'External_Tag use "als-refactor-inline_variable";
76+
77+
end LSP.Ada_Handlers.Refactor.Inline_Variable;

source/ada/lsp-ada_handlers.adb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ with Langkit_Support.Text;
3939
with LAL_Refactor.Delete_Entity;
4040
with LAL_Refactor.Extract_Subprogram;
4141
with LAL_Refactor.Extract_Variable;
42+
with LAL_Refactor.Inline_Variable;
4243
with LAL_Refactor.Introduce_Parameter;
4344
with LAL_Refactor.Pull_Up_Declaration;
4445
with LAL_Refactor.Auto_Import;
@@ -77,6 +78,7 @@ with LSP.Ada_Handlers.Refactor.Delete_Entity;
7778
with LSP.Ada_Handlers.Refactor.Extract_Subprogram;
7879
with LSP.Ada_Handlers.Refactor.Extract_Variable;
7980
with LSP.Ada_Handlers.Refactor.Auto_Import;
81+
with LSP.Ada_Handlers.Refactor.Inline_Variable;
8082
with LSP.Ada_Handlers.Refactor.Introduce_Parameter;
8183
with LSP.Ada_Handlers.Refactor.Move_Parameter;
8284
with LSP.Ada_Handlers.Refactor.Pull_Up_Declaration;
@@ -785,6 +787,10 @@ package body LSP.Ada_Handlers is
785787
-- Checks if the Swap_If_Not refactoring tool is available,
786788
-- and if so, appends a Code Action with its Command.
787789

790+
procedure Inline_Variable_Action;
791+
-- Checks if the Inline_Variable refactoring tool is available,
792+
-- and if so, appends a Code Action with its Command.
793+
788794
-------------------------------------------------
789795
-- Change_Parameters_Default_Value_Code_Action --
790796
-------------------------------------------------
@@ -1062,6 +1068,50 @@ package body LSP.Ada_Handlers is
10621068
end if;
10631069
end Import_Package_Code_Action;
10641070

1071+
----------------------------
1072+
-- Inline_Variable_Action --
1073+
----------------------------
1074+
1075+
procedure Inline_Variable_Action
1076+
is
1077+
use LSP.Ada_Handlers.Refactor.Inline_Variable;
1078+
use Langkit_Support.Slocs;
1079+
use LAL_Refactor.Inline_Variable;
1080+
use type LSP.Structures.Position;
1081+
1082+
function Analysis_Units
1083+
return Libadalang.Analysis.Analysis_Unit_Array is
1084+
(Context.Analysis_Units);
1085+
1086+
Single_Location : constant Boolean :=
1087+
Value.a_range.start = Value.a_range.an_end;
1088+
Location : constant Source_Location :=
1089+
(Langkit_Support.Slocs.Line_Number
1090+
(Value.a_range.start.line) + 1,
1091+
Column_Number (Value.a_range.start.character) + 1);
1092+
1093+
Inliner : Command;
1094+
1095+
begin
1096+
if Single_Location then
1097+
if Is_Inline_Variable_Available
1098+
(Node.Unit, Location, Analysis_Units'Access)
1099+
then
1100+
Inliner.Append_Code_Action
1101+
(Context => Context,
1102+
Commands_Vector => Result,
1103+
Where =>
1104+
(Value.textDocument.uri,
1105+
((Natural (Location.Line) - 1,
1106+
Natural (Location.Column) - 1),
1107+
(Natural (Location.Line) - 1,
1108+
Natural (Location.Column) - 1)),
1109+
LSP.Constants.Empty));
1110+
Found := True;
1111+
end if;
1112+
end if;
1113+
end Inline_Variable_Action;
1114+
10651115
-------------------------------------
10661116
-- Introduce_Parameter_Code_Action --
10671117
-------------------------------------
@@ -1378,6 +1428,8 @@ package body LSP.Ada_Handlers is
13781428

13791429
Import_Package_Code_Action;
13801430

1431+
Inline_Variable_Action;
1432+
13811433
-- Refactoring Code Actions
13821434

13831435
Delete_Entity_Code_Action;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
project Default is
2+
for Main use ("main.adb");
3+
end Default;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
with Ada.Text_IO;
3+
4+
procedure Main is
5+
Inline : Integer := 1;
6+
Var : Integer := 1;
7+
begin
8+
Var := Var + Inline;
9+
Ada.Text_IO.Put_Line (Var'Img);
10+
end Main;

0 commit comments

Comments
 (0)