@@ -23,7 +23,8 @@ import Development.IDE.Types.Location
2323-- standard imports
2424import Control.Monad.Extra
2525import Control.Monad.IO.Class
26- import Data.List (isSuffixOf )
26+ import Data.List (isSuffixOf , find )
27+ import qualified Data.Set as S
2728import Data.Maybe
2829import System.FilePath
2930
@@ -70,19 +71,30 @@ modSummaryToArtifactsLocation nfp ms = ArtifactsLocation nfp (ms_location <$> ms
7071 Just modSum -> isSource (ms_hsc_src modSum)
7172 mbMod = ms_mod <$> ms
7273
74+ data LocateResult
75+ = LocateNotFound
76+ | LocateFoundReexport UnitId
77+ | LocateFoundFile UnitId NormalizedFilePath
78+
7379-- | locate a module in the file system. Where we go from *daml to Haskell
7480locateModuleFile :: MonadIO m
75- => [(UnitId , [FilePath ])]
81+ => [(UnitId , [FilePath ], S. Set ModuleName )]
7682 -> [String ]
7783 -> (ModuleName -> NormalizedFilePath -> m (Maybe NormalizedFilePath ))
7884 -> Bool
7985 -> ModuleName
80- -> m ( Maybe ( UnitId , NormalizedFilePath ))
86+ -> m LocateResult
8187locateModuleFile import_dirss exts targetFor isSource modName = do
8288 let candidates import_dirs =
8389 [ toNormalizedFilePath' (prefix </> moduleNameSlashes modName <.> maybeBoot ext)
8490 | prefix <- import_dirs , ext <- exts]
85- firstJustM go (concat [map (uid,) (candidates dirs) | (uid, dirs) <- import_dirss])
91+ mf <- firstJustM go (concat [map (uid,) (candidates dirs) | (uid, dirs, _) <- import_dirss])
92+ case mf of
93+ Nothing ->
94+ case find (\ (uid, _, reexports) -> S. member modName reexports) import_dirss of
95+ Just (uid,_,_) -> pure $ LocateFoundReexport uid
96+ Nothing -> pure $ LocateNotFound
97+ Just (uid,file) -> pure $ LocateFoundFile uid file
8698 where
8799 go (uid, candidate) = fmap ((uid,) <$> ) $ targetFor modName candidate
88100 maybeBoot ext
@@ -94,11 +106,11 @@ locateModuleFile import_dirss exts targetFor isSource modName = do
94106-- current module. In particular, it will return Nothing for 'main' components
95107-- as they can never be imported into another package.
96108#if MIN_VERSION_ghc(9,3,0)
97- mkImportDirs :: HscEnv -> (UnitId , DynFlags ) -> Maybe (UnitId , [FilePath ])
98- mkImportDirs _env (i, flags) = Just (i, importPaths flags)
109+ mkImportDirs :: HscEnv -> (UnitId , DynFlags ) -> Maybe (UnitId , ( [FilePath ], S. Set ModuleName ) )
110+ mkImportDirs _env (i, flags) = Just (i, ( importPaths flags, reexportedModules flags) )
99111#else
100- mkImportDirs :: HscEnv -> (UnitId , DynFlags ) -> Maybe (PackageName , (UnitId , [FilePath ]))
101- mkImportDirs env (i, flags) = (, (i, importPaths flags)) <$> getUnitName env i
112+ mkImportDirs :: HscEnv -> (UnitId , DynFlags ) -> Maybe (PackageName , (UnitId , [FilePath ], S. Set ModuleName ))
113+ mkImportDirs env (i, flags) = (, (i, importPaths flags, S. empty )) <$> getUnitName env i
102114#endif
103115
104116-- | locate a module in either the file system or the package database. Where we go from *daml to
@@ -125,16 +137,16 @@ locateModule env comp_info exts targetFor modName mbPkgName isSource = do
125137#else
126138 Just " this" -> do
127139#endif
128- lookupLocal (homeUnitId_ dflags) (importPaths dflags)
140+ lookupLocal (homeUnitId_ dflags) (importPaths dflags) S. empty
129141 -- if a package name is given we only go look for a package
130142#if MIN_VERSION_ghc(9,3,0)
131143 OtherPkg uid
132- | Just dirs <- lookup uid import_paths
133- -> lookupLocal uid dirs
144+ | Just ( dirs, reexports) <- lookup uid import_paths
145+ -> lookupLocal uid dirs reexports
134146#else
135147 Just pkgName
136- | Just (uid, dirs) <- lookup (PackageName pkgName) import_paths
137- -> lookupLocal uid dirs
148+ | Just (uid, dirs, reexports ) <- lookup (PackageName pkgName) import_paths
149+ -> lookupLocal uid dirs reexports
138150#endif
139151 | otherwise -> lookupInPackageDB
140152#if MIN_VERSION_ghc(9,3,0)
@@ -143,10 +155,12 @@ locateModule env comp_info exts targetFor modName mbPkgName isSource = do
143155 Nothing -> do
144156#endif
145157
146- mbFile <- locateModuleFile ((homeUnitId_ dflags, importPaths dflags) : other_imports) exts targetFor isSource $ unLoc modName
158+ mbFile <- locateModuleFile ((homeUnitId_ dflags, importPaths dflags, S. empty ) : other_imports) exts targetFor isSource $ unLoc modName
147159 case mbFile of
148- Nothing -> lookupInPackageDB
149- Just (uid, file) -> toModLocation uid file
160+ LocateNotFound -> lookupInPackageDB
161+ -- Lookup again with the perspective of the module reexporting the file
162+ LocateFoundReexport uid -> locateModule (hscSetActiveUnitId uid env) comp_info exts targetFor modName noPkgQual isSource
163+ LocateFoundFile uid file -> toModLocation uid file
150164 where
151165 dflags = hsc_dflags env
152166 import_paths = mapMaybe (mkImportDirs env) comp_info
@@ -160,7 +174,7 @@ locateModule env comp_info exts targetFor modName mbPkgName isSource = do
160174 -- about which module unit a imports.
161175 -- Without multi-component support it is hard to recontruct the dependency environment so
162176 -- unit a will have both unit b and unit c in scope.
163- map (\ uid -> (uid, importPaths ( homeUnitEnv_dflags (ue_findHomeUnitEnv uid ue)) )) hpt_deps
177+ map (\ uid -> let this_df = homeUnitEnv_dflags (ue_findHomeUnitEnv uid ue) in (uid, importPaths this_df, reexportedModules this_df )) hpt_deps
164178 ue = hsc_unit_env env
165179 units = homeUnitEnv_units $ ue_findHomeUnitEnv (homeUnitId_ dflags) ue
166180 hpt_deps :: [UnitId ]
@@ -186,11 +200,13 @@ locateModule env comp_info exts targetFor modName mbPkgName isSource = do
186200 let genMod = mkModule (RealUnit $ Definite uid) (unLoc modName) -- TODO support backpack holes
187201 return $ Right $ FileImport $ ArtifactsLocation file (Just loc) (not isSource) (Just genMod)
188202
189- lookupLocal uid dirs = do
190- mbFile <- locateModuleFile [(uid, dirs)] exts targetFor isSource $ unLoc modName
203+ lookupLocal uid dirs reexports = do
204+ mbFile <- locateModuleFile [(uid, dirs, reexports )] exts targetFor isSource $ unLoc modName
191205 case mbFile of
192- Nothing -> return $ Left $ notFoundErr env modName $ LookupNotFound []
193- Just (uid', file) -> toModLocation uid' file
206+ LocateNotFound -> return $ Left $ notFoundErr env modName $ LookupNotFound []
207+ -- Lookup again with the perspective of the module reexporting the file
208+ LocateFoundReexport uid -> locateModule (hscSetActiveUnitId uid env) comp_info exts targetFor modName noPkgQual isSource
209+ LocateFoundFile uid' file -> toModLocation uid' file
194210
195211 lookupInPackageDB = do
196212 case Compat. lookupModuleWithSuggestions env (unLoc modName) mbPkgName of
@@ -235,3 +251,11 @@ notFound = NotFound
235251 , fr_unusables = []
236252 , fr_suggestions = []
237253 }
254+
255+ #if MIN_VERSION_ghc(9,3,0)
256+ noPkgQual :: PkgQual
257+ noPkgQual = NoPkgQual
258+ #else
259+ noPkgQual :: Maybe a
260+ noPkgQual = Nothing
261+ #endif
0 commit comments