-------------------------------------------------------------------------------
-- (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.
--
--=============================================================================

-- Overview:
-- Loops through all visible_part_rep below visible_part (passed in as Node)
-- calls approriate wf for NextDerivative node of each.  Cannot directly
-- raise any errors but called procedures can.
----------------------------------------------------------------------------

separate (Sem.Wf_Package_Declaration.Wf_Package_Specification)
procedure Wf_Visible
  (Node           : in     STree.SyntaxNode;
   Pack_Sym       : in     Dictionary.Symbol;
   Current_Scope  : in     Dictionary.Scopes;
   Component_Data : in out ComponentManager.ComponentData;
   The_Heap       : in out Heap.HeapRecord)
is
   Next_Node, Node_To_Check : STree.SyntaxNode;
   Unused                   : Dictionary.Symbol;

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

   procedure Wf_Private_Type_Declaration
     (Node          : in STree.SyntaxNode;
      Pack_Sym      : in Dictionary.Symbol;
      Current_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,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context from *,
   --#                                         CommandLineData.Content,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table &
   --#         SPARK_IO.File_Sys          from *,
   --#                                         CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.private_type_declaration;
   --# post STree.Table = STree.Table~;
      is separate;

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

   procedure Wf_Deferred
     (Node          : in STree.SyntaxNode;
      Pack_Sym      : in Dictionary.Symbol;
      Current_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,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         STree.Table &
   --#         ErrorHandler.Error_Context,
   --#         SPARK_IO.File_Sys          from CommandLineData.Content,
   --#                                         ContextManager.Ops.Unit_Stack,
   --#                                         Current_Scope,
   --#                                         Dictionary.Dict,
   --#                                         ErrorHandler.Error_Context,
   --#                                         LexTokenManager.State,
   --#                                         Node,
   --#                                         Pack_Sym,
   --#                                         SPARK_IO.File_Sys,
   --#                                         STree.Table;
   --# pre Syntax_Node_Type (Node, STree.Table) = SP_Symbols.deferred_constant_declaration;
   --# post STree.Table = STree.Table~;
      is separate;

begin -- Wf_Visible
   Next_Node := Last_Child_Of (Start_Node => Node);
   while Next_Node /= Node loop
      --# assert STree.Table = STree.Table~;
      -- ASSUME Next_Node = visible_part_rep
      SystemErrors.RT_Assert
        (C       => Syntax_Node_Type (Node => Next_Node) = SP_Symbols.visible_part_rep,
         Sys_Err => SystemErrors.Invalid_Syntax_Tree,
         Msg     => "Expect Next_Node = visible_part_rep in Wf_Visible");
      Node_To_Check := Next_Sibling (Next_Node);
      -- ASSUME Node_To_Check = basic_declarative_item OR private_type_declaration OR
      --                        deferred_constant_declaration OR subprogram_declaration OR
      --                        generic_subprogram_instantiation OR apragma OR renaming_declaration
      case Syntax_Node_Type (Node => Node_To_Check) is
         when SP_Symbols.basic_declarative_item =>
            -- ASSUME Node_To_Check = basic_declarative_item
            Wf_Basic_Declarative_Item
              (Node           => Node_To_Check,
               Current_Scope  => Current_Scope,
               Component_Data => Component_Data,
               The_Heap       => The_Heap);
         when SP_Symbols.subprogram_declaration =>
            -- ASSUME Node_To_Check = subprogram_declaration
            --# accept Flow, 10, Unused, "Expected ineffective assignment";
            Wf_Subprogram_Declaration
              (Node                     => Node_To_Check,
               Inherit_Node             => STree.NullNode,
               Context_Node             => STree.NullNode,
               Generic_Formal_Part_Node => STree.NullNode,
               Current_Scope            => Current_Scope,
               Generic_Unit             => Dictionary.NullSymbol,
               Component_Data           => Component_Data,
               The_Heap                 => The_Heap,
               Subprog_Sym              => Unused);
            --# end accept;
         when SP_Symbols.generic_subprogram_instantiation =>
            -- ASSUME Node_To_Check = generic_subprogram_instantiation
            Wf_Generic_Subprogram_Instantiation
              (Node           => Node_To_Check,
               Scope          => Current_Scope,
               Component_Data => Component_Data,
               The_Heap       => The_Heap);
         when SP_Symbols.apragma =>
            -- ASSUME Node_To_Check = apragma
            Wf_Pragma (Node  => Node_To_Check,
                       Scope => Current_Scope);
         when SP_Symbols.private_type_declaration =>
            -- ASSUME Node_To_Check = private_type_declaration
            Wf_Private_Type_Declaration (Node          => Node_To_Check,
                                         Pack_Sym      => Pack_Sym,
                                         Current_Scope => Current_Scope);
         when SP_Symbols.deferred_constant_declaration =>
            -- ASSUME Node_To_Check = deferred_constant_declaration
            Wf_Deferred (Node          => Node_To_Check,
                         Pack_Sym      => Pack_Sym,
                         Current_Scope => Current_Scope);
         when SP_Symbols.renaming_declaration =>
            -- ASSUME Node_To_Check = renaming_declaration
            Wf_Renaming_Declaration (Node  => Node_To_Check,
                                     Scope => Current_Scope);
         when others =>
            SystemErrors.Fatal_Error
              (Sys_Err => SystemErrors.Invalid_Syntax_Tree,
               Msg     => "Expect Node_To_Check = basic_declarative_item OR private_type_declaration OR " &
                 "deferred_constant_declaration OR subprogram_declaration OR generic_subprogram_instantiation OR " &
                 "apragma OR renaming_declaration in Wf_Visible");
      end case;
      Next_Node := Parent_Node (Current_Node => Next_Node);
   end loop;
   --# accept Flow, 33, Unused, "Expected to be neither referenced nor exported";
end Wf_Visible;
