{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Types where
import qualified Control.DeepSeq as DeepSeq
import Control.DeepSeq (deepseq)
import qualified Data.String as String
import qualified Language.Haskell.Exts as Haskell
import qualified System.FilePath as FilePath
instance DeepSeq.NFData Haskell.Comment where
rnf (Haskell.Comment bool srcspan str) =
bool `seq` srcspan `seq` str `deepseq` ()
data ImportLine = ImportLine {
importDecl :: !ImportDecl
, importComments :: ![Comment]
, importSource :: !Source
} deriving (Show)
instance DeepSeq.NFData ImportLine where
rnf (ImportLine decl cmts source) =
decl `seq` cmts `deepseq` source `seq` ()
-- | Where did this import come from?
data Source = Local | Package deriving (Eq, Show)
-- | A Comment is associated with a particular import line.
data Comment = Comment !CmtPos !String deriving (Show)
data CmtPos = CmtAbove | CmtRight deriving (Show)
instance DeepSeq.NFData Comment where
rnf (Comment a b) = a `seq` b `seq` ()
-- | A parsed import line.
type ImportDecl = Haskell.ImportDecl Haskell.SrcSpanInfo
type Module = Haskell.Module Haskell.SrcSpanInfo
-- | A Qualification is a qualified name minus the actual name. So it should
-- be the tail of a ModuleName.
newtype Qualification = Qualification String
deriving (Eq, Ord, Show, String.IsString)
-- | An unqualified identifier.
type Name = Haskell.Name Haskell.SrcSpanInfo
newtype ModuleName = ModuleName String
deriving (Eq, Ord, Show, DeepSeq.NFData, String.IsString)
moduleName :: ModuleName -> String
moduleName (ModuleName n) = n
pathToModule :: FilePath -> ModuleName
pathToModule = ModuleName
. map (\c -> if c == '/' then '.' else c) . FilePath.dropExtension
moduleToPath :: ModuleName -> FilePath
moduleToPath (ModuleName name) =
map (\c -> if c == '.' then '/' else c) name ++ ".hs"
-- | Get the qualified name from an import.
importDeclQualification :: ImportDecl -> Qualification
importDeclQualification decl = moduleToQualification $
maybe (Haskell.importModule decl) id (Haskell.importAs decl)
-- | Extract the ModuleName from an ImportDecl.
importDeclModule :: ImportDecl -> ModuleName
importDeclModule imp = case Haskell.importModule imp of
Haskell.ModuleName _ s -> ModuleName s
importModule :: ImportLine -> ModuleName
importModule = importDeclModule . importDecl
-- | The parser represents the \'as\' part of an import as a ModuleName even
-- though it's actually a Qualification.
moduleToQualification :: Haskell.ModuleName Haskell.SrcSpanInfo
-> Qualification
moduleToQualification (Haskell.ModuleName _ s) = Qualification s