@@ -79,6 +79,10 @@ modifyCache f = do
79
79
-- in either case
80
80
runActionWithContext :: (MonadIde m , GHC. GhcMonad m , HasGhcModuleCache m , MonadBaseControl IO m )
81
81
=> GHC. DynFlags -> Maybe FilePath -> m a -> m (IdeResult a )
82
+ -- TODO: @fendor, this currently uses a IdeResult to provide either an error
83
+ -- produced by `loadCradle` or the actual result of `m a`.
84
+ -- We need a way to provide diagnostics from this action instead and report them back
85
+ -- to the user.
82
86
runActionWithContext _df Nothing action =
83
87
-- Cradle with no additional flags
84
88
-- dir <- liftIO $ getCurrentDirectory
@@ -92,7 +96,11 @@ runActionWithContext df (Just uri) action = do
92
96
IdeResultOk () -> fmap IdeResultOk action
93
97
IdeResultFail err -> return $ IdeResultFail err
94
98
95
-
99
+ -- | Load a cradle based on the lookup result.
100
+ -- This operation may take a very long time. If a new cradle is required,
101
+ -- we now set up the GHC Session and load all modules.
102
+ -- If the current cradle is reused, nothing needs to be done.
103
+ -- If a cached cradle can be used, set the cradle as the current cradle.
96
104
loadCradle :: (MonadIde m , HasGhcModuleCache m , GHC. GhcMonad m
97
105
, MonadBaseControl IO m ) => GHC. DynFlags -> LookupCradleResult -> m (IdeResult () )
98
106
loadCradle _ ReuseCradle = do
@@ -115,8 +123,10 @@ loadCradle iniDynFlags (NewCradle fp) = do
115
123
-- Now load the new cradle
116
124
cradle <- liftIO $ findLocalCradle fp
117
125
traceShowM cradle
126
+ -- set a new session
118
127
liftIO (GHC. newHscEnv iniDynFlags) >>= GHC. setSession
119
128
liftIO $ setCurrentDirectory (BIOS. cradleRootDir cradle)
129
+ -- initilise the session
120
130
res <- gcatches
121
131
(do
122
132
withProgress " Initialising Cradle" NotCancellable (initializeCradle cradle)
@@ -146,17 +156,21 @@ loadCradle iniDynFlags (NewCradle fp) = do
146
156
}
147
157
]
148
158
149
-
150
159
case res of
151
160
IdeResultOk () -> do
152
161
setCurrentCradle cradle
153
162
return (IdeResultOk () )
154
163
err -> return err
155
164
where
165
+ -- Simple helper function to detect, whether the given cradle is a stack cradle.
166
+ -- We need this, because we have to append the filepath, for which we are loading the cradle,
167
+ -- to the options because of the issue described in: https://github.com/mpickering/haskell-ide-engine/issues/10
168
+ -- tldr: stack does not actually load anything on initialisation, but rather on typechecking.
156
169
isStackCradle :: BIOS. Cradle -> Bool
157
170
isStackCradle c = BIOS. actionName (BIOS. cradleOptsProg c) == " stack"
158
171
159
- -- initializeCradle ::
172
+ -- | Actually initialize the cradle.
173
+ -- Takes a function to report progress.
160
174
initializeCradle :: GHC. GhcMonad m => BIOS. Cradle -> (Progress -> IO () ) -> m ()
161
175
initializeCradle cradle f = do
162
176
let msg = Just (toMessager f)
@@ -176,10 +190,12 @@ loadCradle iniDynFlags (NewCradle fp) = do
176
190
177
191
targets <- BIOS. initSession opts'
178
192
GHC. setTargets targets
179
- -- Get the module graph using the function `getModuleGraph`
180
193
mod_graph <- GHC. depanal [] True
181
194
void $ GHC. load' GHC. LoadAllTargets msg mod_graph
182
195
196
+ -- | Set the given cradle as our current context.
197
+ -- Retrieves all filepaths this cradle is responsible for from the
198
+ -- GHC.moduleGraph and caches them.
183
199
setCurrentCradle :: (HasGhcModuleCache m , GHC. GhcMonad m ) => BIOS. Cradle -> m ()
184
200
setCurrentCradle cradle = do
185
201
mg <- GHC. getModuleGraph
@@ -188,23 +204,21 @@ setCurrentCradle cradle = do
188
204
ps' <- liftIO $ mapM canonicalizePath ps
189
205
modifyCache (\ s -> s { currentCradle = Just (ps', cradle) })
190
206
191
-
207
+ -- | Cache the current cradle the modules it is responsible for.
192
208
cacheCradle :: (HasGhcModuleCache m , GHC. GhcMonad m ) => ([FilePath ], BIOS. Cradle ) -> m ()
193
209
cacheCradle (ds, c) = do
194
210
env <- GHC. getSession
195
211
let cc = CachedCradle c env
196
212
new_map = T. fromList (map (, cc) (map B. pack ds))
197
213
modifyCache (\ s -> s { cradleCache = T. unionWith (\ a _ -> a) new_map (cradleCache s) })
198
214
199
- -- | Get the Cradle that should be used for a given URI
200
- -- getCradle :: (GM.GmEnv m, MonadIO m, HasGhcModuleCache m, GM.GmLog m
201
- -- , MonadBaseControl IO m, ExceptionMonad m, GM.GmOut m)
215
+ -- | Get a cradle search result for a given filepath.
216
+ -- Can be used to decide whether to load a new cradle or if the current one can be reused.
202
217
getCradle :: (GHC. GhcMonad m , HasGhcModuleCache m )
203
218
=> FilePath -> m LookupCradleResult
204
219
getCradle fp = do
205
220
canon_fp <- liftIO $ canonicalizePath fp
206
- mcache <- getModuleCache
207
- return $ lookupCradle canon_fp mcache
221
+ lookupCradle canon_fp <$> getModuleCache
208
222
209
223
ifCachedInfo :: (HasGhcModuleCache m , MonadIO m ) => FilePath -> a -> (CachedInfo -> m a ) -> m a
210
224
ifCachedInfo fp def callback = do
0 commit comments