module Language.PureScript.Ide.State
( getPscIdeState
, getExternFiles
, getModule
, getModuleWithReexports
, getAllModulesWithReexports
, getAllModulesWithReexportsAndCache
, insertModule
, insertModuleSTM
, getCachedRebuild
, resetPscIdeState
, setCachedRebuild
) where
import Prelude ()
import Prelude.Compat
import Control.Concurrent.STM
import Control.Monad.IO.Class
import "monad-logger" Control.Monad.Logger
import Control.Monad.Reader.Class
import qualified Data.Map.Lazy as M
import Data.Maybe (mapMaybe)
import Data.Monoid
import Language.PureScript.Externs
import Language.PureScript.Ide.Externs
import Language.PureScript.Ide.Reexports
import Language.PureScript.Ide.Types
import Language.PureScript.Ide.Util
import qualified Language.PureScript as P
resetPscIdeState :: PscIde m => m ()
resetPscIdeState = do
stateVar <- envStateVar <$> ask
liftIO $ atomically (writeTVar stateVar emptyPscIdeState)
getPscIdeState :: PscIde m => m PscIdeState
getPscIdeState = do
stateVar <- envStateVar <$> ask
liftIO (readTVarIO stateVar)
getExternFiles :: (PscIde m) => m (M.Map P.ModuleName ExternsFile)
getExternFiles = do
stateVar <- envStateVar <$> ask
liftIO (pscIdeStateExternsFiles <$> readTVarIO stateVar)
getAllModulesWithReexports :: (PscIde m) => m [Module]
getAllModulesWithReexports = getAllModulesWithReexports' <$> getPscIdeState
getAllModulesWithReexports' :: PscIdeState -> [Module]
getAllModulesWithReexports' state =
mapMaybe (getModuleWithReexports' state) (M.keys (pscIdeStateModules state))
getAllModulesWithReexportsAndCache
:: (PscIde m)
=> Maybe P.ModuleName
-> m [Module]
getAllModulesWithReexportsAndCache Nothing = getAllModulesWithReexports
getAllModulesWithReexportsAndCache (Just mn) = do
state <- getPscIdeState
cachedRebuild <- getCachedRebuild
case cachedRebuild of
Just (cachedIdent, ef) | cachedIdent == mn ->
pure (getAllModulesWithReexports' (insertModule' ef state))
_ -> getAllModulesWithReexports
getModule :: (PscIde m, MonadLogger m) => ModuleIdent -> m (Maybe Module)
getModule m = getModule' <$> getPscIdeState <*> pure m
getModule' :: PscIdeState -> ModuleIdent -> Maybe Module
getModule' ps mi = (mi,) <$> M.lookup mi (pscIdeStateModules ps)
getModuleWithReexports :: PscIde m => ModuleIdent -> m (Maybe Module)
getModuleWithReexports i = getModuleWithReexports' <$> getPscIdeState <*> pure i
getModuleWithReexports' :: PscIdeState -> ModuleIdent -> Maybe Module
getModuleWithReexports' ps mi =
resolveReexports (pscIdeStateModules ps) <$> getModule' ps mi
insertModule :: (PscIde m, MonadLogger m) =>
ExternsFile -> m ()
insertModule externsFile = do
stateVar <- envStateVar <$> ask
let moduleName = efModuleName externsFile
$(logDebug) $ "Inserting Module: " <> runModuleNameT moduleName
liftIO . atomically $ insertModuleSTM stateVar externsFile
insertModuleSTM :: TVar PscIdeState -> ExternsFile -> STM ()
insertModuleSTM st ef = modifyTVar st (insertModule' ef)
insertModule' :: ExternsFile -> PscIdeState -> PscIdeState
insertModule' ef state =
state
{ pscIdeStateExternsFiles =
M.insert (efModuleName ef) ef (pscIdeStateExternsFiles state)
, pscIdeStateModules = let (mn, decls) = convertExterns ef
in M.insert mn decls (pscIdeStateModules state)
}
setCachedRebuild :: PscIde m => ExternsFile -> m ()
setCachedRebuild ef = do
st <- envStateVar <$> ask
liftIO . atomically . modifyTVar st $ \x ->
x { pscIdeStateCachedRebuild = Just (efModuleName ef, ef) }
getCachedRebuild :: PscIde m => m (Maybe (P.ModuleName, ExternsFile))
getCachedRebuild = pscIdeStateCachedRebuild <$> getPscIdeState