    {-
    (c) The University of Glasgow 2006
    (c) The GRASP/AQUA Project, Glasgow University, 1992-1998

    \section{Haskell abstract syntax definition}

    This module glues together the pieces of the Haskell abstract syntax,
    which is declared in the various \tr{Hs*} modules.  This module,
    therefore, is almost nothing but re-exporting.
    -}

    {-# LANGUAGE DeriveDataTypeable #-}
    {-# LANGUAGE StandaloneDeriving #-}
    {-# LANGUAGE FlexibleContexts #-}
    {-# LANGUAGE UndecidableInstances #-} -- Wrinkle in Note [Trees That Grow]
                                          -- in module Language.Haskell.Syntax.Extension
    {-# LANGUAGE ConstraintKinds #-}
    {-# LANGUAGE TypeFamilies #-}
    {-# LANGUAGE FlexibleInstances #-} -- For deriving instance Data

    module GHC.Hs (
            module Language.Haskell.Syntax,
            module GHC.Hs.Binds,
            module GHC.Hs.Decls,
            module GHC.Hs.Expr,
            module GHC.Hs.ImpExp,
            module GHC.Hs.Lit,
            module GHC.Hs.Pat,
            module GHC.Hs.Type,
            module GHC.Hs.Utils,
            module GHC.Hs.Doc,
            module GHC.Hs.Extension,
            module GHC.Parser.Annotation,
            Fixity,

            HsModule(..), AnnsModule(..),
            HsParsedModule(..)
    ) where

    -- friends:
    import GHC.Prelude

    import GHC.Hs.Decls
    import GHC.Hs.Binds
    import GHC.Hs.Expr
    import GHC.Hs.ImpExp
    import GHC.Hs.Lit
    import Language.Haskell.Syntax
    import GHC.Hs.Extension
    import GHC.Parser.Annotation
    import GHC.Hs.Pat
    import GHC.Hs.Type
    import GHC.Hs.Utils
    import GHC.Hs.Doc
    import GHC.Hs.Instances () -- For Data instances

    -- others:
    import GHC.Utils.Outputable
    import GHC.Types.Fixity         ( Fixity )
    import GHC.Types.SrcLoc
    import GHC.Unit.Module          ( ModuleName )
    import GHC.Unit.Module.Warnings ( WarningTxt )

    -- libraries:
    import Data.Data hiding ( Fixity )

    -- | Haskell Module
    --
    -- All we actually declare here is the top-level structure for a module.
    data HsModule
      = HsModule {
          HsModule -> EpAnn AnnsModule
    hsmodAnn :: EpAnn AnnsModule,
          HsModule -> LayoutInfo
    hsmodLayout :: LayoutInfo,
            -- ^ Layout info for the module.
            -- For incomplete modules (e.g. the output of parseHeader), it is NoLayoutInfo.
          HsModule -> Maybe (LocatedA ModuleName)
    hsmodName :: Maybe (LocatedA ModuleName),
            -- ^ @Nothing@: \"module X where\" is omitted (in which case the next
            --     field is Nothing too)
          HsModule -> Maybe (LocatedL [LIE GhcPs])
    hsmodExports :: Maybe (LocatedL [LIE GhcPs]),
            -- ^ Export list
            --
            --  - @Nothing@: export list omitted, so export everything
            --
            --  - @Just []@: export /nothing/
            --
            --  - @Just [...]@: as you would expect...
            --
            --
            --  - 'GHC.Parser.Annotation.AnnKeywordId's : 'GHC.Parser.Annotation.AnnOpen'
            --                                   ,'GHC.Parser.Annotation.AnnClose'

            -- For details on above see note [exact print annotations] in GHC.Parser.Annotation
          HsModule -> [LImportDecl GhcPs]
    hsmodImports :: [LImportDecl GhcPs],
            -- ^ We snaffle interesting stuff out of the imported interfaces early
            -- on, adding that info to TyDecls/etc; so this list is often empty,
            -- downstream.
          HsModule -> [LHsDecl GhcPs]
    hsmodDecls :: [LHsDecl GhcPs],
            -- ^ Type, class, value, and interface signature decls
          HsModule -> Maybe (LocatedP WarningTxt)
    hsmodDeprecMessage :: Maybe (LocatedP WarningTxt),
            -- ^ reason\/explanation for warning/deprecation of this module
            --
            --  - 'GHC.Parser.Annotation.AnnKeywordId's : 'GHC.Parser.Annotation.AnnOpen'
            --                                   ,'GHC.Parser.Annotation.AnnClose'
            --

            -- For details on above see note [exact print annotations] in GHC.Parser.Annotation
          HsModule -> Maybe LHsDocString
    hsmodHaddockModHeader :: Maybe LHsDocString
            -- ^ Haddock module info and description, unparsed
            --
            --  - 'GHC.Parser.Annotation.AnnKeywordId's : 'GHC.Parser.Annotation.AnnOpen'
            --                                   ,'GHC.Parser.Annotation.AnnClose'

            -- For details on above see note [exact print annotations] in GHC.Parser.Annotation
       }
         -- ^ 'GHC.Parser.Annotation.AnnKeywordId's
         --
         --  - 'GHC.Parser.Annotation.AnnModule','GHC.Parser.Annotation.AnnWhere'
         --
         --  - 'GHC.Parser.Annotation.AnnOpen','GHC.Parser.Annotation.AnnSemi',
         --    'GHC.Parser.Annotation.AnnClose' for explicit braces and semi around
         --    hsmodImports,hsmodDecls if this style is used.

         -- For details on above see note [exact print annotations] in GHC.Parser.Annotation

    deriving instance Data HsModule

    data AnnsModule
      = AnnsModule {
        AnnsModule -> [AddEpAnn]
    am_main :: [AddEpAnn],
        AnnsModule -> AnnList
    am_decls :: AnnList
        } deriving (Typeable AnnsModule
    AnnsModule -> DataType
    AnnsModule -> Constr
    (forall b. Data b => b -> b) -> AnnsModule -> AnnsModule
    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) -> AnnsModule -> u
    forall u. (forall d. Data d => d -> u) -> AnnsModule -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnnsModule -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnnsModule -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AnnsModule
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnnsModule -> c AnnsModule
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AnnsModule)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AnnsModule)
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> AnnsModule -> m AnnsModule
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AnnsModule -> u
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> AnnsModule -> u
    gmapQ :: forall u. (forall d. Data d => d -> u) -> AnnsModule -> [u]
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> AnnsModule -> [u]
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnnsModule -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> AnnsModule -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnnsModule -> r
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> AnnsModule -> r
    gmapT :: (forall b. Data b => b -> b) -> AnnsModule -> AnnsModule
    $cgmapT :: (forall b. Data b => b -> b) -> AnnsModule -> AnnsModule
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AnnsModule)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c AnnsModule)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AnnsModule)
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c AnnsModule)
    dataTypeOf :: AnnsModule -> DataType
    $cdataTypeOf :: AnnsModule -> DataType
    toConstr :: AnnsModule -> Constr
    $ctoConstr :: AnnsModule -> Constr
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AnnsModule
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c AnnsModule
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnnsModule -> c AnnsModule
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> AnnsModule -> c AnnsModule
    Data, AnnsModule -> AnnsModule -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: AnnsModule -> AnnsModule -> Bool
    $c/= :: AnnsModule -> AnnsModule -> Bool
    == :: AnnsModule -> AnnsModule -> Bool
    $c== :: AnnsModule -> AnnsModule -> Bool
    Eq)

    instance Outputable HsModule where

        ppr :: HsModule -> SDoc
    ppr (HsModule EpAnn AnnsModule
    _ LayoutInfo
    _ Maybe (LocatedA ModuleName)
    Nothing Maybe (LocatedL [LIE GhcPs])
    _ [LImportDecl GhcPs]
    imports [LHsDecl GhcPs]
    decls Maybe (LocatedP WarningTxt)
    _ Maybe LHsDocString
    mbDoc)
          = forall t. Outputable t => Maybe t -> SDoc
    pp_mb Maybe LHsDocString
    mbDoc SDoc -> SDoc -> SDoc
    $$ forall t. Outputable t => [t] -> SDoc
    pp_nonnull [LImportDecl GhcPs]
    imports
                        SDoc -> SDoc -> SDoc
    $$ forall t. Outputable t => [t] -> SDoc
    pp_nonnull [LHsDecl GhcPs]
    decls

        ppr (HsModule EpAnn AnnsModule
    _ LayoutInfo
    _ (Just LocatedA ModuleName
    name) Maybe (LocatedL [LIE GhcPs])
    exports [LImportDecl GhcPs]
    imports [LHsDecl GhcPs]
    decls Maybe (LocatedP WarningTxt)
    deprec Maybe LHsDocString
    mbDoc)
          = [SDoc] -> SDoc
    vcat [
                forall t. Outputable t => Maybe t -> SDoc
    pp_mb Maybe LHsDocString
    mbDoc,
                case Maybe (LocatedL [LIE GhcPs])
    exports of
                  Maybe (LocatedL [LIE GhcPs])
    Nothing -> SDoc -> SDoc
    pp_header (String -> SDoc
    text String
    "where")
                  Just LocatedL [LIE GhcPs]
    es -> [SDoc] -> SDoc
    vcat [
                               SDoc -> SDoc
    pp_header SDoc
    lparen,
                               Int -> SDoc -> SDoc
    nest Int
    8 ([SDoc] -> SDoc
    fsep (SDoc -> [SDoc] -> [SDoc]
    punctuate SDoc
    comma (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr (forall l e. GenLocated l e -> e
    unLoc LocatedL [LIE GhcPs]
    es)))),
                               Int -> SDoc -> SDoc
    nest Int
    4 (String -> SDoc
    text String
    ") where")
                              ],
                forall t. Outputable t => [t] -> SDoc
    pp_nonnull [LImportDecl GhcPs]
    imports,
                forall t. Outputable t => [t] -> SDoc
    pp_nonnull [LHsDecl GhcPs]
    decls
              ]
          where
            pp_header :: SDoc -> SDoc
    pp_header SDoc
    rest = case Maybe (LocatedP WarningTxt)
    deprec of
               Maybe (LocatedP WarningTxt)
    Nothing -> SDoc
    pp_modname SDoc -> SDoc -> SDoc
    <+> SDoc
    rest
               Just LocatedP WarningTxt
    d -> [SDoc] -> SDoc
    vcat [ SDoc
    pp_modname, forall a. Outputable a => a -> SDoc
    ppr LocatedP WarningTxt
    d, SDoc
    rest ]

            pp_modname :: SDoc
    pp_modname = String -> SDoc
    text String
    "module" SDoc -> SDoc -> SDoc
    <+> forall a. Outputable a => a -> SDoc
    ppr LocatedA ModuleName
    name

    pp_mb :: Outputable t => Maybe t -> SDoc
    pp_mb :: forall t. Outputable t => Maybe t -> SDoc
    pp_mb (Just t
    x) = forall a. Outputable a => a -> SDoc
    ppr t
    x
    pp_mb Maybe t
    Nothing  = SDoc
    empty

    pp_nonnull :: Outputable t => [t] -> SDoc
    pp_nonnull :: forall t. Outputable t => [t] -> SDoc
    pp_nonnull [] = SDoc
    empty
    pp_nonnull [t]
    xs = [SDoc] -> SDoc
    vcat (forall a b. (a -> b) -> [a] -> [b]
    map forall a. Outputable a => a -> SDoc
    ppr [t]
    xs)

    data HsParsedModule = HsParsedModule {
        HsParsedModule -> Located HsModule
    hpm_module    :: Located HsModule,
        HsParsedModule -> [String]
    hpm_src_files :: [FilePath]
           -- ^ extra source files (e.g. from #includes).  The lexer collects
           -- these from '# <file> <line>' pragmas, which the C preprocessor
           -- leaves behind.  These files and their timestamps are stored in
           -- the .hi file, so that we can force recompilation if any of
           -- them change (#3589)
      }