-------------------------------------------------------------------------------
-- (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)
procedure Wf_Context_Clause_Package_Body
  (Node              : in     STree.SyntaxNode;
   Comp_Sym          : in     Dictionary.Symbol;
   Scope             : in     Dictionary.Scopes;
   With_Public_Child :    out Boolean)
is
   Next_Node            : STree.SyntaxNode;
   Has_Own_Public_Child : Boolean;

   -----------------------------

   procedure With_Clause
     (Node              : in     STree.SyntaxNode;
      Comp_Sym          : in     Dictionary.Symbol;
      Scope             : in     Dictionary.Scopes;
      With_Public_Child :    out Boolean)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     LexTokenManager.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out STree.Table;
   --# derives Dictionary.Dict,
   --#         STree.Table,
   --#         With_Public_Child          from CommandLineData.Content,
   --#                                         Comp_Sym,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Comp_Sym,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.with_clause;
   --# post STree.Table = STree.Table~;
      is separate;

   procedure Use_Clause (Node     : in STree.SyntaxNode;
                         Comp_Sym : in Dictionary.Symbol;
                         Scope    : in Dictionary.Scopes)
   --# global in     CommandLineData.Content;
   --#        in     ContextManager.Ops.Unit_Stack;
   --#        in     LexTokenManager.State;
   --#        in out Dictionary.Dict;
   --#        in out ErrorHandler.Error_Context;
   --#        in out SPARK_IO.File_Sys;
   --#        in out STree.Table;
   --# derives Dictionary.Dict,
   --#         STree.Table                from CommandLineData.Content,
   --#                                         Comp_Sym,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         Comp_Sym,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Scope,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.use_type_clause;
   --# post STree.Table = STree.Table~;
      is separate;

begin -- Wf_Context_Clause
   Next_Node := Child_Node (Current_Node => Node);
   -- ASSUME Next_Node = with_clause
   SystemErrors.RT_Assert
     (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.with_clause,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Next_Node = with_clause in Wf_Context_Clause");

   With_Clause (Node              => Next_Node,
                Comp_Sym          => Comp_Sym,
                Scope             => Scope,
                With_Public_Child => With_Public_Child);

   Next_Node := Next_Sibling (Current_Node => Next_Node);
   -- ASSUME Next_Node = context_clause_rep
   SystemErrors.RT_Assert
     (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.context_clause_rep,
      Sys_Err => SystemErrors.Invalid_Syntax_Tree,
      Msg     => "Expect Next_Node = context_clause_rep in Wf_Context_Clause");
   if Syntax_Node_Type (Node => Child_Node (Current_Node => Next_Node)) = SP_Symbols.context_clause_rep then
      -- ASSUME Child_Node (Current_Node => Next_Node) = context_clause_rep
      -- there is one or more further with clause or usetype clause to process
      Next_Node := Next_Sibling (Current_Node => Last_Child_Of (Start_Node => Next_Node));
      loop
         --# assert STree.Table = STree.Table~;
         -- ASSUME Next_Node = with_clause OR use_type_clause OR pragma_rep
         SystemErrors.RT_Assert
           (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.with_clause
              or else Syntax_Node_Type (Node => Next_Node) = SP_Symbols.use_type_clause
              or else Syntax_Node_Type (Node => Next_Node) = SP_Symbols.pragma_rep,
            Sys_Err => SystemErrors.Invalid_Syntax_Tree,
            Msg     => "Expect Next_Node = with_clause OR use_type_clause OR pragma_rep in Wf_Context_Clause");
         exit when Syntax_Node_Type (Node => Next_Node) = SP_Symbols.pragma_rep;
         -- ASSUME Next_Node = with_clause OR use_type_clause
         if Syntax_Node_Type (Node => Next_Node) = SP_Symbols.with_clause then
            -- ASSUME Next_Node = with_clause
            With_Clause (Node              => Next_Node,
                         Comp_Sym          => Comp_Sym,
                         Scope             => Scope,
                         With_Public_Child => Has_Own_Public_Child);
            With_Public_Child := With_Public_Child or else Has_Own_Public_Child;
         elsif Syntax_Node_Type (Node => Next_Node) = SP_Symbols.use_type_clause then
            -- ASSUME Next_Node = use_type_clause
            Use_Clause (Node     => Next_Node,
                        Comp_Sym => Comp_Sym,
                        Scope    => Scope);
         else
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Next_Node = with_clause OR use_type_clause in Wf_Context_Clause");
         end if;
         Next_Node := Next_Sibling (Current_Node => Parent_Node (Current_Node => Next_Node));
      end loop;
   elsif Child_Node (Current_Node => Next_Node) /= STree.NullNode then
      SystemErrors.Fatal_Error
        (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Child_Node (Current_Node => Next_Node) = context_clause_rep OR NULL in Wf_Context_Clause");
   end if;
end Wf_Context_Clause_Package_Body;
