@@ -386,11 +386,12 @@ package body LSP.Lal_Utils is
386386 -- ----------------------
387387
388388 procedure Get_Call_Expr_Name
389- (Node : Libadalang.Analysis.Ada_Node'Class;
390- Cursor : Langkit_Support.Slocs.Source_Location;
391- Active_Position : out LSP.Types.LSP_Number;
392- Designator : out Libadalang.Analysis.Ada_Node;
393- Name_Node : out Libadalang.Analysis.Name)
389+ (Node : Libadalang.Analysis.Ada_Node'Class;
390+ Cursor : Langkit_Support.Slocs.Source_Location;
391+ Active_Position : out LSP.Types.LSP_Number;
392+ Designator : out Libadalang.Analysis.Ada_Node;
393+ Prev_Designators : out Laltools.Common.Node_Vectors.Vector;
394+ Name_Node : out Libadalang.Analysis.Name)
394395 is
395396 use Langkit_Support.Slocs;
396397 Cur_Node : Ada_Node := Node.As_Ada_Node;
@@ -453,6 +454,7 @@ package body LSP.Lal_Utils is
453454 begin
454455 Active_Position := 0 ;
455456 Designator := Libadalang.Analysis.No_Ada_Node;
457+ Prev_Designators := Laltools.Common.Node_Vectors.Empty_Vector;
456458 Name_Node := Libadalang.Analysis.No_Name;
457459
458460 if not Cur_Node.Is_Null
@@ -519,6 +521,9 @@ package body LSP.Lal_Utils is
519521 Designator := Assoc.As_Param_Assoc.F_Designator;
520522 Active_Position := Active_Position + 1 ;
521523 exit when Cursor_In_Node (Assoc.As_Ada_Node);
524+ if Designator /= No_Ada_Node then
525+ Prev_Designators.Append (Designator);
526+ end if ;
522527 end loop ;
523528 end if ;
524529
@@ -570,46 +575,101 @@ package body LSP.Lal_Utils is
570575 -- ------------------------
571576
572577 function Get_Active_Parameter
573- (Node : Libadalang.Analysis.Basic_Decl;
574- Designator : Libadalang.Analysis.Ada_Node;
575- Position : LSP.Types.LSP_Number)
578+ (Node : Libadalang.Analysis.Basic_Decl;
579+ Designator : Libadalang.Analysis.Ada_Node;
580+ Prev_Designators : Laltools.Common.Node_Vectors.Vector;
581+ Position : LSP.Types.LSP_Number)
576582 return LSP.Types.LSP_Number
577583 is
578584 Spec : constant Libadalang.Analysis.Base_Subp_Spec :=
579585 Node.P_Subp_Spec_Or_Null;
580- Index : LSP.Types.LSP_Number := 0 ;
581- begin
582- if Spec = Libadalang.Analysis.No_Base_Subp_Spec then
583- return -1 ;
586+ Res : LSP.Types.LSP_Number := -1 ;
587+
588+ function Find_Designator
589+ (D : Libadalang.Analysis.Ada_Node;
590+ Params : Libadalang.Analysis.Param_Spec_Array)
591+ return LSP.Types.LSP_Number;
592+
593+ function Count_Parameters
594+ (Params : Libadalang.Analysis.Param_Spec_Array)
595+ return LSP.Types.LSP_Number;
584596
585- elsif Designator = Libadalang.Analysis.No_Ada_Node then
586- -- Check if the given position is a valid index for Node
587- for Param of Spec.P_Params loop
597+ -- -------------------
598+ -- Find_Designator --
599+ -- -------------------
600+
601+ function Find_Designator
602+ (D : Libadalang.Analysis.Ada_Node;
603+ Params : Libadalang.Analysis.Param_Spec_Array)
604+ return LSP.Types.LSP_Number
605+ is
606+ Index : LSP.Types.LSP_Number := 0 ;
607+ begin
608+ for Param of Params loop
588609 for Id of Param.F_Ids loop
610+ if Id.Text = D.Text then
611+ return Index;
612+ end if ;
589613 Index := Index + 1 ;
590614 end loop ;
591615 end loop ;
592- if Position > Index - 1 then
593- return -1 ;
594- else
595- return Position;
596- end if ;
597616
598- else
599- -- If we have a designator then try to find the position of a
600- -- parameter with the same name
601- for Param of Spec.P_Params loop
617+ return -1 ;
618+ end Find_Designator ;
619+
620+ -- --------------------
621+ -- Count_Parameters --
622+ -- --------------------
623+
624+ function Count_Parameters
625+ (Params : Libadalang.Analysis.Param_Spec_Array)
626+ return LSP.Types.LSP_Number
627+ is
628+ Index : LSP.Types.LSP_Number := 0 ;
629+ begin
630+ for Param of Params loop
602631 for Id of Param.F_Ids loop
603- if Id.Text = Designator.Text then
604- return Index;
605- end if ;
606632 Index := Index + 1 ;
607633 end loop ;
608634 end loop ;
609635
610- -- No matching designator
636+ return Index;
637+ end Count_Parameters ;
638+
639+ begin
640+ if Spec = Libadalang.Analysis.No_Base_Subp_Spec then
611641 return -1 ;
612642 end if ;
643+
644+ declare
645+ Params : constant Libadalang.Analysis.Param_Spec_Array :=
646+ Spec.P_Params;
647+ begin
648+ if Designator = Libadalang.Analysis.No_Ada_Node then
649+ -- Check if the given position is a valid index for Node
650+
651+ if Position >= Count_Parameters (Params) then
652+ return -1 ;
653+ else
654+ Res := Position;
655+ end if ;
656+
657+ else
658+ -- If we have a designator then try to find the position of a
659+ -- parameter with the same name
660+ Res := Find_Designator (Designator, Params);
661+
662+ end if ;
663+
664+ -- Invalidate the result if it doesn't match the previous designators
665+ for Prev_Designator of Prev_Designators loop
666+ if Find_Designator (Prev_Designator, Params) = -1 then
667+ return -1 ;
668+ end if ;
669+ end loop ;
670+ end ;
671+
672+ return Res;
613673 end Get_Active_Parameter ;
614674
615675 -- ----------------
0 commit comments