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

with Dictionary;
with ExaminerConstants;
with Heap;
with LexTokenManager;
with SeqAlgebra;

use type Dictionary.Symbol;
use type LexTokenManager.Token_Position;

--# inherit Dictionary,
--#         ExaminerConstants,
--#         Heap,
--#         LexTokenManager,
--#         SeqAlgebra,
--#         Statistics,
--#         SystemErrors;

package ComponentErrors is

   MaxNumComponentErrors : constant Natural := ExaminerConstants.MaxRecordErrors;

   subtype ComponentError is Natural range 0 .. MaxNumComponentErrors;

   NullComponentError : constant ComponentError := 0;

   type HeapOfErrors is private;

   type ErrorClass is (
                       DataFlow,
                       IneffectiveStmt,
                       IneffectiveFieldAssignment,
                       Dependency,
                       Usage,
                       SemanticWarning);

   procedure Initialise (TheErrorHeap : out HeapOfErrors);
   --# derives TheErrorHeap from ;

   -- Creates a new component error on TheErrorheap from the given
   -- error class, error value, position and sym.
   procedure CreateError
     (TheErrorHeap : in out HeapOfErrors;
      HeapSeq      : in out Heap.HeapRecord;
      ErrClass     : in     ErrorClass;
      ErrVal       : in     Natural;
      Position     : in     LexTokenManager.Token_Position;
      Sym          : in     Dictionary.Symbol;
      NewError     :    out ComponentError);
   --# global in out Statistics.TableUsage;
   --# derives HeapSeq               from * &
   --#         NewError              from TheErrorHeap &
   --#         Statistics.TableUsage from *,
   --#                                    HeapSeq,
   --#                                    TheErrorHeap &
   --#         TheErrorHeap          from *,
   --#                                    ErrClass,
   --#                                    ErrVal,
   --#                                    HeapSeq,
   --#                                    Position,
   --#                                    Sym;

   -- Disposes of component error on TheErrorHeap.
   procedure DisposeOfError (TheErrorHeap : in out HeapOfErrors;
                             HeapSeq      : in out Heap.HeapRecord;
                             OldError     : in     ComponentError);
   --# derives HeapSeq,
   --#         TheErrorHeap from *,
   --#                           OldError,
   --#                           TheErrorHeap;

   -- Returns true if ErrClass, ErrVal, Position and Sym are the same
   -- in the error descriptors referred to by Error1 and Error2.
   -- Otherwise it returns false.
   function IsSameError
     (TheErrorHeap : HeapOfErrors;
      Error1       : ComponentError;
      Error2       : ComponentError)
     return         Boolean;

   function ClassOfError (TheErrorHeap : HeapOfErrors;
                          Error        : ComponentError) return ErrorClass;

   function ValueOfError (TheErrorHeap : HeapOfErrors;
                          Error        : ComponentError) return Natural;

   function PositionOfError (TheErrorHeap : HeapOfErrors;
                             Error        : ComponentError) return LexTokenManager.Token_Position;

   function SymOfError (TheErrorHeap : HeapOfErrors;
                        Error        : ComponentError) return Dictionary.Symbol;

   function AssociatedComponentNodesOfError (TheErrorHeap : HeapOfErrors;
                                             Error        : ComponentError) return SeqAlgebra.Seq;

   procedure ReportUsage (TheErrorHeap : in HeapOfErrors);
   --# global in out Statistics.TableUsage;
   --# derives Statistics.TableUsage from *,
   --#                                    TheErrorHeap;

private
   type ErrorDescriptor is record
      ErrClass                 : ErrorClass;
      ErrVal                   : Natural;
      Position                 : LexTokenManager.Token_Position;
      Sym                      : Dictionary.Symbol;
      AssociatedComponentNodes : SeqAlgebra.Seq;
      NextError                : ComponentError;
   end record;

   subtype ComponentIndex is Natural range 1 .. MaxNumComponentErrors;

   type ArrayOfErrorDescriptors is array (ComponentIndex) of ErrorDescriptor;

   type HeapOfErrors is record
      ListOfComponentErrors       : ArrayOfErrorDescriptors;
      HighMark, NextFreeComponent : ComponentError;
   end record;

end ComponentErrors;
