diff --git a/hindent.cabal b/hindent.cabal index 2cb9ba4f4..c74713052 100644 --- a/hindent.cabal +++ b/hindent.cabal @@ -39,8 +39,12 @@ library HIndent.Ast HIndent.Ast.Context HIndent.Ast.Declaration + HIndent.Ast.Declaration.Class + HIndent.Ast.Declaration.Class.FunctionalDependency + HIndent.Ast.Declaration.Class.NameAndTypeVariables HIndent.Ast.Declaration.Collection HIndent.Ast.Declaration.Data + HIndent.Ast.Declaration.Data.Body HIndent.Ast.Declaration.Data.GADT.Constructor HIndent.Ast.Declaration.Data.GADT.Constructor.Signature HIndent.Ast.Declaration.Data.Header @@ -50,6 +54,8 @@ library HIndent.Ast.Declaration.Family.Type.Injectivity HIndent.Ast.Declaration.Family.Type.ResultSignature HIndent.Ast.Declaration.Instance.Class + HIndent.Ast.Declaration.Instance.Family.Data + HIndent.Ast.Declaration.Instance.Family.Type HIndent.Ast.Declaration.TypeSynonym HIndent.Ast.Declaration.TypeSynonym.Lhs HIndent.Ast.FileHeaderPragma diff --git a/src/HIndent/Ast/Declaration.hs b/src/HIndent/Ast/Declaration.hs index d97db7e9f..b58232e35 100644 --- a/src/HIndent/Ast/Declaration.hs +++ b/src/HIndent/Ast/Declaration.hs @@ -1,3 +1,5 @@ +{-# LANGUAGE RecordWildCards #-} + module HIndent.Ast.Declaration ( Declaration(..) , mkDeclaration @@ -6,10 +8,13 @@ module HIndent.Ast.Declaration import Control.Applicative import Data.Maybe +import qualified HIndent.Ast.Declaration.Class import HIndent.Ast.Declaration.Data import qualified HIndent.Ast.Declaration.Family.Data import qualified HIndent.Ast.Declaration.Family.Type import qualified HIndent.Ast.Declaration.Instance.Class +import qualified HIndent.Ast.Declaration.Instance.Family.Data +import qualified HIndent.Ast.Declaration.Instance.Family.Type import qualified HIndent.Ast.Declaration.TypeSynonym import HIndent.Ast.NodeComments import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC @@ -19,10 +24,13 @@ data Declaration = DataFamily HIndent.Ast.Declaration.Family.Data.DataFamily | TypeFamily HIndent.Ast.Declaration.Family.Type.TypeFamily | DataDeclaration DataDeclaration + | ClassDeclaration HIndent.Ast.Declaration.Class.ClassDeclaration | TypeSynonym HIndent.Ast.Declaration.TypeSynonym.TypeSynonym - | TyClDecl (GHC.TyClDecl GHC.GhcPs) | ClassInstance HIndent.Ast.Declaration.Instance.Class.ClassInstance - | InstDecl (GHC.InstDecl GHC.GhcPs) + | DataFamilyInstance + HIndent.Ast.Declaration.Instance.Family.Data.DataFamilyInstance + | TypeFamilyInstance + HIndent.Ast.Declaration.Instance.Family.Type.TypeFamilyInstance | DerivDecl (GHC.DerivDecl GHC.GhcPs) | ValDecl (GHC.HsBind GHC.GhcPs) | SigDecl (GHC.Sig GHC.GhcPs) @@ -38,11 +46,13 @@ data Declaration instance CommentExtraction Declaration where nodeComments DataFamily {} = NodeComments [] [] [] nodeComments TypeFamily {} = NodeComments [] [] [] - nodeComments DataDeclaration {} = NodeComments [] [] [] + nodeComments HIndent.Ast.Declaration.DataDeclaration {} = + NodeComments [] [] [] + nodeComments ClassDeclaration {} = NodeComments [] [] [] nodeComments TypeSynonym {} = NodeComments [] [] [] - nodeComments TyClDecl {} = NodeComments [] [] [] nodeComments ClassInstance {} = NodeComments [] [] [] - nodeComments InstDecl {} = NodeComments [] [] [] + nodeComments DataFamilyInstance {} = NodeComments [] [] [] + nodeComments TypeFamilyInstance {} = NodeComments [] [] [] nodeComments DerivDecl {} = NodeComments [] [] [] nodeComments ValDecl {} = NodeComments [] [] [] nodeComments SigDecl {} = NodeComments [] [] [] @@ -62,13 +72,27 @@ mkDeclaration (GHC.TyClD _ (GHC.FamDecl _ x)) = <|> TypeFamily <$> HIndent.Ast.Declaration.Family.Type.mkTypeFamily x mkDeclaration (GHC.TyClD _ x@GHC.SynDecl {}) = TypeSynonym $ HIndent.Ast.Declaration.TypeSynonym.mkTypeSynonym x -mkDeclaration (GHC.TyClD _ x@(GHC.DataDecl {})) - | Just decl <- mkDataDeclaration x = DataDeclaration decl -mkDeclaration (GHC.TyClD _ x) = TyClDecl x -mkDeclaration (GHC.InstD _ x) - | Just inst <- HIndent.Ast.Declaration.Instance.Class.mkClassInstance x = - ClassInstance inst - | otherwise = InstDecl x +mkDeclaration (GHC.TyClD _ x@GHC.DataDecl {}) = + maybe + (error "Unreachable.") + HIndent.Ast.Declaration.DataDeclaration + (mkDataDeclaration x) +mkDeclaration (GHC.TyClD _ x@GHC.ClassDecl {}) = + maybe + (error "Unreachable.") + ClassDeclaration + (HIndent.Ast.Declaration.Class.mkClassDeclaration x) +mkDeclaration (GHC.InstD _ x@GHC.ClsInstD {}) = + maybe + (error "Unreachable.") + ClassInstance + (HIndent.Ast.Declaration.Instance.Class.mkClassInstance x) +mkDeclaration (GHC.InstD _ GHC.DataFamInstD {GHC.dfid_inst = GHC.DataFamInstDecl {..}}) = + DataFamilyInstance + $ HIndent.Ast.Declaration.Instance.Family.Data.mkDataFamilyInstance dfid_eqn +mkDeclaration (GHC.InstD _ x@GHC.TyFamInstD {}) = + maybe (error "Unreachable.") TypeFamilyInstance + $ HIndent.Ast.Declaration.Instance.Family.Type.mkTypeFamilyInstance x mkDeclaration (GHC.DerivD _ x) = DerivDecl x mkDeclaration (GHC.ValD _ x) = ValDecl x mkDeclaration (GHC.SigD _ x) = SigDecl x diff --git a/src/HIndent/Ast/Declaration/Class.hs b/src/HIndent/Ast/Declaration/Class.hs new file mode 100644 index 000000000..58be856ed --- /dev/null +++ b/src/HIndent/Ast/Declaration/Class.hs @@ -0,0 +1,38 @@ +{-# LANGUAGE RecordWildCards #-} + +module HIndent.Ast.Declaration.Class + ( ClassDeclaration(..) + , mkClassDeclaration + ) where + +import qualified GHC.Data.Bag as GHC +import HIndent.Ast.Context +import HIndent.Ast.Declaration.Class.FunctionalDependency +import HIndent.Ast.Declaration.Class.NameAndTypeVariables +import HIndent.Ast.NodeComments +import HIndent.Ast.WithComments +import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC +import HIndent.Pretty.NodeComments +import HIndent.Pretty.SigBindFamily + +data ClassDeclaration = ClassDeclaration + { context :: Maybe (WithComments Context) + , nameAndTypeVariables :: NameAndTypeVariables + , functionalDependencies :: [WithComments FunctionalDependency] + , associatedThings :: [LSigBindFamily] + } + +instance CommentExtraction ClassDeclaration where + nodeComments ClassDeclaration {} = NodeComments [] [] [] + +mkClassDeclaration :: GHC.TyClDecl GHC.GhcPs -> Maybe ClassDeclaration +mkClassDeclaration x@GHC.ClassDecl {..} + | Just nameAndTypeVariables <- mkNameAndTypeVariables x = + Just ClassDeclaration {..} + where + context = fmap (fmap mkContext . fromGenLocated) tcdCtxt + functionalDependencies = + fmap (fmap mkFunctionalDependency . fromGenLocated) tcdFDs + associatedThings = + mkSortedLSigBindFamilyList tcdSigs (GHC.bagToList tcdMeths) tcdATs [] [] +mkClassDeclaration _ = Nothing diff --git a/src/HIndent/Ast/Declaration/Class/FunctionalDependency.hs b/src/HIndent/Ast/Declaration/Class/FunctionalDependency.hs new file mode 100644 index 000000000..9b12e784c --- /dev/null +++ b/src/HIndent/Ast/Declaration/Class/FunctionalDependency.hs @@ -0,0 +1,21 @@ +{-# LANGUAGE RecordWildCards #-} + +module HIndent.Ast.Declaration.Class.FunctionalDependency + ( FunctionalDependency(..) + , mkFunctionalDependency + ) where + +import HIndent.Ast.NodeComments +import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC +import HIndent.Pretty.NodeComments + +data FunctionalDependency = FunctionalDependency + { from :: [GHC.LIdP GHC.GhcPs] + , to :: [GHC.LIdP GHC.GhcPs] + } + +instance CommentExtraction FunctionalDependency where + nodeComments FunctionalDependency {} = NodeComments [] [] [] + +mkFunctionalDependency :: GHC.FunDep GHC.GhcPs -> FunctionalDependency +mkFunctionalDependency (GHC.FunDep _ from to) = FunctionalDependency {..} diff --git a/src/HIndent/Ast/Declaration/Class/NameAndTypeVariables.hs b/src/HIndent/Ast/Declaration/Class/NameAndTypeVariables.hs new file mode 100644 index 000000000..deb2ac358 --- /dev/null +++ b/src/HIndent/Ast/Declaration/Class/NameAndTypeVariables.hs @@ -0,0 +1,47 @@ +{-# LANGUAGE RecordWildCards #-} + +module HIndent.Ast.Declaration.Class.NameAndTypeVariables + ( NameAndTypeVariables(..) + , mkNameAndTypeVariables + ) where + +import qualified GHC.Types.Fixity as GHC +import HIndent.Ast.NodeComments +import HIndent.Ast.Type.Variable +import HIndent.Ast.WithComments +import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC +import HIndent.Pretty.NodeComments + +data NameAndTypeVariables + = Prefix + { name :: GHC.LIdP GHC.GhcPs + , typeVariables :: [WithComments TypeVariable] + } + | Infix + { left :: WithComments TypeVariable + , name :: GHC.LIdP GHC.GhcPs + , right :: WithComments TypeVariable + , remains :: [WithComments TypeVariable] + } + +instance CommentExtraction NameAndTypeVariables where + nodeComments Prefix {} = NodeComments [] [] [] + nodeComments Infix {} = NodeComments [] [] [] + +mkNameAndTypeVariables :: GHC.TyClDecl GHC.GhcPs -> Maybe NameAndTypeVariables +mkNameAndTypeVariables GHC.ClassDecl {tcdFixity = GHC.Prefix, ..} = + Just Prefix {..} + where + name = tcdLName + typeVariables = + fmap mkTypeVariable . fromGenLocated <$> GHC.hsq_explicit tcdTyVars +mkNameAndTypeVariables GHC.ClassDecl { tcdFixity = GHC.Infix + , tcdTyVars = GHC.HsQTvs {hsq_explicit = h:t:xs} + , .. + } = Just Infix {..} + where + left = mkTypeVariable <$> fromGenLocated h + name = tcdLName + right = mkTypeVariable <$> fromGenLocated t + remains = fmap (fmap mkTypeVariable . fromGenLocated) xs +mkNameAndTypeVariables _ = Nothing diff --git a/src/HIndent/Ast/Declaration/Data.hs b/src/HIndent/Ast/Declaration/Data.hs index c29fa8af2..df71498aa 100644 --- a/src/HIndent/Ast/Declaration/Data.hs +++ b/src/HIndent/Ast/Declaration/Data.hs @@ -1,65 +1,26 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ViewPatterns #-} module HIndent.Ast.Declaration.Data ( DataDeclaration(..) , mkDataDeclaration ) where -import Data.Maybe -import qualified GHC.Types.SrcLoc as GHC -import HIndent.Ast.Declaration.Data.GADT.Constructor +import HIndent.Ast.Declaration.Data.Body import HIndent.Ast.Declaration.Data.Header import HIndent.Ast.NodeComments -import HIndent.Ast.Type -import HIndent.Ast.WithComments import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC import HIndent.Pretty.NodeComments -data DataDeclaration - = GADT - { header :: Header - , kind :: Maybe (WithComments Type) - , constructors :: [WithComments GADTConstructor] - } - | Record - { header :: Header - , dd_cons :: [GHC.LConDecl GHC.GhcPs] - , dd_derivs :: GHC.HsDeriving GHC.GhcPs - } +data DataDeclaration = DataDeclaration + { header :: Header + , body :: DataBody + } instance CommentExtraction DataDeclaration where - nodeComments GADT {} = NodeComments [] [] [] - nodeComments Record {} = NodeComments [] [] [] + nodeComments DataDeclaration {} = NodeComments [] [] [] mkDataDeclaration :: GHC.TyClDecl GHC.GhcPs -> Maybe DataDeclaration -mkDataDeclaration decl@GHC.DataDecl {tcdDataDefn = defn@GHC.HsDataDefn {..}} - | Just header <- mkHeader decl = - Just - $ if isGADT defn - then GADT - { constructors = - fromMaybe (error "Some constructors are not GADT ones.") - $ mapM (traverse mkGADTConstructor . fromGenLocated) - $ getConDecls defn - , .. - } - else Record {dd_cons = getConDecls defn, ..} - where - kind = fmap mkType . fromGenLocated <$> dd_kindSig +mkDataDeclaration decl@GHC.DataDecl {..} = + DataDeclaration <$> mkHeader decl <*> pure (mkDataBody tcdDataDefn) mkDataDeclaration _ = Nothing - -isGADT :: GHC.HsDataDefn GHC.GhcPs -> Bool -isGADT (getConDecls -> (GHC.L _ GHC.ConDeclGADT {}:_)) = True -isGADT _ = False - -getConDecls :: GHC.HsDataDefn GHC.GhcPs -> [GHC.LConDecl GHC.GhcPs] -#if MIN_VERSION_ghc_lib_parser(9, 6, 0) -getConDecls GHC.HsDataDefn {..} = - case dd_cons of - GHC.NewTypeCon x -> [x] - GHC.DataTypeCons _ xs -> xs -#else -getConDecls GHC.HsDataDefn {..} = dd_cons -#endif diff --git a/src/HIndent/Ast/Declaration/Data/Body.hs b/src/HIndent/Ast/Declaration/Data/Body.hs new file mode 100644 index 000000000..1ad0bd9eb --- /dev/null +++ b/src/HIndent/Ast/Declaration/Data/Body.hs @@ -0,0 +1,59 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ViewPatterns #-} + +module HIndent.Ast.Declaration.Data.Body + ( DataBody(..) + , mkDataBody + ) where + +import Data.Maybe +import qualified GHC.Types.SrcLoc as GHC +import HIndent.Ast.Declaration.Data.GADT.Constructor +import HIndent.Ast.NodeComments +import HIndent.Ast.Type +import HIndent.Ast.WithComments +import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC +import HIndent.Pretty.NodeComments + +data DataBody + = GADT + { kind :: Maybe (WithComments Type) + , constructors :: [WithComments GADTConstructor] + } + | Record + { dd_cons :: [GHC.LConDecl GHC.GhcPs] + , dd_derivs :: GHC.HsDeriving GHC.GhcPs + } + +instance CommentExtraction DataBody where + nodeComments GADT {} = NodeComments [] [] [] + nodeComments Record {} = NodeComments [] [] [] + +mkDataBody :: GHC.HsDataDefn GHC.GhcPs -> DataBody +mkDataBody defn@GHC.HsDataDefn {..} = + if isGADT defn + then GADT + { constructors = + fromMaybe (error "Some constructors are not GADT ones.") + $ mapM (traverse mkGADTConstructor . fromGenLocated) + $ getConDecls defn + , .. + } + else Record {dd_cons = getConDecls defn, ..} + where + kind = fmap mkType . fromGenLocated <$> dd_kindSig + +isGADT :: GHC.HsDataDefn GHC.GhcPs -> Bool +isGADT (getConDecls -> (GHC.L _ GHC.ConDeclGADT {}:_)) = True +isGADT _ = False + +getConDecls :: GHC.HsDataDefn GHC.GhcPs -> [GHC.LConDecl GHC.GhcPs] +#if MIN_VERSION_ghc_lib_parser(9, 6, 0) +getConDecls GHC.HsDataDefn {..} = + case dd_cons of + GHC.NewTypeCon x -> [x] + GHC.DataTypeCons _ xs -> xs +#else +getConDecls GHC.HsDataDefn {..} = dd_cons +#endif diff --git a/src/HIndent/Ast/Declaration/Instance/Family/Data.hs b/src/HIndent/Ast/Declaration/Instance/Family/Data.hs new file mode 100644 index 000000000..b3ea72286 --- /dev/null +++ b/src/HIndent/Ast/Declaration/Instance/Family/Data.hs @@ -0,0 +1,32 @@ +{-# LANGUAGE RecordWildCards #-} + +module HIndent.Ast.Declaration.Instance.Family.Data + ( DataFamilyInstance(..) + , mkDataFamilyInstance + ) where + +import qualified GHC.Hs as GG +import HIndent.Ast.Declaration.Data.Body +import HIndent.Ast.Declaration.Data.NewOrData +import HIndent.Ast.NodeComments +import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC +import HIndent.Pretty.NodeComments + +data DataFamilyInstance = DataFamilyInstance + { newOrData :: NewOrData + , name :: GHC.LIdP GHC.GhcPs + , types :: GHC.HsTyPats GHC.GhcPs + , body :: DataBody + } + +instance CommentExtraction DataFamilyInstance where + nodeComments DataFamilyInstance {} = NodeComments [] [] [] + +mkDataFamilyInstance :: + GHC.FamEqn GHC.GhcPs (GHC.HsDataDefn GHC.GhcPs) -> DataFamilyInstance +mkDataFamilyInstance GHC.FamEqn {..} = DataFamilyInstance {..} + where + newOrData = mkNewOrData feqn_rhs + name = feqn_tycon + types = feqn_pats + body = mkDataBody feqn_rhs diff --git a/src/HIndent/Ast/Declaration/Instance/Family/Type.hs b/src/HIndent/Ast/Declaration/Instance/Family/Type.hs new file mode 100644 index 000000000..8ae505c7b --- /dev/null +++ b/src/HIndent/Ast/Declaration/Instance/Family/Type.hs @@ -0,0 +1,28 @@ +{-# LANGUAGE RecordWildCards #-} + +module HIndent.Ast.Declaration.Instance.Family.Type + ( TypeFamilyInstance(..) + , mkTypeFamilyInstance + ) where + +import HIndent.Ast.NodeComments +import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC +import HIndent.Pretty.NodeComments + +data TypeFamilyInstance = TypeFamilyInstance + { name :: GHC.LIdP GHC.GhcPs + , types :: GHC.HsTyPats GHC.GhcPs + , bind :: GHC.LHsType GHC.GhcPs + } + +instance CommentExtraction TypeFamilyInstance where + nodeComments TypeFamilyInstance {} = NodeComments [] [] [] + +mkTypeFamilyInstance :: GHC.InstDecl GHC.GhcPs -> Maybe TypeFamilyInstance +mkTypeFamilyInstance GHC.TyFamInstD {GHC.tfid_inst = GHC.TyFamInstDecl {GHC.tfid_eqn = GHC.FamEqn {..}}} = + Just $ TypeFamilyInstance {..} + where + name = feqn_tycon + types = feqn_pats + bind = feqn_rhs +mkTypeFamilyInstance _ = Nothing diff --git a/src/HIndent/Pretty.hs b/src/HIndent/Pretty.hs index 738c89801..019a00cdd 100644 --- a/src/HIndent/Pretty.hs +++ b/src/HIndent/Pretty.hs @@ -41,7 +41,11 @@ import qualified GHC.Unit.Module.Warnings as GHC import HIndent.Applicative import qualified HIndent.Ast.Context import HIndent.Ast.Declaration +import HIndent.Ast.Declaration.Class +import HIndent.Ast.Declaration.Class.FunctionalDependency +import HIndent.Ast.Declaration.Class.NameAndTypeVariables import HIndent.Ast.Declaration.Data +import qualified HIndent.Ast.Declaration.Data.Body import HIndent.Ast.Declaration.Data.GADT.Constructor import HIndent.Ast.Declaration.Data.GADT.Constructor.Signature import HIndent.Ast.Declaration.Data.Header @@ -51,6 +55,8 @@ import HIndent.Ast.Declaration.Family.Type import HIndent.Ast.Declaration.Family.Type.Injectivity import HIndent.Ast.Declaration.Family.Type.ResultSignature import HIndent.Ast.Declaration.Instance.Class +import HIndent.Ast.Declaration.Instance.Family.Data +import HIndent.Ast.Declaration.Instance.Family.Type import HIndent.Ast.Declaration.TypeSynonym import HIndent.Ast.Declaration.TypeSynonym.Lhs import HIndent.Ast.NodeComments @@ -142,11 +148,12 @@ class CommentExtraction a => instance Pretty Declaration where pretty' (HIndent.Ast.Declaration.DataFamily x) = pretty x pretty' (HIndent.Ast.Declaration.TypeFamily x) = pretty x - pretty' (DataDeclaration x) = pretty x + pretty' (HIndent.Ast.Declaration.DataDeclaration x) = pretty x + pretty' (HIndent.Ast.Declaration.ClassDeclaration x) = pretty x pretty' (HIndent.Ast.Declaration.TypeSynonym x) = pretty x - pretty' (TyClDecl x) = pretty x pretty' (HIndent.Ast.Declaration.ClassInstance x) = pretty x - pretty' (InstDecl x) = pretty x + pretty' (HIndent.Ast.Declaration.DataFamilyInstance x) = pretty x + pretty' (HIndent.Ast.Declaration.TypeFamilyInstance x) = pretty x pretty' (DerivDecl x) = pretty x pretty' (ValDecl x) = pretty x pretty' (SigDecl x) = pretty x @@ -160,13 +167,15 @@ instance Pretty Declaration where pretty' (RoleAnnotDecl x) = pretty x instance Pretty DataDeclaration where - pretty' GADT {..} = do - pretty header + pretty' HIndent.Ast.Declaration.Data.DataDeclaration {..} = + pretty header >> pretty body + +instance Pretty HIndent.Ast.Declaration.Data.Body.DataBody where + pretty' HIndent.Ast.Declaration.Data.Body.GADT {..} = do whenJust kind $ \x -> string " :: " >> pretty x string " where" indentedBlock $ newlinePrefixed $ fmap pretty constructors - pretty' HIndent.Ast.Declaration.Data.Record {..} = do - pretty header + pretty' HIndent.Ast.Declaration.Data.Body.Record {..} = do case dd_cons of [] -> indentedBlock derivingsAfterNewline [x@(GHC.L _ GHC.ConDeclH98 {con_args = GHC.RecCon {}})] -> do @@ -241,8 +250,9 @@ instance Pretty TypeSynonym where ver = newline >> indentedBlock (string "= " |=> pretty rhs) instance Pretty TypeSynonymLhs where - pretty' Prefix {..} = spaced $ pretty name : fmap pretty typeVariables - pretty' Infix {..} = + pretty' HIndent.Ast.Declaration.TypeSynonym.Lhs.Prefix {..} = + spaced $ pretty name : fmap pretty typeVariables + pretty' HIndent.Ast.Declaration.TypeSynonym.Lhs.Infix {..} = spaced [pretty left, pretty $ fmap InfixOp name, pretty right] instance Pretty Injectivity where @@ -381,6 +391,53 @@ instance Pretty NewOrData where pretty' Newtype = string "newtype" pretty' Data = string "data" +instance Pretty HIndent.Ast.Declaration.Class.ClassDeclaration where + pretty' (HIndent.Ast.Declaration.Class.ClassDeclaration {..}) = do + if isJust context + then verHead + else horHead <-|> verHead + indentedBlock $ newlinePrefixed $ fmap pretty associatedThings + where + horHead = do + string "class " + pretty nameAndTypeVariables + unless (null functionalDependencies) + $ string " | " >> hCommaSep (fmap pretty functionalDependencies) + unless (null associatedThings) $ string " where" + verHead = do + string "class " |=> do + whenJust context $ \ctx -> pretty ctx >> string " =>" >> newline + pretty nameAndTypeVariables + unless (null functionalDependencies) $ do + newline + indentedBlock + $ string "| " |=> vCommaSep (fmap pretty functionalDependencies) + unless (null associatedThings) + $ newline >> indentedBlock (string "where") + +instance Pretty NameAndTypeVariables where + pretty' HIndent.Ast.Declaration.Class.NameAndTypeVariables.Prefix {..} = + spaced $ pretty name : fmap pretty typeVariables + pretty' HIndent.Ast.Declaration.Class.NameAndTypeVariables.Infix {..} = do + parens $ spaced [pretty left, pretty $ fmap InfixOp name, pretty right] + spacePrefixed $ fmap pretty remains + +instance Pretty FunctionalDependency where + pretty' (FunctionalDependency {..}) = + spaced $ fmap pretty from ++ [string "->"] ++ fmap pretty to + +instance Pretty DataFamilyInstance where + pretty' (HIndent.Ast.Declaration.Instance.Family.Data.DataFamilyInstance {..}) = do + spaced + $ pretty newOrData : string "instance" : pretty name : fmap pretty types + pretty body + +instance Pretty TypeFamilyInstance where + pretty' (HIndent.Ast.Declaration.Instance.Family.Type.TypeFamilyInstance {..}) = do + spaced $ string "type instance" : pretty name : fmap pretty types + string " = " + pretty bind + -- Do nothing if there are no pragmas, module headers, imports, or -- declarations. Otherwise, extra blank lines will be inserted if only -- comments are present in the source code. See @@ -388,138 +445,6 @@ instance Pretty NewOrData where instance (CommentExtraction l, Pretty e) => Pretty (GHC.GenLocated l e) where pretty' (GHC.L _ e) = pretty e -instance Pretty (GHC.TyClDecl GHC.GhcPs) where - pretty' = prettyTyClDecl - -prettyTyClDecl :: GHC.TyClDecl GHC.GhcPs -> Printer () -prettyTyClDecl (GHC.FamDecl _ x) = pretty x -prettyTyClDecl GHC.SynDecl {..} = do - string "type " - case tcdFixity of - GHC.Prefix -> - spaced $ pretty tcdLName : fmap pretty (GHC.hsq_explicit tcdTyVars) - GHC.Infix -> - case GHC.hsq_explicit tcdTyVars of - (l:r:xs) -> do - spaced [pretty l, pretty $ fmap InfixOp tcdLName, pretty r] - forM_ xs $ \x -> do - space - pretty x - _ -> error "Not enough parameters are given." - hor <-|> ver - where - hor = string " = " >> pretty tcdRhs - ver = newline >> indentedBlock (string "= " |=> pretty tcdRhs) -#if MIN_VERSION_ghc_lib_parser(9,6,1) -prettyTyClDecl GHC.DataDecl {..} = do - printDataNewtype |=> do - whenJust (GHC.dd_ctxt tcdDataDefn) $ \x -> do - pretty $ Context x - string " =>" - newline - pretty tcdLName - spacePrefixed $ pretty <$> GHC.hsq_explicit tcdTyVars - pretty tcdDataDefn - where - printDataNewtype = - case GHC.dd_cons tcdDataDefn of - GHC.DataTypeCons {} -> string "data " - GHC.NewTypeCon {} -> string "newtype " -#elif MIN_VERSION_ghc_lib_parser(9,4,1) -prettyTyClDecl GHC.DataDecl {..} = do - printDataNewtype |=> do - whenJust (GHC.dd_ctxt tcdDataDefn) $ \x -> do - pretty $ Context x - string " =>" - newline - pretty tcdLName - spacePrefixed $ pretty <$> GHC.hsq_explicit tcdTyVars - pretty tcdDataDefn - where - printDataNewtype = - case GHC.dd_ND tcdDataDefn of - GHC.DataType -> string "data " - GHC.NewType -> string "newtype " -#else -prettyTyClDecl GHC.DataDecl {..} = do - printDataNewtype |=> do - whenJust (GHC.dd_ctxt tcdDataDefn) $ \_ -> do - pretty $ Context $ GHC.dd_ctxt tcdDataDefn - string " =>" - newline - pretty tcdLName - spacePrefixed $ pretty <$> GHC.hsq_explicit tcdTyVars - pretty tcdDataDefn - where - printDataNewtype = - case GHC.dd_ND tcdDataDefn of - GHC.DataType -> string "data " - GHC.NewType -> string "newtype " -#endif -prettyTyClDecl GHC.ClassDecl {..} = do - if isJust tcdCtxt - then verHead - else horHead <-|> verHead - indentedBlock $ newlinePrefixed $ fmap pretty sigsMethodsFamilies - where - horHead = do - string "class " - printNameAndTypeVariables - unless (null tcdFDs) $ do - string " | " - hCommaSep - (fmap - (\x -> - printCommentsAnd x $ \(GHC.FunDep _ from to) -> - spaced $ fmap pretty from ++ [string "->"] ++ fmap pretty to) - tcdFDs) - unless (null sigsMethodsFamilies) $ string " where" - verHead = do - string "class " |=> do - whenJust tcdCtxt $ \ctx -> do - printCommentsAnd ctx $ \case - [] -> string "()" - [x] -> pretty x - xs -> hvTuple $ fmap pretty xs - string " =>" - newline - printNameAndTypeVariables - unless (null tcdFDs) $ do - newline - indentedBlock - $ string "| " - |=> vCommaSep - (flip fmap tcdFDs $ \x -> - printCommentsAnd x $ \(GHC.FunDep _ from to) -> - spaced - $ fmap pretty from ++ [string "->"] ++ fmap pretty to) - unless (null sigsMethodsFamilies) $ do - newline - indentedBlock $ string "where" - printNameAndTypeVariables = - case tcdFixity of - GHC.Prefix -> - spaced $ pretty tcdLName : fmap pretty (GHC.hsq_explicit tcdTyVars) - GHC.Infix -> - case GHC.hsq_explicit tcdTyVars of - (l:r:xs) -> do - parens - $ spaced [pretty l, pretty $ fmap InfixOp tcdLName, pretty r] - spacePrefixed $ fmap pretty xs - _ -> error "Not enough parameters are given." - sigsMethodsFamilies = - SBF.mkSortedLSigBindFamilyList - tcdSigs - (GHC.bagToList tcdMeths) - tcdATs - [] - [] - -instance Pretty (GHC.InstDecl GHC.GhcPs) where - pretty' GHC.ClsInstD {..} = pretty cid_inst - pretty' GHC.DataFamInstD {..} = pretty dfid_inst - pretty' GHC.TyFamInstD {..} = pretty $ TopLevelTyFamInstDecl tfid_inst - instance Pretty (GHC.HsBind GHC.GhcPs) where pretty' = prettyHsBind