    module Language.Haskell.Syntax.Module.Name where

    import Prelude

    import Data.Char (isAlphaNum)
    import Control.DeepSeq
    import qualified Text.ParserCombinators.ReadP as Parse
    import System.FilePath

    import GHC.Data.FastString

    -- | A ModuleName is essentially a simple string, e.g. @Data.List@.
    newtype ModuleName = ModuleName FastString deriving (Int -> ModuleName -> ShowS
    [ModuleName] -> ShowS
    ModuleName -> String
    (Int -> ModuleName -> ShowS)
    -> (ModuleName -> String)
    -> ([ModuleName] -> ShowS)
    -> Show ModuleName
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ModuleName -> ShowS
    showsPrec :: Int -> ModuleName -> ShowS
    $cshow :: ModuleName -> String
    show :: ModuleName -> String
    $cshowList :: [ModuleName] -> ShowS
    showList :: [ModuleName] -> ShowS
    Show, ModuleName -> ModuleName -> Bool
    (ModuleName -> ModuleName -> Bool)
    -> (ModuleName -> ModuleName -> Bool) -> Eq ModuleName
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: ModuleName -> ModuleName -> Bool
    == :: ModuleName -> ModuleName -> Bool
    $c/= :: ModuleName -> ModuleName -> Bool
    /= :: ModuleName -> ModuleName -> Bool
    Eq)

    instance Ord ModuleName where
      ModuleName
    nm1 compare :: ModuleName -> ModuleName -> Ordering
    `compare` ModuleName
    nm2 = ModuleName -> ModuleName -> Ordering
    stableModuleNameCmp ModuleName
    nm1 ModuleName
    nm2

    instance NFData ModuleName where
      rnf :: ModuleName -> ()
    rnf ModuleName
    x = ModuleName
    x ModuleName -> () -> ()
    forall a b. a -> b -> b
    `seq` ()

    stableModuleNameCmp :: ModuleName -> ModuleName -> Ordering
    -- ^ Compares module names lexically, rather than by their 'Unique's
    stableModuleNameCmp :: ModuleName -> ModuleName -> Ordering
    stableModuleNameCmp ModuleName
    n1 ModuleName
    n2 = ModuleName -> FastString
    moduleNameFS ModuleName
    n1 FastString -> FastString -> Ordering
    `lexicalCompareFS` ModuleName -> FastString
    moduleNameFS ModuleName
    n2

    moduleNameFS :: ModuleName -> FastString
    moduleNameFS :: ModuleName -> FastString
    moduleNameFS (ModuleName FastString
    mod) = FastString
    mod

    moduleNameString :: ModuleName -> String
    moduleNameString :: ModuleName -> String
    moduleNameString (ModuleName FastString
    mod) = FastString -> String
    unpackFS FastString
    mod

    mkModuleName :: String -> ModuleName
    mkModuleName :: String -> ModuleName
    mkModuleName String
    s = FastString -> ModuleName
    ModuleName (String -> FastString
    mkFastString String
    s)

    mkModuleNameFS :: FastString -> ModuleName
    mkModuleNameFS :: FastString -> ModuleName
    mkModuleNameFS FastString
    s = FastString -> ModuleName
    ModuleName FastString
    s

    -- |Returns the string version of the module name, with dots replaced by slashes.
    --
    moduleNameSlashes :: ModuleName -> String
    moduleNameSlashes :: ModuleName -> String
    moduleNameSlashes = ShowS
    dots_to_slashes ShowS -> (ModuleName -> String) -> ModuleName -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ModuleName -> String
    moduleNameString
      where dots_to_slashes :: ShowS
    dots_to_slashes = (Char -> Char) -> ShowS
    forall a b. (a -> b) -> [a] -> [b]
    map (\Char
    c -> if Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '.' then Char
    pathSeparator else Char
    c)

    -- |Returns the string version of the module name, with dots replaced by colons.
    --
    moduleNameColons :: ModuleName -> String
    moduleNameColons :: ModuleName -> String
    moduleNameColons = ShowS
    dots_to_colons ShowS -> (ModuleName -> String) -> ModuleName -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ModuleName -> String
    moduleNameString
      where dots_to_colons :: ShowS
    dots_to_colons = (Char -> Char) -> ShowS
    forall a b. (a -> b) -> [a] -> [b]
    map (\Char
    c -> if Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '.' then Char
    ':' else Char
    c)

    parseModuleName :: Parse.ReadP ModuleName
    parseModuleName :: ReadP ModuleName
    parseModuleName = (String -> ModuleName) -> ReadP String -> ReadP ModuleName
    forall a b. (a -> b) -> ReadP a -> ReadP b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap String -> ModuleName
    mkModuleName
                    (ReadP String -> ReadP ModuleName)
    -> ReadP String -> ReadP ModuleName
    forall a b. (a -> b) -> a -> b
    $ (Char -> Bool) -> ReadP String
    Parse.munch1 (\Char
    c -> Char -> Bool
    isAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c Char -> String -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` String
    "_.'")