Skip to content

Commit fdb1975

Browse files
committed
Implement lookupMod function
1 parent 2aecda9 commit fdb1975

File tree

2 files changed

+86
-3
lines changed

2 files changed

+86
-3
lines changed

ghcide/src/Development/IDE/Core/Actions.hs

Lines changed: 85 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@ module Development.IDE.Core.Actions
1010
, lookupMod
1111
) where
1212

13+
import Control.Concurrent.MVar (MVar, newEmptyMVar,
14+
putMVar, readMVar)
15+
import Control.Concurrent.STM (atomically)
16+
import Control.Concurrent.STM.TQueue (unGetTQueue)
17+
import Control.Monad (unless)
1318
import Control.Monad.Extra (mapMaybeM)
1419
import Control.Monad.Reader
1520
import Control.Monad.Trans.Maybe
21+
import qualified Data.ByteString as BS
22+
import Data.Function ((&))
1623
import qualified Data.HashMap.Strict as HM
1724
import Data.Maybe
1825
import qualified Data.Text as T
1926
import Data.Tuple.Extra
27+
import Development.IDE.Core.Compile (loadHieFile)
2028
import Development.IDE.Core.OfInterest
2129
import Development.IDE.Core.PluginUtils
2230
import Development.IDE.Core.PositionMapping
@@ -33,18 +41,92 @@ import Language.LSP.Protocol.Types (DocumentHighlight (..),
3341
SymbolInformation (..),
3442
normalizedFilePathToUri,
3543
uriToNormalizedFilePath)
44+
import Language.LSP.Server (resRootPath)
45+
import System.Directory (createDirectoryIfMissing,
46+
doesFileExist,
47+
getPermissions,
48+
setOwnerExecutable,
49+
setOwnerWritable,
50+
setPermissions)
51+
import System.FilePath (takeDirectory, (<.>),
52+
(</>))
3653

3754

38-
-- | Eventually this will lookup/generate URIs for files in dependencies, but not in the
39-
-- project. Right now, this is just a stub.
55+
-- | Generates URIs for files in dependencies, but not in the
56+
-- project. Dependency files are produced from an HIE file and
57+
-- placed in the .hls/dependencies directory.
4058
lookupMod
4159
:: HieDbWriter -- ^ access the database
4260
-> FilePath -- ^ The `.hie` file we got from the database
4361
-> ModuleName
4462
-> Unit
4563
-> Bool -- ^ Is this file a boot file?
4664
-> MaybeT IdeAction Uri
47-
lookupMod _dbchan _hie_f _mod _uid _boot = MaybeT $ pure Nothing
65+
lookupMod HieDbWriter{indexQueue} hieFile moduleName uid _boot = MaybeT $ do
66+
-- We need the project root directory to determine where to put
67+
-- the .hls directory.
68+
mProjectRoot <- (resRootPath =<<) <$> asks lspEnv
69+
case mProjectRoot of
70+
Nothing -> pure Nothing
71+
Just projectRoot -> do
72+
-- Database writes happen asynchronously. We use an MVar to mark
73+
-- completion of the database update.
74+
completionToken <- liftIO $ newEmptyMVar
75+
-- Write out the contents of the dependency source to the
76+
-- .hls/dependencies directory, generate a URI for that
77+
-- location, and update the HieDb database with the source
78+
-- file location.
79+
moduleUri <- writeAndIndexSource projectRoot completionToken
80+
-- Wait for the database update to be completed.
81+
-- Reading the completionToken is blocked until it has
82+
-- a value.
83+
liftIO $ readMVar completionToken
84+
pure $ Just moduleUri
85+
where
86+
writeAndIndexSource :: FilePath -> MVar () -> IdeAction Uri
87+
writeAndIndexSource projectRoot completionToken = do
88+
fileExists <- liftIO $ doesFileExist writeOutPath
89+
-- No need to write out the file if it already exists.
90+
unless fileExists $ do
91+
nc <- asks ideNc
92+
liftIO $ do
93+
-- Create the directory where we will put the source.
94+
createDirectoryIfMissing True $ takeDirectory writeOutPath
95+
-- Load a raw Bytestring of the source from the HIE file.
96+
moduleSource <- hie_hs_src <$> loadHieFile (mkUpdater nc) hieFile
97+
-- Write the source into the .hls/dependencies directory.
98+
BS.writeFile writeOutPath moduleSource
99+
fileDefaultPermissions <- getPermissions writeOutPath
100+
let filePermissions = fileDefaultPermissions
101+
& setOwnerWritable False
102+
& setOwnerExecutable False
103+
-- Set the source file to readonly permissions.
104+
setPermissions writeOutPath filePermissions
105+
liftIO $ atomically $
106+
unGetTQueue indexQueue $ \withHieDb -> do
107+
withHieDb $ \db ->
108+
-- Add a source file to the database row for
109+
-- the HIE file.
110+
HieDb.addSrcFile db hieFile writeOutPath False
111+
-- Mark completion of the database update.
112+
putMVar completionToken ()
113+
pure $ moduleUri
114+
where
115+
-- The source will be written out in a directory from the
116+
-- name and hash of the package the dependency module is
117+
-- found in. The name and hash are both parts of the UnitId.
118+
writeOutDir :: FilePath
119+
writeOutDir = projectRoot </> ".hls" </> "dependencies" </> show uid
120+
-- The module name is separated into directories, with the
121+
-- last part of the module name giving the name of the
122+
-- haskell file with a .hs extension.
123+
writeOutFile :: FilePath
124+
writeOutFile = moduleNameSlashes moduleName <.> "hs"
125+
writeOutPath :: FilePath
126+
writeOutPath = writeOutDir </> writeOutFile
127+
moduleUri :: Uri
128+
moduleUri = AtPoint.toUri writeOutPath
129+
48130

49131

50132
-- IMPORTANT NOTE : make sure all rules `useWithStaleFastMT`d by these have a "Persistent Stale" rule defined,

ghcide/src/Development/IDE/Spans/AtPoint.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module Development.IDE.Spans.AtPoint (
2020
, defRowToSymbolInfo
2121
, getNamesAtPoint
2222
, toCurrentLocation
23+
, toUri
2324
, rowToLoc
2425
, nameToLocation
2526
, LookupModule

0 commit comments

Comments
 (0)