Skip to content

Commit

Permalink
Merge branch 'issue_1354' into 'edge'
Browse files Browse the repository at this point in the history
Add GNATformat as a secondary formatter

See merge request eng/ide/ada_language_server!1565
  • Loading branch information
joaopsazevedo committed Jul 29, 2024
2 parents efdc89d + eefa6da commit b963eb2
Show file tree
Hide file tree
Showing 27 changed files with 736 additions and 37 deletions.
6 changes: 6 additions & 0 deletions doc/traces.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,9 @@ in `initialize` response.
Log lalpp output if `yes`.

ALS.LAL_PP_OUTPUT_ON_FORMATTING=yes

## `ALS.GNATFORMAT` (default no)

Use GNATformat as format provider.

ALS.GNATFORMAT=yes
1 change: 1 addition & 0 deletions gnat/lsp_server.gpr
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ with "lal_refactor.gpr";
with "ada_libfswatch.gpr";
with "libgnatdoc.gpr";
with "spawn.gpr";
with "gnatformat.gpr";

with "lsp_3_17";
with "lsp_common";
Expand Down
2 changes: 2 additions & 0 deletions source/ada/lsp-ada_contexts.adb
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,9 @@ package body LSP.Ada_Contexts is

Self.Reload;
Update_Source_Files;

Pretty_Printer_Setup;
Self.Format_Options := Gnatformat.Configuration.From_Project (Root);
end Load_Project;

------------
Expand Down
13 changes: 13 additions & 0 deletions source/ada/lsp-ada_contexts.ads
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ with GNATCOLL.VFS;

with GNATdoc.Comments.Options;

with Gnatformat.Configuration;

with GPR2.Project.Tree;
with GPR2.Project.View;

Expand Down Expand Up @@ -177,6 +179,10 @@ package LSP.Ada_Contexts is
Utils.Command_Lines.Command_Line;
-- Return the command line for the Pretty Printer

function Get_Format_Options
(Self : Context) return Gnatformat.Configuration.Format_Options_Type;
-- Return the formatting options for Gnatformat

function Get_Documentation_Style (Self : Context) return
GNATdoc.Comments.Options.Documentation_Style;
-- Get the documentation style used for this context.
Expand Down Expand Up @@ -314,6 +320,8 @@ private
(Pp.Command_Lines.Descriptor'Access);
-- Object to keep gnatpp options

Format_Options : Gnatformat.Configuration.Format_Options_Type;

Style : GNATdoc.Comments.Options.Documentation_Style :=
GNATdoc.Comments.Options.GNAT;
-- The context's documentation style.
Expand All @@ -339,6 +347,11 @@ private
function Get_PP_Options (Self : Context) return
Utils.Command_Lines.Command_Line is (Self.PP_Options);

function Get_Format_Options
(Self : Context)
return Gnatformat.Configuration.Format_Options_Type
is (Self.Format_Options);

function Get_Documentation_Style (Self : Context) return
GNATdoc.Comments.Options.Documentation_Style is (Self.Style);

Expand Down
57 changes: 57 additions & 0 deletions source/ada/lsp-ada_documents.adb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ with GNAT.Strings;
with GNATCOLL.Traces;
with GNATCOLL.VFS;

with Gnatformat.Formatting;

with Langkit_Support.Symbols;
with Langkit_Support.Text;

Expand Down Expand Up @@ -613,6 +615,28 @@ package body LSP.Ada_Documents is
return False;
end Formatting;

------------
-- Format --
------------

function Format
(Self : Document;
Context : LSP.Ada_Contexts.Context)
return LSP.Structures.TextEdit_Vector
is
Result : LSP.Structures.TextEdit_Vector;

Formatted_Document : constant VSS.Strings.Virtual_String :=
VSS.Strings.Conversions.To_Virtual_String
(Gnatformat.Formatting.Format (Self.Unit (Context),
Context.Get_Format_Options));

begin
Self.Diff (New_Text => Formatted_Document, Edit => Result);

return Result;
end Format;

--------------------
-- Get_Any_Symbol --
--------------------
Expand Down Expand Up @@ -1211,6 +1235,39 @@ package body LSP.Ada_Documents is
return False;
end Range_Formatting;

------------------
-- Range_Format --
------------------

function Range_Format
(Self : Document;
Context : LSP.Ada_Contexts.Context;
Span : LSP.Structures.A_Range)
return LSP.Structures.TextEdit
is
use type LSP.Structures.A_Range;

begin
if Span = LSP.Text_Documents.Empty_Range then
return (LSP.Constants.Empty, VSS.Strings.Empty_Virtual_String);
end if;

declare
Range_Formatted_Document :
constant Gnatformat.Formatting.Formatted_Edits :=
Gnatformat.Formatting.Range_Format
(Self.Unit (Context),
Self.To_Source_Location_Range (Span),
Context.Get_Format_Options);

begin
return
(Self.To_A_Range (Range_Formatted_Document.Edit.Location),
VSS.Strings.Conversions.To_Virtual_String
(Range_Formatted_Document.Edit.Text));
end;
end Range_Format;

------------------------
-- Reset_Symbol_Cache --
------------------------
Expand Down
14 changes: 14 additions & 0 deletions source/ada/lsp-ada_documents.ads
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ package LSP.Ada_Documents is
Messages : out VSS.String_Vectors.Virtual_String_Vector) return Boolean;
-- Format document or its part defined in Span

function Format
(Self : Document;
Context : LSP.Ada_Contexts.Context)
return LSP.Structures.TextEdit_Vector;
-- Format Self with formatting options based on Context

function Range_Formatting
(Self : Document;
Context : LSP.Ada_Contexts.Context;
Expand All @@ -187,6 +193,14 @@ package LSP.Ada_Documents is
return Boolean;
-- Format document or its part defined in Span

function Range_Format
(Self : Document;
Context : LSP.Ada_Contexts.Context;
Span : LSP.Structures.A_Range)
return LSP.Structures.TextEdit;
-- Format part of Self defined by Span with formatting options based on
-- Context.

procedure Find_All_References
(Self : Document;
Context : LSP.Ada_Contexts.Context;
Expand Down
3 changes: 3 additions & 0 deletions source/ada/lsp-ada_driver.adb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ with GNAT.OS_Lib;
with GNAT.Strings;

pragma Warnings (Off, "is an internal GNAT unit");
with Gnatformat.Configuration;
with System.Soft_Links;
with System.Secondary_Stack;

Expand Down Expand Up @@ -428,6 +429,8 @@ begin
Ada.Text_IO.Set_Output (Ada.Text_IO.Standard_Error);
-- Protect stdout from pollution by accidental Put_Line calls

Gnatformat.Configuration.Elaborate_GPR2;

declare
Allow_Incremental_Text_Changes : constant GNATCOLL.Traces.Trace_Handle
:= GNATCOLL.Traces.Create ("ALS.ALLOW_INCREMENTAL_TEXT_CHANGES",
Expand Down
164 changes: 127 additions & 37 deletions source/ada/lsp-ada_handlers-formatting.adb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ package body LSP.Ada_Handlers.Formatting is
Formatting_Trace : constant GNATCOLL.Traces.Trace_Handle :=
GNATCOLL.Traces.Create ("ALS.FORMATTING", GNATCOLL.Traces.On);

Gnatformat_Trace : constant GNATCOLL.Traces.Trace_Handle :=
GNATCOLL.Traces.Create ("ALS.GNATFORMAT", GNATCOLL.Traces.Off);

procedure Update_Pp_Formatting_Options
(Pp_Options : in out Utils.Command_Lines.Command_Line;
LSP_Options : LSP.Structures.FormattingOptions);
Expand All @@ -48,36 +51,75 @@ package body LSP.Ada_Handlers.Formatting is
Messages : out VSS.String_Vectors.Virtual_String_Vector;
Error : out LSP.Errors.ResponseError)
is
PP_Options : Utils.Command_Lines.Command_Line := Context.Get_PP_Options;
procedure Gnatpp_Format;

procedure Gnatformat_Format;

-------------------
-- Gnatpp_Format --
-------------------

procedure Gnatpp_Format
is
PP_Options : Utils.Command_Lines.Command_Line :=
Context.Get_PP_Options;

begin
-- Take into account the options set by the request only if the
-- corresponding GPR switches are not explicitly set.

Update_Pp_Formatting_Options
(Pp_Options => PP_Options, LSP_Options => Options);

Success := Document.Formatting
(Context => Context,
Span => Span,
Cmd => PP_Options,
Edit => Response,
Messages => Messages);

if not Success then
Error :=
(code => LSP.Enumerations.InternalError,
message => Messages.Join (' '));
Messages.Clear;
end if;
end Gnatpp_Format;

-----------------------
-- Gnatformat_Format --
-----------------------

procedure Gnatformat_Format
is
begin
Success := True;
Response := Document.Format (Context);

exception
when E : others =>
Context.Tracer.Trace_Exception (E, "in GNATformat Format");
Success := False;
Error :=
(code => LSP.Enumerations.InternalError,
message => "GNATformat failed to format source");
end Gnatformat_Format;

begin
if Document.Has_Diagnostics (Context) then
Success := False;
Error :=
(code => LSP.Enumerations.InternalError,
(code => LSP.Enumerations.InternalError,
message => "Incorrect code can't be formatted");

return;
end if;

-- Take into account the options set by the request only if the
-- corresponding GPR switches are not explicitly set.
if Gnatformat_Trace.Is_Active then
Gnatformat_Format;

Update_Pp_Formatting_Options
(Pp_Options => PP_Options, LSP_Options => Options);

Success := Document.Formatting
(Context => Context,
Span => Span,
Cmd => PP_Options,
Edit => Response,
Messages => Messages);

if not Success then
Error :=
(code => LSP.Enumerations.InternalError,
message => Messages.Join (' '));
Messages.Clear;
else
Gnatpp_Format;
end if;
end Format;

Expand All @@ -94,8 +136,68 @@ package body LSP.Ada_Handlers.Formatting is
Response : out LSP.Structures.TextEdit_Vector;
Error : out LSP.Errors.ResponseError)
is
PP_Options : Utils.Command_Lines.Command_Line := Context.Get_PP_Options;
Messages : VSS.String_Vectors.Virtual_String_Vector;
procedure Gnatpp_Range_Format;

procedure Gnatformat_Range_Format;

-------------------------
-- Gnatpp_Range_Format --
-------------------------

procedure Gnatpp_Range_Format
is
PP_Options : Utils.Command_Lines.Command_Line :=
Context.Get_PP_Options;
Messages : VSS.String_Vectors.Virtual_String_Vector;

begin
-- Take into account the options set by the request only if the
-- corresponding GPR switches are not explicitly set.

Update_Pp_Formatting_Options
(Pp_Options => PP_Options, LSP_Options => Options);

Success := Document.Range_Formatting
(Context => Context,
Span => Span,
PP_Options => PP_Options,
Edit => Response,
Messages => Messages);

if not Success then
Error :=
(code => LSP.Enumerations.InternalError,
message => Messages.Join (' '));
end if;
if Document.Has_Diagnostics (Context) then
Success := False;
Error :=
(code => LSP.Enumerations.InternalError,
message => "Incorrect code can't be formatted");

return;
end if;
end Gnatpp_Range_Format;

----------------------------
-- Gnatformat_Range_Format --
-----------------------------

procedure Gnatformat_Range_Format
is
begin
Success := True;
Response.Clear;
Response.Append (Document.Range_Format (Context, Span));

exception
when E : others =>
Context.Tracer.Trace_Exception (E, "in GNATformat Range_Format");
Success := False;
Error :=
(code => LSP.Enumerations.InternalError,
message => "GNATformat failed to format source");
end Gnatformat_Range_Format;

begin
if Document.Has_Diagnostics (Context) then
Expand All @@ -107,23 +209,11 @@ package body LSP.Ada_Handlers.Formatting is
return;
end if;

-- Take into account the options set by the request only if the
-- corresponding GPR switches are not explicitly set.
if Gnatformat_Trace.Is_Active then
Gnatformat_Range_Format;

Update_Pp_Formatting_Options
(Pp_Options => PP_Options, LSP_Options => Options);

Success := Document.Range_Formatting
(Context => Context,
Span => Span,
PP_Options => PP_Options,
Edit => Response,
Messages => Messages);

if not Success then
Error :=
(code => LSP.Enumerations.InternalError,
message => Messages.Join (' '));
else
Gnatpp_Range_Format;
end if;
end Range_Format;

Expand Down
Loading

0 comments on commit b963eb2

Please sign in to comment.