Skip to content

Commit

Permalink
Merge remote branch 'origin/master' into edge
Browse files Browse the repository at this point in the history
  • Loading branch information
automatic-merge committed Apr 3, 2024
2 parents b7306d9 + abbdd3c commit 98c4407
Show file tree
Hide file tree
Showing 18 changed files with 844 additions and 629 deletions.
211 changes: 161 additions & 50 deletions source/ada/lsp-ada_handlers-project_diagnostics.adb
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,54 @@
-- of the license. --
------------------------------------------------------------------------------

with GPR2.Source_Reference;
with GPR2.Message;
with GPR2.Path_Name;

with VSS.Strings;

with LSP.Enumerations;
with LSP.Utils;

package body LSP.Ada_Handlers.Project_Diagnostics is

Single_Project_Found_Message : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String
("Unique project in root directory was found and " &
"loaded, but it wasn't explicitly configured.");

No_Runtime_Found_Message : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String
("The project was loaded, but no Ada runtime found. " &
"Please check the installation of the Ada compiler.");

No_Project_Found_Message : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String
("No project found in root directory. " &
"Please create a project file and add it to the configuration.");
Project_Loading_Status_Messages : constant array (Load_Project_Status)
of VSS.Strings.Virtual_String :=
(Single_Project_Found =>
VSS.Strings.To_Virtual_String
("Unique project in root directory was found and "
& "loaded, but it wasn't explicitly configured."),
No_Runtime_Found =>
VSS.Strings.To_Virtual_String
("The project was loaded, but no Ada runtime found. "
& "Please check the installation of the Ada compiler."),
No_Project_Found =>
VSS.Strings.To_Virtual_String
("No project found in root directory. "
& "Please create a project file and add it to the "
& "configuration."),
Multiple_Projects_Found =>
VSS.Strings.To_Virtual_String
("No project was loaded, because more than one "
& "project file has been found in the root directory. "
& "Please change configuration to point a correct project "
& "file."),
Invalid_Project_Configured =>
VSS.Strings.To_Virtual_String
("Project file has errors and can't be loaded."),
others => VSS.Strings.Empty_Virtual_String);
-- The diagnostics' messages depending on the project loading status.

Multiple_Projects_Found_Message : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String
("No project was loaded, because more than one project file has been " &
"found in the root directory. Please change configuration to point " &
"a correct project file.");

Invalid_Project_Configured_Message : constant VSS.Strings.Virtual_String :=
VSS.Strings.To_Virtual_String
("Project file has error and can't be loaded.");
Project_Loading_Status_Severities : constant array (Load_Project_Status)
of LSP.Enumerations.DiagnosticSeverity :=
(Valid_Project_Configured => LSP.Enumerations.Hint,
Alire_Project => LSP.Enumerations.Hint,
Single_Project_Found => LSP.Enumerations.Hint,
No_Runtime_Found => LSP.Enumerations.Warning,
Multiple_Projects_Found => LSP.Enumerations.Error,
No_Project_Found => LSP.Enumerations.Error,
Invalid_Project_Configured => LSP.Enumerations.Error);
-- The diagnostics' severities depending on the project loading status.

--------------------
-- Get_Diagnostic --
Expand All @@ -55,33 +73,124 @@ package body LSP.Ada_Handlers.Project_Diagnostics is
Context : LSP.Ada_Contexts.Context;
Errors : out LSP.Structures.Diagnostic_Vector)
is
Item : LSP.Structures.Diagnostic;
use LSP.Structures;

Parent_Diagnostic : LSP.Structures.Diagnostic;
GPR2_Messages : GPR2.Log.Object renames
Self.Handler.Project_Status.GPR2_Messages;

procedure Create_Project_Loading_Diagnostic;
-- Create a parent diagnostic for the project loading status.

procedure Append_GPR2_Diagnostics;
-- Append the GPR2 messages to the given parent diagnostic, if any.

---------------------------------------
-- Create_Project_Loading_Diagnostic --
---------------------------------------

procedure Create_Project_Loading_Diagnostic is
Sloc : constant LSP.Structures.A_Range :=
(start => (0, 0),
an_end => (0, 0));
begin
-- Initialize the parent diagnostic.
Parent_Diagnostic.a_range := ((0, 0), (0, 0));
Parent_Diagnostic.source := "project";
Parent_Diagnostic.severity :=
(True, Project_Loading_Status_Severities (Self.Last_Status));

-- If we don't have any GPR2 messages, display the project loading
-- status message in the parent diagnostic directly.
-- Otherwise display a generic message in the parent amnd append it
-- to its children, along with the other GPR2 messages.
if GPR2_Messages.Is_Empty then
Parent_Diagnostic.message := Project_Loading_Status_Messages
(Self.Last_Status);
else
declare
Project_File : GNATCOLL.VFS.Virtual_File renames
Self.Handler.Project_Status.Project_File;
URI : constant LSP.Structures.DocumentUri :=
Self.Handler.To_URI
(Project_File.Display_Full_Name);
begin
Parent_Diagnostic.message := "Project Problems";
Parent_Diagnostic.relatedInformation.Append
(LSP.Structures.DiagnosticRelatedInformation'
(location =>
LSP.Structures.Location'
(uri => URI, a_range => Sloc,
others => <>),
message =>
Project_Loading_Status_Messages
(Self.Last_Status)));
end;
end if;
end Create_Project_Loading_Diagnostic;

-----------------------------
-- Append_GPR2_Diagnostics --
-----------------------------

procedure Append_GPR2_Diagnostics is
use GPR2.Message;
use LSP.Enumerations;
begin
for Msg of GPR2_Messages loop
if Msg.Level in GPR2.Message.Warning .. GPR2.Message.Error then
declare
Sloc : constant GPR2.Source_Reference.Object :=
GPR2.Message.Sloc (Msg);
File : constant GPR2.Path_Name.Object :=
(if Sloc.Is_Defined and then Sloc.Has_Source_Reference then
GPR2.Path_Name.Create_File
(GPR2.Filename_Type (Sloc.Filename))
else
Self.Handler.Project_Tree.Root_Path);
begin
Parent_Diagnostic.relatedInformation.Append
(LSP .Structures.DiagnosticRelatedInformation'
(location => LSP.Structures.Location'
(uri => LSP.Utils.To_URI (File),
a_range => LSP.Utils.To_Range (Sloc),
others => <>),
message => VSS.Strings.Conversions.To_Virtual_String
(Msg.Message)));
end;

-- If we have one error in the GPR2 messages, the parent
-- diagnostic's severity should be "error" too, otherwise
-- "warning".
if Msg.Level = GPR2.Message.Error then
Parent_Diagnostic.severity :=
(True, LSP.Enumerations.Error);
elsif Parent_Diagnostic.severity.Value /=
LSP.Enumerations.Error
then
Parent_Diagnostic.severity :=
(True, LSP.Enumerations.Warning);
end if;
end if;
end loop;
end Append_GPR2_Diagnostics;

begin
Self.Last_Status := Self.Handler.Project_Status;
Item.a_range := ((0, 0), (0, 0));
Item.source := "project";
Item.severity := (True, LSP.Enumerations.Error);

case Self.Last_Status is
when Valid_Project_Configured | Alire_Project =>
null;
when No_Runtime_Found =>
Item.message := No_Runtime_Found_Message;
Errors.Append (Item);
when Single_Project_Found =>
Item.message := Single_Project_Found_Message;
Item.severity := (True, LSP.Enumerations.Hint);
Errors.Append (Item);
when No_Project_Found =>
Item.message := No_Project_Found_Message;
Errors.Append (Item);
when Multiple_Projects_Found =>
Item.message := Multiple_Projects_Found_Message;
Errors.Append (Item);
when Invalid_Project_Configured =>
Item.message := Invalid_Project_Configured_Message;
Errors.Append (Item);
end case;
Self.Last_Status := Self.Handler.Project_Status.Load_Status;

-- If we have a valid project return immediately: we want to display
-- diagnostics only if there is an issue to solve or a potential
-- enhancement.
if Self.Last_Status = Valid_Project_Configured
or else (Self.Last_Status = Alire_Project and then GPR2_Messages.Is_Empty)
then
return;
end if;

Create_Project_Loading_Diagnostic;
Append_GPR2_Diagnostics;

Errors.Append (Parent_Diagnostic);
end Get_Diagnostic;

------------------------
Expand All @@ -95,7 +204,9 @@ package body LSP.Ada_Handlers.Project_Diagnostics is
is
pragma Unreferenced (Context);
begin
return Self.Last_Status /= Self.Handler.Project_Status;
return
(Self.Last_Status /= Self.Handler.Project_Status.Load_Status
or else not Self.Handler.Project_Status.GPR2_Messages.Is_Empty);
end Has_New_Diagnostic;

end LSP.Ada_Handlers.Project_Diagnostics;
2 changes: 1 addition & 1 deletion source/ada/lsp-ada_handlers-project_diagnostics.ads
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private
type Diagnostic_Source
(Handler : not null access LSP.Ada_Handlers.Message_Handler)
is limited new LSP.Diagnostic_Sources.Diagnostic_Source with record
Last_Status : Load_Project_Status := Valid_Project_Configured;
Last_Status : Load_Project_Status := No_Project_Found;
end record;

end LSP.Ada_Handlers.Project_Diagnostics;
Loading

0 comments on commit 98c4407

Please sign in to comment.