{- |
Module      :  Camfort.Specification.Units.Annotation
Description :  Annotation with unit information.
Copyright   :  (c) 2017, Dominic Orchard, Andrew Rice, Mistral Contrastin, Matthew Danish
License     :  Apache-2.0

Maintainer  :  dom.orchard@gmail.com
Stability   :  experimental

Defines the 'UnitAnnotation' datatype, which is used for annotating a
'ProgramFile' with units information.
-}

{-# LANGUAGE DeriveDataTypeable    #-}
{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}

module Camfort.Specification.Units.Annotation
  (
    -- * Annotation Type
    UA
  , mkUnitAnnotation
  , prevAnnotation
  , unitBlock
  , unitConstraint
  , unitInfo
  , unitPU
  , unitSpec
    -- * Helpers
  , cleanLinks
  , getConstraint
  , getUnitInfo
  , maybeSetUnitConstraintF2
  , maybeSetUnitInfo
  , maybeSetUnitInfoF2
  , setConstraint
  , setUnitInfo
  ) where

import Data.Data (Data, Typeable)
import Data.Generics.Uniplate.Operations (transformBi)

import qualified Language.Fortran.Analysis as FA
import qualified Language.Fortran.AST      as F

import qualified Camfort.Analysis.Annotations             as Ann
import           Camfort.Analysis.CommentAnnotator
  (ASTEmbeddable(..), Linkable(..))
import qualified Camfort.Specification.Units.Environment  as E
import qualified Camfort.Specification.Units.Parser.Types as P

-- The annotation on the AST used for solving units.
data UnitAnnotation a = UnitAnnotation {
    forall a. UnitAnnotation a -> a
prevAnnotation :: a,
    forall a. UnitAnnotation a -> Maybe UnitStatement
unitSpec       :: Maybe P.UnitStatement,
    forall a. UnitAnnotation a -> Maybe Constraint
unitConstraint :: Maybe E.Constraint,
    forall a. UnitAnnotation a -> Maybe UnitInfo
unitInfo       :: Maybe E.UnitInfo,
    forall a.
UnitAnnotation a -> Maybe (Block (Analysis (UnitAnnotation a)))
unitBlock      :: Maybe (F.Block (FA.Analysis (UnitAnnotation a))), -- ^ linked variable declaration
    forall a.
UnitAnnotation a
-> Maybe (ProgramUnit (Analysis (UnitAnnotation a)))
unitPU         :: Maybe (F.ProgramUnit (FA.Analysis (UnitAnnotation a))) -- ^ linked program unit
  } deriving (Typeable (UnitAnnotation a)
Typeable (UnitAnnotation a)
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g)
    -> UnitAnnotation a
    -> c (UnitAnnotation a))
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c (UnitAnnotation a))
-> (UnitAnnotation a -> Constr)
-> (UnitAnnotation a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c (UnitAnnotation a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c (UnitAnnotation a)))
-> ((forall b. Data b => b -> b)
    -> UnitAnnotation a -> UnitAnnotation a)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r)
-> (forall u.
    (forall d. Data d => d -> u) -> UnitAnnotation a -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> UnitAnnotation a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d)
    -> UnitAnnotation a -> m (UnitAnnotation a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> UnitAnnotation a -> m (UnitAnnotation a))
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d)
    -> UnitAnnotation a -> m (UnitAnnotation a))
-> Data (UnitAnnotation a)
UnitAnnotation a -> Constr
UnitAnnotation a -> DataType
(forall b. Data b => b -> b)
-> UnitAnnotation a -> UnitAnnotation a
forall {a}. Data a => Typeable (UnitAnnotation a)
forall a. Data a => UnitAnnotation a -> Constr
forall a. Data a => UnitAnnotation a -> DataType
forall a.
Data a =>
(forall b. Data b => b -> b)
-> UnitAnnotation a -> UnitAnnotation a
forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> UnitAnnotation a -> u
forall a u.
Data a =>
(forall d. Data d => d -> u) -> UnitAnnotation a -> [u]
forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (UnitAnnotation a)
forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitAnnotation a -> c (UnitAnnotation a)
forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (UnitAnnotation a))
forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (UnitAnnotation a))
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u.
Int -> (forall d. Data d => d -> u) -> UnitAnnotation a -> u
forall u. (forall d. Data d => d -> u) -> UnitAnnotation a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (UnitAnnotation a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitAnnotation a -> c (UnitAnnotation a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (UnitAnnotation a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (UnitAnnotation a))
$cgfoldl :: forall a (c :: * -> *).
Data a =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitAnnotation a -> c (UnitAnnotation a)
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> UnitAnnotation a -> c (UnitAnnotation a)
$cgunfold :: forall a (c :: * -> *).
Data a =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (UnitAnnotation a)
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (UnitAnnotation a)
$ctoConstr :: forall a. Data a => UnitAnnotation a -> Constr
toConstr :: UnitAnnotation a -> Constr
$cdataTypeOf :: forall a. Data a => UnitAnnotation a -> DataType
dataTypeOf :: UnitAnnotation a -> DataType
$cdataCast1 :: forall a (t :: * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (UnitAnnotation a))
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (UnitAnnotation a))
$cdataCast2 :: forall a (t :: * -> * -> *) (c :: * -> *).
(Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (UnitAnnotation a))
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (UnitAnnotation a))
$cgmapT :: forall a.
Data a =>
(forall b. Data b => b -> b)
-> UnitAnnotation a -> UnitAnnotation a
gmapT :: (forall b. Data b => b -> b)
-> UnitAnnotation a -> UnitAnnotation a
$cgmapQl :: forall a r r'.
Data a =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
$cgmapQr :: forall a r r'.
Data a =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> UnitAnnotation a -> r
$cgmapQ :: forall a u.
Data a =>
(forall d. Data d => d -> u) -> UnitAnnotation a -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> UnitAnnotation a -> [u]
$cgmapQi :: forall a u.
Data a =>
Int -> (forall d. Data d => d -> u) -> UnitAnnotation a -> u
gmapQi :: forall u.
Int -> (forall d. Data d => d -> u) -> UnitAnnotation a -> u
$cgmapM :: forall a (m :: * -> *).
(Data a, Monad m) =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
$cgmapMp :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
$cgmapMo :: forall a (m :: * -> *).
(Data a, MonadPlus m) =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d)
-> UnitAnnotation a -> m (UnitAnnotation a)
Data, Typeable, Int -> UnitAnnotation a -> ShowS
[UnitAnnotation a] -> ShowS
UnitAnnotation a -> String
(Int -> UnitAnnotation a -> ShowS)
-> (UnitAnnotation a -> String)
-> ([UnitAnnotation a] -> ShowS)
-> Show (UnitAnnotation a)
forall a. Show a => Int -> UnitAnnotation a -> ShowS
forall a. Show a => [UnitAnnotation a] -> ShowS
forall a. Show a => UnitAnnotation a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> UnitAnnotation a -> ShowS
showsPrec :: Int -> UnitAnnotation a -> ShowS
$cshow :: forall a. Show a => UnitAnnotation a -> String
show :: UnitAnnotation a -> String
$cshowList :: forall a. Show a => [UnitAnnotation a] -> ShowS
showList :: [UnitAnnotation a] -> ShowS
Show)

mkUnitAnnotation :: a -> UnitAnnotation a
mkUnitAnnotation :: forall a. a -> UnitAnnotation a
mkUnitAnnotation a
a = a
-> Maybe UnitStatement
-> Maybe Constraint
-> Maybe UnitInfo
-> Maybe (Block (Analysis (UnitAnnotation a)))
-> Maybe (ProgramUnit (Analysis (UnitAnnotation a)))
-> UnitAnnotation a
forall a.
a
-> Maybe UnitStatement
-> Maybe Constraint
-> Maybe UnitInfo
-> Maybe (Block (Analysis (UnitAnnotation a)))
-> Maybe (ProgramUnit (Analysis (UnitAnnotation a)))
-> UnitAnnotation a
UnitAnnotation a
a Maybe UnitStatement
forall a. Maybe a
Nothing Maybe Constraint
forall a. Maybe a
Nothing Maybe UnitInfo
forall a. Maybe a
Nothing Maybe (Block (Analysis (UnitAnnotation a)))
forall a. Maybe a
Nothing Maybe (ProgramUnit (Analysis (UnitAnnotation a)))
forall a. Maybe a
Nothing

-- Convenience name for a common annotation type.
type UA = FA.Analysis (UnitAnnotation Ann.A)

-- Instances for embedding parsed specifications into the AST
instance ASTEmbeddable UA P.UnitStatement where
  annotateWithAST :: UA -> UnitStatement -> UA
annotateWithAST UA
ann UnitStatement
ast =
    (UnitAnnotation A -> UnitAnnotation A) -> UA -> UA
forall a. (a -> a) -> Analysis a -> Analysis a
Ann.onPrev (\UnitAnnotation A
ann' -> UnitAnnotation A
ann' { unitSpec :: Maybe UnitStatement
unitSpec = UnitStatement -> Maybe UnitStatement
forall a. a -> Maybe a
Just UnitStatement
ast }) UA
ann

-- Link annotation comments to declaration statements
instance Linkable UA where
  link :: UA -> Block UA -> UA
link UA
ann (b :: Block UA
b@(F.BlStatement UA
_ SrcSpan
_ Maybe (Expression UA)
_ F.StDeclaration {})) =
      (UnitAnnotation A -> UnitAnnotation A) -> UA -> UA
forall a. (a -> a) -> Analysis a -> Analysis a
Ann.onPrev (\UnitAnnotation A
ann' -> UnitAnnotation A
ann' { unitBlock :: Maybe (Block UA)
unitBlock = Block UA -> Maybe (Block UA)
forall a. a -> Maybe a
Just Block UA
b }) UA
ann
  link UA
ann Block UA
_ = UA
ann
  linkPU :: UA -> ProgramUnit UA -> UA
linkPU UA
ann pu :: ProgramUnit UA
pu@F.PUFunction{} =
      (UnitAnnotation A -> UnitAnnotation A) -> UA -> UA
forall a. (a -> a) -> Analysis a -> Analysis a
Ann.onPrev (\UnitAnnotation A
ann' -> UnitAnnotation A
ann' { unitPU :: Maybe (ProgramUnit UA)
unitPU = ProgramUnit UA -> Maybe (ProgramUnit UA)
forall a. a -> Maybe a
Just ProgramUnit UA
pu }) UA
ann
  linkPU UA
ann pu :: ProgramUnit UA
pu@F.PUSubroutine{} =
      (UnitAnnotation A -> UnitAnnotation A) -> UA -> UA
forall a. (a -> a) -> Analysis a -> Analysis a
Ann.onPrev (\UnitAnnotation A
ann' -> UnitAnnotation A
ann' { unitPU :: Maybe (ProgramUnit UA)
unitPU = ProgramUnit UA -> Maybe (ProgramUnit UA)
forall a. a -> Maybe a
Just ProgramUnit UA
pu }) UA
ann
  linkPU UA
ann ProgramUnit UA
_ = UA
ann

-- | Extract the unit info from a given annotated piece of AST.
getUnitInfo :: F.Annotated f => f UA -> Maybe E.UnitInfo
getUnitInfo :: forall (f :: * -> *). Annotated f => f UA -> Maybe UnitInfo
getUnitInfo = UnitAnnotation A -> Maybe UnitInfo
forall a. UnitAnnotation a -> Maybe UnitInfo
unitInfo (UnitAnnotation A -> Maybe UnitInfo)
-> (f UA -> UnitAnnotation A) -> f UA -> Maybe UnitInfo
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UA -> UnitAnnotation A
forall a. Analysis a -> a
FA.prevAnnotation (UA -> UnitAnnotation A)
-> (f UA -> UA) -> f UA -> UnitAnnotation A
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f UA -> UA
forall a. f a -> a
forall (f :: * -> *) a. Annotated f => f a -> a
F.getAnnotation

-- | Extract the constraint from a given annotated piece of AST.
getConstraint :: F.Annotated f => f UA -> Maybe E.Constraint
getConstraint :: forall (f :: * -> *). Annotated f => f UA -> Maybe Constraint
getConstraint = UnitAnnotation A -> Maybe Constraint
forall a. UnitAnnotation a -> Maybe Constraint
unitConstraint (UnitAnnotation A -> Maybe Constraint)
-> (f UA -> UnitAnnotation A) -> f UA -> Maybe Constraint
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UA -> UnitAnnotation A
forall a. Analysis a -> a
FA.prevAnnotation (UA -> UnitAnnotation A)
-> (f UA -> UA) -> f UA -> UnitAnnotation A
forall b c a. (b -> c) -> (a -> b) -> a -> c
. f UA -> UA
forall a. f a -> a
forall (f :: * -> *) a. Annotated f => f a -> a
F.getAnnotation

-- | Set the UnitInfo field on a piece of AST.
setUnitInfo :: F.Annotated f => E.UnitInfo -> f UA -> f UA
setUnitInfo :: forall (f :: * -> *). Annotated f => UnitInfo -> f UA -> f UA
setUnitInfo UnitInfo
info = (UA -> UA) -> f UA -> f UA
forall a. (a -> a) -> f a -> f a
forall (f :: * -> *) a. Annotated f => (a -> a) -> f a -> f a
F.modifyAnnotation ((UnitAnnotation A -> UnitAnnotation A) -> UA -> UA
forall a. (a -> a) -> Analysis a -> Analysis a
Ann.onPrev (\ UnitAnnotation A
ua -> UnitAnnotation A
ua { unitInfo :: Maybe UnitInfo
unitInfo = UnitInfo -> Maybe UnitInfo
forall a. a -> Maybe a
Just UnitInfo
info }))

-- | Set the Constraint field on a piece of AST.
setConstraint :: F.Annotated f => E.Constraint -> f UA -> f UA
setConstraint :: forall (f :: * -> *). Annotated f => Constraint -> f UA -> f UA
setConstraint (E.ConConj []) = f UA -> f UA
forall a. a -> a
id
setConstraint Constraint
c              =
  (UA -> UA) -> f UA -> f UA
forall a. (a -> a) -> f a -> f a
forall (f :: * -> *) a. Annotated f => (a -> a) -> f a -> f a
F.modifyAnnotation ((UnitAnnotation A -> UnitAnnotation A) -> UA -> UA
forall a. (a -> a) -> Analysis a -> Analysis a
Ann.onPrev (\ UnitAnnotation A
ua -> UnitAnnotation A
ua { unitConstraint :: Maybe Constraint
unitConstraint = Constraint -> Maybe Constraint
forall a. a -> Maybe a
Just Constraint
c }))

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

-- Various helper functions for setting the UnitInfo or Constraint of a piece of AST
maybeSetUnitInfo :: F.Annotated f => Maybe E.UnitInfo -> f UA -> f UA
maybeSetUnitInfo :: forall (f :: * -> *). Annotated f => Maybe UnitInfo -> f UA -> f UA
maybeSetUnitInfo Maybe UnitInfo
u f UA
e  = f UA -> (UnitInfo -> f UA) -> Maybe UnitInfo -> f UA
forall b a. b -> (a -> b) -> Maybe a -> b
maybe f UA
e (UnitInfo -> f UA -> f UA
forall (f :: * -> *). Annotated f => UnitInfo -> f UA -> f UA
`setUnitInfo` f UA
e) Maybe UnitInfo
u

maybeSetUnitInfoF2 :: F.Annotated f => (a -> b -> E.UnitInfo) -> Maybe a -> Maybe b -> f UA -> f UA
maybeSetUnitInfoF2 :: forall (f :: * -> *) a b.
Annotated f =>
(a -> b -> UnitInfo) -> Maybe a -> Maybe b -> f UA -> f UA
maybeSetUnitInfoF2 a -> b -> UnitInfo
f Maybe a
u1 Maybe b
u2 f UA
e = f UA -> (UnitInfo -> f UA) -> Maybe UnitInfo -> f UA
forall b a. b -> (a -> b) -> Maybe a -> b
maybe f UA
e (UnitInfo -> f UA -> f UA
forall (f :: * -> *). Annotated f => UnitInfo -> f UA -> f UA
`setUnitInfo` f UA
e) (a -> b -> UnitInfo
f (a -> b -> UnitInfo) -> Maybe a -> Maybe (b -> UnitInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe a
u1 Maybe (b -> UnitInfo) -> Maybe b -> Maybe UnitInfo
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe b
u2)

maybeSetUnitConstraintF2 :: F.Annotated f => (a -> b -> E.Constraint) -> Maybe a -> Maybe b -> f UA -> f UA
maybeSetUnitConstraintF2 :: forall (f :: * -> *) a b.
Annotated f =>
(a -> b -> Constraint) -> Maybe a -> Maybe b -> f UA -> f UA
maybeSetUnitConstraintF2 a -> b -> Constraint
f Maybe a
u1 Maybe b
u2 f UA
e = f UA -> (Constraint -> f UA) -> Maybe Constraint -> f UA
forall b a. b -> (a -> b) -> Maybe a -> b
maybe f UA
e (Constraint -> f UA -> f UA
forall (f :: * -> *). Annotated f => Constraint -> f UA -> f UA
`setConstraint` f UA
e) (a -> b -> Constraint
f (a -> b -> Constraint) -> Maybe a -> Maybe (b -> Constraint)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe a
u1 Maybe (b -> Constraint) -> Maybe b -> Maybe Constraint
forall a b. Maybe (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe b
u2)

cleanLinks :: F.ProgramFile UA -> F.ProgramFile UA
cleanLinks :: ProgramFile UA -> ProgramFile UA
cleanLinks = (UnitAnnotation A -> UnitAnnotation A)
-> ProgramFile UA -> ProgramFile UA
forall from to. Biplate from to => (to -> to) -> from -> from
transformBi
  (\UnitAnnotation A
a -> UnitAnnotation A
a { unitPU :: Maybe (ProgramUnit UA)
unitPU    = Maybe (ProgramUnit UA)
forall a. Maybe a
Nothing
           , unitBlock :: Maybe (Block UA)
unitBlock = Maybe (Block UA)
forall a. Maybe a
Nothing
           , unitSpec :: Maybe UnitStatement
unitSpec  = Maybe UnitStatement
forall a. Maybe a
Nothing
           } :: UnitAnnotation Ann.A)