packages feed

fix-imports-2.1.0: src/Types.hs

{-# 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