packages feed

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 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