{-# OPTIONS_GHC -fno-warn-duplicate-exports -fno-warn-orphans #-}

-- | This module is not used by GHC itself.  Rather, it exports all of
-- the functions and types you are likely to need when writing a
-- plugin for GHC. So authors of plugins can probably get away simply
-- with saying "import GHC.Plugins".
--
-- Particularly interesting modules for plugin writers include
-- "GHC.Core" and "GHC.Core.Opt.Monad".
module GHC.Plugins
   ( module GHC.Driver.Plugins
   , module GHC.Types.Name.Reader
   , module GHC.Types.Name.Occurrence
   , module GHC.Types.Name
   , module GHC.Types.Var
   , module GHC.Types.Id
   , module GHC.Types.Id.Info
   , module GHC.Core.Opt.Monad
   , module GHC.Core
   , module GHC.Types.Literal
   , module GHC.Core.DataCon
   , module GHC.Core.Utils
   , module GHC.Core.Make
   , module GHC.Core.FVs
   , module GHC.Core.Subst
   , module GHC.Core.Rules
   , module GHC.Types.Annotations
   , module GHC.Driver.Session
   , module GHC.Unit.State
   , module GHC.Unit.Module
   , module GHC.Core.Type
   , module GHC.Core.TyCon
   , module GHC.Core.Coercion
   , module GHC.Builtin.Types
   , module GHC.Driver.Types
   , module GHC.Types.Basic
   , module GHC.Types.Var.Set
   , module GHC.Types.Var.Env
   , module GHC.Types.Name.Set
   , module GHC.Types.Name.Env
   , module GHC.Types.Unique
   , module GHC.Types.Unique.Set
   , module GHC.Types.Unique.FM
   , module GHC.Data.FiniteMap
   , module GHC.Utils.Misc
   , module GHC.Serialized
   , module GHC.Types.SrcLoc
   , module GHC.Utils.Outputable
   , module GHC.Types.Unique.Supply
   , module GHC.Data.FastString
   , module GHC.Tc.Errors.Hole.FitTypes   -- for hole-fit plugins
   , -- * Getting 'Name's
     thNameToGhcName
   )
where

-- Plugin stuff itself
import GHC.Driver.Plugins

-- Variable naming
import GHC.Types.Name.Reader
import GHC.Types.Name.Occurrence  hiding  ( varName {- conflicts with Var.varName -} )
import GHC.Types.Name     hiding  ( varName {- reexport from OccName, conflicts with Var.varName -} )
import GHC.Types.Var
import GHC.Types.Id       hiding  ( lazySetIdInfo, setIdExported, setIdNotExported {- all three conflict with Var -} )
import GHC.Types.Id.Info

-- Core
import GHC.Core.Opt.Monad
import GHC.Core
import GHC.Types.Literal
import GHC.Core.DataCon
import GHC.Core.Utils
import GHC.Core.Make
import GHC.Core.FVs
import GHC.Core.Subst hiding( substTyVarBndr, substCoVarBndr, extendCvSubst )
       -- These names are also exported by Type

-- Core "extras"
import GHC.Core.Rules
import GHC.Types.Annotations

-- Pipeline-related stuff
import GHC.Driver.Session
import GHC.Unit.State

-- Important GHC types
import GHC.Unit.Module
import GHC.Core.Type hiding {- conflict with GHC.Core.Subst -}
                ( substTy, extendTvSubst, extendTvSubstList, isInScope )
import GHC.Core.Coercion hiding {- conflict with GHC.Core.Subst -}
                ( substCo )
import GHC.Core.TyCon
import GHC.Builtin.Types
import GHC.Driver.Types
import GHC.Types.Basic

-- Collections and maps
import GHC.Types.Var.Set
import GHC.Types.Var.Env
import GHC.Types.Name.Set
import GHC.Types.Name.Env
import GHC.Types.Unique.Set
import GHC.Types.Unique.FM
-- Conflicts with UniqFM:
--import LazyUniqFM
import GHC.Data.FiniteMap

-- Common utilities
import GHC.Utils.Misc
import GHC.Serialized
import GHC.Types.SrcLoc
import GHC.Utils.Outputable
import GHC.Types.Unique.Supply
import GHC.Types.Unique ( Unique, Uniquable(..) )
import GHC.Data.FastString
import Data.Maybe

import GHC.Iface.Env    ( lookupOrigIO )
import GHC.Prelude
import GHC.Utils.Monad  ( mapMaybeM )
import GHC.ThToHs       ( thRdrNameGuesses )
import GHC.Tc.Utils.Env ( lookupGlobal )

import GHC.Tc.Errors.Hole.FitTypes

import qualified Language.Haskell.TH as TH

{- This instance is defined outside GHC.Core.Opt.Monad so that
   GHC.Core.Opt.Monad does not depend on GHC.Tc.Utils.Env -}
instance MonadThings CoreM where
    lookupThing :: Name -> CoreM TyThing
lookupThing Name
name = do { HscEnv
hsc_env <- CoreM HscEnv
getHscEnv
                          ; IO TyThing -> CoreM TyThing
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO TyThing -> CoreM TyThing) -> IO TyThing -> CoreM TyThing
forall a b. (a -> b) -> a -> b
$ HscEnv -> Name -> IO TyThing
lookupGlobal HscEnv
hsc_env Name
name }

{-
************************************************************************
*                                                                      *
               Template Haskell interoperability
*                                                                      *
************************************************************************
-}

-- | Attempt to convert a Template Haskell name to one that GHC can
-- understand. Original TH names such as those you get when you use
-- the @'foo@ syntax will be translated to their equivalent GHC name
-- exactly. Qualified or unqualified TH names will be dynamically bound
-- to names in the module being compiled, if possible. Exact TH names
-- will be bound to the name they represent, exactly.
thNameToGhcName :: TH.Name -> CoreM (Maybe Name)
thNameToGhcName :: Name -> CoreM (Maybe Name)
thNameToGhcName Name
th_name
  =  do { [Name]
names <- (RdrName -> CoreM (Maybe Name)) -> [RdrName] -> CoreM [Name]
forall (m :: * -> *) a b.
Applicative m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM RdrName -> CoreM (Maybe Name)
lookup (Name -> [RdrName]
thRdrNameGuesses Name
th_name)
          -- Pick the first that works
          -- E.g. reify (mkName "A") will pick the class A in preference
          -- to the data constructor A
        ; Maybe Name -> CoreM (Maybe Name)
forall (m :: * -> *) a. Monad m => a -> m a
return ([Name] -> Maybe Name
forall a. [a] -> Maybe a
listToMaybe [Name]
names) }
  where
    lookup :: RdrName -> CoreM (Maybe Name)
lookup RdrName
rdr_name
      | Just Name
n <- RdrName -> Maybe Name
isExact_maybe RdrName
rdr_name   -- This happens in derived code
      = Maybe Name -> CoreM (Maybe Name)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Name -> CoreM (Maybe Name))
-> Maybe Name -> CoreM (Maybe Name)
forall a b. (a -> b) -> a -> b
$ if Name -> Bool
isExternalName Name
n then Name -> Maybe Name
forall a. a -> Maybe a
Just Name
n else Maybe Name
forall a. Maybe a
Nothing
      | Just (Module
rdr_mod, OccName
rdr_occ) <- RdrName -> Maybe (Module, OccName)
isOrig_maybe RdrName
rdr_name
      = do { HscEnv
hsc_env <- CoreM HscEnv
getHscEnv
           ; Name -> Maybe Name
forall a. a -> Maybe a
Just (Name -> Maybe Name) -> CoreM Name -> CoreM (Maybe Name)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Name -> CoreM Name
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (HscEnv -> Module -> OccName -> IO Name
lookupOrigIO HscEnv
hsc_env Module
rdr_mod OccName
rdr_occ) }
      | Bool
otherwise = Maybe Name -> CoreM (Maybe Name)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Name
forall a. Maybe a
Nothing