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 ;
@@ -122,13 +123,25 @@ package body LSP.Ada_Handlers.Refactor_Imports_Commands is
122
123
Null_Unbounded_Wide_Wide_String;
123
124
use type Ada.Strings.Wide_Wide_Unbounded.
124
125
Unbounded_Wide_Wide_String;
126
+
125
127
begin
126
128
if Suggestion.With_Clause_Text /= " " then
127
- -- Add with clause and prefix
129
+ if Suggestion.Prefix_Text /= " " then
130
+ -- Add with clause and prefix
131
+ Title :=
132
+ Title
133
+ & " Add 'with' clause for "
134
+ & Suggestion.With_Clause_Text
135
+ & " and prefix the object with "
136
+ & Suggestion.Prefix_Text;
128
137
129
- Title := Title & " Add 'with' clause for "
130
- & Suggestion.With_Clause_Text & " and prefix the object with "
131
- & Suggestion.Prefix_Text;
138
+ else
139
+ -- Add with clause and leave the prefix as it is
140
+ Title :=
141
+ Title
142
+ & " Add 'with' clause for "
143
+ & Suggestion.With_Clause_Text;
144
+ end if ;
132
145
else
133
146
-- Only add prefix
134
147
@@ -167,96 +180,84 @@ package body LSP.Ada_Handlers.Refactor_Imports_Commands is
167
180
Commands_Vector.Append (Item);
168
181
end Append_Suggestion ;
169
182
170
- -- -----------
171
- -- Execute --
172
- -- -----------
183
+ -- --------------------------------
184
+ -- Command_To_Refactoring_Edits --
185
+ -- --------------------------------
173
186
174
- overriding procedure Execute
175
- (Self : Command;
176
- Handler : not null access LSP.Server_Notification_Receivers.
177
- Server_Notification_Receiver'Class;
178
- Client : not null access LSP.Client_Message_Receivers.
179
- Client_Message_Receiver'Class;
180
- Error : in out LSP.Errors.Optional_ResponseError)
187
+ function Command_To_Refactoring_Edits
188
+ (Self : Command;
189
+ Context : LSP.Ada_Contexts.Context;
190
+ Document : LSP.Ada_Documents.Document_Access)
191
+ return Laltools.Refactor.Refactoring_Edits
181
192
is
182
- use type Libadalang.Common.Ada_Node_Kind_Type;
183
- use type Libadalang.Slocs.Source_Location;
184
- use type VSS.Strings.Virtual_String;
185
-
186
- Message_Handler : LSP.Ada_Handlers.Message_Handler renames
187
- LSP.Ada_Handlers.Message_Handler (Handler.all );
188
- Context : LSP.Ada_Contexts.Context renames
189
- Message_Handler.Contexts.Get (Self.Context).all ;
190
-
191
- Document : constant LSP.Ada_Documents.Document_Access :=
192
- Message_Handler.Get_Open_Document (Self.Where.textDocument.uri);
193
- Apply : LSP.Messages.Client_Requests.Workspace_Apply_Edit_Request;
194
- Node : constant Libadalang.Analysis.Ada_Node :=
193
+ use Langkit_Support.Text;
194
+ use Libadalang.Analysis;
195
+ use Libadalang.Common;
196
+ use Libadalang.Slocs;
197
+ use Laltools.Refactor;
198
+ use VSS.Strings;
199
+ use VSS.Strings.Conversions;
200
+
201
+ Node : Ada_Node :=
195
202
Document.Get_Node_At (Context, Self.Where.position);
196
- Loc : LSP.Messages.Location;
197
- Edit : LSP.Messages.AnnotatedTextEdit;
198
203
199
- Edits : LSP.Messages.WorkspaceEdit renames Apply.params.edit;
200
- Version : constant LSP.Messages.VersionedTextDocumentIdentifier :=
201
- Document.Versioned_Identifier;
202
- begin
203
- Apply.params.label :=
204
- (Is_Set => True,
205
- Value =>
206
- VSS.Strings.Conversions.To_Virtual_String (Command'External_Tag));
207
- if Message_Handler.Versioned_Documents then
208
- Edits.documentChanges.Append
209
- (LSP.Messages.Document_Change'
210
- (Kind => LSP.Messages.Text_Document_Edit,
211
- Text_Document_Edit =>
212
- (textDocument => (Version.uri, (True, Version.version)),
213
- edits => <>)));
214
- end if ;
204
+ Edits : Laltools.Refactor.Refactoring_Edits;
215
205
216
- -- Add prefix.
206
+ begin
207
+ -- Add prefix
217
208
218
209
if not Self.Prefix.Is_Empty
219
- and then Node.Kind = Libadalang.Common. Ada_Identifier
210
+ and then Node.Kind in Ada_Identifier
220
211
then
221
212
-- If this is a DottedName them remove the current prefix and replace
222
213
-- it by the suggested one. Otherwise, just add the prepend the
223
214
-- prefix
224
215
225
- if Node.Parent.Kind = Libadalang.Common.Ada_Dotted_Name then
216
+ while Node.Parent.Kind in Ada_Dotted_Name_Range loop
217
+ Node := Node.Parent;
218
+ end loop ;
219
+
220
+ if Node.Kind in Ada_Dotted_Name_Range then
221
+ Node := Node.As_Dotted_Name.F_Suffix.As_Ada_Node;
222
+ end if ;
223
+
224
+ if Node.Parent.Kind = Ada_Dotted_Name then
226
225
-- Node.Parent is the full Dotted Name: this includes the
227
226
-- current prefixes and the identifier. Using this SLOC instead
228
227
-- of only the current prefixes SLOC is better since this covers
229
228
-- cases when the Dotted Name is splitted in multiple lines.
230
229
231
- Loc := LSP.Lal_Utils.Get_Node_Location (Node.Parent);
232
- Edit.span := (Loc.span.first, Loc.span.last);
233
- Edit.newText :=
234
- Self.Prefix & VSS.Strings.To_Virtual_String (Node.Text);
235
- else
236
- Loc := LSP.Lal_Utils.Get_Node_Location (Node);
237
- Edit.span := (Loc.span.first, Loc.span.first);
238
- Edit.newText := Self.Prefix;
239
- end if ;
230
+ Safe_Insert
231
+ (Edits => Edits.Text_Edits,
232
+ File_Name => Node.Unit.Get_Filename,
233
+ Edit =>
234
+ Text_Edit'
235
+ (Location =>
236
+ Make_Range
237
+ (Start_Sloc
238
+ (Node.Parent.As_Dotted_Name.F_Prefix.Sloc_Range),
239
+ Start_Sloc (Node.Sloc_Range)),
240
+ Text =>
241
+ Ada.Strings.Unbounded.To_Unbounded_String
242
+ (To_UTF8 (To_Wide_Wide_String (Self.Prefix)))));
240
243
241
- if Message_Handler.Versioned_Documents then
242
- Edits.documentChanges (1 ).Text_Document_Edit.edits.Append (Edit);
243
244
else
244
- if Edits.changes.Contains (Self.Where.textDocument.uri) then
245
- Edits.changes (Self.Where.textDocument.uri).Append
246
- (LSP.Messages.TextEdit (Edit));
247
- else
248
- declare
249
- Text_Edits : LSP.Messages.TextEdit_Vector;
250
- begin
251
- Text_Edits.Append (LSP.Messages.TextEdit (Edit));
252
- Edits.changes.Include
253
- (Self.Where.textDocument.uri, Text_Edits);
254
- end ;
255
- end if ;
245
+ Safe_Insert
246
+ (Edits => Edits.Text_Edits,
247
+ File_Name => Node.Unit.Get_Filename,
248
+ Edit =>
249
+ Text_Edit'
250
+ (Location =>
251
+ Make_Range
252
+ (Start_Sloc (Node.Sloc_Range),
253
+ Start_Sloc (Node.Sloc_Range)),
254
+ Text =>
255
+ Ada.Strings.Unbounded.To_Unbounded_String
256
+ (To_UTF8 (To_Wide_Wide_String (Self.Prefix))))) ;
256
257
end if ;
257
258
end if ;
258
259
259
- -- Add with clause.
260
+ -- Add with clause
260
261
261
262
if not Self.With_Clause.Is_Empty then
262
263
declare
@@ -270,39 +271,84 @@ package body LSP.Ada_Handlers.Refactor_Imports_Commands is
270
271
Last => Last);
271
272
begin
272
273
if S /= Libadalang.Slocs.No_Source_Location then
273
- Edit.span := LSP.Lal_Utils.To_Span (S);
274
274
if Last then
275
- Edit.newText :=
276
- Document.Line_Terminator
277
- & " with " & Self.With_Clause & " ;" ;
275
+ Safe_Insert
276
+ (Edits => Edits.Text_Edits,
277
+ File_Name => Node.Unit.Get_Filename,
278
+ Edit =>
279
+ Text_Edit'
280
+ (Location => Make_Range (S, S),
281
+ Text =>
282
+ Ada.Strings.Unbounded.To_Unbounded_String
283
+ (To_UTF8 (To_Wide_Wide_String
284
+ (Document.Line_Terminator
285
+ & " with " & Self.With_Clause & " ;" )))));
278
286
279
287
else
280
- Edit.newText :=
281
- " with " & Self.With_Clause & " ;"
282
- & Document.Line_Terminator;
288
+ Safe_Insert
289
+ (Edits => Edits.Text_Edits,
290
+ File_Name => Node.Unit.Get_Filename,
291
+ Edit =>
292
+ Text_Edit'
293
+ (Location => Make_Range (S, S),
294
+ Text =>
295
+ Ada.Strings.Unbounded.To_Unbounded_String
296
+ (To_UTF8 (To_Wide_Wide_String
297
+ (" with " & Self.With_Clause & " ;"
298
+ & Document.Line_Terminator)))));
283
299
end if ;
284
300
285
- if Message_Handler.Versioned_Documents then
286
- Edits.documentChanges (1 ).Text_Document_Edit.edits.Append
287
- (Edit);
288
- else
289
- if Edits.changes.Contains (Self.Where.textDocument.uri) then
290
- Edits.changes (Self.Where.textDocument.uri).Append
291
- (LSP.Messages.TextEdit (Edit));
292
- else
293
- declare
294
- Text_Edits : LSP.Messages.TextEdit_Vector;
295
- begin
296
- Text_Edits.Append (LSP.Messages.TextEdit (Edit));
297
- Edits.changes.Include
298
- (Self.Where.textDocument.uri, Text_Edits);
299
- end ;
300
- end if ;
301
- end if ;
302
301
end if ;
303
302
end ;
304
303
end if ;
305
304
305
+ return Edits;
306
+ end Command_To_Refactoring_Edits ;
307
+
308
+ -- -----------
309
+ -- Execute --
310
+ -- -----------
311
+
312
+ overriding procedure Execute
313
+ (Self : Command;
314
+ Handler : not null access LSP.Server_Notification_Receivers.
315
+ Server_Notification_Receiver'Class;
316
+ Client : not null access LSP.Client_Message_Receivers.
317
+ Client_Message_Receiver'Class;
318
+ Error : in out LSP.Errors.Optional_ResponseError)
319
+ is
320
+ use Laltools.Refactor;
321
+ use LSP.Messages;
322
+ use LSP.Types;
323
+ use VSS.Strings;
324
+ use VSS.Strings.Conversions;
325
+
326
+ Message_Handler : LSP.Ada_Handlers.Message_Handler renames
327
+ LSP.Ada_Handlers.Message_Handler (Handler.all );
328
+ Context : LSP.Ada_Contexts.Context renames
329
+ Message_Handler.Contexts.Get (Self.Context).all ;
330
+
331
+ Document : constant LSP.Ada_Documents.Document_Access :=
332
+ Message_Handler.Get_Open_Document (Self.Where.textDocument.uri);
333
+
334
+ Apply : Client_Requests.Workspace_Apply_Edit_Request;
335
+ Workspace_Edits : WorkspaceEdit renames Apply.params.edit;
336
+ Label : Optional_Virtual_String renames Apply.params.label;
337
+
338
+ Edits : constant Refactoring_Edits :=
339
+ Self.Command_To_Refactoring_Edits (Context, Document);
340
+
341
+ begin
342
+ Workspace_Edits :=
343
+ LSP.Lal_Utils.To_Workspace_Edit
344
+ (Edits => Edits,
345
+ Resource_Operations => Message_Handler.Resource_Operations,
346
+ Versioned_Documents => Message_Handler.Versioned_Documents,
347
+ Document_Provider => Message_Handler'Access );
348
+ Label :=
349
+ (Is_Set => True,
350
+ Value => To_Virtual_String (Command'External_Tag));
351
+
306
352
Client.On_Workspace_Apply_Edit_Request (Apply);
307
353
308
354
exception
0 commit comments