{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
module Distribution.Types.ModuleRenaming (
ModuleRenaming(..),
interpModuleRenaming,
defaultRenaming,
isDefaultRenaming,
) where
import Distribution.Compat.Prelude hiding (empty)
import Prelude ()
import Distribution.ModuleName
import Distribution.Parsec.Class
import Distribution.Pretty
import Distribution.Text
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Distribution.Compat.CharParsing as P
import Distribution.Compat.ReadP ((<++))
import qualified Distribution.Compat.ReadP as Parse
import Text.PrettyPrint (hsep, parens, punctuate, text, (<+>), comma)
data ModuleRenaming
= ModuleRenaming [(ModuleName, ModuleName)]
| DefaultRenaming
| HidingRenaming [ModuleName]
deriving (Show, Read, Eq, Ord, Typeable, Data, Generic)
interpModuleRenaming :: ModuleRenaming -> ModuleName -> Maybe ModuleName
interpModuleRenaming DefaultRenaming = Just
interpModuleRenaming (ModuleRenaming rns) =
let m = Map.fromList rns
in \k -> Map.lookup k m
interpModuleRenaming (HidingRenaming hs) =
let s = Set.fromList hs
in \k -> if k `Set.member` s then Nothing else Just k
defaultRenaming :: ModuleRenaming
defaultRenaming = DefaultRenaming
isDefaultRenaming :: ModuleRenaming -> Bool
isDefaultRenaming DefaultRenaming = True
isDefaultRenaming _ = False
instance Binary ModuleRenaming where
instance NFData ModuleRenaming where rnf = genericRnf
instance Pretty ModuleRenaming where
pretty DefaultRenaming = mempty
pretty (HidingRenaming hides)
= text "hiding" <+> parens (hsep (punctuate comma (map pretty hides)))
pretty (ModuleRenaming rns)
= parens . hsep $ punctuate comma (map dispEntry rns)
where dispEntry (orig, new)
| orig == new = pretty orig
| otherwise = pretty orig <+> text "as" <+> pretty new
instance Parsec ModuleRenaming where
parsec = P.choice [ parseRename, parseHiding, return DefaultRenaming ]
where
parseRename = do
rns <- P.between (P.char '(') (P.char ')') parseList
P.spaces
return (ModuleRenaming rns)
parseHiding = do
_ <- P.string "hiding"
P.spaces
hides <- P.between (P.char '(') (P.char ')')
(P.sepBy parsec (P.char ',' >> P.spaces))
return (HidingRenaming hides)
parseList =
P.sepBy parseEntry (P.char ',' >> P.spaces)
parseEntry = do
orig <- parsec
P.spaces
P.option (orig, orig) $ do
_ <- P.string "as"
P.spaces
new <- parsec
P.spaces
return (orig, new)
instance Text ModuleRenaming where
parse = do fmap ModuleRenaming parseRns
<++ parseHidingRenaming
<++ return DefaultRenaming
where parseRns = do
rns <- Parse.between (Parse.char '(') (Parse.char ')') parseList
Parse.skipSpaces
return rns
parseHidingRenaming = do
_ <- Parse.string "hiding"
Parse.skipSpaces
hides <- Parse.between (Parse.char '(') (Parse.char ')')
(Parse.sepBy parse (Parse.char ',' >> Parse.skipSpaces))
return (HidingRenaming hides)
parseList =
Parse.sepBy parseEntry (Parse.char ',' >> Parse.skipSpaces)
parseEntry :: Parse.ReadP r (ModuleName, ModuleName)
parseEntry = do
orig <- parse
Parse.skipSpaces
(do _ <- Parse.string "as"
Parse.skipSpaces
new <- parse
Parse.skipSpaces
return (orig, new)
<++
return (orig, orig))