2015-03-28 01:33:42 +00:00
|
|
|
module Language.Haskell.GhcMod.Debug (debugInfo, rootInfo, componentInfo) where
|
2013-03-04 02:21:41 +00:00
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
import Control.Arrow (first)
|
2014-03-27 06:23:27 +00:00
|
|
|
import Control.Applicative ((<$>))
|
2015-03-03 20:12:43 +00:00
|
|
|
import qualified Data.Map as Map
|
|
|
|
import qualified Data.Set as Set
|
2015-03-28 01:33:42 +00:00
|
|
|
import Data.Char
|
2015-03-03 20:12:43 +00:00
|
|
|
import Text.PrettyPrint
|
2014-05-11 22:40:00 +00:00
|
|
|
import Language.Haskell.GhcMod.Convert
|
2014-07-11 01:10:37 +00:00
|
|
|
import Language.Haskell.GhcMod.Monad
|
2013-05-17 01:00:01 +00:00
|
|
|
import Language.Haskell.GhcMod.Types
|
2014-07-12 01:30:06 +00:00
|
|
|
import Language.Haskell.GhcMod.Internal
|
2015-03-03 20:12:43 +00:00
|
|
|
import Language.Haskell.GhcMod.CabalHelper
|
|
|
|
import Language.Haskell.GhcMod.Target
|
|
|
|
import Language.Haskell.GhcMod.Pretty
|
2013-03-04 02:21:41 +00:00
|
|
|
|
|
|
|
----------------------------------------------------------------
|
|
|
|
|
2013-05-20 05:28:56 +00:00
|
|
|
-- | Obtaining debug information.
|
2014-07-12 09:16:16 +00:00
|
|
|
debugInfo :: IOish m => GhcModT m String
|
2015-03-03 20:12:43 +00:00
|
|
|
debugInfo = do
|
|
|
|
Options {..} <- options
|
|
|
|
Cradle {..} <- cradle
|
2014-03-20 07:21:48 +00:00
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
cabal <-
|
|
|
|
case cradleCabalFile of
|
|
|
|
Just _ -> cabalDebug
|
|
|
|
Nothing -> return []
|
|
|
|
|
|
|
|
return $ unlines $
|
|
|
|
[ "Root directory: " ++ cradleRootDir
|
|
|
|
, "Current directory: " ++ cradleCurrentDir
|
|
|
|
, "GHC System libraries: " ++ ghcLibDir
|
|
|
|
, "GHC user options: " ++ render (fsep $ map text ghcUserOptions)
|
|
|
|
] ++ cabal
|
|
|
|
|
|
|
|
cabalDebug :: IOish m => GhcModT m [String]
|
|
|
|
cabalDebug = do
|
2015-03-28 01:33:42 +00:00
|
|
|
crdl@Cradle {..} <- cradle
|
|
|
|
mcs <- resolveGmComponents Nothing =<< mapM (resolveEntrypoint crdl) =<< getComponents
|
2015-03-03 20:12:43 +00:00
|
|
|
let entrypoints = Map.map gmcEntrypoints mcs
|
|
|
|
graphs = Map.map gmcHomeModuleGraph mcs
|
|
|
|
opts = Map.map gmcGhcOpts mcs
|
|
|
|
srcOpts = Map.map gmcGhcSrcOpts mcs
|
|
|
|
|
|
|
|
return $
|
|
|
|
[ "Cabal file: " ++ show cradleCabalFile
|
|
|
|
, "Cabal entrypoints:\n" ++ render (nest 4 $
|
|
|
|
mapDoc gmComponentNameDoc smpDoc entrypoints)
|
|
|
|
, "Cabal components:\n" ++ render (nest 4 $
|
|
|
|
mapDoc gmComponentNameDoc graphDoc graphs)
|
|
|
|
, "GHC Cabal options:\n" ++ render (nest 4 $
|
|
|
|
mapDoc gmComponentNameDoc (fsep . map text) opts)
|
|
|
|
, "GHC search path options:\n" ++ render (nest 4 $
|
|
|
|
mapDoc gmComponentNameDoc (fsep . map text) srcOpts)
|
|
|
|
]
|
|
|
|
|
2015-03-28 01:33:42 +00:00
|
|
|
componentInfo :: IOish m => [String] -> GhcModT m String
|
|
|
|
componentInfo ts = do
|
2015-04-12 00:48:05 +00:00
|
|
|
-- TODO: most of this is copypasta of targetGhcOptions. Factor out more
|
|
|
|
-- useful function from there.
|
2015-03-28 01:33:42 +00:00
|
|
|
crdl <- cradle
|
2015-04-12 00:48:05 +00:00
|
|
|
let sefnmn = Set.fromList $ map guessModuleFile ts
|
|
|
|
comps <- mapM (resolveEntrypoint crdl) =<< getComponents
|
|
|
|
mcs <- resolveGmComponents Nothing comps
|
|
|
|
let
|
|
|
|
mdlcs = moduleComponents mcs `zipMap` Set.toList sefnmn
|
|
|
|
candidates = findCandidates $ map snd mdlcs
|
|
|
|
cn = pickComponent candidates
|
|
|
|
opts <- targetGhcOptions crdl sefnmn
|
2015-03-28 01:33:42 +00:00
|
|
|
|
|
|
|
return $ unlines $
|
2015-04-12 00:48:05 +00:00
|
|
|
[ "Matching Components:\n" ++ render (nest 4 $
|
|
|
|
alistDoc (either text mnDoc) (setDoc gmComponentNameDoc) mdlcs)
|
|
|
|
, "Picked Component:\n" ++ render (nest 4 $
|
|
|
|
gmComponentNameDoc cn)
|
|
|
|
, "GHC Cabal options:\n" ++ render (nest 4 $ fsep $ map text opts)
|
2015-03-28 01:33:42 +00:00
|
|
|
]
|
2015-04-12 00:48:05 +00:00
|
|
|
where
|
|
|
|
zipMap f l = l `zip` (f `map` l)
|
2015-03-28 01:33:42 +00:00
|
|
|
|
|
|
|
guessModuleFile :: String -> Either FilePath ModuleName
|
|
|
|
guessModuleFile mn@(h:r)
|
|
|
|
| isUpper h && all isAlphaNum r = Right $ mkModuleName mn
|
|
|
|
guessModuleFile str = Left str
|
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
graphDoc :: GmModuleGraph -> Doc
|
|
|
|
graphDoc GmModuleGraph{..} =
|
2015-04-12 00:48:05 +00:00
|
|
|
mapDoc mpDoc smpDoc' gmgGraph
|
2015-03-03 20:12:43 +00:00
|
|
|
where
|
|
|
|
smpDoc' smp = vcat $ map mpDoc' $ Set.toList smp
|
|
|
|
mpDoc' = text . moduleNameString . mpModule
|
|
|
|
|
2015-04-12 00:48:05 +00:00
|
|
|
setDoc :: (a -> Doc) -> Set.Set a -> Doc
|
|
|
|
setDoc f s = vcat $ map f $ Set.toList s
|
|
|
|
|
2015-03-03 20:12:43 +00:00
|
|
|
smpDoc :: Set.Set ModulePath -> Doc
|
2015-04-12 00:48:05 +00:00
|
|
|
smpDoc smp = setDoc mpDoc smp
|
2015-03-03 20:12:43 +00:00
|
|
|
|
|
|
|
mpDoc :: ModulePath -> Doc
|
|
|
|
mpDoc (ModulePath mn fn) = text (moduleNameString mn) <+> parens (text fn)
|
|
|
|
|
2015-04-12 00:48:05 +00:00
|
|
|
mnDoc :: ModuleName -> Doc
|
|
|
|
mnDoc mn = text (moduleNameString mn)
|
|
|
|
|
|
|
|
alistDoc :: Ord k => (k -> Doc) -> (a -> Doc) -> [(k, a)] -> Doc
|
|
|
|
alistDoc fk fa alist = mapDoc fk fa (Map.fromList alist)
|
2015-03-03 20:12:43 +00:00
|
|
|
|
|
|
|
mapDoc :: (k -> Doc) -> (a -> Doc) -> Map.Map k a -> Doc
|
|
|
|
mapDoc kd ad m = vcat $
|
|
|
|
map (uncurry ($+$)) $ map (first kd) $ Map.toList $ Map.map (nest 4 . ad) m
|
2014-03-20 07:21:48 +00:00
|
|
|
----------------------------------------------------------------
|
|
|
|
|
|
|
|
-- | Obtaining root information.
|
2014-07-12 09:16:16 +00:00
|
|
|
rootInfo :: IOish m => GhcModT m String
|
2014-07-11 01:10:37 +00:00
|
|
|
rootInfo = convert' =<< cradleRootDir <$> cradle
|