Skip to content

Commit 70e06b4

Browse files
UB30-006 GNATpp partial formatting integration
1 parent 8acaaa3 commit 70e06b4

File tree

5 files changed

+282
-10
lines changed

5 files changed

+282
-10
lines changed

source/ada/lsp-ada_contexts.adb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,37 @@ package body LSP.Ada_Contexts is
779779
Messages => Messages);
780780
end Format;
781781

782+
------------------
783+
-- Range_Format --
784+
------------------
785+
786+
procedure Range_Format
787+
(Self : in out Context;
788+
Document : LSP.Ada_Documents.Document_Access;
789+
Span : LSP.Messages.Span;
790+
Options : LSP.Messages.FormattingOptions;
791+
Edit : out LSP.Messages.TextEdit_Vector;
792+
Success : out Boolean;
793+
Messages : out VSS.String_Vectors.Virtual_String_Vector) is
794+
begin
795+
Pp.Command_Lines.Pp_Nat_Switches.Set_Arg
796+
(Self.PP_Options,
797+
Pp.Command_Lines.Indentation,
798+
Natural (Options.tabSize));
799+
800+
Pp.Command_Lines.Pp_Flag_Switches.Set_Arg
801+
(Self.PP_Options,
802+
Pp.Command_Lines.No_Tab,
803+
Options.insertSpaces);
804+
805+
Success := Document.Range_Formatting
806+
(Context => Self,
807+
Span => Span,
808+
PP_Options => Self.PP_Options,
809+
Edit => Edit,
810+
Messages => Messages);
811+
end Range_Format;
812+
782813
----------
783814
-- Free --
784815
----------

source/ada/lsp-ada_contexts.ads

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ package LSP.Ada_Contexts is
111111
Success : out Boolean;
112112
Messages : out VSS.String_Vectors.Virtual_String_Vector);
113113

114+
procedure Range_Format
115+
(Self : in out Context;
116+
Document : LSP.Ada_Documents.Document_Access;
117+
Span : LSP.Messages.Span;
118+
Options : LSP.Messages.FormattingOptions;
119+
Edit : out LSP.Messages.TextEdit_Vector;
120+
Success : out Boolean;
121+
Messages : out VSS.String_Vectors.Virtual_String_Vector);
122+
114123
procedure Find_All_References
115124
(Self : Context;
116125
Definition : Libadalang.Analysis.Defining_Name;

source/ada/lsp-ada_documents.adb

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ with Libadalang.Sources;
3333
with Libadalang.Iterators;
3434

3535
with Laltools.Common;
36+
with Laltools.Partial_GNATPP;
3637

3738
with VSS.Strings.Character_Iterators;
3839
with VSS.Strings.Line_Iterators;
@@ -45,7 +46,9 @@ with LSP.Ada_Documents.LAL_Diagnostics;
4546
with LSP.Common; use LSP.Common;
4647
with LSP.Lal_Utils;
4748

49+
with Pp.Actions;
4850
with Pp.Scanner;
51+
4952
with Utils.Char_Vectors;
5053

5154
package body LSP.Ada_Documents is
@@ -671,7 +674,7 @@ package body LSP.Ada_Documents is
671674
Out_Sloc => Out_Sloc,
672675
Messages => PP_Messages);
673676

674-
-- Prolerly format the messages received from gnatpp, using the
677+
-- Properly format the messages received from gnatpp, using the
675678
-- the GNAT standard way for messages (i.e: <filename>:<sloc>: <msg>)
676679

677680
if not PP_Messages.Is_Empty then
@@ -732,6 +735,154 @@ package body LSP.Ada_Documents is
732735
return False;
733736
end Formatting;
734737

738+
----------------------
739+
-- Range_Formatting --
740+
----------------------
741+
742+
function Range_Formatting
743+
(Self : Document;
744+
Context : LSP.Ada_Contexts.Context;
745+
Span : LSP.Messages.Span;
746+
PP_Options : Pp.Command_Lines.Cmd_Line;
747+
Edit : out LSP.Messages.TextEdit_Vector;
748+
Messages : out VSS.String_Vectors.Virtual_String_Vector)
749+
return Boolean
750+
is
751+
use Langkit_Support.Slocs;
752+
use Laltools.Partial_GNATPP;
753+
use LSP.Types;
754+
use LSP.Messages;
755+
use Utils.Char_Vectors;
756+
use Utils.Char_Vectors.Char_Vectors;
757+
758+
procedure Append_PP_Messages
759+
(PP_Messages : Pp.Scanner.Source_Message_Vector);
760+
-- Append any message of PP_Messages to Messages properly formatting
761+
-- them using the GNAT standard way for messages
762+
-- (i.e: <filename>:<sloc>: <msg>)
763+
764+
------------------------
765+
-- Append_PP_Messages --
766+
------------------------
767+
768+
procedure Append_PP_Messages
769+
(PP_Messages : Pp.Scanner.Source_Message_Vector)
770+
is
771+
Filename : constant String :=
772+
Context.URI_To_File (Self.URI);
773+
File : constant GNATCOLL.VFS.Virtual_File :=
774+
GNATCOLL.VFS.Create_From_UTF8 (Filename);
775+
776+
begin
777+
for Message of PP_Messages loop
778+
Messages.Append
779+
(VSS.Strings.Conversions.To_Virtual_String
780+
(File.Display_Base_Name
781+
& ":"
782+
& Pp.Scanner.Sloc_Image (Message.Sloc)
783+
& ": "
784+
& String (To_Array (Message.Text))));
785+
end loop;
786+
end Append_PP_Messages;
787+
788+
Input : Char_Vector;
789+
Output : Char_Vector;
790+
791+
PP_Messages : Pp.Scanner.Source_Message_Vector;
792+
793+
Input_Selection_Range : constant Source_Location_Range :=
794+
(if Span = LSP.Messages.Empty_Span then
795+
No_Source_Location_Range
796+
else
797+
Make_Range
798+
(Self.Get_Source_Location (Span.first),
799+
Self.Get_Source_Location (Span.last)));
800+
801+
Output_Selection_Range : Source_Location_Range;
802+
803+
Unit : constant Analysis_Unit :=
804+
Self.Unit (Context);
805+
Start_Node, End_Node : Ada_Node;
806+
Enclosing_Node : Ada_Node;
807+
808+
Offset : Natural := 0;
809+
810+
begin
811+
Context.Trace.Trace ("On Range_Formatting");
812+
813+
Context.Trace.Trace ("Get_Selected_Region_Enclosing_Node");
814+
Get_Selected_Region_Enclosing_Node
815+
(Unit => Unit,
816+
SL_Range => Input_Selection_Range,
817+
Start_Node => Start_Node,
818+
End_Node => End_Node,
819+
Enclosing_Node => Enclosing_Node,
820+
Input_Sel => Input,
821+
Output_Sel_Range => Output_Selection_Range);
822+
Context.Trace.Trace ("Start_Node: " & Start_Node.Image);
823+
Context.Trace.Trace ("End_Node: " & End_Node.Image);
824+
Context.Trace.Trace ("Enclosing_Node: " & Enclosing_Node.Image);
825+
Context.Trace.Trace
826+
("Output_Selection_Range: " & Image (Output_Selection_Range));
827+
828+
Context.Trace.Trace
829+
("Get_Starting_Offset and Set_Partial_Gnatpp_Offset");
830+
Offset :=
831+
Get_Starting_Offset
832+
(Node => Enclosing_Node,
833+
PP_Indent =>
834+
Pp.Command_Lines.PP_Indentation (PP_Options),
835+
PP_Indent_Continuation =>
836+
Pp.Command_Lines.PP_Indent_Continuation (PP_Options));
837+
Context.Trace.Trace (Offset'Image);
838+
if Offset /= 0 then
839+
Pp.Actions.Set_Partial_Gnatpp_Offset (Offset - 1);
840+
end if;
841+
842+
Context.Trace.Trace ("Format_Vector");
843+
begin
844+
Pp.Actions.Format_Vector
845+
(Cmd => PP_Options,
846+
Input => Input,
847+
Node => Enclosing_Node,
848+
Output => Output,
849+
Messages => PP_Messages,
850+
Partial_Gnatpp => True);
851+
exception
852+
when others =>
853+
Append_PP_Messages (PP_Messages);
854+
return False;
855+
end;
856+
857+
if not PP_Messages.Is_Empty then
858+
Context.Trace.Trace
859+
("Non empty PP_Messages - appending them to Messages");
860+
Append_PP_Messages (PP_Messages);
861+
return False;
862+
end if;
863+
864+
Context.Trace.Trace ("Computing Range_Formatting Text_Edits");
865+
declare
866+
Edit_Span : constant LSP.Messages.Span :=
867+
Self.To_LSP_Range (Output_Selection_Range);
868+
Output_Str : constant String :=
869+
Char_Vectors.Elems (Output)
870+
(1 .. Char_Vectors.Last_Index (Output) - 1);
871+
Edit_Text : constant VSS.Strings.Virtual_String :=
872+
VSS.Strings.Conversions.To_Virtual_String (Output_Str);
873+
Text_Edit : constant LSP.Messages.TextEdit := (Edit_Span, Edit_Text);
874+
875+
begin
876+
Edit.Append (Text_Edit);
877+
end;
878+
879+
return True;
880+
881+
exception
882+
when others =>
883+
return False;
884+
end Range_Formatting;
885+
735886
------------------------
736887
-- Get_Imported_Units --
737888
------------------------

source/ada/lsp-ada_documents.ads

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,16 @@ package LSP.Ada_Documents is
181181
return Boolean;
182182
-- Format document or its part defined in Span
183183

184+
function Range_Formatting
185+
(Self : Document;
186+
Context : LSP.Ada_Contexts.Context;
187+
Span : LSP.Messages.Span;
188+
PP_Options : Pp.Command_Lines.Cmd_Line;
189+
Edit : out LSP.Messages.TextEdit_Vector;
190+
Messages : out VSS.String_Vectors.Virtual_String_Vector)
191+
return Boolean;
192+
-- Format document or its part defined in Span
193+
184194
procedure Get_Imported_Units
185195
(Self : Document;
186196
Context : LSP.Ada_Contexts.Context;
@@ -353,9 +363,9 @@ private
353363
New_Span : LSP.Messages.Span := LSP.Messages.Empty_Span;
354364
Edit : out LSP.Messages.TextEdit_Vector);
355365
-- Create a diff between document Text and New_Text and return Text_Edit
356-
-- based on Needleman-Wunsch algorithm
366+
-- based on Needleman-Wunsch algorithm.
357367
-- Old_Span and New_Span are used when we need to compare certain
358-
-- old/new lines instead of whole buffers
368+
-- old/new lines instead of whole buffers.
359369

360370
function URI (Self : Document) return LSP.Messages.DocumentUri is
361371
(Self.URI);

source/ada/lsp-ada_handlers.adb

Lines changed: 78 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ package body LSP.Ada_Handlers is
117117
GNATCOLL.Traces.On);
118118
-- Trace to enable/disable runtime indexing. Useful for the testsuite.
119119

120+
Partial_GNATpp : constant GNATCOLL.Traces.Trace_Handle :=
121+
GNATCOLL.Traces.Create ("ALS.PARTIAL_GNATPP",
122+
GNATCOLL.Traces.Off);
123+
-- Use partial formatting mode of gnatpp if On. Otherwise, use diff
124+
-- algorithm.
125+
120126
Is_Parent : constant LSP.Messages.AlsReferenceKind_Set :=
121127
(Is_Server_Side => True,
122128
As_Flags => [LSP.Messages.Parent => True, others => False]);
@@ -232,6 +238,14 @@ package body LSP.Ada_Handlers is
232238
return LSP.Messages.Server_Responses.Formatting_Response;
233239
-- Format the text of the given document in the given range (span).
234240

241+
function Range_Format
242+
(Self : in out LSP.Ada_Contexts.Context;
243+
Document : LSP.Ada_Documents.Document_Access;
244+
Span : LSP.Messages.Span;
245+
Options : LSP.Messages.FormattingOptions)
246+
return LSP.Messages.Server_Responses.Formatting_Response;
247+
-- Format the text of the given document in the given range (span).
248+
235249
type File_Span is record
236250
File : GNATCOLL.VFS.Virtual_File;
237251
Span : LSP.Messages.Span;
@@ -800,7 +814,7 @@ package body LSP.Ada_Handlers is
800814
Document : LSP.Ada_Documents.Document_Access;
801815
Span : LSP.Messages.Span;
802816
Options : LSP.Messages.FormattingOptions)
803-
return LSP.Messages.Server_Responses.Formatting_Response
817+
return LSP.Messages.Server_Responses.Formatting_Response
804818
is
805819
Response : LSP.Messages.Server_Responses.Formatting_Response
806820
(Is_Error => False);
@@ -840,6 +854,56 @@ package body LSP.Ada_Handlers is
840854
return Response;
841855
end Format;
842856

857+
------------------
858+
-- Range_Format --
859+
------------------
860+
861+
function Range_Format
862+
(Self : in out LSP.Ada_Contexts.Context;
863+
Document : LSP.Ada_Documents.Document_Access;
864+
Span : LSP.Messages.Span;
865+
Options : LSP.Messages.FormattingOptions)
866+
return LSP.Messages.Server_Responses.Formatting_Response
867+
is
868+
Response : LSP.Messages.Server_Responses.Formatting_Response
869+
(Is_Error => False);
870+
Success : Boolean;
871+
Messages : VSS.String_Vectors.Virtual_String_Vector;
872+
873+
begin
874+
Self.Range_Format
875+
(Document => Document,
876+
Span => Span,
877+
Options => Options,
878+
Edit => Response.result,
879+
Success => Success,
880+
Messages => Messages);
881+
882+
if not Success then
883+
declare
884+
use VSS.Strings;
885+
886+
Response : LSP.Messages.Server_Responses.Formatting_Response
887+
(Is_Error => True);
888+
Error_Msg : VSS.Strings.Virtual_String;
889+
begin
890+
-- Display error messages from gnatpp, if any
891+
for Msg of Messages loop
892+
Error_Msg := Error_Msg & Msg;
893+
end loop;
894+
895+
Response.error :=
896+
(True,
897+
(code => LSP.Errors.InternalError,
898+
message => Error_Msg,
899+
data => <>));
900+
return Response;
901+
end;
902+
end if;
903+
904+
return Response;
905+
end Range_Format;
906+
843907
------------------------
844908
-- Initialize_Request --
845909
------------------------
@@ -5798,7 +5862,7 @@ package body LSP.Ada_Handlers is
57985862
Response.error :=
57995863
(True,
58005864
(code => LSP.Errors.InternalError,
5801-
message => "Incorrect code can't be formatted",
5865+
message => "Syntactically incorrect code can't be formatted",
58025866
data => <>));
58035867
end return;
58045868
end if;
@@ -5807,11 +5871,18 @@ package body LSP.Ada_Handlers is
58075871
use LSP.Messages;
58085872

58095873
Result : constant Server_Responses.Formatting_Response :=
5810-
Format
5811-
(Self => Context.all,
5812-
Document => Document,
5813-
Span => Request.params.span,
5814-
Options => Request.params.options);
5874+
(if Partial_GNATpp.Is_Active then
5875+
Range_Format
5876+
(Self => Context.all,
5877+
Document => Document,
5878+
Span => Request.params.span,
5879+
Options => Request.params.options)
5880+
else
5881+
Format
5882+
(Self => Context.all,
5883+
Document => Document,
5884+
Span => Request.params.span,
5885+
Options => Request.params.options));
58155886
Response : Server_Responses.Range_Formatting_Response
58165887
(Is_Error => Result.Is_Error);
58175888
begin

0 commit comments

Comments
 (0)