-------------------------------------------------------------------------------
-- (C) Altran Praxis Limited
-------------------------------------------------------------------------------
--
-- The SPARK toolset is free software; you can redistribute it and/or modify it
-- under terms of the GNU General Public License as published by the Free
-- Software Foundation; either version 3, or (at your option) any later
-- version. The SPARK toolset is distributed in the hope that it will be
-- useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
-- Public License for more details. You should have received a copy of the GNU
-- General Public License distributed with the SPARK toolset; see file
-- COPYING3. If not, go to http://www.gnu.org/licenses for a complete copy of
-- the license.
--
--=============================================================================

separate (Sem.Walk_Expression_P)
procedure Find_Named_Argument_Association_Parameter
  (Node                   : in     STree.SyntaxNode;
   Subprog_Sym            : in     Dictionary.Symbol;
   Name_Is_Parameter_Name :    out Boolean;
   Param_Sym              :    out Dictionary.Symbol)
is
   Ident_Node : STree.SyntaxNode;
   Ident_Str  : LexTokenManager.Lex_String;
   It         : Dictionary.Iterator;
   Sym        : Dictionary.Symbol;

   function Find_Identifier (Node : STree.SyntaxNode) return STree.SyntaxNode
   --# global in STree.Table;
   --# pre STree.Syntax_Node_Type (Node, STree.Table) = SP_Symbols.named_argument_association or
   --#   STree.Syntax_Node_Type (Node, STree.Table) = SP_Symbols.annotation_named_argument_association;
   --# return Return_Node => STree.Syntax_Node_Type (Return_Node, STree.Table) = SP_Symbols.identifier;
   is
      Ident_Node : STree.SyntaxNode;
   begin
      Ident_Node := STree.Child_Node (Current_Node => Node);
      -- ASSUME Ident_Node = annotation_named_argument_association OR annotation_simple_name OR
      --                     named_argument_association OR simple_name
      if STree.Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.simple_name
        or else STree.Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.annotation_simple_name then
         -- ASSUME Ident_Node = annotation_simple_name OR simple_name
         Ident_Node := STree.Child_Node (Current_Node => Ident_Node);
      elsif STree.Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.named_argument_association
        or else STree.Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.annotation_named_argument_association then
         -- ASSUME Ident_Node = named_argument_association OR annotation_named_argument_association
         Ident_Node := STree.Child_Node (Current_Node => STree.Next_Sibling (Current_Node => Ident_Node));
      else
         SystemErrors.Fatal_Error
           (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Ident_Node = annotation_named_argument_association OR annotation_simple_name OR " &
              "named_argument_association OR simple_name in Find_Identifier");
      end if;
      -- ASSUME Ident_Node = identifier
      SystemErrors.RT_Assert
        (C       => STree.Syntax_Node_Type (Node => Ident_Node) = SP_Symbols.identifier,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Ident_Node = identifier in Find_Identifier");
      return Ident_Node;
   end Find_Identifier;

begin -- Find_Named_Argument_Association_Parameter
   Ident_Node := Find_Identifier (Node => Node);
   Ident_Str  := STree.Node_Lex_String (Node => Ident_Node);

   Name_Is_Parameter_Name := False;
   Param_Sym              := Dictionary.NullSymbol;

   It := Dictionary.FirstSubprogramParameter (Subprog_Sym);
   while not Dictionary.IsNullIterator (It) loop
      --# assert STree.Syntax_Node_Type (Ident_Node, STree.Table) = SP_Symbols.identifier and
      --#   STree.Table = STree.Table~;
      Sym := Dictionary.CurrentSymbol (It);
      if LexTokenManager.Lex_String_Case_Insensitive_Compare (Lex_Str1 => Dictionary.GetSimpleName (Sym),
                                                              Lex_Str2 => Ident_Str) =
        LexTokenManager.Str_Eq then
         Name_Is_Parameter_Name := True;
         Param_Sym              := Sym;
         STree.Set_Node_Lex_String (Sym  => Sym,
                                    Node => Ident_Node);
         exit;
      end if;
      It := Dictionary.NextSymbol (It);
   end loop;
end Find_Named_Argument_Association_Parameter;
