@@ -29,7 +29,7 @@ import Fingerprint
2929
3030import Data.Binary
3131import Data.Bifunctor (second)
32−import Control.Monad
32+import Control.Monad.Extra
3333import Control.Monad.Trans.Class
3434import Control.Monad.Trans.Maybe
3535import Development.IDE.Core.Compile
@@ -50,6 +50,7 @@ import Data.Foldable
5050import qualified Data.IntMap.Strict as IntMap
5151import qualified Data.IntSet as IntSet
5252import Data.List
53+import Data.Ord
5354import qualified Data.Set as Set
5455import qualified Data.Text as T
5556import Development.IDE.GHC.Error
@@ -58,8 +59,6 @@ import Development.IDE.Core.RuleTypes
5859import Development.IDE.Spans.Type
5960
6061import qualified GHC.LanguageExtensions as LangExt
61−import UniqSupply
62−import NameCache
6362import HscTypes
6463import DynFlags (xopt)
6564import GHC.Generics(Generic)
@@ -112,9 +111,60 @@ getDefinition :: NormalizedFilePath -> Position -> Action (Maybe Location)
112111getDefinition file pos = fmap join $ runMaybeT $ do
113112 opts <- lift getIdeOptions
114113 spans <- useE GetSpanInfo file
115− pkgState <- hscEnv <$> useE GhcSession file
116− let getHieFile x = useNoFile (GetHieFile x)
117− lift $ AtPoint.gotoDefinition getHieFile opts pkgState (spansExprs spans) pos
114+ lift $ AtPoint.gotoDefinition (getHieFile file) opts (spansExprs spans) pos
115+
116+getHieFile
117+ :: NormalizedFilePath -- ^ file we're editing
118+ -> Module -- ^ module dep we want info for
119+ -> Action (Maybe (HieFile, FilePath)) -- ^ hie stuff for the module
120+getHieFile file mod = do
121+ TransitiveDependencies {transitiveNamedModuleDeps} <- use_ GetDependencies file
122+ case find (\x -> nmdModuleName x == moduleName mod) transitiveNamedModuleDeps of
123+ Just NamedModuleDep{nmdFilePath=nfp} -> do
124+ let modPath = fromNormalizedFilePath nfp
125+ (_diags, hieFile) <- getHomeHieFile nfp
126+ return $ (, modPath) <$> hieFile
127+ _ -> getPackageHieFile mod file
128+
129+
130+getHomeHieFile :: NormalizedFilePath -> Action ([a], Maybe HieFile)
131+getHomeHieFile f = do
132+ pm <- use_ GetParsedModule f
133+ let normal_hie_f = toNormalizedFilePath hie_f
134+ hie_f = ml_hie_file $ ms_location $ pm_mod_summary pm
135+ mbHieTimestamp <- use GetModificationTime normal_hie_f
136+ srcTimestamp <- use_ GetModificationTime f
137+
138+ let isUpToDate
139+ | Just d <- mbHieTimestamp = comparing modificationTime d srcTimestamp == GT
140+ | otherwise = False
141+
142+-- In the future, TypeCheck will emit .hie files as a side effect
143+-- unless isUpToDate $
144+-- void $ use_ TypeCheck f
145+
146+ hf <- liftIO $ if isUpToDate then Just <$> loadHieFile hie_f else pure Nothing
147+ return ([], hf)
148+
149+getPackageHieFile :: Module -- ^ Package Module to load .hie file for
150+ -> NormalizedFilePath -- ^ Path of home module importing the package module
151+ -> Action (Maybe (HieFile, FilePath))
152+getPackageHieFile mod file = do
153+ pkgState <- hscEnv <$> use_ GhcSession file
154+ IdeOptions {..} <- getIdeOptions
155+ let unitId = moduleUnitId mod
156+ case lookupPackageConfig unitId pkgState of
157+ Just pkgConfig -> do
158+ -- 'optLocateHieFile' returns Nothing if the file does not exist
159+ hieFile <- liftIO $ optLocateHieFile optPkgLocationOpts pkgConfig mod
160+ path <- liftIO $ optLocateSrcFile optPkgLocationOpts pkgConfig mod
161+ case (hieFile, path) of
162+ (Just hiePath, Just modPath) ->
163+ -- deliberately loaded outside the Shake graph
164+ -- to avoid dependencies on non-workspace files
165+ liftIO $ Just . (, modPath) <$> loadHieFile hiePath
166+ _ -> return Nothing
167+ _ -> return Nothing
118168
119169-- | Parse the contents of a daml file.
120170getParsedModule :: NormalizedFilePath -> Action (Maybe ParsedModule)
@@ -348,14 +398,6 @@ loadGhcSession = do
348398 opts <- getIdeOptions
349399 return ("" <$ optShakeFiles opts, ([], Just val))
350400
351−
352−getHieFileRule :: Rules ()
353−getHieFileRule =
354− defineNoFile $ \(GetHieFile f) -> do
355− u <- liftIO $ mkSplitUniqSupply 'a'
356− let nameCache = initNameCache u []
357− liftIO $ fmap (hie_file_result . fst) $ readHieFile nameCache f
358−
359401-- | A rule that wires per-file rules together
360402mainRule :: Rules ()
361403mainRule = do
@@ -369,4 +411,3 @@ mainRule = do
369411 generateCoreRule
370412 generateByteCodeRule
371413 loadGhcSession
372− getHieFileRule