{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RecordWildCards   #-}
{-# LANGUAGE TypeFamilies      #-}

{-
(c) The University of Glasgow 2006
(c) The GRASP/AQUA Project, Glasgow University, 1992-1998

\section[Name]{@Name@: to transmit name info from renamer to typechecker}
-}

-- |
-- #name_types#
-- GHC uses several kinds of name internally:
--
-- * 'GHC.Types.Name.Occurrence.OccName': see "GHC.Types.Name.Occurrence#name_types"
--
-- * 'GHC.Types.Name.Reader.RdrName': see "GHC.Types.Name.Reader#name_types"
--
-- * 'GHC.Types.Name.Name' is the type of names that have had their scoping and
--   binding resolved. They have an 'OccName' but also a 'GHC.Types.Unique.Unique'
--   that disambiguates Names that have the same 'OccName' and indeed is used for all
--   'Name' comparison. Names also contain information about where they originated
--   from, see "GHC.Types.Name#name_sorts"
--
-- * 'GHC.Types.Id.Id': see "GHC.Types.Id#name_types"
--
-- * 'GHC.Types.Var.Var': see "GHC.Types.Var#name_types"
--
-- #name_sorts#
-- Names are one of:
--
--  * External, if they name things declared in other modules. Some external
--    Names are wired in, i.e. they name primitives defined in the compiler itself
--
--  * Internal, if they name things in the module being compiled. Some internal
--    Names are system names, if they are names manufactured by the compiler

module GHC.Types.Name (
        -- * The main types
        Name,                                   -- Abstract
        BuiltInSyntax(..),

        -- ** Creating 'Name's
        mkSystemName, mkSystemNameAt,
        mkInternalName, mkClonedInternalName, mkDerivedInternalName,
        mkSystemVarName, mkSysTvName,
        mkFCallName,
        mkExternalName, mkWiredInName,

        -- ** Manipulating and deconstructing 'Name's
        nameUnique, setNameUnique,
        nameOccName, nameNameSpace, nameModule, nameModule_maybe,
        setNameLoc,
        tidyNameOcc,
        localiseName,
        namePun_maybe,

        pprName,
        nameSrcLoc, nameSrcSpan, pprNameDefnLoc, pprDefinedAt,
        pprFullName, pprTickyName,

        -- ** Predicates on 'Name's
        isSystemName, isInternalName, isExternalName,
        isTyVarName, isTyConName, isDataConName,
        isValName, isVarName, isDynLinkName,
        isWiredInName, isWiredIn, isBuiltInSyntax,
        isHoleName,
        wiredInNameTyThing_maybe,
        nameIsLocalOrFrom, nameIsExternalOrFrom, nameIsHomePackage,
        nameIsHomePackageImport, nameIsFromExternalPackage,
        stableNameCmp,

        -- * Class 'NamedThing' and overloaded friends
        NamedThing(..),
        getSrcLoc, getSrcSpan, getOccString, getOccFS,

        pprInfixName, pprPrefixName, pprModulePrefix, pprNameUnqualified,
        nameStableString,

        -- Re-export the OccName stuff
        module GHC.Types.Name.Occurrence
    ) where

import GHC.Prelude

import {-# SOURCE #-} GHC.Types.TyThing ( TyThing )
import {-# SOURCE #-} GHC.Builtin.Types ( listTyCon )

import GHC.Platform
import GHC.Types.Name.Occurrence
import GHC.Unit.Module
import GHC.Unit.Home
import GHC.Types.SrcLoc
import GHC.Types.Unique
import GHC.Utils.Misc
import GHC.Data.Maybe
import GHC.Utils.Binary
import GHC.Data.FastString
import GHC.Utils.Outputable
import GHC.Utils.Panic

import Control.DeepSeq
import Data.Data
import qualified Data.Semigroup as S

{-
************************************************************************
*                                                                      *
\subsection[Name-datatype]{The @Name@ datatype, and name construction}
*                                                                      *
************************************************************************
-}

-- | A unique, unambiguous name for something, containing information about where
-- that thing originated.
data Name = Name
  { Name -> NameSort
n_sort :: NameSort
    -- ^ What sort of name it is

  , Name -> OccName
n_occ  :: OccName
    -- ^ Its occurrence name.
    --
    -- NOTE: kept lazy to allow known names to be known constructor applications
    -- and to inline better. See Note [Fast comparison for built-in Names]

  , Name -> Unique
n_uniq :: {-# UNPACK #-} !Unique
    -- ^ Its unique.

  , Name -> SrcSpan
n_loc  :: !SrcSpan
    -- ^ Definition site
    --
    -- NOTE: we make the n_loc field strict to eliminate some potential
    -- (and real!) space leaks, due to the fact that we don't look at
    -- the SrcLoc in a Name all that often.
  }

-- See Note [About the NameSorts]
data NameSort
  = External Module

  | WiredIn Module TyThing BuiltInSyntax
        -- A variant of External, for wired-in things

  | Internal            -- A user-defined Id or TyVar
                        -- defined in the module being compiled

  | System              -- A system-defined Id or TyVar.  Typically the
                        -- OccName is very uninformative (like 's')

instance Outputable NameSort where
  ppr :: NameSort -> SDoc
ppr (External Module
_)    = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"external"
  ppr (WiredIn Module
_ TyThing
_ BuiltInSyntax
_) = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"wired-in"
  ppr  NameSort
Internal       = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"internal"
  ppr  NameSort
System         = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"system"

instance NFData Name where
  rnf :: Name -> ()
rnf Name{OccName
Unique
SrcSpan
NameSort
n_sort :: Name -> NameSort
n_occ :: Name -> OccName
n_uniq :: Name -> Unique
n_loc :: Name -> SrcSpan
n_sort :: NameSort
n_occ :: OccName
n_uniq :: Unique
n_loc :: SrcSpan
..} = NameSort -> ()
forall a. NFData a => a -> ()
rnf NameSort
n_sort

instance NFData NameSort where
  rnf :: NameSort -> ()
rnf (External Module
m) = Module -> ()
forall a. NFData a => a -> ()
rnf Module
m
  rnf (WiredIn Module
m TyThing
t BuiltInSyntax
b) = Module -> ()
forall a. NFData a => a -> ()
rnf Module
m () -> () -> ()
forall a b. a -> b -> b
`seq` TyThing
t TyThing -> () -> ()
forall a b. a -> b -> b
`seq` BuiltInSyntax
b BuiltInSyntax -> () -> ()
forall a b. a -> b -> b
`seq` ()
    -- XXX this is a *lie*, we're not going to rnf the TyThing, but
    -- since the TyThings for WiredIn Names are all static they can't
    -- be hiding space leaks or errors.
  rnf NameSort
Internal = ()
  rnf NameSort
System = ()

-- | BuiltInSyntax is for things like @(:)@, @[]@ and tuples,
-- which have special syntactic forms.  They aren't in scope
-- as such.
data BuiltInSyntax = BuiltInSyntax | UserSyntax

{-
Note [Fast comparison for built-in Names]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Consider this wired-in Name in GHC.Builtin.Names:

   int8TyConName = tcQual gHC_INT  (fsLit "Int8")  int8TyConKey

Ultimately this turns into something like:

   int8TyConName = Name gHC_INT (mkOccName ..."Int8") int8TyConKey

So a comparison like `x == int8TyConName` will turn into `getUnique x ==
int8TyConKey`, nice and efficient.  But if the `n_occ` field is strict, that
definition will look like:

   int8TyCOnName = case (mkOccName..."Int8") of occ ->
                   Name gHC_INT occ int8TyConKey

and now the comparison will not optimise.  This matters even more when there are
numerous comparisons (see #19386):

if | tc == int8TyCon  -> ...
   | tc == int16TyCon -> ...
   ...etc...

when we would like to get a single multi-branched case.

TL;DR: we make the `n_occ` field lazy.
-}

{-
Note [About the NameSorts]
~~~~~~~~~~~~~~~~~~~~~~~~~~

1.  Initially, top-level Ids (including locally-defined ones) get External names,
    and all other local Ids get Internal names

2.  In any invocation of GHC, an External Name for "M.x" has one and only one
    unique.  This unique association is ensured via the Name Cache;
    see Note [The Name Cache] in GHC.Iface.Env.

3.  Things with a External name are given C static labels, so they finally
    appear in the .o file's symbol table.  They appear in the symbol table
    in the form M.n.  If originally-local things have this property they
    must be made @External@ first.

4.  In the tidy-core phase, a External that is not visible to an importer
    is changed to Internal, and a Internal that is visible is changed to External

5.  A System Name differs in the following ways:
        a) has unique attached when printing dumps
        b) unifier eliminates sys tyvars in favour of user provs where possible

    Before anything gets printed in interface files or output code, it's
    fed through a 'tidy' processor, which zaps the OccNames to have
    unique names; and converts all sys-locals to user locals
    If any desugarer sys-locals have survived that far, they get changed to
    "ds1", "ds2", etc.

Built-in syntax => It's a syntactic form, not "in scope" (e.g. [])

Wired-in thing  => The thing (Id, TyCon) is fully known to the compiler,
                   not read from an interface file.
                   E.g. Bool, True, Int, Float, and many others

All built-in syntax is for wired-in things.
-}

instance HasOccName Name where
  occName :: Name -> OccName
occName = Name -> OccName
nameOccName

nameUnique              :: Name -> Unique
nameOccName             :: Name -> OccName
nameNameSpace           :: Name -> NameSpace
nameModule              :: HasDebugCallStack => Name -> Module
nameSrcLoc              :: Name -> SrcLoc
nameSrcSpan             :: Name -> SrcSpan

nameUnique :: Name -> Unique
nameUnique    Name
name = Name -> Unique
n_uniq Name
name
nameOccName :: Name -> OccName
nameOccName   Name
name = Name -> OccName
n_occ  Name
name
nameNameSpace :: Name -> NameSpace
nameNameSpace Name
name = OccName -> NameSpace
occNameSpace (Name -> OccName
n_occ Name
name)
nameSrcLoc :: Name -> SrcLoc
nameSrcLoc    Name
name = SrcSpan -> SrcLoc
srcSpanStart (Name -> SrcSpan
n_loc Name
name)
nameSrcSpan :: Name -> SrcSpan
nameSrcSpan   Name
name = Name -> SrcSpan
n_loc  Name
name

{-
************************************************************************
*                                                                      *
\subsection{Predicates on names}
*                                                                      *
************************************************************************
-}

isInternalName    :: Name -> Bool
isExternalName    :: Name -> Bool
isSystemName      :: Name -> Bool
isWiredInName     :: Name -> Bool

isWiredInName :: Name -> Bool
isWiredInName (Name {n_sort :: Name -> NameSort
n_sort = WiredIn Module
_ TyThing
_ BuiltInSyntax
_}) = Bool
True
isWiredInName Name
_                               = Bool
False

isWiredIn :: NamedThing thing => thing -> Bool
isWiredIn :: forall thing. NamedThing thing => thing -> Bool
isWiredIn = Name -> Bool
isWiredInName (Name -> Bool) -> (thing -> Name) -> thing -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. thing -> Name
forall a. NamedThing a => a -> Name
getName

wiredInNameTyThing_maybe :: Name -> Maybe TyThing
wiredInNameTyThing_maybe :: Name -> Maybe TyThing
wiredInNameTyThing_maybe (Name {n_sort :: Name -> NameSort
n_sort = WiredIn Module
_ TyThing
thing BuiltInSyntax
_}) = TyThing -> Maybe TyThing
forall a. a -> Maybe a
Just TyThing
thing
wiredInNameTyThing_maybe Name
_                                   = Maybe TyThing
forall a. Maybe a
Nothing

isBuiltInSyntax :: Name -> Bool
isBuiltInSyntax :: Name -> Bool
isBuiltInSyntax (Name {n_sort :: Name -> NameSort
n_sort = WiredIn Module
_ TyThing
_ BuiltInSyntax
BuiltInSyntax}) = Bool
True
isBuiltInSyntax Name
_                                           = Bool
False

isExternalName :: Name -> Bool
isExternalName (Name {n_sort :: Name -> NameSort
n_sort = External Module
_})    = Bool
True
isExternalName (Name {n_sort :: Name -> NameSort
n_sort = WiredIn Module
_ TyThing
_ BuiltInSyntax
_}) = Bool
True
isExternalName Name
_                               = Bool
False

isInternalName :: Name -> Bool
isInternalName Name
name = Bool -> Bool
not (Name -> Bool
isExternalName Name
name)

isHoleName :: Name -> Bool
isHoleName :: Name -> Bool
isHoleName = Module -> Bool
forall u. GenModule (GenUnit u) -> Bool
isHoleModule (Module -> Bool) -> (Name -> Module) -> Name -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (() :: Constraint) => Name -> Module
Name -> Module
nameModule

-- | Will the 'Name' come from a dynamically linked package?
isDynLinkName :: Platform -> Module -> Name -> Bool
isDynLinkName :: Platform -> Module -> Name -> Bool
isDynLinkName Platform
platform Module
this_mod Name
name
  | Just Module
mod <- Name -> Maybe Module
nameModule_maybe Name
name
    -- Issue #8696 - when GHC is dynamically linked, it will attempt
    -- to load the dynamic dependencies of object files at compile
    -- time for things like QuasiQuotes or
    -- TemplateHaskell. Unfortunately, this interacts badly with
    -- intra-package linking, because we don't generate indirect
    -- (dynamic) symbols for intra-package calls. This means that if a
    -- module with an intra-package call is loaded without its
    -- dependencies, then GHC fails to link.
    --
    -- In the mean time, always force dynamic indirections to be
    -- generated: when the module name isn't the module being
    -- compiled, references are dynamic.
    = case Platform -> OS
platformOS Platform
platform of
        -- On Windows the hack for #8696 makes it unlinkable.
        -- As the entire setup of the code from Cmm down to the RTS expects
        -- the use of trampolines for the imported functions only when
        -- doing intra-package linking, e.g. referring to a symbol defined in the same
        -- package should not use a trampoline.
        -- I much rather have dynamic TH not supported than the entire Dynamic linking
        -- not due to a hack.
        -- Also not sure this would break on Windows anyway.
        OS
OSMinGW32 -> Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
mod Unit -> Unit -> Bool
forall a. Eq a => a -> a -> Bool
/= Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
this_mod

        -- For the other platforms, still perform the hack
        OS
_         -> Module
mod Module -> Module -> Bool
forall a. Eq a => a -> a -> Bool
/= Module
this_mod

  | Bool
otherwise = Bool
False  -- no, it is not even an external name


nameModule :: (() :: Constraint) => Name -> Module
nameModule Name
name =
  Name -> Maybe Module
nameModule_maybe Name
name Maybe Module -> Module -> Module
forall a. Maybe a -> a -> a
`orElse`
  String -> SDoc -> Module
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"nameModule" (NameSort -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Name -> NameSort
n_sort Name
name) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
name)

nameModule_maybe :: Name -> Maybe Module
nameModule_maybe :: Name -> Maybe Module
nameModule_maybe (Name { n_sort :: Name -> NameSort
n_sort = External Module
mod})    = Module -> Maybe Module
forall a. a -> Maybe a
Just Module
mod
nameModule_maybe (Name { n_sort :: Name -> NameSort
n_sort = WiredIn Module
mod TyThing
_ BuiltInSyntax
_}) = Module -> Maybe Module
forall a. a -> Maybe a
Just Module
mod
nameModule_maybe Name
_                                  = Maybe Module
forall a. Maybe a
Nothing

is_interactive_or_from :: Module -> Module -> Bool
is_interactive_or_from :: Module -> Module -> Bool
is_interactive_or_from Module
from Module
mod = Module
from Module -> Module -> Bool
forall a. Eq a => a -> a -> Bool
== Module
mod Bool -> Bool -> Bool
|| Module -> Bool
isInteractiveModule Module
mod

-- Return the pun for a name if available.
-- Used for pretty-printing under ListTuplePuns.
namePun_maybe :: Name -> Maybe FastString
namePun_maybe :: Name -> Maybe FastString
namePun_maybe Name
name | Name -> Unique
forall a. Uniquable a => a -> Unique
getUnique Name
name Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Unique
forall a. Uniquable a => a -> Unique
getUnique TyCon
listTyCon = FastString -> Maybe FastString
forall a. a -> Maybe a
Just (String -> FastString
fsLit String
"[]")
namePun_maybe Name
_ = Maybe FastString
forall a. Maybe a
Nothing

nameIsLocalOrFrom :: Module -> Name -> Bool
-- ^ Returns True if the name is
--   (a) Internal
--   (b) External but from the specified module
--   (c) External but from the 'interactive' package
--
-- The key idea is that
--    False means: the entity is defined in some other module
--                 you can find the details (type, fixity, instances)
--                     in some interface file
--                 those details will be stored in the EPT or HPT
--
--    True means:  the entity is defined in this module or earlier in
--                     the GHCi session
--                 you can find details (type, fixity, instances) in the
--                     TcGblEnv or TcLclEnv
--
-- The isInteractiveModule part is because successive interactions of a GHCi session
-- each give rise to a fresh module (Ghci1, Ghci2, etc), but they all come
-- from the magic 'interactive' package; and all the details are kept in the
-- TcLclEnv, TcGblEnv, NOT in the HPT or EPT.
-- See Note [The interactive package] in "GHC.Runtime.Context"

nameIsLocalOrFrom :: Module -> Name -> Bool
nameIsLocalOrFrom Module
from Name
name
  | Just Module
mod <- Name -> Maybe Module
nameModule_maybe Name
name = Module -> Module -> Bool
is_interactive_or_from Module
from Module
mod
  | Bool
otherwise                         = Bool
True

nameIsExternalOrFrom :: Module -> Name -> Bool
-- ^ Returns True if the name is external or from the 'interactive' package
-- See documentation of `nameIsLocalOrFrom` function
nameIsExternalOrFrom :: Module -> Name -> Bool
nameIsExternalOrFrom Module
from Name
name
  | Just Module
mod <- Name -> Maybe Module
nameModule_maybe Name
name = Module -> Module -> Bool
is_interactive_or_from Module
from Module
mod
  | Bool
otherwise                         = Bool
False

nameIsHomePackage :: Module -> Name -> Bool
-- True if the Name is defined in module of this package
nameIsHomePackage :: Module -> Name -> Bool
nameIsHomePackage Module
this_mod
  = \Name
nm -> case Name -> NameSort
n_sort Name
nm of
              External Module
nm_mod    -> Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
nm_mod Unit -> Unit -> Bool
forall a. Eq a => a -> a -> Bool
== Unit
this_pkg
              WiredIn Module
nm_mod TyThing
_ BuiltInSyntax
_ -> Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
nm_mod Unit -> Unit -> Bool
forall a. Eq a => a -> a -> Bool
== Unit
this_pkg
              NameSort
Internal -> Bool
True
              NameSort
System   -> Bool
False
  where
    this_pkg :: Unit
this_pkg = Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
this_mod

nameIsHomePackageImport :: Module -> Name -> Bool
-- True if the Name is defined in module of this package
-- /other than/ the this_mod
nameIsHomePackageImport :: Module -> Name -> Bool
nameIsHomePackageImport Module
this_mod
  = \Name
nm -> case Name -> Maybe Module
nameModule_maybe Name
nm of
              Maybe Module
Nothing -> Bool
False
              Just Module
nm_mod -> Module
nm_mod Module -> Module -> Bool
forall a. Eq a => a -> a -> Bool
/= Module
this_mod
                          Bool -> Bool -> Bool
&& Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
nm_mod Unit -> Unit -> Bool
forall a. Eq a => a -> a -> Bool
== Unit
this_pkg
  where
    this_pkg :: Unit
this_pkg = Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
this_mod

-- | Returns True if the Name comes from some other package: neither this
-- package nor the interactive package.
nameIsFromExternalPackage :: HomeUnit -> Name -> Bool
nameIsFromExternalPackage :: HomeUnit -> Name -> Bool
nameIsFromExternalPackage HomeUnit
home_unit Name
name
  | Just Module
mod <- Name -> Maybe Module
nameModule_maybe Name
name
  , HomeUnit -> Module -> Bool
notHomeModule HomeUnit
home_unit Module
mod   -- Not the current unit
  , Bool -> Bool
not (Module -> Bool
isInteractiveModule Module
mod) -- Not the 'interactive' package
  = Bool
True
  | Bool
otherwise
  = Bool
False

isTyVarName :: Name -> Bool
isTyVarName :: Name -> Bool
isTyVarName Name
name = OccName -> Bool
isTvOcc (Name -> OccName
nameOccName Name
name)

isTyConName :: Name -> Bool
isTyConName :: Name -> Bool
isTyConName Name
name = OccName -> Bool
isTcOcc (Name -> OccName
nameOccName Name
name)

isDataConName :: Name -> Bool
isDataConName :: Name -> Bool
isDataConName Name
name = OccName -> Bool
isDataOcc (Name -> OccName
nameOccName Name
name)

isValName :: Name -> Bool
isValName :: Name -> Bool
isValName Name
name = OccName -> Bool
isValOcc (Name -> OccName
nameOccName Name
name)

isVarName :: Name -> Bool
isVarName :: Name -> Bool
isVarName = OccName -> Bool
isVarOcc (OccName -> Bool) -> (Name -> OccName) -> Name -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> OccName
nameOccName

isSystemName :: Name -> Bool
isSystemName (Name {n_sort :: Name -> NameSort
n_sort = NameSort
System}) = Bool
True
isSystemName Name
_                        = Bool
False

{-
************************************************************************
*                                                                      *
\subsection{Making names}
*                                                                      *
************************************************************************
-}

-- | Create a name which is (for now at least) local to the current module and hence
-- does not need a 'Module' to disambiguate it from other 'Name's
mkInternalName :: Unique -> OccName -> SrcSpan -> Name
mkInternalName :: Unique -> OccName -> SrcSpan -> Name
mkInternalName Unique
uniq OccName
occ SrcSpan
loc = Name { n_uniq :: Unique
n_uniq = Unique
uniq
                                   , n_sort :: NameSort
n_sort = NameSort
Internal
                                   , n_occ :: OccName
n_occ = OccName
occ
                                   , n_loc :: SrcSpan
n_loc = SrcSpan
loc }
        -- NB: You might worry that after lots of huffing and
        -- puffing we might end up with two local names with distinct
        -- uniques, but the same OccName.  Indeed we can, but that's ok
        --      * the insides of the compiler don't care: they use the Unique
        --      * when printing for -ddump-xxx you can switch on -dppr-debug to get the
        --        uniques if you get confused
        --      * for interface files we tidyCore first, which makes
        --        the OccNames distinct when they need to be

mkClonedInternalName :: Unique -> Name -> Name
mkClonedInternalName :: Unique -> Name -> Name
mkClonedInternalName Unique
uniq (Name { n_occ :: Name -> OccName
n_occ = OccName
occ, n_loc :: Name -> SrcSpan
n_loc = SrcSpan
loc })
  = Name { n_uniq :: Unique
n_uniq = Unique
uniq, n_sort :: NameSort
n_sort = NameSort
Internal
         , n_occ :: OccName
n_occ = OccName
occ, n_loc :: SrcSpan
n_loc = SrcSpan
loc }

mkDerivedInternalName :: (OccName -> OccName) -> Unique -> Name -> Name
mkDerivedInternalName :: (OccName -> OccName) -> Unique -> Name -> Name
mkDerivedInternalName OccName -> OccName
derive_occ Unique
uniq (Name { n_occ :: Name -> OccName
n_occ = OccName
occ, n_loc :: Name -> SrcSpan
n_loc = SrcSpan
loc })
  = Name { n_uniq :: Unique
n_uniq = Unique
uniq, n_sort :: NameSort
n_sort = NameSort
Internal
         , n_occ :: OccName
n_occ = OccName -> OccName
derive_occ OccName
occ, n_loc :: SrcSpan
n_loc = SrcSpan
loc }

-- | Create a name which definitely originates in the given module
mkExternalName :: Unique -> Module -> OccName -> SrcSpan -> Name
{-# INLINE mkExternalName #-}
-- WATCH OUT! External Names should be in the Name Cache
-- (see Note [The Name Cache] in GHC.Iface.Env), so don't just call mkExternalName
-- with some fresh unique without populating the Name Cache
mkExternalName :: Unique -> Module -> OccName -> SrcSpan -> Name
mkExternalName Unique
uniq Module
mod OccName
occ SrcSpan
loc
  = Name { n_uniq :: Unique
n_uniq = Unique
uniq, n_sort :: NameSort
n_sort = Module -> NameSort
External Module
mod,
           n_occ :: OccName
n_occ = OccName
occ, n_loc :: SrcSpan
n_loc = SrcSpan
loc }

-- | Create a name which is actually defined by the compiler itself
mkWiredInName :: Module -> OccName -> Unique -> TyThing -> BuiltInSyntax -> Name
{-# INLINE mkWiredInName #-}
mkWiredInName :: Module -> OccName -> Unique -> TyThing -> BuiltInSyntax -> Name
mkWiredInName Module
mod OccName
occ Unique
uniq TyThing
thing BuiltInSyntax
built_in
  = Name { n_uniq :: Unique
n_uniq = Unique
uniq,
           n_sort :: NameSort
n_sort = Module -> TyThing -> BuiltInSyntax -> NameSort
WiredIn Module
mod TyThing
thing BuiltInSyntax
built_in,
           n_occ :: OccName
n_occ = OccName
occ, n_loc :: SrcSpan
n_loc = SrcSpan
wiredInSrcSpan }

-- | Create a name brought into being by the compiler
mkSystemName :: Unique -> OccName -> Name
mkSystemName :: Unique -> OccName -> Name
mkSystemName Unique
uniq OccName
occ = Unique -> OccName -> SrcSpan -> Name
mkSystemNameAt Unique
uniq OccName
occ SrcSpan
noSrcSpan

mkSystemNameAt :: Unique -> OccName -> SrcSpan -> Name
mkSystemNameAt :: Unique -> OccName -> SrcSpan -> Name
mkSystemNameAt Unique
uniq OccName
occ SrcSpan
loc = Name { n_uniq :: Unique
n_uniq = Unique
uniq, n_sort :: NameSort
n_sort = NameSort
System
                                   , n_occ :: OccName
n_occ = OccName
occ, n_loc :: SrcSpan
n_loc = SrcSpan
loc }

mkSystemVarName :: Unique -> FastString -> Name
mkSystemVarName :: Unique -> FastString -> Name
mkSystemVarName Unique
uniq FastString
fs = Unique -> OccName -> Name
mkSystemName Unique
uniq (FastString -> OccName
mkVarOccFS FastString
fs)

mkSysTvName :: Unique -> FastString -> Name
mkSysTvName :: Unique -> FastString -> Name
mkSysTvName Unique
uniq FastString
fs = Unique -> OccName -> Name
mkSystemName Unique
uniq (FastString -> OccName
mkTyVarOccFS FastString
fs)

-- | Make a name for a foreign call
mkFCallName :: Unique -> FastString -> Name
mkFCallName :: Unique -> FastString -> Name
mkFCallName Unique
uniq FastString
str = Unique -> OccName -> SrcSpan -> Name
mkInternalName Unique
uniq (FastString -> OccName
mkVarOccFS FastString
str) SrcSpan
noSrcSpan
   -- The encoded string completely describes the ccall

-- When we renumber/rename things, we need to be
-- able to change a Name's Unique to match the cached
-- one in the thing it's the name of.  If you know what I mean.
setNameUnique :: Name -> Unique -> Name
setNameUnique :: Name -> Unique -> Name
setNameUnique Name
name Unique
uniq = Name
name {n_uniq = uniq}

-- This is used for hsigs: we want to use the name of the originally exported
-- entity, but edit the location to refer to the reexport site
setNameLoc :: Name -> SrcSpan -> Name
setNameLoc :: Name -> SrcSpan -> Name
setNameLoc Name
name SrcSpan
loc = Name
name {n_loc = loc}

tidyNameOcc :: Name -> OccName -> Name
-- We set the OccName of a Name when tidying
-- In doing so, we change System --> Internal, so that when we print
-- it we don't get the unique by default.  It's tidy now!
tidyNameOcc :: Name -> OccName -> Name
tidyNameOcc name :: Name
name@(Name { n_sort :: Name -> NameSort
n_sort = NameSort
System }) OccName
occ = Name
name { n_occ = occ, n_sort = Internal}
tidyNameOcc Name
name                            OccName
occ = Name
name { n_occ = occ }

-- | Make the 'Name' into an internal name, regardless of what it was to begin with
localiseName :: Name -> Name
localiseName :: Name -> Name
localiseName Name
n = Name
n { n_sort = Internal }

{-
************************************************************************
*                                                                      *
\subsection{Hashing and comparison}
*                                                                      *
************************************************************************
-}

cmpName :: Name -> Name -> Ordering
cmpName :: Name -> Name -> Ordering
cmpName Name
n1 Name
n2 = Name -> Unique
n_uniq Name
n1 Unique -> Unique -> Ordering
`nonDetCmpUnique` Name -> Unique
n_uniq Name
n2

-- | Compare Names lexicographically
-- This only works for Names that originate in the source code or have been
-- tidied.
stableNameCmp :: Name -> Name -> Ordering
stableNameCmp :: Name -> Name -> Ordering
stableNameCmp (Name { n_sort :: Name -> NameSort
n_sort = NameSort
s1, n_occ :: Name -> OccName
n_occ = OccName
occ1 })
              (Name { n_sort :: Name -> NameSort
n_sort = NameSort
s2, n_occ :: Name -> OccName
n_occ = OccName
occ2 })
  = NameSort -> NameSort -> Ordering
sort_cmp NameSort
s1 NameSort
s2 Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
S.<> OccName -> OccName -> Ordering
forall a. Ord a => a -> a -> Ordering
compare OccName
occ1 OccName
occ2
    -- The ordinary compare on OccNames is lexicographic
  where
    -- Later constructors are bigger
    sort_cmp :: NameSort -> NameSort -> Ordering
sort_cmp (External Module
m1) (External Module
m2)       = Module
m1 Module -> Module -> Ordering
`stableModuleCmp` Module
m2
    sort_cmp (External {}) NameSort
_                   = Ordering
LT
    sort_cmp (WiredIn {}) (External {})        = Ordering
GT
    sort_cmp (WiredIn Module
m1 TyThing
_ BuiltInSyntax
_) (WiredIn Module
m2 TyThing
_ BuiltInSyntax
_) = Module
m1 Module -> Module -> Ordering
`stableModuleCmp` Module
m2
    sort_cmp (WiredIn {})     NameSort
_                = Ordering
LT
    sort_cmp NameSort
Internal         (External {})    = Ordering
GT
    sort_cmp NameSort
Internal         (WiredIn {})     = Ordering
GT
    sort_cmp NameSort
Internal         NameSort
Internal         = Ordering
EQ
    sort_cmp NameSort
Internal         NameSort
System           = Ordering
LT
    sort_cmp NameSort
System           NameSort
System           = Ordering
EQ
    sort_cmp NameSort
System           NameSort
_                = Ordering
GT

{-
************************************************************************
*                                                                      *
\subsection[Name-instances]{Instance declarations}
*                                                                      *
************************************************************************
-}

-- | The same comments as for `Name`'s `Ord` instance apply.
instance Eq Name where
    Name
a == :: Name -> Name -> Bool
== Name
b = case (Name
a Name -> Name -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Name
b) of { Ordering
EQ -> Bool
True;  Ordering
_ -> Bool
False }
    Name
a /= :: Name -> Name -> Bool
/= Name
b = case (Name
a Name -> Name -> Ordering
forall a. Ord a => a -> a -> Ordering
`compare` Name
b) of { Ordering
EQ -> Bool
False; Ordering
_ -> Bool
True }

-- | __Caution__: This instance is implemented via `nonDetCmpUnique`, which
-- means that the ordering is not stable across deserialization or rebuilds.
--
-- See `nonDetCmpUnique` for further information, and trac #15240 for a bug
-- caused by improper use of this instance.

-- For a deterministic lexicographic ordering, use `stableNameCmp`.
instance Ord Name where
    compare :: Name -> Name -> Ordering
compare = Name -> Name -> Ordering
cmpName

instance Uniquable Name where
    getUnique :: Name -> Unique
getUnique = Name -> Unique
nameUnique

instance NamedThing Name where
    getName :: Name -> Name
getName Name
n = Name
n

instance Data Name where
  -- don't traverse?
  toConstr :: Name -> Constr
toConstr Name
_   = String -> Constr
abstractConstr String
"Name"
  gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Name
gunfold forall b r. Data b => c (b -> r) -> c r
_ forall r. r -> c r
_  = String -> Constr -> c Name
forall a. HasCallStack => String -> a
error String
"gunfold"
  dataTypeOf :: Name -> DataType
dataTypeOf Name
_ = String -> DataType
mkNoRepType String
"Name"

{-
************************************************************************
*                                                                      *
\subsection{Binary}
*                                                                      *
************************************************************************
-}

-- | Assumes that the 'Name' is a non-binding one. See
-- 'GHC.Iface.Syntax.putIfaceTopBndr' and 'GHC.Iface.Syntax.getIfaceTopBndr' for
-- serializing binding 'Name's. See 'UserData' for the rationale for this
-- distinction.
instance Binary Name where
   put_ :: BinHandle -> Name -> IO ()
put_ BinHandle
bh Name
name =
      case BinHandle -> UserData
getUserData BinHandle
bh of
        UserData{ ud_put_nonbinding_name :: UserData -> BinHandle -> Name -> IO ()
ud_put_nonbinding_name = BinHandle -> Name -> IO ()
put_name } -> BinHandle -> Name -> IO ()
put_name BinHandle
bh Name
name

   get :: BinHandle -> IO Name
get BinHandle
bh =
      case BinHandle -> UserData
getUserData BinHandle
bh of
        UserData { ud_get_name :: UserData -> BinHandle -> IO Name
ud_get_name = BinHandle -> IO Name
get_name } -> BinHandle -> IO Name
get_name BinHandle
bh

{-
************************************************************************
*                                                                      *
\subsection{Pretty printing}
*                                                                      *
************************************************************************
-}

instance Outputable Name where
    ppr :: Name -> SDoc
ppr Name
name = Name -> SDoc
forall doc. IsLine doc => Name -> doc
pprName Name
name

instance OutputableBndr Name where
    pprBndr :: BindingSite -> Name -> SDoc
pprBndr BindingSite
_ Name
name = Name -> SDoc
forall doc. IsLine doc => Name -> doc
pprName Name
name
    pprInfixOcc :: Name -> SDoc
pprInfixOcc  = Name -> SDoc
forall a. (Outputable a, NamedThing a) => a -> SDoc
pprInfixName
    pprPrefixOcc :: Name -> SDoc
pprPrefixOcc = Name -> SDoc
forall a. NamedThing a => a -> SDoc
pprPrefixName

pprName :: forall doc. IsLine doc => Name -> doc
pprName :: forall doc. IsLine doc => Name -> doc
pprName name :: Name
name@(Name {n_sort :: Name -> NameSort
n_sort = NameSort
sort, n_uniq :: Name -> Unique
n_uniq = Unique
uniq, n_occ :: Name -> OccName
n_occ = OccName
occ})
  = (SDocContext -> doc) -> doc
forall doc. IsOutput doc => (SDocContext -> doc) -> doc
docWithContext ((SDocContext -> doc) -> doc) -> (SDocContext -> doc) -> doc
forall a b. (a -> b) -> a -> b
$ \SDocContext
ctx ->
    let sty :: PprStyle
sty = SDocContext -> PprStyle
sdocStyle SDocContext
ctx
        debug :: Bool
debug = SDocContext -> Bool
sdocPprDebug SDocContext
ctx
        listTuplePuns :: Bool
listTuplePuns = SDocContext -> Bool
sdocListTuplePuns SDocContext
ctx
    in Bool -> Maybe FastString -> doc -> doc
handlePuns Bool
listTuplePuns (Name -> Maybe FastString
namePun_maybe Name
name) (doc -> doc) -> doc -> doc
forall a b. (a -> b) -> a -> b
$
    case NameSort
sort of
      WiredIn Module
mod TyThing
_ BuiltInSyntax
builtin   -> Bool
-> PprStyle
-> Unique
-> Module
-> OccName
-> Bool
-> BuiltInSyntax
-> doc
forall doc.
IsLine doc =>
Bool
-> PprStyle
-> Unique
-> Module
-> OccName
-> Bool
-> BuiltInSyntax
-> doc
pprExternal Bool
debug PprStyle
sty Unique
uniq Module
mod OccName
occ Bool
True  BuiltInSyntax
builtin
      External Module
mod            -> Bool
-> PprStyle
-> Unique
-> Module
-> OccName
-> Bool
-> BuiltInSyntax
-> doc
forall doc.
IsLine doc =>
Bool
-> PprStyle
-> Unique
-> Module
-> OccName
-> Bool
-> BuiltInSyntax
-> doc
pprExternal Bool
debug PprStyle
sty Unique
uniq Module
mod OccName
occ Bool
False BuiltInSyntax
UserSyntax
      NameSort
System                  -> Bool -> PprStyle -> Unique -> OccName -> doc
forall doc.
IsLine doc =>
Bool -> PprStyle -> Unique -> OccName -> doc
pprSystem   Bool
debug PprStyle
sty Unique
uniq OccName
occ
      NameSort
Internal                -> Bool -> PprStyle -> Unique -> OccName -> doc
forall doc.
IsLine doc =>
Bool -> PprStyle -> Unique -> OccName -> doc
pprInternal Bool
debug PprStyle
sty Unique
uniq OccName
occ
  where
    -- Print GHC.Types.List as [], etc.
    handlePuns :: Bool -> Maybe FastString -> doc -> doc
    handlePuns :: Bool -> Maybe FastString -> doc -> doc
handlePuns Bool
True (Just FastString
pun) doc
_ = FastString -> doc
forall doc. IsLine doc => FastString -> doc
ftext FastString
pun
    handlePuns Bool
_    Maybe FastString
_          doc
r = doc
r
{-# SPECIALISE pprName :: Name -> SDoc #-}
{-# SPECIALISE pprName :: Name -> HLine #-} -- see Note [SPECIALIZE to HDoc] in GHC.Utils.Outputable

-- | Print fully qualified name (with unit-id, module and unique)
pprFullName :: Module -> Name -> SDoc
pprFullName :: Module -> Name -> SDoc
pprFullName Module
this_mod Name{n_sort :: Name -> NameSort
n_sort = NameSort
sort, n_uniq :: Name -> Unique
n_uniq = Unique
uniq, n_occ :: Name -> OccName
n_occ = OccName
occ} =
  let mod :: Module
mod = case NameSort
sort of
        WiredIn  Module
m TyThing
_ BuiltInSyntax
_ -> Module
m
        External Module
m     -> Module
m
        NameSort
System         -> Module
this_mod
        NameSort
Internal       -> Module
this_mod
      in FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext (UnitId -> FastString
unitIdFS (Module -> UnitId
moduleUnitId Module
mod))
         SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
colon    SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext (ModuleName -> FastString
moduleNameFS (ModuleName -> FastString) -> ModuleName -> FastString
forall a b. (a -> b) -> a -> b
$ Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
mod)
         SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> SDoc
forall doc. IsLine doc => doc
dot      SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext (OccName -> FastString
occNameFS OccName
occ)
         SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> SDoc
forall doc. IsLine doc => Char -> doc
char Char
'_' SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> SDoc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
uniq


-- | Print a ticky ticky styled name
--
-- Module argument is the module to use for internal and system names. When
-- printing the name in a ticky profile, the module name is included even for
-- local things. However, ticky uses the format "x (M)" rather than "M.x".
-- Hence, this function provides a separation from normal styling.
pprTickyName :: Module -> Name -> SDoc
pprTickyName :: Module -> Name -> SDoc
pprTickyName Module
this_mod Name
name
  | Name -> Bool
isInternalName Name
name = Name -> SDoc
forall doc. IsLine doc => Name -> doc
pprName Name
name SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc
parens (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr Module
this_mod)
  | Bool
otherwise           = Name -> SDoc
forall doc. IsLine doc => Name -> doc
pprName Name
name

-- | Print the string of Name unqualifiedly directly.
pprNameUnqualified :: Name -> SDoc
pprNameUnqualified :: Name -> SDoc
pprNameUnqualified Name { n_occ :: Name -> OccName
n_occ = OccName
occ } = OccName -> SDoc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ

pprExternal :: IsLine doc => Bool -> PprStyle -> Unique -> Module -> OccName -> Bool -> BuiltInSyntax -> doc
pprExternal :: forall doc.
IsLine doc =>
Bool
-> PprStyle
-> Unique
-> Module
-> OccName
-> Bool
-> BuiltInSyntax
-> doc
pprExternal Bool
debug PprStyle
sty Unique
uniq Module
mod OccName
occ Bool
is_wired BuiltInSyntax
is_builtin
  | PprStyle -> Bool
codeStyle PprStyle
sty = Module -> doc
forall doc. IsLine doc => Module -> doc
pprModule Module
mod doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'_' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_z_occ_name OccName
occ
        -- In code style, always qualify
        -- ToDo: maybe we could print all wired-in things unqualified
        --       in code style, to reduce symbol table bloat?
  | Bool
debug         = doc
pp_mod doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ
                     doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc -> doc
forall doc. IsLine doc => doc -> doc
braces ([doc] -> doc
forall doc. IsLine doc => [doc] -> doc
hsep [if Bool
is_wired then String -> doc
forall doc. IsLine doc => String -> doc
text String
"(w)" else doc
forall doc. IsOutput doc => doc
empty,
                                      NameSpace -> doc
forall doc. IsLine doc => NameSpace -> doc
pprNameSpaceBrief (OccName -> NameSpace
occNameSpace OccName
occ),
                                      Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUnique Unique
uniq])
  | BuiltInSyntax
BuiltInSyntax <- BuiltInSyntax
is_builtin = OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ  -- Never qualify builtin syntax
  | Bool
otherwise                   =
        if Module -> Bool
forall u. GenModule (GenUnit u) -> Bool
isHoleModule Module
mod
            then case PprStyle -> QueryQualifyName
qualName PprStyle
sty Module
mod OccName
occ of
                    QualifyName
NameUnqual -> OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ
                    QualifyName
_ -> doc -> doc
forall doc. IsLine doc => doc -> doc
braces (ModuleName -> doc
forall doc. IsLine doc => ModuleName -> doc
pprModuleName (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
mod) doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
dot doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ)
            else PprStyle -> Module -> OccName -> doc
forall doc. IsLine doc => PprStyle -> Module -> OccName -> doc
pprModulePrefix PprStyle
sty Module
mod OccName
occ doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ
  where
    pp_mod :: doc
pp_mod = (SDocContext -> Bool) -> doc -> doc
forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressModulePrefixes
               (Module -> doc
forall doc. IsLine doc => Module -> doc
pprModule Module
mod doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
dot)

pprInternal :: IsLine doc => Bool -> PprStyle -> Unique -> OccName -> doc
pprInternal :: forall doc.
IsLine doc =>
Bool -> PprStyle -> Unique -> OccName -> doc
pprInternal Bool
debug PprStyle
sty Unique
uniq OccName
occ
  | PprStyle -> Bool
codeStyle PprStyle
sty  = Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
uniq
  | Bool
debug          = OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc -> doc
forall doc. IsLine doc => doc -> doc
braces ([doc] -> doc
forall doc. IsLine doc => [doc] -> doc
hsep [NameSpace -> doc
forall doc. IsLine doc => NameSpace -> doc
pprNameSpaceBrief (OccName -> NameSpace
occNameSpace OccName
occ),
                                                       Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUnique Unique
uniq])
  | PprStyle -> Bool
dumpStyle PprStyle
sty  = OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
ppr_underscore_unique Unique
uniq
                        -- For debug dumps, we're not necessarily dumping
                        -- tidied code, so we need to print the uniques.
  | Bool
otherwise      = OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ   -- User style

-- Like Internal, except that we only omit the unique in Iface style
pprSystem :: IsLine doc => Bool -> PprStyle -> Unique -> OccName -> doc
pprSystem :: forall doc.
IsLine doc =>
Bool -> PprStyle -> Unique -> OccName -> doc
pprSystem Bool
debug PprStyle
sty Unique
uniq OccName
occ
  | PprStyle -> Bool
codeStyle PprStyle
sty  = Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
uniq
  | Bool
debug          = OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
ppr_underscore_unique Unique
uniq
                     doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc -> doc
forall doc. IsLine doc => doc -> doc
braces (NameSpace -> doc
forall doc. IsLine doc => NameSpace -> doc
pprNameSpaceBrief (OccName -> NameSpace
occNameSpace OccName
occ))
  | Bool
otherwise      = OccName -> doc
forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
ppr_underscore_unique Unique
uniq
                                -- If the tidy phase hasn't run, the OccName
                                -- is unlikely to be informative (like 's'),
                                -- so print the unique


pprModulePrefix :: IsLine doc => PprStyle -> Module -> OccName -> doc
-- Print the "M." part of a name, based on whether it's in scope or not
-- See Note [Printing original names] in GHC.Types.Name.Ppr
pprModulePrefix :: forall doc. IsLine doc => PprStyle -> Module -> OccName -> doc
pprModulePrefix PprStyle
sty Module
mod OccName
occ = (SDocContext -> Bool) -> doc -> doc
forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressModulePrefixes (doc -> doc) -> doc -> doc
forall a b. (a -> b) -> a -> b
$
    case PprStyle -> QueryQualifyName
qualName PprStyle
sty Module
mod OccName
occ of              -- See Outputable.QualifyName:
      NameQual ModuleName
modname -> ModuleName -> doc
forall doc. IsLine doc => ModuleName -> doc
pprModuleName ModuleName
modname doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
dot       -- Name is in scope
      QualifyName
NameNotInScope1  -> Module -> doc
forall doc. IsLine doc => Module -> doc
pprModule Module
mod doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
dot               -- Not in scope
      QualifyName
NameNotInScope2  -> Unit -> doc
forall doc. IsLine doc => Unit -> doc
pprUnit (Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
mod) doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
colon           -- Module not in
                          doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> ModuleName -> doc
forall doc. IsLine doc => ModuleName -> doc
pprModuleName (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
mod) doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> doc
forall doc. IsLine doc => doc
dot    -- scope either
      QualifyName
NameUnqual       -> doc
forall doc. IsOutput doc => doc
empty                   -- In scope unqualified

pprUnique :: IsLine doc => Unique -> doc
-- Print a unique unless we are suppressing them
pprUnique :: forall doc. IsLine doc => Unique -> doc
pprUnique Unique
uniq
  = (SDocContext -> Bool) -> doc -> doc
forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressUniques (doc -> doc) -> doc -> doc
forall a b. (a -> b) -> a -> b
$
      Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
uniq

ppr_underscore_unique :: IsLine doc => Unique -> doc
-- Print an underscore separating the name from its unique
-- But suppress it if we aren't printing the uniques anyway
ppr_underscore_unique :: forall doc. IsLine doc => Unique -> doc
ppr_underscore_unique Unique
uniq
  = (SDocContext -> Bool) -> doc -> doc
forall doc. IsLine doc => (SDocContext -> Bool) -> doc -> doc
ppUnlessOption SDocContext -> Bool
sdocSuppressUniques (doc -> doc) -> doc -> doc
forall a b. (a -> b) -> a -> b
$
      Char -> doc
forall doc. IsLine doc => Char -> doc
char Char
'_' doc -> doc -> doc
forall doc. IsLine doc => doc -> doc -> doc
<> Unique -> doc
forall doc. IsLine doc => Unique -> doc
pprUniqueAlways Unique
uniq

ppr_occ_name :: IsLine doc => OccName -> doc
ppr_occ_name :: forall doc. IsLine doc => OccName -> doc
ppr_occ_name OccName
occ = FastString -> doc
forall doc. IsLine doc => FastString -> doc
ftext (OccName -> FastString
occNameFS OccName
occ)
        -- Don't use pprOccName; instead, just print the string of the OccName;
        -- we print the namespace in the debug stuff above

-- In code style, we Z-encode the strings.  The results of Z-encoding each FastString are
-- cached behind the scenes in the FastString implementation.
ppr_z_occ_name :: IsLine doc => OccName -> doc
ppr_z_occ_name :: forall doc. IsLine doc => OccName -> doc
ppr_z_occ_name OccName
occ = FastZString -> doc
forall doc. IsLine doc => FastZString -> doc
ztext (FastString -> FastZString
zEncodeFS (OccName -> FastString
occNameFS OccName
occ))

-- Prints (if mod information is available) "Defined at <loc>" or
--  "Defined in <mod>" information for a Name.
pprDefinedAt :: Name -> SDoc
pprDefinedAt :: Name -> SDoc
pprDefinedAt Name
name = String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Defined" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Name -> SDoc
pprNameDefnLoc Name
name

pprNameDefnLoc :: Name -> SDoc
-- Prints "at <loc>" or
--     or "in <mod>" depending on what info is available
pprNameDefnLoc :: Name -> SDoc
pprNameDefnLoc Name
name
  = case Name -> SrcLoc
nameSrcLoc Name
name of
         -- nameSrcLoc rather than nameSrcSpan
         -- It seems less cluttered to show a location
         -- rather than a span for the definition point
       RealSrcLoc RealSrcLoc
s Maybe BufPos
_ -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"at" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> RealSrcLoc -> SDoc
forall a. Outputable a => a -> SDoc
ppr RealSrcLoc
s
       UnhelpfulLoc FastString
s
         | Name -> Bool
isInternalName Name
name Bool -> Bool -> Bool
|| Name -> Bool
isSystemName Name
name
         -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"at" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext FastString
s
         | Bool
otherwise
         -> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"in" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (Module -> SDoc
forall a. Outputable a => a -> SDoc
ppr ((() :: Constraint) => Name -> Module
Name -> Module
nameModule Name
name))


-- | Get a string representation of a 'Name' that's unique and stable
-- across recompilations. Used for deterministic generation of binds for
-- derived instances.
-- eg. "$aeson_70dylHtv1FFGeai1IoxcQr$Data.Aeson.Types.Internal$String"
nameStableString :: Name -> String
nameStableString :: Name -> String
nameStableString Name{OccName
Unique
SrcSpan
NameSort
n_sort :: Name -> NameSort
n_occ :: Name -> OccName
n_uniq :: Name -> Unique
n_loc :: Name -> SrcSpan
n_sort :: NameSort
n_occ :: OccName
n_uniq :: Unique
n_loc :: SrcSpan
..} =
  NameSort -> String
nameSortStableString NameSort
n_sort String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"$" String -> String -> String
forall a. [a] -> [a] -> [a]
++ OccName -> String
occNameString OccName
n_occ

nameSortStableString :: NameSort -> String
nameSortStableString :: NameSort -> String
nameSortStableString NameSort
System = String
"$_sys"
nameSortStableString NameSort
Internal = String
"$_in"
nameSortStableString (External Module
mod) = Module -> String
moduleStableString Module
mod
nameSortStableString (WiredIn Module
mod TyThing
_ BuiltInSyntax
_) = Module -> String
moduleStableString Module
mod

{-
************************************************************************
*                                                                      *
\subsection{Overloaded functions related to Names}
*                                                                      *
************************************************************************
-}

-- | A class allowing convenient access to the 'Name' of various datatypes
class NamedThing a where
    getOccName :: a -> OccName
    getName    :: a -> Name

    getOccName a
n = Name -> OccName
nameOccName (a -> Name
forall a. NamedThing a => a -> Name
getName a
n)      -- Default method

instance NamedThing e => NamedThing (Located e) where
    getName :: Located e -> Name
getName = e -> Name
forall a. NamedThing a => a -> Name
getName (e -> Name) -> (Located e -> e) -> Located e -> Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located e -> e
forall l e. GenLocated l e -> e
unLoc

getSrcLoc           :: NamedThing a => a -> SrcLoc
getSrcSpan          :: NamedThing a => a -> SrcSpan
getOccString        :: NamedThing a => a -> String
getOccFS            :: NamedThing a => a -> FastString

getSrcLoc :: forall a. NamedThing a => a -> SrcLoc
getSrcLoc           = Name -> SrcLoc
nameSrcLoc           (Name -> SrcLoc) -> (a -> Name) -> a -> SrcLoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Name
forall a. NamedThing a => a -> Name
getName
getSrcSpan :: forall a. NamedThing a => a -> SrcSpan
getSrcSpan          = Name -> SrcSpan
nameSrcSpan          (Name -> SrcSpan) -> (a -> Name) -> a -> SrcSpan
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Name
forall a. NamedThing a => a -> Name
getName
getOccString :: forall a. NamedThing a => a -> String
getOccString        = OccName -> String
occNameString        (OccName -> String) -> (a -> OccName) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> OccName
forall a. NamedThing a => a -> OccName
getOccName
getOccFS :: forall a. NamedThing a => a -> FastString
getOccFS            = OccName -> FastString
occNameFS            (OccName -> FastString) -> (a -> OccName) -> a -> FastString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> OccName
forall a. NamedThing a => a -> OccName
getOccName

pprInfixName :: (Outputable a, NamedThing a) => a -> SDoc
-- See Outputable.pprPrefixVar, pprInfixVar;
-- add parens or back-quotes as appropriate
pprInfixName :: forall a. (Outputable a, NamedThing a) => a -> SDoc
pprInfixName  a
n = Bool -> SDoc -> SDoc
pprInfixVar (OccName -> Bool
isSymOcc (a -> OccName
forall a. NamedThing a => a -> OccName
getOccName a
n)) (a -> SDoc
forall a. Outputable a => a -> SDoc
ppr a
n)

pprPrefixName :: NamedThing a => a -> SDoc
pprPrefixName :: forall a. NamedThing a => a -> SDoc
pprPrefixName a
thing = Bool -> SDoc -> SDoc
pprPrefixVar (OccName -> Bool
isSymOcc (Name -> OccName
nameOccName Name
name)) (Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
name)
 where
   name :: Name
name = a -> Name
forall a. NamedThing a => a -> Name
getName a
thing