hsdev 0.1.3.0 → 0.1.3.1
raw patch · 5 files changed
+60/−15 lines, 5 filesdep −monad-controlPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: monad-control
API changes (from Hackage documentation)
- HsDev.Symbols.Util: inDepsOf :: Info -> ModuleId -> Bool
+ HsDev.Symbols.Util: inDepsOfFile :: Project -> FilePath -> ModuleId -> Bool
+ HsDev.Symbols.Util: inDepsOfProject :: Project -> ModuleId -> Bool
+ HsDev.Symbols.Util: inDepsOfTarget :: Info -> ModuleId -> Bool
Files
- hsdev.cabal +1/−3
- src/HsDev/Client/Commands.hs +31/−3
- src/HsDev/Commands.hs +1/−1
- src/HsDev/Symbols/Resolve.hs +12/−4
- src/HsDev/Symbols/Util.hs +15/−4
hsdev.cabal view
@@ -2,7 +2,7 @@ -- see http://haskell.org/cabal/users-guide/ name: hsdev -version: 0.1.3.0 +version: 0.1.3.1 synopsis: Haskell development library and tool with support of autocompletion, symbol info, go to declaration, find references etc. description: Haskell development library and tool with support of autocompletion, symbol info, go to declaration, find references, hayoo search etc. @@ -99,8 +99,6 @@ haskell-src-exts >= 1.16.0, hdocs >= 0.4.0, HTTP >= 4000.2.0, - -- ghc-mod workaround - monad-control >= 0.3 && < 1.0, monad-loops >= 0.4, mtl >= 2.1.0, network >= 2.4.0,
src/HsDev/Client/Commands.hs view
@@ -81,6 +81,8 @@ -- Context free commands cmdList' "modules" [] (sandboxes ++ [ manyReq $ projectArg `desc` "projects to list modules from", + moduleArg, + depsArg, noLastArg, manyReq packageArg, sourced, standaloned]) @@ -92,13 +94,13 @@ projectArg `desc` "related project", fileArg `desc` "source file", moduleArg, localsArg, - packageArg, noLastArg, packageVersionArg, + packageArg, depsArg, noLastArg, packageVersionArg, sourced, standaloned]) "get symbol info" symbol', cmd' "module" [] (sandboxes ++ [ moduleArg, localsArg, - packageArg, noLastArg, packageVersionArg, + packageArg, depsArg, noLastArg, packageVersionArg, projectArg `desc` "module project", fileArg `desc` "module source file", sourced]) @@ -172,6 +174,7 @@ cacheFile = req "cache-file" "path" `desc` "cache file" ctx = [fileArg `desc` "source file", sandboxArg] dataArg = req "data" "contents" `desc` "data to pass to command" + depsArg = req "deps" "object" `desc` "filter to such that in dependency of specified object (file or project)" exportsArg = flag "exports" `short` ['e'] `desc` "resolve module exports" fileArg = req "file" "path" `short` ['f'] findArg = req "find" "query" `desc` "infix match" @@ -329,17 +332,20 @@ listModules' _ as copts = do dbval <- getDb copts projs <- traverse (findProject copts) $ listArg "project" as + deps <- traverse (findDep copts) $ listArg "deps" as cabals <- getSandboxes copts as let packages = listArg "package" as - hasFilters = not $ null projs && null packages && null cabals + hasFilters = not $ null projs && null packages && null cabals && null deps filters = allOf $ catMaybes [ if hasFilters then Just $ anyOf $ catMaybes [ if null projs then Nothing else Just (\m -> any (`inProject` m) projs), + if null deps then Nothing else Just (\m -> any (`inDeps` m) deps), if null packages && null cabals then Nothing else Just (\m -> (any (`inPackage` m) packages || null packages) && (any (`inCabal` m) cabals || null cabals))] else Nothing, + fmap (\n m -> fromString n == moduleIdName m) $ arg "module" as, if flagSet "src" as then Just byFile else Nothing, if flagSet "stand" as then Just standalone else Nothing] return $ map moduleId $ newest as $ selectModules (filters . moduleId) dbval @@ -364,6 +370,7 @@ dbval <- liftM (localsDatabase as) $ getDb copts proj <- traverse (findProject copts) $ arg "project" as file <- traverse (findPath copts) $ arg "file" as + deps <- traverse (findDep copts) $ arg "deps" as cabal <- getCabal_ copts as let filters = checkModule $ allOf $ catMaybes [ @@ -371,6 +378,7 @@ fmap inFile file, fmap inModule (arg "module" as), fmap inPackage (arg "package" as), + fmap inDeps deps, fmap inVersion (arg "version" as), fmap inCabal cabal, if flagSet "src" as then Just byFile else Nothing, @@ -390,6 +398,7 @@ proj <- mapErrorT (fmap $ strMsg +++ id) $ traverse (findProject copts) $ arg "project" as cabal <- mapErrorT (fmap $ strMsg +++ id) $ getCabal_ copts as file' <- mapErrorT (fmap $ strMsg +++ id) $ traverse (findPath copts) $ arg "file" as + deps <- mapErrorT (fmap $ strMsg +++ id) $ traverse (findDep copts) $ arg "deps" as let filters = allOf $ catMaybes [ fmap inProject proj, @@ -397,6 +406,7 @@ fmap inFile file', fmap inModule (arg "module" as), fmap inPackage (arg "package" as), + fmap inDeps deps, fmap inVersion (arg "version" as), if flagSet "src" as then Just byFile else Nothing] rs <- mapErrorT (fmap $ strMsg +++ id) $ @@ -667,6 +677,24 @@ addCabal p | takeExtension p == ".cabal" = p | otherwise = p </> (takeBaseName p <.> "cabal") + +-- | Find dependency: it may be source, project file or project name +findDep :: (MonadIO m, Error e) => CommandOptions -> String -> ErrorT e m (Project, Maybe FilePath) +findDep copts depName = do + proj <- msum [ + mapErrorStr $ do + p <- liftIO (locateProject depName) + maybe (throwError $ strMsg $ "Project " ++ depName ++ " not found") (mapErrorT liftIO . loadProject) p, + findProject copts depName] + src <- if takeExtension depName == ".hs" + then liftM Just (findPath copts depName) + else return Nothing + return (proj, src) + +-- | Check if project or source depends from this module +inDeps :: (Project, Maybe FilePath) -> ModuleId -> Bool +inDeps (proj, Just src) = inDepsOfFile proj src +inDeps (proj, Nothing) = inDepsOfProject proj -- | Supply module with its source file path if any toPair :: Module -> Maybe (FilePath, Module)
src/HsDev/Commands.hs view
@@ -188,4 +188,4 @@ (maybe (const True) inProject mproj) (liftM2 (&&) (restrictCabal cabal) - (maybe (const True) inDepsOf (join $ fileTarget <$> mproj <*> pure file))) + (maybe (const True) inDepsOfTarget (join $ fileTarget <$> mproj <*> pure file)))
src/HsDev/Symbols/Resolve.hs view
@@ -15,7 +15,7 @@ import Data.List (sortBy, groupBy, find) import Data.Map (Map) import qualified Data.Map as M -import Data.Maybe (fromMaybe, maybeToList) +import Data.Maybe (fromMaybe, maybeToList, listToMaybe) import Data.Monoid (mconcat, mappend) import Data.Ord (comparing) import Data.String (fromString) @@ -83,7 +83,9 @@ moduleExports $ m return $ ResolvedModule m (sortDeclarations scope') (sortDeclarations exports') thisDecls :: [Declaration] - thisDecls = map selfImport $ moduleDeclarations m + thisDecls = map (selfDefined . selfImport) $ moduleDeclarations m + selfDefined :: Declaration -> Declaration + selfDefined d = d { declarationDefined = Just (moduleId m) } selfImport :: Declaration -> Declaration selfImport d = d { declarationImported = Just [import_ $ moduleName m] } save :: ResolveM ResolvedModule -> ResolveM ResolvedModule @@ -128,8 +130,14 @@ setImport :: Import -> Declaration -> Declaration setImport i' d' = d' { declarationImported = Just [i'] `mappend` declarationImported d' } selectImport :: Import -> [ModuleId -> Bool] -> ResolveM [Module] - selectImport i' fs = liftM (selectModules select') ask where - select' md = moduleName md == importModuleName i' && any ($ moduleId md) (byImport i' : fs) + selectImport i' fs = do + db <- ask + return $ + fromMaybe [] $ + listToMaybe $ dropWhile null $ + [selectModules (select' f) db | f <- byImport i' : fs] + where + select' f md = moduleName md == importModuleName i' && f (moduleId md) filterImportList :: [Declaration] -> [Declaration] filterImportList = case importList i of Nothing -> id
src/HsDev/Symbols/Util.hs view
@@ -1,6 +1,6 @@ module HsDev.Symbols.Util ( projectOf, cabalOf, packageOf, - inProject, inDepsOf, inCabal, inPackage, inVersion, inFile, inModuleSource, inModule, byFile, byCabal, standalone, + inProject, inDepsOfTarget, inDepsOfFile, inDepsOfProject, inCabal, inPackage, inVersion, inFile, inModuleSource, inModule, byFile, byCabal, standalone, imports, qualifier, imported, visible, inScope, newestPackage, sourceModule, visibleModule, preferredModule, uniqueModules, @@ -8,9 +8,10 @@ ) where import Control.Arrow ((***), (&&&), first) +import Control.Monad (liftM) import Data.Function (on) import Data.Maybe -import Data.List (maximumBy, groupBy, sortBy, partition) +import Data.List (maximumBy, groupBy, sortBy, partition, nub) import Data.Ord (comparing) import Data.String (fromString) import System.FilePath (normalise) @@ -41,8 +42,18 @@ inProject p m = projectOf m == Just p -- | Check if module in deps of project target -inDepsOf :: Info -> ModuleId -> Bool -inDepsOf i m = any (`inPackage` m) $ infoDepends i +inDepsOfTarget :: Info -> ModuleId -> Bool +inDepsOfTarget i m = any (`inPackage` m) $ infoDepends i + +-- | Check if module in deps of source +inDepsOfFile :: Project -> FilePath -> ModuleId -> Bool +inDepsOfFile p f = maybe (const False) inDepsOfTarget $ fileTarget p f + +-- | Check if module in deps of project +inDepsOfProject :: Project -> ModuleId -> Bool +inDepsOfProject = maybe (const False) (anyPackage . nub . concatMap infoDepends . infos) . projectDescription where + anyPackage :: [String] -> ModuleId -> Bool + anyPackage = liftM or . mapM inPackage -- | Check if module in cabal inCabal :: Cabal -> ModuleId -> Bool