{-# 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.Types.PkgQual
   , module GHC.Core.Opt.Monad
   , module GHC.Core.Opt.Pipeline.Types
   , module GHC.Core.Opt.Stats
   , 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.Driver.Ppr
   , module GHC.Unit.State
   , module GHC.Unit.Module
   , module GHC.Unit.Home
   , module GHC.Core.Type
   , module GHC.Core.TyCon
   , module GHC.Core.Coercion
   , module GHC.Builtin.Types
   , module GHC.Driver.Env
   , 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.Utils.Panic
   , module GHC.Types.Unique.Supply
   , module GHC.Data.FastString
   , module GHC.Tc.Errors.Hole.FitTypes   -- for hole-fit plugins
   , module GHC.Tc.Errors.Hole.Plugin   -- for hole-fit plugins
   , module GHC.Unit.Module.ModGuts
   , module GHC.Unit.Module.ModSummary
   , module GHC.Unit.Module.ModIface
   , module GHC.Types.Meta
   , module GHC.Types.SourceError
   , module GHC.Parser.Errors.Types
   , module GHC.Types.Error
   , module GHC.Hs
   , -- * Getting 'Name's
     thNameToGhcName
   , thNameToGhcNameIO
   )
where

-- Plugin stuff itself
import GHC.Driver.Plugins

-- Variable naming
import GHC.Types.TyThing
import GHC.Types.PkgQual
import GHC.Types.SourceError
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.Opt.Pipeline.Types
import GHC.Core.Opt.Stats
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, extendSubstInScopeSet )
       -- These names are also exported by Type

import GHC.Core.Rules
import GHC.Types.Annotations
import GHC.Types.Meta

import GHC.Driver.Session
import GHC.Unit.State

import GHC.Unit.Home
import GHC.Unit.Module
import GHC.Unit.Module.ModGuts
import GHC.Unit.Module.ModSummary
import GHC.Unit.Module.ModIface
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.Env
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.Utils.Panic
import GHC.Driver.Ppr
import GHC.Types.Unique.Supply
import GHC.Types.Unique ( Unique, Uniquable(..) )
import GHC.Data.FastString
import Data.Maybe

import GHC.Iface.Env    ( lookupNameCache )
import GHC.Prelude
import GHC.Utils.Monad  ( mapMaybeM )
import GHC.ThToHs       ( thRdrNameGuesses )
import GHC.Tc.Utils.Env ( lookupGlobal )
import GHC.Types.Name.Cache ( NameCache )

import GHC.Tc.Errors.Hole.FitTypes
import GHC.Tc.Errors.Hole.Plugin

-- For parse result plugins
import GHC.Parser.Errors.Types ( PsWarning, PsError )
import GHC.Types.Error         ( Messages )
import GHC.Hs                  ( HsParsedModule )

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 a. IO a -> CoreM a
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
  HscEnv
hsc_env <- CoreM HscEnv
getHscEnv
  IO (Maybe Name) -> CoreM (Maybe Name)
forall a. IO a -> CoreM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe Name) -> CoreM (Maybe Name))
-> IO (Maybe Name) -> CoreM (Maybe Name)
forall a b. (a -> b) -> a -> b
$ NameCache -> Name -> IO (Maybe Name)
thNameToGhcNameIO (HscEnv -> NameCache
hsc_NC HscEnv
hsc_env) Name
th_name

-- | 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.
--
-- One must be careful to consistently use the same 'NameCache' to
-- create identifier that might be compared. (C.f. how the
-- 'Control.Monad.ST.ST' Monad enforces that variables from separate
-- 'Control.Monad.ST.runST' invocations are never intermingled; it would
-- be valid to use the same tricks for 'Name's and 'NameCache's.)
--
-- For now, the easiest and recommended way to ensure a consistent
-- 'NameCache' is used it to retrieve the preexisting one from an active
-- 'HscEnv'. A single 'HscEnv' is created per GHC "session", and this
-- ensures everything in that session will get the same name cache.
thNameToGhcNameIO :: NameCache -> TH.Name -> IO (Maybe Name)
thNameToGhcNameIO :: NameCache -> Name -> IO (Maybe Name)
thNameToGhcNameIO NameCache
cache Name
th_name
  =  do { [Name]
names <- (RdrName -> IO (Maybe Name)) -> [RdrName] -> IO [Name]
forall (m :: * -> *) a b.
Applicative m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM RdrName -> IO (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 -> IO (Maybe Name)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Name] -> Maybe Name
forall a. [a] -> Maybe a
listToMaybe [Name]
names) }
  where
    lookup :: RdrName -> IO (Maybe Name)
lookup RdrName
rdr_name
      | Just Name
n <- RdrName -> Maybe Name
isExact_maybe RdrName
rdr_name   -- This happens in derived code
      = Maybe Name -> IO (Maybe Name)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Name -> IO (Maybe Name)) -> Maybe Name -> IO (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
      = Name -> Maybe Name
forall a. a -> Maybe a
Just (Name -> Maybe Name) -> IO Name -> IO (Maybe Name)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NameCache -> Module -> OccName -> IO Name
lookupNameCache NameCache
cache Module
rdr_mod OccName
rdr_occ
      | Bool
otherwise = Maybe Name -> IO (Maybe Name)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Name
forall a. Maybe a
Nothing