module OccName (
NameSpace,
nameSpacesRelated,
tcName, clsName, tcClsName, dataName, varName,
tvName, srcDataName,
pprNameSpace, pprNonVarNameSpace, pprNameSpaceBrief,
OccName,
pprOccName,
mkOccName, mkOccNameFS,
mkVarOcc, mkVarOccFS,
mkDataOcc, mkDataOccFS,
mkTyVarOcc, mkTyVarOccFS,
mkTcOcc, mkTcOccFS,
mkClsOcc, mkClsOccFS,
mkDFunOcc,
setOccNameSpace,
demoteOccName,
HasOccName(..),
isDerivedOccName,
mkDataConWrapperOcc, mkWorkerOcc,
mkMatcherOcc, mkBuilderOcc,
mkDefaultMethodOcc,
mkGenDefMethodOcc,
mkDerivedTyConOcc, mkNewTyCoOcc, mkClassOpAuxOcc,
mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc,
mkClassDataConOcc, mkDictOcc, mkIPOcc,
mkSpecOcc, mkForeignExportOcc, mkRepEqOcc, mkGenOcc1, mkGenOcc2,
mkGenD, mkGenR, mkGen1R, mkGenRCo, mkGenC, mkGenS,
mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc,
mkSuperDictSelOcc, mkLocalOcc, mkMethodOcc, mkInstTyTcOcc,
mkInstTyCoOcc, mkEqPredCoOcc,
mkVectOcc, mkVectTyConOcc, mkVectDataConOcc, mkVectIsoOcc,
mkPDataTyConOcc, mkPDataDataConOcc,
mkPDatasTyConOcc, mkPDatasDataConOcc,
mkPReprTyConOcc,
mkPADFunOcc,
occNameFS, occNameString, occNameSpace,
isVarOcc, isTvOcc, isTcOcc, isDataOcc, isDataSymOcc, isSymOcc, isValOcc,
parenSymOcc, startsWithUnderscore,
isTcClsNameSpace, isTvNameSpace, isDataConNameSpace, isVarNameSpace, isValNameSpace,
OccEnv, emptyOccEnv, unitOccEnv, extendOccEnv, mapOccEnv,
lookupOccEnv, mkOccEnv, mkOccEnv_C, extendOccEnvList, elemOccEnv,
occEnvElts, foldOccEnv, plusOccEnv, plusOccEnv_C, extendOccEnv_C,
extendOccEnv_Acc, filterOccEnv, delListFromOccEnv, delFromOccEnv,
alterOccEnv, pprOccEnv,
OccSet, emptyOccSet, unitOccSet, mkOccSet, extendOccSet,
extendOccSetList,
unionOccSets, unionManyOccSets, minusOccSet, elemOccSet, occSetElts,
foldOccSet, isEmptyOccSet, intersectOccSet, intersectsOccSet,
TidyOccEnv, emptyTidyOccEnv, tidyOccName, initTidyOccEnv,
FastStringEnv, emptyFsEnv, lookupFsEnv, extendFsEnv, mkFsEnv
) where
import Util
import Unique
import DynFlags
import UniqFM
import UniqSet
import FastString
import Outputable
import Lexeme
import Binary
import Data.Char
import Data.Data
type FastStringEnv a = UniqFM a
emptyFsEnv :: FastStringEnv a
lookupFsEnv :: FastStringEnv a -> FastString -> Maybe a
extendFsEnv :: FastStringEnv a -> FastString -> a -> FastStringEnv a
mkFsEnv :: [(FastString,a)] -> FastStringEnv a
emptyFsEnv = emptyUFM
lookupFsEnv = lookupUFM
extendFsEnv = addToUFM
mkFsEnv = listToUFM
data NameSpace = VarName
| DataName
| TvName
| TcClsName
deriving( Eq, Ord )
tcName, clsName, tcClsName :: NameSpace
dataName, srcDataName :: NameSpace
tvName, varName :: NameSpace
tcName = TcClsName
clsName = TcClsName
tcClsName = TcClsName
dataName = DataName
srcDataName = DataName
tvName = TvName
varName = VarName
isDataConNameSpace :: NameSpace -> Bool
isDataConNameSpace DataName = True
isDataConNameSpace _ = False
isTcClsNameSpace :: NameSpace -> Bool
isTcClsNameSpace TcClsName = True
isTcClsNameSpace _ = False
isTvNameSpace :: NameSpace -> Bool
isTvNameSpace TvName = True
isTvNameSpace _ = False
isVarNameSpace :: NameSpace -> Bool
isVarNameSpace TvName = True
isVarNameSpace VarName = True
isVarNameSpace _ = False
isValNameSpace :: NameSpace -> Bool
isValNameSpace DataName = True
isValNameSpace VarName = True
isValNameSpace _ = False
pprNameSpace :: NameSpace -> SDoc
pprNameSpace DataName = ptext (sLit "data constructor")
pprNameSpace VarName = ptext (sLit "variable")
pprNameSpace TvName = ptext (sLit "type variable")
pprNameSpace TcClsName = ptext (sLit "type constructor or class")
pprNonVarNameSpace :: NameSpace -> SDoc
pprNonVarNameSpace VarName = empty
pprNonVarNameSpace ns = pprNameSpace ns
pprNameSpaceBrief :: NameSpace -> SDoc
pprNameSpaceBrief DataName = char 'd'
pprNameSpaceBrief VarName = char 'v'
pprNameSpaceBrief TvName = ptext (sLit "tv")
pprNameSpaceBrief TcClsName = ptext (sLit "tc")
demoteNameSpace :: NameSpace -> Maybe NameSpace
demoteNameSpace VarName = Nothing
demoteNameSpace DataName = Nothing
demoteNameSpace TvName = Nothing
demoteNameSpace TcClsName = Just DataName
data OccName = OccName
{ occNameSpace :: !NameSpace
, occNameFS :: !FastString
}
deriving Typeable
instance Eq OccName where
(OccName sp1 s1) == (OccName sp2 s2) = s1 == s2 && sp1 == sp2
instance Ord OccName where
compare (OccName sp1 s1) (OccName sp2 s2)
= (s1 `compare` s2) `thenCmp` (sp1 `compare` sp2)
instance Data OccName where
toConstr _ = abstractConstr "OccName"
gunfold _ _ = error "gunfold"
dataTypeOf _ = mkNoRepType "OccName"
instance HasOccName OccName where
occName = id
instance Outputable OccName where
ppr = pprOccName
instance OutputableBndr OccName where
pprBndr _ = ppr
pprInfixOcc n = pprInfixVar (isSymOcc n) (ppr n)
pprPrefixOcc n = pprPrefixVar (isSymOcc n) (ppr n)
pprOccName :: OccName -> SDoc
pprOccName (OccName sp occ)
= getPprStyle $ \ sty ->
if codeStyle sty
then ztext (zEncodeFS occ)
else pp_occ <> pp_debug sty
where
pp_debug sty | debugStyle sty = braces (pprNameSpaceBrief sp)
| otherwise = empty
pp_occ = sdocWithDynFlags $ \dflags ->
if gopt Opt_SuppressUniques dflags
then text (strip_th_unique (unpackFS occ))
else ftext occ
strip_th_unique ('[' : c : _) | isAlphaNum c = []
strip_th_unique (c : cs) = c : strip_th_unique cs
strip_th_unique [] = []
mkOccName :: NameSpace -> String -> OccName
mkOccName occ_sp str = OccName occ_sp (mkFastString str)
mkOccNameFS :: NameSpace -> FastString -> OccName
mkOccNameFS occ_sp fs = OccName occ_sp fs
mkVarOcc :: String -> OccName
mkVarOcc s = mkOccName varName s
mkVarOccFS :: FastString -> OccName
mkVarOccFS fs = mkOccNameFS varName fs
mkDataOcc :: String -> OccName
mkDataOcc = mkOccName dataName
mkDataOccFS :: FastString -> OccName
mkDataOccFS = mkOccNameFS dataName
mkTyVarOcc :: String -> OccName
mkTyVarOcc = mkOccName tvName
mkTyVarOccFS :: FastString -> OccName
mkTyVarOccFS fs = mkOccNameFS tvName fs
mkTcOcc :: String -> OccName
mkTcOcc = mkOccName tcName
mkTcOccFS :: FastString -> OccName
mkTcOccFS = mkOccNameFS tcName
mkClsOcc :: String -> OccName
mkClsOcc = mkOccName clsName
mkClsOccFS :: FastString -> OccName
mkClsOccFS = mkOccNameFS clsName
demoteOccName :: OccName -> Maybe OccName
demoteOccName (OccName space name) = do
space' <- demoteNameSpace space
return $ OccName space' name
nameSpacesRelated :: NameSpace -> NameSpace -> Bool
nameSpacesRelated ns1 ns2 = ns1 == ns2 || otherNameSpace ns1 == ns2
otherNameSpace :: NameSpace -> NameSpace
otherNameSpace VarName = DataName
otherNameSpace DataName = VarName
otherNameSpace TvName = TcClsName
otherNameSpace TcClsName = TvName
class HasOccName name where
occName :: name -> OccName
instance Uniquable OccName where
getUnique (OccName VarName fs) = mkVarOccUnique fs
getUnique (OccName DataName fs) = mkDataOccUnique fs
getUnique (OccName TvName fs) = mkTvOccUnique fs
getUnique (OccName TcClsName fs) = mkTcOccUnique fs
newtype OccEnv a = A (UniqFM a)
emptyOccEnv :: OccEnv a
unitOccEnv :: OccName -> a -> OccEnv a
extendOccEnv :: OccEnv a -> OccName -> a -> OccEnv a
extendOccEnvList :: OccEnv a -> [(OccName, a)] -> OccEnv a
lookupOccEnv :: OccEnv a -> OccName -> Maybe a
mkOccEnv :: [(OccName,a)] -> OccEnv a
mkOccEnv_C :: (a -> a -> a) -> [(OccName,a)] -> OccEnv a
elemOccEnv :: OccName -> OccEnv a -> Bool
foldOccEnv :: (a -> b -> b) -> b -> OccEnv a -> b
occEnvElts :: OccEnv a -> [a]
extendOccEnv_C :: (a->a->a) -> OccEnv a -> OccName -> a -> OccEnv a
extendOccEnv_Acc :: (a->b->b) -> (a->b) -> OccEnv b -> OccName -> a -> OccEnv b
plusOccEnv :: OccEnv a -> OccEnv a -> OccEnv a
plusOccEnv_C :: (a->a->a) -> OccEnv a -> OccEnv a -> OccEnv a
mapOccEnv :: (a->b) -> OccEnv a -> OccEnv b
delFromOccEnv :: OccEnv a -> OccName -> OccEnv a
delListFromOccEnv :: OccEnv a -> [OccName] -> OccEnv a
filterOccEnv :: (elt -> Bool) -> OccEnv elt -> OccEnv elt
alterOccEnv :: (Maybe elt -> Maybe elt) -> OccEnv elt -> OccName -> OccEnv elt
emptyOccEnv = A emptyUFM
unitOccEnv x y = A $ unitUFM x y
extendOccEnv (A x) y z = A $ addToUFM x y z
extendOccEnvList (A x) l = A $ addListToUFM x l
lookupOccEnv (A x) y = lookupUFM x y
mkOccEnv l = A $ listToUFM l
elemOccEnv x (A y) = elemUFM x y
foldOccEnv a b (A c) = foldUFM a b c
occEnvElts (A x) = eltsUFM x
plusOccEnv (A x) (A y) = A $ plusUFM x y
plusOccEnv_C f (A x) (A y) = A $ plusUFM_C f x y
extendOccEnv_C f (A x) y z = A $ addToUFM_C f x y z
extendOccEnv_Acc f g (A x) y z = A $ addToUFM_Acc f g x y z
mapOccEnv f (A x) = A $ mapUFM f x
mkOccEnv_C comb l = A $ addListToUFM_C comb emptyUFM l
delFromOccEnv (A x) y = A $ delFromUFM x y
delListFromOccEnv (A x) y = A $ delListFromUFM x y
filterOccEnv x (A y) = A $ filterUFM x y
alterOccEnv fn (A y) k = A $ alterUFM fn y k
instance Outputable a => Outputable (OccEnv a) where
ppr x = pprOccEnv ppr x
pprOccEnv :: (a -> SDoc) -> OccEnv a -> SDoc
pprOccEnv ppr_elt (A env) = pprUniqFM ppr_elt env
type OccSet = UniqSet OccName
emptyOccSet :: OccSet
unitOccSet :: OccName -> OccSet
mkOccSet :: [OccName] -> OccSet
extendOccSet :: OccSet -> OccName -> OccSet
extendOccSetList :: OccSet -> [OccName] -> OccSet
unionOccSets :: OccSet -> OccSet -> OccSet
unionManyOccSets :: [OccSet] -> OccSet
minusOccSet :: OccSet -> OccSet -> OccSet
elemOccSet :: OccName -> OccSet -> Bool
occSetElts :: OccSet -> [OccName]
foldOccSet :: (OccName -> b -> b) -> b -> OccSet -> b
isEmptyOccSet :: OccSet -> Bool
intersectOccSet :: OccSet -> OccSet -> OccSet
intersectsOccSet :: OccSet -> OccSet -> Bool
emptyOccSet = emptyUniqSet
unitOccSet = unitUniqSet
mkOccSet = mkUniqSet
extendOccSet = addOneToUniqSet
extendOccSetList = addListToUniqSet
unionOccSets = unionUniqSets
unionManyOccSets = unionManyUniqSets
minusOccSet = minusUniqSet
elemOccSet = elementOfUniqSet
occSetElts = uniqSetToList
foldOccSet = foldUniqSet
isEmptyOccSet = isEmptyUniqSet
intersectOccSet = intersectUniqSets
intersectsOccSet s1 s2 = not (isEmptyOccSet (s1 `intersectOccSet` s2))
occNameString :: OccName -> String
occNameString (OccName _ s) = unpackFS s
setOccNameSpace :: NameSpace -> OccName -> OccName
setOccNameSpace sp (OccName _ occ) = OccName sp occ
isVarOcc, isTvOcc, isTcOcc, isDataOcc :: OccName -> Bool
isVarOcc (OccName VarName _) = True
isVarOcc _ = False
isTvOcc (OccName TvName _) = True
isTvOcc _ = False
isTcOcc (OccName TcClsName _) = True
isTcOcc _ = False
isValOcc :: OccName -> Bool
isValOcc (OccName VarName _) = True
isValOcc (OccName DataName _) = True
isValOcc _ = False
isDataOcc (OccName DataName _) = True
isDataOcc _ = False
isDataSymOcc :: OccName -> Bool
isDataSymOcc (OccName DataName s) = isLexConSym s
isDataSymOcc _ = False
isSymOcc :: OccName -> Bool
isSymOcc (OccName DataName s) = isLexConSym s
isSymOcc (OccName TcClsName s) = isLexSym s
isSymOcc (OccName VarName s) = isLexSym s
isSymOcc (OccName TvName s) = isLexSym s
parenSymOcc :: OccName -> SDoc -> SDoc
parenSymOcc occ doc | isSymOcc occ = parens doc
| otherwise = doc
startsWithUnderscore :: OccName -> Bool
startsWithUnderscore occ = case occNameString occ of
('_' : _) -> True
_other -> False
mk_deriv :: NameSpace
-> String
-> String
-> OccName
mk_deriv occ_sp sys_prefix str = mkOccName occ_sp (sys_prefix ++ str)
isDerivedOccName :: OccName -> Bool
isDerivedOccName occ =
case occNameString occ of
'$':c:_ | isAlphaNum c -> True
':':c:_ | isAlphaNum c -> True
_other -> False
mkDataConWrapperOcc, mkWorkerOcc,
mkMatcherOcc, mkBuilderOcc,
mkDefaultMethodOcc,
mkGenDefMethodOcc, mkDerivedTyConOcc, mkClassDataConOcc, mkDictOcc,
mkIPOcc, mkSpecOcc, mkForeignExportOcc, mkRepEqOcc, mkGenOcc1, mkGenOcc2,
mkGenD, mkGenR, mkGen1R, mkGenRCo,
mkDataTOcc, mkDataCOcc, mkDataConWorkerOcc, mkNewTyCoOcc,
mkInstTyCoOcc, mkEqPredCoOcc, mkClassOpAuxOcc,
mkCon2TagOcc, mkTag2ConOcc, mkMaxTagOcc
:: OccName -> OccName
mkDataConWrapperOcc = mk_simple_deriv varName "$W"
mkWorkerOcc = mk_simple_deriv varName "$w"
mkMatcherOcc = mk_simple_deriv varName "$m"
mkBuilderOcc = mk_simple_deriv varName "$b"
mkDefaultMethodOcc = mk_simple_deriv varName "$dm"
mkGenDefMethodOcc = mk_simple_deriv varName "$gdm"
mkClassOpAuxOcc = mk_simple_deriv varName "$c"
mkDerivedTyConOcc = mk_simple_deriv tcName ":"
mkClassDataConOcc = mk_simple_deriv dataName "D:"
mkDictOcc = mk_simple_deriv varName "$d"
mkIPOcc = mk_simple_deriv varName "$i"
mkSpecOcc = mk_simple_deriv varName "$s"
mkForeignExportOcc = mk_simple_deriv varName "$f"
mkRepEqOcc = mk_simple_deriv tvName "$r"
mkNewTyCoOcc = mk_simple_deriv tcName "NTCo:"
mkInstTyCoOcc = mk_simple_deriv tcName "TFCo:"
mkEqPredCoOcc = mk_simple_deriv tcName "$co"
mkCon2TagOcc = mk_simple_deriv varName "$con2tag_"
mkTag2ConOcc = mk_simple_deriv varName "$tag2con_"
mkMaxTagOcc = mk_simple_deriv varName "$maxtag_"
mkGenOcc1 = mk_simple_deriv varName "$gfrom"
mkGenOcc2 = mk_simple_deriv varName "$gto"
mkGenD = mk_simple_deriv tcName "D1"
mkGenC :: OccName -> Int -> OccName
mkGenC occ m = mk_deriv tcName ("C1_" ++ show m) (occNameString occ)
mkGenS :: OccName -> Int -> Int -> OccName
mkGenS occ m n = mk_deriv tcName ("S1_" ++ show m ++ "_" ++ show n)
(occNameString occ)
mkGenR = mk_simple_deriv tcName "Rep_"
mkGen1R = mk_simple_deriv tcName "Rep1_"
mkGenRCo = mk_simple_deriv tcName "CoRep_"
mkDataTOcc = mk_simple_deriv varName "$t"
mkDataCOcc = mk_simple_deriv varName "$c"
mkVectOcc, mkVectTyConOcc, mkVectDataConOcc, mkVectIsoOcc,
mkPADFunOcc, mkPReprTyConOcc,
mkPDataTyConOcc, mkPDataDataConOcc,
mkPDatasTyConOcc, mkPDatasDataConOcc
:: Maybe String -> OccName -> OccName
mkVectOcc = mk_simple_deriv_with varName "$v"
mkVectTyConOcc = mk_simple_deriv_with tcName "V:"
mkVectDataConOcc = mk_simple_deriv_with dataName "VD:"
mkVectIsoOcc = mk_simple_deriv_with varName "$vi"
mkPADFunOcc = mk_simple_deriv_with varName "$pa"
mkPReprTyConOcc = mk_simple_deriv_with tcName "VR:"
mkPDataTyConOcc = mk_simple_deriv_with tcName "VP:"
mkPDatasTyConOcc = mk_simple_deriv_with tcName "VPs:"
mkPDataDataConOcc = mk_simple_deriv_with dataName "VPD:"
mkPDatasDataConOcc = mk_simple_deriv_with dataName "VPDs:"
mk_simple_deriv :: NameSpace -> String -> OccName -> OccName
mk_simple_deriv sp px occ = mk_deriv sp px (occNameString occ)
mk_simple_deriv_with :: NameSpace -> String -> Maybe String -> OccName -> OccName
mk_simple_deriv_with sp px Nothing occ = mk_deriv sp px (occNameString occ)
mk_simple_deriv_with sp px (Just with) occ = mk_deriv sp (px ++ with ++ "_") (occNameString occ)
mkDataConWorkerOcc datacon_occ = setOccNameSpace varName datacon_occ
mkSuperDictSelOcc :: Int
-> OccName
-> OccName
mkSuperDictSelOcc index cls_tc_occ
= mk_deriv varName "$p" (show index ++ occNameString cls_tc_occ)
mkLocalOcc :: Unique
-> OccName
-> OccName
mkLocalOcc uniq occ
= mk_deriv varName ("$L" ++ show uniq) (occNameString occ)
mkInstTyTcOcc :: String
-> OccSet
-> OccName
mkInstTyTcOcc str set =
chooseUniqueOcc tcName ('R' : ':' : str) set
mkDFunOcc :: String
-> Bool
-> OccSet
-> OccName
mkDFunOcc info_str is_boot set
= chooseUniqueOcc VarName (prefix ++ info_str) set
where
prefix | is_boot = "$fx"
| otherwise = "$f"
chooseUniqueOcc :: NameSpace -> String -> OccSet -> OccName
chooseUniqueOcc ns str set = loop (mkOccName ns str) (0::Int)
where
loop occ n
| occ `elemOccSet` set = loop (mkOccName ns (str ++ show n)) (n+1)
| otherwise = occ
mkMethodOcc :: OccName -> OccName
mkMethodOcc occ@(OccName VarName _) = occ
mkMethodOcc occ = mk_simple_deriv varName "$m" occ
type TidyOccEnv = UniqFM Int
emptyTidyOccEnv :: TidyOccEnv
emptyTidyOccEnv = emptyUFM
initTidyOccEnv :: [OccName] -> TidyOccEnv
initTidyOccEnv = foldl add emptyUFM
where
add env (OccName _ fs) = addToUFM env fs 1
tidyOccName :: TidyOccEnv -> OccName -> (TidyOccEnv, OccName)
tidyOccName env occ@(OccName occ_sp fs)
= case lookupUFM env fs of
Nothing -> (addToUFM env fs 1, occ)
Just {} -> case lookupUFM env base1 of
Nothing -> (addToUFM env base1 2, OccName occ_sp base1)
Just n -> find 1 n
where
base :: String
base = dropWhileEndLE isDigit (unpackFS fs)
base1 = mkFastString (base ++ "1")
find !k !n
= case lookupUFM env new_fs of
Just {} -> find (k+1 :: Int) (n+k)
Nothing -> (new_env, OccName occ_sp new_fs)
where
new_fs = mkFastString (base ++ show n)
new_env = addToUFM (addToUFM env new_fs 1) base1 (n+1)
instance Binary NameSpace where
put_ bh VarName = do
putByte bh 0
put_ bh DataName = do
putByte bh 1
put_ bh TvName = do
putByte bh 2
put_ bh TcClsName = do
putByte bh 3
get bh = do
h <- getByte bh
case h of
0 -> do return VarName
1 -> do return DataName
2 -> do return TvName
_ -> do return TcClsName
instance Binary OccName where
put_ bh (OccName aa ab) = do
put_ bh aa
put_ bh ab
get bh = do
aa <- get bh
ab <- get bh
return (OccName aa ab)