module Language.Haskell.Tools.Refactor.Querying where import Control.Monad.Trans.Except (ExceptT, runExceptT, throwE) import Data.List ((++), map, find) import Data.Aeson (Value) import GHC (RealSrcSpan, Ghc) import Language.Haskell.Tools.AST () import Language.Haskell.Tools.Refactor.Monad (ProjectRefactoring, Refactoring) import Language.Haskell.Tools.Refactor.Prepare (correctRefactorSpan, readSrcSpan) import Language.Haskell.Tools.Refactor.Representation (RefactorChange, ModuleDom) data QueryChoice = LocationQuery { queryName :: String , locationQuery :: RealSrcSpan -> ModuleDom -> [ModuleDom] -> QueryMonad Value } type QueryMonad = ExceptT String Ghc queryCommands :: [QueryChoice] -> [String] queryCommands = map queryName queryError :: String -> QueryMonad a queryError = throwE performQuery :: [QueryChoice] -- ^ The set of available queries -> [String] -- ^ The query command -> Either FilePath ModuleDom -- ^ The module in which the refactoring is performed -> [ModuleDom] -- ^ Other modules -> Ghc (Either String Value) performQuery queries (name:args) mod mods = case (query, mod, args) of (Just (LocationQuery _ query), Right mod, sp:_) -> runExceptT $ query (correctRefactorSpan (snd mod) $ readSrcSpan sp) mod mods (Just (LocationQuery _ query), _, _) -> return $ Left $ "The query '" ++ name ++ "' needs one argument: a source range" (Nothing, _, _) -> return $ Left $ "Unknown command: " ++ name where query = find ((== name) . queryName) queries