Skip to content

Commit a026535

Browse files
UB30-006 GNATpp partial formatting integration
1 parent a4d7511 commit a026535

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
@@ -795,6 +795,37 @@ package body LSP.Ada_Contexts is
795795
Messages => Messages);
796796
end Format;
797797

798+
------------------
799+
-- Range_Format --
800+
------------------
801+
802+
procedure Range_Format
803+
(Self : in out Context;
804+
Document : LSP.Ada_Documents.Document_Access;
805+
Span : LSP.Messages.Span;
806+
Options : LSP.Messages.FormattingOptions;
807+
Edit : out LSP.Messages.TextEdit_Vector;
808+
Success : out Boolean;
809+
Messages : out VSS.String_Vectors.Virtual_String_Vector) is
810+
begin
811+
Pp.Command_Lines.Pp_Nat_Switches.Set_Arg
812+
(Self.PP_Options,
813+
Pp.Command_Lines.Indentation,
814+
Natural (Options.tabSize));
815+
816+
Pp.Command_Lines.Pp_Flag_Switches.Set_Arg
817+
(Self.PP_Options,
818+
Pp.Command_Lines.No_Tab,
819+
Options.insertSpaces);
820+
821+
Success := Document.Range_Formatting
822+
(Context => Self,
823+
Span => Span,
824+
PP_Options => Self.PP_Options,
825+
Edit => Edit,
826+
Messages => Messages);
827+
end Range_Format;
828+
798829
----------
799830
-- Free --
800831
----------

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
@@ -184,6 +184,16 @@ package LSP.Ada_Documents is
184184
return Boolean;
185185
-- Format document or its part defined in Span
186186

187+
function Range_Formatting
188+
(Self : Document;
189+
Context : LSP.Ada_Contexts.Context;
190+
Span : LSP.Messages.Span;
191+
PP_Options : Pp.Command_Lines.Cmd_Line;
192+
Edit : out LSP.Messages.TextEdit_Vector;
193+
Messages : out VSS.String_Vectors.Virtual_String_Vector)
194+
return Boolean;
195+
-- Format document or its part defined in Span
196+
187197
procedure Get_Imported_Units
188198
(Self : Document;
189199
Context : LSP.Ada_Contexts.Context;
@@ -356,9 +366,9 @@ private
356366
New_Span : LSP.Messages.Span := LSP.Messages.Empty_Span;
357367
Edit : out LSP.Messages.TextEdit_Vector);
358368
-- Create a diff between document Text and New_Text and return Text_Edit
359-
-- based on Needleman-Wunsch algorithm
369+
-- based on Needleman-Wunsch algorithm.
360370
-- Old_Span and New_Span are used when we need to compare certain
361-
-- old/new lines instead of whole buffers
371+
-- old/new lines instead of whole buffers.
362372

363373
function URI (Self : Document) return LSP.Messages.DocumentUri is
364374
(Self.URI);

source/ada/lsp-ada_handlers.adb

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

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

237+
function Range_Format
238+
(Self : in out LSP.Ada_Contexts.Context;
239+
Document : LSP.Ada_Documents.Document_Access;
240+
Span : LSP.Messages.Span;
241+
Options : LSP.Messages.FormattingOptions)
242+
return LSP.Messages.Server_Responses.Formatting_Response;
243+
-- Format the text of the given document in the given range (span).
244+
231245
type File_Span is record
232246
File : GNATCOLL.VFS.Virtual_File;
233247
Span : LSP.Messages.Span;
@@ -831,7 +845,7 @@ package body LSP.Ada_Handlers is
831845
Document : LSP.Ada_Documents.Document_Access;
832846
Span : LSP.Messages.Span;
833847
Options : LSP.Messages.FormattingOptions)
834-
return LSP.Messages.Server_Responses.Formatting_Response
848+
return LSP.Messages.Server_Responses.Formatting_Response
835849
is
836850
Response : LSP.Messages.Server_Responses.Formatting_Response
837851
(Is_Error => False);
@@ -871,6 +885,56 @@ package body LSP.Ada_Handlers is
871885
return Response;
872886
end Format;
873887

888+
------------------
889+
-- Range_Format --
890+
------------------
891+
892+
function Range_Format
893+
(Self : in out LSP.Ada_Contexts.Context;
894+
Document : LSP.Ada_Documents.Document_Access;
895+
Span : LSP.Messages.Span;
896+
Options : LSP.Messages.FormattingOptions)
897+
return LSP.Messages.Server_Responses.Formatting_Response
898+
is
899+
Response : LSP.Messages.Server_Responses.Formatting_Response
900+
(Is_Error => False);
901+
Success : Boolean;
902+
Messages : VSS.String_Vectors.Virtual_String_Vector;
903+
904+
begin
905+
Self.Range_Format
906+
(Document => Document,
907+
Span => Span,
908+
Options => Options,
909+
Edit => Response.result,
910+
Success => Success,
911+
Messages => Messages);
912+
913+
if not Success then
914+
declare
915+
use VSS.Strings;
916+
917+
Response : LSP.Messages.Server_Responses.Formatting_Response
918+
(Is_Error => True);
919+
Error_Msg : VSS.Strings.Virtual_String;
920+
begin
921+
-- Display error messages from gnatpp, if any
922+
for Msg of Messages loop
923+
Error_Msg := Error_Msg & Msg;
924+
end loop;
925+
926+
Response.error :=
927+
(True,
928+
(code => LSP.Errors.InternalError,
929+
message => Error_Msg,
930+
data => <>));
931+
return Response;
932+
end;
933+
end if;
934+
935+
return Response;
936+
end Range_Format;
937+
874938
------------------------
875939
-- Initialize_Request --
876940
------------------------
@@ -5862,7 +5926,7 @@ package body LSP.Ada_Handlers is
58625926
Response.error :=
58635927
(True,
58645928
(code => LSP.Errors.InternalError,
5865-
message => "Incorrect code can't be formatted",
5929+
message => "Syntactically incorrect code can't be formatted",
58665930
data => <>));
58675931
end return;
58685932
end if;
@@ -5871,11 +5935,18 @@ package body LSP.Ada_Handlers is
58715935
use LSP.Messages;
58725936

58735937
Result : constant Server_Responses.Formatting_Response :=
5874-
Format
5875-
(Self => Context.all,
5876-
Document => Document,
5877-
Span => Request.params.span,
5878-
Options => Request.params.options);
5938+
(if Partial_GNATpp.Is_Active then
5939+
Range_Format
5940+
(Self => Context.all,
5941+
Document => Document,
5942+
Span => Request.params.span,
5943+
Options => Request.params.options)
5944+
else
5945+
Format
5946+
(Self => Context.all,
5947+
Document => Document,
5948+
Span => Request.params.span,
5949+
Options => Request.params.options));
58795950
Response : Server_Responses.Range_Formatting_Response
58805951
(Is_Error => Result.Is_Error);
58815952
begin

0 commit comments

Comments
 (0)