Skip to content

Commit 3b7bf1e

Browse files
Merge branch 'topic/gpr-formatting' into 'master'
Use the fallback indenter for GPR for formatting See merge request eng/ide/ada_language_server!2147
2 parents 49956cf + 3ef7ee2 commit 3b7bf1e

19 files changed

+553
-142
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ repos:
2929
- --namespace-packages
3030
additional_dependencies:
3131
- pytest-lsp
32+
- lsprotocol<2025.0.0
3233
- e3-testsuite
3334
- psutil
3435
- types-psutil

source/ada/lsp-ada_documents.adb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1013,8 +1013,9 @@ package body LSP.Ada_Documents is
10131013
To : LSP.Structures.Position)
10141014
return VSS.Strings.Virtual_String
10151015
is
1016+
Span : constant LSP.Structures.A_Range := (start => From, an_end => To);
10161017
begin
1017-
return Self.Slice ((From, To));
1018+
return Self.Slice (Span);
10181019
end Get_Text;
10191020

10201021
---------------------

source/ada/lsp-ada_documents.ads

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ package LSP.Ada_Documents is
120120
-- Get an identifier at given position in the document or an empty string.
121121

122122
function Get_Text
123-
(Self : Document;
124-
From : LSP.Structures.Position;
125-
To : LSP.Structures.Position)
123+
(Self : Document;
124+
From : LSP.Structures.Position;
125+
To : LSP.Structures.Position)
126126
return VSS.Strings.Virtual_String;
127-
-- Get the text in the document between From and To
127+
-- Get the text in the document between From and To.
128128

129129
procedure Get_Completion_Node
130130
(Self : Document;

source/ada/lsp-ada_formatter.adb

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,9 @@ package body LSP.Ada_Formatter is
137137
Self.Parent.Context.Get_Configuration.Range_Formatting_Fallback
138138
then
139139
LSP.Ada_Handlers.Formatting.Indent_Lines
140-
(Context => Context.all,
141-
Document => Document,
140+
(Tracer => Context.Tracer,
141+
Filename => Context.URI_To_File (Document.URI),
142+
Document => Document.all,
142143
Span => Value.a_range,
143144
Options =>
144145
LSP.Ada_Handlers.Formatting.Get_Formatting_Options
@@ -221,8 +222,9 @@ package body LSP.Ada_Formatter is
221222
Indent_Array :
222223
constant LSP.Formatters.Fallback_Indenter.Indentation_Array :=
223224
LSP.Ada_Handlers.Formatting.Get_Indentation
224-
(Context => Context.all,
225-
Document => Document,
225+
(Filename => Context.URI_To_File (Document.URI),
226+
Buffer =>
227+
Document.Get_Text ((0, 0), (Value.position.line + 1, 0)),
226228
Span =>
227229
((Value.position.line, 0), (Value.position.line + 1, 0)),
228230
Options => Full_Options);
@@ -301,11 +303,11 @@ package body LSP.Ada_Formatter is
301303
Response.Append
302304
(LSP.Structures.TextEdit'
303305
(a_range => (start => Value.position, an_end => Value.position),
304-
newText => LSP.Ada_Handlers.Formatting.Handle_Tabs
305-
(Context.all,
306-
Document,
307-
Full_Options,
308-
Indentation * ' ')));
306+
newText =>
307+
LSP.Ada_Handlers.Formatting.Handle_Tabs
308+
(Filename => Context.URI_To_File (Document.URI),
309+
Options => Full_Options,
310+
S => Indentation * ' ')));
309311
end Handle_Document_With_Diagnostics;
310312

311313
-----------------------------------------
@@ -374,10 +376,9 @@ package body LSP.Ada_Formatter is
374376
(start => Value.position, an_end => Value.position),
375377
newText =>
376378
LSP.Ada_Handlers.Formatting.Handle_Tabs
377-
(Context.all,
378-
Document,
379-
Full_Options,
380-
Indentation * ' ')));
379+
(Filename => Context.URI_To_File (Document.URI),
380+
Options => Full_Options,
381+
S => Indentation * ' ')));
381382

382383
return;
383384
end if;
@@ -398,10 +399,9 @@ package body LSP.Ada_Formatter is
398399
(start => Value.position, an_end => Value.position),
399400
newText =>
400401
LSP.Ada_Handlers.Formatting.Handle_Tabs
401-
(Context.all,
402-
Document,
403-
Full_Options,
404-
Indentation * ' ')));
402+
(Filename => Context.URI_To_File (Document.URI),
403+
Options => Full_Options,
404+
S => Indentation * ' ')));
405405

406406
return;
407407
end if;
@@ -430,15 +430,15 @@ package body LSP.Ada_Formatter is
430430
end if;
431431

432432
Response.Append
433-
(LSP.Structures.TextEdit'
434-
(a_range =>
435-
(start => Value.position, an_end => Value.position),
436-
newText =>
437-
LSP.Ada_Handlers.Formatting.Handle_Tabs
438-
(Context.all,
439-
Document,
440-
Full_Options,
441-
Indentation * ' ')));
433+
(New_Item =>
434+
LSP.Structures.TextEdit'
435+
(a_range =>
436+
(start => Value.position, an_end => Value.position),
437+
newText =>
438+
LSP.Ada_Handlers.Formatting.Handle_Tabs
439+
(Filename => Context.URI_To_File (Document.URI),
440+
Options => Full_Options,
441+
S => Indentation * ' ')));
442442
end;
443443
end Handle_Document_Without_Diagnostics;
444444

source/ada/lsp-ada_handlers-formatting.adb

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ package body LSP.Ada_Handlers.Formatting is
3434
-- Error message sent when trying to format invalid code.
3535

3636
function Reindent_Line
37-
(Context : LSP.Ada_Contexts.Context;
38-
Document : not null LSP.Ada_Documents.Document_Access;
37+
(Filename : GNATCOLL.VFS.Virtual_File;
38+
Line : VSS.Strings.Virtual_String;
3939
Options : Gnatformat.Configuration.Format_Options_Type;
4040
Pos : LSP.Structures.Position;
4141
New_Indent : Natural) return LSP.Structures.TextEdit;
@@ -46,17 +46,15 @@ package body LSP.Ada_Handlers.Formatting is
4646
-------------------
4747

4848
function Reindent_Line
49-
(Context : LSP.Ada_Contexts.Context;
50-
Document : not null LSP.Ada_Documents.Document_Access;
49+
(Filename : GNATCOLL.VFS.Virtual_File;
50+
Line : VSS.Strings.Virtual_String;
5151
Options : Gnatformat.Configuration.Format_Options_Type;
5252
Pos : LSP.Structures.Position;
5353
New_Indent : Natural) return LSP.Structures.TextEdit
5454
is
5555
use type VSS.Characters.Virtual_Character;
5656
use VSS.Strings;
5757

58-
Line : constant Virtual_String :=
59-
Document.Get_Text (Pos, (Pos.line + 1, 0));
6058
-- Get the full line because we want to remove its existing blank
6159
-- characters.
6260
New_Prefix : constant Virtual_String :=
@@ -81,7 +79,11 @@ package body LSP.Ada_Handlers.Formatting is
8179
return
8280
LSP.Structures.TextEdit'
8381
(a_range => (Pos, (Pos.line, First_Non_Blank)),
84-
newText => Handle_Tabs (Context, Document, Options, New_Prefix));
82+
newText =>
83+
Handle_Tabs
84+
(Filename => Filename,
85+
Options => Options,
86+
S => New_Prefix));
8587
end Reindent_Line;
8688

8789
------------
@@ -170,14 +172,12 @@ package body LSP.Ada_Handlers.Formatting is
170172
---------------------
171173

172174
function Get_Indentation
173-
(Context : LSP.Ada_Contexts.Context;
174-
Document : not null LSP.Ada_Documents.Document_Access;
175+
(Filename : GNATCOLL.VFS.Virtual_File;
176+
Buffer : VSS.Strings.Virtual_String;
175177
Span : LSP.Structures.A_Range;
176178
Options : Gnatformat.Configuration.Format_Options_Type)
177179
return LSP.Formatters.Fallback_Indenter.Indentation_Array
178180
is
179-
Filename : constant GNATCOLL.VFS.Virtual_File :=
180-
Context.URI_To_File (Document.URI);
181181
Indentation : constant Positive :=
182182
Gnatformat.Configuration.Get_Indentation
183183
(Options, Filename.Display_Full_Name);
@@ -187,9 +187,7 @@ package body LSP.Ada_Handlers.Formatting is
187187
begin
188188
return
189189
LSP.Formatters.Fallback_Indenter.Get_Indentation
190-
(Buffer =>
191-
VSS.Strings.Conversions.To_UTF_8_String
192-
(Document.Get_Text ((0, 0), Span.an_end)),
190+
(Buffer => VSS.Strings.Conversions.To_UTF_8_String (Buffer),
193191
From => Span.start.line + 1,
194192
To => Span.an_end.line + 1,
195193
Indent_Level => Indentation,
@@ -201,38 +199,68 @@ package body LSP.Ada_Handlers.Formatting is
201199
------------------
202200

203201
procedure Indent_Lines
204-
(Context : LSP.Ada_Contexts.Context;
205-
Document : not null LSP.Ada_Documents.Document_Access;
206-
Span : LSP.Structures.A_Range;
202+
(Tracer : not null LSP.Tracers.Tracer_Access;
203+
Filename : GNATCOLL.VFS.Virtual_File;
204+
Document : LSP.Text_Documents.Text_Document'Class;
207205
Options : Gnatformat.Configuration.Format_Options_Type;
206+
Span : LSP.Structures.A_Range := LSP.Text_Documents.Empty_Range;
208207
Success : out Boolean;
209208
Response : out LSP.Structures.TextEdit_Vector;
210209
Messages : out VSS.String_Vectors.Virtual_String_Vector;
211210
Error : out LSP.Errors.ResponseError)
212211
is
213212
pragma Unreferenced (Messages);
213+
use LSP.Structures;
214+
use LSP.Text_Documents;
214215
use VSS.Strings;
216+
217+
Actual_Span : constant A_Range :=
218+
(if Span = Empty_Range
219+
then ((0, 0), (Integer'Max (Document.Line_Count - 1, 0), 0))
220+
else Span);
221+
-- If no span is provided, indent the whole document.
222+
223+
Buffer : constant VSS.Strings.Virtual_String :=
224+
(if Span = Empty_Range
225+
then Document.Text
226+
else Document.Slice (((0, 0), Actual_Span.an_end)));
227+
-- Get the relevant buffer to indent.
228+
-- If no span is provided, get the whole document buffer.
229+
-- Otherwise get the buffer from the start of the document
230+
-- to the end of the given span.
231+
215232
Indent_Lines :
216233
constant LSP.Formatters.Fallback_Indenter.Indentation_Array :=
217-
Get_Indentation (Context, Document, Span, Options => Options);
234+
Get_Indentation
235+
(Filename => Filename,
236+
Buffer => Buffer,
237+
Span => Actual_Span,
238+
Options => Options);
239+
-- Get the indentation levels for each line in the span.
240+
241+
Pos : LSP.Structures.Position;
218242
begin
219-
Context.Tracer.Trace_Text
220-
(Incorrect_Code_Msg & ", using the fallback indenter");
243+
Tracer.Trace_Text (Incorrect_Code_Msg & ", using the fallback indenter");
221244
for Line in Indent_Lines'Range loop
222245
if Indent_Lines (Line) /= -1 then
246+
-- LSP is 0-based, while the array returned by the fallback
247+
-- indenter is 1-based.
248+
Pos := (Line - 1, 0);
249+
250+
-- Generate a text edit to reindent the line.
223251
Response.Append
224252
(Reindent_Line
225-
(Context => Context,
226-
Document => Document,
253+
(Filename => Filename,
254+
Line => Document.Get_Line (Pos.line),
227255
Options => Options,
228-
Pos => (Line - 1, 0),
256+
Pos => Pos,
229257
New_Indent => Indent_Lines (Line)));
230258
end if;
231259
end loop;
232260
Success := True;
233261
exception
234262
when E : others =>
235-
Context.Tracer.Trace_Exception (E, Fallback_Exception_Found_Msg);
263+
Tracer.Trace_Exception (E, Fallback_Exception_Found_Msg);
236264
Success := False;
237265
Error :=
238266
(code =>
@@ -245,19 +273,17 @@ package body LSP.Ada_Handlers.Formatting is
245273
-----------------
246274

247275
function Handle_Tabs
248-
(Context : LSP.Ada_Contexts.Context;
249-
Document : not null LSP.Ada_Documents.Document_Access;
276+
(Filename : GNATCOLL.VFS.Virtual_File;
250277
Options : Gnatformat.Configuration.Format_Options_Type;
251278
S : VSS.Strings.Virtual_String) return VSS.Strings.Virtual_String
252279
is
253280
use Gnatformat.Configuration;
254281
use type VSS.Characters.Virtual_Character;
255282
use VSS.Strings;
256283

257-
Filename : constant GNATCOLL.VFS.Virtual_File :=
258-
Context.URI_To_File (Document.URI);
259284
Indentation : constant Character_Count :=
260-
Character_Count (Get_Indentation (Options, Filename.Display_Full_Name));
285+
Character_Count
286+
(Get_Indentation (Options, Filename.Display_Full_Name));
261287
Use_Tabs : constant Boolean :=
262288
Get_Indentation_Kind (Options, Filename.Display_Full_Name) = Tabs;
263289
Res : VSS.Strings.Virtual_String;

source/ada/lsp-ada_handlers-formatting.ads

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ with LSP.Ada_Contexts;
2323
with LSP.Errors;
2424
with LSP.Structures;
2525
with LSP.Formatters.Fallback_Indenter;
26+
with LSP.Text_Documents;
2627

2728
with VSS.Strings;
2829
with VSS.String_Vectors;
@@ -51,33 +52,48 @@ package LSP.Ada_Handlers.Formatting is
5152
-- Format the text of the given document in the given range (span).
5253

5354
function Get_Indentation
54-
(Context : LSP.Ada_Contexts.Context;
55-
Document : not null LSP.Ada_Documents.Document_Access;
55+
(Filename : GNATCOLL.VFS.Virtual_File;
56+
Buffer : VSS.Strings.Virtual_String;
5657
Span : LSP.Structures.A_Range;
5758
Options : Gnatformat.Configuration.Format_Options_Type)
5859
return LSP.Formatters.Fallback_Indenter.Indentation_Array;
5960
-- Use the fallback indenter to get an array of indentation for each
60-
-- line in span.
61+
-- line in Span.
62+
-- Each line in the array is 1-based indexed (i.e., the first line is at
63+
-- index 1).
64+
-- Buffer is the content of the document referenced by Filename. Should
65+
-- contain the whole content of the document or a substring including
66+
-- at least the lines in Span.
6167

6268
procedure Indent_Lines
63-
(Context : LSP.Ada_Contexts.Context;
64-
Document : not null LSP.Ada_Documents.Document_Access;
65-
Span : LSP.Structures.A_Range;
69+
(Tracer : not null LSP.Tracers.Tracer_Access;
70+
Filename : GNATCOLL.VFS.Virtual_File;
71+
Document : LSP.Text_Documents.Text_Document'Class;
6672
Options : Gnatformat.Configuration.Format_Options_Type;
73+
Span : LSP.Structures.A_Range := LSP.Text_Documents.Empty_Range;
6774
Success : out Boolean;
6875
Response : out LSP.Structures.TextEdit_Vector;
6976
Messages : out VSS.String_Vectors.Virtual_String_Vector;
7077
Error : out LSP.Errors.ResponseError);
7178
-- Generate a TextEdit_Vector to reindent the lines in Span using the
7279
-- fallback indenter.
80+
-- If no Span is provided, the whole document is indented.
81+
-- Document is the document to indent.
82+
-- Tracer is used to log messages.
83+
-- Filename is the name of the file referenced by Document. Used to
84+
-- retrieve file-specific indentation options.
85+
-- Options are the formatting options to use.
86+
-- Success is set to True if indentation was successful.
87+
-- Response contains the generated TextEdit_Vector.
88+
-- Messages contains any informational or warning messages.
89+
-- Error is set if an error occurred.
7390

7491
function Handle_Tabs
75-
(Context : LSP.Ada_Contexts.Context;
76-
Document : not null LSP.Ada_Documents.Document_Access;
92+
(Filename : GNATCOLL.VFS.Virtual_File;
7793
Options : Gnatformat.Configuration.Format_Options_Type;
7894
S : VSS.Strings.Virtual_String) return VSS.Strings.Virtual_String;
79-
-- Handle tabs and whitespaces convertion depending of the setting in
80-
-- the context.
95+
-- Handle tabs and whitespaces convertion depending on the
96+
-- tabulation-related settings in Options.
8197

8298
function Get_Formatting_Options
8399
(Context : LSP.Ada_Contexts.Context;

0 commit comments

Comments
 (0)