1
1
-- ----------------------------------------------------------------------------
2
2
-- Language Server Protocol --
3
3
-- --
4
- -- Copyright (C) 2020-2023 , AdaCore --
4
+ -- Copyright (C) 2020-2022 , AdaCore --
5
5
-- --
6
6
-- This is free software; you can redistribute it and/or modify it under --
7
7
-- terms of the GNU General Public License as published by the Free Soft- --
16
16
-- ----------------------------------------------------------------------------
17
17
18
18
with Ada.Strings.UTF_Encoding ;
19
+ with Ada.Strings.Unbounded ;
19
20
with Ada.Strings.Wide_Wide_Unbounded ;
20
21
21
22
with Langkit_Support.Text ;
22
23
23
24
with Libadalang.Analysis ;
25
+ with Libadalang.Common ;
26
+
27
+ with Laltools.Common ;
24
28
25
- with LSP.Commands ;
26
29
with LSP.Messages ;
27
30
28
31
with VSS.Strings.Conversions ;
32
+ with LSP.Commands ;
29
33
30
- package body LSP.Ada_Handlers.Refactor.Auto_Import is
34
+ package body LSP.Ada_Handlers.Refactor.Imports_Commands is
31
35
32
36
-- --------------
33
37
-- Initialize --
@@ -42,11 +46,8 @@ package body LSP.Ada_Handlers.Refactor.Auto_Import is
42
46
begin
43
47
Self.Context := Context.Id;
44
48
Self.Where := Where;
45
- Self.Suggestion :=
46
- (Import =>
47
- VSS.Strings.Conversions.To_Unbounded_Wide_Wide_String (With_Clause),
48
- Qualifier =>
49
- VSS.Strings.Conversions.To_Unbounded_Wide_Wide_String (Prefix));
49
+ Self.With_Clause := With_Clause;
50
+ Self.Prefix := Prefix;
50
51
end Initialize ;
51
52
52
53
-- ----------
@@ -73,25 +74,10 @@ package body LSP.Ada_Handlers.Refactor.Auto_Import is
73
74
LSP.Types.Read_String (JS, V.Context);
74
75
elsif Key = " where" then
75
76
LSP.Messages.TextDocumentPositionParams'Read (JS, V.Where);
76
- elsif Key = " import" then
77
- declare
78
- Import : VSS.Strings.Virtual_String;
79
- begin
80
- LSP.Types.Read_String (JS, Import);
81
- V.Suggestion.Import :=
82
- VSS.Strings.Conversions.To_Unbounded_Wide_Wide_String
83
- (Import);
84
- end ;
85
-
86
- elsif Key = " qualifier" then
87
- declare
88
- Qualififer : VSS.Strings.Virtual_String;
89
- begin
90
- LSP.Types.Read_String (JS, Qualififer);
91
- V.Suggestion.Qualifier :=
92
- VSS.Strings.Conversions.To_Unbounded_Wide_Wide_String
93
- (Qualififer);
94
- end ;
77
+ elsif Key = " with_clause" then
78
+ LSP.Types.Read_String (JS, V.With_Clause);
79
+ elsif Key = " prefix" then
80
+ LSP.Types.Read_String (JS, V.Prefix);
95
81
else
96
82
JS.Skip_Value;
97
83
end if ;
@@ -110,13 +96,13 @@ package body LSP.Ada_Handlers.Refactor.Auto_Import is
110
96
Context : Context_Access;
111
97
Where : LSP.Messages.Location;
112
98
Commands_Vector : in out LSP.Messages.CodeAction_Vector;
113
- Suggestion : LAL_Refactor.Auto_Import.Import_Type )
99
+ Suggestion : LAL_Refactor.Refactor_Imports.Import_Suggestion )
114
100
is
115
101
Pointer : LSP.Commands.Command_Pointer;
116
102
Item : LSP.Messages.CodeAction;
117
103
118
104
function Create_Suggestion_Title
119
- (Suggestion : LAL_Refactor.Auto_Import.Import_Type )
105
+ (Suggestion : LAL_Refactor.Refactor_Imports.Import_Suggestion )
120
106
return VSS.Strings.Virtual_String;
121
107
-- Creates the suggestion text that will be shown by the client to
122
108
-- to the developer. The text is costumized based on the need of
@@ -126,17 +112,42 @@ package body LSP.Ada_Handlers.Refactor.Auto_Import is
126
112
-- Create_Suggestions_Title --
127
113
-- ----------------------------
128
114
function Create_Suggestion_Title
129
- (Suggestion : LAL_Refactor.Auto_Import.Import_Type )
115
+ (Suggestion : LAL_Refactor.Refactor_Imports.Import_Suggestion )
130
116
return VSS.Strings.Virtual_String
131
117
is
132
- use Ada.Strings.Wide_Wide_Unbounded;
118
+ Title : Ada.Strings.Wide_Wide_Unbounded.
119
+ Unbounded_Wide_Wide_String
120
+ := Ada.Strings.Wide_Wide_Unbounded.
121
+ Null_Unbounded_Wide_Wide_String;
122
+ use type Ada.Strings.Wide_Wide_Unbounded.
123
+ Unbounded_Wide_Wide_String;
133
124
134
- Title : constant Langkit_Support.Text.Unbounded_Text_Type :=
135
- " Qualify with " & Suggestion.Qualifier;
136
125
begin
137
- return
138
- VSS.Strings.To_Virtual_String
139
- (Langkit_Support.Text.To_Text (Title));
126
+ if Suggestion.With_Clause_Text /= " " then
127
+ if Suggestion.Prefix_Text /= " " then
128
+ -- Add with clause and prefix
129
+ Title :=
130
+ Title
131
+ & " Add 'with' clause for "
132
+ & Suggestion.With_Clause_Text
133
+ & " and prefix the object with "
134
+ & Suggestion.Prefix_Text;
135
+
136
+ else
137
+ -- Add with clause and leave the prefix as it is
138
+ Title :=
139
+ Title
140
+ & " Add 'with' clause for "
141
+ & Suggestion.With_Clause_Text;
142
+ end if ;
143
+ else
144
+ -- Only add prefix
145
+
146
+ Title := Title & " Prefix the object with "
147
+ & Suggestion.Prefix_Text;
148
+ end if ;
149
+ return VSS.Strings.To_Virtual_String
150
+ (Langkit_Support.Text.To_Text (Title));
140
151
end Create_Suggestion_Title ;
141
152
142
153
begin
@@ -146,15 +157,15 @@ package body LSP.Ada_Handlers.Refactor.Auto_Import is
146
157
Where.span.first),
147
158
With_Clause =>
148
159
VSS.Strings.Conversions.To_Virtual_String
149
- (Suggestion.Import ),
160
+ (Suggestion.With_Clause_Text ),
150
161
Prefix =>
151
162
VSS.Strings.Conversions.To_Virtual_String
152
- (Suggestion.Qualifier ));
163
+ (Suggestion.Prefix_Text ));
153
164
Pointer.Set (Self);
154
165
Item :=
155
166
(title => Create_Suggestion_Title (Suggestion),
156
167
kind => (Is_Set => True,
157
- Value => LSP.Messages.QuickFix ),
168
+ Value => LSP.Messages.RefactorRewrite ),
158
169
diagnostics => (Is_Set => False),
159
170
disabled => (Is_Set => False),
160
171
edit => (Is_Set => False),
@@ -177,20 +188,119 @@ package body LSP.Ada_Handlers.Refactor.Auto_Import is
177
188
Document : LSP.Ada_Documents.Document_Access)
178
189
return LAL_Refactor.Refactoring_Edits
179
190
is
191
+ use Langkit_Support.Text;
180
192
use Libadalang.Analysis;
181
- use LAL_Refactor.Auto_Import;
193
+ use Libadalang.Common;
194
+ use Libadalang.Slocs;
195
+ use LAL_Refactor;
196
+ use VSS.Strings;
197
+ use VSS.Strings.Conversions;
182
198
183
- Name : constant Libadalang.Analysis.Name :=
184
- Document.Get_Node_At (Context, Self.Where.position).As_Name ;
199
+ Node : Ada_Node :=
200
+ Document.Get_Node_At (Context, Self.Where.position);
185
201
186
- function Units return Analysis_Unit_Array is ([]) ;
202
+ Edits : LAL_Refactor.Refactoring_Edits ;
187
203
188
204
begin
189
- return
190
- Create_Auto_Importer
191
- (Name,
192
- Self.Suggestion)
193
- .Refactor (Units'Access );
205
+ -- Add prefix
206
+
207
+ if not Self.Prefix.Is_Empty
208
+ and then Node.Kind in Ada_Identifier
209
+ then
210
+ -- If this is a DottedName them remove the current prefix and replace
211
+ -- it by the suggested one. Otherwise, just add the prepend the
212
+ -- prefix
213
+
214
+ while Node.Parent.Kind in Ada_Dotted_Name_Range loop
215
+ Node := Node.Parent;
216
+ end loop ;
217
+
218
+ if Node.Kind in Ada_Dotted_Name_Range then
219
+ Node := Node.As_Dotted_Name.F_Suffix.As_Ada_Node;
220
+ end if ;
221
+
222
+ if Node.Parent.Kind = Ada_Dotted_Name then
223
+ -- Node.Parent is the full Dotted Name: this includes the
224
+ -- current prefixes and the identifier. Using this SLOC instead
225
+ -- of only the current prefixes SLOC is better since this covers
226
+ -- cases when the Dotted Name is splitted in multiple lines.
227
+
228
+ Safe_Insert
229
+ (Edits => Edits.Text_Edits,
230
+ File_Name => Node.Unit.Get_Filename,
231
+ Edit =>
232
+ Text_Edit'
233
+ (Location =>
234
+ Make_Range
235
+ (Start_Sloc
236
+ (Node.Parent.As_Dotted_Name.F_Prefix.Sloc_Range),
237
+ Start_Sloc (Node.Sloc_Range)),
238
+ Text =>
239
+ Ada.Strings.Unbounded.To_Unbounded_String
240
+ (To_UTF8 (To_Wide_Wide_String (Self.Prefix)))));
241
+
242
+ else
243
+ Safe_Insert
244
+ (Edits => Edits.Text_Edits,
245
+ File_Name => Node.Unit.Get_Filename,
246
+ Edit =>
247
+ Text_Edit'
248
+ (Location =>
249
+ Make_Range
250
+ (Start_Sloc (Node.Sloc_Range),
251
+ Start_Sloc (Node.Sloc_Range)),
252
+ Text =>
253
+ Ada.Strings.Unbounded.To_Unbounded_String
254
+ (To_UTF8 (To_Wide_Wide_String (Self.Prefix)))));
255
+ end if ;
256
+ end if ;
257
+
258
+ -- Add with clause
259
+
260
+ if not Self.With_Clause.Is_Empty then
261
+ declare
262
+ Last : Boolean;
263
+ S : constant Libadalang.Slocs.Source_Location :=
264
+ Laltools.Common.Get_Insert_With_Location
265
+ (Node => Laltools.Common.Get_Compilation_Unit (Node),
266
+ Pack_Name =>
267
+ VSS.Strings.Conversions.To_Wide_Wide_String
268
+ (Self.With_Clause),
269
+ Last => Last);
270
+ begin
271
+ if S /= Libadalang.Slocs.No_Source_Location then
272
+ if Last then
273
+ Safe_Insert
274
+ (Edits => Edits.Text_Edits,
275
+ File_Name => Node.Unit.Get_Filename,
276
+ Edit =>
277
+ Text_Edit'
278
+ (Location => Make_Range (S, S),
279
+ Text =>
280
+ Ada.Strings.Unbounded.To_Unbounded_String
281
+ (To_UTF8 (To_Wide_Wide_String
282
+ (Document.Line_Terminator
283
+ & " with " & Self.With_Clause & " ;" )))));
284
+
285
+ else
286
+ Safe_Insert
287
+ (Edits => Edits.Text_Edits,
288
+ File_Name => Node.Unit.Get_Filename,
289
+ Edit =>
290
+ Text_Edit'
291
+ (Location => Make_Range (S, S),
292
+ Text =>
293
+ Ada.Strings.Unbounded.To_Unbounded_String
294
+ (To_UTF8 (To_Wide_Wide_String
295
+ (" with " & Self.With_Clause & " ;"
296
+ & Document.Line_Terminator)))));
297
+ end if ;
298
+
299
+ end if ;
300
+ end ;
301
+ end if ;
302
+
303
+ return Edits;
194
304
end Command_To_Refactoring_Edits ;
195
305
196
306
-- ------------
@@ -235,15 +345,11 @@ package body LSP.Ada_Handlers.Refactor.Auto_Import is
235
345
LSP.Types.Write_String (S, V.Context);
236
346
JS.Key (" where" );
237
347
LSP.Messages.TextDocumentPositionParams'Write (S, V.Where);
238
- JS.Key (" import" );
239
- LSP.Types.Write_String
240
- (S,
241
- VSS.Strings.Conversions.To_Virtual_String (V.Suggestion.Import));
242
- JS.Key (" qualifier" );
243
- LSP.Types.Write_String
244
- (S,
245
- VSS.Strings.Conversions.To_Virtual_String (V.Suggestion.Qualifier));
348
+ JS.Key (" with_clause" );
349
+ LSP.Types.Write_String (S, V.With_Clause);
350
+ JS.Key (" prefix" );
351
+ LSP.Types.Write_String (S, V.Prefix);
246
352
JS.End_Object;
247
353
end Write_Command ;
248
354
249
- end LSP.Ada_Handlers.Refactor.Auto_Import ;
355
+ end LSP.Ada_Handlers.Refactor.Imports_Commands ;
0 commit comments