Skip to content

Commit

Permalink
Merge branch 'topic/lal_refactor.13.nameres_failures' into 'edge'
Browse files Browse the repository at this point in the history
Improve handling of Error during Resolve_Name

See merge request eng/ide/ada_language_server!1498
  • Loading branch information
AdrienBoulanger committed Mar 27, 2024
2 parents 8486b8b + 7eccf59 commit 6cb2c1e
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 31 deletions.
4 changes: 2 additions & 2 deletions source/ada/lsp-ada_handlers-call_hierarchy.adb
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ package body LSP.Ada_Handlers.Call_Hierarchy is
--------------

procedure Callback (Subp_Call : Libadalang.Analysis.Ada_Node'Class) is
Ignore : Boolean;
Dummy : Libadalang.Common.Ref_Result_Kind;
Call_Definition : Libadalang.Analysis.Defining_Name;
Subp_Call_Name : constant Libadalang.Analysis.Name :=
Laltools.Common.Get_Node_As_Name (Subp_Call.As_Ada_Node);
Expand All @@ -290,7 +290,7 @@ package body LSP.Ada_Handlers.Call_Hierarchy is
-- First try to resolve the called function

Call_Definition := Laltools.Common.Resolve_Name
(Subp_Call_Name, Trace, Ignore);
(Subp_Call_Name, Trace, Dummy);

if not Call_Definition.Is_Null then
if Result.Contains (Call_Definition) then
Expand Down
183 changes: 154 additions & 29 deletions source/ada/lsp-ada_handlers.adb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
-- of the license. --
------------------------------------------------------------------------------

with Ada.Characters.Latin_1;
with Ada.Strings.Unbounded;
with Ada.Strings.UTF_Encoding;
with Ada.Tags.Generic_Dispatching_Constructor;
Expand All @@ -37,6 +38,7 @@ with Laltools.Common;
with Laltools.Partial_GNATPP;

with Langkit_Support.Slocs;
with Langkit_Support.Text;

with LAL_Refactor.Extract_Subprogram;
with LAL_Refactor.Introduce_Parameter;
Expand Down Expand Up @@ -134,6 +136,17 @@ package body LSP.Ada_Handlers is
Name : String);
-- Save method in/out in a log file

function Resolve_Name
(Self : in out Message_Handler;
Id : LSP.Structures.Integer_Or_Virtual_String;
Context : LSP.Ada_Contexts.Context;
Name_Node : Libadalang.Analysis.Name;
Imprecise : out Boolean)
return Libadalang.Analysis.Defining_Name;
-- Toplayer Resolve_Name based on Laltools.Common.Resolve_Name.
-- This function is handling Imprecise and Error results during Nameres by
-- logging them and generating Diagnostics if needed.

function To_LSP_Location
(Self : in out Message_Handler'Class;
Node : Libadalang.Analysis.Ada_Node'Class;
Expand Down Expand Up @@ -345,11 +358,11 @@ package body LSP.Ada_Handlers is
Trace : constant GNATCOLL.Traces.Trace_Handle :=
LSP.GNATCOLL_Tracers.Handle (Self.Tracer.all);

Name_Node : constant Libadalang.Analysis.Name :=
Name_Node : constant Libadalang.Analysis.Name :=
Laltools.Common.Get_Node_As_Name
(Self.Get_Node_At (Context, Position));

Imprecise : Boolean;
Ref_Kind : Libadalang.Common.Ref_Result_Kind;
begin
if Name_Node.Is_Null then
return Libadalang.Analysis.No_Defining_Name;
Expand All @@ -358,7 +371,7 @@ package body LSP.Ada_Handlers is
return Laltools.Common.Resolve_Name
(Name_Node,
Trace,
Imprecise => Imprecise);
Ref_Kind => Ref_Kind);
end Imprecise_Resolve_Name;

---------------------------------
Expand Down Expand Up @@ -1731,7 +1744,7 @@ package body LSP.Ada_Handlers is
On_Defining_Name : Boolean := False;
-- Set to True if we are on a denfining name node

Is_Imprecise : Boolean;
Imprecise : Boolean;
begin
if Name_Node.Is_Null then
return;
Expand All @@ -1742,8 +1755,13 @@ package body LSP.Ada_Handlers is

if Definition.Is_Null then
-- If we aren't on a defining_name already then try to resolve
Definition := Laltools.Common.Resolve_Name
(Name_Node, Trace, Is_Imprecise);
Definition :=
Resolve_Name
(Self => Self,
Id => Id,
Context => C.all,
Name_Node => Name_Node,
Imprecise => Imprecise);
else
On_Defining_Name := True;
end if;
Expand Down Expand Up @@ -1795,12 +1813,13 @@ package body LSP.Ada_Handlers is

if not Decl_For_Find_Overrides.Is_Null then
declare
Overridings : constant Libadalang.Analysis.Basic_Decl_Array :=
Is_Imprecise : Boolean;
Overridings : constant Libadalang.Analysis.Basic_Decl_Array :=
C.Find_All_Overrides
(Decl_For_Find_Overrides,
Imprecise_Results => Is_Imprecise);

Bases : constant Libadalang.Analysis.Basic_Decl_Array :=
Bases : constant Libadalang.Analysis.Basic_Decl_Array :=
C.Find_All_Base_Declarations
(Decl_For_Find_Overrides,
Imprecise_Results => Is_Imprecise);
Expand Down Expand Up @@ -1856,7 +1875,7 @@ package body LSP.Ada_Handlers is
Vector : LSP.Structures.Location_Vector renames Response.Variant_1;
Filter : LSP.Locations.File_Span_Sets.Set;

Imprecise : Boolean := False;
Imprecise : Boolean;

Display_Method_Policy : constant
LSP.Enumerations.AlsDisplayMethodAncestryOnNavigationPolicy :=
Expand Down Expand Up @@ -1893,10 +1912,13 @@ package body LSP.Ada_Handlers is
Definition := Laltools.Common.Get_Name_As_Defining (Name_Node);

if Definition.Is_Null then
Definition := Laltools.Common.Resolve_Name
(Name_Node,
Trace,
Imprecise => Imprecise);
Definition :=
Resolve_Name
(Self => Self,
Id => Id,
Context => C.all,
Name_Node => Name_Node,
Imprecise => Imprecise);

if not Definition.Is_Null then
Self.Append_Location (Vector, Filter, Definition);
Expand Down Expand Up @@ -1970,6 +1992,7 @@ package body LSP.Ada_Handlers is

if not Decl_For_Find_Overrides.Is_Null then
declare
Imprecise : Boolean;
Overridings : constant Basic_Decl_Array :=
C.Find_All_Overrides
(Decl_For_Find_Overrides,
Expand Down Expand Up @@ -2912,17 +2935,20 @@ package body LSP.Ada_Handlers is
end Update_Response;

Definition : Libadalang.Analysis.Defining_Name;
Imprecise : Boolean;
Imprecise : Boolean := False;
Decl : Libadalang.Analysis.Basic_Decl;

begin
if Name_Node.Is_Null then
return;
end if;

-- Find the definition
Definition := Laltools.Common.Resolve_Name
(Name_Node, Trace, Imprecise);
Definition := Resolve_Name
(Self => Self,
Id => Id,
Context => C.all,
Name_Node => Name_Node,
Imprecise => Imprecise);

-- If we didn't find a definition, give up for this context
if Definition.Is_Null then
Expand Down Expand Up @@ -3464,9 +3490,6 @@ package body LSP.Ada_Handlers is
Id : LSP.Structures.Integer_Or_Virtual_String;
Value : LSP.Structures.PrepareRenameParams)
is
Trace : constant GNATCOLL.Traces.Trace_Handle :=
LSP.GNATCOLL_Tracers.Handle (Self.Tracer.all);

Response : LSP.Structures.PrepareRenameResult_Or_Null;

Context : constant LSP.Ada_Context_Sets.Context_Access :=
Expand All @@ -3480,12 +3503,14 @@ package body LSP.Ada_Handlers is

Defining_Name : Libadalang.Analysis.Defining_Name;

Imprecise : Boolean;
Imprecise : Boolean := False;
begin
if not Name_Node.Is_Null then
Defining_Name := Laltools.Common.Resolve_Name
(Name_Node,
Trace,
Defining_Name := Resolve_Name
(Self => Self,
Id => Id,
Context => Context.all,
Name_Node => Name_Node,
Imprecise => Imprecise);
end if;

Expand Down Expand Up @@ -4101,9 +4126,6 @@ package body LSP.Ada_Handlers is
------------------------

procedure Resolve_In_Context (C : LSP.Ada_Context_Sets.Context_Access) is
Trace : constant GNATCOLL.Traces.Trace_Handle :=
LSP.GNATCOLL_Tracers.Handle (Self.Tracer.all);

Name_Node : constant Libadalang.Analysis.Name :=
Laltools.Common.Get_Node_As_Name (Self.Get_Node_At (C.all, Value));

Expand All @@ -4125,8 +4147,13 @@ package body LSP.Ada_Handlers is
Def_Name.P_Basic_Decl.P_Type_Expression;
begin
if not Type_Expr.Is_Null then
Definition := Laltools.Common.Resolve_Name
(Type_Expr.P_Type_Name, Trace, Imprecise);
Definition :=
Resolve_Name
(Self => Self,
Id => Id,
Context => C.all,
Name_Node => Type_Expr.P_Type_Name,
Imprecise => Imprecise);
end if;
end;
else
Expand Down Expand Up @@ -4221,6 +4248,104 @@ package body LSP.Ada_Handlers is
LSP.Ada_Handlers.Project_Loading.Reload_Project (Self);
end Reload_Project;

------------------
-- Resolve_Name --
------------------

function Resolve_Name
(Self : in out Message_Handler;
Id : LSP.Structures.Integer_Or_Virtual_String;
Context : LSP.Ada_Contexts.Context;
Name_Node : Libadalang.Analysis.Name;
Imprecise : out Boolean)
return Libadalang.Analysis.Defining_Name
is
Definition : Libadalang.Analysis.Defining_Name;
Result_Kind : Libadalang.Common.Ref_Result_Kind;
Trace : constant GNATCOLL.Traces.Trace_Handle :=
LSP.GNATCOLL_Tracers.Handle (Self.Tracer.all);
Id_Image : constant String :=
(if Id.Is_Integer
then Id.Integer'Image
else VSS.Strings.Conversions.To_UTF_8_String (Id.Virtual_String));
begin
Imprecise := False;

if Name_Node.Is_Null then
-- Internal tracing of resolve on null node
Self.Tracer.Trace ("Can't resolve null node for request " & Id_Image);
return Libadalang.Analysis.No_Defining_Name;
end if;

-- Find the definition
Definition := Laltools.Common.Resolve_Name
(Name_Node, Trace, Result_Kind);

if Result_Kind in Libadalang.Common.Error then
declare
Err_Msg : constant String :=
"Failed to resolve " & Name_Node.Image;
Diag_Params : LSP.Structures.PublishDiagnosticsParams;
Diagnostic : LSP.Structures.Diagnostic;
Loc : constant LSP.Structures.Location :=
Self.To_LSP_Location (Name_Node);
begin
-- Internal tracing of failed resolution with context info
Self.Tracer.Trace
(Err_Msg
& " in context "
& VSS.Strings.Conversions.To_UTF_8_String (Context.Id)
& " for request "
& Id_Image);

-- Send a diagnostic for the user
Diagnostic.a_range := Loc.a_range;
Diagnostic.severity := LSP.Constants.Error;
Diagnostic.source := "Ada";
-- Diagnostics are shown to the user so show a simple
-- representation of Namer_Node
Diagnostic.message :=
VSS.Strings.Conversions.To_Virtual_String
("Failed to resolve "
& Langkit_Support.Text.To_UTF8 (Name_Node.Text)
& Ada.Characters.Latin_1.LF
& "Please check the output of the following command:"
& Ada.Characters.Latin_1.LF
& " lal_nameres -P "
& String
(Self.Project_Tree.Root_Project.Path_Name.Filesystem_String)
& " --all --only-show-failures "
& VSS.Strings.Conversions.To_UTF_8_String (Loc.uri));

Diag_Params.uri := Loc.uri;
Diag_Params.diagnostics.Append (Diagnostic);
Self.Sender.On_PublishDiagnostics_Notification (Diag_Params);

-- Inform the client that the request failed
Self.Sender.On_Error_Response
(Id,
(code => LSP.Enumerations.InternalError,
message => VSS.Strings.Conversions.To_Virtual_String
(Err_Msg)));

return Libadalang.Analysis.No_Defining_Name;
end;

elsif Result_Kind in Libadalang.Common.Imprecise then
-- Internal tracing of imprecise resolving
Self.Tracer.Trace
("Imprecise result when resolving "
& Name_Node.Image
& " in context "
& VSS.Strings.Conversions.To_UTF_8_String (Context.Id)
& " for request "
& Id_Image);
Imprecise := True;
end if;

return Definition;
end Resolve_Name;

-----------------------
-- Set_Configuration --
-----------------------
Expand Down

0 comments on commit 6cb2c1e

Please sign in to comment.