Merge branch 'release-5.5.0.0' into release

This commit is contained in:
Daniel Gröber 2016-01-04 20:36:27 +01:00
commit f172704ad0
85 changed files with 6143 additions and 1483 deletions

134
Data/Binary/Generic.hs Normal file
View File

@ -0,0 +1,134 @@
{-# LANGUAGE BangPatterns, CPP, FlexibleInstances, KindSignatures,
ScopedTypeVariables, TypeOperators, TypeSynonymInstances #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
-----------------------------------------------------------------------------
-- |
-- Module : Data.Binary.Generic
-- Copyright : Bryan O'Sullivan
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : Bryan O'Sullivan <bos@serpentine.com>
-- Stability : unstable
-- Portability : Only works with GHC 7.2 and newer
--
-- Instances for supporting GHC generics.
--
-----------------------------------------------------------------------------
module Data.Binary.Generic where
import Control.Applicative
import Data.Binary
import Data.Bits
import GHC.Generics
import Prelude
class GGBinary f where
ggput :: f t -> Put
ggget :: Get (f t)
-- Type without constructors
instance GGBinary V1 where
ggput _ = return ()
ggget = return undefined
-- Constructor without arguments
instance GGBinary U1 where
ggput U1 = return ()
ggget = return U1
-- Product: constructor with parameters
instance (GGBinary a, GGBinary b) => GGBinary (a :*: b) where
ggput (x :*: y) = ggput x >> ggput y
ggget = (:*:) <$> ggget <*> ggget
-- Metadata (constructor name, etc)
instance GGBinary a => GGBinary (M1 i c a) where
ggput = ggput . unM1
ggget = M1 <$> ggget
-- Constants, additional parameters, and rank-1 recursion
instance Binary a => GGBinary (K1 i a) where
ggput = put . unK1
ggget = K1 <$> get
-- Borrowed from the cereal package.
-- The following GGBinary instance for sums has support for serializing
-- types with up to 2^64-1 constructors. It will use the minimal
-- number of bytes needed to encode the constructor. For example when
-- a type has 2^8 constructors or less it will use a single byte to
-- encode the constructor. If it has 2^16 constructors or less it will
-- use two bytes, and so on till 2^64-1.
#define GUARD(WORD) (size - 1) <= fromIntegral (maxBound :: WORD)
#define PUTSUM(WORD) GUARD(WORD) = putSum (0 :: WORD) (fromIntegral size)
#define GETSUM(WORD) GUARD(WORD) = (get :: Get WORD) >>= checkGetSum (fromIntegral size)
instance ( GSum a, GSum b
, GGBinary a, GGBinary b
, SumSize a, SumSize b) => GGBinary (a :+: b) where
ggput | PUTSUM(Word8) | PUTSUM(Word16) | PUTSUM(Word32) | PUTSUM(Word64)
| otherwise = sizeError "encode" size
where
size = unTagged (sumSize :: Tagged (a :+: b) Word64)
{-# INLINE ggput #-}
ggget | GETSUM(Word8) | GETSUM(Word16) | GETSUM(Word32) | GETSUM(Word64)
| otherwise = sizeError "decode" size
where
size = unTagged (sumSize :: Tagged (a :+: b) Word64)
{-# INLINE ggget #-}
sizeError :: Show size => String -> size -> error
sizeError s size =
error $ "Can't " ++ s ++ " a type with " ++ show size ++ " constructors"
------------------------------------------------------------------------
checkGetSum :: (Ord word, Num word, Bits word, GSum f)
=> word -> word -> Get (f a)
checkGetSum size code | code < size = getSum code size
| otherwise = fail "Unknown encoding for constructor"
{-# INLINE checkGetSum #-}
class GSum f where
getSum :: (Ord word, Num word, Bits word) => word -> word -> Get (f a)
putSum :: (Num w, Bits w, Binary w) => w -> w -> f a -> Put
instance (GSum a, GSum b, GGBinary a, GGBinary b) => GSum (a :+: b) where
getSum !code !size | code < sizeL = L1 <$> getSum code sizeL
| otherwise = R1 <$> getSum (code - sizeL) sizeR
where
sizeL = size `shiftR` 1
sizeR = size - sizeL
{-# INLINE getSum #-}
putSum !code !size s = case s of
L1 x -> putSum code sizeL x
R1 x -> putSum (code + sizeL) sizeR x
where
sizeL = size `shiftR` 1
sizeR = size - sizeL
{-# INLINE putSum #-}
instance GGBinary a => GSum (C1 c a) where
getSum _ _ = ggget
{-# INLINE getSum #-}
putSum !code _ x = put code *> ggput x
{-# INLINE putSum #-}
------------------------------------------------------------------------
class SumSize f where
sumSize :: Tagged f Word64
newtype Tagged (s :: * -> *) b = Tagged {unTagged :: b}
instance (SumSize a, SumSize b) => SumSize (a :+: b) where
sumSize = Tagged $ unTagged (sumSize :: Tagged a Word64) +
unTagged (sumSize :: Tagged b Word64)
instance SumSize (C1 c a) where
sumSize = Tagged 1

View File

@ -44,6 +44,7 @@ module Language.Haskell.GhcMod (
, pkgDoc , pkgDoc
, rootInfo , rootInfo
, types , types
, test
, splits , splits
, sig , sig
, refine , refine
@ -88,3 +89,4 @@ import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Target import Language.Haskell.GhcMod.Target
import Language.Haskell.GhcMod.Output import Language.Haskell.GhcMod.Output
import Language.Haskell.GhcMod.FileMapping import Language.Haskell.GhcMod.FileMapping
import Language.Haskell.GhcMod.Test

View File

@ -12,7 +12,7 @@ import Language.Haskell.GhcMod.Modules
boot :: IOish m => GhcModT m String boot :: IOish m => GhcModT m String
boot = concat <$> sequence ms boot = concat <$> sequence ms
where where
ms = [modules, languages, flags, concat <$> mapM browse preBrowsedModules] ms = [modules False, languages, flags, concat <$> mapM (browse (BrowseOpts False False False)) preBrowsedModules]
preBrowsedModules :: [String] preBrowsedModules :: [String]
preBrowsedModules = [ preBrowsedModules = [

View File

@ -1,5 +1,6 @@
module Language.Haskell.GhcMod.Browse ( module Language.Haskell.GhcMod.Browse (
browse browse,
BrowseOpts(..)
) where ) where
import Control.Applicative import Control.Applicative
@ -13,8 +14,9 @@ import qualified GHC as G
import Language.Haskell.GhcMod.Convert import Language.Haskell.GhcMod.Convert
import Language.Haskell.GhcMod.Doc (showPage, styleUnqualified) import Language.Haskell.GhcMod.Doc (showPage, styleUnqualified)
import Language.Haskell.GhcMod.Gap as Gap import Language.Haskell.GhcMod.Gap as Gap
import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.Types import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.Logging
import Name (getOccString) import Name (getOccString)
import Outputable import Outputable
import TyCon (isAlgTyCon) import TyCon (isAlgTyCon)
@ -25,27 +27,27 @@ import Prelude
---------------------------------------------------------------- ----------------------------------------------------------------
-- | Getting functions, classes, etc from a module. -- | Getting functions, classes, etc from a module.
-- If 'detailed' is 'True', their types are also obtained.
-- If 'operators' is 'True', operators are also returned.
browse :: forall m. IOish m browse :: forall m. IOish m
=> String -- ^ A module name. (e.g. \"Data.List\", "base:Prelude") => BrowseOpts -- ^ Configuration parameters
-> String -- ^ A module name. (e.g. \"Data.List\", "base:Prelude")
-> GhcModT m String -> GhcModT m String
browse pkgmdl = do browse opts pkgmdl = do
convert' . sort =<< go convert' . sort =<< go
where where
-- TODO: Add API to Gm.Target to check if module is home module without -- TODO: Add API to Gm.Target to check if module is home module without
-- bringing up a GHC session as well then this can be made a lot cleaner -- bringing up a GHC session as well then this can be made a lot cleaner
go = ghandle (\(SomeException _) -> return []) $ do go = ghandle (\ex@(SomeException _) -> logException ex >> return []) $ do
goPkgModule `G.gcatch` (\(SomeException _) -> goHomeModule) goPkgModule `G.gcatch` (\(SomeException _) -> goHomeModule)
logException ex =
gmLog GmException "browse" $ showDoc ex
goPkgModule = do goPkgModule = do
opt <- options
runGmPkgGhc $ runGmPkgGhc $
processExports opt =<< tryModuleInfo =<< G.findModule mdlname mpkgid processExports opts =<< tryModuleInfo =<< G.findModule mdlname mpkgid
goHomeModule = runGmlT [Right mdlname] $ do goHomeModule = runGmlT [Right mdlname] $ do
opt <- options processExports opts =<< tryModuleInfo =<< G.findModule mdlname Nothing
processExports opt =<< tryModuleInfo =<< G.findModule mdlname Nothing
tryModuleInfo m = fromJust <$> G.getModuleInfo m tryModuleInfo m = fromJust <$> G.getModuleInfo m
@ -76,31 +78,31 @@ isNotOp (h:_) = isAlpha h || (h == '_')
isNotOp _ = error "isNotOp" isNotOp _ = error "isNotOp"
processExports :: (G.GhcMonad m, MonadIO m, ExceptionMonad m) processExports :: (G.GhcMonad m, MonadIO m, ExceptionMonad m)
=> Options -> ModuleInfo -> m [String] => BrowseOpts -> ModuleInfo -> m [String]
processExports opt minfo = do processExports opt minfo = do
let let
removeOps removeOps
| optOperators opt = id | optBrowseOperators opt = id
| otherwise = filter (isNotOp . getOccString) | otherwise = filter (isNotOp . getOccString)
mapM (showExport opt minfo) $ removeOps $ G.modInfoExports minfo mapM (showExport opt minfo) $ removeOps $ G.modInfoExports minfo
showExport :: forall m. (G.GhcMonad m, MonadIO m, ExceptionMonad m) showExport :: forall m. (G.GhcMonad m, MonadIO m, ExceptionMonad m)
=> Options -> ModuleInfo -> Name -> m String => BrowseOpts -> ModuleInfo -> Name -> m String
showExport opt minfo e = do showExport opt minfo e = do
mtype' <- mtype mtype' <- mtype
return $ concat $ catMaybes [mqualified, Just $ formatOp $ getOccString e, mtype'] return $ concat $ catMaybes [mqualified, Just $ formatOp $ getOccString e, mtype']
where where
mqualified = (G.moduleNameString (G.moduleName $ G.nameModule e) ++ ".") `justIf` optQualified opt mqualified = (G.moduleNameString (G.moduleName $ G.nameModule e) ++ ".") `justIf` optBrowseQualified opt
mtype :: m (Maybe String) mtype :: m (Maybe String)
mtype mtype
| optDetailed opt = do | optBrowseDetailed opt = do
tyInfo <- G.modInfoLookupName minfo e tyInfo <- G.modInfoLookupName minfo e
-- If nothing found, load dependent module and lookup global -- If nothing found, load dependent module and lookup global
tyResult <- maybe (inOtherModule e) (return . Just) tyInfo tyResult <- maybe (inOtherModule e) (return . Just) tyInfo
dflag <- G.getSessionDynFlags dflag <- G.getSessionDynFlags
return $ do return $ do
typeName <- tyResult >>= showThing dflag typeName <- tyResult >>= showThing dflag
(" :: " ++ typeName) `justIf` optDetailed opt (" :: " ++ typeName) `justIf` optBrowseDetailed opt
| otherwise = return Nothing | otherwise = return Nothing
formatOp nm formatOp nm
| null nm = error "formatOp" | null nm = error "formatOp"

View File

@ -21,6 +21,7 @@ module Language.Haskell.GhcMod.CabalHelper
, getGhcMergedPkgOptions , getGhcMergedPkgOptions
, getCabalPackageDbStack , getCabalPackageDbStack
, prepareCabalHelper , prepareCabalHelper
, withAutogen
) )
#endif #endif
where where
@ -30,7 +31,8 @@ import Control.Monad
import Control.Category ((.)) import Control.Category ((.))
import Data.Maybe import Data.Maybe
import Data.Monoid import Data.Monoid
import Data.Serialize (Serialize) import Data.Version
import Data.Binary (Binary)
import Data.Traversable import Data.Traversable
import Distribution.Helper hiding (Programs(..)) import Distribution.Helper hiding (Programs(..))
import qualified Distribution.Helper as CH import qualified Distribution.Helper as CH
@ -58,7 +60,7 @@ getGhcMergedPkgOptions = chCached $ \distdir -> Cached {
cacheLens = Just (lGmcMergedPkgOptions . lGmCaches), cacheLens = Just (lGmcMergedPkgOptions . lGmCaches),
cacheFile = mergedPkgOptsCacheFile distdir, cacheFile = mergedPkgOptsCacheFile distdir,
cachedAction = \_tcf (_progs, _projdir, _ver) _ma -> do cachedAction = \_tcf (_progs, _projdir, _ver) _ma -> do
opts <- withCabal $ runCHQuery ghcMergedPkgOptions opts <- runCHQuery ghcMergedPkgOptions
return ([setupConfigPath distdir], opts) return ([setupConfigPath distdir], opts)
} }
@ -68,7 +70,7 @@ getCabalPackageDbStack = chCached $ \distdir -> Cached {
cacheFile = pkgDbStackCacheFile distdir, cacheFile = pkgDbStackCacheFile distdir,
cachedAction = \_tcf (_progs, _projdir, _ver) _ma -> do cachedAction = \_tcf (_progs, _projdir, _ver) _ma -> do
crdl <- cradle crdl <- cradle
dbs <- withCabal $ map chPkgToGhcPkg <$> dbs <- map chPkgToGhcPkg <$>
runCHQuery packageDbStack runCHQuery packageDbStack
return ([setupConfigFile crdl, sandboxConfigFile crdl], dbs) return ([setupConfigFile crdl, sandboxConfigFile crdl], dbs)
} }
@ -85,7 +87,7 @@ chPkgToGhcPkg (ChPkgSpecific f) = PackageDb f
-- 'resolveGmComponents'. -- 'resolveGmComponents'.
getComponents :: (Applicative m, IOish m, Gm m) getComponents :: (Applicative m, IOish m, Gm m)
=> m [GmComponent 'GMCRaw ChEntrypoint] => m [GmComponent 'GMCRaw ChEntrypoint]
getComponents = chCached$ \distdir -> Cached { getComponents = chCached $ \distdir -> Cached {
cacheLens = Just (lGmcComponents . lGmCaches), cacheLens = Just (lGmcComponents . lGmCaches),
cacheFile = cabalHelperCacheFile distdir, cacheFile = cabalHelperCacheFile distdir,
cachedAction = \ _tcf (_progs, _projdir, _ver) _ma -> do cachedAction = \ _tcf (_progs, _projdir, _ver) _ma -> do
@ -138,55 +140,22 @@ prepareCabalHelper = do
when (isCabalHelperProject $ cradleProject crdl) $ when (isCabalHelperProject $ cradleProject crdl) $
withCabal $ liftIO $ prepare readProc projdir distdir withCabal $ liftIO $ prepare readProc projdir distdir
withCabal :: (IOish m, GmEnv m, GmOut m, GmLog m) => m a -> m a withAutogen :: (IOish m, GmEnv m, GmOut m, GmLog m) => m a -> m a
withCabal action = do withAutogen action = do
gmLog GmDebug "" $ strDoc $ "making sure autogen files exist"
crdl <- cradle crdl <- cradle
opts <- options
readProc <- gmReadProcess
let projdir = cradleRootDir crdl let projdir = cradleRootDir crdl
distdir = projdir </> cradleDistDir crdl distdir = projdir </> cradleDistDir crdl
(pkgName', _) <- runCHQuery packageId
mCabalFile <- liftIO $ timeFile `traverse` cradleCabalFile crdl mCabalFile <- liftIO $ timeFile `traverse` cradleCabalFile crdl
mCabalConfig <- liftIO $ timeMaybe (setupConfigFile crdl) mCabalMacroHeader <- liftIO $ timeMaybe (distdir </> macrosHeaderPath)
mCabalSandboxConfig <- liftIO $ timeMaybe (sandboxConfigFile crdl) mCabalPathsModule <- liftIO $ timeMaybe (distdir </> autogenModulePath pkgName')
mCusPkgDbStack <- getCustomPkgDbStack when (mCabalMacroHeader < mCabalFile || mCabalPathsModule < mCabalFile) $ do
gmLog GmDebug "" $ strDoc $ "autogen files out of sync"
pkgDbStackOutOfSync <- writeAutogen projdir distdir
case mCusPkgDbStack of
Just cusPkgDbStack -> do
let qe = (defaultQueryEnv projdir distdir) {
qeReadProcess = readProc
, qePrograms = helperProgs $ optPrograms opts
}
pkgDb <- runQuery qe $ map chPkgToGhcPkg <$> packageDbStack
return $ pkgDb /= cusPkgDbStack
Nothing -> return False
proj <- cradleProject <$> cradle
when (isSetupConfigOutOfDate mCabalFile mCabalConfig) $
gmLog GmDebug "" $ strDoc $ "setup configuration is out of date, reconfiguring Cabal project."
when (isSetupConfigOutOfDate mCabalSandboxConfig mCabalConfig) $
gmLog GmDebug "" $ strDoc $ "sandbox configuration is out of date, reconfiguring Cabal project."
when pkgDbStackOutOfSync $
gmLog GmDebug "" $ strDoc $ "package-db stack out of sync with ghc-mod.package-db-stack, reconfiguring Cabal project."
when ( isSetupConfigOutOfDate mCabalFile mCabalConfig
|| pkgDbStackOutOfSync
|| isSetupConfigOutOfDate mCabalSandboxConfig mCabalConfig) $
case proj of
CabalProject ->
cabalReconfigure readProc (optPrograms opts) crdl projdir distdir
StackProject {} ->
stackReconfigure crdl (optPrograms opts)
_ ->
error $ "withCabal: unsupported project type: " ++ show proj
action action
@ -197,7 +166,60 @@ withCabal action = do
liftIO $ writeAutogenFiles readProc projdir distdir liftIO $ writeAutogenFiles readProc projdir distdir
cabalReconfigure readProc progs crdl projdir distdir = do withCabal :: (IOish m, GmEnv m, GmOut m, GmLog m) => m a -> m a
withCabal action = do
crdl <- cradle
mCabalFile <- liftIO $ timeFile `traverse` cradleCabalFile crdl
mCabalConfig <- liftIO $ timeMaybe (setupConfigFile crdl)
mCabalSandboxConfig <- liftIO $ timeMaybe (sandboxConfigFile crdl)
let haveSetupConfig = isJust mCabalConfig
cusPkgDb <- getCustomPkgDbStack
(flgs, pkgDbStackOutOfSync) <- do
if haveSetupConfig
then runCHQuery $ do
flgs <- nonDefaultConfigFlags
pkgDb <- map chPkgToGhcPkg <$> packageDbStack
return (flgs, fromMaybe False $ (pkgDb /=) <$> cusPkgDb)
else return ([], False)
when (isSetupConfigOutOfDate mCabalFile mCabalConfig) $
gmLog GmDebug "" $ strDoc $ "setup configuration is out of date"
when (isSetupConfigOutOfDate mCabalSandboxConfig mCabalConfig) $
gmLog GmDebug "" $ strDoc $ "sandbox configuration is out of date"
when pkgDbStackOutOfSync $
gmLog GmDebug "" $ strDoc $ "package-db stack out of sync with ghc-mod.package-db-stack"
when ( isSetupConfigOutOfDate mCabalFile mCabalConfig
|| pkgDbStackOutOfSync
|| isSetupConfigOutOfDate mCabalSandboxConfig mCabalConfig) $ do
proj <- cradleProject <$> cradle
opts <- options
case proj of
CabalProject -> do
gmLog GmDebug "" $ strDoc "reconfiguring Cabal project"
cabalReconfigure (optPrograms opts) crdl flgs
StackProject {} -> do
gmLog GmDebug "" $ strDoc "reconfiguring Stack project"
-- TODO: we could support flags for stack too, but it seems
-- you're supposed to put those in stack.yaml so detecting which
-- flags to pass down would be more difficult
-- "--flag PACKAGE:[-]FLAG Override flags set in stack.yaml
-- (applies to local packages and extra-deps)"
stackReconfigure crdl (optPrograms opts)
_ ->
error $ "withCabal: unsupported project type: " ++ show proj
action
where
cabalReconfigure progs crdl flgs = do
readProc <- gmReadProcess
withDirectory_ (cradleRootDir crdl) $ do withDirectory_ (cradleRootDir crdl) $ do
cusPkgStack <- maybe [] ((PackageDb "clear"):) <$> getCustomPkgDbStack cusPkgStack <- maybe [] ((PackageDb "clear"):) <$> getCustomPkgDbStack
let progOpts = let progOpts =
@ -208,20 +230,20 @@ withCabal action = do
then [ "--with-ghc-pkg=" ++ T.ghcPkgProgram progs ] then [ "--with-ghc-pkg=" ++ T.ghcPkgProgram progs ]
else [] else []
++ map pkgDbArg cusPkgStack ++ map pkgDbArg cusPkgStack
++ flagOpt
toFlag (f, True) = f
toFlag (f, False) = '-':f
flagOpt = ["--flags", unwords $ map toFlag flgs]
liftIO $ void $ readProc (T.cabalProgram progs) ("configure":progOpts) "" liftIO $ void $ readProc (T.cabalProgram progs) ("configure":progOpts) ""
writeAutogen projdir distdir
stackReconfigure crdl progs = do stackReconfigure crdl progs = do
let projdir = cradleRootDir crdl
distdir = projdir </> cradleDistDir crdl
withDirectory_ (cradleRootDir crdl) $ do withDirectory_ (cradleRootDir crdl) $ do
supported <- haveStackSupport supported <- haveStackSupport
if supported if supported
then do then do
spawn [T.stackProgram progs, "build", "--only-dependencies", "."] spawn [T.stackProgram progs, "build", "--only-dependencies", "."]
spawn [T.stackProgram progs, "build", "--only-configure", "."] spawn [T.stackProgram progs, "build", "--only-configure", "."]
writeAutogen projdir distdir
else else
gmLog GmWarning "" $ strDoc $ "Stack project configuration is out of date, please reconfigure manually using 'stack build' as your stack version is too old (need at least 0.1.4.0)" gmLog GmWarning "" $ strDoc $ "Stack project configuration is out of date, please reconfigure manually using 'stack build' as your stack version is too old (need at least 0.1.4.0)"
@ -268,7 +290,7 @@ helperProgs progs = CH.Programs {
ghcPkgProgram = T.ghcPkgProgram progs ghcPkgProgram = T.ghcPkgProgram progs
} }
chCached :: (Applicative m, IOish m, Gm m, Serialize a) chCached :: (Applicative m, IOish m, Gm m, Binary a)
=> (FilePath -> Cached m GhcModState ChCacheData a) -> m a => (FilePath -> Cached m GhcModState ChCacheData a) -> m a
chCached c = do chCached c = do
projdir <- cradleRootDir <$> cradle projdir <- cradleRootDir <$> cradle
@ -276,7 +298,7 @@ chCached c = do
d <- cacheInputData projdir d <- cacheInputData projdir
withCabal $ cached projdir (c distdir) d withCabal $ cached projdir (c distdir) d
where where
-- we don't need to include the disdir in the cache input because when it -- we don't need to include the distdir in the cache input because when it
-- changes the cache files will be gone anyways ;) -- changes the cache files will be gone anyways ;)
cacheInputData projdir = do cacheInputData projdir = do
opts <- options opts <- options
@ -284,7 +306,7 @@ chCached c = do
progs' <- patchStackPrograms crdl (optPrograms opts) progs' <- patchStackPrograms crdl (optPrograms opts)
return $ ( helperProgs progs' return $ ( helperProgs progs'
, projdir , projdir
, (gmVer, chVer) , (showVersion gmVer, chVer)
) )
gmVer = GhcMod.version gmVer = GhcMod.version

View File

@ -1,4 +1,19 @@
{-# LANGUAGE OverloadedStrings #-} -- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE CPP, OverloadedStrings #-}
module Language.Haskell.GhcMod.Caching ( module Language.Haskell.GhcMod.Caching (
module Language.Haskell.GhcMod.Caching module Language.Haskell.GhcMod.Caching
, module Language.Haskell.GhcMod.Caching.Types , module Language.Haskell.GhcMod.Caching.Types
@ -7,64 +22,75 @@ module Language.Haskell.GhcMod.Caching (
import Control.Arrow (first) import Control.Arrow (first)
import Control.Monad import Control.Monad
import Control.Monad.Trans.Maybe import Control.Monad.Trans.Maybe
#if !MIN_VERSION_binary(0,7,0)
import Control.Exception
#endif
import Data.Maybe import Data.Maybe
import Data.Serialize (Serialize, encode, decode) import Data.Binary hiding (get)
import Data.Version import Data.Version
import Data.Label import Data.Label
import qualified Data.ByteString.Lazy as LBS
import qualified Data.ByteString as BS import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8 import qualified Data.ByteString.Char8 as BS8
import System.FilePath import System.FilePath
import System.Directory.ModTime
import Utils (TimedFile(..), timeMaybe, mightExist) import Utils (TimedFile(..), timeMaybe, mightExist)
import Paths_ghc_mod (version) import Paths_ghc_mod (version)
import Prelude
import Language.Haskell.GhcMod.Monad.Types import Language.Haskell.GhcMod.Monad.Types
import Language.Haskell.GhcMod.Caching.Types import Language.Haskell.GhcMod.Caching.Types
import Language.Haskell.GhcMod.Logging import Language.Haskell.GhcMod.Logging
-- | Cache a MonadIO action with proper invalidation. -- | Cache a MonadIO action with proper invalidation.
cached :: forall m a d. (Gm m, MonadIO m, Serialize a, Eq d, Serialize d, Show d) cached :: forall m a d. (Gm m, MonadIO m, Binary a, Eq d, Binary d, Show d)
=> FilePath -- ^ Directory to prepend to 'cacheFile' => FilePath -- ^ Directory to prepend to 'cacheFile'
-> Cached m GhcModState d a -- ^ Cache descriptor -> Cached m GhcModState d a -- ^ Cache descriptor
-> d -> d
-> m a -> m a
cached dir cd d = do cached dir cd d = do
mcc <- readCache mcc <- readCache
tcfile <- liftIO $ timeMaybe (cacheFile cd)
case mcc of case mcc of
Nothing -> Nothing -> do
writeCache (TimedCacheFiles tcfile []) Nothing "cache missing or unreadable" t <- liftIO $ getCurrentModTime
Just (ifs, d', a) | d /= d' -> do writeCache (TimedCacheFiles t []) Nothing "cache missing or unreadable"
tcf <- timeCacheInput dir (cacheFile cd) ifs Just (t, ifs, d', a) | d /= d' -> do
writeCache tcf (Just a) $ "input data changed" -- ++ " was: " ++ show d ++ " is: " ++ show d' tcfs <- timeCacheInput dir ifs
Just (ifs, _, a) -> do writeCache (TimedCacheFiles t tcfs) (Just a) $ "input data changed" -- ++ " was: " ++ show d ++ " is: " ++ show d'
tcf <- timeCacheInput dir (cacheFile cd) ifs Just (t, ifs, _, a) -> do
case invalidatingInputFiles tcf of tcfs <- timeCacheInput dir ifs
Just [] -> return a case invalidatingInputFiles $ TimedCacheFiles t tcfs of
Just _ -> writeCache tcf (Just a) "input files changed" [] -> return a
Nothing -> writeCache tcf (Just a) "cache missing, existed a sec ago WTF?" _ -> writeCache (TimedCacheFiles t tcfs) (Just a) "input files changed"
where where
cacheHeader = BS8.pack $ "Written by ghc-mod " ++ showVersion version ++ "\n" cacheHeader = BS8.pack $ "Written by ghc-mod " ++ showVersion version ++ "\n"
writeCache tcf ma cause = do lbsToStrict = BS.concat . LBS.toChunks
(ifs', a) <- (cachedAction cd) tcf d ma lbsFromStrict bs = LBS.fromChunks [bs]
writeCache tcfs ma cause = do
(ifs', a) <- (cachedAction cd) tcfs d ma
t <- liftIO $ getCurrentModTime
gmLog GmDebug "" $ (text "regenerating cache") <+>: text (cacheFile cd) gmLog GmDebug "" $ (text "regenerating cache") <+>: text (cacheFile cd)
<+> parens (text cause) <+> parens (text cause)
case cacheLens cd of case cacheLens cd of
Nothing -> return () Nothing -> return ()
Just label -> do Just label -> do
gmLog GmDebug "" $ (text "writing memory cache") <+>: text (cacheFile cd) gmLog GmDebug "" $ (text "writing memory cache") <+>: text (cacheFile cd)
setLabel label $ Just (ifs', d, a) setLabel label $ Just (t, ifs', d, a)
let c = BS.append cacheHeader $ lbsToStrict $ encode (t, ifs', d, a)
liftIO $ BS.writeFile (dir </> cacheFile cd) c
liftIO $ BS.writeFile (dir </> cacheFile cd) $
BS.append cacheHeader $ encode (ifs', d, a)
return a return a
setLabel l x = do setLabel l x = do
s <- gmsGet s <- gmsGet
gmsPut $ set l x s gmsPut $ set l x s
readCache :: m (Maybe ([FilePath], d, a)) readCache :: m (Maybe (ModTime, [FilePath], d, a))
readCache = runMaybeT $ do readCache = runMaybeT $ do
case cacheLens cd of case cacheLens cd of
Just label -> do Just label -> do
@ -74,30 +100,42 @@ cached dir cd d = do
Nothing -> Nothing ->
readCacheFromFile readCacheFromFile
readCacheFromFile :: MaybeT m (ModTime, [FilePath], d, a)
readCacheFromFile = do readCacheFromFile = do
f <- MaybeT $ liftIO $ mightExist $ cacheFile cd f <- MaybeT $ liftIO $ mightExist $ cacheFile cd
readCacheFromFile' f readCacheFromFile' f
readCacheFromFile' :: FilePath -> MaybeT m (ModTime, [FilePath], d, a)
readCacheFromFile' f = MaybeT $ do readCacheFromFile' f = MaybeT $ do
gmLog GmDebug "" $ (text "reading cache") <+>: text (cacheFile cd) gmLog GmDebug "" $ (text "reading cache") <+>: text (cacheFile cd)
cc <- liftIO $ BS.readFile f cc <- liftIO $ BS.readFile f
case first BS8.words $ BS8.span (/='\n') cc of case first BS8.words $ BS8.span (/='\n') cc of
(["Written", "by", "ghc-mod", ver], rest) (["Written", "by", "ghc-mod", ver], rest)
| BS8.unpack ver == showVersion version -> | BS8.unpack ver == showVersion version ->
return $ either (const Nothing) Just $ decode $ BS.drop 1 rest either (const Nothing) Just
`liftM` decodeE (lbsFromStrict $ BS.drop 1 rest)
_ -> return Nothing _ -> return Nothing
timeCacheInput :: MonadIO m => FilePath -> FilePath -> [FilePath] -> m TimedCacheFiles decodeE b = do
timeCacheInput dir cfile ifs = liftIO $ do #if MIN_VERSION_binary(0,7,0)
-- TODO: is checking the times this way around race free? return $ case decodeOrFail b of
ins <- (timeMaybe . (dir </>)) `mapM` ifs Left (_rest, _offset, errmsg) -> Left errmsg
mtcfile <- timeMaybe cfile Right (_reset, _offset, a) -> Right a
return $ TimedCacheFiles mtcfile (catMaybes ins) #else
ea <- liftIO $ try $ evaluate $ decode b
return $ case ea of
Left (ErrorCall errmsg) -> Left errmsg
Right a -> Right a
invalidatingInputFiles :: TimedCacheFiles -> Maybe [FilePath] #endif
invalidatingInputFiles tcf =
case tcCacheFile tcf of timeCacheInput :: MonadIO m => FilePath -> [FilePath] -> m [TimedFile]
Nothing -> Nothing timeCacheInput dir ifs = liftIO $ do
Just tcfile -> Just $ map tfPath $ ins <- (timeMaybe . (dir </>)) `mapM` ifs
return $ catMaybes ins
invalidatingInputFiles :: TimedCacheFiles -> [FilePath]
invalidatingInputFiles (TimedCacheFiles tcreated tcfs) =
map tfPath $
-- get input files older than tcfile -- get input files older than tcfile
filter (tcfile<) $ tcFiles tcf filter ((TimedFile "" tcreated)<) tcfs

View File

@ -1,11 +1,26 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
module Language.Haskell.GhcMod.Caching.Types where module Language.Haskell.GhcMod.Caching.Types where
import Utils import Utils
import Data.Label import Data.Label
import Data.Version import System.Directory.ModTime
import Distribution.Helper import Distribution.Helper
type CacheContents d a = Maybe ([FilePath], d, a) type CacheContents d a = Maybe (ModTime, [FilePath], d, a)
type CacheLens s d a = s :-> CacheContents d a type CacheLens s d a = s :-> CacheContents d a
data Cached m s d a = Cached { data Cached m s d a = Cached {
@ -43,10 +58,10 @@ data Cached m s d a = Cached {
} }
data TimedCacheFiles = TimedCacheFiles { data TimedCacheFiles = TimedCacheFiles {
tcCacheFile :: Maybe TimedFile, tcCreated :: ModTime,
-- ^ 'cacheFile' timestamp -- ^ 'cacheFile' timestamp
tcFiles :: [TimedFile] tcFiles :: [TimedFile]
-- ^ Timestamped files returned by the cached action -- ^ Timestamped files returned by the cached action
} deriving (Eq, Ord, Show) } deriving (Eq, Ord)
type ChCacheData = (Programs, FilePath, (Version, [Char])) type ChCacheData = (Programs, FilePath, (String, String))

View File

@ -4,6 +4,7 @@ module Language.Haskell.GhcMod.Cradle
( (
findCradle findCradle
, findCradle' , findCradle'
, findCradleNoLog
, findSpecCradle , findSpecCradle
, cleanupCradle , cleanupCradle
) )
@ -15,6 +16,8 @@ import Language.Haskell.GhcMod.Monad.Types
import Language.Haskell.GhcMod.Types import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Utils import Language.Haskell.GhcMod.Utils
import Language.Haskell.GhcMod.Stack import Language.Haskell.GhcMod.Stack
import Language.Haskell.GhcMod.Logging
import Control.Applicative import Control.Applicative
import Control.Monad import Control.Monad
@ -23,6 +26,8 @@ import Data.Maybe
import System.Directory import System.Directory
import System.FilePath import System.FilePath
import Prelude import Prelude
import Control.Monad.Trans.Journal (runJournalT)
---------------------------------------------------------------- ----------------------------------------------------------------
@ -30,10 +35,13 @@ import Prelude
-- Find a cabal file by tracing ancestor directories. -- Find a cabal file by tracing ancestor directories.
-- Find a sandbox according to a cabal sandbox config -- Find a sandbox according to a cabal sandbox config
-- in a cabal directory. -- in a cabal directory.
findCradle :: (IOish m, GmOut m) => m Cradle findCradle :: (GmLog m, IOish m, GmOut m) => m Cradle
findCradle = findCradle' =<< liftIO getCurrentDirectory findCradle = findCradle' =<< liftIO getCurrentDirectory
findCradle' :: (IOish m, GmOut m) => FilePath -> m Cradle findCradleNoLog :: forall m. (IOish m, GmOut m) => m Cradle
findCradleNoLog = fst <$> (runJournalT findCradle :: m (Cradle, GhcModLog))
findCradle' :: (GmLog m, IOish m, GmOut m) => FilePath -> m Cradle
findCradle' dir = run $ findCradle' dir = run $
msum [ stackCradle dir msum [ stackCradle dir
, cabalCradle dir , cabalCradle dir
@ -42,7 +50,7 @@ findCradle' dir = run $
] ]
where run a = fillTempDir =<< (fromJust <$> runMaybeT a) where run a = fillTempDir =<< (fromJust <$> runMaybeT a)
findSpecCradle :: (IOish m, GmOut m) => FilePath -> m Cradle findSpecCradle :: (GmLog m, IOish m, GmOut m) => FilePath -> m Cradle
findSpecCradle dir = do findSpecCradle dir = do
let cfs = [stackCradleSpec, cabalCradle, sandboxCradle] let cfs = [stackCradleSpec, cabalCradle, sandboxCradle]
cs <- catMaybes <$> mapM (runMaybeT . ($ dir)) cfs cs <- catMaybes <$> mapM (runMaybeT . ($ dir)) cfs
@ -77,8 +85,12 @@ cabalCradle wdir = do
, cradleDistDir = "dist" , cradleDistDir = "dist"
} }
stackCradle :: (IOish m, GmOut m) => FilePath -> MaybeT m Cradle stackCradle :: (GmLog m, IOish m, GmOut m) => FilePath -> MaybeT m Cradle
stackCradle wdir = do stackCradle wdir = do
#if !MIN_VERSION_ghc(7,8,0)
-- GHC < 7.8 is not supported by stack
mzero
#endif
cabalFile <- MaybeT $ liftIO $ findCabalFile wdir cabalFile <- MaybeT $ liftIO $ findCabalFile wdir
let cabalDir = takeDirectory cabalFile let cabalDir = takeDirectory cabalFile
@ -87,7 +99,9 @@ stackCradle wdir = do
-- If dist/setup-config already exists the user probably wants to use cabal -- If dist/setup-config already exists the user probably wants to use cabal
-- rather than stack, or maybe that's just me ;) -- rather than stack, or maybe that's just me ;)
whenM (liftIO $ doesFileExist $ setupConfigPath "dist") $ mzero whenM (liftIO $ doesFileExist $ setupConfigPath "dist") $ do
gmLog GmWarning "" $ text "'dist/setup-config' exists, ignoring Stack and using cabal-install instead."
mzero
senv <- MaybeT $ getStackEnv cabalDir senv <- MaybeT $ getStackEnv cabalDir
@ -100,7 +114,7 @@ stackCradle wdir = do
, cradleDistDir = seDistDir senv , cradleDistDir = seDistDir senv
} }
stackCradleSpec :: (IOish m, GmOut m) => FilePath -> MaybeT m Cradle stackCradleSpec :: (GmLog m, IOish m, GmOut m) => FilePath -> MaybeT m Cradle
stackCradleSpec wdir = do stackCradleSpec wdir = do
crdl <- stackCradle wdir crdl <- stackCradle wdir
case crdl of case crdl of

View File

@ -1,6 +1,20 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
module Language.Haskell.GhcMod.CustomPackageDb where module Language.Haskell.GhcMod.CustomPackageDb where
import Control.Applicative import Control.Applicative
import Control.Monad import Control.Monad
import Control.Category ((.)) import Control.Category ((.))
@ -11,7 +25,6 @@ import Language.Haskell.GhcMod.Monad.Types
import Language.Haskell.GhcMod.PathsAndFiles import Language.Haskell.GhcMod.PathsAndFiles
import Prelude hiding ((.)) import Prelude hiding ((.))
parseCustomPackageDb :: String -> [GhcPkgDb] parseCustomPackageDb :: String -> [GhcPkgDb]
parseCustomPackageDb src = map parsePkgDb $ filter (not . null) $ lines src parseCustomPackageDb src = map parsePkgDb $ filter (not . null) $ lines src
where where
@ -19,7 +32,7 @@ parseCustomPackageDb src = map parsePkgDb $ filter (not . null) $ lines src
parsePkgDb "user" = UserDb parsePkgDb "user" = UserDb
parsePkgDb s = PackageDb s parsePkgDb s = PackageDb s
getCustomPkgDbStack :: (IOish m, GmEnv m) => m (Maybe [GhcPkgDb]) getCustomPkgDbStack :: (MonadIO m, GmEnv m) => m (Maybe [GhcPkgDb])
getCustomPkgDbStack = do getCustomPkgDbStack = do
mCusPkgDbFile <- liftIO . (traverse readFile <=< findCustomPackageDbFile) . cradleRootDir =<< cradle mCusPkgDbFile <- liftIO . (traverse readFile <=< findCustomPackageDbFile) . cradleRootDir =<< cradle
return $ parseCustomPackageDb <$> mCusPkgDbFile return $ parseCustomPackageDb <$> mCusPkgDbFile

View File

@ -3,6 +3,7 @@ module Language.Haskell.GhcMod.Debug (debugInfo, rootInfo, componentInfo) where
import Control.Arrow (first) import Control.Arrow (first)
import Control.Applicative import Control.Applicative
import Control.Monad import Control.Monad
import Control.Monad.Trans.Journal
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import Data.Char import Data.Char
@ -138,5 +139,5 @@ mapDoc kd ad m = vcat $
---------------------------------------------------------------- ----------------------------------------------------------------
-- | Obtaining root information. -- | Obtaining root information.
rootInfo :: (IOish m, GmOut m) => m String rootInfo :: forall m. (IOish m, GmOut m) => m String
rootInfo = (++"\n") . cradleRootDir <$> findCradle rootInfo = (++"\n") . cradleRootDir <$> fst `liftM` (runJournalT findCradle :: m (Cradle, GhcModLog))

View File

@ -1,6 +1,54 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
module Language.Haskell.GhcMod.DebugLogger where module Language.Haskell.GhcMod.DebugLogger where
-- (c) The University of Glasgow 2005
--
-- The Glasgow Haskell Compiler License
--
-- Copyright 2002, The University Court of the University of Glasgow.
-- All rights reserved.
--
-- Redistribution and use in source and binary forms, with or without
-- modification, are permitted provided that the following conditions are met:
--
-- - Redistributions of source code must retain the above copyright notice,
-- this list of conditions and the following disclaimer.
--
-- - Redistributions in binary form must reproduce the above copyright notice,
-- this list of conditions and the following disclaimer in the documentation
-- and/or other materials provided with the distribution.
--
-- - Neither name of the University nor the names of its contributors may be
-- used to endorse or promote products derived from this software without
-- specific prior written permission.
--
-- THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
-- GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-- UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-- DAMAGE.
import GHC import GHC
import FastString import FastString

View File

@ -25,8 +25,8 @@ setDebugLogger put df = do
-- * Friendly to foreign export -- * Friendly to foreign export
-- * Not friendly to -XTemplateHaskell and -XPatternSynonyms -- * Not friendly to -XTemplateHaskell and -XPatternSynonyms
-- * Uses little memory -- * Uses little memory
setModeSimple :: DynFlags -> DynFlags setHscNothing :: DynFlags -> DynFlags
setModeSimple df = df { setHscNothing df = df {
ghcMode = CompManager ghcMode = CompManager
, ghcLink = NoLink , ghcLink = NoLink
, hscTarget = HscNothing , hscTarget = HscNothing
@ -37,8 +37,8 @@ setModeSimple df = df {
-- * Not friendly to foreign export -- * Not friendly to foreign export
-- * Friendly to -XTemplateHaskell and -XPatternSynonyms -- * Friendly to -XTemplateHaskell and -XPatternSynonyms
-- * Uses lots of memory -- * Uses lots of memory
setModeIntelligent :: DynFlags -> DynFlags setHscInterpreted :: DynFlags -> DynFlags
setModeIntelligent df = df { setHscInterpreted df = df {
ghcMode = CompManager ghcMode = CompManager
, ghcLink = LinkInMemory , ghcLink = LinkInMemory
, hscTarget = HscInterpreted , hscTarget = HscInterpreted

View File

@ -20,10 +20,30 @@ import Control.Monad.Trans.Maybe
import GHC import GHC
import Control.Monad import Control.Monad
loadMappedFile :: IOish m => FilePath -> FilePath -> GhcModT m () {- | maps 'FilePath', given as first argument to take source from
'FilePath' given as second argument. Works exactly the same as
first form of `--map-file` CLI option.
\'from\' can be either full path, or path relative to project root.
\'to\' has to be either relative to project root, or full path (preferred)
-}
loadMappedFile :: IOish m
=> FilePath -- ^ \'from\', file that will be mapped
-> FilePath -- ^ \'to\', file to take source from
-> GhcModT m ()
loadMappedFile from to = loadMappedFile' from to False loadMappedFile from to = loadMappedFile' from to False
loadMappedFileSource :: IOish m => FilePath -> String -> GhcModT m () {- |
maps 'FilePath', given as first argument to have source as given
by second argument.
\'from\' may or may not exist, and should be either full path,
or relative to project root.
-}
loadMappedFileSource :: IOish m
=> FilePath -- ^ \'from\', file that will be mapped
-> String -- ^ \'src\', source
-> GhcModT m ()
loadMappedFileSource from src = do loadMappedFileSource from src = do
tmpdir <- cradleTempDir `fmap` cradle tmpdir <- cradleTempDir `fmap` cradle
to <- liftIO $ do to <- liftIO $ do
@ -37,7 +57,9 @@ loadMappedFile' :: IOish m => FilePath -> FilePath -> Bool -> GhcModT m ()
loadMappedFile' from to isTemp = do loadMappedFile' from to isTemp = do
cfn <- getCanonicalFileNameSafe from cfn <- getCanonicalFileNameSafe from
unloadMappedFile' cfn unloadMappedFile' cfn
addMMappedFile cfn (FileMapping to isTemp) crdl <- cradle
let to' = makeRelative (cradleRootDir crdl) to
addMMappedFile cfn (FileMapping to' isTemp)
mapFile :: (IOish m, GmState m, GhcMonad m, GmEnv m) => mapFile :: (IOish m, GmState m, GhcMonad m, GmEnv m) =>
HscEnv -> Target -> m Target HscEnv -> Target -> m Target
@ -57,7 +79,16 @@ mkMappedTarget _ _ taoc (Just to) =
return $ mkTarget (TargetFile (fmPath to) Nothing) taoc Nothing return $ mkTarget (TargetFile (fmPath to) Nothing) taoc Nothing
mkMappedTarget _ tid taoc _ = return $ mkTarget tid taoc Nothing mkMappedTarget _ tid taoc _ = return $ mkTarget tid taoc Nothing
unloadMappedFile :: IOish m => FilePath -> GhcModT m () {-|
unloads previously mapped file \'file\', so that it's no longer mapped,
and removes any temporary files created when file was
mapped.
\'file\' should be either full path, or relative to project root.
-}
unloadMappedFile :: IOish m
=> FilePath -- ^ \'file\', file to unmap
-> GhcModT m ()
unloadMappedFile = getCanonicalFileNameSafe >=> unloadMappedFile' unloadMappedFile = getCanonicalFileNameSafe >=> unloadMappedFile'
unloadMappedFile' :: IOish m => FilePath -> GhcModT m () unloadMappedFile' :: IOish m => FilePath -> GhcModT m ()

View File

@ -10,33 +10,42 @@ module Language.Haskell.GhcMod.Find
, findSymbol , findSymbol
, lookupSym , lookupSym
, isOutdated , isOutdated
-- * Load 'SymbolDb' asynchronously
, AsyncSymbolDb
, newAsyncSymbolDb
, getAsyncSymbolDb
) )
#endif #endif
where where
import Control.Applicative
import Control.Monad (when, void)
import Data.Function (on)
import Data.List (groupBy, sort)
import qualified GHC as G
import Language.Haskell.GhcMod.Convert import Language.Haskell.GhcMod.Convert
import Language.Haskell.GhcMod.Gap (listVisibleModules) import Language.Haskell.GhcMod.Gap
import Language.Haskell.GhcMod.Monad import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.Output
import Language.Haskell.GhcMod.PathsAndFiles import Language.Haskell.GhcMod.PathsAndFiles
import Language.Haskell.GhcMod.Types import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Utils import Language.Haskell.GhcMod.Utils
import Language.Haskell.GhcMod.World (timedPackageCaches) import Language.Haskell.GhcMod.World
import Language.Haskell.GhcMod.Output
import Name (getOccString) import qualified GHC as G
import Module (moduleName) import Name
import System.Directory (doesFileExist, getModificationTime) import Module
import Exception
import Control.Applicative
import Control.Monad
import Control.Monad.Trans.Control
import Control.Concurrent
import Data.Function
import Data.List
import Data.Map (Map)
import qualified Data.Map as M
import System.Directory
import System.Directory.ModTime
import System.FilePath ((</>)) import System.FilePath ((</>))
import System.IO import System.IO
import Prelude import Prelude
import Data.Map (Map)
import qualified Data.Map as M
---------------------------------------------------------------- ----------------------------------------------------------------
-- | Type of function and operation names. -- | Type of function and operation names.
@ -120,7 +129,7 @@ isOlderThan cache files = do
if not exist if not exist
then return True then return True
else do else do
tCache <- getModificationTime cache tCache <- getModTime cache
return $ any (tCache <=) $ map tfTime files -- including equal just in case return $ any (tCache <=) $ map tfTime files -- including equal just in case
-- | Browsing all functions in all system modules. -- | Browsing all functions in all system modules.
@ -146,3 +155,39 @@ collectModules :: [(Symbol, ModuleString)]
collectModules = map tieup . groupBy ((==) `on` fst) . sort collectModules = map tieup . groupBy ((==) `on` fst) . sort
where where
tieup x = (head (map fst x), map snd x) tieup x = (head (map fst x), map snd x)
----------------------------------------------------------------
data AsyncSymbolDb = AsyncSymbolDb FilePath (MVar (Either SomeException SymbolDb))
asyncLoadSymbolDb :: IOish m
=> FilePath
-> MVar (Either SomeException SymbolDb)
-> GhcModT m ()
asyncLoadSymbolDb tmpdir mv = void $
liftBaseWith $ \run -> forkIO $ void $ run $ do
edb <- gtry $ loadSymbolDb tmpdir
liftIO $ putMVar mv edb
newAsyncSymbolDb :: IOish m => FilePath -> GhcModT m AsyncSymbolDb
newAsyncSymbolDb tmpdir = do
mv <- liftIO newEmptyMVar
asyncLoadSymbolDb tmpdir mv
return $ AsyncSymbolDb tmpdir mv
getAsyncSymbolDb :: forall m. IOish m => AsyncSymbolDb -> GhcModT m SymbolDb
getAsyncSymbolDb (AsyncSymbolDb tmpdir mv) = do
db <- liftIO $ handleEx <$> takeMVar mv
outdated <- isOutdated db
if outdated
then do
asyncLoadSymbolDb tmpdir mv
liftIO $ handleEx <$> readMVar mv
else do
liftIO $ putMVar mv $ Right db
return db
where
handleEx edb =
case edb of
Left ex -> throw ex
Right db -> db

View File

@ -370,7 +370,7 @@ pprInfo m pefas (thing, fixity, insts)
(char '\t' <> ptext (sLit "--") <+> loc) (char '\t' <> ptext (sLit "--") <+> loc)
where loc = ptext (sLit "Defined") <+> pprNameDefnLoc' (getName thing') where loc = ptext (sLit "Defined") <+> pprNameDefnLoc' (getName thing')
#else #else
pprTyThingInContextLoc' pefas thing' = hang (pprTyThingInContext pefas thing') 2 pprTyThingInContextLoc' pefas' thing' = hang (pprTyThingInContext pefas' thing') 2
(char '\t' <> ptext (sLit "--") <+> loc) (char '\t' <> ptext (sLit "--") <+> loc)
where loc = ptext (sLit "Defined") <+> pprNameDefnLoc' (getName thing') where loc = ptext (sLit "Defined") <+> pprNameDefnLoc' (getName thing')
#endif #endif

View File

@ -3,10 +3,6 @@
module Language.Haskell.GhcMod.Internal ( module Language.Haskell.GhcMod.Internal (
-- * Types -- * Types
GHCOption GHCOption
, Package
, PackageBaseName
, PackageVersion
, PackageId
, IncludeDir , IncludeDir
, GmlT(..) , GmlT(..)
, MonadIO(..) , MonadIO(..)
@ -21,7 +17,6 @@ module Language.Haskell.GhcMod.Internal (
-- * Environment, state and logging -- * Environment, state and logging
, GhcModEnv(..) , GhcModEnv(..)
, GhcModState , GhcModState
, CompilerMode(..)
, GhcModLog , GhcModLog
, GmLog(..) , GmLog(..)
, GmLogLevel(..) , GmLogLevel(..)
@ -38,8 +33,6 @@ module Language.Haskell.GhcMod.Internal (
-- ** Accessing 'GhcModEnv' and 'GhcModState' -- ** Accessing 'GhcModEnv' and 'GhcModState'
, options , options
, cradle , cradle
, getCompilerMode
, setCompilerMode
, targetGhcOptions , targetGhcOptions
, withOptions , withOptions
-- * 'GhcModError' -- * 'GhcModError'

View File

@ -4,8 +4,8 @@ import Exception (ghandle)
import Control.Exception (SomeException(..)) import Control.Exception (SomeException(..))
import Language.Haskell.GhcMod.Logger (checkErrorPrefix) import Language.Haskell.GhcMod.Logger (checkErrorPrefix)
import Language.Haskell.GhcMod.Convert import Language.Haskell.GhcMod.Convert
import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.Types import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad
import Language.Haskell.HLint (hlint) import Language.Haskell.HLint (hlint)
import Language.Haskell.GhcMod.Utils (withMappedFile) import Language.Haskell.GhcMod.Utils (withMappedFile)
@ -15,12 +15,12 @@ import Data.List (stripPrefix)
-- | Checking syntax of a target file using hlint. -- | Checking syntax of a target file using hlint.
-- Warnings and errors are returned. -- Warnings and errors are returned.
lint :: IOish m lint :: IOish m
=> FilePath -- ^ A target file. => LintOpts -- ^ Configuration parameters
-> FilePath -- ^ A target file.
-> GhcModT m String -> GhcModT m String
lint file = do lint opt file =
opt <- options
withMappedFile file $ \tempfile -> withMappedFile file $ \tempfile ->
liftIO (hlint $ tempfile : "--quiet" : optHlintOpts opt) liftIO (hlint $ tempfile : "--quiet" : optLintHlintOpts opt)
>>= mapM (replaceFileName tempfile) >>= mapM (replaceFileName tempfile)
>>= ghandle handler . pack >>= ghandle handler . pack
where where

View File

@ -45,6 +45,11 @@ gmSetLogLevel :: GmLog m => GmLogLevel -> m ()
gmSetLogLevel level = gmSetLogLevel level =
gmlJournal $ GhcModLog (Just level) (Last Nothing) [] gmlJournal $ GhcModLog (Just level) (Last Nothing) []
gmGetLogLevel :: forall m. GmLog m => m GmLogLevel
gmGetLogLevel = do
GhcModLog { gmLogLevel = Just level } <- gmlHistory
return level
gmSetDumpLevel :: GmLog m => Bool -> m () gmSetDumpLevel :: GmLog m => Bool -> m ()
gmSetDumpLevel level = gmSetDumpLevel level =
gmlJournal $ GhcModLog Nothing (Last (Just level)) [] gmlJournal $ GhcModLog Nothing (Last (Just level)) []
@ -78,6 +83,12 @@ gmLog level loc' doc = do
gmlJournal (GhcModLog Nothing (Last Nothing) [(level, loc', msgDoc)]) gmlJournal (GhcModLog Nothing (Last Nothing) [(level, loc', msgDoc)])
-- | Appends a collection of logs to the logging environment, with effects
-- | if their log level specifies it should
gmAppendLog :: (MonadIO m, GmLog m, GmOut m) => GhcModLog -> m ()
gmAppendLog GhcModLog { gmLogMessages } = (\(level, loc, msgDoc) -> gmLog level loc msgDoc) `mapM_` gmLogMessages
gmVomit :: (MonadIO m, GmLog m, GmOut m, GmEnv m) => String -> Doc -> String -> m () gmVomit :: (MonadIO m, GmLog m, GmOut m, GmEnv m) => String -> Doc -> String -> m ()
gmVomit filename doc content = do gmVomit filename doc content = do
gmLog GmVomit "" $ doc <+>: text content gmLog GmVomit "" $ doc <+>: text content

View File

@ -14,13 +14,14 @@ import qualified GHC as G
---------------------------------------------------------------- ----------------------------------------------------------------
-- | Listing installed modules. -- | Listing installed modules.
modules :: (IOish m, Gm m) => m String modules :: (IOish m, Gm m)
modules = do => Bool -- ^ 'detailed', if 'True', also prints packages that modules belong to.
Options { optDetailed } <- options -> m String
modules detailed = do
df <- runGmPkgGhc G.getSessionDynFlags df <- runGmPkgGhc G.getSessionDynFlags
let mns = listVisibleModuleNames df let mns = listVisibleModuleNames df
pmnss = map (first moduleNameString) $ zip mns (modulePkg df `map` mns) pmnss = map (first moduleNameString) $ zip mns (modulePkg df `map` mns)
convert' $ nub [ if optDetailed then pkg ++ " " ++ mn else mn convert' $ nub [ if detailed then pkg ++ " " ++ mn else mn
| (mn, pkgs) <- pmnss, pkg <- pkgs ] | (mn, pkgs) <- pmnss, pkg <- pkgs ]
where where
modulePkg df = lookupModulePackageInAllPackages df modulePkg df = lookupModulePackageInAllPackages df

View File

@ -50,31 +50,41 @@ import Control.Monad.Trans.Journal (runJournalT)
import Exception import Exception
import System.Directory import System.Directory
import System.IO.Unsafe
import Prelude import Prelude
withGhcModEnv :: (IOish m, GmOut m) => FilePath -> Options -> (GhcModEnv -> m a) -> m a withGhcModEnv :: (IOish m, GmOut m) => FilePath -> Options -> ((GhcModEnv, GhcModLog) -> m a) -> m a
withGhcModEnv = withGhcModEnv' withCradle withGhcModEnv = withGhcModEnv' withCradle
where where
withCradle dir = withCradle dir =
gbracket (findCradle' dir) (liftIO . cleanupCradle) gbracket (runJournalT $ findCradle' dir) (liftIO . cleanupCradle . fst)
withGhcModEnv' :: (IOish m, GmOut m) => (FilePath -> (Cradle -> m a) -> m a) -> FilePath -> Options -> (GhcModEnv -> m a) -> m a cwdLock :: MVar ThreadId
cwdLock = unsafePerformIO $ newEmptyMVar
{-# NOINLINE cwdLock #-}
withGhcModEnv' :: (IOish m, GmOut m) => (FilePath -> ((Cradle, GhcModLog) -> m a) -> m a) -> FilePath -> Options -> ((GhcModEnv, GhcModLog) -> m a) -> m a
withGhcModEnv' withCradle dir opts f = withGhcModEnv' withCradle dir opts f =
withCradle dir $ \crdl -> withCradle dir $ \(crdl,lg) ->
withCradleRootDir crdl $ withCradleRootDir crdl $
f $ GhcModEnv opts crdl f (GhcModEnv opts crdl, lg)
where where
withCradleRootDir (cradleRootDir -> projdir) a = do swapCurrentDirectory ndir = do
cdir <- liftIO $ getCurrentDirectory odir <- canonicalizePath =<< getCurrentDirectory
eq <- liftIO $ pathsEqual projdir cdir setCurrentDirectory ndir
if not eq return odir
then throw $ GMEWrongWorkingDirectory projdir cdir
else a
pathsEqual a b = do withCradleRootDir (cradleRootDir -> projdir) a = do
ca <- canonicalizePath a success <- liftIO $ tryPutMVar cwdLock =<< myThreadId
cb <- canonicalizePath b if not success
return $ ca == cb then error "withGhcModEnv': using ghc-mod from multiple threads is not supported!"
else gbracket setup teardown (const a)
where
setup = liftIO $ swapCurrentDirectory projdir
teardown odir = liftIO $ do
setCurrentDirectory odir
void $ takeMVar cwdLock
runGmOutT :: IOish m => Options -> GmOutT m a -> m a runGmOutT :: IOish m => Options -> GmOutT m a -> m a
runGmOutT opts ma = do runGmOutT opts ma = do
@ -91,15 +101,17 @@ runGmOutT' :: IOish m => GhcModOut -> GmOutT m a -> m a
runGmOutT' gmo ma = flip runReaderT gmo $ unGmOutT ma runGmOutT' gmo ma = flip runReaderT gmo $ unGmOutT ma
-- | Run a @GhcModT m@ computation. -- | Run a @GhcModT m@ computation.
runGhcModT :: (IOish m, GmOut m) runGhcModT :: IOish m
=> Options => Options
-> GhcModT m a -> GhcModT m a
-> m (Either GhcModError a, GhcModLog) -> m (Either GhcModError a, GhcModLog)
runGhcModT opt action = liftIO (getCurrentDirectory >>= canonicalizePath) >>= \dir' -> do runGhcModT opt action = liftIO (getCurrentDirectory >>= canonicalizePath) >>= \dir' -> do
runGmOutT opt $ runGmOutT opt $
withGhcModEnv dir' opt $ \env -> withGhcModEnv dir' opt $ \(env,lg) ->
first (fst <$>) <$> runGhcModT' env defaultGhcModState first (fst <$>) <$> runGhcModT' env defaultGhcModState
(gmSetLogLevel (ooptLogLevel $ optOutput opt) >> action) (gmSetLogLevel (ooptLogLevel $ optOutput opt) >>
gmAppendLog lg >>
action)
-- | @hoistGhcModT result@. Embed a GhcModT computation's result into a GhcModT -- | @hoistGhcModT result@. Embed a GhcModT computation's result into a GhcModT
-- computation. Note that if the computation that returned @result@ modified the -- computation. Note that if the computation that returned @result@ modified the

View File

@ -0,0 +1,28 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015,2016 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
-- MonadUtils of GHC 7.6 or earlier defines its own MonadIO.
-- RWST does not automatically become an instance of MonadIO.
-- MonadUtils of GHC 7.8 or later imports MonadIO in Monad.Control.IO.Class.
-- So, RWST automatically becomes an instance of
#if __GLASGOW_HASKELL__ < 708
-- 'CoreMonad.MonadIO' and 'Control.Monad.IO.Class.MonadIO' are different
-- classes before ghc 7.8
#define DIFFERENT_MONADIO 1
-- RWST doen't have a MonadIO instance before ghc 7.8
#define MONADIO_INSTANCES 1
#endif

View File

@ -0,0 +1,68 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015,2016 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module Language.Haskell.GhcMod.Monad.Env where
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad.Newtypes
import Control.Monad
import Control.Monad.Trans.Journal (JournalT)
import Control.Monad.State.Strict (StateT(..))
import Control.Monad.Error (ErrorT(..))
import Control.Monad.Reader.Class
import Control.Monad.Trans.Class (MonadTrans(..))
import Prelude
class Monad m => GmEnv m where
gmeAsk :: m GhcModEnv
gmeAsk = gmeReader id
gmeReader :: (GhcModEnv -> a) -> m a
gmeReader f = f `liftM` gmeAsk
gmeLocal :: (GhcModEnv -> GhcModEnv) -> m a -> m a
{-# MINIMAL (gmeAsk | gmeReader), gmeLocal #-}
instance Monad m => GmEnv (GmT m) where
gmeAsk = GmT ask
gmeReader = GmT . reader
gmeLocal f a = GmT $ local f (unGmT a)
instance GmEnv m => GmEnv (GmOutT m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
instance GmEnv m => GmEnv (StateT s m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
instance GmEnv m => GmEnv (JournalT GhcModLog m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
instance GmEnv m => GmEnv (ErrorT GhcModError m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
deriving instance (Monad m, GmEnv (GhcModT m)) => GmEnv (GmlT m)

View File

@ -0,0 +1,71 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015,2016 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module Language.Haskell.GhcMod.Monad.Log where
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad.Newtypes
import Control.Monad
import Control.Monad.Trans.Journal (JournalT)
import Control.Monad.Reader (ReaderT(..))
import Control.Monad.State.Strict (StateT(..))
import Control.Monad.Error (Error, ErrorT(..))
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Journal.Class (MonadJournal(..))
import Control.Monad.Trans.Class (MonadTrans(..))
import Prelude
class Monad m => GmLog m where
gmlJournal :: GhcModLog -> m ()
gmlHistory :: m GhcModLog
gmlClear :: m ()
instance Monad m => GmLog (JournalT GhcModLog m) where
gmlJournal = journal
gmlHistory = history
gmlClear = clear
instance Monad m => GmLog (GmT m) where
gmlJournal = GmT . lift . lift . journal
gmlHistory = GmT $ lift $ lift history
gmlClear = GmT $ lift $ lift clear
instance (Monad m, GmLog m) => GmLog (ReaderT r m) where
gmlJournal = lift . gmlJournal
gmlHistory = lift gmlHistory
gmlClear = lift gmlClear
instance (Monad m, GmLog m) => GmLog (StateT s m) where
gmlJournal = lift . gmlJournal
gmlHistory = lift gmlHistory
gmlClear = lift gmlClear
instance (Monad m, GmLog m, Error e) => GmLog (ErrorT e m) where
gmlJournal = lift . gmlJournal
gmlHistory = lift gmlHistory
gmlClear = lift gmlClear
instance (Monad m, GmLog m) => GmLog (MaybeT m) where
gmlJournal = lift . gmlJournal
gmlHistory = lift gmlHistory
gmlClear = lift gmlClear
deriving instance GmLog m => GmLog (GmOutT m)
deriving instance (Monad m, GmLog (GhcModT m)) => GmLog (GmlT m)

View File

@ -0,0 +1,176 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015,2016 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, DeriveFunctor #-}
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, UndecidableInstances #-}
{-# LANGUAGE RankNTypes, FlexibleInstances #-}
module Language.Haskell.GhcMod.Monad.Newtypes where
#include "Compat.hs_h"
import Language.Haskell.GhcMod.Types
import GHC
import Control.Applicative
import Control.Monad
import Control.Monad.Reader (ReaderT(..))
import Control.Monad.Error (ErrorT(..), MonadError(..))
import Control.Monad.State.Strict (StateT(..))
import Control.Monad.Trans.Journal (JournalT)
import Control.Monad.Reader.Class
import Control.Monad.State.Class (MonadState(..))
import Control.Monad.Journal.Class (MonadJournal(..))
import Control.Monad.Trans.Class (MonadTrans(..))
import Control.Monad.Trans.Control
import Control.Monad.Base (MonadBase(..), liftBase)
import Data.IORef
import Prelude
type GhcModT m = GmT (GmOutT m)
newtype GmOutT m a = GmOutT {
unGmOutT :: ReaderT GhcModOut m a
} deriving ( Functor
, Applicative
, Alternative
, Monad
, MonadPlus
, MonadTrans
)
newtype GmT m a = GmT {
unGmT :: StateT GhcModState
(ErrorT GhcModError
(JournalT GhcModLog
(ReaderT GhcModEnv m) ) ) a
} deriving ( Functor
, Applicative
, Alternative
, Monad
, MonadPlus
, MonadError GhcModError
)
newtype GmlT m a = GmlT { unGmlT :: GhcModT m a }
deriving ( Functor
, Applicative
, Alternative
, Monad
, MonadPlus
, MonadError GhcModError
)
newtype LightGhc a = LightGhc { unLightGhc :: ReaderT (IORef HscEnv) IO a }
deriving ( Functor
, Applicative
, Monad
)
-- GmOutT ----------------------------------------
instance (MonadBaseControl IO m) => MonadBase IO (GmOutT m) where
liftBase = GmOutT . liftBase
instance (MonadBaseControl IO m) => MonadBaseControl IO (GmOutT m) where
type StM (GmOutT m) a = StM (ReaderT GhcModEnv m) a
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
{-# INLINE liftBaseWith #-}
{-# INLINE restoreM #-}
instance MonadTransControl GmOutT where
type StT GmOutT a = StT (ReaderT GhcModEnv) a
liftWith = defaultLiftWith GmOutT unGmOutT
restoreT = defaultRestoreT GmOutT
-- GmlT ------------------------------------------
instance (MonadBaseControl IO m) => MonadBase IO (GmlT m) where
liftBase = GmlT . liftBase
instance (MonadBaseControl IO m) => MonadBaseControl IO (GmlT m) where
type StM (GmlT m) a = StM (GmT m) a
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
{-# INLINE liftBaseWith #-}
{-# INLINE restoreM #-}
instance MonadTransControl GmlT where
type StT GmlT a = StT GmT a
liftWith f = GmlT $
liftWith $ \runGm ->
liftWith $ \runEnv ->
f $ \ma -> runEnv $ runGm $ unGmlT ma
restoreT = GmlT . restoreT . restoreT
instance MonadTrans GmlT where
lift = GmlT . lift . lift
-- GmT ------------------------------------------
instance forall r m. MonadReader r m => MonadReader r (GmT m) where
local f ma = gmLiftWithInner (\run -> local f (run ma))
ask = gmLiftInner ask
instance MonadState s m => MonadState s (GmT m) where
get = GmT $ lift $ lift $ lift get
put = GmT . lift . lift . lift . put
state = GmT . lift . lift . lift . state
instance Monad m => MonadJournal GhcModLog (GmT m) where
journal w = GmT $ lift $ lift $ (journal w)
history = GmT $ lift $ lift $ history
clear = GmT $ lift $ lift $ clear
instance (MonadBaseControl IO m) => MonadBase IO (GmT m) where
liftBase = GmT . liftBase
instance (MonadBaseControl IO m) => MonadBaseControl IO (GmT m) where
type StM (GmT m) a =
StM (StateT GhcModState
(ErrorT GhcModError
(JournalT GhcModLog
(ReaderT GhcModEnv m) ) ) ) a
liftBaseWith f = GmT (liftBaseWith $ \runInBase ->
f $ runInBase . unGmT)
restoreM = GmT . restoreM
{-# INLINE liftBaseWith #-}
{-# INLINE restoreM #-}
instance MonadTransControl GmT where
type StT GmT a = (Either GhcModError (a, GhcModState), GhcModLog)
liftWith f = GmT $
liftWith $ \runS ->
liftWith $ \runE ->
liftWith $ \runJ ->
liftWith $ \runR ->
f $ \ma -> runR $ runJ $ runE $ runS $ unGmT ma
restoreT = GmT . restoreT . restoreT . restoreT . restoreT
{-# INLINE liftWith #-}
{-# INLINE restoreT #-}
instance MonadTrans GmT where
lift = GmT . lift . lift . lift . lift
gmLiftInner :: Monad m => m a -> GmT m a
gmLiftInner = GmT . lift . lift . lift . lift
gmLiftWithInner :: (MonadTransControl t, Monad m, Monad (t m))
=> (Run t -> m (StT t a)) -> t m a
gmLiftWithInner f = liftWith f >>= restoreT . return

View File

@ -0,0 +1,83 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015,2016 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE CPP, UndecidableInstances, StandaloneDeriving #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Language.Haskell.GhcMod.Monad.Orphans where
#include "Compat.hs_h"
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad.Newtypes
#if DIFFERENT_MONADIO
import qualified MonadUtils as GHC (MonadIO(..))
#endif
import qualified Control.Monad.IO.Class as MTL
import Control.Monad.Reader (ReaderT(..))
import Control.Monad.State.Strict (StateT(..))
import Control.Monad.Trans.Journal (JournalT)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Error (Error(..), ErrorT(..))
--------------------------------------------------
-- Miscellaneous instances
#if DIFFERENT_MONADIO
instance MTL.MonadIO m => GHC.MonadIO (ReaderT x m) where
liftIO = MTL.liftIO
instance MTL.MonadIO m => GHC.MonadIO (StateT x m) where
liftIO = MTL.liftIO
instance (Error e, MTL.MonadIO m) => GHC.MonadIO (ErrorT e m) where
liftIO = MTL.liftIO
instance MTL.MonadIO m => GHC.MonadIO (JournalT x m) where
liftIO = MTL.liftIO
instance MTL.MonadIO m => GHC.MonadIO (MaybeT m) where
liftIO = MTL.liftIO
deriving instance MTL.MonadIO m => GHC.MonadIO (GmOutT m)
deriving instance MTL.MonadIO m => GHC.MonadIO (GmT m)
deriving instance MTL.MonadIO m => GHC.MonadIO (GmlT m)
deriving instance GHC.MonadIO LightGhc
#endif
deriving instance MTL.MonadIO m => MTL.MonadIO (GmOutT m)
deriving instance MTL.MonadIO m => MTL.MonadIO (GmT m)
deriving instance MTL.MonadIO m => MTL.MonadIO (GmlT m)
deriving instance MTL.MonadIO LightGhc
instance MonadIO IO where
liftIO = id
instance MonadIO m => MonadIO (ReaderT x m) where
liftIO = MTL.liftIO
instance MonadIO m => MonadIO (StateT x m) where
liftIO = MTL.liftIO
instance (Error e, MonadIO m) => MonadIO (ErrorT e m) where
liftIO = MTL.liftIO
instance MonadIO m => MonadIO (JournalT x m) where
liftIO = MTL.liftIO
instance MonadIO m => MonadIO (MaybeT m) where
liftIO = MTL.liftIO
instance MonadIOC m => MonadIO (GmOutT m) where
liftIO = MTL.liftIO
instance MonadIOC m => MonadIO (GmT m) where
liftIO = MTL.liftIO
instance MonadIOC m => MonadIO (GmlT m) where
liftIO = MTL.liftIO
instance MonadIO LightGhc where
liftIO = MTL.liftIO

View File

@ -0,0 +1,52 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015,2016 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, UndecidableInstances #-}
module Language.Haskell.GhcMod.Monad.Out where
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad.Newtypes
import Control.Monad
import Control.Monad.State.Strict (StateT(..))
import Control.Monad.Trans.Journal (JournalT)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Reader.Class
import Control.Monad.Trans.Class (MonadTrans(..))
import Prelude
class Monad m => GmOut m where
gmoAsk :: m GhcModOut
instance Monad m => GmOut (GmOutT m) where
gmoAsk = GmOutT ask
instance Monad m => GmOut (GmlT m) where
gmoAsk = GmlT $ lift $ GmOutT ask
instance GmOut m => GmOut (GmT m) where
gmoAsk = lift gmoAsk
instance GmOut m => GmOut (StateT s m) where
gmoAsk = lift gmoAsk
instance GmOut m => GmOut (JournalT w m) where
gmoAsk = lift gmoAsk
instance GmOut m => GmOut (MaybeT m) where
gmoAsk = lift gmoAsk

View File

@ -0,0 +1,67 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015,2016 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE GeneralizedNewtypeDeriving, StandaloneDeriving #-}
{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
module Language.Haskell.GhcMod.Monad.State where
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad.Newtypes
import Control.Monad
import Control.Monad.State.Strict (StateT(..))
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.State.Class (MonadState(..))
import Control.Monad.Trans.Class (MonadTrans(..))
import Prelude
class Monad m => GmState m where
gmsGet :: m GhcModState
gmsGet = gmsState (\s -> (s, s))
gmsPut :: GhcModState -> m ()
gmsPut s = gmsState (\_ -> ((), s))
gmsState :: (GhcModState -> (a, GhcModState)) -> m a
gmsState f = do
s <- gmsGet
let ~(a, s') = f s
gmsPut s'
return a
{-# MINIMAL gmsState | gmsGet, gmsPut #-}
instance GmState m => GmState (StateT s m) where
gmsGet = lift gmsGet
gmsPut = lift . gmsPut
gmsState = lift . gmsState
instance Monad m => GmState (StateT GhcModState m) where
gmsGet = get
gmsPut = put
gmsState = state
instance Monad m => GmState (GmT m) where
gmsGet = GmT get
gmsPut = GmT . put
gmsState = GmT . state
instance GmState m => GmState (MaybeT m) where
gmsGet = MaybeT $ Just `liftM` gmsGet
gmsPut = MaybeT . (Just `liftM`) . gmsPut
gmsState = MaybeT . (Just `liftM`) . gmsState
deriving instance (Monad m, GmState (GhcModT m)) => GmState (GmlT m)

View File

@ -36,7 +36,6 @@ module Language.Haskell.GhcMod.Monad.Types (
, defaultGhcModState , defaultGhcModState
, GmGhcSession(..) , GmGhcSession(..)
, GmComponent(..) , GmComponent(..)
, CompilerMode(..)
-- * Accessing 'GhcModEnv', 'GhcModState' and 'GhcModLog' -- * Accessing 'GhcModEnv', 'GhcModState' and 'GhcModLog'
, GmLogLevel(..) , GmLogLevel(..)
, GhcModLog(..) , GhcModLog(..)
@ -50,8 +49,6 @@ module Language.Haskell.GhcMod.Monad.Types (
, options , options
, outputOpts , outputOpts
, withOptions , withOptions
, getCompilerMode
, setCompilerMode
, getMMappedFiles , getMMappedFiles
, setMMappedFiles , setMMappedFiles
, addMMappedFile , addMMappedFile
@ -65,21 +62,17 @@ module Language.Haskell.GhcMod.Monad.Types (
, gmlSetSession , gmlSetSession
) where ) where
-- MonadUtils of GHC 7.6 or earlier defines its own MonadIO. #include "Compat.hs_h"
-- RWST does not automatically become an instance of MonadIO.
-- MonadUtils of GHC 7.8 or later imports MonadIO in Monad.Control.IO.Class.
-- So, RWST automatically becomes an instance of
#if __GLASGOW_HASKELL__ < 708
-- 'CoreMonad.MonadIO' and 'Control.Monad.IO.Class.MonadIO' are different
-- classes before ghc 7.8
#define DIFFERENT_MONADIO 1
-- RWST doen't have a MonadIO instance before ghc 7.8
#define MONADIO_INSTANCES 1
#endif
import Language.Haskell.GhcMod.Types import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad.Env
import Language.Haskell.GhcMod.Monad.State
import Language.Haskell.GhcMod.Monad.Log
import Language.Haskell.GhcMod.Monad.Out
import Language.Haskell.GhcMod.Monad.Newtypes
import Language.Haskell.GhcMod.Monad.Orphans ()
import GHC import GHC
import DynFlags import DynFlags
import Exception import Exception
@ -89,25 +82,12 @@ import Control.Applicative
import Control.Monad import Control.Monad
import Control.Monad.Reader (ReaderT(..)) import Control.Monad.Reader (ReaderT(..))
import Control.Monad.Error (ErrorT(..), MonadError(..))
import Control.Monad.State.Strict (StateT(..)) import Control.Monad.State.Strict (StateT(..))
import Control.Monad.Trans.Journal (JournalT) import Control.Monad.Trans.Journal (JournalT)
import Control.Monad.Trans.Maybe (MaybeT(..))
import Control.Monad.Base (MonadBase(..), liftBase)
import Control.Monad.Trans.Control import Control.Monad.Trans.Control
import Control.Monad.Reader.Class import Control.Monad.Reader.Class
import Control.Monad.Writer.Class
import Control.Monad.State.Class (MonadState(..))
import Control.Monad.Journal.Class (MonadJournal(..))
import Control.Monad.Trans.Class (MonadTrans(..))
import Control.Monad.Error (Error(..))
import qualified Control.Monad.IO.Class as MTL
#if DIFFERENT_MONADIO
import Data.Monoid (Monoid)
#endif
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe import Data.Maybe
@ -115,328 +95,8 @@ import Data.Monoid
import Data.IORef import Data.IORef
import Prelude import Prelude
import qualified MonadUtils as GHC (MonadIO(..))
type GhcModT m = GmT (GmOutT m)
newtype GmOutT m a = GmOutT {
unGmOutT :: ReaderT GhcModOut m a
} deriving ( Functor
, Applicative
, Alternative
, Monad
, MonadPlus
, MonadTrans
, MTL.MonadIO
#if DIFFERENT_MONADIO
, GHC.MonadIO
#endif
, GmLog
)
newtype GmT m a = GmT {
unGmT :: StateT GhcModState
(ErrorT GhcModError
(JournalT GhcModLog
(ReaderT GhcModEnv m) ) ) a
} deriving ( Functor
, Applicative
, Alternative
, Monad
, MonadPlus
, MTL.MonadIO
#if DIFFERENT_MONADIO
, GHC.MonadIO
#endif
, MonadError GhcModError
)
newtype GmlT m a = GmlT { unGmlT :: GhcModT m a }
deriving ( Functor
, Applicative
, Alternative
, Monad
, MonadPlus
, MTL.MonadIO
#if DIFFERENT_MONADIO
, GHC.MonadIO
#endif
, MonadError GhcModError
, GmEnv
, GmState
, GmLog
)
newtype LightGhc a = LightGhc { unLightGhc :: ReaderT (IORef HscEnv) IO a }
deriving ( Functor
, Applicative
, Monad
, MTL.MonadIO
#if DIFFERENT_MONADIO
, GHC.MonadIO
#endif
)
--------------------------------------------------
-- Miscellaneous instances
#if DIFFERENT_MONADIO
instance MTL.MonadIO m => GHC.MonadIO (ReaderT x m) where
liftIO = MTL.liftIO
instance MTL.MonadIO m => GHC.MonadIO (StateT x m) where
liftIO = MTL.liftIO
instance (Error e, MTL.MonadIO m) => GHC.MonadIO (ErrorT e m) where
liftIO = MTL.liftIO
instance MTL.MonadIO m => GHC.MonadIO (JournalT x m) where
liftIO = MTL.liftIO
instance MTL.MonadIO m => GHC.MonadIO (MaybeT m) where
liftIO = MTL.liftIO
#endif
instance MonadIO IO where
liftIO = id
instance MonadIO m => MonadIO (ReaderT x m) where
liftIO = MTL.liftIO
instance MonadIO m => MonadIO (StateT x m) where
liftIO = MTL.liftIO
instance (Error e, MonadIO m) => MonadIO (ErrorT e m) where
liftIO = MTL.liftIO
instance MonadIO m => MonadIO (JournalT x m) where
liftIO = MTL.liftIO
instance MonadIO m => MonadIO (MaybeT m) where
liftIO = MTL.liftIO
instance MonadIOC m => MonadIO (GmOutT m) where
liftIO = MTL.liftIO
instance MonadIOC m => MonadIO (GmT m) where
liftIO = MTL.liftIO
instance MonadIOC m => MonadIO (GmlT m) where
liftIO = MTL.liftIO
instance MonadIO LightGhc where
liftIO = MTL.liftIO
instance MonadTrans GmT where
lift = GmT . lift . lift . lift . lift
instance MonadTrans GmlT where
lift = GmlT . lift . lift
--------------------------------------------------
-- Gm Classes
type Gm m = (GmEnv m, GmState m, GmLog m, GmOut m) type Gm m = (GmEnv m, GmState m, GmLog m, GmOut m)
-- GmEnv -----------------------------------------
class Monad m => GmEnv m where
gmeAsk :: m GhcModEnv
gmeAsk = gmeReader id
gmeReader :: (GhcModEnv -> a) -> m a
gmeReader f = f `liftM` gmeAsk
gmeLocal :: (GhcModEnv -> GhcModEnv) -> m a -> m a
{-# MINIMAL (gmeAsk | gmeReader), gmeLocal #-}
instance Monad m => GmEnv (GmT m) where
gmeAsk = GmT ask
gmeReader = GmT . reader
gmeLocal f a = GmT $ local f (unGmT a)
instance GmEnv m => GmEnv (GmOutT m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
instance GmEnv m => GmEnv (StateT s m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
instance GmEnv m => GmEnv (JournalT GhcModLog m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
instance GmEnv m => GmEnv (ErrorT GhcModError m) where
gmeAsk = lift gmeAsk
gmeReader = lift . gmeReader
gmeLocal f ma = gmLiftWithInner (\run -> gmeLocal f (run ma))
-- GmState ---------------------------------------
class Monad m => GmState m where
gmsGet :: m GhcModState
gmsGet = gmsState (\s -> (s, s))
gmsPut :: GhcModState -> m ()
gmsPut s = gmsState (\_ -> ((), s))
gmsState :: (GhcModState -> (a, GhcModState)) -> m a
gmsState f = do
s <- gmsGet
let ~(a, s') = f s
gmsPut s'
return a
{-# MINIMAL gmsState | gmsGet, gmsPut #-}
instance GmState m => GmState (StateT s m) where
gmsGet = lift gmsGet
gmsPut = lift . gmsPut
gmsState = lift . gmsState
instance Monad m => GmState (StateT GhcModState m) where
gmsGet = get
gmsPut = put
gmsState = state
instance Monad m => GmState (GmT m) where
gmsGet = GmT get
gmsPut = GmT . put
gmsState = GmT . state
instance GmState m => GmState (MaybeT m) where
gmsGet = MaybeT $ Just `liftM` gmsGet
gmsPut = MaybeT . (Just `liftM`) . gmsPut
gmsState = MaybeT . (Just `liftM`) . gmsState
-- GmLog -----------------------------------------
class Monad m => GmLog m where
gmlJournal :: GhcModLog -> m ()
gmlHistory :: m GhcModLog
gmlClear :: m ()
instance Monad m => GmLog (JournalT GhcModLog m) where
gmlJournal = journal
gmlHistory = history
gmlClear = clear
instance Monad m => GmLog (GmT m) where
gmlJournal = GmT . lift . lift . journal
gmlHistory = GmT $ lift $ lift history
gmlClear = GmT $ lift $ lift clear
instance (Monad m, GmLog m) => GmLog (ReaderT r m) where
gmlJournal = lift . gmlJournal
gmlHistory = lift gmlHistory
gmlClear = lift gmlClear
instance (Monad m, GmLog m) => GmLog (StateT s m) where
gmlJournal = lift . gmlJournal
gmlHistory = lift gmlHistory
gmlClear = lift gmlClear
-- GmOut -----------------------------------------
class Monad m => GmOut m where
gmoAsk :: m GhcModOut
instance Monad m => GmOut (GmOutT m) where
gmoAsk = GmOutT ask
instance Monad m => GmOut (GmlT m) where
gmoAsk = GmlT $ lift $ GmOutT ask
instance GmOut m => GmOut (GmT m) where
gmoAsk = lift gmoAsk
instance GmOut m => GmOut (StateT s m) where
gmoAsk = lift gmoAsk
instance Monad m => MonadJournal GhcModLog (GmT m) where
journal !w = GmT $ lift $ lift $ (journal w)
history = GmT $ lift $ lift $ history
clear = GmT $ lift $ lift $ clear
instance forall r m. MonadReader r m => MonadReader r (GmT m) where
local f ma = gmLiftWithInner (\run -> local f (run ma))
ask = gmLiftInner ask
instance (Monoid w, MonadWriter w m) => MonadWriter w (GmT m) where
tell = gmLiftInner . tell
listen ma =
liftWith (\run -> listen (run ma)) >>= \(sta, w) ->
flip (,) w `liftM` restoreT (return sta)
pass maww = maww >>= gmLiftInner . pass . return
instance MonadState s m => MonadState s (GmT m) where
get = GmT $ lift $ lift $ lift get
put = GmT . lift . lift . lift . put
state = GmT . lift . lift . lift . state
--------------------------------------------------
-- monad-control instances
-- GmOutT ----------------------------------------
instance (MonadBaseControl IO m) => MonadBase IO (GmOutT m) where
liftBase = GmOutT . liftBase
instance (MonadBaseControl IO m) => MonadBaseControl IO (GmOutT m) where
type StM (GmOutT m) a = StM (ReaderT GhcModEnv m) a
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
{-# INLINE liftBaseWith #-}
{-# INLINE restoreM #-}
instance MonadTransControl GmOutT where
type StT GmOutT a = StT (ReaderT GhcModEnv) a
liftWith = defaultLiftWith GmOutT unGmOutT
restoreT = defaultRestoreT GmOutT
-- GmlT ------------------------------------------
instance (MonadBaseControl IO m) => MonadBase IO (GmlT m) where
liftBase = GmlT . liftBase
instance (MonadBaseControl IO m) => MonadBaseControl IO (GmlT m) where
type StM (GmlT m) a = StM (GmT m) a
liftBaseWith = defaultLiftBaseWith
restoreM = defaultRestoreM
{-# INLINE liftBaseWith #-}
{-# INLINE restoreM #-}
instance MonadTransControl GmlT where
type StT GmlT a = StT GmT a
liftWith f = GmlT $
liftWith $ \runGm ->
liftWith $ \runEnv ->
f $ \ma -> runEnv $ runGm $ unGmlT ma
restoreT = GmlT . restoreT . restoreT
-- GmT ------------------------------------------
instance (MonadBaseControl IO m) => MonadBase IO (GmT m) where
liftBase = GmT . liftBase
instance (MonadBaseControl IO m) => MonadBaseControl IO (GmT m) where
type StM (GmT m) a =
StM (StateT GhcModState
(ErrorT GhcModError
(JournalT GhcModLog
(ReaderT GhcModEnv m) ) ) ) a
liftBaseWith f = GmT (liftBaseWith $ \runInBase ->
f $ runInBase . unGmT)
restoreM = GmT . restoreM
{-# INLINE liftBaseWith #-}
{-# INLINE restoreM #-}
instance MonadTransControl GmT where
type StT GmT a = (Either GhcModError (a, GhcModState), GhcModLog)
liftWith f = GmT $
liftWith $ \runS ->
liftWith $ \runE ->
liftWith $ \runJ ->
liftWith $ \runR ->
f $ \ma -> runR $ runJ $ runE $ runS $ unGmT ma
restoreT = GmT . restoreT . restoreT . restoreT . restoreT
{-# INLINE liftWith #-}
{-# INLINE restoreT #-}
gmLiftInner :: Monad m => m a -> GmT m a
gmLiftInner = GmT . lift . lift . lift . lift
gmLiftWithInner :: (MonadTransControl t, Monad m, Monad (t m))
=> (Run t -> m (StT t a)) -> t m a
gmLiftWithInner f = liftWith f >>= restoreT . return
-------------------------------------------------- --------------------------------------------------
-- GHC API instances ----------------------------- -- GHC API instances -----------------------------
@ -455,16 +115,16 @@ instance (MonadIO m, MonadBaseControl IO m) => GhcMonad (GmlT m) where
gmlGetSession :: (MonadIO m, MonadBaseControl IO m) => GmlT m HscEnv gmlGetSession :: (MonadIO m, MonadBaseControl IO m) => GmlT m HscEnv
gmlGetSession = do gmlGetSession = do
ref <- gmgsSession . fromJust . gmGhcSession <$> gmsGet ref <- gmgsSession . fromJust . gmGhcSession <$> gmsGet
GHC.liftIO $ readIORef ref liftIO $ readIORef ref
gmlSetSession :: (MonadIO m, MonadBaseControl IO m) => HscEnv -> GmlT m () gmlSetSession :: (MonadIO m, MonadBaseControl IO m) => HscEnv -> GmlT m ()
gmlSetSession a = do gmlSetSession a = do
ref <- gmgsSession . fromJust . gmGhcSession <$> gmsGet ref <- gmgsSession . fromJust . gmGhcSession <$> gmsGet
GHC.liftIO $ flip writeIORef a ref liftIO $ flip writeIORef a ref
instance GhcMonad LightGhc where instance GhcMonad LightGhc where
getSession = (GHC.liftIO . readIORef) =<< LightGhc ask getSession = (liftIO . readIORef) =<< LightGhc ask
setSession a = (GHC.liftIO . flip writeIORef a) =<< LightGhc ask setSession a = (liftIO . flip writeIORef a) =<< LightGhc ask
#if __GLASGOW_HASKELL__ >= 706 #if __GLASGOW_HASKELL__ >= 706
instance (MonadIO m, MonadBaseControl IO m) => HasDynFlags (GmlT m) where instance (MonadIO m, MonadBaseControl IO m) => HasDynFlags (GmlT m) where
@ -519,6 +179,14 @@ instance (MonadIO m, MonadBaseControl IO m) => ExceptionMonad (ReaderT s m) wher
gmask = liftBaseOp gmask . liftRestore gmask = liftBaseOp gmask . liftRestore
where liftRestore f r = f $ liftBaseOp_ r where liftRestore f r = f $ liftBaseOp_ r
instance (Monoid w, MonadIO m, MonadBaseControl IO m) => ExceptionMonad (JournalT w m) where
gcatch act handler = control $ \run ->
run act `gcatch` (run . handler)
gmask = liftBaseOp gmask . liftRestore
where liftRestore f r = f $ liftBaseOp_ r
---------------------------------------------------------------- ----------------------------------------------------------------
options :: GmEnv m => m Options options :: GmEnv m => m Options
@ -530,12 +198,6 @@ outputOpts = gmoOptions `liftM` gmoAsk
cradle :: GmEnv m => m Cradle cradle :: GmEnv m => m Cradle
cradle = gmCradle `liftM` gmeAsk cradle = gmCradle `liftM` gmeAsk
getCompilerMode :: GmState m => m CompilerMode
getCompilerMode = gmCompilerMode `liftM` gmsGet
setCompilerMode :: GmState m => CompilerMode -> m ()
setCompilerMode mode = (\s -> gmsPut s { gmCompilerMode = mode } ) =<< gmsGet
getMMappedFiles :: GmState m => m FileMappingMap getMMappedFiles :: GmState m => m FileMappingMap
getMMappedFiles = gmMMappedFiles `liftM` gmsGet getMMappedFiles = gmMMappedFiles `liftM` gmsGet

View File

@ -200,7 +200,16 @@ setupConfigPath dist = dist </> "setup-config"
-- localBuildInfoFile defaultDistPref -- localBuildInfoFile defaultDistPref
macrosHeaderPath :: FilePath macrosHeaderPath :: FilePath
macrosHeaderPath = "build/autogen/cabal_macros.h" macrosHeaderPath = autogenModulesDir </> "cabal_macros.h"
autogenModulePath :: String -> String
autogenModulePath pkg_name =
autogenModulesDir </> ("Paths_" ++ map fixchar pkg_name) <.> ".hs"
where fixchar '-' = '_'
fixchar c = c
autogenModulesDir :: FilePath
autogenModulesDir = "build" </> "autogen"
ghcSandboxPkgDbDir :: String -> String ghcSandboxPkgDbDir :: String -> String
ghcSandboxPkgDbDir buildPlatf = do ghcSandboxPkgDbDir buildPlatf = do

View File

@ -143,7 +143,7 @@ runGmlTWith efnmns' mdf wrapper action = do
| otherwise = setEmptyLogger | otherwise = setEmptyLogger
initSession opts' $ initSession opts' $
setModeSimple >>> setLogger >>> mdf setHscNothing >>> setLogger >>> mdf
mappedStrs <- getMMappedFilePaths mappedStrs <- getMMappedFilePaths
let targetStrs = mappedStrs ++ map moduleNameString mns ++ cfns let targetStrs = mappedStrs ++ map moduleNameString mns ++ cfns
@ -199,25 +199,20 @@ resolvedComponentsCache distdir = Cached {
cacheFile = resolvedComponentsCacheFile distdir, cacheFile = resolvedComponentsCacheFile distdir,
cachedAction = \tcfs comps ma -> do cachedAction = \tcfs comps ma -> do
Cradle {..} <- cradle Cradle {..} <- cradle
let iifsM = invalidatingInputFiles tcfs let iifs = invalidatingInputFiles tcfs
setupChanged =
(cradleRootDir </> setupConfigPath distdir) `elem` iifs
mums :: Maybe [Either FilePath ModuleName] mums :: Maybe [Either FilePath ModuleName]
mums = mums =
case iifsM of
Nothing -> Nothing
Just iifs ->
let let
filterOutSetupCfg = filterOutSetupCfg =
filter (/= cradleRootDir </> setupConfigPath distdir) filter (/= cradleRootDir </> setupConfigPath distdir)
changedFiles = filterOutSetupCfg iifs changedFiles = filterOutSetupCfg iifs
in if null changedFiles in if null changedFiles || setupChanged
then Nothing then Nothing
else Just $ map Left changedFiles else Just $ map Left changedFiles
setupChanged = maybe False
(elem $ cradleRootDir </> setupConfigPath distdir)
iifsM
case (setupChanged, ma) of
(False, Just mcs) -> gmsGet >>= \s -> gmsPut s { gmComponents = mcs }
_ -> return ()
let mdesc (Left f) = "file:" ++ f let mdesc (Left f) = "file:" ++ f
mdesc (Right mn) = "module:" ++ moduleNameString mn mdesc (Right mn) = "module:" ++ moduleNameString mn
@ -229,7 +224,8 @@ resolvedComponentsCache distdir = Cached {
gmLog GmDebug "resolvedComponentsCache" $ gmLog GmDebug "resolvedComponentsCache" $
text "files changed" <+>: changedDoc text "files changed" <+>: changedDoc
mcs <- resolveGmComponents mums comps mcs <- resolveGmComponents ((,) <$> mums <*> ma) comps
return (setupConfigPath distdir : flatten mcs , mcs) return (setupConfigPath distdir : flatten mcs , mcs)
} }
@ -334,7 +330,7 @@ resolveEntrypoint Cradle {..} c@GmComponent {..} = do
rms <- resolveModule env srcDirs `mapM` eps rms <- resolveModule env srcDirs `mapM` eps
return c { gmcEntrypoints = Set.fromList $ catMaybes rms } return c { gmcEntrypoints = Set.fromList $ catMaybes rms }
-- TODO: remember that he file from `main-is:` is always module `Main` and let -- TODO: remember that the file from `main-is:` is always module `Main` and let
-- ghc do the warning about it. Right now we run that module through -- ghc do the warning about it. Right now we run that module through
-- resolveModule like any other -- resolveModule like any other
resolveChEntrypoints :: FilePath -> ChEntrypoint -> IO [CompilationUnit] resolveChEntrypoints :: FilePath -> ChEntrypoint -> IO [CompilationUnit]
@ -387,27 +383,30 @@ resolveModule env srcDirs (Left fn') = do
-- | makeRelative dir fn /= fn -- | makeRelative dir fn /= fn
type CompilationUnit = Either FilePath ModuleName type CompilationUnit = Either FilePath ModuleName
type Components =
[GmComponent 'GMCRaw (Set ModulePath)]
type ResolvedComponentsMap =
Map ChComponentName (GmComponent 'GMCResolved (Set ModulePath))
resolveGmComponents :: (IOish m, Gm m) resolveGmComponents :: (IOish m, Gm m)
=> Maybe [CompilationUnit] => Maybe ([CompilationUnit], ResolvedComponentsMap)
-- ^ Updated modules -- ^ Updated modules
-> [GmComponent 'GMCRaw (Set ModulePath)] -> Components -> m ResolvedComponentsMap
-> m (Map ChComponentName (GmComponent 'GMCResolved (Set ModulePath))) resolveGmComponents mcache cs = do
resolveGmComponents mumns cs = do let rcm = fromMaybe Map.empty $ snd <$> mcache
s <- gmsGet
m' <- foldrM' (gmComponents s) cs $ \c m -> do m' <- foldrM' rcm cs $ \c m -> do
case Map.lookup (gmcName c) m of case Map.lookup (gmcName c) m of
Nothing -> insertUpdated m c Nothing -> insertUpdated m c
Just c' -> if same gmcRawEntrypoints c c' && same gmcGhcSrcOpts c c' Just c' -> if same gmcRawEntrypoints c c' && same gmcGhcSrcOpts c c'
then return m then return m
else insertUpdated m c else insertUpdated m c
gmsPut s { gmComponents = m' }
return m' return m'
where where
foldrM' b fa f = foldrM f b fa foldrM' b fa f = foldrM f b fa
insertUpdated m c = do insertUpdated m c = do
rc <- resolveGmComponent mumns c rc <- resolveGmComponent (fst <$> mcache) c
return $ Map.insert (gmcName rc) rc m return $ Map.insert (gmcName rc) rc m
same :: Eq b same :: Eq b
@ -431,20 +430,24 @@ loadTargets opts targetStrs = do
setTargets targets setTargets targets
mode <- getCompilerMode mg <- depanal [] False
if mode == Intelligent
then loadTargets' Intelligent let interp = needsHscInterpreted mg
else do target <- hscTarget <$> getSessionDynFlags
mdls <- depanal [] False when (interp && target /= HscInterpreted) $ do
let fallback = needsFallback mdls
if fallback then do
resetTargets targets resetTargets targets
setIntelligent _ <- setSessionDynFlags . setHscInterpreted =<< getSessionDynFlags
gmLog GmInfo "loadTargets" $ gmLog GmInfo "loadTargets" $ text "Target needs interpeter, switching to LinkInMemory/HscInterpreted. Perfectly normal if anything is using TemplateHaskell, QuasiQuotes or PatternSynonyms."
text "Target needs interpeter, switching to LinkInMemory/HscInterpreted. Perfectly normal if anything is using TemplateHaskell, QuasiQuotes or PatternSynonyms."
loadTargets' Intelligent target' <- hscTarget <$> getSessionDynFlags
else
loadTargets' Simple case target' of
HscNothing -> do
void $ load LoadAllTargets
mapM_ (parseModule >=> typecheckModule >=> desugarModule) mg
HscInterpreted -> do
void $ load LoadAllTargets
_ -> error ("loadTargets: unsupported hscTarget")
gmLog GmDebug "loadTargets" $ text "Loading done" gmLog GmDebug "loadTargets" $ text "Loading done"
@ -456,30 +459,16 @@ loadTargets opts targetStrs = do
return $ Target tid taoc src return $ Target tid taoc src
relativize tgt = return tgt relativize tgt = return tgt
loadTargets' Simple = do
void $ load LoadAllTargets
mapM_ (parseModule >=> typecheckModule >=> desugarModule) =<< getModuleGraph
loadTargets' Intelligent = do
df <- getSessionDynFlags
void $ setSessionDynFlags (setModeIntelligent df)
void $ load LoadAllTargets
resetTargets targets' = do resetTargets targets' = do
setTargets [] setTargets []
void $ load LoadAllTargets void $ load LoadAllTargets
setTargets targets' setTargets targets'
setIntelligent = do
newdf <- setModeIntelligent <$> getSessionDynFlags
void $ setSessionDynFlags newdf
setCompilerMode Intelligent
showTargetId (Target (TargetModule s) _ _) = moduleNameString s showTargetId (Target (TargetModule s) _ _) = moduleNameString s
showTargetId (Target (TargetFile s _) _ _) = s showTargetId (Target (TargetFile s _) _ _) = s
needsFallback :: ModuleGraph -> Bool needsHscInterpreted :: ModuleGraph -> Bool
needsFallback = any $ \ms -> needsHscInterpreted = any $ \ms ->
let df = ms_hspp_opts ms in let df = ms_hspp_opts ms in
Opt_TemplateHaskell `xopt` df Opt_TemplateHaskell `xopt` df
|| Opt_QuasiQuotes `xopt` df || Opt_QuasiQuotes `xopt` df
@ -492,4 +481,5 @@ cabalResolvedComponents :: (IOish m) =>
cabalResolvedComponents = do cabalResolvedComponents = do
crdl@(Cradle{..}) <- cradle crdl@(Cradle{..}) <- cradle
comps <- mapM (resolveEntrypoint crdl) =<< getComponents comps <- mapM (resolveEntrypoint crdl) =<< getComponents
withAutogen $
cached cradleRootDir (resolvedComponentsCache cradleDistDir) comps cached cradleRootDir (resolvedComponentsCache cradleDistDir) comps

View File

@ -0,0 +1,45 @@
module Language.Haskell.GhcMod.Test where
import Control.Applicative
import Data.List
import System.FilePath
import System.Directory
import Prelude
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad
import Language.Haskell.GhcMod.DynFlags
import GHC
import GHC.Exception
import OccName
test :: IOish m
=> FilePath -> GhcModT m String
test f = runGmlT' [Left f] (fmap setHscInterpreted . deferErrors) $ do
mg <- getModuleGraph
root <- cradleRootDir <$> cradle
f' <- makeRelative root <$> liftIO (canonicalizePath f)
let Just ms = find ((==Just f') . ml_hs_file . ms_location) mg
mdl = ms_mod ms
mn = moduleName mdl
Just mi <- getModuleInfo mdl
let exs = map (occNameString . getOccName) $ modInfoExports mi
cqs = filter ("prop_" `isPrefixOf`) exs
setContext [ IIDecl $ simpleImportDecl mn
, IIDecl $ simpleImportDecl $ mkModuleName "Test.QuickCheck"
]
_res <- mapM runTest cqs
return ""
runTest :: GhcMonad m => String -> m (Maybe SomeException)
runTest fn = do
res <- runStmt ("quickCheck " ++ fn) RunToCompletion
return $ case res of
RunOk [] -> Nothing
RunException se -> Just se
_ -> error "runTest"

View File

@ -15,9 +15,8 @@ import Control.Exception (Exception)
import Control.Applicative import Control.Applicative
import Control.Concurrent import Control.Concurrent
import Control.Monad import Control.Monad
import Data.Serialize import Data.Binary
import Data.Version import Data.Binary.Generic
import Data.List (intercalate)
import Data.Map (Map) import Data.Map (Map)
import qualified Data.Map as Map import qualified Data.Map as Map
import Data.Set (Set) import Data.Set (Set)
@ -35,7 +34,6 @@ import qualified MonadUtils as GHC (MonadIO(..))
#endif #endif
import GHC (ModuleName, moduleNameString, mkModuleName) import GHC (ModuleName, moduleNameString, mkModuleName)
import HscTypes (HscEnv) import HscTypes (HscEnv)
import PackageConfig (PackageConfig)
import GHC.Generics import GHC.Generics
import Text.PrettyPrint (Doc) import Text.PrettyPrint (Doc)
import Prelude import Prelude
@ -104,13 +102,6 @@ data Options = Options {
, optPrograms :: Programs , optPrograms :: Programs
-- | GHC command line options set on the @ghc-mod@ command line -- | GHC command line options set on the @ghc-mod@ command line
, optGhcUserOptions :: [GHCOption] , optGhcUserOptions :: [GHCOption]
-- | If 'True', 'browse' also returns operators.
, optOperators :: Bool
-- | If 'True', 'browse' also returns types.
, optDetailed :: Bool
-- | If 'True', 'browse' will return fully qualified name
, optQualified :: Bool
, optHlintOpts :: [String]
, optFileMappings :: [(FilePath, Maybe FilePath)] , optFileMappings :: [(FilePath, Maybe FilePath)]
} deriving (Show) } deriving (Show)
@ -130,10 +121,6 @@ defaultOptions = Options {
, stackProgram = "stack" , stackProgram = "stack"
} }
, optGhcUserOptions = [] , optGhcUserOptions = []
, optOperators = False
, optDetailed = False
, optQualified = False
, optHlintOpts = []
, optFileMappings = [] , optFileMappings = []
} }
@ -212,17 +199,13 @@ data GhcModCaches = GhcModCaches {
data GhcModState = GhcModState { data GhcModState = GhcModState {
gmGhcSession :: !(Maybe GmGhcSession) gmGhcSession :: !(Maybe GmGhcSession)
, gmComponents :: !(Map ChComponentName (GmComponent 'GMCResolved (Set ModulePath)))
, gmCompilerMode :: !CompilerMode
, gmCaches :: !GhcModCaches , gmCaches :: !GhcModCaches
, gmMMappedFiles :: !FileMappingMap , gmMMappedFiles :: !FileMappingMap
} }
data CompilerMode = Simple | Intelligent deriving (Eq,Show,Read)
defaultGhcModState :: GhcModState defaultGhcModState :: GhcModState
defaultGhcModState = defaultGhcModState =
GhcModState n Map.empty Simple (GhcModCaches n n n n) Map.empty GhcModState n (GhcModCaches n n n n) Map.empty
where n = Nothing where n = Nothing
---------------------------------------------------------------- ----------------------------------------------------------------
@ -233,7 +216,9 @@ data GhcPkgDb = GlobalDb
| PackageDb String | PackageDb String
deriving (Eq, Show, Generic) deriving (Eq, Show, Generic)
instance Serialize GhcPkgDb instance Binary GhcPkgDb where
put = ggput . from
get = to `fmap` ggget
-- | A single GHC command line option. -- | A single GHC command line option.
type GHCOption = String type GHCOption = String
@ -241,33 +226,6 @@ type GHCOption = String
-- | An include directory for modules. -- | An include directory for modules.
type IncludeDir = FilePath type IncludeDir = FilePath
-- | A package name.
type PackageBaseName = String
-- | A package version.
type PackageVersion = String
-- | A package id.
type PackageId = String
-- | A package's name, verson and id.
type Package = (PackageBaseName, PackageVersion, PackageId)
pkgName :: Package -> PackageBaseName
pkgName (n, _, _) = n
pkgVer :: Package -> PackageVersion
pkgVer (_, v, _) = v
pkgId :: Package -> PackageId
pkgId (_, _, i) = i
showPkg :: Package -> String
showPkg (n, v, _) = intercalate "-" [n, v]
showPkgId :: Package -> String
showPkgId (n, v, i) = intercalate "-" [n, v, i]
-- | Haskell expression. -- | Haskell expression.
newtype Expression = Expression { getExpression :: String } newtype Expression = Expression { getExpression :: String }
deriving (Show, Eq, Ord) deriving (Show, Eq, Ord)
@ -287,14 +245,11 @@ data GmLogLevel =
| GmVomit | GmVomit
deriving (Eq, Ord, Enum, Bounded, Show, Read) deriving (Eq, Ord, Enum, Bounded, Show, Read)
-- | Collection of packages
type PkgDb = (Map Package PackageConfig)
data GmModuleGraph = GmModuleGraph { data GmModuleGraph = GmModuleGraph {
gmgGraph :: Map ModulePath (Set ModulePath) gmgGraph :: Map ModulePath (Set ModulePath)
} deriving (Eq, Ord, Show, Read, Generic, Typeable) } deriving (Eq, Ord, Show, Read, Generic, Typeable)
instance Serialize GmModuleGraph where instance Binary GmModuleGraph where
put GmModuleGraph {..} = put (mpim, graph) put GmModuleGraph {..} = put (mpim, graph)
where where
mpim :: Map ModulePath Integer mpim :: Map ModulePath Integer
@ -334,13 +289,17 @@ data GmComponent (t :: GmComponentType) eps = GmComponent {
, gmcSourceDirs :: [FilePath] , gmcSourceDirs :: [FilePath]
} deriving (Eq, Ord, Show, Read, Generic, Functor) } deriving (Eq, Ord, Show, Read, Generic, Functor)
instance Serialize eps => Serialize (GmComponent t eps) instance Binary eps => Binary (GmComponent t eps) where
put = ggput . from
get = to `fmap` ggget
data ModulePath = ModulePath { mpModule :: ModuleName, mpPath :: FilePath } data ModulePath = ModulePath { mpModule :: ModuleName, mpPath :: FilePath }
deriving (Eq, Ord, Show, Read, Generic, Typeable) deriving (Eq, Ord, Show, Read, Generic, Typeable)
instance Serialize ModulePath instance Binary ModulePath where
put = ggput . from
get = to `fmap` ggget
instance Serialize ModuleName where instance Binary ModuleName where
get = mkModuleName <$> get get = mkModuleName <$> get
put mn = put (moduleNameString mn) put mn = put (moduleNameString mn)
@ -398,13 +357,42 @@ instance Error GhcModError where
instance Exception GhcModError instance Exception GhcModError
deriving instance Generic Version instance Binary CabalHelper.Programs where
instance Serialize Version put = ggput . from
get = to `fmap` ggget
instance Binary ChModuleName where
put = ggput . from
get = to `fmap` ggget
instance Binary ChComponentName where
put = ggput . from
get = to `fmap` ggget
instance Binary ChEntrypoint where
put = ggput . from
get = to `fmap` ggget
instance Serialize CabalHelper.Programs -- | Options for "lintWith" function
instance Serialize ChModuleName data LintOpts = LintOpts {
instance Serialize ChComponentName optLintHlintOpts :: [String]
instance Serialize ChEntrypoint -- ^ options that will be passed to hlint executable
} deriving (Show)
-- | Default "LintOpts" instance
defaultLintOpts :: LintOpts
defaultLintOpts = LintOpts []
-- | Options for "browseWith" function
data BrowseOpts = BrowseOpts {
optBrowseOperators :: Bool
-- ^ If 'True', "browseWith" also returns operators.
, optBrowseDetailed :: Bool
-- ^ If 'True', "browseWith" also returns types.
, optBrowseQualified :: Bool
-- ^ If 'True', "browseWith" will return fully qualified name
} deriving (Show)
-- | Default "BrowseOpts" instance
defaultBrowseOpts :: BrowseOpts
defaultBrowseOpts = BrowseOpts False False False
mkLabel ''GhcModCaches mkLabel ''GhcModCaches
mkLabel ''GhcModState mkLabel ''GhcModState

View File

@ -70,8 +70,8 @@ uniqTempDirName dir =
| otherwise = c | otherwise = c
newTempDir :: FilePath -> IO FilePath newTempDir :: FilePath -> IO FilePath
newTempDir dir = newTempDir _dir =
flip createTempDirectory (uniqTempDirName dir) =<< getTemporaryDirectory flip createTempDirectory "ghc-mod" =<< getTemporaryDirectory
whenM :: Monad m => m Bool -> m () -> m () whenM :: Monad m => m Bool -> m () -> m ()
whenM mb ma = mb >>= flip when ma whenM mb ma = mb >>= flip when ma

View File

@ -20,7 +20,7 @@ data World = World {
, worldCabalConfig :: Maybe TimedFile , worldCabalConfig :: Maybe TimedFile
, worldCabalSandboxConfig :: Maybe TimedFile , worldCabalSandboxConfig :: Maybe TimedFile
, worldSymbolCache :: Maybe TimedFile , worldSymbolCache :: Maybe TimedFile
} deriving (Eq, Show) } deriving (Eq)
timedPackageCaches :: IOish m => GhcModT m [TimedFile] timedPackageCaches :: IOish m => GhcModT m [TimedFile]
timedPackageCaches = do timedPackageCaches = do

View File

@ -1,12 +1,12 @@
# Happy Haskell Programming # Happy Haskell Programming
[![Build Status](https://travis-ci.org/kazu-yamamoto/ghc-mod.png)](https://travis-ci.org/kazu-yamamoto/ghc-mod) [![Build Status](https://travis-ci.org/kazu-yamamoto/ghc-mod.svg?branch=master)](https://travis-ci.org/kazu-yamamoto/ghc-mod)
Please read: [http://www.mew.org/~kazu/proj/ghc-mod/](http://www.mew.org/~kazu/proj/ghc-mod/) Please read: [http://www.mew.org/~kazu/proj/ghc-mod/](http://www.mew.org/~kazu/proj/ghc-mod/)
## Using the stable version ## Using the stable version
The Emacs front-end is available from The Emacs front-end is available from
[*stable* MELPA](http://melpa-stable.milkbox.net/). This package should [*stable* MELPA](https://stable.melpa.org/). This package should
always be compatible with the latest version of ghc-mod from hackage. always be compatible with the latest version of ghc-mod from hackage.
To use stable *stable* MELPA add this to your `.emacs`: To use stable *stable* MELPA add this to your `.emacs`:
@ -14,7 +14,7 @@ To use stable *stable* MELPA add this to your `.emacs`:
```elisp ```elisp
(require 'package) (require 'package)
(add-to-list 'package-archives (add-to-list 'package-archives
'("melpa" . "http://melpa-stable.milkbox.net/packages/")) '("melpa" . "https://stable.melpa.org/packages/"))
(package-initialize) (package-initialize)
``` ```
@ -33,7 +33,7 @@ package database such as the `nixos-15.09` or `nixos-unstable` channel. Just
include the package `ghc-mod` into your `ghcWithPackages` environment like any include the package `ghc-mod` into your `ghcWithPackages` environment like any
other library. The [Nixpkgs Haskell User's other library. The [Nixpkgs Haskell User's
Guide](http://hydra.nixos.org/job/nixpkgs/trunk/manual/latest/download-by-type/doc/manual#users-guide-to-the-haskell-infrastructure) Guide](http://hydra.nixos.org/job/nixpkgs/trunk/manual/latest/download-by-type/doc/manual#users-guide-to-the-haskell-infrastructure)
covers this subject in gret detail. covers this subject in great detail.
## Using the development version ## Using the development version

View File

@ -0,0 +1,58 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Daniel Gröber <dxld ÄT darkboxed DOT org>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE CPP #-}
module System.Directory.ModTime where
import Control.Applicative
import Data.Binary
#if MIN_VERSION_directory(1,2,0)
import Data.Time (UTCTime(..), Day(..), getCurrentTime)
#else
import System.Time (ClockTime(..), getClockTime)
#endif
import System.Directory
import Prelude
#if MIN_VERSION_directory(1,2,0)
newtype ModTime = ModTime UTCTime
deriving (Eq, Ord)
getCurrentModTime = ModTime <$> getCurrentTime
instance Binary ModTime where
put (ModTime (UTCTime (ModifiedJulianDay day) difftime)) =
put day >> put (toRational difftime)
get =
ModTime <$> (UTCTime <$> (ModifiedJulianDay <$> get) <*> (fromRational <$> get))
#else
newtype ModTime = ModTime ClockTime
deriving (Eq, Ord, Show)
getCurrentModTime = ModTime <$> getClockTime
instance Binary ModTime where
put (ModTime (TOD s ps)) =
put s >> put ps
get =
ModTime <$> (TOD <$> get <*> get)
#endif
getCurrentModTime :: IO ModTime
getModTime :: FilePath -> IO ModTime
getModTime f = ModTime <$> getModificationTime f

View File

@ -4,29 +4,18 @@ module Utils where
import Control.Applicative import Control.Applicative
import Data.Traversable import Data.Traversable
import System.Directory import System.Directory
import System.Directory.ModTime
#if MIN_VERSION_directory(1,2,0)
import Data.Time (UTCTime)
#else
import System.Time (ClockTime)
#endif
import Prelude import Prelude
#if MIN_VERSION_directory(1,2,0)
type ModTime = UTCTime
#else
type ModTime = ClockTime
#endif
data TimedFile = TimedFile { tfPath :: FilePath, tfTime :: ModTime } data TimedFile = TimedFile { tfPath :: FilePath, tfTime :: ModTime }
deriving (Eq, Show) deriving (Eq)
instance Ord TimedFile where instance Ord TimedFile where
compare (TimedFile _ a) (TimedFile _ b) = compare a b compare (TimedFile _ a) (TimedFile _ b) = compare a b
timeFile :: FilePath -> IO TimedFile timeFile :: FilePath -> IO TimedFile
timeFile f = TimedFile <$> pure f <*> getModificationTime f timeFile f = TimedFile <$> pure f <*> getModTime f
mightExist :: FilePath -> IO (Maybe FilePath) mightExist :: FilePath -> IO (Maybe FilePath)
mightExist f = do mightExist f = do

View File

@ -1,7 +1,7 @@
*Happy Haskell Programming *Happy Haskell Programming
The ["ghc-mod command" ghc-mod.html] and ["ghc-modi command" ghc-modi.html] are backend commands to enrich Haskell programming on editors The ["ghc-mod command" ghc-mod.html] and ["ghc-modi command" ghc-modi.html] are backend commands to enrich Haskell programming on editors
including Emacs, Vim, and Sublime. including Emacs, Vim, Atom, and Sublime.
ghc-mod and ghc-modi are based on the ["ghc-mod library" http://hackage.haskell.org/packages/archive/ghc-mod/latest/doc/html/Language-Haskell-GhcMod.html] ghc-mod and ghc-modi are based on the ["ghc-mod library" http://hackage.haskell.org/packages/archive/ghc-mod/latest/doc/html/Language-Haskell-GhcMod.html]
which is a wrapper of ["GHC API" http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/] and [Cabal http://hackage.haskell.org/package/Cabal]. which is a wrapper of ["GHC API" http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/] and [Cabal http://hackage.haskell.org/package/Cabal].
@ -20,6 +20,10 @@ The ["source repository of ghc-mod" https://github.com/kazu-yamamoto/ghc-mod] is
-[ghcmod-vim https://github.com/eagletmt/ghcmod-vim] -[ghcmod-vim https://github.com/eagletmt/ghcmod-vim]
-[syntastic https://github.com/scrooloose/syntastic] -[syntastic https://github.com/scrooloose/syntastic]
**Atom
-[ide-haskell https://atom.io/packages/ide-haskell]
**Sublime **Sublime
-[SublimeHaskell https://github.com/SublimeHaskell/SublimeHaskell] -[SublimeHaskell https://github.com/SublimeHaskell/SublimeHaskell]

View File

@ -2,12 +2,12 @@
**Downloading **Downloading
Please use *stable* [MELPA http://melpa-stable.milkbox.net/] to download Emacs front-end. So, your "~/.emacs" should be: Please use *stable* [MELPA https://stable.melpa.org/] to download Emacs front-end. So, your "~/.emacs" should be:
>| >|
(require 'package) (require 'package)
(add-to-list 'package-archives (add-to-list 'package-archives
'("melpa" . "http://melpa-stable.milkbox.net/packages/")) '("melpa" . "https://stable.melpa.org/packages/"))
(package-initialize) (package-initialize)
|< |<

View File

@ -101,7 +101,7 @@ unloaded modules are loaded")
(defun ghc-boot (n) (defun ghc-boot (n)
(prog2 (prog2
(message "Initializing...") (message "Initializing...")
(ghc-sync-process "boot\n" n nil 'skip-map-file) (ghc-sync-process "boot\n" n)
(message "Initializing...done"))) (message "Initializing...done")))
(defun ghc-load-modules (mods) (defun ghc-load-modules (mods)

View File

@ -111,13 +111,7 @@
(cn (int-to-string (1+ (current-column)))) (cn (int-to-string (1+ (current-column))))
(file (buffer-file-name)) (file (buffer-file-name))
(cmd (format "type %s %s %s\n" file ln cn))) (cmd (format "type %s %s %s\n" file ln cn)))
(ghc-sync-process cmd nil 'ghc-type-fix-string))) (ghc-sync-process cmd nil)))
(defun ghc-type-fix-string ()
(save-excursion
(goto-char (point-min))
(while (search-forward "[Char]" nil t)
(replace-match "String"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;

View File

@ -1,3 +1,4 @@
;;; -*- lexical-binding: t -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ;;;
;;; ghc-process.el ;;; ghc-process.el
@ -21,12 +22,11 @@
(defvar-local ghc-process-process-name nil) (defvar-local ghc-process-process-name nil)
(defvar-local ghc-process-original-buffer nil) (defvar-local ghc-process-original-buffer nil)
(defvar-local ghc-process-original-file nil) (defvar-local ghc-process-original-file nil)
(defvar-local ghc-process-callback nil)
(defvar-local ghc-process-hook nil)
(defvar-local ghc-process-root nil) (defvar-local ghc-process-root nil)
(defvar ghc-command "ghc-mod") (defvar ghc-command "ghc-mod")
(defvar ghc-report-errors t "Report GHC errors to *GHC Error* buffer")
(defvar ghc-error-buffer "*GHC Error*") (defvar ghc-error-buffer "*GHC Error*")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -34,12 +34,12 @@
(defun ghc-get-project-root () (defun ghc-get-project-root ()
(ghc-run-ghc-mod '("root"))) (ghc-run-ghc-mod '("root")))
(defun ghc-with-process (cmd callback &optional hook1 hook2 skip-map-file) (defun ghc-with-process (cmd async-after-callback &optional sync-before-hook)
(unless ghc-process-process-name (unless ghc-process-process-name
(setq ghc-process-process-name (ghc-get-project-root))) (setq ghc-process-process-name (ghc-get-project-root)))
(when (and ghc-process-process-name (not ghc-process-running)) (when (and ghc-process-process-name (not ghc-process-running))
(setq ghc-process-running t) (setq ghc-process-running t)
(if hook1 (funcall hook1)) (if sync-before-hook (funcall sync-before-hook))
(let* ((cbuf (current-buffer)) (let* ((cbuf (current-buffer))
(name ghc-process-process-name) (name ghc-process-process-name)
(root (file-name-as-directory ghc-process-process-name)) (root (file-name-as-directory ghc-process-process-name))
@ -51,14 +51,13 @@
(ghc-with-current-buffer buf (ghc-with-current-buffer buf
(setq ghc-process-original-buffer cbuf) (setq ghc-process-original-buffer cbuf)
(setq ghc-process-original-file file) (setq ghc-process-original-file file)
(setq ghc-process-hook hook2)
(setq ghc-process-root root) (setq ghc-process-root root)
(let ((pro (ghc-get-process cpro name buf root)) (let ((pro (ghc-get-process cpro name buf root))
(map-cmd (format "map-file %s\n" file))) (map-cmd (format "map-file %s\n" file)))
;; map-file ; (unmap-cmd (format "unmap-file %s\n" file)))
(unless skip-map-file (when (buffer-modified-p (current-buffer))
(setq ghc-process-file-mapping t) (setq ghc-process-file-mapping t)
(setq ghc-process-callback nil) (setq ghc-process-async-after-callback nil)
(erase-buffer) (erase-buffer)
(when ghc-debug (when ghc-debug
(ghc-with-debug-buffer (ghc-with-debug-buffer
@ -69,7 +68,7 @@
(save-restriction (save-restriction
(widen) (widen)
(process-send-region pro (point-min) (point-max)))) (process-send-region pro (point-min) (point-max))))
(process-send-string pro "\004\n") (process-send-string pro "\n\004\n")
(condition-case nil (condition-case nil
(let ((inhibit-quit nil)) (let ((inhibit-quit nil))
(while ghc-process-file-mapping (while ghc-process-file-mapping
@ -78,12 +77,21 @@
(setq ghc-process-running nil) (setq ghc-process-running nil)
(setq ghc-process-file-mapping nil)))) (setq ghc-process-file-mapping nil))))
;; command ;; command
(setq ghc-process-callback callback) (setq ghc-process-async-after-callback async-after-callback)
(erase-buffer) (erase-buffer)
(when ghc-debug (when ghc-debug
(ghc-with-debug-buffer (ghc-with-debug-buffer
(insert (format "%% %s" cmd)))) (insert (format "%% %s" cmd))))
(process-send-string pro cmd) (process-send-string pro cmd)
;;; this needs to be done asyncrounously after the command actually
;;; finished, gah
;; (when do-map-file
;; (when ghc-debug
;; (ghc-with-debug-buffer
;; (insert (format "%% %s" unmap-cmd))))
;; (process-send-string pro unmap-cmd))
pro))))) pro)))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -144,6 +152,7 @@
(with-current-buffer pbuf (with-current-buffer pbuf
(goto-char (point-max)) (goto-char (point-max))
(insert-buffer-substring tbuf 1 end)) (insert-buffer-substring tbuf 1 end))
(when ghc-report-errors
(with-current-buffer (get-buffer-create ghc-error-buffer) (with-current-buffer (get-buffer-create ghc-error-buffer)
(setq buffer-read-only t) (setq buffer-read-only t)
(let* ((buffer-read-only nil) (let* ((buffer-read-only nil)
@ -156,7 +165,7 @@
(goto-char (point-max)) (goto-char (point-max))
(insert-buffer-substring tbuf 1 end) (insert-buffer-substring tbuf 1 end)
(set-buffer-modified-p nil)) (set-buffer-modified-p nil))
(redisplay)))) (redisplay)))))
(delete-region 1 end))))) (delete-region 1 end)))))
(goto-char (point-max)) (goto-char (point-max))
(forward-line -1) (forward-line -1)
@ -164,13 +173,12 @@
((looking-at "^OK$") ((looking-at "^OK$")
(delete-region (point) (point-max)) (delete-region (point) (point-max))
(setq ghc-process-file-mapping nil) (setq ghc-process-file-mapping nil)
(when ghc-process-callback (when ghc-process-async-after-callback
(if ghc-process-hook (funcall ghc-process-hook))
(goto-char (point-min)) (goto-char (point-min))
(funcall ghc-process-callback 'ok) (funcall ghc-process-async-after-callback 'ok)
(setq ghc-process-running nil))) (setq ghc-process-running nil)))
((looking-at "^NG ") ((looking-at "^NG ")
(funcall ghc-process-callback 'ng) (funcall ghc-process-async-after-callback 'ng)
(setq ghc-process-running nil))))))) (setq ghc-process-running nil)))))))
(defun ghc-process-sentinel (_process _event) (defun ghc-process-sentinel (_process _event)
@ -183,12 +191,12 @@
(defvar ghc-process-num-of-results nil) (defvar ghc-process-num-of-results nil)
(defvar ghc-process-results nil) (defvar ghc-process-results nil)
(defun ghc-sync-process (cmd &optional n hook skip-map-file) (defun ghc-sync-process (cmd &optional n)
(unless ghc-process-running (unless ghc-process-running
(setq ghc-process-rendezvous nil) (setq ghc-process-rendezvous nil)
(setq ghc-process-results nil) (setq ghc-process-results nil)
(setq ghc-process-num-of-results (or n 1)) (setq ghc-process-num-of-results (or n 1))
(let ((pro (ghc-with-process cmd 'ghc-process-callback nil hook skip-map-file))) (let ((pro (ghc-with-process cmd 'ghc-sync-process-callback nil)))
;; ghc-process-running is now t. ;; ghc-process-running is now t.
;; But if the process exits abnormally, it is set to nil. ;; But if the process exits abnormally, it is set to nil.
(condition-case nil (condition-case nil
@ -199,7 +207,7 @@
(setq ghc-process-running nil)))) (setq ghc-process-running nil))))
ghc-process-results)) ghc-process-results))
(defun ghc-process-callback (status) (defun ghc-sync-process-callback (status)
(cond (cond
((eq status 'ok) ((eq status 'ok)
(let* ((n ghc-process-num-of-results) (let* ((n ghc-process-num-of-results)

View File

@ -28,7 +28,7 @@
(< emacs-minor-version minor))) (< emacs-minor-version minor)))
(error "ghc-mod requires at least Emacs %d.%d" major minor))) (error "ghc-mod requires at least Emacs %d.%d" major minor)))
(defconst ghc-version "5.4.0.0") (defconst ghc-version "5.5.0.0")
(defgroup ghc-mod '() "ghc-mod customization") (defgroup ghc-mod '() "ghc-mod customization")

View File

@ -1,5 +1,5 @@
Name: ghc-mod Name: ghc-mod
Version: 5.4.0.0 Version: 5.5.0.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>, Author: Kazu Yamamoto <kazu@iij.ad.jp>,
Daniel Gröber <dxld@darkboxed.org>, Daniel Gröber <dxld@darkboxed.org>,
Alejandro Serrano <trupill@gmail.com> Alejandro Serrano <trupill@gmail.com>
@ -33,6 +33,7 @@ Extra-Source-Files: ChangeLog
SetupCompat.hs SetupCompat.hs
NotCPP/*.hs NotCPP/*.hs
NotCPP/COPYING NotCPP/COPYING
Language/Haskell/GhcMod/Monad/Compat.hs_h
test/data/annotations/*.hs test/data/annotations/*.hs
test/data/broken-cabal/*.cabal test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in test/data/broken-cabal/cabal.sandbox.config.in
@ -131,6 +132,12 @@ Library
Language.Haskell.GhcMod.Logging Language.Haskell.GhcMod.Logging
Language.Haskell.GhcMod.Modules Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.Monad.Env
Language.Haskell.GhcMod.Monad.Log
Language.Haskell.GhcMod.Monad.Newtypes
Language.Haskell.GhcMod.Monad.Orphans
Language.Haskell.GhcMod.Monad.Out
Language.Haskell.GhcMod.Monad.State
Language.Haskell.GhcMod.Monad.Types Language.Haskell.GhcMod.Monad.Types
Language.Haskell.GhcMod.Output Language.Haskell.GhcMod.Output
Language.Haskell.GhcMod.PathsAndFiles Language.Haskell.GhcMod.PathsAndFiles
@ -140,38 +147,41 @@ Library
Language.Haskell.GhcMod.SrcUtils Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Stack Language.Haskell.GhcMod.Stack
Language.Haskell.GhcMod.Target Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Test
Language.Haskell.GhcMod.Types Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils Language.Haskell.GhcMod.Utils
Language.Haskell.GhcMod.World Language.Haskell.GhcMod.World
Other-Modules: Paths_ghc_mod Other-Modules: Paths_ghc_mod
Utils Utils
Build-Depends: base >= 4.0 && < 5 Data.Binary.Generic
, bytestring System.Directory.ModTime
, cereal >= 0.4 Build-Depends: base < 5 && >= 4.0
, containers , bytestring < 0.11
, cabal-helper == 0.6.* && >= 0.6.0.0 , binary < 0.8 && >= 0.5.1.0
, deepseq , containers < 0.6
, directory , cabal-helper < 0.7 && >= 0.6.1.0
, filepath , deepseq < 1.5
, ghc , directory < 1.3
, ghc-paths , filepath < 1.5
, ghc-syb-utils , ghc < 7.11
, hlint >= 1.8.61 , ghc-paths < 0.2
, monad-journal >= 0.4 , ghc-syb-utils < 0.3
, old-time , hlint < 1.10 && >= 1.8.61
, pretty , monad-journal < 0.8 && >= 0.4
, process , old-time < 1.2
, syb , pretty < 1.2
, temporary , process < 1.3
, time , syb < 0.7
, transformers , temporary < 1.3
, transformers-base , time < 1.6
, mtl >= 2.0 , transformers < 0.5
, monad-control >= 1 , transformers-base < 0.5
, split , mtl < 2.3 && >= 2.0
, haskell-src-exts , monad-control < 1.1 && >= 1
, text , split < 0.3
, djinn-ghc >= 0.0.2.2 , haskell-src-exts < 1.18
, text < 1.3
, djinn-ghc < 0.1 && >= 0.0.2.2
, fclabels == 2.0.* , fclabels == 2.0.*
, extra == 1.4.* , extra == 1.4.*
, pipes == 4.1.* , pipes == 4.1.*
@ -186,38 +196,46 @@ Executable ghc-mod
Default-Language: Haskell2010 Default-Language: Haskell2010
Main-Is: GHCMod.hs Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod Other-Modules: Paths_ghc_mod
, GHCMod.Options
, GHCMod.Options.Commands
, GHCMod.Version
, GHCMod.Options.DocUtils
, GHCMod.Options.ShellParse
, GHCMod.Options.Help
GHC-Options: -Wall -fno-warn-deprecations -threaded GHC-Options: -Wall -fno-warn-deprecations -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5 Build-Depends: base < 5 && >= 4.0
, async , directory < 1.3
, directory , filepath < 1.5
, filepath , pretty < 1.2
, pretty , process < 1.3
, process , split < 0.3
, split , mtl < 2.3 && >= 2.0
, mtl >= 2.0 , ghc < 7.11
, ghc , monad-control ==1.0.*
, fclabels ==2.0.*
, optparse-applicative >=0.11.0 && <0.13.0
, ghc-mod , ghc-mod
, fclabels == 2.0.*
Executable ghc-modi Executable ghc-modi
Default-Language: Haskell2010 Default-Language: Haskell2010
Main-Is: GHCModi.hs Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod Other-Modules: Paths_ghc_mod
Misc
Utils Utils
GHC-Options: -Wall -threaded -fno-warn-deprecations GHC-Options: -Wall -threaded -fno-warn-deprecations
if os(windows) if os(windows)
Cpp-Options: -DWINDOWS Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src, . HS-Source-Dirs: src, .
Build-Depends: base >= 4.0 && < 5 Build-Depends: base < 5 && >= 4.0
, directory , binary < 0.8 && >= 0.5.1.0
, filepath , directory < 1.3
, process , filepath < 1.5
, time , process < 1.3
, old-time , old-time < 1.2
, time < 1.6
, ghc-mod
Test-Suite doctest Test-Suite doctest
Type: exitcode-stdio-1.0 Type: exitcode-stdio-1.0
@ -237,8 +255,8 @@ Test-Suite spec
ConstraintKinds, FlexibleContexts, ConstraintKinds, FlexibleContexts,
DataKinds, KindSignatures, TypeOperators, ViewPatterns DataKinds, KindSignatures, TypeOperators, ViewPatterns
Main-Is: Main.hs Main-Is: Main.hs
Hs-Source-Dirs: test, . Hs-Source-Dirs: test, ., src
Ghc-Options: -Wall -fno-warn-deprecations Ghc-Options: -Wall -fno-warn-deprecations -threaded
CPP-Options: -DSPEC=1 CPP-Options: -DSPEC=1
Type: exitcode-stdio-1.0 Type: exitcode-stdio-1.0
Other-Modules: Paths_ghc_mod Other-Modules: Paths_ghc_mod
@ -257,6 +275,7 @@ Test-Suite spec
PathsAndFilesSpec PathsAndFilesSpec
HomeModuleGraphSpec HomeModuleGraphSpec
FileMappingSpec FileMappingSpec
ShellParseSpec
Build-Depends: hspec >= 2.0.0 Build-Depends: hspec >= 2.0.0
if impl(ghc == 7.4.*) if impl(ghc == 7.4.*)

View File

@ -7,44 +7,31 @@
\texttt{ghc-mod} is both a backend program for enhancing editors and other kinds \texttt{ghc-mod} is both a backend program for enhancing editors and other kinds
of development environments with support for Haskell, and an Emacs package of development environments with support for Haskell, and an Emacs package
providing the user facing functionality, internally called \texttt{ghc} for providing the user facing functionality, internally called \texttt{ghc} for
historical reasons. Other people have also developed numerous front ends for Vim historical reasons. Others have developed front ends for Vim, Atom and a few
and there also exist some for Atom and a few other proprietary editors. other proprietary editors.
After a period of declining activity, development has been picking up pace again This summer's two month \texttt{ghc-mod} hacking session was mostly spent
since Daniel Gr\"ober took over as maintainer. Most changes during versions (finally) getting a release supporting GHC 7.10 out the door as well as fixing
5.0.0--5.2.1.2 consisted only of fixes and internal cleanup work, but for the bugs and adding full support for the \textit{Stack} build tool.
past four months, vastly improved Cabal support has been in the works and is now
starting to stabilize.
This work is a major step forward in terms of how well ghc-mod's suggestions Since the last report the \textit{haskell-ide} project has seen the light of day
reflect what \texttt{cabal build} would report, and should also allow ghc-mod's (or rather been revived). There we are planning to adopt \texttt{ghc-mod} as a
other features to work even in more complicated Cabal setups. core component to use its environment abstraction.
Daniel Gr\"ober has been accepted for a summer internship at IIJ Innovation The \textit{haskell-ide} project itself (maybe soon to be called
Institute's Research Laboratory working on \texttt{ghc-mod} for two months \textit{ghc-ide-engine}) is aiming to be the central component of a unified
(August--September). He will be working on: Haskell Tooling landscape.
\begin{compactitem}
\item adding GHCi-like interactive code execution, to bring \texttt{ghc-mod} up \texttt{ghc-mod}'s mission statement remains the same but in the future it will
to feature parity with GHCi and beyond, be but one, important, component in a larger ecosystem of Haskell Tools.
\item investigating how to best cooperate with \texttt{ide-backend}, We are looking forward to \textit{haskell-ide} making the Haskell Tooling
landscape a lot less fragmented. However until this project produces meaningful
\item adding a network interface to make using ghc-mod in other projects results life goes on and \texttt{ghc-mod} needs to be maintained.
easier, and
\item if time allows, cleaning up the Emacs frontend to be more user-friendly
and in line with Emacs' conventions.
\end{compactitem}
The goal of this work is to make \texttt{ghc-mod} the obvious choice for anyone
implementing Haskell support for a development environment and improving
\texttt{ghc-mod}'s overall feature set and reliability in order to give new as
well as experienced Haskell developers the best possible experience.
Right now \texttt{ghc-mod} has only one core developer and only a handful of Right now \texttt{ghc-mod} has only one core developer and only a handful of
occasional drive-by contributors. If \textit{you} want to help make Haskell occasional contributors. If \textit{you} want to help make Haskell development
development even more fun come and join us! even more fun come and join us!
\FurtherReading \FurtherReading
\url{https://github.com/kazu-yamamoto/ghc-mod} \url{https://github.com/kazu-yamamoto/ghc-mod}

View File

@ -0,0 +1,215 @@
Name: ghc-mod
Version: 5.0.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.List
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, directory
, filepath
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Utils
GHC-Options: -Wall -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, containers
, directory
, filepath
, split
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,219 @@
Name: ghc-mod
Version: 5.0.1.1
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.List
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, directory
, filepath
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Utils
GHC-Options: -Wall -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, containers
, directory
, filepath
, split
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,219 @@
Name: ghc-mod
Version: 5.0.1.2
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.List
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, directory
, filepath
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Utils
GHC-Options: -Wall -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, containers
, directory
, filepath
, split
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,215 @@
Name: ghc-mod
Version: 5.0.1
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.List
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, directory
, filepath
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Utils
GHC-Options: -Wall -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, containers
, directory
, filepath
, split
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.2.2.0
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,225 @@
Name: ghc-mod
Version: 5.1.0.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.2.2.0 && < 0.2.3.2
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, directory
, filepath
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Utils
GHC-Options: -Wall -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, split
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.2.2.0 && < 0.2.3.2
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,225 @@
Name: ghc-mod
Version: 5.1.0.1
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.4
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, directory
, filepath
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Utils
GHC-Options: -Wall -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, split
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.4
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,225 @@
Name: ghc-mod
Version: 5.1.0.2
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.4
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, directory
, filepath
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Utils
GHC-Options: -Wall -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, split
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.4
, old-time
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,236 @@
Name: ghc-mod
Version: 5.1.1.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, data-default
, directory
, filepath
, pretty
, process
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Misc
Utils
GHC-Options: -Wall -threaded
if os(windows)
Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, old-time
, process
, split
, time
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,238 @@
Name: ghc-mod
Version: 5.2.0.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, data-default
, directory
, filepath
, pretty
, process
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Misc
Utils
GHC-Options: -Wall -threaded
if os(windows)
Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, old-time
, process
, split
, time
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: Dir
Spec
BrowseSpec
CabalApiSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
GhcPkgSpec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,242 @@
Name: ghc-mod
Version: 5.2.1.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PathsAndFiles
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Language.Haskell.GhcMod.World
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, data-default
, directory
, filepath
, pretty
, process
, split
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Misc
Utils
GHC-Options: -Wall -threaded
if os(windows)
Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, old-time
, process
, split
, time
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: BrowseSpec
CabalApiSpec
CheckSpec
Dir
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
PathsAndFilesSpec
Spec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,243 @@
Name: ghc-mod
Version: 5.2.1.1
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/case-split/*.hs
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PathsAndFiles
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Language.Haskell.GhcMod.World
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, data-default
, directory
, filepath
, pretty
, process
, split
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Misc
Utils
GHC-Options: -Wall -threaded
if os(windows)
Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, old-time
, process
, split
, time
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: BrowseSpec
CabalApiSpec
CheckSpec
Dir
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
PathsAndFilesSpec
Spec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,243 @@
Name: ghc-mod
Version: 5.2.1.2
Author: Kazu Yamamoto <kazu@iij.ad.jp>
Daniel Gröber <dxld@darkboxed.org>
Alejandro Serrano <trupill@gmail.com>
Maintainer: Kazu Yamamoto <kazu@iij.ad.jp>
License: BSD3
License-File: LICENSE
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description: The ghc-mod command is a backend command to enrich
Haskell programming on editors including
Emacs, Vim, and Sublime.
The ghc-mod command is based on ghc-mod library
which is a wrapper of GHC API.
This package includes the ghc-mod command,
the ghc-mod library, and Emacs front-end
(for historical reasons).
For more information, please see its home page.
Category: Development
Cabal-Version: >= 1.10
Build-Type: Simple
Data-Dir: elisp
Data-Files: Makefile ghc.el ghc-func.el ghc-doc.el ghc-comp.el
ghc-check.el ghc-process.el ghc-command.el ghc-info.el
ghc-ins-mod.el ghc-indent.el ghc-pkg.el ghc-rewrite.el
Extra-Source-Files: ChangeLog
test/data/*.cabal
test/data/*.hs
test/data/cabal.sandbox.config.in
test/data/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/*.cabal
test/data/broken-sandbox/cabal.sandbox.config
test/data/case-split/*.hs
test/data/cabal-flags/*.cabal
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/Data/*.hs
test/data/subdir1/subdir2/dummy
test/data/.cabal-sandbox/packages/00-index.tar
Library
Default-Language: Haskell2010
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.Cabal16
Language.Haskell.GhcMod.Cabal18
Language.Haskell.GhcMod.Cabal21
Language.Haskell.GhcMod.CabalApi
Language.Haskell.GhcMod.CabalConfig
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.GHCApi
Language.Haskell.GhcMod.GHCChoice
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.PathsAndFiles
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Language.Haskell.GhcMod.World
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.8.61
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc <= 7.4.2)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, data-default
, directory
, filepath
, pretty
, process
, split
, mtl >= 2.0
, ghc
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Misc
Utils
GHC-Options: -Wall -threaded
if os(windows)
Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base >= 4.0 && < 5
, async
, containers
, directory
, filepath
, old-time
, process
, split
, time
, ghc
, ghc-mod
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall
Type: exitcode-stdio-1.0
Other-Modules: BrowseSpec
CabalApiSpec
CheckSpec
Dir
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
PathsAndFilesSpec
Spec
TestUtils
Build-Depends: base >= 4.0 && < 5
, containers
, deepseq
, directory
, filepath
, ghc
, ghc-paths
, ghc-syb-utils
, hlint >= 1.7.1
, io-choice
, monad-journal >= 0.4
, old-time
, pretty
, process
, syb
, temporary
, time
, transformers
, transformers-base
, mtl >= 2.0
, monad-control
, hspec >= 1.8.2
, split
, haskell-src-exts
, text
, djinn-ghc >= 0.0.2.2
if impl(ghc >= 7.8)
Build-Depends: Cabal >= 1.18
else
Build-Depends: convertible
, Cabal >= 1.10 && < 1.17
if impl(ghc < 7.6)
Build-Depends: executable-path
CPP-Options: -DSPEC=1
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,250 @@
X-Revision: 3
Name: ghc-mod
Version: 5.3.0.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>,
Daniel Gröber <dxld@darkboxed.org>,
Alejandro Serrano <trupill@gmail.com>
Maintainer: Daniel Gröber <dxld@darkboxed.org>
License: AGPL-3
License-File: LICENSE
License-Files: COPYING.BSD3 COPYING.AGPL3
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description:
ghc-mod is a backend program to enrich Haskell programming in editors. It
strives to offer most of the features one has come to expect from modern IDEs
in any editor.
ghc-mod provides a library for other haskell programs to use as well as a
standalone program for easy editor integration. All of the fundamental
functionality of the frontend program can be accessed through the library
however many implementation details are hidden and if you want to
significantly extend ghc-mod you should submit these changes upstream instead
of implementing them on top of the library.
For more information, please see its home page.
Category: GHC, Development
Cabal-Version: >= 1.14
Build-Type: Custom
Data-Files: elisp/Makefile
elisp/*.el
Data-Files: LICENSE COPYING.BSD3 COPYING.AGPL3
Extra-Source-Files: ChangeLog
SetupCompat.hs
NotCPP/*.hs
test/data/annotations/*.hs
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/cabal.sandbox.config
test/data/broken-sandbox/dummy.cabal
test/data/cabal-flags/cabal-flags.cabal
test/data/cabal-project/*.cabal
test/data/cabal-project/*.hs
test/data/cabal-project/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/cabal-project/cabal.sandbox.config.in
test/data/cabal-project/subdir1/subdir2/dummy
test/data/case-split/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/foreign-export/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/lib/Data/*.hs
test/data/hlint/*.hs
test/data/home-module-graph/cpp/*.hs
test/data/home-module-graph/cycle/*.hs
test/data/home-module-graph/errors/*.hs
test/data/home-module-graph/indirect/*.hs
test/data/home-module-graph/indirect-update/*.hs
test/data/import-cycle/*.hs
test/data/non-exported/*.hs
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/quasi-quotes/*.hs
test/data/template-haskell/*.hs
test/data/target/*.hs
test/data/check-missing-warnings/*.hs
test/data/custom-cradle/custom-cradle.cabal
test/data/custom-cradle/ghc-mod.package-db-stack
test/data/custom-cradle/package-db-a/.gitkeep
test/data/custom-cradle/package-db-b/.gitkeep
test/data/custom-cradle/package-db-c/.gitkeep
test/data/cabal-preprocessors/*.cabal
test/data/cabal-preprocessors/*.hs
test/data/cabal-preprocessors/*.hsc
Library
Default-Language: Haskell2010
GHC-Options: -Wall -fno-warn-deprecations
Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns,
ConstraintKinds, FlexibleContexts,
DataKinds, KindSignatures, TypeOperators
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Other-Modules: Paths_ghc_mod
Utils
Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.CabalHelper
Language.Haskell.GhcMod.Caching
Language.Haskell.GhcMod.Caching.Types
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.HomeModuleGraph
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Logging
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.Monad.Types
Language.Haskell.GhcMod.Output
Language.Haskell.GhcMod.PathsAndFiles
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Pretty
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Language.Haskell.GhcMod.World
Build-Depends: base < 5 && >= 4.0
, bytestring < 0.11
, cereal < 0.5 && >= 0.4
, containers < 0.6
, cabal-helper < 0.6 && >= 0.5.1.0
, deepseq < 1.5
, directory < 1.3
, filepath < 1.5
, ghc < 7.11
, ghc-paths < 0.2
, ghc-syb-utils < 0.3
, hlint < 1.10 && >= 1.8.61
, monad-journal < 0.8 && >= 0.4
, old-time < 1.2
, pretty < 1.2
, process < 1.3
, syb < 0.7
, temporary < 1.3
, time < 1.6
, transformers < 0.5
, transformers-base < 0.5
, mtl < 2.3 && >= 2.0
, monad-control < 1.1 && >= 1
, split < 0.3
, haskell-src-exts < 1.17
, text < 1.3
, djinn-ghc < 0.1 && >= 0.0.2.2
, fclabels == 2.0.*
if impl(ghc < 7.8)
Build-Depends: convertible
if impl(ghc < 7.5)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1,
ghc-prim
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall -fno-warn-deprecations
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base < 5 && >= 4.0
, async < 2.1
, directory < 1.3
, filepath < 1.5
, pretty < 1.2
, process < 1.3
, split < 0.3
, mtl < 2.3 && >= 2.0
, ghc < 7.11
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Misc
Utils
GHC-Options: -Wall -threaded -fno-warn-deprecations
if os(windows)
Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src, .
Build-Depends: base < 5 && >= 4.0
, directory < 1.3
, filepath < 1.5
, process < 1.3
, old-time < 1.2
, time < 1.6
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
if impl(ghc == 7.4.*)
Buildable: False
Build-Depends: base
, doctest >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns,
ConstraintKinds, FlexibleContexts,
DataKinds, KindSignatures, TypeOperators
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall -fno-warn-deprecations
CPP-Options: -DSPEC=1
Type: exitcode-stdio-1.0
Other-Modules: Paths_ghc_mod
Dir
Spec
TestUtils
BrowseSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
PathsAndFilesSpec
HomeModuleGraphSpec
Build-Depends: hspec >= 2.0.0
if impl(ghc == 7.4.*)
Build-Depends: executable-path
X-Build-Depends-Like: CLibName
Source-Repository head
Type: git
Location: git://github.com/kazu-yamamoto/ghc-mod.git

View File

@ -0,0 +1,271 @@
X-Revision: 4
Name: ghc-mod
Version: 5.4.0.0
Author: Kazu Yamamoto <kazu@iij.ad.jp>,
Daniel Gröber <dxld@darkboxed.org>,
Alejandro Serrano <trupill@gmail.com>
Maintainer: Daniel Gröber <dxld@darkboxed.org>
License: AGPL-3
License-File: LICENSE
License-Files: COPYING.BSD3 COPYING.AGPL3
Homepage: http://www.mew.org/~kazu/proj/ghc-mod/
Synopsis: Happy Haskell Programming
Description:
ghc-mod is a backend program to enrich Haskell programming in editors. It
strives to offer most of the features one has come to expect from modern IDEs
in any editor.
ghc-mod provides a library for other haskell programs to use as well as a
standalone program for easy editor integration. All of the fundamental
functionality of the frontend program can be accessed through the library
however many implementation details are hidden and if you want to
significantly extend ghc-mod you should submit these changes upstream instead
of implementing them on top of the library.
For more information, please see its home page.
Category: GHC, Development
Cabal-Version: >= 1.14
Build-Type: Custom
Data-Files: elisp/Makefile
elisp/*.el
Data-Files: LICENSE COPYING.BSD3 COPYING.AGPL3
Extra-Source-Files: ChangeLog
SetupCompat.hs
NotCPP/*.hs
NotCPP/COPYING
test/data/annotations/*.hs
test/data/broken-cabal/*.cabal
test/data/broken-cabal/cabal.sandbox.config.in
test/data/broken-sandbox/cabal.sandbox.config
test/data/broken-sandbox/dummy.cabal
test/data/cabal-flags/cabal-flags.cabal
test/data/cabal-project/*.cabal
test/data/cabal-project/*.hs
test/data/cabal-project/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/Cabal-1.18.1.3-2b161c6bf77657aa17e1681d83cb051b.conf
test/data/cabal-project/cabal.sandbox.config.in
test/data/cabal-project/subdir1/subdir2/dummy
test/data/case-split/*.hs
test/data/check-packageid/cabal.sandbox.config.in
test/data/check-packageid/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/check-test-subdir/*.cabal
test/data/check-test-subdir/src/Check/Test/*.hs
test/data/check-test-subdir/test/*.hs
test/data/check-test-subdir/test/Bar/*.hs
test/data/duplicate-pkgver/cabal.sandbox.config.in
test/data/duplicate-pkgver/duplicate-pkgver.cabal
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-1.0-7c59d13f32294d1ef6dc6233c24df961.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-14e543bdae2da4d2aeff5386892c9112.conf
test/data/duplicate-pkgver/.cabal-sandbox/i386-osx-ghc-7.6.3-packages.conf.d/template-haskell-2.8.0.0-32d4f24abdbb6bf41272b183b2e23e9c.conf
test/data/foreign-export/*.hs
test/data/ghc-mod-check/*.cabal
test/data/ghc-mod-check/*.hs
test/data/ghc-mod-check/lib/Data/*.hs
test/data/hlint/*.hs
test/data/home-module-graph/cpp/*.hs
test/data/home-module-graph/cycle/*.hs
test/data/home-module-graph/errors/*.hs
test/data/home-module-graph/indirect/*.hs
test/data/home-module-graph/indirect-update/*.hs
test/data/import-cycle/*.hs
test/data/non-exported/*.hs
test/data/pattern-synonyms/*.cabal
test/data/pattern-synonyms/*.hs
test/data/quasi-quotes/*.hs
test/data/template-haskell/*.hs
test/data/target/*.hs
test/data/check-missing-warnings/*.hs
test/data/custom-cradle/custom-cradle.cabal
test/data/custom-cradle/ghc-mod.package-db-stack
test/data/custom-cradle/package-db-a/.gitkeep
test/data/custom-cradle/package-db-b/.gitkeep
test/data/custom-cradle/package-db-c/.gitkeep
test/data/cabal-preprocessors/*.cabal
test/data/cabal-preprocessors/*.hs
test/data/cabal-preprocessors/*.hsc
test/data/file-mapping/*.hs
test/data/file-mapping/preprocessor/*.hs
test/data/file-mapping/lhs/*.lhs
test/data/nice-qualification/*.hs
test/data/stack-project/stack.yaml
test/data/stack-project/new-template.cabal
test/data/stack-project/*.hs
test/data/stack-project/app/*.hs
test/data/stack-project/src/*.hs
test/data/stack-project/test/*.hs
Library
Default-Language: Haskell2010
GHC-Options: -Wall -fno-warn-deprecations
Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns,
ConstraintKinds, FlexibleContexts,
DataKinds, KindSignatures, TypeOperators, ViewPatterns
Exposed-Modules: Language.Haskell.GhcMod
Language.Haskell.GhcMod.Internal
Language.Haskell.GhcMod.Boot
Language.Haskell.GhcMod.Browse
Language.Haskell.GhcMod.CabalHelper
Language.Haskell.GhcMod.Caching
Language.Haskell.GhcMod.Caching.Types
Language.Haskell.GhcMod.CaseSplit
Language.Haskell.GhcMod.Check
Language.Haskell.GhcMod.Convert
Language.Haskell.GhcMod.Cradle
Language.Haskell.GhcMod.CustomPackageDb
Language.Haskell.GhcMod.Debug
Language.Haskell.GhcMod.DebugLogger
Language.Haskell.GhcMod.Doc
Language.Haskell.GhcMod.DynFlags
Language.Haskell.GhcMod.Error
Language.Haskell.GhcMod.FileMapping
Language.Haskell.GhcMod.FillSig
Language.Haskell.GhcMod.Find
Language.Haskell.GhcMod.Flag
Language.Haskell.GhcMod.Gap
Language.Haskell.GhcMod.GhcPkg
Language.Haskell.GhcMod.HomeModuleGraph
Language.Haskell.GhcMod.Info
Language.Haskell.GhcMod.Lang
Language.Haskell.GhcMod.Lint
Language.Haskell.GhcMod.LightGhc
Language.Haskell.GhcMod.Logger
Language.Haskell.GhcMod.Logging
Language.Haskell.GhcMod.Modules
Language.Haskell.GhcMod.Monad
Language.Haskell.GhcMod.Monad.Types
Language.Haskell.GhcMod.Output
Language.Haskell.GhcMod.PathsAndFiles
Language.Haskell.GhcMod.PkgDoc
Language.Haskell.GhcMod.Pretty
Language.Haskell.GhcMod.Read
Language.Haskell.GhcMod.SrcUtils
Language.Haskell.GhcMod.Stack
Language.Haskell.GhcMod.Target
Language.Haskell.GhcMod.Types
Language.Haskell.GhcMod.Utils
Language.Haskell.GhcMod.World
Other-Modules: Paths_ghc_mod
Utils
Build-Depends: base < 5 && >= 4.0
, bytestring < 0.11
, cereal < 0.5 && >= 0.4
, containers < 0.6
, cabal-helper < 0.7 && >= 0.6.1.0
, deepseq < 1.5
, directory < 1.3
, filepath < 1.5
, ghc < 7.11
, ghc-paths < 0.2
, ghc-syb-utils < 0.3
, hlint < 1.10 && >= 1.8.61
, monad-journal < 0.8 && >= 0.4
, old-time < 1.2
, pretty < 1.2
, process < 1.3
, syb < 0.7
, temporary < 1.3
, time < 1.6
, transformers < 0.5
, transformers-base < 0.5
, mtl < 2.3 && >= 2.0
, monad-control < 1.1 && >= 1
, split < 0.3
, haskell-src-exts < 1.18
, text < 1.3
, djinn-ghc < 0.1 && >= 0.0.2.2
, fclabels == 2.0.*
, extra == 1.4.*
, pipes == 4.1.*
if impl(ghc < 7.8)
Build-Depends: convertible
if impl(ghc < 7.5)
-- Only used to constrain random to a version that still works with GHC 7.4
Build-Depends: random <= 1.0.1.1,
ghc-prim
Executable ghc-mod
Default-Language: Haskell2010
Main-Is: GHCMod.hs
Other-Modules: Paths_ghc_mod
GHC-Options: -Wall -fno-warn-deprecations -threaded
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src
Build-Depends: base < 5 && >= 4.0
, async < 2.1
, directory < 1.3
, filepath < 1.5
, pretty < 1.2
, process < 1.3
, split < 0.3
, mtl < 2.3 && >= 2.0
, ghc < 7.11
, fclabels == 2.0.*
, ghc-mod
Executable ghc-modi
Default-Language: Haskell2010
Main-Is: GHCModi.hs
Other-Modules: Paths_ghc_mod
Misc
Utils
GHC-Options: -Wall -threaded -fno-warn-deprecations
if os(windows)
Cpp-Options: -DWINDOWS
Default-Extensions: ConstraintKinds, FlexibleContexts
HS-Source-Dirs: src, .
Build-Depends: base < 5 && >= 4.0
, directory < 1.3
, filepath < 1.5
, process < 1.3
, old-time < 1.2
, time < 1.6
Test-Suite doctest
Type: exitcode-stdio-1.0
Default-Language: Haskell2010
HS-Source-Dirs: test
Ghc-Options: -Wall
Default-Extensions: ConstraintKinds, FlexibleContexts
Main-Is: doctests.hs
if impl(ghc == 7.4.*)
Buildable: False
Build-Depends: base
, doctest < 0.11 && >= 0.9.3
Test-Suite spec
Default-Language: Haskell2010
Default-Extensions: ScopedTypeVariables, RecordWildCards, NamedFieldPuns,
ConstraintKinds, FlexibleContexts,
DataKinds, KindSignatures, TypeOperators, ViewPatterns
Main-Is: Main.hs
Hs-Source-Dirs: test, .
Ghc-Options: -Wall -fno-warn-deprecations
CPP-Options: -DSPEC=1
Type: exitcode-stdio-1.0
Other-Modules: Paths_ghc_mod
Dir
Spec
TestUtils
BrowseSpec
CustomPackageDbSpec
CheckSpec
FlagSpec
InfoSpec
LangSpec
LintSpec
ListSpec
MonadSpec
PathsAndFilesSpec
HomeModuleGraphSpec
FileMappingSpec
Build-Depends: hspec < 2.3 && >= 2.0.0
if impl(ghc == 7.4.*)
Build-Depends: executable-path
X-Build-Depends-Like: CLibName
Source-Repository head
Type: git
Location: https://github.com/kazu-yamamoto/ghc-mod.git

28
scripts/download-metadata.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
################################################################################
# #
# Download package metadata for all versions on Hackage #
# #
# Copyright (C) 2015 Daniel Gröber <dxld@darkboxed.org> #
# #
# Copying and distribution of this file, with or without modification, #
# are permitted in any medium without royalty provided the copyright #
# notice and this notice are preserved. This file is offered as-is, #
# without any warranty. #
# #
# Usage: ./download-metadata.sh PACKAGE OUTPUT_DIRECTORY #
# #
################################################################################
PACKAGE=$1
OUTDIR=$2
versions="$(wget -O - https://hackage.haskell.org/package/"$PACKAGE"/preferred.json | jq '."normal-version"[]' -r)"
mkdir -p "$OUTDIR"
for v in $versions; do
wget https://hackage.haskell.org/package/"$PACKAGE-$v"/"$PACKAGE".cabal -O "$OUTDIR/${PACKAGE}-${v}.cabal"
done

62
scripts/upload-metadata.hs Executable file
View File

@ -0,0 +1,62 @@
#!/bin/sh
is_term() {
[ -t 0 ]
}
# Disable echo while typing the password if in a terminal
hidden_prompt() {
if is_term; then
settings=$(stty -g)
trap "stty '$settings'" 0
stty -echo
echo -n "$1: "
IFS="" read -r $2
echo
stty "$settings"
else
IFS="" read -r $2
fi
}
set -e
PACKAGE=$1
OUTDIR=$2
read -p "Username: " user
hidden_prompt "Password" pw
versions="$(curl https://hackage.haskell.org/package/"$PACKAGE"/preferred.json | jq '."normal-version"[]' -r)"
for v in $versions; do
rev=$(cat $OUTDIR/$PACKAGE-$v.cabal | grep -i "^x-revision:" | tr -s '[:blank:]*' '\t' | cut -f 2)
if [ -z "$rev" ]; then
rev=0
fi
content=$( ( echo "X-Revision: $((rev + 1))"; cat $OUTDIR/$PACKAGE-$v.cabal | sed '/^X-Revision:/Id' ) )
resp=$(curl --form-string "cabalfile=$content" -F "publish=Publish new revision" https://hackage.haskell.org/package/"${PACKAGE}-${v}"/"${PACKAGE}.cabal"/edit -u "$user:$pw")
changes=$(printf '%s\n' "$resp" | sed -n '/Changes in this revision/,/<\/ul>/p' | w3m -dump -T text/html)
errors=$(printf '%s\n' "$resp" | sed -n '/Errors/,/<\/form>/p')
notpublished=$(printf '%s\n' "$resp" | grep "Cannot publish new revision")
if [ -z "$changes" -o -n "$notpublished" ]; then
if printf '%s\n' "$errors" | grep -q "No changes"; then
continue;
fi
printf '%s\n' "$resp" > /tmp/hackage-metadata-error
printf '%s\n' "$errors" | w3m -dump -T text/html
exit 1
fi
done

View File

@ -2,450 +2,64 @@
module Main where module Main where
import Config (cProjectVersion)
import Control.Category
import Control.Applicative import Control.Applicative
import Control.Arrow
import Control.Monad import Control.Monad
import Data.Typeable (Typeable) import Data.Typeable (Typeable)
import Data.Version (showVersion)
import Data.Label
import Data.List import Data.List
import Data.List.Split
import Data.Char (isSpace)
import Data.Maybe
import Exception import Exception
import Language.Haskell.GhcMod import Language.Haskell.GhcMod
import Language.Haskell.GhcMod.Internal hiding (MonadIO,liftIO) import Language.Haskell.GhcMod.Internal hiding (MonadIO,liftIO)
import Language.Haskell.GhcMod.Types import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad import Language.Haskell.GhcMod.Monad
import Paths_ghc_mod import Language.Haskell.GhcMod.Find (AsyncSymbolDb, newAsyncSymbolDb, getAsyncSymbolDb)
import System.Console.GetOpt (OptDescr(..), ArgDescr(..), ArgOrder(..))
import qualified System.Console.GetOpt as O
import System.FilePath ((</>)) import System.FilePath ((</>))
import System.Directory (setCurrentDirectory, getAppUserDataDirectory, import System.Directory (setCurrentDirectory, getAppUserDataDirectory,
removeDirectoryRecursive) removeDirectoryRecursive)
import System.Environment (getArgs)
import System.IO import System.IO
import System.Exit import System.Exit
import Text.PrettyPrint import Text.PrettyPrint hiding ((<>))
import Prelude hiding ((.)) import GHCMod.Options
import Prelude
import Misc
progVersion :: String -> String
progVersion pf =
"ghc-mod"++pf++" version " ++ showVersion version ++ " compiled by GHC "
++ cProjectVersion ++ "\n"
ghcModVersion :: String
ghcModVersion = progVersion ""
ghcModiVersion :: String
ghcModiVersion = progVersion "i"
optionUsage :: (String -> String) -> [OptDescr a] -> [String]
optionUsage indent opts = concatMap optUsage opts
where
optUsage (Option so lo dsc udsc) =
[ concat $ intersperse ", " $ addLabel `map` allFlags
, indent $ udsc
, ""
]
where
allFlags = shortFlags ++ longFlags
shortFlags = (('-':) . return) `map` so :: [String]
longFlags = ("--"++) `map` lo
addLabel f@('-':'-':_) = f ++ flagLabel "="
addLabel f@('-':_) = f ++ flagLabel " "
addLabel _ = undefined
flagLabel s =
case dsc of
NoArg _ -> ""
ReqArg _ label -> s ++ label
OptArg _ label -> s ++ "["++label++"]"
-- TODO: Generate the stuff below automatically
usage :: String
usage =
"Usage: ghc-mod [OPTIONS...] COMMAND [CMD_ARGS...] \n\
\*Global Options (OPTIONS)*\n\
\ Global options can be specified before and after the command and\n\
\ interspersed with command specific options\n\
\\n"
++ (unlines $ indent <$> optionUsage indent globalArgSpec) ++
"*Commands*\n\
\ - version\n\
\ Print the version of the program.\n\
\\n\
\ - help\n\
\ Print this help message.\n\
\\n\
\ - list [FLAGS...] | modules [FLAGS...]\n\
\ List all visible modules.\n\
\ Flags:\n\
\ -d\n\
\ Print package modules belong to.\n\
\\n\
\ - lang\n\
\ List all known GHC language extensions.\n\
\\n\
\ - flag\n\
\ List GHC -f<bla> flags.\n\
\\n\
\ - browse [FLAGS...] [PACKAGE:]MODULE...\n\
\ List symbols in a module.\n\
\ Flags:\n\
\ -o\n\
\ Also print operators.\n\
\ -d\n\
\ Print symbols with accompanying signatures.\n\
\ -q\n\
\ Qualify symbols.\n\
\\n\
\ - check FILE...\n\
\ Load the given files using GHC and report errors/warnings, but\n\
\ don't produce output files.\n\
\\n\
\ - expand FILE...\n\
\ Like `check' but also pass `-ddump-splices' to GHC.\n\
\\n\
\ - info FILE [MODULE] EXPR\n\
\ Look up an identifier in the context of FILE (like ghci's `:info')\n\
\ MODULE is completely ignored and only allowed for backwards\n\
\ compatibility.\n\
\\n\
\ - type FILE [MODULE] LINE COL\n\
\ Get the type of the expression under (LINE,COL).\n\
\\n\
\ - split FILE [MODULE] LINE COL\n\
\ Split a function case by examining a type's constructors.\n\
\\n\
\ For example given the following code snippet:\n\
\\n\
\ f :: [a] -> a\n\
\ f x = _body\n\
\\n\
\ would be replaced by:\n\
\\n\
\ f :: [a] -> a\n\
\ f [] = _body\n\
\ f (x:xs) = _body\n\
\\n\
\ (See https://github.com/kazu-yamamoto/ghc-mod/pull/274)\n\
\\n\
\ - sig FILE MODULE LINE COL\n\
\ Generate initial code given a signature.\n\
\\n\
\ For example when (LINE,COL) is on the signature in the following\n\
\ code snippet:\n\
\\n\
\ func :: [a] -> Maybe b -> (a -> b) -> (a,b)\n\
\\n\
\ ghc-mod would add the following on the next line:\n\
\\n\
\ func x y z f = _func_body\n\
\\n\
\ (See: https://github.com/kazu-yamamoto/ghc-mod/pull/274)\n\
\\n\
\ - refine FILE MODULE LINE COL EXPR\n\
\ Refine the typed hole at (LINE,COL) given EXPR.\n\
\\n\
\ For example if EXPR is `filter', which has type `(a -> Bool) -> [a]\n\
\ -> [a]' and (LINE,COL) is on the hole `_body' in the following\n\
\ code snippet:\n\
\\n\
\ filterNothing :: [Maybe a] -> [a]\n\
\ filterNothing xs = _body\n\
\\n\
\ ghc-mod changes the code to get a value of type `[a]', which\n\
\ results in:\n\
\\n\
\ filterNothing xs = filter _body_1 _body_2\n\
\\n\
\ (See also: https://github.com/kazu-yamamoto/ghc-mod/issues/311)\n\
\\n\
\ - auto FILE MODULE LINE COL\n\
\ Try to automatically fill the contents of a hole.\n\
\\n\
\ - find SYMBOL\n\
\ List all modules that define SYMBOL.\n\
\\n\
\ - lint FILE\n\
\ Check files using `hlint'.\n\
\ Flags:\n\
\ -h\n\
\ Option to be passed to hlint.\n\
\\n\
\ - root\n\
\ Try to find the project directory. For Cabal projects this is the\n\
\ directory containing the cabal file, for projects that use a cabal\n\
\ sandbox but have no cabal file this is the directory containing the\n\
\ cabal.sandbox.config file and otherwise this is the current\n\
\ directory.\n\
\\n\
\ - doc MODULE\n\
\ Try finding the html documentation directory for the given MODULE.\n\
\\n\
\ - debug\n\
\ Print debugging information. Please include the output in any bug\n\
\ reports you submit.\n\
\\n\
\ - debugComponent [MODULE_OR_FILE...]\n\
\ Debugging information related to cabal component resolution.\n\
\\n\
\ - boot\n\
\ Internal command used by the emacs frontend.\n\
\\n\
\ - legacy-interactive\n\
\ ghc-modi compatibility mode.\n"
where
indent = (" "++)
cmdUsage :: String -> String -> String
cmdUsage cmd realUsage =
let
-- Find command head
a = dropWhile (not . isCmdHead) $ lines realUsage
-- Take til the end of the current command block
b = flip takeWhile a $ \l ->
all isSpace l || (isIndented l && (isCmdHead l || isNotCmdHead l))
-- Drop extra newline from the end
c = dropWhileEnd (all isSpace) b
isIndented = (" " `isPrefixOf`)
isNotCmdHead = ( not . (" - " `isPrefixOf`))
containsAnyCmdHead s = ((" - ") `isInfixOf` s)
containsCurrCmdHead s = ((" - " ++ cmd) `isInfixOf` s)
isCmdHead s =
containsAnyCmdHead s &&
or [ containsCurrCmdHead s
, any (cmd `isPrefixOf`) (splitOn " | " s)
]
unindent (' ':' ':' ':' ':l) = l
unindent l = l
in unlines $ unindent <$> c
ghcModStyle :: Style ghcModStyle :: Style
ghcModStyle = style { lineLength = 80, ribbonsPerLine = 1.2 } ghcModStyle = style { lineLength = 80, ribbonsPerLine = 1.2 }
---------------------------------------------------------------- ----------------------------------------------------------------
option :: [Char] -> [String] -> String -> ArgDescr a -> OptDescr a
option s l udsc dsc = Option s l dsc udsc
reqArg :: String -> (String -> a) -> ArgDescr a
reqArg udsc dsc = ReqArg dsc udsc
optArg :: String -> (Maybe String -> a) -> ArgDescr a
optArg udsc dsc = OptArg dsc udsc
intToLogLevel :: Int -> GmLogLevel
intToLogLevel = toEnum
globalArgSpec :: [OptDescr (Options -> Either [String] Options)]
globalArgSpec =
[ option "v" ["verbose"] "Increase or set log level. (0-7)" $
optArg "LEVEL" $ \ml o -> Right $ case ml of
Nothing ->
modify (lOoptLogLevel . lOptOutput) increaseLogLevel o
Just l ->
set (lOoptLogLevel . lOptOutput) (toEnum $ min 7 $ read l) o
, option "s" [] "Be silent, set log level to 0" $
NoArg $ \o -> Right $ set (lOoptLogLevel . lOptOutput) (toEnum 0) o
, option "l" ["tolisp"] "Format output as an S-Expression" $
NoArg $ \o -> Right $ set (lOoptStyle . lOptOutput) LispStyle o
, option "b" ["boundary", "line-seperator"] "Output line separator"$
reqArg "SEP" $ \s o -> Right $ set (lOoptLineSeparator . lOptOutput) (LineSeparator s) o
, option "" ["line-prefix"] "Output line separator"$
reqArg "OUT,ERR" $ \s o -> let
[out, err] = splitOn "," s
in Right $ set (lOoptLinePrefix . lOptOutput) (Just (out, err)) o
, option "g" ["ghcOpt", "ghc-option"] "Option to be passed to GHC" $
reqArg "OPT" $ \g o -> Right $
o { optGhcUserOptions = g : optGhcUserOptions o }
{-
File map docs:
CLI options:
* `--map-file "file1.hs=file2.hs"` can be used to tell
ghc-mod that it should take source code for `file1.hs` from `file2.hs`.
`file1.hs` can be either full path, or path relative to project root.
`file2.hs` has to be either relative to project root,
or full path (preferred).
* `--map-file "file.hs"` can be used to tell ghc-mod that it should take
source code for `file.hs` from stdin. File end marker is `\EOT\n`,
i.e. `\x04\x0A`. `file.hs` may or may not exist, and should be
either full path, or relative to project root.
Interactive commands:
* `map-file file.hs` -- tells ghc-modi to read `file.hs` source from stdin.
Works the same as second form of `--map-file` CLI option.
* `unmap-file file.hs` -- unloads previously mapped file, so that it's
no longer mapped. `file.hs` can be full path or relative to
project root, either will work.
Exposed functions:
* `loadMappedFile :: FilePath -> FilePath -> GhcModT m ()` -- maps `FilePath`,
given as first argument to take source from `FilePath` given as second
argument. Works exactly the same as first form of `--map-file`
CLI option.
* `loadMappedFileSource :: FilePath -> String -> GhcModT m ()` -- maps
`FilePath`, given as first argument to have source as given
by second argument. Works exactly the same as second form of `--map-file`
CLI option, sans reading from stdin.
* `unloadMappedFile :: FilePath -> GhcModT m ()` -- unmaps `FilePath`, given as
first argument, and removes any temporary files created when file was
mapped. Works exactly the same as `unmap-file` interactive command
-}
, option "" ["map-file"] "Redirect one file to another, --map-file \"file1.hs=file2.hs\"" $
reqArg "OPT" $ \g o ->
let m = case second (drop 1) $ span (/='=') g of
(s,"") -> (s, Nothing)
(f,t) -> (f, Just t)
in
Right $ o { optFileMappings = m : optFileMappings o }
, option "" ["with-ghc"] "GHC executable to use" $
reqArg "PATH" $ \p o -> Right $ set (lGhcProgram . lOptPrograms) p o
, option "" ["with-ghc-pkg"] "ghc-pkg executable to use (only needed when guessing from GHC path fails)" $
reqArg "PATH" $ \p o -> Right $ set (lGhcPkgProgram . lOptPrograms) p o
, option "" ["with-cabal"] "cabal-install executable to use" $
reqArg "PATH" $ \p o -> Right $ set (lCabalProgram . lOptPrograms) p o
, option "" ["with-stack"] "stack executable to use" $
reqArg "PATH" $ \p o -> Right $ set (lStackProgram . lOptPrograms) p o
, option "" ["version"] "print version information" $
NoArg $ \_ -> Left ["version"]
, option "" ["help"] "print this help message" $
NoArg $ \_ -> Left ["help"]
]
parseGlobalArgs :: [String] -> Either InvalidCommandLine (Options, [String])
parseGlobalArgs argv
= case O.getOpt' RequireOrder globalArgSpec argv of
(o,r,u,[]) -> case foldr (=<<) (Right defaultOptions) o of
Right o' -> Right (o', u ++ r)
Left c -> Right (defaultOptions, c)
(_,_,u,e) -> Left $ InvalidCommandLine $ Right $
"Parsing command line options failed: "
++ concat (e ++ map errUnrec u)
where
errUnrec :: String -> String
errUnrec optStr = "unrecognized option `" ++ optStr ++ "'\n"
parseCommandArgs :: [OptDescr (Options -> Either [String] Options)]
-> [String]
-> Options
-> (Options, [String])
parseCommandArgs spec argv opts
= case O.getOpt RequireOrder (globalArgSpec ++ spec) argv of
(o,r,[]) -> case foldr (=<<) (Right opts) o of
Right o' -> (o', r)
Left c -> (defaultOptions, c)
(_,_,errs) ->
fatalError $ "Parsing command options failed: " ++ concat errs
----------------------------------------------------------------
data CmdError = UnknownCommand String
| NoSuchFileError String
| LibraryError GhcModError
deriving (Show, Typeable)
instance Exception CmdError
data InteractiveOptions = InteractiveOptions {
ghcModExtensions :: Bool
}
handler :: IOish m => GhcModT m a -> GhcModT m a handler :: IOish m => GhcModT m a -> GhcModT m a
handler = flip gcatches $ handler = flip gcatches
[ GHandler $ \(FatalError msg) -> exitError msg [ GHandler $ \(e :: ExitCode) -> throw e
, GHandler $ \e@(ExitSuccess) -> throw e
, GHandler $ \e@(ExitFailure _) -> throw e
, GHandler $ \(InvalidCommandLine e) -> do
case e of
Left cmd ->
exitError $ "Usage for `"++cmd++"' command:\n\n"
++ (cmdUsage cmd usage) ++ "\n"
++ "ghc-mod: Invalid command line form."
Right msg -> exitError $ "ghc-mod: " ++ msg
, GHandler $ \(SomeException e) -> exitError $ "ghc-mod: " ++ show e , GHandler $ \(SomeException e) -> exitError $ "ghc-mod: " ++ show e
] ]
main :: IO () main :: IO ()
main = do main = do
hSetEncoding stdout utf8 hSetEncoding stdout utf8
args <- getArgs parseArgs >>= \res@(globalOptions, _) ->
case parseGlobalArgs args of catches (progMain res) [
Left e -> throw e
Right res@(globalOptions,_) -> catches (progMain res) [
Handler $ \(e :: GhcModError) -> Handler $ \(e :: GhcModError) ->
runGmOutT globalOptions $ exitError $ renderStyle ghcModStyle (gmeDoc e) runGmOutT globalOptions $ exitError $ renderStyle ghcModStyle (gmeDoc e)
] ]
progMain :: (Options,[String]) -> IO () progMain :: (Options, GhcModCommands) -> IO ()
progMain (globalOptions,cmdArgs) = runGmOutT globalOptions $ progMain (globalOptions, commands) = runGmOutT globalOptions $
case globalCommands cmdArgs of wrapGhcCommands globalOptions commands
Just s -> gmPutStr s
Nothing -> wrapGhcCommands globalOptions cmdArgs
globalCommands :: [String] -> Maybe String
globalCommands (cmd:_)
| cmd == "help" = Just usage
| cmd == "version" = Just ghcModVersion
globalCommands _ = Nothing
-- ghc-modi -- ghc-modi
legacyInteractive :: IOish m => GhcModT m () legacyInteractive :: IOish m => GhcModT m ()
legacyInteractive = do legacyInteractive = do
opt <- options
prepareCabalHelper prepareCabalHelper
tmpdir <- cradleTempDir <$> cradle tmpdir <- cradleTempDir <$> cradle
gmo <- gmoAsk asyncSymbolDb <- newAsyncSymbolDb tmpdir
symdbreq <- liftIO $ newSymDbReq opt gmo tmpdir
world <- getCurrentWorld world <- getCurrentWorld
legacyInteractiveLoop symdbreq world legacyInteractiveLoop asyncSymbolDb world
bug :: IOish m => String -> GhcModT m () legacyInteractiveLoop :: IOish m => AsyncSymbolDb -> World -> GhcModT m ()
bug msg = do legacyInteractiveLoop asyncSymbolDb world = do
gmPutStrLn $ notGood $ "BUG: " ++ msg
liftIO exitFailure
notGood :: String -> String
notGood msg = "NG " ++ escapeNewlines msg
escapeNewlines :: String -> String
escapeNewlines = replace "\n" "\\n" . replace "\\n" "\\\\n"
replace :: String -> String -> String -> String
replace needle replacement = intercalate replacement . splitOn needle
legacyInteractiveLoop :: IOish m
=> SymDbReq -> World -> GhcModT m ()
legacyInteractiveLoop symdbreq world = do
liftIO . setCurrentDirectory =<< cradleRootDir <$> cradle liftIO . setCurrentDirectory =<< cradleRootDir <$> cradle
-- blocking -- blocking
cmdArg <- liftIO $ getLine cmdArg <- liftIO getLine
-- after blocking, we need to see if the world has changed. -- after blocking, we need to see if the world has changed.
@ -455,72 +69,48 @@ legacyInteractiveLoop symdbreq world = do
then getCurrentWorld -- TODO: gah, we're hitting the fs twice then getCurrentWorld -- TODO: gah, we're hitting the fs twice
else return world else return world
when changed $ do when changed dropSession
dropSession
let (cmd':args') = split (keepDelimsR $ condense $ whenElt isSpace) cmdArg res <- flip gcatches interactiveHandlers $ do
arg = concat args' pargs <- either (throw . InvalidCommandLine . Right) return
cmd = dropWhileEnd isSpace cmd' $ parseArgsInteractive cmdArg
args = dropWhileEnd isSpace `map` args' case pargs of
CmdFind symbol ->
res <- flip gcatches interactiveHandlers $ case dropWhileEnd isSpace cmd of lookupSymbol symbol =<< getAsyncSymbolDb asyncSymbolDb
"check" -> checkSyntaxCmd [arg] -- other commands are handled here
"lint" -> lintCmd [arg] x -> ghcCommands x
"find" -> do
db <- getDb symdbreq >>= checkDb symdbreq
lookupSymbol arg db
"info" -> infoCmd [head args, concat $ tail args']
"type" -> typesCmd args
"split" -> splitsCmd args
"sig" -> sigCmd args
"auto" -> autoCmd args
"refine" -> refineCmd args
"boot" -> bootCmd []
"browse" -> browseCmd args
"map-file" -> liftIO getFileSourceFromStdin
>>= loadMappedFileSource arg
>> return ""
"unmap-file" -> unloadMappedFile arg
>> return ""
"quit" -> liftIO $ exitSuccess
"" -> liftIO $ exitSuccess
_ -> fatalError $ "unknown command: `" ++ cmd ++ "'"
gmPutStr res >> gmPutStrLn "OK" >> liftIO (hFlush stdout) gmPutStr res >> gmPutStrLn "OK" >> liftIO (hFlush stdout)
legacyInteractiveLoop symdbreq world' legacyInteractiveLoop asyncSymbolDb world'
where where
interactiveHandlers = interactiveHandlers =
[ GHandler $ \e@(FatalError _) -> throw e [ GHandler $ \(e :: ExitCode) -> throw e
, GHandler $ \e@(ExitSuccess) -> throw e , GHandler $ \(InvalidCommandLine e) -> do
, GHandler $ \e@(ExitFailure _) -> throw e gmErrStrLn $ either ("Invalid command line: "++) Prelude.id e
return ""
, GHandler $ \(SomeException e) -> gmErrStrLn (show e) >> return "" , GHandler $ \(SomeException e) -> gmErrStrLn (show e) >> return ""
] ]
getFileSourceFromStdin :: IO String getFileSourceFromStdin :: IO String
getFileSourceFromStdin = do getFileSourceFromStdin = do
let loop' acc = do linesIn <- readStdin'
line <- getLine return (intercalate "\n" linesIn)
if not (null line) && last line == '\EOT' where
then return $ acc ++ init line readStdin' = do
else loop' (acc++line++"\n") x <- getLine
loop' "" if x/="\EOT"
then fmap (x:) readStdin'
else return []
-- Someone please already rewrite the cmdline parsing code *weep* :'( -- Someone please already rewrite the cmdline parsing code *weep* :'(
wrapGhcCommands :: (IOish m, GmOut m) => Options -> [String] -> m () wrapGhcCommands :: (IOish m, GmOut m) => Options -> GhcModCommands -> m ()
wrapGhcCommands _opts [] = fatalError "No command given (try --help)" wrapGhcCommands _opts CmdRoot = gmPutStr =<< rootInfo
wrapGhcCommands _opts ("root":_) = gmPutStr =<< rootInfo wrapGhcCommands opts cmd =
wrapGhcCommands opts args = do
handleGmError $ runGhcModT opts $ handler $ do handleGmError $ runGhcModT opts $ handler $ do
forM_ (reverse $ optFileMappings opts) $ forM_ (reverse $ optFileMappings opts) $
uncurry loadMMappedFiles uncurry loadMMappedFiles
ghcCommands args gmPutStr =<< ghcCommands cmd
where where
handleGmError action = do handleGmError action = do
(e, _l) <- liftIO . evaluate =<< action (e, _l) <- liftIO . evaluate =<< action
@ -536,37 +126,39 @@ wrapGhcCommands opts args = do
loadMappedFileSource from src loadMappedFileSource from src
ghcCommands :: IOish m => [String] -> GhcModT m () ghcCommands :: IOish m => GhcModCommands -> GhcModT m String
ghcCommands [] = fatalError "No command given (try --help)" -- ghcCommands cmd = action args
ghcCommands (cmd:args) = gmPutStr =<< action args ghcCommands (CmdLang) = languages
where ghcCommands (CmdFlag) = flags
action = case cmd of ghcCommands (CmdDebug) = debugInfo
_ | cmd == "list" || cmd == "modules" -> modulesCmd ghcCommands (CmdDebugComponent ts) = componentInfo ts
"lang" -> languagesCmd ghcCommands (CmdBoot) = boot
"flag" -> flagsCmd -- ghcCommands (CmdNukeCaches) = nukeCaches >> return ""
"browse" -> browseCmd -- ghcCommands (CmdRoot) = undefined -- handled in wrapGhcCommands
"check" -> checkSyntaxCmd ghcCommands (CmdLegacyInteractive) = legacyInteractive >> return ""
"expand" -> expandTemplateCmd ghcCommands (CmdModules detail) = modules detail
"debug" -> debugInfoCmd ghcCommands (CmdDumpSym tmpdir) = dumpSymbol tmpdir
"debug-component" -> componentInfoCmd ghcCommands (CmdFind symb) = findSymbol symb
"info" -> infoCmd ghcCommands (CmdDoc m) = pkgDoc m
"type" -> typesCmd ghcCommands (CmdLint opts file) = lint opts file
"split" -> splitsCmd ghcCommands (CmdBrowse opts ms) = concat <$> browse opts `mapM` ms
"sig" -> sigCmd ghcCommands (CmdCheck files) = checkSyntax files
"refine" -> refineCmd ghcCommands (CmdExpand files) = expandTemplate files
"auto" -> autoCmd ghcCommands (CmdInfo file symb) = info file $ Expression symb
"find" -> findSymbolCmd ghcCommands (CmdType file (line, col)) = types file line col
"lint" -> lintCmd ghcCommands (CmdSplit file (line, col)) = splits file line col
-- "root" -> rootInfoCmd ghcCommands (CmdSig file (line, col)) = sig file line col
"doc" -> pkgDocCmd ghcCommands (CmdAuto file (line, col)) = auto file line col
"dumpsym" -> dumpSymbolCmd ghcCommands (CmdRefine file (line, col) expr) = refine file line col $ Expression expr
"boot" -> bootCmd -- interactive-only commands
"legacy-interactive" -> legacyInteractiveCmd ghcCommands (CmdMapFile f) =
-- "nuke-caches" -> nukeCachesCmd liftIO getFileSourceFromStdin
_ -> fatalError $ "unknown command: `" ++ cmd ++ "'" >>= loadMappedFileSource f
>> return ""
newtype FatalError = FatalError String deriving (Show, Typeable) ghcCommands (CmdUnmapFile f) = unloadMappedFile f >> return ""
instance Exception FatalError ghcCommands (CmdQuit) = liftIO exitSuccess
ghcCommands (CmdTest file) = test file
ghcCommands cmd = throw $ InvalidCommandLine $ Left $ show cmd
newtype InvalidCommandLine = InvalidCommandLine (Either String String) newtype InvalidCommandLine = InvalidCommandLine (Either String String)
deriving (Show, Typeable) deriving (Show, Typeable)
@ -575,117 +167,6 @@ instance Exception InvalidCommandLine
exitError :: (MonadIO m, GmOut m) => String -> m a exitError :: (MonadIO m, GmOut m) => String -> m a
exitError msg = gmErrStrLn (dropWhileEnd (=='\n') msg) >> liftIO exitFailure exitError msg = gmErrStrLn (dropWhileEnd (=='\n') msg) >> liftIO exitFailure
fatalError :: String -> a
fatalError s = throw $ FatalError $ "ghc-mod: " ++ s
withParseCmd :: IOish m
=> [OptDescr (Options -> Either [String] Options)]
-> ([String] -> GhcModT m a)
-> [String]
-> GhcModT m a
withParseCmd spec action args = do
(opts', rest) <- parseCommandArgs spec args <$> options
withOptions (const opts') $ action rest
withParseCmd' :: (IOish m, ExceptionMonad m)
=> String
-> [OptDescr (Options -> Either [String] Options)]
-> ([String] -> GhcModT m a)
-> [String]
-> GhcModT m a
withParseCmd' cmd spec action args =
catchArgs cmd $ withParseCmd spec action args
catchArgs :: (Monad m, ExceptionMonad m) => String -> m a -> m a
catchArgs cmd action =
action `gcatch` \(PatternMatchFail _) ->
throw $ InvalidCommandLine (Left cmd)
modulesCmd, languagesCmd, flagsCmd, browseCmd, checkSyntaxCmd, expandTemplateCmd,
debugInfoCmd, componentInfoCmd, infoCmd, typesCmd, splitsCmd, sigCmd,
refineCmd, autoCmd, findSymbolCmd, lintCmd, pkgDocCmd,
dumpSymbolCmd, bootCmd, legacyInteractiveCmd, nukeCachesCmd
:: IOish m => [String] -> GhcModT m String
modulesCmd = withParseCmd' "modules" s $ \[] -> modules
where s = modulesArgSpec
languagesCmd = withParseCmd' "lang" [] $ \[] -> languages
flagsCmd = withParseCmd' "flag" [] $ \[] -> flags
debugInfoCmd = withParseCmd' "debug" [] $ \[] -> debugInfo
componentInfoCmd = withParseCmd' "debugComponent" [] $ \ts -> componentInfo ts
-- internal
bootCmd = withParseCmd' "boot" [] $ \[] -> boot
nukeCachesCmd = withParseCmd' "nuke-caches" [] $ \[] -> nukeCaches >> return ""
dumpSymbolCmd = withParseCmd' "dump" [] $ \[tmpdir] -> dumpSymbol tmpdir
findSymbolCmd = withParseCmd' "find" [] $ \[sym] -> findSymbol sym
pkgDocCmd = withParseCmd' "doc" [] $ \[mdl] -> pkgDoc mdl
lintCmd = withParseCmd' "lint" s $ \[file] -> lint file
where s = hlintArgSpec
browseCmd = withParseCmd s $ \mdls -> concat <$> browse `mapM` mdls
where s = browseArgSpec
checkSyntaxCmd = withParseCmd [] $ checkAction checkSyntax
expandTemplateCmd = withParseCmd [] $ checkAction expandTemplate
typesCmd = withParseCmd [] $ locAction "type" types
splitsCmd = withParseCmd [] $ locAction "split" splits
sigCmd = withParseCmd [] $ locAction "sig" sig
autoCmd = withParseCmd [] $ locAction "auto" auto
refineCmd = withParseCmd [] $ locAction' "refine" refine
infoCmd = withParseCmd [] $ action
where action [file,_,expr] = info file $ Expression expr
action [file,expr] = info file $ Expression expr
action _ = throw $ InvalidCommandLine (Left "info")
legacyInteractiveCmd = withParseCmd [] go
where
go [] =
legacyInteractive >> return ""
go ("help":[]) =
return usage
go ("version":[]) =
return ghcModiVersion
go _ = throw $ InvalidCommandLine (Left "legacy-interactive")
checkAction :: ([t] -> a) -> [t] -> a
checkAction _ [] = throw $ InvalidCommandLine (Right "No files given.")
checkAction action files = action files
locAction :: String -> (String -> Int -> Int -> a) -> [String] -> a
locAction _ action [file,_,line,col] = action file (read line) (read col)
locAction _ action [file, line,col] = action file (read line) (read col)
locAction cmd _ _ = throw $ InvalidCommandLine (Left cmd)
locAction' :: String -> (String -> Int -> Int -> Expression -> a) -> [String] -> a
locAction' _ action [f,_,line,col,expr] = action f (read line) (read col) (Expression expr)
locAction' _ action [f, line,col,expr] = action f (read line) (read col) (Expression expr)
locAction' cmd _ _ = throw $ InvalidCommandLine (Left cmd)
modulesArgSpec :: [OptDescr (Options -> Either [String] Options)]
modulesArgSpec =
[ option "d" ["detailed"] "Print package modules belong to." $
NoArg $ \o -> Right $ o { optDetailed = True }
]
hlintArgSpec :: [OptDescr (Options -> Either [String] Options)]
hlintArgSpec =
[ option "h" ["hlintOpt"] "Option to be passed to hlint" $
reqArg "hlintOpt" $ \h o -> Right $ o { optHlintOpts = h : optHlintOpts o }
]
browseArgSpec :: [OptDescr (Options -> Either [String] Options)]
browseArgSpec =
[ option "o" ["operators"] "Also print operators." $
NoArg $ \o -> Right $ o { optOperators = True }
, option "d" ["detailed"] "Print symbols with accompanying signature." $
NoArg $ \o -> Right $ o { optDetailed = True }
, option "q" ["qualified"] "Qualify symbols" $
NoArg $ \o -> Right $ o { optQualified = True }
]
nukeCaches :: IOish m => GhcModT m () nukeCaches :: IOish m => GhcModT m ()
nukeCaches = do nukeCaches = do
chdir <- liftIO $ (</> "cabal-helper") <$> getAppUserDataDirectory "ghc-mod" chdir <- liftIO $ (</> "cabal-helper") <$> getAppUserDataDirectory "ghc-mod"

201
src/GHCMod/Options.hs Normal file
View File

@ -0,0 +1,201 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
module GHCMod.Options (
parseArgs,
parseArgsInteractive,
GhcModCommands(..)
) where
import Options.Applicative
import Options.Applicative.Types
import Language.Haskell.GhcMod.Types
import Control.Arrow
import Data.Char (toUpper, toLower)
import Data.List (intercalate)
import Language.Haskell.GhcMod.Read
import GHCMod.Options.Commands
import GHCMod.Version
import GHCMod.Options.DocUtils
import GHCMod.Options.Help
import GHCMod.Options.ShellParse
parseArgs :: IO (Options, GhcModCommands)
parseArgs =
execParser opts
where
opts = info (argAndCmdSpec <**> helpVersion)
$$ fullDesc
<=> header "ghc-mod: Happy Haskell Programming"
parseArgsInteractive :: String -> Either String GhcModCommands
parseArgsInteractive args =
handle $ execParserPure (prefs idm) opts $ parseCmdLine args
where
opts = info interactiveCommandsSpec $$ fullDesc
handle (Success a) = Right a
handle (Failure failure) =
Left $ fst $ renderFailure failure ""
handle _ = Left "Completion invoked"
helpVersion :: Parser (a -> a)
helpVersion =
helper
<*> abortOption (InfoMsg ghcModVersion)
$$ long "version"
<=> help "Print the version of the program."
<*> argument r
$$ value id
<=> metavar ""
where
r :: ReadM (a -> a)
r = do
v <- readerAsk
case v of
"help" -> readerAbort ShowHelpText
"version" -> readerAbort $ InfoMsg ghcModVersion
_ -> return id
argAndCmdSpec :: Parser (Options, GhcModCommands)
argAndCmdSpec = (,) <$> globalArgSpec <*> commandsSpec
splitOn :: Eq a => a -> [a] -> ([a], [a])
splitOn c = second (drop 1) . break (==c)
logLevelParser :: Parser GmLogLevel
logLevelParser =
logLevelSwitch <*>
logLevelOption
<||> silentSwitch
where
logLevelOption =
option parseLL
$$ long "verbose"
<=> metavar "LEVEL"
<=> value GmWarning
<=> showDefaultWith showLL
<=> help' $$$ do
"Set log level ("
<> int' (fromEnum (minBound :: GmLogLevel))
<> "-"
<> int' (fromEnum (maxBound :: GmLogLevel))
<> ")"
"You can also use strings (case-insensitive):"
para'
$ intercalate ", "
$ map showLL ([minBound..maxBound] :: [GmLogLevel])
logLevelSwitch =
repeatAp succ' . length <$> many $$ flag' ()
$$ short 'v'
<=> help "Increase log level"
silentSwitch = flag' GmSilent
$$ long "silent"
<=> short 's'
<=> help "Be silent, set log level to 'silent'"
showLL = drop 2 . map toLower . show
repeatAp f n = foldr (.) id (replicate n f)
succ' x | x == maxBound = x
| otherwise = succ x
parseLL = do
v <- readerAsk
let
il'= toEnum . min maxBound <$> readMaybe v
ll' = readMaybe ("Gm" ++ capFirst v)
maybe (readerError $ "Not a log level \"" ++ v ++ "\"") return $ ll' <|> il'
capFirst (h:t) = toUpper h : map toLower t
capFirst [] = []
outputOptsSpec :: Parser OutputOpts
outputOptsSpec = OutputOpts
<$> logLevelParser
<*> flag PlainStyle LispStyle
$$ long "tolisp"
<=> short 'l'
<=> help "Format output as an S-Expression"
<*> LineSeparator <$$> strOption
$$ long "boundary"
<=> long "line-separator"
<=> short 'b'
<=> metavar "SEP"
<=> value "\0"
<=> showDefault
<=> help "Output line separator"
<*> optional $$ splitOn ',' <$$> strOption
$$ long "line-prefix"
<=> metavar "OUT,ERR"
<=> help "Output prefixes"
programsArgSpec :: Parser Programs
programsArgSpec = Programs
<$> strOption
$$ long "with-ghc"
<=> value "ghc"
<=> showDefault
<=> help "GHC executable to use"
<*> strOption
$$ long "with-ghc-pkg"
<=> value "ghc-pkg"
<=> showDefault
<=> help "ghc-pkg executable to use (only needed when guessing from GHC path fails)"
<*> strOption
$$ long "with-cabal"
<=> value "cabal"
<=> showDefault
<=> help "cabal-install executable to use"
<*> strOption
$$ long "with-stack"
<=> value "stack"
<=> showDefault
<=> help "stack executable to use"
globalArgSpec :: Parser Options
globalArgSpec = Options
<$> outputOptsSpec
<*> programsArgSpec
<*> many $$ strOption
$$ long "ghcOpt"
<=> long "ghc-option"
<=> short 'g'
<=> metavar "OPT"
<=> help "Option to be passed to GHC"
<*> many fileMappingSpec
where
fileMappingSpec =
getFileMapping . splitOn '=' <$> strOption
$$ long "map-file"
<=> metavar "MAPPING"
<=> fileMappingHelp
fileMappingHelp = help' $ do
"Redirect one file to another"
"--map-file \"file1.hs=file2.hs\""
indent 4 $ do
"can be used to tell ghc-mod"
\\ "that it should take source code"
\\ "for `file1.hs` from `file2.hs`."
"`file1.hs` can be either full path,"
\\ "or path relative to project root."
"`file2.hs` has to be either relative to project root,"
\\ "or full path (preferred)"
"--map-file \"file.hs\""
indent 4 $ do
"can be used to tell ghc-mod that it should take"
\\ "source code for `file.hs` from stdin. File end"
\\ "marker is `\\n\\EOT\\n`, i.e. `\\x0A\\x04\\x0A`."
\\ "`file.hs` may or may not exist, and should be"
\\ "either full path, or relative to project root."
getFileMapping = second (\i -> if null i then Nothing else Just i)

View File

@ -0,0 +1,293 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE OverloadedStrings #-}
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
module GHCMod.Options.Commands where
import Options.Applicative
import Options.Applicative.Types
import Options.Applicative.Builder.Internal
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Read
import GHCMod.Options.DocUtils
import GHCMod.Options.Help
type Symbol = String
type Expr = String
type Module = String
type Line = Int
type Col = Int
type Point = (Line, Col)
data GhcModCommands =
CmdLang
| CmdFlag
| CmdDebug
| CmdBoot
| CmdNukeCaches
| CmdRoot
| CmdLegacyInteractive
| CmdModules Bool
| CmdDumpSym FilePath
| CmdFind Symbol
| CmdDoc Module
| CmdLint LintOpts FilePath
| CmdBrowse BrowseOpts [Module]
| CmdDebugComponent [String]
| CmdCheck [FilePath]
| CmdExpand [FilePath]
| CmdInfo FilePath Symbol
| CmdType FilePath Point
| CmdSplit FilePath Point
| CmdSig FilePath Point
| CmdAuto FilePath Point
| CmdRefine FilePath Point Expr
| CmdTest FilePath
-- interactive-only commands
| CmdMapFile FilePath
| CmdUnmapFile FilePath
| CmdQuit
deriving (Show)
commandsSpec :: Parser GhcModCommands
commandsSpec =
hsubparser commands
commands :: Mod CommandFields GhcModCommands
commands =
command "lang"
$$ info (pure CmdLang)
$$ progDesc "List all known GHC language extensions"
<> command "flag"
$$ info (pure CmdFlag)
$$ progDesc "List GHC -f<foo> flags"
<> command "debug"
$$ info (pure CmdDebug)
$$ progDesc' $$$ do
"Print debugging information. Please include"
\\ "the output in any bug reports you submit"
<> command "debug-component"
$$ info debugComponentArgSpec
$$ progDesc' $$$ do
"Debugging information related to cabal component"
\\ "resolution"
<> command "boot"
$$ info (pure CmdBoot)
$$ progDesc "Internal command used by the emacs frontend"
-- <> command "nuke-caches"
-- $$ info (pure CmdNukeCaches) idm
<> command "root"
$$ info (pure CmdRoot)
$$ progDesc'
"Try to find the project directory."
<=> desc $$$ do
"For Cabal projects this is the"
\\ "directory containing the cabal file, for projects"
\\ "that use a cabal sandbox but have no cabal file"
\\ "this is the directory containing the cabal.sandbox.config"
\\ "file and otherwise this is the current directory"
<> command "legacy-interactive"
$$ info legacyInteractiveArgSpec
$$ progDesc "ghc-modi compatibility mode"
<> command "list"
$$ info modulesArgSpec
$$ progDesc "List all visible modules"
<> command "modules"
$$ info modulesArgSpec
$$ progDesc "List all visible modules"
<> command "dumpsym"
$$ info dumpSymArgSpec idm
<> command "find"
$$ info findArgSpec
$$ progDesc "List all modules that define SYMBOL"
<> command "doc"
$$ info docArgSpec
$$ progDesc' $$$ do
"Try finding the html documentation directory"
\\ "for the given MODULE"
<> command "lint"
$$ info lintArgSpec
$$ progDesc "Check files using `hlint'"
<> command "browse"
$$ info browseArgSpec
$$ progDesc "List symbols in a module"
<> command "check"
$$ info checkArgSpec
$$ progDesc' $$$ do
"Load the given files using GHC and report errors/warnings,"
\\ "but don't produce output files"
<> command "expand"
$$ info expandArgSpec
$$ progDesc "Like `check' but also pass `-ddump-splices' to GHC"
<> command "info"
$$ info infoArgSpec
$$ progDesc' $$$ do
"Look up an identifier in the context"
\\ "of FILE (like ghci's `:info')"
<> command "type"
$$ info typeArgSpec
$$ progDesc "Get the type of the expression under (LINE,COL)"
<> command "split"
$$ info splitArgSpec
$$ progDesc
"Split a function case by examining a type's constructors"
<=> desc $$$ do
"For example given the following code snippet:"
code $ do
"f :: [a] -> a"
"f x = _body"
"would be replaced by:"
code $ do
"f :: [a] -> a"
"f [] = _body"
"f (x:xs) = _body"
"(See https://github.com/kazu-yamamoto/ghc-mod/pull/274)"
<> command "sig"
$$ info sigArgSpec
$$ progDesc "Generate initial code given a signature"
<=> desc $$$ do
"For example when (LINE,COL) is on the"
\\ "signature in the following code snippet:"
code "func :: [a] -> Maybe b -> (a -> b) -> (a,b)"
"ghc-mod would add the following on the next line:"
code "func x y z f = _func_body"
"(See: https://github.com/kazu-yamamoto/ghc-mod/pull/274)"
<> command "auto"
$$ info autoArgSpec
$$ progDesc "Try to automatically fill the contents of a hole"
<> command "refine"
$$ info refineArgSpec
$$ progDesc "Refine the typed hole at (LINE,COL) given EXPR"
<=> desc $$$ do
"For example if EXPR is `filter', which has type"
\\ "`(a -> Bool) -> [a] -> [a]' and (LINE,COL) is on"
\\ " the hole `_body' in the following code snippet:"
code $ do
"filterNothing :: [Maybe a] -> [a]"
"filterNothing xs = _body"
"ghc-mod changes the code to get a value of type"
\\ " `[a]', which results in:"
code "filterNothing xs = filter _body_1 _body_2"
"(See also: https://github.com/kazu-yamamoto/ghc-mod/issues/311)"
<> command "test"
$$ info (CmdTest <$> strArg "FILE")
$$ progDesc ""
interactiveCommandsSpec :: Parser GhcModCommands
interactiveCommandsSpec =
hsubparser'
$ commands
<> command "map-file"
$$ info mapArgSpec
$$ progDesc "tells ghc-modi to read `file.hs` source from stdin"
<=> desc $$$ do
"Works the same as second form of"
\\ "`--map-file` CLI option."
<> command "unmap-file"
$$ info unmapArgSpec
$$ progDesc' $$$ do
"unloads previously mapped file,"
\\ "so that it's no longer mapped."
<=> desc $$$ do
"`file.hs` can be full path or relative"
\\ "to project root, either will work."
<> command "quit"
$$ info (pure CmdQuit)
$$ progDesc "Exit interactive mode"
<> command ""
$$ info (pure CmdQuit) idm
strArg :: String -> Parser String
strArg = argument str . metavar
filesArgsSpec :: ([String] -> b) -> Parser b
filesArgsSpec x = x <$> some (strArg "FILES..")
locArgSpec :: (String -> (Int, Int) -> b) -> Parser b
locArgSpec x = x
<$> strArg "FILE"
<*> ( (,)
<$> argument int (metavar "LINE")
<*> argument int (metavar "COL")
)
modulesArgSpec, dumpSymArgSpec, docArgSpec, findArgSpec,
lintArgSpec, browseArgSpec, checkArgSpec, expandArgSpec,
infoArgSpec, typeArgSpec, autoArgSpec, splitArgSpec,
sigArgSpec, refineArgSpec, debugComponentArgSpec,
mapArgSpec, unmapArgSpec, legacyInteractiveArgSpec :: Parser GhcModCommands
modulesArgSpec = CmdModules
<$> switch
$$ long "detailed"
<=> short 'd'
<=> help "Print package modules belong to"
dumpSymArgSpec = CmdDumpSym <$> strArg "TMPDIR"
findArgSpec = CmdFind <$> strArg "SYMBOL"
docArgSpec = CmdDoc <$> strArg "MODULE"
lintArgSpec = CmdLint
<$> LintOpts <$$> many $$ strOption
$$ long "hlintOpt"
<=> short 'h'
<=> help "Option to be passed to hlint"
<*> strArg "FILE"
browseArgSpec = CmdBrowse
<$> (BrowseOpts
<$> switch
$$ long "operators"
<=> short 'o'
<=> help "Also print operators"
<*> switch
$$ long "detailed"
<=> short 'd'
<=> help "Print symbols with accompanying signature"
<*> switch
$$ long "qualified"
<=> short 'q'
<=> help "Qualify symbols"
)
<*> some (strArg "MODULE")
debugComponentArgSpec = filesArgsSpec CmdDebugComponent
checkArgSpec = filesArgsSpec CmdCheck
expandArgSpec = filesArgsSpec CmdExpand
infoArgSpec = CmdInfo
<$> strArg "FILE"
<*> strArg "SYMBOL"
typeArgSpec = locArgSpec CmdType
autoArgSpec = locArgSpec CmdAuto
splitArgSpec = locArgSpec CmdSplit
sigArgSpec = locArgSpec CmdSig
refineArgSpec = locArgSpec CmdRefine <*> strArg "SYMBOL"
mapArgSpec = CmdMapFile <$> strArg "FILE"
unmapArgSpec = CmdUnmapFile <$> strArg "FILE"
legacyInteractiveArgSpec = const CmdLegacyInteractive <$>
optional interactiveCommandsSpec
hsubparser' :: Mod CommandFields a -> Parser a
hsubparser' m = mkParser d g rdr
where
Mod _ d g = m `mappend` metavar ""
(cmds, subs) = mkCommand m
rdr = CmdReader cmds (fmap add_helper . subs)
add_helper pinfo = pinfo
{ infoParser = infoParser pinfo <**> helper }
int :: ReadM Int
int = do
v <- readerAsk
maybe (readerError $ "Not a number \"" ++ v ++ "\"") return $ readMaybe v

View File

@ -0,0 +1,48 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
module GHCMod.Options.DocUtils (
($$),
($$$),
(<=>),
(<$$>),
(<||>)
) where
import Options.Applicative
import Data.Monoid
import Prelude
infixl 6 <||>
infixr 7 <$$>
infixr 7 $$
infixr 8 <=>
infixr 9 $$$
($$) :: (a -> b) -> a -> b
($$) = ($)
($$$) :: (a -> b) -> a -> b
($$$) = ($)
(<||>) :: Alternative a => a b -> a b -> a b
(<||>) = (<|>)
(<=>) :: Monoid m => m -> m -> m
(<=>) = (<>)
(<$$>) :: Functor f => (a -> b) -> f a -> f b
(<$$>) = (<$>)

View File

@ -0,0 +1,79 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE OverloadedStrings, FlexibleInstances, GeneralizedNewtypeDeriving #-}
module GHCMod.Options.Help where
import Options.Applicative
import Options.Applicative.Help.Pretty (Doc)
import qualified Options.Applicative.Help.Pretty as PP
import Control.Monad.State
import GHC.Exts( IsString(..) )
import Data.Maybe
import Data.Monoid
import Prelude
newtype MyDocM s a = MyDoc {unwrapState :: State s a}
deriving (Monad, Functor, Applicative, MonadState s)
type MyDoc = MyDocM (Maybe Doc) ()
instance IsString (MyDocM (Maybe Doc) a) where
fromString = append . para
instance Monoid (MyDocM (Maybe Doc) ()) where
mappend a b = append $ doc a <> doc b
mempty = append PP.empty
para :: String -> Doc
para = PP.fillSep . map PP.text . words
append :: Doc -> MyDocM (Maybe Doc) a
append s = modify m >> return undefined
where
m :: Maybe Doc -> Maybe Doc
m Nothing = Just s
m (Just old) = Just $ old PP..$. s
infixr 7 \\
(\\) :: MyDoc -> MyDoc -> MyDoc
(\\) a b = append $ doc a PP.<+> doc b
doc :: MyDoc -> Doc
doc = fromMaybe PP.empty . flip execState Nothing . unwrapState
help' :: MyDoc -> Mod f a
help' = helpDoc . Just . doc
desc :: MyDoc -> InfoMod a
desc = footerDoc . Just . doc . indent 2
code :: MyDoc -> MyDoc
code x = do
_ <- " "
indent 4 x
" "
progDesc' :: MyDoc -> InfoMod a
progDesc' = progDescDoc . Just . doc
indent :: Int -> MyDoc -> MyDoc
indent n = append . PP.indent n . doc
int' :: Int -> MyDoc
int' = append . PP.int
para' :: String -> MyDoc
para' = append . para

View File

@ -0,0 +1,44 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
module GHCMod.Options.ShellParse (parseCmdLine) where
import Data.Char
import Data.List
go :: String -> String -> [String] -> Bool -> [String]
-- result
go [] curarg accargs _ = reverse $ reverse curarg : accargs
go (c:cl) curarg accargs quotes
-- open quotes
| c == '\STX', not quotes
= go cl curarg accargs True
-- close quotes
| c == '\ETX', quotes
= go cl curarg accargs False
-- space separates arguments outside quotes
| isSpace c, not quotes
= if null curarg
then go cl curarg accargs quotes
else go cl [] (reverse curarg : accargs) quotes
-- general character
| otherwise = go cl (c:curarg) accargs quotes
parseCmdLine :: String -> [String]
parseCmdLine comline'
| Just comline <- stripPrefix "ascii-escape " $ dropWhile isSpace comline'
= go (dropWhile isSpace comline) [] [] False
parseCmdLine [] = [""]
parseCmdLine comline = words comline

32
src/GHCMod/Version.hs Normal file
View File

@ -0,0 +1,32 @@
-- ghc-mod: Making Haskell development *more* fun
-- Copyright (C) 2015 Nikolay Yakimov <root@livid.pp.ru>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Affero General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU Affero General Public License for more details.
--
-- You should have received a copy of the GNU Affero General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
module GHCMod.Version where
import Paths_ghc_mod
import Data.Version (showVersion)
import Config (cProjectVersion)
progVersion :: String -> String
progVersion pf =
"ghc-mod"++pf++" version " ++ showVersion version ++ " compiled by GHC "
++ cProjectVersion
ghcModVersion :: String
ghcModVersion = progVersion ""
ghcModiVersion :: String
ghcModiVersion = progVersion "i"

View File

@ -1,4 +1,4 @@
{-# LANGUAGE ScopedTypeVariables, DeriveDataTypeable #-} {-# LANGUAGE ScopedTypeVariables #-}
-- | WARNING -- | WARNING
-- This program is deprecated, use `ghc-mod legacy-interactive` instead. -- This program is deprecated, use `ghc-mod legacy-interactive` instead.

View File

@ -1,48 +0,0 @@
{-# LANGUAGE DeriveDataTypeable, CPP #-}
module Misc (
SymDbReq
, newSymDbReq
, getDb
, checkDb
) where
import Control.Concurrent.Async (Async, async, wait)
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
import Prelude
import Language.Haskell.GhcMod
import Language.Haskell.GhcMod.Internal hiding (MonadIO,liftIO)
import Language.Haskell.GhcMod.Types
import Language.Haskell.GhcMod.Monad
----------------------------------------------------------------
type SymDbReqAction = (Either GhcModError SymbolDb, GhcModLog)
data SymDbReq = SymDbReq (IORef (Async SymDbReqAction)) (IO SymDbReqAction)
newSymDbReq :: Options -> GhcModOut -> FilePath -> IO SymDbReq
newSymDbReq opt gmo tmpdir = do
let act = runGmOutT' gmo $ runGhcModT opt $ loadSymbolDb tmpdir
req <- async act
ref <- newIORef req
return $ SymDbReq ref act
getDb :: IOish m => SymDbReq -> GhcModT m SymbolDb
getDb (SymDbReq ref _) = do
req <- liftIO $ readIORef ref
-- 'wait' really waits for the asynchronous action at the fist time.
-- Then it reads a cached value from the second time.
hoistGhcModT =<< liftIO (wait req)
checkDb :: IOish m => SymDbReq -> SymbolDb -> GhcModT m SymbolDb
checkDb (SymDbReq ref act) db = do
outdated <- isOutdated db
if outdated then do
-- async and wait here is unnecessary because this is essentially
-- synchronous. But Async can be used a cache.
req <- liftIO $ async act
liftIO $ writeIORef ref req
hoistGhcModT =<< liftIO (wait req)
else
return db

View File

@ -2,5 +2,5 @@ flags: {}
packages: packages:
- '.' - '.'
extra-deps: extra-deps:
- cabal-helper-0.6.0.0 - cabal-helper-0.6.1.0
resolver: lts-3.1 resolver: lts-3.1

View File

@ -12,23 +12,23 @@ spec :: Spec
spec = do spec = do
describe "browse Data.Map" $ do describe "browse Data.Map" $ do
it "contains at least `differenceWithKey'" $ do it "contains at least `differenceWithKey'" $ do
syms <- runD $ lines <$> browse "Data.Map" syms <- runD $ lines <$> browse defaultBrowseOpts "Data.Map"
syms `shouldContain` ["differenceWithKey"] syms `shouldContain` ["differenceWithKey"]
describe "browse -d Data.Either" $ do describe "browse -d Data.Either" $ do
it "contains functions (e.g. `either') including their type signature" $ do it "contains functions (e.g. `either') including their type signature" $ do
syms <- run defaultOptions { optDetailed = True } syms <- runD
$ lines <$> browse "Data.Either" $ lines <$> browse defaultBrowseOpts{ optBrowseDetailed = True } "Data.Either"
syms `shouldContain` ["either :: (a -> c) -> (b -> c) -> Either a b -> c"] syms `shouldContain` ["either :: (a -> c) -> (b -> c) -> Either a b -> c"]
it "contains type constructors (e.g. `Left') including their type signature" $ do it "contains type constructors (e.g. `Left') including their type signature" $ do
syms <- run defaultOptions { optDetailed = True} syms <- runD
$ lines <$> browse "Data.Either" $ lines <$> browse defaultBrowseOpts{ optBrowseDetailed = True } "Data.Either"
syms `shouldContain` ["Left :: a -> Either a b"] syms `shouldContain` ["Left :: a -> Either a b"]
describe "`browse' in a project directory" $ do describe "`browse' in a project directory" $ do
it "can list symbols defined in a a local module" $ do it "can list symbols defined in a a local module" $ do
withDirectory_ "test/data/ghc-mod-check/" $ do withDirectory_ "test/data/ghc-mod-check/" $ do
syms <- runD $ lines <$> browse "Data.Foo" syms <- runD $ lines <$> browse defaultBrowseOpts "Data.Foo"
syms `shouldContain` ["foo"] syms `shouldContain` ["foo"]
syms `shouldContain` ["fibonacci"] syms `shouldContain` ["fibonacci"]

View File

@ -1,3 +1,4 @@
{-# LANGUAGE CPP #-}
module CabalHelperSpec where module CabalHelperSpec where
import Control.Arrow import Control.Arrow
@ -57,11 +58,13 @@ spec = do
then forM_ opts (\o -> o `shouldContain` ["-no-user-package-conf","-package-conf", cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir bp]) then forM_ opts (\o -> o `shouldContain` ["-no-user-package-conf","-package-conf", cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir bp])
else forM_ opts (\o -> o `shouldContain` ["-no-user-package-db","-package-db",cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir bp]) else forM_ opts (\o -> o `shouldContain` ["-no-user-package-db","-package-db",cwd </> "test/data/cabal-project/.cabal-sandbox/"++ghcSandboxPkgDbDir bp])
#if !MIN_VERSION_ghc(7,8,0)
it "handles stack project" $ do it "handles stack project" $ do
let tdir = "test/data/stack-project" let tdir = "test/data/stack-project"
[ghcOpts] <- map gmcGhcOpts . filter ((==ChExeName "new-template-exe") . gmcName) <$> runD' tdir getComponents [ghcOpts] <- map gmcGhcOpts . filter ((==ChExeName "new-template-exe") . gmcName) <$> runD' tdir getComponents
let pkgs = pkgOptions ghcOpts let pkgs = pkgOptions ghcOpts
sort pkgs `shouldBe` ["base", "bytestring"] sort pkgs `shouldBe` ["base", "bytestring"]
#endif
it "extracts build dependencies" $ do it "extracts build dependencies" $ do
let tdir = "test/data/cabal-project" let tdir = "test/data/cabal-project"
@ -70,12 +73,25 @@ spec = do
pkgs = pkgOptions ghcOpts pkgs = pkgOptions ghcOpts
pkgs `shouldBe` ["Cabal","base","template-haskell"] pkgs `shouldBe` ["Cabal","base","template-haskell"]
it "uses non default flags" $ do it "uses non default flags and preserves them across reconfigures" $ do
let tdir = "test/data/cabal-flags" let tdir = "test/data/cabal-flags"
_ <- withDirectory_ tdir $ _ <- withDirectory_ tdir $
readProcess "cabal" ["configure", "-ftest-flag"] "" readProcess "cabal" ["configure", "-ftest-flag"] ""
let test = do
opts <- map gmcGhcOpts <$> runD' tdir getComponents opts <- map gmcGhcOpts <$> runD' tdir getComponents
let ghcOpts = head opts let ghcOpts = head opts
pkgs = pkgOptions ghcOpts pkgs = pkgOptions ghcOpts
pkgs `shouldBe` ["Cabal","base"] pkgs `shouldBe` ["Cabal","base"]
test
touch $ tdir </> "cabal-flags.cabal"
test
touch :: FilePath -> IO ()
touch fn = do
f <- readFile fn
writeFile (fn <.> "tmp") f
renameFile (fn <.> "tmp") fn

View File

@ -8,7 +8,6 @@ import System.Directory (canonicalizePath)
import System.FilePath (pathSeparator) import System.FilePath (pathSeparator)
import Test.Hspec import Test.Hspec
import TestUtils import TestUtils
import Prelude
import Dir import Dir
@ -37,14 +36,14 @@ spec = do
it "returns the current directory" $ do it "returns the current directory" $ do
withDirectory_ "/" $ do withDirectory_ "/" $ do
curDir <- stripLastDot <$> canonicalizePath "/" curDir <- stripLastDot <$> canonicalizePath "/"
res <- clean_ $ runGmOutDef findCradle res <- clean_ $ runGmOutDef findCradleNoLog
cradleCurrentDir res `shouldBe` curDir cradleCurrentDir res `shouldBe` curDir
cradleRootDir res `shouldBe` curDir cradleRootDir res `shouldBe` curDir
cradleCabalFile res `shouldBe` Nothing cradleCabalFile res `shouldBe` Nothing
it "finds a cabal file and a sandbox" $ do it "finds a cabal file and a sandbox" $ do
withDirectory "test/data/cabal-project/subdir1/subdir2" $ \dir -> do withDirectory "test/data/cabal-project/subdir1/subdir2" $ \dir -> do
res <- relativeCradle dir <$> clean_ (runGmOutDef findCradle) res <- relativeCradle dir <$> clean_ (runGmOutDef findCradleNoLog)
cradleCurrentDir res `shouldBe` cradleCurrentDir res `shouldBe`
"test/data/cabal-project/subdir1/subdir2" "test/data/cabal-project/subdir1/subdir2"
@ -56,7 +55,7 @@ spec = do
it "works even if a sandbox config file is broken" $ do it "works even if a sandbox config file is broken" $ do
withDirectory "test/data/broken-sandbox" $ \dir -> do withDirectory "test/data/broken-sandbox" $ \dir -> do
res <- relativeCradle dir <$> clean_ (runGmOutDef findCradle) res <- relativeCradle dir <$> clean_ (runGmOutDef findCradleNoLog)
cradleCurrentDir res `shouldBe` cradleCurrentDir res `shouldBe`
"test" </> "data" </> "broken-sandbox" "test" </> "data" </> "broken-sandbox"

View File

@ -122,13 +122,13 @@ spec = do
withDirectory_ "test/data/file-mapping" $ do withDirectory_ "test/data/file-mapping" $ do
res <- runD $ do res <- runD $ do
loadMappedFile "File.hs" "File_Redir_Lint.hs" loadMappedFile "File.hs" "File_Redir_Lint.hs"
lint "File.hs" lint defaultLintOpts "File.hs"
res `shouldBe` "File.hs:4:1: Error: Eta reduce\NULFound:\NUL func a b = (*) a b\NULWhy not:\NUL func = (*)\n" res `shouldBe` "File.hs:4:1: Error: Eta reduce\NULFound:\NUL func a b = (*) a b\NULWhy not:\NUL func = (*)\n"
it "lints in-memory file if one is specified and outputs original filename" $ do it "lints in-memory file if one is specified and outputs original filename" $ do
withDirectory_ "test/data/file-mapping" $ do withDirectory_ "test/data/file-mapping" $ do
res <- runD $ do res <- runD $ do
loadMappedFileSource "File.hs" "func a b = (++) a b\n" loadMappedFileSource "File.hs" "func a b = (++) a b\n"
lint "File.hs" lint defaultLintOpts "File.hs"
res `shouldBe` "File.hs:1:1: Error: Eta reduce\NULFound:\NUL func a b = (++) a b\NULWhy not:\NUL func = (++)\n" res `shouldBe` "File.hs:1:1: Error: Eta reduce\NULFound:\NUL func a b = (++) a b\NULWhy not:\NUL func = (++)\n"
it "shows types of the expression for redirected files" $ do it "shows types of the expression for redirected files" $ do
let tdir = "test/data/file-mapping" let tdir = "test/data/file-mapping"
@ -163,6 +163,14 @@ spec = do
mapM_ (uncurry loadMappedFile) fm mapM_ (uncurry loadMappedFile) fm
checkSyntax ["File.hs"] checkSyntax ["File.hs"]
res `shouldBe` "File.hs:3:1:Warning: Top-level binding with no type signature: main :: IO ()\n" res `shouldBe` "File.hs:3:1:Warning: Top-level binding with no type signature: main :: IO ()\n"
it "works with full path as well" $ do
withDirectory_ "test/data/file-mapping/preprocessor" $ do
cwd <- getCurrentDirectory
let fm = [("File.hs", cwd </> "File_Redir.hs")]
res <- run defaultOptions $ do
mapM_ (uncurry loadMappedFile) fm
checkSyntax ["File.hs"]
res `shouldBe` "File.hs:3:1:Warning: Top-level binding with no type signature: main :: IO ()\n"
it "checks in-memory file" $ do it "checks in-memory file" $ do
withDirectory_ "test/data/file-mapping/preprocessor" $ do withDirectory_ "test/data/file-mapping/preprocessor" $ do
src <- readFile "File_Redir.hs" src <- readFile "File_Redir.hs"
@ -175,14 +183,14 @@ spec = do
withDirectory_ "test/data/file-mapping/preprocessor" $ do withDirectory_ "test/data/file-mapping/preprocessor" $ do
res <- runD $ do res <- runD $ do
loadMappedFile "File.hs" "File_Redir_Lint.hs" loadMappedFile "File.hs" "File_Redir_Lint.hs"
lint "File.hs" lint defaultLintOpts "File.hs"
res `shouldBe` "File.hs:6:1: Error: Eta reduce\NULFound:\NUL func a b = (*) a b\NULWhy not:\NUL func = (*)\n" res `shouldBe` "File.hs:6:1: Error: Eta reduce\NULFound:\NUL func a b = (*) a b\NULWhy not:\NUL func = (*)\n"
it "lints in-memory file if one is specified and outputs original filename" $ do it "lints in-memory file if one is specified and outputs original filename" $ do
withDirectory_ "test/data/file-mapping/preprocessor" $ do withDirectory_ "test/data/file-mapping/preprocessor" $ do
src <- readFile "File_Redir_Lint.hs" src <- readFile "File_Redir_Lint.hs"
res <- runD $ do res <- runD $ do
loadMappedFileSource "File.hs" src loadMappedFileSource "File.hs" src
lint "File.hs" lint defaultLintOpts "File.hs"
res `shouldBe` "File.hs:6:1: Error: Eta reduce\NULFound:\NUL func a b = (*) a b\NULWhy not:\NUL func = (*)\n" res `shouldBe` "File.hs:6:1: Error: Eta reduce\NULFound:\NUL func a b = (*) a b\NULWhy not:\NUL func = (*)\n"
describe "literate haskell tests" $ do describe "literate haskell tests" $ do
it "checks redirected file if one is specified and outputs original filename" $ do it "checks redirected file if one is specified and outputs original filename" $ do

View File

@ -8,10 +8,10 @@ spec :: Spec
spec = do spec = do
describe "lint" $ do describe "lint" $ do
it "can detect a redundant import" $ do it "can detect a redundant import" $ do
res <- runD $ lint "test/data/hlint/hlint.hs" res <- runD $ lint defaultLintOpts "test/data/hlint/hlint.hs"
res `shouldBe` "test/data/hlint/hlint.hs:4:8: Error: Redundant do\NULFound:\NUL do putStrLn \"Hello, world!\"\NULWhy not:\NUL putStrLn \"Hello, world!\"\n" res `shouldBe` "test/data/hlint/hlint.hs:4:8: Error: Redundant do\NULFound:\NUL do putStrLn \"Hello, world!\"\NULWhy not:\NUL putStrLn \"Hello, world!\"\n"
context "when no suggestions are given" $ do context "when no suggestions are given" $ do
it "doesn't output an empty line" $ do it "doesn't output an empty line" $ do
res <- runD $ lint "test/data/ghc-mod-check/lib/Data/Foo.hs" res <- runD $ lint defaultLintOpts "test/data/ghc-mod-check/lib/Data/Foo.hs"
res `shouldBe` "" res `shouldBe` ""

View File

@ -10,5 +10,5 @@ spec :: Spec
spec = do spec = do
describe "modules" $ do describe "modules" $ do
it "contains at least `Data.Map'" $ do it "contains at least `Data.Map'" $ do
mdls <- runD $ lines <$> modules mdls <- runD $ lines <$> modules False
mdls `shouldContain` ["Data.Map"] mdls `shouldContain` ["Data.Map"]

View File

@ -3,6 +3,8 @@ module MonadSpec where
import Test.Hspec import Test.Hspec
import TestUtils import TestUtils
import Control.Monad.Error.Class import Control.Monad.Error.Class
import Control.Concurrent
import Control.Exception
spec :: Spec spec :: Spec
spec = do spec = do
@ -15,3 +17,21 @@ spec = do
return "hello" return "hello"
`catchError` (const $ fail "oh noes") `catchError` (const $ fail "oh noes")
a `shouldBe` (Left $ GMEString "oh noes") a `shouldBe` (Left $ GMEString "oh noes")
describe "runGhcModT" $
it "throws an exception when run in multiple threads" $ do
mv1 :: MVar (Either SomeException ())
<- newEmptyMVar
mv2 :: MVar (Either SomeException ())
<- newEmptyMVar
_ <- forkOS $ putMVar mv1 =<< (try $ evaluate =<< (runD $ liftIO $ readMVar mv2 >> return ()))
_ <- forkOS $ putMVar mv2 =<< (try $ evaluate =<< (runD $ return ()))
e1 <- takeMVar mv1
e2 <- takeMVar mv2
(isLeft e1 || isLeft e2) `shouldBe` True
isLeft :: Either a b -> Bool
isLeft (Right _) = False
isLeft (Left _) = True

34
test/ShellParseSpec.hs Normal file
View File

@ -0,0 +1,34 @@
module ShellParseSpec where
import GHCMod.Options.ShellParse
import Test.Hspec
spec :: Spec
spec =
describe "parseCmdLine" $ do
it "splits arguments" $ do
parseCmdLine "test command line" `shouldBe` ["test", "command", "line"]
parseCmdLine "ascii-escape test command line" `shouldBe` ["test", "command", "line"]
it "honors quoted segments if turned on" $
parseCmdLine "ascii-escape test command line \STXwith quoted segment\ETX"
`shouldBe` ["test", "command", "line", "with quoted segment"]
it "doesn't honor quoted segments if turned off" $
parseCmdLine "test command line \STXwith quoted segment\ETX"
`shouldBe` words "test command line \STXwith quoted segment\ETX"
it "squashes multiple spaces" $ do
parseCmdLine "test command"
`shouldBe` ["test", "command"]
parseCmdLine "ascii-escape test command"
`shouldBe` ["test", "command"]
it "ingores leading spaces" $ do
parseCmdLine " test command"
`shouldBe` ["test", "command"]
parseCmdLine " ascii-escape test command"
`shouldBe` ["test", "command"]
it "parses empty string as no argument" $ do
parseCmdLine ""
`shouldBe` [""]
parseCmdLine "ascii-escape "
`shouldBe` [""]

View File

@ -43,22 +43,9 @@ extract action = do
Right a -> return a Right a -> return a
Left e -> error $ show e Left e -> error $ show e
withSpecCradle :: (IOish m, GmOut m) => FilePath -> (Cradle -> m a) -> m a withSpecCradle :: (IOish m, GmOut m) => FilePath -> ((Cradle, GhcModLog) -> m a) -> m a
withSpecCradle cradledir f = do withSpecCradle cradledir f = do
gbracket (findSpecCradle cradledir) (liftIO . cleanupCradle) $ \crdl -> gbracket (runJournalT $ findSpecCradle cradledir) (liftIO . cleanupCradle . fst) f
bracketWorkingDirectory (cradleRootDir crdl) $
f crdl
bracketWorkingDirectory ::
(ExceptionMonad m, MonadIO m) => FilePath -> m c -> m c
bracketWorkingDirectory dir a =
gbracket (swapWorkingDirectory dir) (liftIO . setCurrentDirectory) (const a)
swapWorkingDirectory :: MonadIO m => FilePath -> m FilePath
swapWorkingDirectory ndir = liftIO $ do
odir <- getCurrentDirectory >>= canonicalizePath
setCurrentDirectory $ ndir
return odir
runGhcModTSpec :: Options -> GhcModT IO a -> IO (Either GhcModError a, GhcModLog) runGhcModTSpec :: Options -> GhcModT IO a -> IO (Either GhcModError a, GhcModLog)
runGhcModTSpec opt action = do runGhcModTSpec opt action = do
@ -69,7 +56,7 @@ runGhcModTSpec' :: IOish m
=> FilePath -> Options -> GhcModT m b -> m (Either GhcModError b, GhcModLog) => FilePath -> Options -> GhcModT m b -> m (Either GhcModError b, GhcModLog)
runGhcModTSpec' dir opt action = liftIO (canonicalizePath dir) >>= \dir' -> do runGhcModTSpec' dir opt action = liftIO (canonicalizePath dir) >>= \dir' -> do
runGmOutT opt $ runGmOutT opt $
withGhcModEnv' withSpecCradle dir' opt $ \env -> do withGhcModEnv' withSpecCradle dir' opt $ \(env,_) -> do
first (fst <$>) <$> runGhcModT' env defaultGhcModState first (fst <$>) <$> runGhcModT' env defaultGhcModState
(gmSetLogLevel (ooptLogLevel $ optOutput opt) >> action) (gmSetLogLevel (ooptLogLevel $ optOutput opt) >> action)

View File

@ -0,0 +1,37 @@
-- $ ghc -package ghc -package ghc-paths GhcTestcase.hs
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import GHC
import GHC.Paths (libdir)
import DynFlags
import System.Environment
main :: IO ()
main = do
args <- getArgs
defaultErrorHandler defaultFatalMessager defaultFlushOut $
runGhc (Just libdir) $
doStuff "Main.hs" "Main" args
doStuff :: String -> String -> [String] -> Ghc ()
doStuff targetFile targetModule args = do
dflags0 <- getSessionDynFlags
let dflags1 = dflags0 {
ghcMode = CompManager
, ghcLink = LinkInMemory
, hscTarget = HscInterpreted
, optLevel = 0
}
(dflags2, _, _) <- parseDynamicFlags dflags1 (map noLoc args)
_ <- setSessionDynFlags dflags2
target <- guessTarget targetFile Nothing
setTargets [target { targetAllowObjCode = True }]
_ <- load LoadAllTargets
setContext [IIModule $ mkModuleName targetModule]
return ()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
module Main where
import A
main = print foo

View File

@ -0,0 +1,12 @@
name: not-interpreted-error
version: 0.1.0.0
license-file: LICENSE
author: asdf
maintainer: asdf
build-type: Simple
cabal-version: >=1.10
executable main
main-is: Main.hs
build-depends: base
default-language: Haskell2010