on master help sign in
Track module dependencies (#431)
2ae46aePepe Iborra
src/Development/IDE/Core/RuleTypes.hs+2−2
@@ -15,7 +15,6 @@ import Control.DeepSeq
15import Data.Binary
15import Data.Binary
16import Development.IDE.Import.DependencyInformation
16import Development.IDE.Import.DependencyInformation
17import Development.IDE.GHC.Util
17import Development.IDE.GHC.Util
18−import Development.IDE.Types.Location
19import Data.Hashable
18import Data.Hashable
20import Data.Typeable
19import Data.Typeable
21import qualified Data.Set as S
20import qualified Data.Set as S
@@ -28,6 +27,7 @@ import HscTypes (CgGuts, Linkable, HomeModInfo, ModDetails)
28import Development.IDE.GHC.Compat
27import Development.IDE.GHC.Compat
29
28
30import Development.IDE.Spans.Type
29import Development.IDE.Spans.Type
30+import Development.IDE.Import.FindImports (ArtifactsLocation)
31
31
32
32
33-- NOTATION
33-- NOTATION
@@ -75,7 +75,7 @@ type instance RuleResult GhcSession = HscEnvEq
75
75
76-- | Resolve the imports in a module to the file path of a module
76-- | Resolve the imports in a module to the file path of a module
77-- in the same package or the package id of another package.
77-- in the same package or the package id of another package.
78−type instance RuleResult GetLocatedImports = ([(Located ModuleName, Maybe NormalizedFilePath)], S.Set InstalledUnitId)
78+type instance RuleResult GetLocatedImports = ([(Located ModuleName, Maybe ArtifactsLocation)], S.Set InstalledUnitId)
79
79
80-- | This rule is used to report import cycles. It depends on GetDependencyInformation.
80-- | This rule is used to report import cycles. It depends on GetDependencyInformation.
81-- We cannot report the cycles directly from GetDependencyInformation since
81-- We cannot report the cycles directly from GetDependencyInformation since
src/Development/IDE/Core/Rules.hs+7−6
@@ -4,6 +4,7 @@
4{-# LANGUAGE TypeFamilies #-}
4{-# LANGUAGE TypeFamilies #-}
5{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE DuplicateRecordFields #-}
6{-# LANGUAGE DuplicateRecordFields #-}
7+{-# LANGUAGE PatternSynonyms #-}
7
8
8-- | A Shake implementation of the compiler service, built
9-- | A Shake implementation of the compiler service, built
9-- using the "Shaker" abstraction layer for in-memory use.
10-- using the "Shaker" abstraction layer for in-memory use.
@@ -27,6 +28,7 @@ module Development.IDE.Core.Rules(
27import Fingerprint
28import Fingerprint
28
29
29import Data.Binary
30import Data.Binary
31+import Data.Bifunctor (second)
30import Control.Monad
32import Control.Monad
31import Control.Monad.Trans.Class
33import Control.Monad.Trans.Class
32import Control.Monad.Trans.Maybe
34import Control.Monad.Trans.Maybe
@@ -39,6 +41,7 @@ import Development.IDE.Core.FileExists
39import Development.IDE.Core.FileStore (getFileContents)
41import Development.IDE.Core.FileStore (getFileContents)
40import Development.IDE.Types.Diagnostics
42import Development.IDE.Types.Diagnostics
41import Development.IDE.Types.Location
43import Development.IDE.Types.Location
44+import Development.IDE.GHC.Compat hiding (parseModule, typecheckModule)
42import Development.IDE.GHC.Util
45import Development.IDE.GHC.Util
43import Data.Coerce
46import Data.Coerce
44import Data.Either.Extra
47import Data.Either.Extra
@@ -54,9 +57,7 @@ import Development.Shake hiding (Diagnostic)
54import Development.IDE.Core.RuleTypes
57import Development.IDE.Core.RuleTypes
55import Development.IDE.Spans.Type
58import Development.IDE.Spans.Type
56
59
57−import GHC hiding (parseModule, typecheckModule)
58import qualified GHC.LanguageExtensions as LangExt
60import qualified GHC.LanguageExtensions as LangExt
59−import Development.IDE.GHC.Compat (hie_file_result, readHieFile)
60import UniqSupply
61import UniqSupply
61import NameCache
62import NameCache
62import HscTypes
63import HscTypes
@@ -176,7 +177,7 @@ getLocatedImportsRule =
176-- imports recursively.
177-- imports recursively.
177rawDependencyInformation :: NormalizedFilePath -> Action RawDependencyInformation
178rawDependencyInformation :: NormalizedFilePath -> Action RawDependencyInformation
178rawDependencyInformation f = do
179rawDependencyInformation f = do
179− let (initialId, initialMap) = getPathId f emptyPathIdMap
180+ let (initialId, initialMap) = getPathId (ArtifactsLocation $ ModLocation (Just $ fromNormalizedFilePath f) "" "") emptyPathIdMap
180 go (IntSet.singleton $ getFilePathId initialId)
181 go (IntSet.singleton $ getFilePathId initialId)
181 (RawDependencyInformation IntMap.empty initialMap)
182 (RawDependencyInformation IntMap.empty initialMap)
182 where
183 where
@@ -194,7 +195,7 @@ rawDependencyInformation f = do
194 let rawDepInfo' = insertImport fId (Left ModuleParseError) rawDepInfo
195 let rawDepInfo' = insertImport fId (Left ModuleParseError) rawDepInfo
195 in go fs rawDepInfo'
196 in go fs rawDepInfo'
196 Just (modImports, pkgImports) -> do
197 Just (modImports, pkgImports) -> do
197− let f :: PathIdMap -> (a, Maybe NormalizedFilePath) -> (PathIdMap, (a, Maybe FilePathId))
198+ let f :: PathIdMap -> (a, Maybe ArtifactsLocation) -> (PathIdMap, (a, Maybe FilePathId))
198 f pathMap (imp, mbPath) = case mbPath of
199 f pathMap (imp, mbPath) = case mbPath of
199 Nothing -> (pathMap, (imp, Nothing))
200 Nothing -> (pathMap, (imp, Nothing))
200 Just path ->
201 Just path ->
@@ -265,11 +266,11 @@ getSpanInfoRule :: Rules ()
265getSpanInfoRule =
266getSpanInfoRule =
266 define $ \GetSpanInfo file -> do
267 define $ \GetSpanInfo file -> do
267 tc <- use_ TypeCheck file
268 tc <- use_ TypeCheck file
268− deps <- maybe (TransitiveDependencies [] []) fst <$> useWithStale GetDependencies file
269+ deps <- maybe (TransitiveDependencies [] [] []) fst <$> useWithStale GetDependencies file
269 parsedDeps <- mapMaybe (fmap fst) <$> usesWithStale GetParsedModule (transitiveModuleDeps deps)
270 parsedDeps <- mapMaybe (fmap fst) <$> usesWithStale GetParsedModule (transitiveModuleDeps deps)
270 (fileImports, _) <- use_ GetLocatedImports file
271 (fileImports, _) <- use_ GetLocatedImports file
271 packageState <- hscEnv <$> use_ GhcSession file
272 packageState <- hscEnv <$> use_ GhcSession file
272− x <- liftIO $ getSrcSpanInfos packageState fileImports tc parsedDeps
273+ x <- liftIO $ getSrcSpanInfos packageState (fmap (second (fmap modLocationToNormalizedFilePath)) fileImports) tc parsedDeps
273 return ([], Just x)
274 return ([], Just x)
274
275
275-- Typechecks a module.
276-- Typechecks a module.
src/Development/IDE/GHC/Compat.hs+13−3
@@ -23,6 +23,8 @@ module Development.IDE.GHC.Compat(
23 pattern ValD,
23 pattern ValD,
24 pattern ClassOpSig,
24 pattern ClassOpSig,
25 pattern IEThingWith,
25 pattern IEThingWith,
26+ GHC.ModLocation,
27+ pattern ModLocation,
26
28
27 module GHC
29 module GHC
28 ) where
30 ) where
@@ -32,14 +34,14 @@ import DynFlags
32import FieldLabel
34import FieldLabel
33
35
34import qualified GHC
36import qualified GHC
35−import GHC hiding (ClassOpSig, DerivD, ForD, IEThingWith, InstD, TyClD, ValD)
37+import GHC hiding (ClassOpSig, DerivD, ForD, IEThingWith, InstD, TyClD, ValD, ModLocation)
36
38
37#if MIN_GHC_API_VERSION(8,8,0)
39#if MIN_GHC_API_VERSION(8,8,0)
38import HieAst
40import HieAst
39import HieBin
41import HieBin
40import HieTypes
42import HieTypes
41#else
43#else
42−import GhcPlugins
44+import GhcPlugins hiding (ModLocation)
43import NameCache
45import NameCache
44import Avail
46import Avail
45import TcRnTypes
47import TcRnTypes
@@ -136,4 +138,12 @@ pattern IEThingWith a b c d <-
136 GHC.IEThingWith _ a b c d
138 GHC.IEThingWith _ a b c d
137#else
139#else
138 GHC.IEThingWith a b c d
140 GHC.IEThingWith a b c d
139−#endif
141+#endif
142+
143+pattern ModLocation :: Maybe FilePath -> FilePath -> FilePath -> GHC.ModLocation
144+pattern ModLocation a b c <-
145+#if MIN_GHC_API_VERSION(8,8,0)
146+ GHC.ModLocation a b c _ where ModLocation a b c = GHC.ModLocation a b c ""
147+#else
148+ GHC.ModLocation a b c where ModLocation a b c = GHC.ModLocation a b c
149+#endif
src/Development/IDE/Import/DependencyInformation.hs+71−13
@@ -9,6 +9,7 @@ module Development.IDE.Import.DependencyInformation
9 , ModuleParseError(..)
9 , ModuleParseError(..)
10 , TransitiveDependencies(..)
10 , TransitiveDependencies(..)
11 , FilePathId(..)
11 , FilePathId(..)
12+ , NamedModuleDep(..)
12
13
13 , PathIdMap
14 , PathIdMap
14 , emptyPathIdMap
15 , emptyPathIdMap
@@ -17,7 +18,7 @@ module Development.IDE.Import.DependencyInformation
17 , pathToId
18 , pathToId
18 , idToPath
19 , idToPath
19 , reachableModules
20 , reachableModules
20−
21+ , modLocationToNormalizedFilePath
21 , processDependencyInformation
22 , processDependencyInformation
22 , transitiveDeps
23 , transitiveDeps
23 ) where
24 ) where
@@ -46,6 +47,7 @@ import GHC.Generics (Generic)
46
47
47import Development.IDE.Types.Diagnostics
48import Development.IDE.Types.Diagnostics
48import Development.IDE.Types.Location
49import Development.IDE.Types.Location
50+import Development.IDE.Import.FindImports (ArtifactsLocation(..))
49
51
50import GHC
52import GHC
51import Module
53import Module
@@ -67,27 +69,34 @@ newtype FilePathId = FilePathId { getFilePathId :: Int }
67 deriving (Show, NFData, Eq, Ord)
69 deriving (Show, NFData, Eq, Ord)
68
70
69data PathIdMap = PathIdMap
71data PathIdMap = PathIdMap
70− { idToPathMap :: !(IntMap NormalizedFilePath)
72+ { idToPathMap :: !(IntMap ArtifactsLocation)
71 , pathToIdMap :: !(HashMap NormalizedFilePath FilePathId)
73 , pathToIdMap :: !(HashMap NormalizedFilePath FilePathId)
72 }
74 }
73 deriving (Show, Generic)
75 deriving (Show, Generic)
74
76
75instance NFData PathIdMap
77instance NFData PathIdMap
76
78
79+modLocationToNormalizedFilePath :: ArtifactsLocation -> NormalizedFilePath
80+modLocationToNormalizedFilePath (ArtifactsLocation loc) =
81+ case ml_hs_file loc of
82+ Just filePath -> toNormalizedFilePath filePath
83+ -- Since we craete all 'ModLocation' values via 'mkHomeModLocation'
84+ Nothing -> error "Has something changed in mkHomeModLocation?"
85+
77emptyPathIdMap :: PathIdMap
86emptyPathIdMap :: PathIdMap
78emptyPathIdMap = PathIdMap IntMap.empty HMS.empty
87emptyPathIdMap = PathIdMap IntMap.empty HMS.empty
79
88
80−getPathId :: NormalizedFilePath -> PathIdMap -> (FilePathId, PathIdMap)
89+getPathId :: ArtifactsLocation -> PathIdMap -> (FilePathId, PathIdMap)
81getPathId path m@PathIdMap{..} =
90getPathId path m@PathIdMap{..} =
82− case HMS.lookup path pathToIdMap of
91+ case HMS.lookup (modLocationToNormalizedFilePath path) pathToIdMap of
83 Nothing ->
92 Nothing ->
84 let !newId = FilePathId $ HMS.size pathToIdMap
93 let !newId = FilePathId $ HMS.size pathToIdMap
85 in (newId, insertPathId path newId m)
94 in (newId, insertPathId path newId m)
86 Just id -> (id, m)
95 Just id -> (id, m)
87
96
88−insertPathId :: NormalizedFilePath -> FilePathId -> PathIdMap -> PathIdMap
97+insertPathId :: ArtifactsLocation -> FilePathId -> PathIdMap -> PathIdMap
89insertPathId path id PathIdMap{..} =
98insertPathId path id PathIdMap{..} =
90− PathIdMap (IntMap.insert (getFilePathId id) path idToPathMap) (HMS.insert path id pathToIdMap)
99+ PathIdMap (IntMap.insert (getFilePathId id) path idToPathMap) (HMS.insert (modLocationToNormalizedFilePath path) id pathToIdMap)
91
100
92insertImport :: FilePathId -> Either ModuleParseError ModuleImports -> RawDependencyInformation -> RawDependencyInformation
101insertImport :: FilePathId -> Either ModuleParseError ModuleImports -> RawDependencyInformation -> RawDependencyInformation
93insertImport (FilePathId k) v rawDepInfo = rawDepInfo { rawImports = IntMap.insert k v (rawImports rawDepInfo) }
102insertImport (FilePathId k) v rawDepInfo = rawDepInfo { rawImports = IntMap.insert k v (rawImports rawDepInfo) }
@@ -96,7 +105,11 @@ pathToId :: PathIdMap -> NormalizedFilePath -> FilePathId
96pathToId PathIdMap{pathToIdMap} path = pathToIdMap HMS.! path
105pathToId PathIdMap{pathToIdMap} path = pathToIdMap HMS.! path
97
106
98idToPath :: PathIdMap -> FilePathId -> NormalizedFilePath
107idToPath :: PathIdMap -> FilePathId -> NormalizedFilePath
108+idToPath pathIdMap filePathId = modLocationToNormalizedFilePath $ idToModLocation pathIdMap filePathId
109+
110+idToModLocation :: PathIdMap -> FilePathId -> ArtifactsLocation
99−idToPath PathIdMap{idToPathMap} (FilePathId id) = idToPathMap IntMap.! id
111+idToModLocation PathIdMap{idToPathMap} (FilePathId id) = idToPathMap IntMap.! id
112+
100
113
101-- | Unprocessed results that we find by following imports recursively.
114-- | Unprocessed results that we find by following imports recursively.
102data RawDependencyInformation = RawDependencyInformation
115data RawDependencyInformation = RawDependencyInformation
@@ -112,6 +125,7 @@ data DependencyInformation =
112 DependencyInformation
125 DependencyInformation
113 { depErrorNodes :: !(IntMap (NonEmpty NodeError))
126 { depErrorNodes :: !(IntMap (NonEmpty NodeError))
114 -- ^ Nodes that cannot be processed correctly.
127 -- ^ Nodes that cannot be processed correctly.
128+ , depModuleNames :: !(IntMap ShowableModuleName)
115 , depModuleDeps :: !(IntMap IntSet)
129 , depModuleDeps :: !(IntMap IntSet)
116 -- ^ For a non-error node, this contains the set of module immediate dependencies
130 -- ^ For a non-error node, this contains the set of module immediate dependencies
117 -- in the same package.
131 -- in the same package.
@@ -120,6 +134,12 @@ data DependencyInformation =
120 , depPathIdMap :: !PathIdMap
134 , depPathIdMap :: !PathIdMap
121 } deriving (Show, Generic)
135 } deriving (Show, Generic)
122
136
137+newtype ShowableModuleName =
138+ ShowableModuleName {showableModuleName :: ModuleName}
139+ deriving NFData
140+
141+instance Show ShowableModuleName where show = moduleNameString . showableModuleName
142+
123reachableModules :: DependencyInformation -> [NormalizedFilePath]
143reachableModules :: DependencyInformation -> [NormalizedFilePath]
124reachableModules DependencyInformation{..} =
144reachableModules DependencyInformation{..} =
125 map (idToPath depPathIdMap . FilePathId) $ IntMap.keys depErrorNodes <> IntMap.keys depModuleDeps
145 map (idToPath depPathIdMap . FilePathId) $ IntMap.keys depErrorNodes <> IntMap.keys depModuleDeps
@@ -186,16 +206,24 @@ processDependencyInformation rawDepInfo@RawDependencyInformation{..} =
186 DependencyInformation
206 DependencyInformation
187 { depErrorNodes = IntMap.fromList errorNodes
207 { depErrorNodes = IntMap.fromList errorNodes
188 , depModuleDeps = moduleDeps
208 , depModuleDeps = moduleDeps
209+ , depModuleNames = IntMap.fromList $ coerce moduleNames
189 , depPkgDeps = pkgDependencies rawDepInfo
210 , depPkgDeps = pkgDependencies rawDepInfo
190 , depPathIdMap = rawPathIdMap
211 , depPathIdMap = rawPathIdMap
191 }
212 }
192 where resultGraph = buildResultGraph rawImports
213 where resultGraph = buildResultGraph rawImports
193 (errorNodes, successNodes) = partitionNodeResults $ IntMap.toList resultGraph
214 (errorNodes, successNodes) = partitionNodeResults $ IntMap.toList resultGraph
215+ moduleNames :: [(FilePathId, ModuleName)]
216+ moduleNames =
217+ [ (fId, modName) | (_, imports) <- successNodes, (L _ modName, fId) <- imports]
194 successEdges :: [(FilePathId, FilePathId, [FilePathId])]
218 successEdges :: [(FilePathId, FilePathId, [FilePathId])]
195 successEdges =
219 successEdges =
220+ map
196− map (\(file, imports) -> (FilePathId file, FilePathId file, map snd imports)) successNodes
221+ (\(file, imports) -> (FilePathId file, FilePathId file, map snd imports))
222+ successNodes
197 moduleDeps =
223 moduleDeps =
224+ IntMap.fromList $
198− IntMap.fromList $ map (\(_, FilePathId v, vs) -> (v, IntSet.fromList $ coerce vs)) successEdges
225+ map (\(_, FilePathId v, vs) -> (v, IntSet.fromList $ coerce vs))
226+ successEdges
199
227
200-- | Given a dependency graph, buildResultGraph detects and propagates errors in that graph as follows:
228-- | Given a dependency graph, buildResultGraph detects and propagates errors in that graph as follows:
201-- 1. Mark each node that is part of an import cycle as an error node.
229-- 1. Mark each node that is part of an import cycle as an error node.
@@ -268,18 +296,27 @@ transitiveDeps DependencyInformation{..} file = do
268 IntSet.delete (getFilePathId fileId) .
296 IntSet.delete (getFilePathId fileId) .
269 IntSet.fromList . map (fst3 . fromVertex) .
297 IntSet.fromList . map (fst3 . fromVertex) .
270 reachable g <$> toVertex (getFilePathId fileId)
298 reachable g <$> toVertex (getFilePathId fileId)
299+ let transitiveModuleDepIds =
271− let transitiveModuleDepIds = filter (\v -> v `IntSet.member` reachableVs) $ map (fst3 . fromVertex) vs
300+ filter (\v -> v `IntSet.member` reachableVs) $ map (fst3 . fromVertex) vs
272 let transitivePkgDeps =
301 let transitivePkgDeps =
273 Set.toList $ Set.unions $
302 Set.toList $ Set.unions $
274 map (\f -> IntMap.findWithDefault Set.empty f depPkgDeps) $
303 map (\f -> IntMap.findWithDefault Set.empty f depPkgDeps) $
275 getFilePathId fileId : transitiveModuleDepIds
304 getFilePathId fileId : transitiveModuleDepIds
305+ let transitiveModuleDeps =
276− let transitiveModuleDeps = map (idToPath depPathIdMap . FilePathId) transitiveModuleDepIds
306+ map (idToPath depPathIdMap . FilePathId) transitiveModuleDepIds
307+ let transitiveNamedModuleDeps =
308+ [ NamedModuleDep (idToPath depPathIdMap (FilePathId fid)) mn ml
309+ | (fid, ShowableModuleName mn) <- IntMap.toList depModuleNames
310+ , let ArtifactsLocation ml = idToPathMap depPathIdMap IntMap.! fid
311+ ]
277 pure TransitiveDependencies {..}
312 pure TransitiveDependencies {..}
313+ where
278− where (g, fromVertex, toVertex) = graphFromEdges (map (\(f, fs) -> (f, f, IntSet.toList fs)) $ IntMap.toList depModuleDeps)
314+ (g, fromVertex, toVertex) = graphFromEdges (map (\(f, fs) -> (f, f, IntSet.toList fs)) $ IntMap.toList depModuleDeps)
279− vs = topSort g
315+ vs = topSort g
280
316
281data TransitiveDependencies = TransitiveDependencies
317data TransitiveDependencies = TransitiveDependencies
282 { transitiveModuleDeps :: [NormalizedFilePath]
318 { transitiveModuleDeps :: [NormalizedFilePath]
319+ , transitiveNamedModuleDeps :: [NamedModuleDep]
283 -- ^ Transitive module dependencies in topological order.
320 -- ^ Transitive module dependencies in topological order.
284 -- The module itself is not included.
321 -- The module itself is not included.
285 , transitivePkgDeps :: [InstalledUnitId]
322 , transitivePkgDeps :: [InstalledUnitId]
@@ -287,3 +324,24 @@ data TransitiveDependencies = TransitiveDependencies
287 } deriving (Eq, Show, Generic)
324 } deriving (Eq, Show, Generic)
288
325
289instance NFData TransitiveDependencies
326instance NFData TransitiveDependencies
327+
328+data NamedModuleDep = NamedModuleDep {
329+ nmdFilePath :: !NormalizedFilePath,
330+ nmdModuleName :: !ModuleName,
331+ nmdModLocation :: !ModLocation
332+ }
333+ deriving Generic
334+
335+instance Eq NamedModuleDep where
336+ a == b = nmdFilePath a == nmdFilePath b
337+
338+instance NFData NamedModuleDep where
339+ rnf NamedModuleDep{..} =
340+ rnf nmdFilePath `seq`
341+ rnf nmdModuleName `seq`
342+ -- 'ModLocation' lacks an 'NFData' instance
343+ rwhnf nmdModLocation
344+
345+instance Show NamedModuleDep where
346+ show NamedModuleDep{..} = show nmdFilePath
347+
src/Development/IDE/Import/FindImports.hs+15−3
@@ -7,6 +7,7 @@
7module Development.IDE.Import.FindImports
7module Development.IDE.Import.FindImports
8 ( locateModule
8 ( locateModule
9 , Import(..)
9 , Import(..)
10+ , ArtifactsLocation(..)
10 ) where
11 ) where
11
12
12import Development.IDE.GHC.Error as ErrUtils
13import Development.IDE.GHC.Error as ErrUtils
@@ -29,10 +30,16 @@ import Control.Monad.IO.Class
29import System.FilePath
30import System.FilePath
30
31
31data Import
32data Import
32− = FileImport !NormalizedFilePath
33+ = FileImport !ArtifactsLocation
33 | PackageImport !M.InstalledUnitId
34 | PackageImport !M.InstalledUnitId
34 deriving (Show)
35 deriving (Show)
35
36
37+newtype ArtifactsLocation = ArtifactsLocation ModLocation
38+ deriving (Show)
39+
40+instance NFData ArtifactsLocation where
41+ rnf = const ()
42+
36instance NFData Import where
43instance NFData Import where
37 rnf (FileImport x) = rnf x
44 rnf (FileImport x) = rnf x
38 rnf (PackageImport x) = rnf x
45 rnf (PackageImport x) = rnf x
@@ -74,7 +81,7 @@ locateModule dflags exts doesExist modName mbPkgName isSource = do
74 mbFile <- locateModuleFile dflags exts doesExist isSource $ unLoc modName
81 mbFile <- locateModuleFile dflags exts doesExist isSource $ unLoc modName
75 case mbFile of
82 case mbFile of
76 Nothing -> return $ Left $ notFoundErr dflags modName $ LookupNotFound []
83 Nothing -> return $ Left $ notFoundErr dflags modName $ LookupNotFound []
77− Just file -> return $ Right $ FileImport file
84+ Just file -> toModLocation file
78 -- if a package name is given we only go look for a package
85 -- if a package name is given we only go look for a package
79 Just _pkgName -> lookupInPackageDB dflags
86 Just _pkgName -> lookupInPackageDB dflags
80 Nothing -> do
87 Nothing -> do
@@ -83,8 +90,13 @@ locateModule dflags exts doesExist modName mbPkgName isSource = do
83 mbFile <- locateModuleFile dflags exts doesExist isSource $ unLoc modName
90 mbFile <- locateModuleFile dflags exts doesExist isSource $ unLoc modName
84 case mbFile of
91 case mbFile of
85 Nothing -> lookupInPackageDB dflags
92 Nothing -> lookupInPackageDB dflags
86− Just file -> return $ Right $ FileImport file
93+ Just file -> toModLocation file
87 where
94 where
95+ toModLocation file = liftIO $ do
96+ loc <- mkHomeModLocation dflags (unLoc modName) (fromNormalizedFilePath file)
97+ return $ Right $ FileImport $ ArtifactsLocation loc
98+
99+
88 lookupInPackageDB dfs =
100 lookupInPackageDB dfs =
89 case lookupModuleWithSuggestions dfs (unLoc modName) mbPkgName of
101 case lookupModuleWithSuggestions dfs (unLoc modName) mbPkgName of
90 LookupFound _m pkgConfig -> return $ Right $ PackageImport $ unitId pkgConfig
102 LookupFound _m pkgConfig -> return $ Right $ PackageImport $ unitId pkgConfig
src/Development/IDE/Plugin/Completions.hs+1−1
@@ -31,7 +31,7 @@ plugin = Plugin produceCompletions setHandlersCompletion
31produceCompletions :: Rules ()
31produceCompletions :: Rules ()
32produceCompletions =
32produceCompletions =
33 define $ \ProduceCompletions file -> do
33 define $ \ProduceCompletions file -> do
34− deps <- maybe (TransitiveDependencies [] []) fst <$> useWithStale GetDependencies file
34+ deps <- maybe (TransitiveDependencies [] [] []) fst <$> useWithStale GetDependencies file
35 parsedDeps <- mapMaybe (fmap fst) <$> usesWithStale GetParsedModule (transitiveModuleDeps deps)
35 parsedDeps <- mapMaybe (fmap fst) <$> usesWithStale GetParsedModule (transitiveModuleDeps deps)
36 tm <- fmap fst <$> useWithStale TypeCheck file
36 tm <- fmap fst <$> useWithStale TypeCheck file
37 packageState <- fmap (hscEnv . fst) <$> useWithStale GhcSession file
37 packageState <- fmap (hscEnv . fst) <$> useWithStale GhcSession file