{-# LANGUAGE CPP #-}

module HIndent.Ast.FileHeaderPragma.Collection
  ( FileHeaderPragmaCollection
  , mkFileHeaderPragmaCollection
  , hasPragmas
  ) where

import Data.Maybe
import Generics.SYB
import HIndent.Ast.FileHeaderPragma
import HIndent.Ast.NodeComments
import qualified HIndent.GhcLibParserWrapper.GHC.Hs as GHC
import HIndent.Pretty
import HIndent.Pretty.Combinators
import HIndent.Pretty.NodeComments

newtype FileHeaderPragmaCollection =
  FileHeaderPragmaCollection [FileHeaderPragma]

instance CommentExtraction FileHeaderPragmaCollection where
  nodeComments :: FileHeaderPragmaCollection -> NodeComments
nodeComments FileHeaderPragmaCollection
_ = [LEpaComment] -> [LEpaComment] -> [LEpaComment] -> NodeComments
NodeComments [] [] []

instance Pretty FileHeaderPragmaCollection where
  pretty' :: FileHeaderPragmaCollection -> Printer ()
pretty' (FileHeaderPragmaCollection [FileHeaderPragma]
xs) = [Printer ()] -> Printer ()
lined ([Printer ()] -> Printer ()) -> [Printer ()] -> Printer ()
forall a b. (a -> b) -> a -> b
$ (FileHeaderPragma -> Printer ())
-> [FileHeaderPragma] -> [Printer ()]
forall a b. (a -> b) -> [a] -> [b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FileHeaderPragma -> Printer ()
forall a. Pretty a => a -> Printer ()
pretty [FileHeaderPragma]
xs

mkFileHeaderPragmaCollection :: GHC.HsModule' -> FileHeaderPragmaCollection
mkFileHeaderPragmaCollection :: HsModule' -> FileHeaderPragmaCollection
mkFileHeaderPragmaCollection =
  [FileHeaderPragma] -> FileHeaderPragmaCollection
FileHeaderPragmaCollection
    ([FileHeaderPragma] -> FileHeaderPragmaCollection)
-> (HsModule' -> [FileHeaderPragma])
-> HsModule'
-> FileHeaderPragmaCollection
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (EpaCommentTok -> Maybe FileHeaderPragma)
-> [EpaCommentTok] -> [FileHeaderPragma]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe EpaCommentTok -> Maybe FileHeaderPragma
mkFileHeaderPragma
    ([EpaCommentTok] -> [FileHeaderPragma])
-> (HsModule' -> [EpaCommentTok])
-> HsModule'
-> [FileHeaderPragma]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HsModule' -> [EpaCommentTok]
collectBlockComments

hasPragmas :: FileHeaderPragmaCollection -> Bool
hasPragmas :: FileHeaderPragmaCollection -> Bool
hasPragmas (FileHeaderPragmaCollection [FileHeaderPragma]
xs) = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [FileHeaderPragma] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FileHeaderPragma]
xs

collectBlockComments :: GHC.HsModule' -> [GHC.EpaCommentTok]
collectBlockComments :: HsModule' -> [EpaCommentTok]
collectBlockComments = (EpaCommentTok -> Bool) -> GenericQ [EpaCommentTok]
forall r. Typeable r => (r -> Bool) -> GenericQ [r]
listify EpaCommentTok -> Bool
isBlockComment (EpAnn AnnsModule -> [EpaCommentTok])
-> (HsModule' -> EpAnn AnnsModule) -> HsModule' -> [EpaCommentTok]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HsModule' -> EpAnn AnnsModule
GHC.getModuleAnn

-- | Checks if the given comment is a block one.
isBlockComment :: GHC.EpaCommentTok -> Bool
isBlockComment :: EpaCommentTok -> Bool
isBlockComment GHC.EpaBlockComment {} = Bool
True
isBlockComment EpaCommentTok
_ = Bool
False