Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Towards a direct (non plugin-based) API #2388

Merged
merged 4 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions liquidhaskell-boot/src-ghc/Liquid/GHC/API.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import GHC as Ghc
( Class
, DataCon
, DesugaredModule(DesugaredModule, dm_typechecked_module, dm_core_module)
, DynFlags(backend, debugLevel, ghcLink, ghcMode)
, DynFlags(backend, debugLevel, ghcLink, ghcMode, warningFlags)
, FixityDirection(InfixN, InfixR)
, FixitySig(FixitySig)
, GenLocated(L)
Expand All @@ -37,6 +37,7 @@ import GHC as Ghc
, GhcException(CmdLineError, ProgramError)
, GhcLink(LinkInMemory)
, GhcMode(CompManager)
, GhcMonad
, GhcPs
, GhcRn
, HsDecl(SigD)
Expand Down Expand Up @@ -81,9 +82,11 @@ import GHC as Ghc
, TypecheckedModule(tm_checked_module_info, tm_internals_, tm_parsed_module)
, classMethods
, classSCTheta
, coreModule
, dataConTyCon
, dataConFieldLabels
, dataConWrapperType
, desugarModule
, getLocA
, getLogger
, getName
Expand All @@ -109,6 +112,7 @@ import GHC as Ghc
, isRecordSelector
, isTypeSynonymTyCon
, isVanillaDataCon
, lookupName
, mkHsApp
, mkHsDictLet
, mkHsForAllInvisTele
Expand Down Expand Up @@ -154,6 +158,7 @@ import GHC as Ghc
, tyConDataCons
, tyConKind
, tyConTyVars
, typecheckModule
, unLoc
)

Expand Down Expand Up @@ -412,10 +417,6 @@ import GHC.Driver.Config.Diagnostic as Ghc
, initDsMessageOpts
, initIfaceMessageOpts
)
import GHC.Driver.Main as Ghc
( hscDesugar
, hscTcRcLookupName
)
import GHC.Driver.Plugins as Ghc
( ParsedResult(..)
)
Expand All @@ -428,7 +429,7 @@ import GHC.Driver.Session as Ghc
, updOptLevel
, xopt_set
)
import GHC.Driver.Monad as Ghc (withSession)
import GHC.Driver.Monad as Ghc (withSession, reflectGhc, Session(..))
import GHC.HsToCore.Monad as Ghc
( DsM, initDsTc, initDsWithModGuts, newUnique )
import GHC.Iface.Syntax as Ghc
Expand All @@ -452,6 +453,7 @@ import GHC.Driver.Backend as Ghc (interpreterBackend)
import GHC.Driver.Env as Ghc
( HscEnv(hsc_mod_graph, hsc_unit_env, hsc_dflags, hsc_plugins)
, Hsc
, hscSetFlags, hscUpdateFlags
)
import GHC.Driver.Errors as Ghc
( printMessages )
Expand Down Expand Up @@ -499,6 +501,7 @@ import GHC.Tc.Utils.Monad as Ghc
( captureConstraints
, discardConstraints
, getEnv
, getTopEnv
, failIfErrsM
, failM
, failWithTc
Expand All @@ -510,6 +513,7 @@ import GHC.Tc.Utils.Monad as Ghc
, reportDiagnostic
, reportDiagnostics
, updEnv
, updTopEnv
)
import GHC.Tc.Utils.TcType as Ghc (tcSplitDFunTy, tcSplitMethodTy)
import GHC.Tc.Zonk.Type as Ghc
Expand Down
66 changes: 6 additions & 60 deletions liquidhaskell-boot/src-ghc/Liquid/GHC/API/Extra.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@ module Liquid.GHC.API.Extra (
, apiComments
, apiCommentsParsedSource
, dataConSig
, desugarModuleIO
, fsToUnitId
, isPatErrorAlt
, lookupModSummary
, minus_RDR
, modInfoLookupNameIO
, modInfoLookupName
, moduleInfoTc
, parseModuleIO
, qualifiedNameFS
, relevantModules
, renderWithStyle
Expand All @@ -28,13 +26,12 @@ module Liquid.GHC.API.Extra (
, strictNothing
, thisPackage
, tyConRealArity
, typecheckModuleIO
, untick
) where

import Control.Monad.IO.Class
import Liquid.GHC.API.StableModule as StableModule
import GHC
import GHC hiding (modInfoLookupName)
import Data.Data (Data, gmapQr, gmapT)
import Data.Generics (extQ, extT)
import Data.Foldable (asum)
Expand All @@ -49,7 +46,6 @@ import GHC.Core.Make (pAT_ERROR_ID)
import GHC.Core.Type as Ghc hiding (typeKind , isPredTy, extendCvSubst, linear)
import GHC.Data.Bag (bagToList)
import GHC.Data.FastString as Ghc
import qualified GHC.Data.EnumSet as EnumSet
import GHC.Data.Maybe
import qualified GHC.Data.Strict
import GHC.Driver.Env
Expand All @@ -63,7 +59,6 @@ import GHC.Types.SourceText (SourceText(..))
import GHC.Types.SrcLoc as Ghc
import GHC.Types.TypeEnv
import GHC.Types.Unique (getUnique, hasKey)
import GHC.Types.Unique.FM

import GHC.Unit.Module.Deps as Ghc (Dependencies(dep_direct_mods))
import GHC.Unit.Module.Graph as Ghc
Expand Down Expand Up @@ -146,52 +141,6 @@ relevantModules mg modGuts = used `S.union` dependencies
UsageMergedRequirement { usg_mod = modl } -> modl : acc
_ -> acc

--
-- Parsing, typechecking and desugaring a module
--
parseModuleIO :: HscEnv -> ModSummary -> IO ParsedModule
parseModuleIO hscEnv ms = do
let hsc_env_tmp = hscEnv { hsc_dflags = ms_hspp_opts ms }
hpm <- hscParse hsc_env_tmp ms
return (ParsedModule ms (hpm_module hpm) (hpm_src_files hpm))

-- | Our own simplified version of 'TypecheckedModule'.
data TypecheckedModuleLH = TypecheckedModuleLH {
tmlh_parsed_module :: ParsedModule
, tmlh_renamed_source :: Maybe RenamedSource
, tmlh_mod_summary :: ModSummary
, tmlh_gbl_env :: TcGblEnv
}

typecheckModuleIO :: HscEnv -> ParsedModule -> IO TypecheckedModuleLH
typecheckModuleIO hscEnv pmod = do
-- Suppress all the warnings, so that they won't be printed (which would result in them being
-- printed twice, one by GHC and once here).
let ms = pm_mod_summary pmod
let dynFlags' = ms_hspp_opts ms
let hsc_env_tmp = hscEnv { hsc_dflags = dynFlags' { warningFlags = EnumSet.empty } }
(tc_gbl_env, rn_info)
<- hscTypecheckRename hsc_env_tmp ms $
HsParsedModule { hpm_module = parsedSource pmod,
hpm_src_files = pm_extra_src_files pmod }
return TypecheckedModuleLH {
tmlh_parsed_module = pmod
, tmlh_renamed_source = rn_info
, tmlh_mod_summary = ms
, tmlh_gbl_env = tc_gbl_env
}

-- | Desugar a typechecked module.
desugarModuleIO :: HscEnv -> ModSummary -> TypecheckedModuleLH -> IO ModGuts
desugarModuleIO hscEnv originalModSum typechecked = do
-- See [NOTE:ghc810] on why we override the dynFlags here before calling 'desugarModule'.
let modSum = originalModSum { ms_hspp_opts = hsc_dflags hscEnv }
let parsedMod' = (tmlh_parsed_module typechecked) { pm_mod_summary = modSum }
let typechecked' = typechecked { tmlh_parsed_module = parsedMod' }

let hsc_env_tmp = hscEnv { hsc_dflags = ms_hspp_opts (tmlh_mod_summary typechecked') }
hscDesugar hsc_env_tmp (tmlh_mod_summary typechecked') (tmlh_gbl_env typechecked')

-- | Abstraction of 'EpaComment'.
data ApiComment
= ApiLineComment String
Expand Down Expand Up @@ -275,16 +224,13 @@ lookupModSummary hscEnv mdl = do
-- | Our own simplified version of 'ModuleInfo' to overcome the fact we cannot construct the \"original\"
-- one as the constructor is not exported, and 'getHomeModuleInfo' and 'getPackageModuleInfo' are not
-- exported either, so we had to backport them as well.
newtype ModuleInfoLH = ModuleInfoLH { minflh_type_env :: UniqFM Name TyThing }
newtype ModuleInfoLH = ModuleInfoLH { minflh_type_env :: TypeEnv }

modInfoLookupNameIO :: HscEnv
-> ModuleInfoLH
-> Name
-> IO (Maybe TyThing)
modInfoLookupNameIO hscEnv minf name =
modInfoLookupName :: (GhcMonad m) => ModuleInfoLH -> Name -> m (Maybe TyThing)
modInfoLookupName minf name = do
case lookupTypeEnv (minflh_type_env minf) name of
Just tyThing -> return (Just tyThing)
Nothing -> lookupType hscEnv name
Nothing -> lookupGlobalName name

moduleInfoTc :: HscEnv -> TcGblEnv -> IO ModuleInfoLH
moduleInfoTc hscEnv tcGblEnv = do
Expand Down
63 changes: 22 additions & 41 deletions liquidhaskell-boot/src/Language/Haskell/Liquid/GHC/Interface.hs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ module Language.Haskell.Liquid.GHC.Interface (
, keepRawTokenStream
, ignoreInline
, lookupTyThings
, availableTyCons
, availableVars
, availableTyThings
, updLiftedSpec
) where

Expand Down Expand Up @@ -184,47 +183,29 @@ qImports qns = QImports
-- for this module; we will use this to create our name-resolution environment
-- (see `Bare.Resolve`)
---------------------------------------------------------------------------------------
lookupTyThings :: HscEnv -> TcGblEnv -> IO [(Name, Maybe TyThing)]
lookupTyThings hscEnv tcGblEnv = forM names (lookupTyThing hscEnv tcGblEnv)
lookupTyThings :: (GhcMonad m) => TcGblEnv -> m [(Name, Maybe TyThing)]
lookupTyThings tcGblEnv = mapM (lookupTyThing tcGblEnv) names
where
names :: [Ghc.Name]
names = liftM2 (++)
(fmap Ghc.greName . Ghc.globalRdrEnvElts . tcg_rdr_env)
(fmap is_dfun_name . tcg_insts) tcGblEnv
-- | Lookup a single 'Name' in the GHC environment, yielding back the 'Name' alongside the 'TyThing',
-- if one is found.
lookupTyThing :: HscEnv -> TcGblEnv -> Name -> IO (Name, Maybe TyThing)
lookupTyThing hscEnv tcGblEnv n = do
mty <- runMaybeT $
MaybeT (Ghc.hscTcRcLookupName hscEnv n)
`mplus`
MaybeT (
do mi <- moduleInfoTc hscEnv tcGblEnv
modInfoLookupNameIO hscEnv mi n
)
return (n, mty)

availableTyThings :: HscEnv -> TcGblEnv -> [AvailInfo] -> IO [TyThing]
availableTyThings hscEnv tcGblEnv avails =
names = liftA2 (++)
(fmap Ghc.greName . Ghc.globalRdrEnvElts . tcg_rdr_env)
(fmap is_dfun_name . tcg_insts)
tcGblEnv

lookupTyThing :: (GhcMonad m) => TcGblEnv -> Name -> m (Name, Maybe TyThing)
lookupTyThing tcGblEnv name = do
hscEnv <- getSession
mbTy <- runMaybeT . msum . map MaybeT $
[ lookupName name
, do minf <- liftIO $ moduleInfoTc hscEnv tcGblEnv
modInfoLookupName minf name
]
return (name, mbTy)

availableTyThings :: (GhcMonad m) => TcGblEnv -> [AvailInfo] -> m [TyThing]
availableTyThings tcGblEnv avails =
fmap catMaybes $
mapM (fmap snd . lookupTyThing hscEnv tcGblEnv) $
availableNames avails

-- | Returns all the available (i.e. exported) 'TyCon's (type constructors) for the input 'Module'.
availableTyCons :: HscEnv -> TcGblEnv -> [AvailInfo] -> IO [Ghc.TyCon]
availableTyCons hscEnv tcGblEnv avails =
fmap (\things -> [tyCon | (ATyCon tyCon) <- things]) (availableTyThings hscEnv tcGblEnv avails)

-- | Returns all the available (i.e. exported) 'Var's for the input 'Module'.
availableVars :: HscEnv -> TcGblEnv -> [AvailInfo] -> IO [Ghc.Var]
availableVars hscEnv tcGblEnv avails =
fmap (\things -> [var | (AnId var) <- things]) (availableTyThings hscEnv tcGblEnv avails)

availableNames :: [AvailInfo] -> [Name]
availableNames =
concatMap $ \case
Avail n -> [n]
AvailTC n ns -> n : ns
mapM (fmap snd . lookupTyThing tcGblEnv) $
concatMap availNames avails

_dumpTypeEnv :: TypecheckedModule -> IO ()
_dumpTypeEnv tm = do
Expand Down
10 changes: 0 additions & 10 deletions liquidhaskell-boot/src/Language/Haskell/Liquid/GHC/Misc.hs
Original file line number Diff line number Diff line change
Expand Up @@ -623,16 +623,6 @@ stripParens t = fromMaybe t (strip t)
stripParensSym :: Symbol -> Symbol
stripParensSym (symbolText -> t) = symbol (stripParens t)

desugarModule :: TypecheckedModule -> Ghc DesugaredModule
desugarModule tcm = do
let ms = pm_mod_summary $ tm_parsed_module tcm
-- let ms = modSummary tcm
let (tcg, _) = tm_internals_ tcm
hsc_env <- getSession
let hsc_env_tmp = hsc_env { hsc_dflags = ms_hspp_opts ms }
guts <- liftIO $ hscDesugar{- WithLoc -} hsc_env_tmp ms tcg
return DesugaredModule { dm_typechecked_module = tcm, dm_core_module = guts }

--------------------------------------------------------------------------------
-- | GHC Compatibility Layer ---------------------------------------------------
--------------------------------------------------------------------------------
Expand Down
Loading
Loading