-- |
-- Module      :  Cryptol.ModuleSystem.Interface
-- Copyright   :  (c) 2013-2016 Galois, Inc.
-- License     :  BSD3
-- Maintainer  :  cryptol@galois.com
-- Stability   :  provisional
-- Portability :  portable

{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RecordWildCards #-}
module Cryptol.ModuleSystem.Interface (
    Iface
  , IfaceG(..)
  , IfaceDecls(..)
  , IfaceTySyn, ifTySynName
  , IfaceNewtype
  , IfaceDecl(..)
  , IfaceParams(..)

  , emptyIface
  , ifacePrimMap
  , noIfaceParams
  , isEmptyIfaceParams
  , ifaceIsFunctor
  , flatPublicIface
  , flatPublicDecls
  , filterIfaceDecls
  , ifaceDeclsNames
  ) where

import           Data.Set(Set)
import qualified Data.Set as Set
import qualified Data.Map as Map
import           Data.Semigroup
import           Data.Text (Text)

import GHC.Generics (Generic)
import Control.DeepSeq

import Prelude ()
import Prelude.Compat

import Cryptol.ModuleSystem.Name
import Cryptol.Utils.Ident (ModName)
import Cryptol.Utils.Panic(panic)
import Cryptol.Utils.Fixity(Fixity)
import Cryptol.Parser.AST(Pragma)
import Cryptol.Parser.Position(Located)
import Cryptol.TypeCheck.Type


-- | The resulting interface generated by a module that has been typechecked.
data IfaceG mname = Iface
  { IfaceG mname -> mname
ifModName   :: !mname       -- ^ Module name
  , IfaceG mname -> IfaceDecls
ifPublic    :: IfaceDecls   -- ^ Exported definitions
  , IfaceG mname -> IfaceDecls
ifPrivate   :: IfaceDecls   -- ^ Private defintiions
  , IfaceG mname -> IfaceParams
ifParams    :: IfaceParams  -- ^ Uninterpreted constants (aka module params)
  } deriving (Int -> IfaceG mname -> ShowS
[IfaceG mname] -> ShowS
IfaceG mname -> String
(Int -> IfaceG mname -> ShowS)
-> (IfaceG mname -> String)
-> ([IfaceG mname] -> ShowS)
-> Show (IfaceG mname)
forall mname. Show mname => Int -> IfaceG mname -> ShowS
forall mname. Show mname => [IfaceG mname] -> ShowS
forall mname. Show mname => IfaceG mname -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IfaceG mname] -> ShowS
$cshowList :: forall mname. Show mname => [IfaceG mname] -> ShowS
show :: IfaceG mname -> String
$cshow :: forall mname. Show mname => IfaceG mname -> String
showsPrec :: Int -> IfaceG mname -> ShowS
$cshowsPrec :: forall mname. Show mname => Int -> IfaceG mname -> ShowS
Show, (forall x. IfaceG mname -> Rep (IfaceG mname) x)
-> (forall x. Rep (IfaceG mname) x -> IfaceG mname)
-> Generic (IfaceG mname)
forall x. Rep (IfaceG mname) x -> IfaceG mname
forall x. IfaceG mname -> Rep (IfaceG mname) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall mname x. Rep (IfaceG mname) x -> IfaceG mname
forall mname x. IfaceG mname -> Rep (IfaceG mname) x
$cto :: forall mname x. Rep (IfaceG mname) x -> IfaceG mname
$cfrom :: forall mname x. IfaceG mname -> Rep (IfaceG mname) x
Generic, IfaceG mname -> ()
(IfaceG mname -> ()) -> NFData (IfaceG mname)
forall mname. NFData mname => IfaceG mname -> ()
forall a. (a -> ()) -> NFData a
rnf :: IfaceG mname -> ()
$crnf :: forall mname. NFData mname => IfaceG mname -> ()
NFData)

ifaceIsFunctor :: IfaceG mname -> Bool
ifaceIsFunctor :: IfaceG mname -> Bool
ifaceIsFunctor = Bool -> Bool
not (Bool -> Bool) -> (IfaceG mname -> Bool) -> IfaceG mname -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IfaceParams -> Bool
isEmptyIfaceParams (IfaceParams -> Bool)
-> (IfaceG mname -> IfaceParams) -> IfaceG mname -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IfaceG mname -> IfaceParams
forall mname. IfaceG mname -> IfaceParams
ifParams

-- | The public declarations in all modules, including nested
-- The modules field contains public functors
-- Assumes that we are not a functor.
flatPublicIface :: IfaceG mname -> IfaceDecls
flatPublicIface :: IfaceG mname -> IfaceDecls
flatPublicIface IfaceG mname
iface = IfaceDecls -> IfaceDecls
flatPublicDecls (IfaceG mname -> IfaceDecls
forall mname. IfaceG mname -> IfaceDecls
ifPublic IfaceG mname
iface)


flatPublicDecls :: IfaceDecls -> IfaceDecls
flatPublicDecls :: IfaceDecls -> IfaceDecls
flatPublicDecls IfaceDecls
ifs = [IfaceDecls] -> IfaceDecls
forall a. Monoid a => [a] -> a
mconcat ( IfaceDecls
ifs { ifModules :: Map Name (IfaceG Name)
ifModules = Map Name (IfaceG Name)
fun }
                              IfaceDecls -> [IfaceDecls] -> [IfaceDecls]
forall a. a -> [a] -> [a]
: (IfaceG Name -> IfaceDecls) -> [IfaceG Name] -> [IfaceDecls]
forall a b. (a -> b) -> [a] -> [b]
map IfaceG Name -> IfaceDecls
forall mname. IfaceG mname -> IfaceDecls
flatPublicIface (Map Name (IfaceG Name) -> [IfaceG Name]
forall k a. Map k a -> [a]
Map.elems Map Name (IfaceG Name)
nofun)
                              )

  where
  (Map Name (IfaceG Name)
fun,Map Name (IfaceG Name)
nofun) = (IfaceG Name -> Bool)
-> Map Name (IfaceG Name)
-> (Map Name (IfaceG Name), Map Name (IfaceG Name))
forall a k. (a -> Bool) -> Map k a -> (Map k a, Map k a)
Map.partition IfaceG Name -> Bool
forall mname. IfaceG mname -> Bool
ifaceIsFunctor (IfaceDecls -> Map Name (IfaceG Name)
ifModules IfaceDecls
ifs)


type Iface = IfaceG ModName

emptyIface :: mname -> IfaceG mname
emptyIface :: mname -> IfaceG mname
emptyIface mname
nm = Iface :: forall mname.
mname -> IfaceDecls -> IfaceDecls -> IfaceParams -> IfaceG mname
Iface
  { ifModName :: mname
ifModName = mname
nm
  , ifPublic :: IfaceDecls
ifPublic  = IfaceDecls
forall a. Monoid a => a
mempty
  , ifPrivate :: IfaceDecls
ifPrivate = IfaceDecls
forall a. Monoid a => a
mempty
  , ifParams :: IfaceParams
ifParams  = IfaceParams
noIfaceParams
  }

data IfaceParams = IfaceParams
  { IfaceParams -> Map Name ModTParam
ifParamTypes       :: Map.Map Name ModTParam
  , IfaceParams -> [Located Prop]
ifParamConstraints :: [Located Prop] -- ^ Constraints on param. types
  , IfaceParams -> Map Name ModVParam
ifParamFuns        :: Map.Map Name ModVParam
  } deriving (Int -> IfaceParams -> ShowS
[IfaceParams] -> ShowS
IfaceParams -> String
(Int -> IfaceParams -> ShowS)
-> (IfaceParams -> String)
-> ([IfaceParams] -> ShowS)
-> Show IfaceParams
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IfaceParams] -> ShowS
$cshowList :: [IfaceParams] -> ShowS
show :: IfaceParams -> String
$cshow :: IfaceParams -> String
showsPrec :: Int -> IfaceParams -> ShowS
$cshowsPrec :: Int -> IfaceParams -> ShowS
Show, (forall x. IfaceParams -> Rep IfaceParams x)
-> (forall x. Rep IfaceParams x -> IfaceParams)
-> Generic IfaceParams
forall x. Rep IfaceParams x -> IfaceParams
forall x. IfaceParams -> Rep IfaceParams x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep IfaceParams x -> IfaceParams
$cfrom :: forall x. IfaceParams -> Rep IfaceParams x
Generic, IfaceParams -> ()
(IfaceParams -> ()) -> NFData IfaceParams
forall a. (a -> ()) -> NFData a
rnf :: IfaceParams -> ()
$crnf :: IfaceParams -> ()
NFData)

noIfaceParams :: IfaceParams
noIfaceParams :: IfaceParams
noIfaceParams = IfaceParams :: Map Name ModTParam
-> [Located Prop] -> Map Name ModVParam -> IfaceParams
IfaceParams
  { ifParamTypes :: Map Name ModTParam
ifParamTypes = Map Name ModTParam
forall k a. Map k a
Map.empty
  , ifParamConstraints :: [Located Prop]
ifParamConstraints = []
  , ifParamFuns :: Map Name ModVParam
ifParamFuns = Map Name ModVParam
forall k a. Map k a
Map.empty
  }

isEmptyIfaceParams :: IfaceParams -> Bool
isEmptyIfaceParams :: IfaceParams -> Bool
isEmptyIfaceParams IfaceParams { [Located Prop]
Map Name ModVParam
Map Name ModTParam
ifParamFuns :: Map Name ModVParam
ifParamConstraints :: [Located Prop]
ifParamTypes :: Map Name ModTParam
ifParamFuns :: IfaceParams -> Map Name ModVParam
ifParamConstraints :: IfaceParams -> [Located Prop]
ifParamTypes :: IfaceParams -> Map Name ModTParam
.. } =
  Map Name ModTParam -> Bool
forall k a. Map k a -> Bool
Map.null Map Name ModTParam
ifParamTypes Bool -> Bool -> Bool
&& [Located Prop] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Located Prop]
ifParamConstraints Bool -> Bool -> Bool
&& Map Name ModVParam -> Bool
forall k a. Map k a -> Bool
Map.null Map Name ModVParam
ifParamFuns

data IfaceDecls = IfaceDecls
  { IfaceDecls -> Map Name IfaceTySyn
ifTySyns        :: Map.Map Name IfaceTySyn
  , IfaceDecls -> Map Name IfaceNewtype
ifNewtypes      :: Map.Map Name IfaceNewtype
  , IfaceDecls -> Map Name IfaceAbstractType
ifAbstractTypes :: Map.Map Name IfaceAbstractType
  , IfaceDecls -> Map Name IfaceDecl
ifDecls         :: Map.Map Name IfaceDecl
  , IfaceDecls -> Map Name (IfaceG Name)
ifModules       :: !(Map.Map Name (IfaceG Name))
  } deriving (Int -> IfaceDecls -> ShowS
[IfaceDecls] -> ShowS
IfaceDecls -> String
(Int -> IfaceDecls -> ShowS)
-> (IfaceDecls -> String)
-> ([IfaceDecls] -> ShowS)
-> Show IfaceDecls
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IfaceDecls] -> ShowS
$cshowList :: [IfaceDecls] -> ShowS
show :: IfaceDecls -> String
$cshow :: IfaceDecls -> String
showsPrec :: Int -> IfaceDecls -> ShowS
$cshowsPrec :: Int -> IfaceDecls -> ShowS
Show, (forall x. IfaceDecls -> Rep IfaceDecls x)
-> (forall x. Rep IfaceDecls x -> IfaceDecls) -> Generic IfaceDecls
forall x. Rep IfaceDecls x -> IfaceDecls
forall x. IfaceDecls -> Rep IfaceDecls x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep IfaceDecls x -> IfaceDecls
$cfrom :: forall x. IfaceDecls -> Rep IfaceDecls x
Generic, IfaceDecls -> ()
(IfaceDecls -> ()) -> NFData IfaceDecls
forall a. (a -> ()) -> NFData a
rnf :: IfaceDecls -> ()
$crnf :: IfaceDecls -> ()
NFData)

filterIfaceDecls :: (Name -> Bool) -> IfaceDecls -> IfaceDecls
filterIfaceDecls :: (Name -> Bool) -> IfaceDecls -> IfaceDecls
filterIfaceDecls Name -> Bool
p IfaceDecls
ifs = IfaceDecls :: Map Name IfaceTySyn
-> Map Name IfaceNewtype
-> Map Name IfaceAbstractType
-> Map Name IfaceDecl
-> Map Name (IfaceG Name)
-> IfaceDecls
IfaceDecls
  { ifTySyns :: Map Name IfaceTySyn
ifTySyns        = Map Name IfaceTySyn -> Map Name IfaceTySyn
forall a. Map Name a -> Map Name a
filterMap (IfaceDecls -> Map Name IfaceTySyn
ifTySyns IfaceDecls
ifs)
  , ifNewtypes :: Map Name IfaceNewtype
ifNewtypes      = Map Name IfaceNewtype -> Map Name IfaceNewtype
forall a. Map Name a -> Map Name a
filterMap (IfaceDecls -> Map Name IfaceNewtype
ifNewtypes IfaceDecls
ifs)
  , ifAbstractTypes :: Map Name IfaceAbstractType
ifAbstractTypes = Map Name IfaceAbstractType -> Map Name IfaceAbstractType
forall a. Map Name a -> Map Name a
filterMap (IfaceDecls -> Map Name IfaceAbstractType
ifAbstractTypes IfaceDecls
ifs)
  , ifDecls :: Map Name IfaceDecl
ifDecls         = Map Name IfaceDecl -> Map Name IfaceDecl
forall a. Map Name a -> Map Name a
filterMap (IfaceDecls -> Map Name IfaceDecl
ifDecls IfaceDecls
ifs)
  , ifModules :: Map Name (IfaceG Name)
ifModules       = Map Name (IfaceG Name) -> Map Name (IfaceG Name)
forall a. Map Name a -> Map Name a
filterMap (IfaceDecls -> Map Name (IfaceG Name)
ifModules IfaceDecls
ifs)
  }
  where
  filterMap :: Map.Map Name a -> Map.Map Name a
  filterMap :: Map Name a -> Map Name a
filterMap = (Name -> a -> Bool) -> Map Name a -> Map Name a
forall k a. (k -> a -> Bool) -> Map k a -> Map k a
Map.filterWithKey (\Name
k a
_ -> Name -> Bool
p Name
k)

ifaceDeclsNames :: IfaceDecls -> Set Name
ifaceDeclsNames :: IfaceDecls -> Set Name
ifaceDeclsNames IfaceDecls
i = [Set Name] -> Set Name
forall (f :: * -> *) a. (Foldable f, Ord a) => f (Set a) -> Set a
Set.unions [ Map Name IfaceTySyn -> Set Name
forall k a. Map k a -> Set k
Map.keysSet (IfaceDecls -> Map Name IfaceTySyn
ifTySyns IfaceDecls
i)
                               , Map Name IfaceNewtype -> Set Name
forall k a. Map k a -> Set k
Map.keysSet (IfaceDecls -> Map Name IfaceNewtype
ifNewtypes IfaceDecls
i)
                               , Map Name IfaceAbstractType -> Set Name
forall k a. Map k a -> Set k
Map.keysSet (IfaceDecls -> Map Name IfaceAbstractType
ifAbstractTypes IfaceDecls
i)
                               , Map Name IfaceDecl -> Set Name
forall k a. Map k a -> Set k
Map.keysSet (IfaceDecls -> Map Name IfaceDecl
ifDecls IfaceDecls
i)
                               , Map Name (IfaceG Name) -> Set Name
forall k a. Map k a -> Set k
Map.keysSet (IfaceDecls -> Map Name (IfaceG Name)
ifModules IfaceDecls
i)
                               ]


instance Semigroup IfaceDecls where
  IfaceDecls
l <> :: IfaceDecls -> IfaceDecls -> IfaceDecls
<> IfaceDecls
r = IfaceDecls :: Map Name IfaceTySyn
-> Map Name IfaceNewtype
-> Map Name IfaceAbstractType
-> Map Name IfaceDecl
-> Map Name (IfaceG Name)
-> IfaceDecls
IfaceDecls
    { ifTySyns :: Map Name IfaceTySyn
ifTySyns   = Map Name IfaceTySyn -> Map Name IfaceTySyn -> Map Name IfaceTySyn
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union (IfaceDecls -> Map Name IfaceTySyn
ifTySyns IfaceDecls
l)   (IfaceDecls -> Map Name IfaceTySyn
ifTySyns IfaceDecls
r)
    , ifNewtypes :: Map Name IfaceNewtype
ifNewtypes = Map Name IfaceNewtype
-> Map Name IfaceNewtype -> Map Name IfaceNewtype
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union (IfaceDecls -> Map Name IfaceNewtype
ifNewtypes IfaceDecls
l) (IfaceDecls -> Map Name IfaceNewtype
ifNewtypes IfaceDecls
r)
    , ifAbstractTypes :: Map Name IfaceAbstractType
ifAbstractTypes = Map Name IfaceAbstractType
-> Map Name IfaceAbstractType -> Map Name IfaceAbstractType
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union (IfaceDecls -> Map Name IfaceAbstractType
ifAbstractTypes IfaceDecls
l) (IfaceDecls -> Map Name IfaceAbstractType
ifAbstractTypes IfaceDecls
r)
    , ifDecls :: Map Name IfaceDecl
ifDecls    = Map Name IfaceDecl -> Map Name IfaceDecl -> Map Name IfaceDecl
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union (IfaceDecls -> Map Name IfaceDecl
ifDecls IfaceDecls
l)    (IfaceDecls -> Map Name IfaceDecl
ifDecls IfaceDecls
r)
    , ifModules :: Map Name (IfaceG Name)
ifModules  = Map Name (IfaceG Name)
-> Map Name (IfaceG Name) -> Map Name (IfaceG Name)
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union (IfaceDecls -> Map Name (IfaceG Name)
ifModules IfaceDecls
l)  (IfaceDecls -> Map Name (IfaceG Name)
ifModules IfaceDecls
r)
    }

instance Monoid IfaceDecls where
  mempty :: IfaceDecls
mempty      = Map Name IfaceTySyn
-> Map Name IfaceNewtype
-> Map Name IfaceAbstractType
-> Map Name IfaceDecl
-> Map Name (IfaceG Name)
-> IfaceDecls
IfaceDecls Map Name IfaceTySyn
forall k a. Map k a
Map.empty Map Name IfaceNewtype
forall k a. Map k a
Map.empty Map Name IfaceAbstractType
forall k a. Map k a
Map.empty Map Name IfaceDecl
forall k a. Map k a
Map.empty Map Name (IfaceG Name)
forall k a. Map k a
Map.empty
  mappend :: IfaceDecls -> IfaceDecls -> IfaceDecls
mappend     = IfaceDecls -> IfaceDecls -> IfaceDecls
forall a. Semigroup a => a -> a -> a
(<>)
  mconcat :: [IfaceDecls] -> IfaceDecls
mconcat [IfaceDecls]
ds  = IfaceDecls :: Map Name IfaceTySyn
-> Map Name IfaceNewtype
-> Map Name IfaceAbstractType
-> Map Name IfaceDecl
-> Map Name (IfaceG Name)
-> IfaceDecls
IfaceDecls
    { ifTySyns :: Map Name IfaceTySyn
ifTySyns   = [Map Name IfaceTySyn] -> Map Name IfaceTySyn
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
Map.unions ((IfaceDecls -> Map Name IfaceTySyn)
-> [IfaceDecls] -> [Map Name IfaceTySyn]
forall a b. (a -> b) -> [a] -> [b]
map IfaceDecls -> Map Name IfaceTySyn
ifTySyns   [IfaceDecls]
ds)
    , ifNewtypes :: Map Name IfaceNewtype
ifNewtypes = [Map Name IfaceNewtype] -> Map Name IfaceNewtype
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
Map.unions ((IfaceDecls -> Map Name IfaceNewtype)
-> [IfaceDecls] -> [Map Name IfaceNewtype]
forall a b. (a -> b) -> [a] -> [b]
map IfaceDecls -> Map Name IfaceNewtype
ifNewtypes [IfaceDecls]
ds)
    , ifAbstractTypes :: Map Name IfaceAbstractType
ifAbstractTypes = [Map Name IfaceAbstractType] -> Map Name IfaceAbstractType
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
Map.unions ((IfaceDecls -> Map Name IfaceAbstractType)
-> [IfaceDecls] -> [Map Name IfaceAbstractType]
forall a b. (a -> b) -> [a] -> [b]
map IfaceDecls -> Map Name IfaceAbstractType
ifAbstractTypes [IfaceDecls]
ds)
    , ifDecls :: Map Name IfaceDecl
ifDecls    = [Map Name IfaceDecl] -> Map Name IfaceDecl
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
Map.unions ((IfaceDecls -> Map Name IfaceDecl)
-> [IfaceDecls] -> [Map Name IfaceDecl]
forall a b. (a -> b) -> [a] -> [b]
map IfaceDecls -> Map Name IfaceDecl
ifDecls    [IfaceDecls]
ds)
    , ifModules :: Map Name (IfaceG Name)
ifModules  = [Map Name (IfaceG Name)] -> Map Name (IfaceG Name)
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
Map.unions ((IfaceDecls -> Map Name (IfaceG Name))
-> [IfaceDecls] -> [Map Name (IfaceG Name)]
forall a b. (a -> b) -> [a] -> [b]
map IfaceDecls -> Map Name (IfaceG Name)
ifModules [IfaceDecls]
ds)
    }

type IfaceTySyn = TySyn

ifTySynName :: TySyn -> Name
ifTySynName :: IfaceTySyn -> Name
ifTySynName = IfaceTySyn -> Name
tsName

type IfaceNewtype = Newtype
type IfaceAbstractType = AbstractType

data IfaceDecl = IfaceDecl
  { IfaceDecl -> Name
ifDeclName    :: !Name          -- ^ Name of thing
  , IfaceDecl -> Schema
ifDeclSig     :: Schema         -- ^ Type
  , IfaceDecl -> [Pragma]
ifDeclPragmas :: [Pragma]       -- ^ Pragmas
  , IfaceDecl -> Bool
ifDeclInfix   :: Bool           -- ^ Is this an infix thing
  , IfaceDecl -> Maybe Fixity
ifDeclFixity  :: Maybe Fixity   -- ^ Fixity information
  , IfaceDecl -> Maybe Text
ifDeclDoc     :: Maybe Text     -- ^ Documentation
  } deriving (Int -> IfaceDecl -> ShowS
[IfaceDecl] -> ShowS
IfaceDecl -> String
(Int -> IfaceDecl -> ShowS)
-> (IfaceDecl -> String)
-> ([IfaceDecl] -> ShowS)
-> Show IfaceDecl
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [IfaceDecl] -> ShowS
$cshowList :: [IfaceDecl] -> ShowS
show :: IfaceDecl -> String
$cshow :: IfaceDecl -> String
showsPrec :: Int -> IfaceDecl -> ShowS
$cshowsPrec :: Int -> IfaceDecl -> ShowS
Show, (forall x. IfaceDecl -> Rep IfaceDecl x)
-> (forall x. Rep IfaceDecl x -> IfaceDecl) -> Generic IfaceDecl
forall x. Rep IfaceDecl x -> IfaceDecl
forall x. IfaceDecl -> Rep IfaceDecl x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep IfaceDecl x -> IfaceDecl
$cfrom :: forall x. IfaceDecl -> Rep IfaceDecl x
Generic, IfaceDecl -> ()
(IfaceDecl -> ()) -> NFData IfaceDecl
forall a. (a -> ()) -> NFData a
rnf :: IfaceDecl -> ()
$crnf :: IfaceDecl -> ()
NFData)


-- | Produce a PrimMap from an interface.
--
-- NOTE: the map will expose /both/ public and private names.
ifacePrimMap :: Iface -> PrimMap
ifacePrimMap :: Iface -> PrimMap
ifacePrimMap Iface { ModName
IfaceDecls
IfaceParams
ifParams :: IfaceParams
ifPrivate :: IfaceDecls
ifPublic :: IfaceDecls
ifModName :: ModName
ifParams :: forall mname. IfaceG mname -> IfaceParams
ifPrivate :: forall mname. IfaceG mname -> IfaceDecls
ifPublic :: forall mname. IfaceG mname -> IfaceDecls
ifModName :: forall mname. IfaceG mname -> mname
.. } =
  PrimMap :: Map PrimIdent Name -> Map PrimIdent Name -> PrimMap
PrimMap { primDecls :: Map PrimIdent Name
primDecls = (PrimMap -> Map PrimIdent Name) -> Map PrimIdent Name
forall k a. Ord k => (PrimMap -> Map k a) -> Map k a
merge PrimMap -> Map PrimIdent Name
primDecls
          , primTypes :: Map PrimIdent Name
primTypes = (PrimMap -> Map PrimIdent Name) -> Map PrimIdent Name
forall k a. Ord k => (PrimMap -> Map k a) -> Map k a
merge PrimMap -> Map PrimIdent Name
primTypes }
  where
  merge :: (PrimMap -> Map k a) -> Map k a
merge PrimMap -> Map k a
f = Map k a -> Map k a -> Map k a
forall k a. Ord k => Map k a -> Map k a -> Map k a
Map.union (PrimMap -> Map k a
f PrimMap
public) (PrimMap -> Map k a
f PrimMap
private)

  public :: PrimMap
public  = IfaceDecls -> PrimMap
ifaceDeclsPrimMap IfaceDecls
ifPublic
  private :: PrimMap
private = IfaceDecls -> PrimMap
ifaceDeclsPrimMap IfaceDecls
ifPrivate

ifaceDeclsPrimMap :: IfaceDecls -> PrimMap
ifaceDeclsPrimMap :: IfaceDecls -> PrimMap
ifaceDeclsPrimMap IfaceDecls { Map Name IfaceAbstractType
Map Name IfaceNewtype
Map Name IfaceTySyn
Map Name IfaceDecl
Map Name (IfaceG Name)
ifModules :: Map Name (IfaceG Name)
ifDecls :: Map Name IfaceDecl
ifAbstractTypes :: Map Name IfaceAbstractType
ifNewtypes :: Map Name IfaceNewtype
ifTySyns :: Map Name IfaceTySyn
ifDecls :: IfaceDecls -> Map Name IfaceDecl
ifAbstractTypes :: IfaceDecls -> Map Name IfaceAbstractType
ifNewtypes :: IfaceDecls -> Map Name IfaceNewtype
ifTySyns :: IfaceDecls -> Map Name IfaceTySyn
ifModules :: IfaceDecls -> Map Name (IfaceG Name)
.. } =
  PrimMap :: Map PrimIdent Name -> Map PrimIdent Name -> PrimMap
PrimMap { primDecls :: Map PrimIdent Name
primDecls = [(PrimIdent, Name)] -> Map PrimIdent Name
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(PrimIdent, Name)]
newtypes [(PrimIdent, Name)] -> [(PrimIdent, Name)] -> [(PrimIdent, Name)]
forall a. [a] -> [a] -> [a]
++ [(PrimIdent, Name)]
exprs)
          , primTypes :: Map PrimIdent Name
primTypes = [(PrimIdent, Name)] -> Map PrimIdent Name
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([(PrimIdent, Name)]
newtypes [(PrimIdent, Name)] -> [(PrimIdent, Name)] -> [(PrimIdent, Name)]
forall a. [a] -> [a] -> [a]
++ [(PrimIdent, Name)]
types)
          }
  where
  entry :: Name -> (PrimIdent, Name)
entry Name
n = case Name -> Maybe PrimIdent
asPrim Name
n of
              Just PrimIdent
pid -> (PrimIdent
pid,Name
n)
              Maybe PrimIdent
Nothing ->
                String -> [String] -> (PrimIdent, Name)
forall a. HasCallStack => String -> [String] -> a
panic String
"ifaceDeclsPrimMap"
                          [ String
"Top level name not declared in a module?"
                          , Name -> String
forall a. Show a => a -> String
show Name
n ]

  exprs :: [(PrimIdent, Name)]
exprs    = (Name -> (PrimIdent, Name)) -> [Name] -> [(PrimIdent, Name)]
forall a b. (a -> b) -> [a] -> [b]
map Name -> (PrimIdent, Name)
entry (Map Name IfaceDecl -> [Name]
forall k a. Map k a -> [k]
Map.keys Map Name IfaceDecl
ifDecls)
  newtypes :: [(PrimIdent, Name)]
newtypes = (Name -> (PrimIdent, Name)) -> [Name] -> [(PrimIdent, Name)]
forall a b. (a -> b) -> [a] -> [b]
map Name -> (PrimIdent, Name)
entry (Map Name IfaceNewtype -> [Name]
forall k a. Map k a -> [k]
Map.keys Map Name IfaceNewtype
ifNewtypes)
  types :: [(PrimIdent, Name)]
types    = (Name -> (PrimIdent, Name)) -> [Name] -> [(PrimIdent, Name)]
forall a b. (a -> b) -> [a] -> [b]
map Name -> (PrimIdent, Name)
entry (Map Name IfaceTySyn -> [Name]
forall k a. Map k a -> [k]
Map.keys Map Name IfaceTySyn
ifTySyns)