Use package dbs defined by current cradle when dealing with SymbolDBs
This commit is contained in:
parent
fbe0800856
commit
57e2c112dc
@ -1,4 +1,4 @@
|
|||||||
{-# LANGUAGE CPP, BangPatterns #-}
|
{-# LANGUAGE CPP, BangPatterns, DoAndIfThenElse #-}
|
||||||
|
|
||||||
module Language.Haskell.GhcMod.Find
|
module Language.Haskell.GhcMod.Find
|
||||||
#ifndef SPEC
|
#ifndef SPEC
|
||||||
@ -16,21 +16,21 @@ module Language.Haskell.GhcMod.Find
|
|||||||
where
|
where
|
||||||
|
|
||||||
import Control.Applicative ((<$>))
|
import Control.Applicative ((<$>))
|
||||||
import Control.Monad (when, void)
|
import Control.Monad (when, void, (<=<))
|
||||||
import Data.Function (on)
|
import Data.Function (on)
|
||||||
import Data.List (groupBy, sort)
|
import Data.List (groupBy, sort)
|
||||||
import Data.Maybe (fromMaybe)
|
|
||||||
import qualified GHC as G
|
import qualified GHC as G
|
||||||
import Language.Haskell.GhcMod.Convert
|
import Language.Haskell.GhcMod.Convert
|
||||||
|
import Language.Haskell.GhcMod.Gap (listVisibleModules)
|
||||||
import Language.Haskell.GhcMod.Monad
|
import Language.Haskell.GhcMod.Monad
|
||||||
|
import Language.Haskell.GhcMod.PathsAndFiles
|
||||||
import Language.Haskell.GhcMod.Types
|
import Language.Haskell.GhcMod.Types
|
||||||
import Language.Haskell.GhcMod.Utils
|
import Language.Haskell.GhcMod.Utils
|
||||||
import Language.Haskell.GhcMod.PathsAndFiles
|
import Language.Haskell.GhcMod.World (timedPackageCaches)
|
||||||
import Language.Haskell.GhcMod.Gap (listVisibleModules)
|
|
||||||
import Name (getOccString)
|
import Name (getOccString)
|
||||||
import Module (moduleName)
|
import Module (moduleName)
|
||||||
import System.Directory (doesFileExist, getModificationTime)
|
import System.Directory (doesFileExist, getModificationTime)
|
||||||
import System.FilePath ((</>), takeDirectory)
|
import System.FilePath ((</>))
|
||||||
import System.IO
|
import System.IO
|
||||||
|
|
||||||
#ifndef MIN_VERSION_containers
|
#ifndef MIN_VERSION_containers
|
||||||
@ -50,14 +50,14 @@ import qualified Data.Map as M
|
|||||||
-- | Type of function and operation names.
|
-- | Type of function and operation names.
|
||||||
type Symbol = String
|
type Symbol = String
|
||||||
-- | Database from 'Symbol' to \['ModuleString'\].
|
-- | Database from 'Symbol' to \['ModuleString'\].
|
||||||
data SymbolDb = SymbolDb {
|
data SymbolDb = SymbolDb
|
||||||
table :: Map Symbol [ModuleString]
|
{ table :: Map Symbol [ModuleString]
|
||||||
, packageCachePath :: FilePath
|
|
||||||
, symbolDbCachePath :: FilePath
|
, symbolDbCachePath :: FilePath
|
||||||
} deriving (Show)
|
} deriving (Show)
|
||||||
|
|
||||||
isOutdated :: SymbolDb -> IO Bool
|
isOutdated :: (GmEnv m, IOish m) => SymbolDb -> m Bool
|
||||||
isOutdated db = symbolDbCachePath db `isOlderThan` packageCachePath db
|
isOutdated db =
|
||||||
|
liftIO . (isOlderThan (symbolDbCachePath db) <=< timedPackageCaches) =<< cradle
|
||||||
|
|
||||||
----------------------------------------------------------------
|
----------------------------------------------------------------
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ lookupSymbol :: IOish m => Symbol -> SymbolDb -> GhcModT m String
|
|||||||
lookupSymbol sym db = convert' $ lookupSym sym db
|
lookupSymbol sym db = convert' $ lookupSym sym db
|
||||||
|
|
||||||
lookupSym :: Symbol -> SymbolDb -> [ModuleString]
|
lookupSym :: Symbol -> SymbolDb -> [ModuleString]
|
||||||
lookupSym sym db = fromMaybe [] $ M.lookup sym $ table db
|
lookupSym sym db = M.findWithDefault [] sym $ table db
|
||||||
|
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
|
|
||||||
@ -83,14 +83,14 @@ loadSymbolDb = do
|
|||||||
tmpdir <- cradleTempDir <$> cradle
|
tmpdir <- cradleTempDir <$> cradle
|
||||||
file <- liftIO $ chop <$> readProcess ghcMod ["dumpsym", tmpdir] ""
|
file <- liftIO $ chop <$> readProcess ghcMod ["dumpsym", tmpdir] ""
|
||||||
!db <- M.fromAscList . map conv . lines <$> liftIO (readFile file)
|
!db <- M.fromAscList . map conv . lines <$> liftIO (readFile file)
|
||||||
return $ SymbolDb {
|
return $ SymbolDb
|
||||||
table = db
|
{ table = db
|
||||||
, packageCachePath = takeDirectory file </> packageCache
|
|
||||||
, symbolDbCachePath = file
|
, symbolDbCachePath = file
|
||||||
}
|
}
|
||||||
where
|
where
|
||||||
conv :: String -> (Symbol,[ModuleString])
|
conv :: String -> (Symbol,[ModuleString])
|
||||||
conv = read
|
conv = read
|
||||||
|
chop :: String -> String
|
||||||
chop "" = ""
|
chop "" = ""
|
||||||
chop xs = init xs
|
chop xs = init xs
|
||||||
|
|
||||||
@ -102,13 +102,15 @@ loadSymbolDb = do
|
|||||||
-- The file name is printed.
|
-- The file name is printed.
|
||||||
|
|
||||||
dumpSymbol :: IOish m => FilePath -> GhcModT m String
|
dumpSymbol :: IOish m => FilePath -> GhcModT m String
|
||||||
dumpSymbol dir = runGmPkgGhc $ do
|
dumpSymbol dir = do
|
||||||
let cache = dir </> symbolCacheFile
|
crdl <- cradle
|
||||||
pkgdb = dir </> packageCache
|
runGmPkgGhc $ do
|
||||||
|
create <- liftIO $ isOlderThan cache =<< timedPackageCaches crdl
|
||||||
create <- liftIO $ cache `isOlderThan` pkgdb
|
when create $
|
||||||
when create $ (liftIO . writeSymbolCache cache) =<< getGlobalSymbolTable
|
liftIO . writeSymbolCache cache =<< getGlobalSymbolTable
|
||||||
return $ unlines [cache]
|
return $ unlines [cache]
|
||||||
|
where
|
||||||
|
cache = dir </> symbolCacheFile
|
||||||
|
|
||||||
writeSymbolCache :: FilePath
|
writeSymbolCache :: FilePath
|
||||||
-> [(Symbol,[ModuleString])]
|
-> [(Symbol,[ModuleString])]
|
||||||
@ -117,15 +119,16 @@ writeSymbolCache cache sm =
|
|||||||
void . withFile cache WriteMode $ \hdl ->
|
void . withFile cache WriteMode $ \hdl ->
|
||||||
mapM (hPrint hdl) sm
|
mapM (hPrint hdl) sm
|
||||||
|
|
||||||
isOlderThan :: FilePath -> FilePath -> IO Bool
|
-- | Check whether given file is older than any file from the given set.
|
||||||
isOlderThan cache file = do
|
-- Returns True if given file does not exist.
|
||||||
|
isOlderThan :: FilePath -> [TimedFile] -> IO Bool
|
||||||
|
isOlderThan cache files = do
|
||||||
exist <- doesFileExist cache
|
exist <- doesFileExist cache
|
||||||
if not exist then
|
if not exist
|
||||||
return True
|
then return True
|
||||||
else do
|
else do
|
||||||
tCache <- getModificationTime cache
|
tCache <- getModificationTime cache
|
||||||
tFile <- getModificationTime file
|
return $ any (tCache <=) $ map tfTime files -- including equal just in case
|
||||||
return $ tCache <= tFile -- including equal just in case
|
|
||||||
|
|
||||||
-- | Browsing all functions in all system modules.
|
-- | Browsing all functions in all system modules.
|
||||||
getGlobalSymbolTable :: LightGhc [(Symbol,[ModuleString])]
|
getGlobalSymbolTable :: LightGhc [(Symbol,[ModuleString])]
|
||||||
|
@ -75,7 +75,7 @@ getDb (SymDbReq ref _) = do
|
|||||||
|
|
||||||
checkDb :: IOish m => SymDbReq -> SymbolDb -> GhcModT m SymbolDb
|
checkDb :: IOish m => SymDbReq -> SymbolDb -> GhcModT m SymbolDb
|
||||||
checkDb (SymDbReq ref act) db = do
|
checkDb (SymDbReq ref act) db = do
|
||||||
outdated <- liftIO $ isOutdated db
|
outdated <- isOutdated db
|
||||||
if outdated then do
|
if outdated then do
|
||||||
-- async and wait here is unnecessary because this is essentially
|
-- async and wait here is unnecessary because this is essentially
|
||||||
-- synchronous. But Async can be used a cache.
|
-- synchronous. But Async can be used a cache.
|
||||||
|
Loading…
Reference in New Issue
Block a user