on master help sign in
language: a shake rule to get interface/hie files (#2291)

* language: a shake rule to get interface/hie files This adds a shake rule to get module interfaces and hie files. This gives more control on when to build them and also an opportunity to change the package name after typechecking. This is used in the next PR to add package hashes to the package name in the interface files. * generate hie files only on demand

commit3e163354cd936c72cc3b216c55701acd1340ff06 authorRobin Krom <robin@digitalasset.com> dateFri 26 Jul 2019, 15:06 (7 years ago) parent5643bff
3 files changed+18−31
src/Development/IDE/Core/Compile.hs+7−23 src/Development/IDE/Core/Rules.hs+11−2 src/Development/IDE/Types/Options.hs−6
src/Development/IDE/Core/Compile.hs+7−23
@@ -52,7 +52,6 @@ import Data.Maybe
5252import Data.Tuple.Extra
5353import qualified Data.Map.Strict as Map
5454import System.FilePath
55−import System.Directory
5655import System.IO.Extra
5756import Data.Char
5857
@@ -84,19 +83,18 @@ computePackageDeps env pkg = do
8483
8584-- | Typecheck a single module using the supplied dependencies and packages.
8685typecheckModule
87− :: IdeOptions
88− -> HscEnv
86+ :: HscEnv
8987 -> [TcModuleResult]
9088 -> ParsedModule
9189 -> IO ([FileDiagnostic], Maybe TcModuleResult)
92−typecheckModule opt packageState deps pm =
90+typecheckModule packageState deps pm =
9391 fmap (either (, Nothing) (second Just)) $
9492 runGhcEnv packageState $
9593 catchSrcErrors $ do
9694 setupEnv deps
9795 (warnings, tcm) <- withWarnings $ \tweak ->
9896 GHC.typecheckModule pm{pm_mod_summary = tweak $ pm_mod_summary pm}
99− tcm2 <- mkTcModuleResult (optIfaceDir opt) tcm
97+ tcm2 <- mkTcModuleResult tcm
10098 return (warnings, tcm2)
10199
102100-- | Compile a single type-checked module to a 'CoreModule' value, or
@@ -138,30 +136,16 @@ addRelativeImport modu dflags = dflags
138136
139137mkTcModuleResult
140138 :: GhcMonad m
141− => InterfaceDirectory
142− -> TypecheckedModule
139+ => TypecheckedModule
143140 -> m TcModuleResult
144−mkTcModuleResult (InterfaceDirectory mbIfaceDir) tcm = do
145− session <- getSession
146− (iface,_) <- liftIO $ mkIfaceTc session Nothing Sf_None details tcGblEnv
147− liftIO $ whenJust mbIfaceDir $ \ifaceDir -> do
148− let path = ifaceDir </> file tcm
149− createDirectoryIfMissing True (takeDirectory path)
150− writeIfaceFile (hsc_dflags session) (replaceExtension path ".hi") iface
151− -- For now, we write .hie files whenever we write .hi files which roughly corresponds to
152− -- when we are building a package. It should be easily decoupable if that turns out to be
153− -- useful.
154− hieFile <- runHsc session $ mkHieFile (tcModSummary tcm) tcGblEnv (fromJust $ renamedSource tcm)
155− writeHieFile (replaceExtension path ".hie") hieFile
141+mkTcModuleResult tcm = do
142+ session <- getSession
143+ (iface, _) <- liftIO $ mkIfaceTc session Nothing Sf_None details tcGblEnv
156144 let mod_info = HomeModInfo iface details Nothing
157145 return $ TcModuleResult tcm mod_info
158146 where
159− file = ms_hspp_file . tcModSummary
160147 (tcGblEnv, details) = tm_internals_ tcm
161148
162−tcModSummary :: TypecheckedModule -> ModSummary
163−tcModSummary = pm_mod_summary . tm_parsed_module
164−
165149-- | Setup the environment that GHC needs according to our
166150-- best understanding (!)
167151setupEnv :: GhcMonad m => [TcModuleResult] -> m ()
src/Development/IDE/Core/Rules.hs+11−2
@@ -22,6 +22,7 @@ module Development.IDE.Core.Rules(
2222 getDefinition,
2323 getDependencies,
2424 getParsedModule,
25+ getTcModuleResults,
2526 fileFromParsedModule
2627 ) where
2728
@@ -119,6 +120,15 @@ getDefinition file pos = fmap join $ runMaybeT $ do
119120getParsedModule :: NormalizedFilePath -> Action (Maybe ParsedModule)
120121getParsedModule file = use GetParsedModule file
121122
123+-- | Get typechecked module results of a file and all it's transitive dependencies.
124+getTcModuleResults :: NormalizedFilePath -> Action (Maybe ([TcModuleResult], HscEnv))
125+getTcModuleResults file =
126+ runMaybeT $ do
127+ files <- transitiveModuleDeps <$> useE GetDependencies file
128+ tms <- usesE TypeCheck (file : files)
129+ session <- lift $ useNoFile_ GhcSession
130+ pure (tms, session)
131+
122132
123133------------------------------------------------------------
124134-- Rules
@@ -248,8 +258,7 @@ typeCheckRule =
248258 tms <- uses_ TypeCheck (transitiveModuleDeps deps)
249259 setPriority priorityTypeCheck
250260 packageState <- useNoFile_ GhcSession
251− opt <- getIdeOptions
252− liftIO $ typecheckModule opt packageState tms pm
261+ liftIO $ typecheckModule packageState tms pm
253262
254263
255264generateCoreRule :: Rules ()
src/Development/IDE/Types/Options.hs−6
@@ -7,7 +7,6 @@
77module Development.IDE.Types.Options
88 ( IdeOptions(..)
99 , IdePkgLocationOptions(..)
10− , InterfaceDirectory(..)
1110 , defaultIdeOptions
1211 ) where
1312
@@ -16,16 +15,12 @@ import GHC hiding (parseModule, typecheckModule)
1615import GhcPlugins as GHC hiding (fst3, (<>))
1716
1817
19−-- | If `Nothing` we do not write .hi files.
20−newtype InterfaceDirectory = InterfaceDirectory (Maybe FilePath)
21−
2218data IdeOptions = IdeOptions
2319 { optPreprocessor :: GHC.ParsedSource -> ([(GHC.SrcSpan, String)], GHC.ParsedSource)
2420 , optGhcSession :: Action HscEnv
2521 -- ^ Setup a GHC session using a given package state. If a `ParsedModule` is supplied,
2622 -- the import path should be setup for that module.
2723 , optPkgLocationOpts :: IdePkgLocationOptions
28− , optIfaceDir :: InterfaceDirectory
2924 , optExtensions :: [String]
3025
3126 , optThreads :: Int
@@ -37,7 +32,6 @@ data IdeOptions = IdeOptions
3732defaultIdeOptions :: Action HscEnv -> IdeOptions
3833defaultIdeOptions session = IdeOptions
3934 {optPreprocessor = (,) []
40− ,optIfaceDir = InterfaceDirectory Nothing
4135 ,optGhcSession = session
4236 ,optExtensions = ["hs"]
4337 ,optPkgLocationOpts = defaultIdePkgLocationOptions