{- |
    Module      :  $Header$
    Description :  SpansInfo for entities
    Copyright   :  (c) 2017 Kai-Oliver Prott
    License     :  BSD-3-clause

    Maintainer  :  fte@informatik.uni-kiel.de
    Stability   :  experimental
    Portability :  portable

    This module implements a data type for span information for entities from a
    source file and function to operate on them. A span info consists of the
    span of the entity and a list of sub-spans whith additional information
    about location of keywords, e.g.
-}
module Curry.Base.SpanInfo
  ( SpanInfo(..), HasSpanInfo(..)
  , fromSrcSpan, fromSrcSpanBoth, getSrcSpan, setSrcSpan, spanInfoLike
  , fromSrcInfoPoints, getSrcInfoPoints, setSrcInfoPoints
  , getStartPosition, getSrcSpanEnd, setStartPosition, setEndPosition
  , spanInfo2Pos
  ) where

import Curry.Base.Position
import Curry.Base.Span

data SpanInfo = SpanInfo
    { SpanInfo -> Span
srcSpan        :: Span
    , SpanInfo -> [Span]
srcInfoPoints  :: [Span]
    }
    | NoSpanInfo
  deriving (SpanInfo -> SpanInfo -> Bool
(SpanInfo -> SpanInfo -> Bool)
-> (SpanInfo -> SpanInfo -> Bool) -> Eq SpanInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SpanInfo -> SpanInfo -> Bool
$c/= :: SpanInfo -> SpanInfo -> Bool
== :: SpanInfo -> SpanInfo -> Bool
$c== :: SpanInfo -> SpanInfo -> Bool
Eq, ReadPrec [SpanInfo]
ReadPrec SpanInfo
Int -> ReadS SpanInfo
ReadS [SpanInfo]
(Int -> ReadS SpanInfo)
-> ReadS [SpanInfo]
-> ReadPrec SpanInfo
-> ReadPrec [SpanInfo]
-> Read SpanInfo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SpanInfo]
$creadListPrec :: ReadPrec [SpanInfo]
readPrec :: ReadPrec SpanInfo
$creadPrec :: ReadPrec SpanInfo
readList :: ReadS [SpanInfo]
$creadList :: ReadS [SpanInfo]
readsPrec :: Int -> ReadS SpanInfo
$creadsPrec :: Int -> ReadS SpanInfo
Read, Int -> SpanInfo -> ShowS
[SpanInfo] -> ShowS
SpanInfo -> String
(Int -> SpanInfo -> ShowS)
-> (SpanInfo -> String) -> ([SpanInfo] -> ShowS) -> Show SpanInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SpanInfo] -> ShowS
$cshowList :: [SpanInfo] -> ShowS
show :: SpanInfo -> String
$cshow :: SpanInfo -> String
showsPrec :: Int -> SpanInfo -> ShowS
$cshowsPrec :: Int -> SpanInfo -> ShowS
Show)

class HasPosition a => HasSpanInfo a where

  getSpanInfo :: a -> SpanInfo

  setSpanInfo :: SpanInfo -> a -> a

  updateEndPos :: a -> a
  updateEndPos = a -> a
forall a. a -> a
id

instance HasSpanInfo SpanInfo where
  getSpanInfo :: SpanInfo -> SpanInfo
getSpanInfo = SpanInfo -> SpanInfo
forall a. a -> a
id
  setSpanInfo :: SpanInfo -> SpanInfo -> SpanInfo
setSpanInfo = SpanInfo -> SpanInfo -> SpanInfo
forall a b. a -> b -> a
const

instance HasPosition SpanInfo where
  getPosition :: SpanInfo -> Position
getPosition = SpanInfo -> Position
forall a. HasSpanInfo a => a -> Position
getStartPosition
  setPosition :: Position -> SpanInfo -> SpanInfo
setPosition = Position -> SpanInfo -> SpanInfo
forall a. HasSpanInfo a => Position -> a -> a
setStartPosition

fromSrcSpan :: Span -> SpanInfo
fromSrcSpan :: Span -> SpanInfo
fromSrcSpan sp :: Span
sp = Span -> [Span] -> SpanInfo
SpanInfo Span
sp []

fromSrcSpanBoth :: Span -> SpanInfo
fromSrcSpanBoth :: Span -> SpanInfo
fromSrcSpanBoth sp :: Span
sp = Span -> [Span] -> SpanInfo
SpanInfo Span
sp [Span
sp]

getSrcSpan :: HasSpanInfo a => a -> Span
getSrcSpan :: a -> Span
getSrcSpan a :: a
a = case a -> SpanInfo
forall a. HasSpanInfo a => a -> SpanInfo
getSpanInfo a
a of
  NoSpanInfo   -> Span
NoSpan
  SpanInfo s :: Span
s _ -> Span
s

setSrcSpan :: HasSpanInfo a => Span -> a -> a
setSrcSpan :: Span -> a -> a
setSrcSpan s :: Span
s a :: a
a = case a -> SpanInfo
forall a. HasSpanInfo a => a -> SpanInfo
getSpanInfo a
a of
  NoSpanInfo     -> SpanInfo -> a -> a
forall a. HasSpanInfo a => SpanInfo -> a -> a
setSpanInfo (Span -> [Span] -> SpanInfo
SpanInfo Span
s [])  a
a
  SpanInfo _ inf :: [Span]
inf -> SpanInfo -> a -> a
forall a. HasSpanInfo a => SpanInfo -> a -> a
setSpanInfo (Span -> [Span] -> SpanInfo
SpanInfo Span
s [Span]
inf) a
a

fromSrcInfoPoints :: [Span] -> SpanInfo
fromSrcInfoPoints :: [Span] -> SpanInfo
fromSrcInfoPoints = Span -> [Span] -> SpanInfo
SpanInfo Span
NoSpan

getSrcInfoPoints :: HasSpanInfo a => a -> [Span]
getSrcInfoPoints :: a -> [Span]
getSrcInfoPoints a :: a
a = case a -> SpanInfo
forall a. HasSpanInfo a => a -> SpanInfo
getSpanInfo a
a of
  NoSpanInfo    -> []
  SpanInfo _ xs :: [Span]
xs -> [Span]
xs

setSrcInfoPoints :: HasSpanInfo a => [Span] -> a -> a
setSrcInfoPoints :: [Span] -> a -> a
setSrcInfoPoints inf :: [Span]
inf a :: a
a = case a -> SpanInfo
forall a. HasSpanInfo a => a -> SpanInfo
getSpanInfo a
a of
  NoSpanInfo   -> SpanInfo -> a -> a
forall a. HasSpanInfo a => SpanInfo -> a -> a
setSpanInfo (Span -> [Span] -> SpanInfo
SpanInfo Span
NoSpan [Span]
inf) a
a
  SpanInfo s :: Span
s _ -> SpanInfo -> a -> a
forall a. HasSpanInfo a => SpanInfo -> a -> a
setSpanInfo (Span -> [Span] -> SpanInfo
SpanInfo Span
s      [Span]
inf) a
a

getStartPosition :: HasSpanInfo a => a -> Position
getStartPosition :: a -> Position
getStartPosition a :: a
a =  case a -> Span
forall a. HasSpanInfo a => a -> Span
getSrcSpan a
a of
  NoSpan     -> Position
NoPos
  Span _ s :: Position
s _ -> Position
s

getSrcSpanEnd :: HasSpanInfo a => a -> Position
getSrcSpanEnd :: a -> Position
getSrcSpanEnd a :: a
a = case a -> SpanInfo
forall a. HasSpanInfo a => a -> SpanInfo
getSpanInfo a
a of
  NoSpanInfo     -> Position
NoPos
  (SpanInfo s :: Span
s _) -> Span -> Position
end Span
s

setStartPosition :: HasSpanInfo a => Position -> a -> a
setStartPosition :: Position -> a -> a
setStartPosition p :: Position
p a :: a
a = case a -> Span
forall a. HasSpanInfo a => a -> Span
getSrcSpan a
a of
  NoSpan       -> Span -> a -> a
forall a. HasSpanInfo a => Span -> a -> a
setSrcSpan (String -> Position -> Position -> Span
Span "" Position
p Position
NoPos) a
a
  (Span f :: String
f _ e :: Position
e) -> Span -> a -> a
forall a. HasSpanInfo a => Span -> a -> a
setSrcSpan (String -> Position -> Position -> Span
Span String
f  Position
p     Position
e) a
a

setEndPosition :: HasSpanInfo a => Position -> a -> a
setEndPosition :: Position -> a -> a
setEndPosition e :: Position
e a :: a
a = case a -> Span
forall a. HasSpanInfo a => a -> Span
getSrcSpan a
a of
  NoSpan       -> Span -> a -> a
forall a. HasSpanInfo a => Span -> a -> a
setSrcSpan (String -> Position -> Position -> Span
Span "" Position
NoPos Position
e) a
a
  (Span f :: String
f p :: Position
p _) -> Span -> a -> a
forall a. HasSpanInfo a => Span -> a -> a
setSrcSpan (String -> Position -> Position -> Span
Span String
f  Position
p     Position
e) a
a

spanInfo2Pos :: HasSpanInfo a => a -> Position
spanInfo2Pos :: a -> Position
spanInfo2Pos = a -> Position
forall a. HasSpanInfo a => a -> Position
getStartPosition

spanInfoLike :: (HasSpanInfo a, HasSpanInfo b) => a -> b -> a
spanInfoLike :: a -> b -> a
spanInfoLike a :: a
a b :: b
b = SpanInfo -> a -> a
forall a. HasSpanInfo a => SpanInfo -> a -> a
setSpanInfo (b -> SpanInfo
forall a. HasSpanInfo a => a -> SpanInfo
getSpanInfo b
b) a
a