module Language.PureScript.Ide.Filter
(Filter, moduleFilter, prefixFilter, equalityFilter, dependencyFilter,
runFilter, applyFilters)
where
import Prelude ()
import Prelude.Compat
import Control.Monad
import Data.Aeson
import Data.Foldable
import Data.Maybe (listToMaybe, mapMaybe)
import Data.Monoid
import Data.Text (Text, isPrefixOf)
import Language.PureScript.Ide.Types
newtype Filter = Filter (Endo [Module]) deriving(Monoid)
mkFilter :: ([Module] -> [Module]) -> Filter
mkFilter = Filter . Endo
moduleFilter :: [ModuleIdent] -> Filter
moduleFilter =
mkFilter . moduleFilter'
moduleFilter' :: [ModuleIdent] -> [Module] -> [Module]
moduleFilter' moduleIdents = filter (flip elem moduleIdents . fst)
dependencyFilter :: [ModuleIdent] -> Filter
dependencyFilter = mkFilter . dependencyFilter'
dependencyFilter' :: [ModuleIdent] -> [Module] -> [Module]
dependencyFilter' moduleIdents mods =
moduleFilter' (concatMap (getDepForModule mods) moduleIdents) mods
where
getDepForModule :: [Module] -> ModuleIdent -> [ModuleIdent]
getDepForModule ms moduleIdent =
moduleIdent : maybe [] extractDeps (findModule moduleIdent ms)
findModule :: ModuleIdent -> [Module] -> Maybe Module
findModule i ms = listToMaybe $ filter go ms
where go (mn, _) = i == mn
extractDeps :: Module -> [ModuleIdent]
extractDeps = mapMaybe extractDep . snd
where extractDep (Dependency n _ _) = Just n
extractDep _ = Nothing
prefixFilter :: Text -> Filter
prefixFilter "" = mkFilter id
prefixFilter t = mkFilter $ identFilter prefix t
where
prefix :: ExternDecl -> Text -> Bool
prefix (FunctionDecl name _) search = search `isPrefixOf` name
prefix (DataDecl name _) search = search `isPrefixOf` name
prefix (ModuleDecl name _) search = search `isPrefixOf` name
prefix _ _ = False
equalityFilter :: Text -> Filter
equalityFilter = mkFilter . identFilter equality
where
equality :: ExternDecl -> Text -> Bool
equality (FunctionDecl name _) prefix = prefix == name
equality (DataDecl name _) prefix = prefix == name
equality _ _ = False
identFilter :: (ExternDecl -> Text -> Bool ) -> Text -> [Module] -> [Module]
identFilter predicate search =
filter (not . null . snd) . fmap filterModuleDecls
where
filterModuleDecls :: Module -> Module
filterModuleDecls (moduleIdent,decls) =
(moduleIdent, filter (`predicate` search) decls)
runFilter :: Filter -> [Module] -> [Module]
runFilter (Filter f)= appEndo f
applyFilters :: [Filter] -> [Module] -> [Module]
applyFilters = runFilter . fold
instance FromJSON Filter where
parseJSON = withObject "filter" $ \o -> do
(filter' :: String) <- o .: "filter"
case filter' of
"exact" -> do
params <- o .: "params"
search <- params .: "search"
return $ equalityFilter search
"prefix" -> do
params <- o.: "params"
search <- params .: "search"
return $ prefixFilter search
"modules" -> do
params <- o .: "params"
modules <- params .: "modules"
return $ moduleFilter modules
"dependencies" -> do
params <- o .: "params"
deps <- params .: "modules"
return $ dependencyFilter deps
_ -> mzero