{-# LANGUAGE AllowAmbiguousTypes #-} -- For hideableShow -- | This module enables to 'hideName' -- to get reproductible dumps of TemplateHaskell slices. module Language.Haskell.TH.HideName where import Data.Bifunctor (bimap) import Data.Maybe (Maybe (..)) import Data.Bool (Bool(..)) import Data.Function (id) import Data.Functor ((<$>)) import Language.Haskell.TH import Language.Haskell.TH.Syntax import Prelude (undefined) -- ** Type 'HideableName' -- | Useful on golden unit tests because 'Name's -- change often when changing unrelated source code -- or even when changing basic GHC or executable flags. class HideableName (showNames::Bool) where hideableName :: HideName a => a -> a -- | Like 'id'. instance HideableName 'True where hideableName = id -- | Like 'hideName'. instance HideableName 'False where hideableName = hideName -- * Class 'HideName' class HideName a where -- | Map all 'Name's to a constant in order to overcome -- cases where resetting 'TH.counter' is not enough -- to get deterministic 'TH.Name's. hideName :: a -> a instance HideName a => HideName (Maybe a) where hideName = (hideName <$>) instance (HideName a, HideName b) => HideName (a,b) where hideName = bimap hideName hideName instance HideName Body where hideName (GuardedB gs) = GuardedB ((\(g, e) -> (hideName g, hideName e)) <$> gs) hideName (NormalB e) = NormalB (hideName e) instance HideName Clause where hideName (Clause ps b ds) = Clause (hideName <$> ps) (hideName b) (hideName <$> ds) instance HideName Dec where hideName (FunD f cs) = FunD (hideName f) (hideName <$> cs) hideName (ValD p r ds) = ValD (hideName p) (hideName r) (hideName <$> ds) -- FIXME: completing is not likely useful since Symantic.Parser is only using __Typed__ Template Haskell --hideName (DataD cxt n bs mk cs dcs) = DataD (hideName cxt) (hideName n) (hideName bs) (hideName mk) (hideName cs) (hideName dcs) hideName _ = undefined -- | NewtypeD Cxt Name [TyVarBndr ()] -- (Maybe Kind) -- Kind signature -- Con [DerivClause] -- ^ @{ newtype Cxt x => T x = A (B x) -- -- deriving (Z,W Q) -- -- deriving stock Eq }@ -- | TypeDataD Name [TyVarBndr ()] -- (Maybe Kind) -- Kind signature (allowed only for GADTs) -- [Con] -- ^ @{ type data T x = A x | B (T x) }@ -- | TySynD Name [TyVarBndr ()] Type -- ^ @{ type T x = (x,x) }@ -- | ClassD Cxt Name [TyVarBndr ()] -- [FunDep] [Dec] -- ^ @{ class Eq a => Ord a where ds }@ -- | InstanceD (Maybe Overlap) Cxt Type [Dec] -- -- ^ @{ instance {\-\# OVERLAPS \#-\} -- -- Show w => Show [w] where ds }@ -- | SigD Name Type -- ^ @{ length :: [a] -> Int }@ -- | KiSigD Name Kind -- ^ @{ type TypeRep :: k -> Type }@ -- | ForeignD Foreign -- ^ @{ foreign import ... } -- --{ foreign export ... }@ -- -- | InfixD Fixity Name -- ^ @{ infix 3 foo }@ -- | DefaultD [Type] -- ^ @{ default (Integer, Double) }@ -- -- -- | pragmas -- | PragmaD Pragma -- ^ @{ {\-\# INLINE [1] foo \#-\} }@ -- -- -- | data families (may also appear in [Dec] of 'ClassD' and 'InstanceD') -- | DataFamilyD Name [TyVarBndr ()] -- (Maybe Kind) -- -- ^ @{ data family T a b c :: * }@ -- -- | DataInstD Cxt (Maybe [TyVarBndr ()]) Type -- (Maybe Kind) -- Kind signature -- [Con] [DerivClause] -- ^ @{ data instance Cxt x => T [x] -- -- = A x | B (T x) -- -- deriving (Z,W) -- -- deriving stock Eq }@ -- -- | NewtypeInstD Cxt (Maybe [TyVarBndr ()]) Type -- Quantified type vars -- (Maybe Kind) -- Kind signature -- Con [DerivClause] -- ^ @{ newtype instance Cxt x => T [x] -- -- = A (B x) -- -- deriving (Z,W) -- -- deriving stock Eq }@ -- | TySynInstD TySynEqn -- ^ @{ type instance ... }@ -- -- -- | open type families (may also appear in [Dec] of 'ClassD' and 'InstanceD') -- | OpenTypeFamilyD TypeFamilyHead -- -- ^ @{ type family T a b c = (r :: *) | r -> a b }@ -- -- | ClosedTypeFamilyD TypeFamilyHead [TySynEqn] -- -- ^ @{ type family F a b = (r :: *) | r -> a where ... }@ -- -- | RoleAnnotD Name [Role] -- ^ @{ type role T nominal representational }@ -- | StandaloneDerivD (Maybe DerivStrategy) Cxt Type -- -- ^ @{ deriving stock instance Ord a => Ord (Foo a) }@ -- | DefaultSigD Name Type -- ^ @{ default size :: Data a => a -> Int }@ -- -- -- | Pattern Synonyms -- | PatSynD Name PatSynArgs PatSynDir Pat -- -- ^ @{ pattern P v1 v2 .. vn <- p }@ unidirectional or -- -- @{ pattern P v1 v2 .. vn = p }@ implicit bidirectional or -- -- @{ pattern P v1 v2 .. vn <- p -- -- where P v1 v2 .. vn = e }@ explicit bidirectional -- -- -- -- also, besides prefix pattern synonyms, both infix and record -- -- pattern synonyms are supported. See 'PatSynArgs' for details -- -- | PatSynSigD Name PatSynType -- ^ A pattern synonym's type signature. -- -- | ImplicitParamBindD String Exp -- -- ^ @{ ?x = expr }@ -- -- -- -- Implicit parameter binding declaration. Can only be used in let -- -- and where clauses which consist entirely of implicit bindings. instance HideName Exp where hideName (AppE e1 e2) = AppE (hideName e1) (hideName e2) hideName (AppTypeE e t) = AppTypeE (hideName e) (hideName t) hideName (ArithSeqE d) = ArithSeqE (hideName d) hideName (CaseE e ms) = CaseE (hideName e) (hideName <$> ms) hideName (CompE ss) = CompE (hideName <$> ss) hideName (ConE c) = ConE (hideName c) hideName (CondE guard true false) = CondE (hideName guard) (hideName true) (hideName false) hideName (DoE m ss) = DoE (hideName <$> m) (hideName <$> ss) hideName (ImplicitParamVarE n) = ImplicitParamVarE n hideName (InfixE e1 op e2) = InfixE (hideName <$> e1) (hideName op) (hideName <$> e2) hideName (LabelE s) = LabelE s hideName (LamCaseE ms) = LamCaseE (hideName <$> ms) hideName (LamE ps e) = LamE (hideName <$> ps) (hideName e) hideName (LetE ds e) = LetE (hideName <$> ds) (hideName e) hideName (ListE es) = ListE (hideName <$> es) hideName (LitE l) = LitE l hideName (MDoE m ss) = MDoE (hideName <$> m) (hideName <$> ss) hideName (MultiIfE alts) = MultiIfE ((\(g, e) -> (hideName g, hideName e)) <$> alts) hideName (ParensE e) = ParensE (hideName e) hideName (RecConE nm fs) = RecConE (hideName nm) ((\(n, e) -> (hideName n, hideName e)) <$> fs) hideName (RecUpdE e fs) = RecUpdE (hideName e) ((\(n, ee) -> (hideName n, hideName ee)) <$> fs) hideName (SigE e t) = SigE (hideName e) (hideName t) hideName (StaticE e) = StaticE (hideName e) hideName (TupE es) = TupE ((hideName <$>) <$> es) hideName (UInfixE e1 op e2) = UInfixE (hideName e1) (hideName op) (hideName e2) hideName (UnboundVarE v) = UnboundVarE (hideName v) hideName (UnboxedSumE e alt arity) = UnboxedSumE (hideName e) alt arity hideName (UnboxedTupE es) = UnboxedTupE ((hideName <$>) <$> es) hideName (VarE v) = VarE (hideName v) hideName (GetFieldE e n) = GetFieldE (hideName e) n hideName (ProjectionE ns) = ProjectionE ns instance HideName Guard where hideName (NormalG e) = NormalG (hideName e) hideName (PatG ss) = PatG (hideName <$> ss) instance HideName Lit where hideName x = x instance HideName Match where hideName (Match p b ds) = Match (hideName p) (hideName b) (hideName <$> ds) instance HideName ModName where hideName (ModName n) = ModName n instance HideName Name where -- This is the hidding hideName (Name (OccName on) (NameU _u)) = Name (OccName on) NameS hideName (Name (OccName on) (NameL _u)) = Name (OccName on) NameS hideName (Name on n) = Name (hideName on) (hideName n) instance HideName NameFlavour where hideName (NameG n p m) = NameG n p m hideName (NameL n) = NameL n hideName (NameQ n) = NameQ n hideName NameS = NameS hideName (NameU n) = NameU n instance HideName OccName where hideName (OccName n) = OccName n instance HideName Range where hideName (FromR e) = FromR (hideName e) hideName (FromThenR f t) = FromThenR (hideName f) (hideName t) hideName (FromToR f t) = FromToR (hideName f) (hideName t) hideName (FromThenToR f t to) = FromThenToR (hideName f) (hideName t) (hideName to) instance HideName Stmt where hideName (BindS p e) = BindS (hideName p) (hideName e) hideName (LetS ds) = LetS (hideName <$> ds) hideName (NoBindS e) = NoBindS (hideName e) hideName (ParS ss) = ParS ((hideName <$>) <$> ss) hideName (RecS ss) = RecS (hideName <$> ss) instance HideName (TyVarBndr f) where hideName (PlainTV n f) = PlainTV (hideName n) f hideName (KindedTV n f k) = KindedTV (hideName n) f (hideName k) instance HideName Type where hideName (ForallT vs ctx t) = ForallT (hideName <$> vs) (hideName <$> ctx) (hideName t) hideName (ForallVisT vs t) = ForallVisT (hideName <$> vs) (hideName t) hideName (AppT t x) = AppT (hideName t) (hideName x) hideName (AppKindT t k) = AppKindT (hideName t) (hideName k) hideName (SigT t k) = SigT (hideName t) (hideName k) hideName (VarT n) = VarT (hideName n) hideName (ConT n) = ConT (hideName n) hideName (PromotedT n) = PromotedT (hideName n) hideName (InfixT x n y) = InfixT (hideName x) (hideName n) (hideName y) hideName (UInfixT x n y) = UInfixT (hideName x) (hideName n) (hideName y) hideName (ParensT t) = ParensT (hideName t) hideName (TupleT x) = TupleT x hideName (UnboxedTupleT x) = UnboxedTupleT x hideName (UnboxedSumT x) = UnboxedSumT x hideName (ArrowT) = ArrowT hideName (MulArrowT) = MulArrowT hideName (EqualityT) = EqualityT hideName (ListT) = ListT hideName (PromotedTupleT x) = PromotedTupleT x hideName (PromotedNilT) = PromotedNilT hideName (PromotedConsT) = PromotedConsT hideName (StarT) = StarT hideName (ConstraintT) = ConstraintT hideName (LitT t) = LitT t hideName (WildCardT) = WildCardT hideName (ImplicitParamT n t) = ImplicitParamT n (hideName t) instance HideName Pat where hideName (AsP v p) = AsP (hideName v) (hideName p) hideName (BangP p) = BangP (hideName p) hideName (ConP n ts ps) = ConP (hideName n) (hideName <$> ts) (hideName <$> ps) hideName (InfixP p1 n p2) = InfixP (hideName p1) (hideName n) (hideName p2) hideName (ListP ps) = ListP (hideName <$> ps) hideName (LitP l) = LitP (hideName l) hideName (ParensP p) = ParensP (hideName p) hideName (RecP nm fs) = RecP (nm) ((\(n,p) -> (hideName n, hideName p)) <$> fs) hideName (SigP p t) = SigP (hideName p) (hideName t) hideName (TildeP p) = TildeP (hideName p) hideName (TupP ps) = TupP (hideName <$> ps) hideName (UInfixP p1 n p2) = UInfixP (hideName p1) (hideName n) (hideName p2) hideName (UnboxedSumP p alt arity) = UnboxedSumP (hideName p) alt arity hideName (UnboxedTupP ps) = UnboxedTupP (hideName <$> ps) hideName (VarP v) = VarP (hideName v) hideName (ViewP e p) = ViewP (hideName e) (hideName p) hideName WildP = WildP instance HideName a => HideName [a] where hideName = (hideName <$>)