summaryrefslogtreecommitdiff
path: root/ghc
diff options
context:
space:
mode:
Diffstat (limited to 'ghc')
-rw-r--r--ghc/GhciMonad.hs48
-rw-r--r--ghc/GhciTags.hs42
-rw-r--r--ghc/InteractiveUI.hs616
-rw-r--r--ghc/Main.hs19
-rw-r--r--ghc/ghc-bin.cabal.in4
-rw-r--r--ghc/ghc.mk11
-rw-r--r--ghc/hschooks.c5
7 files changed, 471 insertions, 274 deletions
diff --git a/ghc/GhciMonad.hs b/ghc/GhciMonad.hs
index f1767c3ea5..f68d0b9a55 100644
--- a/ghc/GhciMonad.hs
+++ b/ghc/GhciMonad.hs
@@ -16,13 +16,12 @@ module GhciMonad (
Command,
BreakLocation(..),
TickArray,
- setDynFlags,
+ getDynFlags,
runStmt, runDecls, resume, timeIt, recordBreak, revertCAFs,
printForUser, printForUserPartWay, prettyLocations,
initInterpBuffering, turnOffBuffering, flushInterpBuffers,
- ghciHandleGhcException,
) where
#include "HsVersions.h"
@@ -31,7 +30,6 @@ import qualified GHC
import GhcMonad hiding (liftIO)
import Outputable hiding (printForUser, printForUserPartWay)
import qualified Outputable
-import Panic hiding (showException)
import Util
import DynFlags
import HscTypes
@@ -39,7 +37,6 @@ import SrcLoc
import Module
import ObjLink
import Linker
-import StaticFlags
import qualified MonadUtils
import Exception
@@ -55,7 +52,8 @@ import GHC.Exts
import System.Console.Haskeline (CompletionFunc, InputT)
import qualified System.Console.Haskeline as Haskeline
-import Control.Monad.Trans as Trans
+import Control.Monad.Trans.Class as Trans
+import Control.Monad.IO.Class as Trans
-----------------------------------------------------------------------------
-- GHCi monad
@@ -171,9 +169,6 @@ instance Monad GHCi where
instance Functor GHCi where
fmap f m = m >>= return . f
-ghciHandleGhcException :: (GhcException -> GHCi a) -> GHCi a -> GHCi a
-ghciHandleGhcException = handleGhcException
-
getGHCiState :: GHCi GHCiState
getGHCiState = GHCi $ \r -> liftIO $ readIORef r
setGHCiState :: GHCiState -> GHCi ()
@@ -221,22 +216,22 @@ instance ExceptionMonad GHCi where
instance MonadIO GHCi where
liftIO = MonadUtils.liftIO
+instance Haskeline.MonadException Ghc where
+ controlIO f = Ghc $ \s -> Haskeline.controlIO $ \(Haskeline.RunIO run) -> let
+ run' = Haskeline.RunIO (fmap (Ghc . const) . run . flip unGhc s)
+ in fmap (flip unGhc s) $ f run'
+
instance Haskeline.MonadException GHCi where
- catch = gcatch
- block = gblock
- unblock = gunblock
- -- XXX when Haskeline's MonadException changes, we can drop our
- -- deprecated block/unblock methods
+ controlIO f = GHCi $ \s -> Haskeline.controlIO $ \(Haskeline.RunIO run) -> let
+ run' = Haskeline.RunIO (fmap (GHCi . const) . run . flip unGHCi s)
+ in fmap (flip unGHCi s) $ f run'
instance ExceptionMonad (InputT GHCi) where
gcatch = Haskeline.catch
- gmask f = Haskeline.block (f Haskeline.unblock) -- slightly wrong
- gblock = Haskeline.block
- gunblock = Haskeline.unblock
+ gmask f = Haskeline.liftIOOp gmask (f . Haskeline.liftIOOp_)
-setDynFlags :: DynFlags -> GHCi [PackageId]
-setDynFlags dflags = do
- GHC.setSessionDynFlags dflags
+ gblock = Haskeline.liftIOOp_ gblock
+ gunblock = Haskeline.liftIOOp_ gunblock
isOptionSet :: GHCiOption -> GHCi Bool
isOptionSet opt
@@ -256,12 +251,14 @@ unsetOption opt
printForUser :: GhcMonad m => SDoc -> m ()
printForUser doc = do
unqual <- GHC.getPrintUnqual
- MonadUtils.liftIO $ Outputable.printForUser stdout unqual doc
+ dflags <- getDynFlags
+ MonadUtils.liftIO $ Outputable.printForUser dflags stdout unqual doc
printForUserPartWay :: SDoc -> GHCi ()
printForUserPartWay doc = do
unqual <- GHC.getPrintUnqual
- liftIO $ Outputable.printForUserPartWay stdout opt_PprUserLength unqual doc
+ dflags <- getDynFlags
+ liftIO $ Outputable.printForUserPartWay dflags stdout (pprUserLength dflags) unqual doc
-- | Run a single Haskell expression
runStmt :: String -> GHC.SingleStep -> GHCi (Maybe GHC.RunResult)
@@ -308,18 +305,19 @@ timeIt action
a <- action
allocs2 <- liftIO $ getAllocations
time2 <- liftIO $ getCPUTime
- liftIO $ printTimes (fromIntegral (allocs2 - allocs1))
+ dflags <- getDynFlags
+ liftIO $ printTimes dflags (fromIntegral (allocs2 - allocs1))
(time2 - time1)
return a
foreign import ccall unsafe "getAllocations" getAllocations :: IO Int64
-- defined in ghc/rts/Stats.c
-printTimes :: Integer -> Integer -> IO ()
-printTimes allocs psecs
+printTimes :: DynFlags -> Integer -> Integer -> IO ()
+printTimes dflags allocs psecs
= do let secs = (fromIntegral psecs / (10^(12::Integer))) :: Float
secs_str = showFFloat (Just 2) secs
- putStrLn (showSDoc (
+ putStrLn (showSDoc dflags (
parens (text (secs_str "") <+> text "secs" <> comma <+>
text (show allocs) <+> text "bytes")))
diff --git a/ghc/GhciTags.hs b/ghc/GhciTags.hs
index a3ad646309..1f43328f8d 100644
--- a/ghc/GhciTags.hs
+++ b/ghc/GhciTags.hs
@@ -6,13 +6,6 @@
--
-----------------------------------------------------------------------------
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSp
--- for details
-
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}
module GhciTags (
createCTagsWithLineNumbersCmd,
@@ -24,7 +17,6 @@ import Exception
import GHC
import GhciMonad
import Outputable
-import Util
-- ToDo: figure out whether we need these, and put something appropriate
-- into the GHC API instead
@@ -32,7 +24,9 @@ import Name (nameOccName)
import OccName (pprOccName)
import MonadUtils
+import Data.Function
import Data.Maybe
+import Data.Ord
import Panic
import Data.List
import Control.Monad
@@ -65,12 +59,12 @@ ghciCreateTagsFile kind file = do
createTagsFile kind file
-- ToDo:
--- - remove restriction that all modules must be interpreted
--- (problem: we don't know source locations for entities unless
--- we compiled the module.
+-- - remove restriction that all modules must be interpreted
+-- (problem: we don't know source locations for entities unless
+-- we compiled the module.
--
--- - extract createTagsFile so it can be used from the command-line
--- (probably need to fix first problem before this is useful).
+-- - extract createTagsFile so it can be used from the command-line
+-- (probably need to fix first problem before this is useful).
--
createTagsFile :: TagsKind -> FilePath -> GHCi ()
createTagsFile tagskind tagsFile = do
@@ -93,12 +87,13 @@ listModuleTags m = do
case mbModInfo of
Nothing -> return []
Just mInfo -> do
+ dflags <- getDynFlags
mb_print_unqual <- GHC.mkPrintUnqualifiedForModule mInfo
let unqual = fromMaybe GHC.alwaysQualify mb_print_unqual
let names = fromMaybe [] $GHC.modInfoTopLevelScope mInfo
let localNames = filter ((m==) . nameModule) names
mbTyThings <- mapM GHC.lookupName localNames
- return $! [ tagInfo unqual exported kind name realLoc
+ return $! [ tagInfo dflags unqual exported kind name realLoc
| tyThing <- catMaybes mbTyThings
, let name = getName tyThing
, let exported = GHC.modInfoIsExportedName mInfo name
@@ -126,24 +121,25 @@ data TagInfo = TagInfo
-- get tag info, for later translation into Vim or Emacs style
-tagInfo :: PrintUnqualified -> Bool -> Char -> Name -> RealSrcLoc -> TagInfo
-tagInfo unqual exported kind name loc
+tagInfo :: DynFlags -> PrintUnqualified -> Bool -> Char -> Name -> RealSrcLoc
+ -> TagInfo
+tagInfo dflags unqual exported kind name loc
= TagInfo exported kind
- (showSDocForUser unqual $ pprOccName (nameOccName name))
- (showSDocForUser unqual $ ftext (srcLocFile loc))
+ (showSDocForUser dflags unqual $ pprOccName (nameOccName name))
+ (showSDocForUser dflags unqual $ ftext (srcLocFile loc))
(srcLocLine loc) (srcLocCol loc) Nothing
collateAndWriteTags :: TagsKind -> FilePath -> [TagInfo] -> IO (Either IOError ())
-- ctags style with the Ex exresion being just the line number, Vim et al
collateAndWriteTags CTagsWithLineNumbers file tagInfos = do
- let tags = unlines $ sortLe (<=) $ map showCTag tagInfos
+ let tags = unlines $ sort $ map showCTag tagInfos
tryIO (writeFile file tags)
-- ctags style with the Ex exresion being a regex searching the line, Vim et al
collateAndWriteTags CTagsWithRegExes file tagInfos = do -- ctags style, Vim et al
tagInfoGroups <- makeTagGroupsWithSrcInfo tagInfos
- let tags = unlines $ sortLe (<=) $ map showCTag $concat tagInfoGroups
+ let tags = unlines $ sort $ map showCTag $concat tagInfoGroups
tryIO (writeFile file tags)
collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
@@ -160,16 +156,14 @@ collateAndWriteTags ETags file tagInfos = do -- etags style, Emacs/XEmacs
makeTagGroupsWithSrcInfo :: [TagInfo] -> IO [[TagInfo]]
makeTagGroupsWithSrcInfo tagInfos = do
- let byFile op ti0 ti1 = tagFile ti0 `op` tagFile ti1
- groups = groupBy (byFile (==)) $ sortLe (byFile (<=)) tagInfos
+ let groups = groupBy ((==) `on` tagFile) $ sortBy (comparing tagFile) tagInfos
mapM addTagSrcInfo groups
where
addTagSrcInfo [] = ghcError (CmdLineError "empty tag file group??")
addTagSrcInfo group@(tagInfo:_) = do
file <- readFile $tagFile tagInfo
- let byLine ti0 ti1 = tagLine ti0 <= tagLine ti1
- sortedGroup = sortLe byLine group
+ let sortedGroup = sortBy (comparing tagLine) group
return $ perFile sortedGroup 1 0 $ lines file
perFile allTags@(tag:tags) cnt pos allLs@(l:ls)
diff --git a/ghc/InteractiveUI.hs b/ghc/InteractiveUI.hs
index 45bac2c9ef..d9d6bc235e 100644
--- a/ghc/InteractiveUI.hs
+++ b/ghc/InteractiveUI.hs
@@ -21,12 +21,14 @@ import Debugger
-- The GHC interface
import DynFlags
+import GhcMonad ( modifySession )
import qualified GHC
import GHC ( LoadHowMuch(..), Target(..), TargetId(..), InteractiveImport(..),
TyThing(..), Phase, BreakIndex, Resume, SingleStep, Ghc,
handleSourceError )
import HsImpExp
-import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, dep_pkgs )
+import HscTypes ( tyThingParent_maybe, handleFlagWarnings, getSafeMode, dep_pkgs, hsc_IC,
+ setInteractivePrintName )
import Module
import Name
import Packages ( trusted, getPackageDetails, exposed, exposedModules, pkgIdMap )
@@ -49,27 +51,26 @@ import Linker
import Maybes ( orElse, expectJust )
import NameSet
import Panic hiding ( showException )
-import StaticFlags
-import Util ( on, global, toArgs, toCmdArgs, removeSpaces, getCmd,
- filterOut, seqList, looksLikeModuleName, partitionWith )
+import Util
-- Haskell Libraries
import System.Console.Haskeline as Haskeline
-import qualified System.Console.Haskeline.Encoding as Encoding
import Control.Applicative hiding (empty)
import Control.Monad as Monad
-import Control.Monad.Trans
+import Control.Monad.Trans.Class
+import Control.Monad.IO.Class
import Data.Array
import qualified Data.ByteString.Char8 as BS
import Data.Char
+import Data.Function
import Data.IORef ( IORef, readIORef, writeIORef )
import Data.List ( find, group, intercalate, intersperse, isPrefixOf, nub,
partition, sort, sortBy )
import Data.Maybe
-import Exception hiding (catch, block, unblock)
+import Exception hiding (catch)
import Foreign.C
import Foreign.Safe
@@ -126,7 +127,7 @@ builtin_commands = [
("def", keepGoing (defineMacro False), completeExpression),
("def!", keepGoing (defineMacro True), completeExpression),
("delete", keepGoing deleteCmd, noCompletion),
- ("edit", keepGoing editFile, completeFilename),
+ ("edit", keepGoing' editFile, completeFilename),
("etags", keepGoing createETagsFileCmd, completeFilename),
("force", keepGoing forceCmd, completeExpression),
("forward", keepGoing forwardCmd, noCompletion),
@@ -146,7 +147,9 @@ builtin_commands = [
("run", keepGoing runRun, completeFilename),
("script", keepGoing' scriptCmd, completeFilename),
("set", keepGoing setCmd, completeSetOptions),
+ ("seti", keepGoing setiCmd, completeSeti),
("show", keepGoing showCmd, completeShowOptions),
+ ("showi", keepGoing showiCmd, completeShowiOptions),
("sprint", keepGoing sprintCmd, completeExpression),
("step", keepGoing stepCmd, completeIdentifier),
("steplocal", keepGoing stepLocalCmd, completeIdentifier),
@@ -185,7 +188,7 @@ keepGoing' a str = a str >> return False
keepGoingPaths :: ([FilePath] -> InputT GHCi ()) -> (String -> InputT GHCi Bool)
keepGoingPaths a str
= do case toArgs str of
- Left err -> Encoding.encode err >>= liftIO . BS.hPutStrLn stderr
+ Left err -> liftIO $ hPutStrLn stderr err
Right args -> a args
return False
@@ -253,6 +256,7 @@ helpText =
" -- Commands for changing settings:\n" ++
"\n" ++
" :set <option> ... set options\n" ++
+ " :seti <option> ... set options for interactive evaluation only\n" ++
" :set args <arg> ... set the arguments returned by System.getArgs\n" ++
" :set prog <progname> set the value returned by System.getProgName\n" ++
" :set prompt <prompt> set the prompt used in GHCi\n" ++
@@ -279,9 +283,10 @@ helpText =
" :show imports show the current imports\n" ++
" :show modules show the currently loaded modules\n" ++
" :show packages show the currently active package flags\n" ++
- " :show languages show the currently active language flags\n" ++
+ " :show language show the currently active language flags\n" ++
" :show <setting> show value of <setting>, which is one of\n" ++
" [args, prog, prompt, editor, stop]\n" ++
+ " :showi language show language flags for interactive evaluation\n" ++
"\n"
findEditor :: IO String
@@ -330,6 +335,11 @@ interactiveUI srcs maybe_exprs = do
-- Initialise buffering for the *interpreted* I/O system
initInterpBuffering
+ -- The initial set of DynFlags used for interactive evaluation is the same
+ -- as the global DynFlags, plus -XExtendedDefaultRules
+ dflags <- getDynFlags
+ GHC.setInteractiveDynFlags (xopt_set dflags Opt_ExtendedDefaultRules)
+
liftIO $ when (isNothing maybe_exprs) $ do
-- Only for GHCi (not runghc and ghc -e):
@@ -381,8 +391,9 @@ withGhcAppData right left = do
runGHCi :: [(FilePath, Maybe Phase)] -> Maybe [String] -> GHCi ()
runGHCi paths maybe_exprs = do
+ dflags <- getDynFlags
let
- read_dot_files = not opt_IgnoreDotGhci
+ read_dot_files = not (dopt Opt_IgnoreDotGhci dflags)
current_dir = return (Just ".ghci")
@@ -421,11 +432,10 @@ runGHCi paths maybe_exprs = do
getDirectory f = case takeDirectory f of "" -> "."; d -> d
--
- setGHCContext []
+ setGHCContextFromGHCiState
when (read_dot_files) $ do
- mcfgs0 <- sequence $ [ current_dir, app_user_dir, home_dir ]
- ++ map (return . Just) opt_GhciScripts
+ mcfgs0 <- sequence $ [ current_dir, app_user_dir, home_dir ] ++ map (return . Just ) (ghciScripts dflags)
mcfgs <- liftIO $ mapM canonicalizePath' (catMaybes mcfgs0)
mapM_ sourceConfigFile $ nub $ catMaybes mcfgs
-- nub, because we don't want to read .ghci twice if the
@@ -437,17 +447,16 @@ runGHCi paths maybe_exprs = do
when (not (null paths)) $ do
ok <- ghciHandle (\e -> do showException e; return Failed) $
-- TODO: this is a hack.
- runInputTWithPrefs defaultPrefs defaultSettings $ do
- let (filePaths, phases) = unzip paths
- filePaths' <- mapM (Encoding.decode . BS.pack) filePaths
- loadModule (zip filePaths' phases)
+ runInputTWithPrefs defaultPrefs defaultSettings $
+ loadModule paths
when (isJust maybe_exprs && failed ok) $
liftIO (exitWith (ExitFailure 1))
+ installInteractivePrint (interactivePrint dflags) (isJust maybe_exprs)
+
-- if verbosity is greater than 0, or we are connected to a
-- terminal, display the prompt in the interactive loop.
is_tty <- liftIO (hIsTerminalDevice stdin)
- dflags <- getDynFlags
let show_prompt = verbosity dflags > 0 || is_tty
-- reset line number
@@ -575,8 +584,7 @@ mkPrompt = do
rev_imports = reverse imports -- rightmost are the most recent
modules_bit =
- hsep [ char '*' <> ppr (GHC.moduleName m)
- | IIModule m <- rev_imports ] <+>
+ hsep [ char '*' <> ppr m | IIModule m <- rev_imports ] <+>
hsep (map ppr [ myIdeclName d | IIDecl d <- rev_imports ])
-- use the 'as' name if there is one
@@ -591,7 +599,8 @@ mkPrompt = do
f [] = empty
st <- getGHCiState
- return (showSDoc (f (prompt st)))
+ dflags <- getDynFlags
+ return (showSDoc dflags (f (prompt st)))
queryQueue :: GHCi (Maybe String)
@@ -602,6 +611,18 @@ queryQueue = do
c:cs -> do setGHCiState st{ cmdqueue = cs }
return (Just c)
+-- Reconfigurable pretty-printing Ticket #5461
+installInteractivePrint :: Maybe String -> Bool -> GHCi ()
+installInteractivePrint Nothing _ = return ()
+installInteractivePrint (Just ipFun) exprmode = do
+ ok <- trySuccess $ do
+ (name:_) <- GHC.parseName ipFun
+ modifySession (\he -> let new_ic = setInteractivePrintName (hsc_IC he) name
+ in he{hsc_IC = new_ic})
+ return Succeeded
+
+ when (failed ok && exprmode) $ liftIO (exitWith (ExitFailure 1))
+
-- | The main read-eval-print loop
runCommands :: InputT GHCi (Maybe String) -> InputT GHCi ()
runCommands = runCommands' handler
@@ -957,8 +978,9 @@ info :: String -> InputT GHCi ()
info "" = ghcError (CmdLineError "syntax: ':i <thing-you-want-info-about>'")
info s = handleSourceError GHC.printException $ do
unqual <- GHC.getPrintUnqual
+ dflags <- getDynFlags
sdocs <- mapM infoThing (words s)
- mapM_ (liftIO . putStrLn . showSDocForUser unqual) sdocs
+ mapM_ (liftIO . putStrLn . showSDocForUser dflags unqual) sdocs
infoThing :: GHC.GhcMonad m => String -> m SDoc
infoThing str = do
@@ -984,12 +1006,12 @@ filterOutChildren get_thing xs
pprInfo :: PrintExplicitForalls -> (TyThing, Fixity, [GHC.ClsInst]) -> SDoc
pprInfo pefas (thing, fixity, insts)
= pprTyThingInContextLoc pefas thing
- $$ show_fixity fixity
+ $$ show_fixity
$$ vcat (map GHC.pprInstance insts)
where
- show_fixity fix
- | fix == GHC.defaultFixity = empty
- | otherwise = ppr fix <+> ppr (GHC.getName thing)
+ show_fixity
+ | fixity == GHC.defaultFixity = empty
+ | otherwise = ppr fixity <+> pprInfixName (GHC.getName thing)
-----------------------------------------------------------------------------
-- :main
@@ -1045,15 +1067,16 @@ trySuccess act =
-----------------------------------------------------------------------------
-- :edit
-editFile :: String -> GHCi ()
+editFile :: String -> InputT GHCi ()
editFile str =
- do file <- if null str then chooseEditFile else return str
- st <- getGHCiState
+ do file <- if null str then lift chooseEditFile else return str
+ st <- lift getGHCiState
let cmd = editor st
when (null cmd)
$ ghcError (CmdLineError "editor not set, use :set editor")
- _ <- liftIO $ system (cmd ++ ' ':file)
- return ()
+ code <- liftIO $ system (cmd ++ ' ':file)
+ when (code == ExitSuccess)
+ $ reloadModule ""
-- The user didn't specify a file so we pick one for them.
-- Our strategy is to pick the first module that failed to load,
@@ -1168,7 +1191,8 @@ checkModule m = do
let modl = GHC.mkModuleName m
ok <- handleSourceError (\e -> GHC.printException e >> return False) $ do
r <- GHC.typecheckModule =<< GHC.parseModule =<< GHC.getModSummary modl
- liftIO $ putStrLn $ showSDoc $
+ dflags <- getDynFlags
+ liftIO $ putStrLn $ showSDoc dflags $
case GHC.moduleInfo r of
cm | Just scope <- GHC.modInfoTopLevelScope cm ->
let
@@ -1285,8 +1309,13 @@ setContextAfterLoad keep_ctxt ms = do
load_this summary | m <- GHC.ms_mod summary = do
is_interp <- GHC.moduleIsInterpreted m
- let new_ctx | is_interp = [IIModule m]
- | otherwise = [IIDecl $ simpleImportDecl (GHC.moduleName m)]
+ dflags <- getDynFlags
+ let star_ok = is_interp && not (safeLanguageOn dflags)
+ -- We import the module with a * iff
+ -- - it is interpreted, and
+ -- - -XSafe is off (it doesn't allow *-imports)
+ let new_ctx | star_ok = [mkIIModule (GHC.moduleName m)]
+ | otherwise = [mkIIDecl (GHC.moduleName m)]
setContextKeepingPackageModules keep_ctxt new_ctx
@@ -1304,7 +1333,7 @@ setContextKeepingPackageModules keep_ctx trans_ctx = do
new_rem_ctx <- if keep_ctx then return rem_ctx
else keepPackageImports rem_ctx
setGHCiState st{ remembered_ctx = new_rem_ctx,
- transient_ctx = trans_ctx }
+ transient_ctx = filterSubsumed new_rem_ctx trans_ctx }
setGHCContextFromGHCiState
@@ -1332,9 +1361,9 @@ modulesLoadedMsg ok mods = do
punctuate comma (map ppr mods)) <> text "."
case ok of
Failed ->
- liftIO $ putStrLn $ showSDoc (text "Failed, modules loaded: " <> mod_commas)
+ liftIO $ putStrLn $ showSDoc dflags (text "Failed, modules loaded: " <> mod_commas)
Succeeded ->
- liftIO $ putStrLn $ showSDoc (text "Ok, modules loaded: " <> mod_commas)
+ liftIO $ putStrLn $ showSDoc dflags (text "Ok, modules loaded: " <> mod_commas)
-----------------------------------------------------------------------------
@@ -1432,7 +1461,7 @@ isSafeModule m = do
let iface' = fromJust iface
- trust = showPpr $ getSafeMode $ GHC.mi_trust iface'
+ trust = showPpr dflags $ getSafeMode $ GHC.mi_trust iface'
pkgT = packageTrusted dflags m
pkg = if pkgT then "trusted" else "untrusted"
(good', bad') = tallyPkgs dflags $
@@ -1462,7 +1491,7 @@ isSafeModule m = do
False -> liftIO $ putStrLn $ mname ++ " is NOT trusted!"
where
- goodTrust t = t `elem` [Sf_Safe, Sf_SafeInfered, Sf_Trustworthy]
+ goodTrust t = t `elem` [Sf_Safe, Sf_SafeInferred, Sf_Trustworthy]
mname = GHC.moduleNameString $ GHC.moduleName m
@@ -1502,7 +1531,7 @@ guessCurrentModule cmd
when (null imports) $ ghcError $
CmdLineError (':' : cmd ++ ": no current module")
case (head imports) of
- IIModule m -> return m
+ IIModule m -> GHC.findModule m Nothing
IIDecl d -> GHC.findModule (unLoc (ideclName d)) (ideclPkgQual d)
-- without bang, show items in context of their parents and omit children
@@ -1579,7 +1608,7 @@ browseModule bang modl exports_only = do
prettyThings = map (pretty pefas) things
prettyThings' | bang = annotate $ zip modNames prettyThings
| otherwise = prettyThings
- liftIO $ putStrLn $ showSDocForUser unqual (vcat prettyThings')
+ liftIO $ putStrLn $ showSDocForUser dflags unqual (vcat prettyThings')
-- ToDo: modInfoInstances currently throws an exception for
-- package modules. When it works, we can do this:
-- $$ vcat (map GHC.pprInstance (GHC.modInfoInstances mod_info))
@@ -1609,69 +1638,109 @@ moduleCmd str
sensible ('*':m) = looksLikeModuleName m
sensible m = looksLikeModuleName m
- starred ('*':m) = Left m
- starred m = Right m
+ starred ('*':m) = Left (GHC.mkModuleName m)
+ starred m = Right (GHC.mkModuleName m)
+
-addModulesToContext :: [String] -> [String] -> GHCi ()
-addModulesToContext as bs = do
- mapM_ (add True) as
- mapM_ (add False) bs
+-- -----------------------------------------------------------------------------
+-- Four ways to manipulate the context:
+-- (a) :module +<stuff>: addModulesToContext
+-- (b) :module -<stuff>: remModulesFromContext
+-- (c) :module <stuff>: setContext
+-- (d) import <module>...: addImportToContext
+
+addModulesToContext :: [ModuleName] -> [ModuleName] -> GHCi ()
+addModulesToContext starred unstarred = restoreContextOnFailure $ do
+ addModulesToContext_ starred unstarred
+
+addModulesToContext_ :: [ModuleName] -> [ModuleName] -> GHCi ()
+addModulesToContext_ starred unstarred = do
+ mapM_ addII (map mkIIModule starred ++ map mkIIDecl unstarred)
setGHCContextFromGHCiState
- where
- add :: Bool -> String -> GHCi ()
- add star str = do
- i <- checkAdd star str
- modifyGHCiState $ \st ->
- st { remembered_ctx = addNotSubsumed i (remembered_ctx st) }
-remModulesFromContext :: [String] -> [String] -> GHCi ()
-remModulesFromContext as bs = do
- mapM_ rm (as ++ bs)
+remModulesFromContext :: [ModuleName] -> [ModuleName] -> GHCi ()
+remModulesFromContext starred unstarred = do
+ -- we do *not* call restoreContextOnFailure here. If the user
+ -- is trying to fix up a context that contains errors by removing
+ -- modules, we don't want GHC to silently put them back in again.
+ mapM_ rm (starred ++ unstarred)
setGHCContextFromGHCiState
where
- rm :: String -> GHCi ()
+ rm :: ModuleName -> GHCi ()
rm str = do
- m <- moduleName <$> lookupModule str
+ m <- moduleName <$> lookupModuleName str
let filt = filter ((/=) m . iiModuleName)
modifyGHCiState $ \st ->
st { remembered_ctx = filt (remembered_ctx st)
, transient_ctx = filt (transient_ctx st) }
+setContext :: [ModuleName] -> [ModuleName] -> GHCi ()
+setContext starred unstarred = restoreContextOnFailure $ do
+ modifyGHCiState $ \st -> st { remembered_ctx = [], transient_ctx = [] }
+ -- delete the transient context
+ addModulesToContext_ starred unstarred
+
addImportToContext :: String -> GHCi ()
-addImportToContext str = do
+addImportToContext str = restoreContextOnFailure $ do
idecl <- GHC.parseImportDecl str
- _ <- GHC.lookupModule (unLoc (ideclName idecl)) Nothing -- #5836
- modifyGHCiState $ \st ->
- st { remembered_ctx = addNotSubsumed (IIDecl idecl) (remembered_ctx st) }
+ addII (IIDecl idecl) -- #5836
setGHCContextFromGHCiState
-setContext :: [String] -> [String] -> GHCi ()
-setContext starred not_starred = do
- is1 <- mapM (checkAdd True) starred
- is2 <- mapM (checkAdd False) not_starred
- let iss = foldr addNotSubsumed [] (is1++is2)
- modifyGHCiState $ \st -> st { remembered_ctx = iss, transient_ctx = [] }
- -- delete the transient context
- setGHCContextFromGHCiState
+-- Util used by addImportToContext and addModulesToContext
+addII :: InteractiveImport -> GHCi ()
+addII iidecl = do
+ checkAdd iidecl
+ modifyGHCiState $ \st ->
+ st { remembered_ctx = addNotSubsumed iidecl (remembered_ctx st)
+ , transient_ctx = filter (not . (iidecl `iiSubsumes`))
+ (transient_ctx st)
+ }
-checkAdd :: Bool -> String -> GHCi InteractiveImport
-checkAdd star mstr = do
- dflags <- getDynFlags
- case safeLanguageOn dflags of
- True | star -> ghcError $ CmdLineError "can't use * imports with Safe Haskell"
+-- Sometimes we can't tell whether an import is valid or not until
+-- we finally call 'GHC.setContext'. e.g.
+--
+-- import System.IO (foo)
+--
+-- will fail because System.IO does not export foo. In this case we
+-- don't want to store the import in the context permanently, so we
+-- catch the failure from 'setGHCContextFromGHCiState' and set the
+-- context back to what it was.
+--
+-- See #6007
+--
+restoreContextOnFailure :: GHCi a -> GHCi a
+restoreContextOnFailure do_this = do
+ st <- getGHCiState
+ let rc = remembered_ctx st; tc = transient_ctx st
+ do_this `gonException` (modifyGHCiState $ \st' ->
+ st' { remembered_ctx = rc, transient_ctx = tc })
+
+-- -----------------------------------------------------------------------------
+-- Validate a module that we want to add to the context
- True -> do m <- lookupModule mstr
- s <- GHC.isModuleTrusted m
- case s of
- True -> return $ IIDecl (simpleImportDecl $ moduleName m)
- False -> ghcError $ CmdLineError $ "can't import " ++ mstr
- ++ " as it isn't trusted."
+checkAdd :: InteractiveImport -> GHCi ()
+checkAdd ii = do
+ dflags <- getDynFlags
+ let safe = safeLanguageOn dflags
+ case ii of
+ IIModule modname
+ | safe -> ghcError $ CmdLineError "can't use * imports with Safe Haskell"
+ | otherwise -> wantInterpretedModuleName modname >> return ()
+
+ IIDecl d -> do
+ let modname = unLoc (ideclName d)
+ pkgqual = ideclPkgQual d
+ m <- GHC.lookupModule modname pkgqual
+ when safe $ do
+ t <- GHC.isModuleTrusted m
+ when (not t) $
+ ghcError $ CmdLineError $
+ "can't import " ++ moduleNameString modname
+ ++ " as it isn't trusted."
- False | star -> do m <- wantInterpretedModule mstr
- return $ IIModule m
- False -> do m <- lookupModule mstr
- return $ IIDecl (simpleImportDecl $ moduleName m)
+-- -----------------------------------------------------------------------------
+-- Update the GHC API's view of the context
-- | Sets the GHC context from the GHCi state. The GHC context is
-- always set this way, we never modify it incrementally.
@@ -1687,46 +1756,36 @@ checkAdd star mstr = do
--
setGHCContextFromGHCiState :: GHCi ()
setGHCContextFromGHCiState = do
- let ok (IIModule m) = checkAdd True (moduleNameString (moduleName m))
- ok (IIDecl d) = checkAdd False (moduleNameString (unLoc (ideclName d)))
st <- getGHCiState
- iidecls <- filterM (tryBool . ok) (transient_ctx st ++ remembered_ctx st)
- setGHCContext iidecls
-
+ -- re-use checkAdd to check whether the module is valid. If the
+ -- module does not exist, we do *not* want to print an error
+ -- here, we just want to silently keep the module in the context
+ -- until such time as the module reappears again. So we ignore
+ -- the actual exception thrown by checkAdd, using tryBool to
+ -- turn it into a Bool.
+ iidecls <- filterM (tryBool.checkAdd) (transient_ctx st ++ remembered_ctx st)
+ dflags <- GHC.getSessionDynFlags
+ GHC.setContext $
+ if xopt Opt_ImplicitPrelude dflags && not (any isPreludeImport iidecls)
+ then iidecls ++ [implicitPreludeImport]
+ else iidecls
+ -- XXX put prel at the end, so that guessCurrentModule doesn't pick it up.
--- | Sets the GHC contexts to the given set of imports, adding a Prelude
--- import if there isn't an explicit one already.
-setGHCContext :: [InteractiveImport] -> GHCi ()
-setGHCContext iidecls = GHC.setContext (iidecls ++ prel)
- -- XXX put prel at the end, so that guessCurrentModule doesn't pick it up.
- where
- prel | any isPreludeImport iidecls = []
- | otherwise = [implicitPreludeImport]
-- -----------------------------------------------------------------------------
-- Utils on InteractiveImport
--- | Returns True if the left import subsumes the right one. Doesn't
--- need to be 100% accurate, conservatively returning False is fine.
---
--- Note that an IIModule does not necessarily subsume an IIDecl,
--- because e.g. a module might export a name that is only available
--- qualified within the module itself.
---
-iiSubsumes :: InteractiveImport -> InteractiveImport -> Bool
-iiSubsumes (IIModule m1) (IIModule m2) = m1==m2
-iiSubsumes (IIDecl d1) (IIDecl d2) -- A bit crude
- = unLoc (ideclName d1) == unLoc (ideclName d2)
- && ideclAs d1 == ideclAs d2
- && (not (ideclQualified d1) || ideclQualified d2)
- && (isNothing (ideclHiding d1) || ideclHiding d1 == ideclHiding d2)
-iiSubsumes _ _ = False
+mkIIModule :: ModuleName -> InteractiveImport
+mkIIModule = IIModule
-iiModules :: [InteractiveImport] -> [Module]
+mkIIDecl :: ModuleName -> InteractiveImport
+mkIIDecl = IIDecl . simpleImportDecl
+
+iiModules :: [InteractiveImport] -> [ModuleName]
iiModules is = [m | IIModule m <- is]
iiModuleName :: InteractiveImport -> ModuleName
-iiModuleName (IIModule m) = moduleName m
+iiModuleName (IIModule m) = m
iiModuleName (IIDecl d) = unLoc (ideclName d)
preludeModuleName :: ModuleName
@@ -1745,6 +1804,39 @@ addNotSubsumed i is
| any (`iiSubsumes` i) is = is
| otherwise = i : filter (not . (i `iiSubsumes`)) is
+-- | @filterSubsumed is js@ returns the elements of @js@ not subsumed
+-- by any of @is@.
+filterSubsumed :: [InteractiveImport] -> [InteractiveImport]
+ -> [InteractiveImport]
+filterSubsumed is js = filter (\j -> not (any (`iiSubsumes` j) is)) js
+
+-- | Returns True if the left import subsumes the right one. Doesn't
+-- need to be 100% accurate, conservatively returning False is fine.
+-- (EXCEPT: (IIModule m) *must* subsume itself, otherwise a panic in
+-- plusProv will ensue (#5904))
+--
+-- Note that an IIModule does not necessarily subsume an IIDecl,
+-- because e.g. a module might export a name that is only available
+-- qualified within the module itself.
+--
+-- Note that 'import M' does not necessarily subsume 'import M(foo)',
+-- because M might not export foo and we want an error to be produced
+-- in that case.
+--
+iiSubsumes :: InteractiveImport -> InteractiveImport -> Bool
+iiSubsumes (IIModule m1) (IIModule m2) = m1==m2
+iiSubsumes (IIDecl d1) (IIDecl d2) -- A bit crude
+ = unLoc (ideclName d1) == unLoc (ideclName d2)
+ && ideclAs d1 == ideclAs d2
+ && (not (ideclQualified d1) || ideclQualified d2)
+ && (ideclHiding d1 `hidingSubsumes` ideclHiding d2)
+ where
+ _ `hidingSubsumes` Just (False,[]) = True
+ Just (False, xs) `hidingSubsumes` Just (False,ys) = all (`elem` xs) ys
+ h1 `hidingSubsumes` h2 = h1 == h2
+iiSubsumes _ _ = False
+
+
----------------------------------------------------------------------------
-- :set
@@ -1756,35 +1848,68 @@ addNotSubsumed i is
-- figure out which ones & disallow them.
setCmd :: String -> GHCi ()
-setCmd ""
+setCmd "" = showOptions False
+setCmd "-a" = showOptions True
+setCmd str
+ = case getCmd str of
+ Right ("args", rest) ->
+ case toArgs rest of
+ Left err -> liftIO (hPutStrLn stderr err)
+ Right args -> setArgs args
+ Right ("prog", rest) ->
+ case toArgs rest of
+ Right [prog] -> setProg prog
+ _ -> liftIO (hPutStrLn stderr "syntax: :set prog <progname>")
+ Right ("prompt", rest) -> setPrompt $ dropWhile isSpace rest
+ Right ("editor", rest) -> setEditor $ dropWhile isSpace rest
+ Right ("stop", rest) -> setStop $ dropWhile isSpace rest
+ _ -> case toArgs str of
+ Left err -> liftIO (hPutStrLn stderr err)
+ Right wds -> setOptions wds
+
+setiCmd :: String -> GHCi ()
+setiCmd "" = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags False
+setiCmd "-a" = GHC.getInteractiveDynFlags >>= liftIO . showDynFlags True
+setiCmd str =
+ case toArgs str of
+ Left err -> liftIO (hPutStrLn stderr err)
+ Right wds -> newDynFlags True wds
+
+showOptions :: Bool -> GHCi ()
+showOptions show_all
= do st <- getGHCiState
+ dflags <- getDynFlags
let opts = options st
- liftIO $ putStrLn (showSDoc (
+ liftIO $ putStrLn (showSDoc dflags (
text "options currently set: " <>
if null opts
then text "none."
else hsep (map (\o -> char '+' <> text (optToStr o)) opts)
))
- dflags <- getDynFlags
- liftIO $ putStrLn (showSDoc (
- text "GHCi-specific dynamic flag settings:" $$
- nest 2 (vcat (map (flagSetting dflags) ghciFlags))
- ))
- liftIO $ putStrLn (showSDoc (
- text "other dynamic, non-language, flag settings:" $$
- nest 2 (vcat (map (flagSetting dflags) others))
- ))
- liftIO $ putStrLn (showSDoc (
- text "warning settings:" $$
- nest 2 (vcat (map (warnSetting dflags) DynFlags.fWarningFlags))
- ))
-
- where flagSetting dflags (str, f, _)
- | dopt f dflags = fstr str
- | otherwise = fnostr str
- warnSetting dflags (str, f, _)
- | wopt f dflags = fstr str
- | otherwise = fnostr str
+ getDynFlags >>= liftIO . showDynFlags show_all
+
+
+showDynFlags :: Bool -> DynFlags -> IO ()
+showDynFlags show_all dflags = do
+ showLanguages' show_all dflags
+ putStrLn $ showSDoc dflags $
+ text "GHCi-specific dynamic flag settings:" $$
+ nest 2 (vcat (map (setting dopt) ghciFlags))
+ putStrLn $ showSDoc dflags $
+ text "other dynamic, non-language, flag settings:" $$
+ nest 2 (vcat (map (setting dopt) others))
+ putStrLn $ showSDoc dflags $
+ text "warning settings:" $$
+ nest 2 (vcat (map (setting wopt) DynFlags.fWarningFlags))
+ where
+ setting test (str, f, _)
+ | quiet = empty
+ | is_on = fstr str
+ | otherwise = fnostr str
+ where is_on = test f dflags
+ quiet = not show_all && test f default_dflags == is_on
+
+ default_dflags = defaultDynFlags (settings dflags)
fstr str = text "-f" <> text str
fnostr str = text "-fno-" <> text str
@@ -1797,22 +1922,6 @@ setCmd ""
,Opt_BreakOnError
,Opt_PrintEvldWithShow
]
-setCmd str
- = case getCmd str of
- Right ("args", rest) ->
- case toArgs rest of
- Left err -> liftIO (hPutStrLn stderr err)
- Right args -> setArgs args
- Right ("prog", rest) ->
- case toArgs rest of
- Right [prog] -> setProg prog
- _ -> liftIO (hPutStrLn stderr "syntax: :set prog <progname>")
- Right ("prompt", rest) -> setPrompt $ dropWhile isSpace rest
- Right ("editor", rest) -> setEditor $ dropWhile isSpace rest
- Right ("stop", rest) -> setStop $ dropWhile isSpace rest
- _ -> case toArgs str of
- Left err -> liftIO (hPutStrLn stderr err)
- Right wds -> setOptions wds
setArgs, setOptions :: [String] -> GHCi ()
setProg, setEditor, setStop, setPrompt :: String -> GHCi ()
@@ -1863,32 +1972,49 @@ setOptions wds =
let (plus_opts, minus_opts) = partitionWith isPlus wds
mapM_ setOpt plus_opts
-- then, dynamic flags
- newDynFlags minus_opts
+ newDynFlags False minus_opts
-newDynFlags :: [String] -> GHCi ()
-newDynFlags minus_opts = do
- dflags0 <- getDynFlags
- let pkg_flags = packageFlags dflags0
- (dflags1, leftovers, warns) <- liftIO $ GHC.parseDynamicFlags dflags0 $ map noLoc minus_opts
- liftIO $ handleFlagWarnings dflags1 warns
+newDynFlags :: Bool -> [String] -> GHCi ()
+newDynFlags interactive_only minus_opts = do
+ let lopts = map noLoc minus_opts
+ idflags0 <- GHC.getInteractiveDynFlags
+ (idflags1, leftovers, warns) <- GHC.parseDynamicFlags idflags0 lopts
+
+ liftIO $ handleFlagWarnings idflags1 warns
when (not $ null leftovers)
(ghcError . CmdLineError
$ "Some flags have not been recognized: "
++ (concat . intersperse ", " $ map unLoc leftovers))
- new_pkgs <- setDynFlags dflags1
-
- -- if the package flags changed, we should reset the context
- -- and link the new packages.
- dflags2 <- getDynFlags
- when (packageFlags dflags2 /= pkg_flags) $ do
- liftIO $ hPutStrLn stderr "package flags have changed, resetting and loading new packages..."
- GHC.setTargets []
- _ <- GHC.load LoadAllTargets
- liftIO (linkPackages dflags2 new_pkgs)
- -- package flags changed, we can't re-use any of the old context
- setContextAfterLoad False []
+ when (interactive_only &&
+ packageFlags idflags1 /= packageFlags idflags0) $ do
+ liftIO $ hPutStrLn stderr "cannot set package flags with :seti; use :set"
+ GHC.setInteractiveDynFlags idflags1
+ installInteractivePrint (interactivePrint idflags1) False
+
+ dflags0 <- getDynFlags
+ when (not interactive_only) $ do
+ (dflags1, _, _) <- liftIO $ GHC.parseDynamicFlags dflags0 lopts
+ new_pkgs <- GHC.setProgramDynFlags dflags1
+
+ -- if the package flags changed, reset the context and link
+ -- the new packages.
+ dflags2 <- getDynFlags
+ when (packageFlags dflags2 /= packageFlags dflags0) $ do
+ liftIO $ hPutStrLn stderr "package flags have changed, resetting and loading new packages..."
+ GHC.setTargets []
+ _ <- GHC.load LoadAllTargets
+ liftIO $ linkPackages dflags2 new_pkgs
+ -- package flags changed, we can't re-use any of the old context
+ setContextAfterLoad False []
+ -- and copy the package state to the interactive DynFlags
+ idflags <- GHC.getInteractiveDynFlags
+ GHC.setInteractiveDynFlags
+ idflags{ pkgState = pkgState dflags2
+ , pkgDatabase = pkgDatabase dflags2
+ , packageFlags = packageFlags dflags2 }
+
return ()
@@ -1919,7 +2045,7 @@ unsetOptions str
mapM_ unsetOpt plus_opts
no_flags <- mapM no_flag minus_opts
- newDynFlags no_flags
+ newDynFlags False no_flags
isMinus :: String -> Bool
isMinus ('-':_) = True
@@ -1959,6 +2085,8 @@ optToStr RevertCAFs = "r"
-- :show
showCmd :: String -> GHCi ()
+showCmd "" = showOptions False
+showCmd "-a" = showOptions True
showCmd str = do
st <- getGHCiState
case words str of
@@ -1970,23 +2098,36 @@ showCmd str = do
["imports"] -> showImports
["modules" ] -> showModules
["bindings"] -> showBindings
- ["linker"] -> liftIO showLinkerState
+ ["linker"] ->
+ do dflags <- getDynFlags
+ liftIO $ showLinkerState dflags
["breaks"] -> showBkptTable
["context"] -> showContext
["packages"] -> showPackages
- ["languages"] -> showLanguages
+ ["languages"] -> showLanguages -- backwards compat
+ ["language"] -> showLanguages
+ ["lang"] -> showLanguages -- useful abbreviation
_ -> ghcError (CmdLineError ("syntax: :show [ args | prog | prompt | editor | stop | modules | bindings\n"++
- " | breaks | context | packages | languages ]"))
+ " | breaks | context | packages | language ]"))
+
+showiCmd :: String -> GHCi ()
+showiCmd str = do
+ case words str of
+ ["languages"] -> showiLanguages -- backwards compat
+ ["language"] -> showiLanguages
+ ["lang"] -> showiLanguages -- useful abbreviation
+ _ -> ghcError (CmdLineError ("syntax: :showi language"))
showImports :: GHCi ()
showImports = do
st <- getGHCiState
+ dflags <- getDynFlags
let rem_ctx = reverse (remembered_ctx st)
trans_ctx = transient_ctx st
show_one (IIModule star_m)
- = ":module +*" ++ moduleNameString (moduleName star_m)
- show_one (IIDecl imp) = showSDoc (ppr imp)
+ = ":module +*" ++ moduleNameString star_m
+ show_one (IIDecl imp) = showPpr dflags imp
prel_imp
| any isPreludeImport (rem_ctx ++ trans_ctx) = []
@@ -2028,11 +2169,11 @@ showBindings = do
pprTT :: PrintExplicitForalls -> (TyThing, Fixity, [GHC.ClsInst]) -> SDoc
pprTT pefas (thing, fixity, _insts) =
pprTyThing pefas thing
- $$ show_fixity fixity
+ $$ show_fixity
where
- show_fixity fix
- | fix == GHC.defaultFixity = empty
- | otherwise = ppr fix <+> ppr (GHC.getName thing)
+ show_fixity
+ | fixity == GHC.defaultFixity = empty
+ | otherwise = ppr fixity <+> ppr (GHC.getName thing)
printTyThing :: TyThing -> GHCi ()
@@ -2056,8 +2197,9 @@ showContext = do
showPackages :: GHCi ()
showPackages = do
- pkg_flags <- fmap packageFlags getDynFlags
- liftIO $ putStrLn $ showSDoc $ vcat $
+ dflags <- getDynFlags
+ let pkg_flags = packageFlags dflags
+ liftIO $ putStrLn $ showSDoc dflags $ vcat $
text ("active package flags:"++if null pkg_flags then " none" else "")
: map showFlag pkg_flags
where showFlag (ExposePackage p) = text $ " -package " ++ p
@@ -2068,18 +2210,42 @@ showPackages = do
showFlag (DistrustPackage p) = text $ " -distrust " ++ p
showLanguages :: GHCi ()
-showLanguages = do
- dflags <- getDynFlags
- liftIO $ putStrLn $ showSDoc $ vcat $
- text "active language flags:" :
- [text (" -X" ++ str) | (str, f, _) <- DynFlags.xFlags, xopt f dflags]
-
+showLanguages = getDynFlags >>= liftIO . showLanguages' False
+
+showiLanguages :: GHCi ()
+showiLanguages = GHC.getInteractiveDynFlags >>= liftIO . showLanguages' False
+
+showLanguages' :: Bool -> DynFlags -> IO ()
+showLanguages' show_all dflags =
+ putStrLn $ showSDoc dflags $ vcat
+ [ text "base language is: " <>
+ case language dflags of
+ Nothing -> text "Haskell2010"
+ Just Haskell98 -> text "Haskell98"
+ Just Haskell2010 -> text "Haskell2010"
+ , (if show_all then text "all active language options:"
+ else text "with the following modifiers:") $$
+ nest 2 (vcat (map (setting xopt) DynFlags.xFlags))
+ ]
+ where
+ setting test (str, f, _)
+ | quiet = empty
+ | is_on = text "-X" <> text str
+ | otherwise = text "-XNo" <> text str
+ where is_on = test f dflags
+ quiet = not show_all && test f default_dflags == is_on
+
+ default_dflags =
+ defaultDynFlags (settings dflags) `lang_set`
+ case language dflags of
+ Nothing -> Just Haskell2010
+ other -> other
-- -----------------------------------------------------------------------------
-- Completion
completeCmd, completeMacro, completeIdentifier, completeModule,
- completeSetModule,
+ completeSetModule, completeSeti, completeShowiOptions,
completeHomeModule, completeSetOptions, completeShowOptions,
completeHomeModuleOrFile, completeExpression
:: CompletionFunc GHCi
@@ -2116,26 +2282,27 @@ completeMacro = wrapIdentCompleter $ \w -> do
completeIdentifier = wrapIdentCompleter $ \w -> do
rdrs <- GHC.getRdrNamesInScope
- return (filter (w `isPrefixOf`) (map (showSDoc.ppr) rdrs))
+ dflags <- GHC.getSessionDynFlags
+ return (filter (w `isPrefixOf`) (map (showPpr dflags) rdrs))
completeModule = wrapIdentCompleter $ \w -> do
dflags <- GHC.getSessionDynFlags
let pkg_mods = allExposedModules dflags
loaded_mods <- liftM (map GHC.ms_mod_name) getLoadedModules
return $ filter (w `isPrefixOf`)
- $ map (showSDoc.ppr) $ loaded_mods ++ pkg_mods
+ $ map (showPpr dflags) $ loaded_mods ++ pkg_mods
completeSetModule = wrapIdentCompleterWithModifier "+-" $ \m w -> do
+ dflags <- GHC.getSessionDynFlags
modules <- case m of
Just '-' -> do
imports <- GHC.getContext
return $ map iiModuleName imports
_ -> do
- dflags <- GHC.getSessionDynFlags
let pkg_mods = allExposedModules dflags
loaded_mods <- liftM (map GHC.ms_mod_name) getLoadedModules
return $ loaded_mods ++ pkg_mods
- return $ filter (w `isPrefixOf`) $ map (showSDoc.ppr) modules
+ return $ filter (w `isPrefixOf`) $ map (showPpr dflags) modules
completeHomeModule = wrapIdentCompleter listHomeModules
@@ -2143,19 +2310,27 @@ listHomeModules :: String -> GHCi [String]
listHomeModules w = do
g <- GHC.getModuleGraph
let home_mods = map GHC.ms_mod_name g
+ dflags <- getDynFlags
return $ sort $ filter (w `isPrefixOf`)
- $ map (showSDoc.ppr) home_mods
+ $ map (showPpr dflags) home_mods
completeSetOptions = wrapCompleter flagWordBreakChars $ \w -> do
return (filter (w `isPrefixOf`) opts)
where opts = "args":"prog":"prompt":"editor":"stop":flagList
flagList = map head $ group $ sort allFlags
+completeSeti = wrapCompleter flagWordBreakChars $ \w -> do
+ return (filter (w `isPrefixOf`) flagList)
+ where flagList = map head $ group $ sort allFlags
+
completeShowOptions = wrapCompleter flagWordBreakChars $ \w -> do
return (filter (w `isPrefixOf`) opts)
where opts = ["args", "prog", "prompt", "editor", "stop",
"modules", "bindings", "linker", "breaks",
- "context", "packages", "languages"]
+ "context", "packages", "language"]
+
+completeShowiOptions = wrapCompleter flagWordBreakChars $ \w -> do
+ return (filter (w `isPrefixOf`) ["language"])
completeHomeModuleOrFile = completeWord Nothing filenameWordBreakChars
$ unionComplete (fmap (map simpleCompletion) . listHomeModules)
@@ -2352,10 +2527,11 @@ breakSwitch (arg1:rest)
| all isDigit arg1 = do
imports <- GHC.getContext
case iiModules imports of
- (md : _) -> breakByModuleLine md (read arg1) rest
+ (mn : _) -> do
+ md <- lookupModuleName mn
+ breakByModuleLine md (read arg1) rest
[] -> do
- liftIO $ putStrLn "Cannot find default module for breakpoint."
- liftIO $ putStrLn "Perhaps no modules are loaded for debugging?"
+ liftIO $ putStrLn "No modules are loaded with debugging support."
| otherwise = do -- try parsing it as an identifier
wantNameFromInterpretedModule noCanDo arg1 $ \name -> do
let loc = GHC.srcSpanStart (GHC.nameSrcSpan name)
@@ -2514,7 +2690,9 @@ list2 [arg] | all isDigit arg = do
imports <- GHC.getContext
case iiModules imports of
[] -> liftIO $ putStrLn "No module to list"
- (md : _) -> listModuleLine md (read arg)
+ (mn : _) -> do
+ md <- lift $ lookupModuleName mn
+ listModuleLine md (read arg)
list2 [arg1,arg2] | looksLikeModuleName arg1, all isDigit arg2 = do
md <- wantInterpretedModule arg1
listModuleLine md (read arg2)
@@ -2718,14 +2896,16 @@ showException :: SomeException -> GHCi ()
showException se =
liftIO $ case fromException se of
-- omit the location for CmdLineError:
- Just (CmdLineError s) -> putStrLn s
+ Just (CmdLineError s) -> putException s
-- ditto:
- Just ph@(PhaseFailed {}) -> putStrLn (showGhcException ph "")
- Just other_ghc_ex -> print other_ghc_ex
+ Just ph@(PhaseFailed {}) -> putException (showGhcException ph "")
+ Just other_ghc_ex -> putException (show other_ghc_ex)
Nothing ->
case fromException se of
- Just UserInterrupt -> putStrLn "Interrupted."
- _ -> putStrLn ("*** Exception: " ++ show se)
+ Just UserInterrupt -> putException "Interrupted."
+ _ -> putException ("*** Exception: " ++ show se)
+ where
+ putException = hPutStrLn stderr
-----------------------------------------------------------------------------
@@ -2735,8 +2915,8 @@ showException se =
-- in an exception loop (eg. let a = error a in a) the ^C exception
-- may never be delivered. Thanks to Marcin for pointing out the bug.
-ghciHandle :: MonadException m => (SomeException -> m a) -> m a -> m a
-ghciHandle h m = Haskeline.catch m $ \e -> unblock (h e)
+ghciHandle :: ExceptionMonad m => (SomeException -> m a) -> m a -> m a
+ghciHandle h m = gcatch m $ \e -> gunblock (h e)
ghciTry :: GHCi a -> GHCi (Either SomeException a)
ghciTry (GHCi m) = GHCi $ \s -> gtry (m s)
@@ -2752,7 +2932,10 @@ tryBool m = do
-- Utils
lookupModule :: GHC.GhcMonad m => String -> m Module
-lookupModule mName = GHC.lookupModule (GHC.mkModuleName mName) Nothing
+lookupModule mName = lookupModuleName (GHC.mkModuleName mName)
+
+lookupModuleName :: GHC.GhcMonad m => ModuleName -> m Module
+lookupModuleName mName = GHC.lookupModule mName Nothing
isHomeModule :: Module -> Bool
isHomeModule m = GHC.modulePackageId m == mainPackageId
@@ -2760,10 +2943,7 @@ isHomeModule m = GHC.modulePackageId m == mainPackageId
-- TODO: won't work if home dir is encoded.
-- (changeDirectory may not work either in that case.)
expandPath :: MonadIO m => String -> InputT m String
-expandPath p = do
- exp_path <- liftIO $ expandPathIO p
- e <- fmap BS.unpack $ Encoding.encode exp_path
- return e
+expandPath = liftIO . expandPathIO
expandPathIO :: String -> IO String
expandPathIO p =
@@ -2775,8 +2955,12 @@ expandPathIO p =
return other
wantInterpretedModule :: GHC.GhcMonad m => String -> m Module
-wantInterpretedModule str = do
- modl <- lookupModule str
+wantInterpretedModule str = wantInterpretedModuleName (GHC.mkModuleName str)
+
+wantInterpretedModuleName :: GHC.GhcMonad m => ModuleName -> m Module
+wantInterpretedModuleName modname = do
+ modl <- lookupModuleName modname
+ let str = moduleNameString modname
dflags <- getDynFlags
when (GHC.modulePackageId modl /= thisPackage dflags) $
ghcError (CmdLineError ("module '" ++ str ++ "' is from another package;\nthis command requires an interpreted module"))
diff --git a/ghc/Main.hs b/ghc/Main.hs
index a1943cff50..d757c2d706 100644
--- a/ghc/Main.hs
+++ b/ghc/Main.hs
@@ -30,6 +30,7 @@ import InteractiveUI ( interactiveUI, ghciWelcomeMsg )
-- Various other random stuff that we need
import Config
+import Constants
import HscTypes
import Packages ( dumpPackages )
import DriverPhases ( Phase(..), isSourceFilename, anyHsc,
@@ -78,7 +79,8 @@ import Data.Maybe
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
- GHC.defaultErrorHandler defaultLogAction $ do
+ hSetBuffering stderr NoBuffering
+ GHC.defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
-- 1. extract the -B flag from the args
argv0 <- getArgs
@@ -155,6 +157,8 @@ main' postLoadMode dflags0 args flagWarnings = do
-- turn on -fimplicit-import-qualified for GHCi now, so that it
-- can be overriden from the command-line
+ -- XXX: this should really be in the interactive DynFlags, but
+ -- we don't set that until later in interactiveUI
dflags1a | DoInteractive <- postLoadMode = imp_qual_enabled
| DoEval _ <- postLoadMode = imp_qual_enabled
| otherwise = dflags1
@@ -164,6 +168,8 @@ main' postLoadMode dflags0 args flagWarnings = do
-- Leftover ones are presumably files
(dflags2, fileish_args, dynamicFlagWarnings) <- GHC.parseDynamicFlags dflags1a args
+ GHC.prettyPrintGhcErrors dflags2 $ do
+
let flagWarnings' = flagWarnings ++ dynamicFlagWarnings
handleSourceError (\e -> do
@@ -253,6 +259,10 @@ partition_args (arg:args) srcs objs
- module names (not forgetting hierarchical module names),
+ - things beginning with '-' are flags that were not recognised by
+ the flag parser, and we want them to generate errors later in
+ checkOptions, so we class them as source files (#5921)
+
- and finally we consider everything not containing a '.' to be
a comp manager input, as shorthand for a .hs or .lhs filename.
@@ -262,6 +272,7 @@ partition_args (arg:args) srcs objs
looks_like_an_input :: String -> Bool
looks_like_an_input m = isSourceFilename m
|| looksLikeModuleName m
+ || "-" `isPrefixOf` m
|| '.' `notElem` m
-- -----------------------------------------------------------------------------
@@ -760,7 +771,7 @@ abiHash strs = do
r <- findImportedModule hsc_env modname Nothing
case r of
Found _ m -> return m
- _error -> ghcError $ CmdLineError $ showSDoc $
+ _error -> ghcError $ CmdLineError $ showSDoc dflags $
cannotFindInterface dflags modname r
mods <- mapM find_it (map fst strs)
@@ -769,13 +780,13 @@ abiHash strs = do
ifaces <- initIfaceCheck hsc_env $ mapM get_iface mods
bh <- openBinMem (3*1024) -- just less than a block
- put_ bh opt_HiVersion
+ put_ bh hiVersion
-- package hashes change when the compiler version changes (for now)
-- see #5328
mapM_ (put_ bh . mi_mod_hash) ifaces
f <- fingerprintBinMem bh
- putStrLn (showSDoc (ppr f))
+ putStrLn (showPpr dflags f)
-- -----------------------------------------------------------------------------
-- Util
diff --git a/ghc/ghc-bin.cabal.in b/ghc/ghc-bin.cabal.in
index 0cf51d05e1..a7e7bbae66 100644
--- a/ghc/ghc-bin.cabal.in
+++ b/ghc/ghc-bin.cabal.in
@@ -27,7 +27,7 @@ Executable ghc
Main-Is: Main.hs
Build-Depends: base >= 3 && < 5,
array >= 0.1 && < 0.5,
- bytestring >= 0.9 && < 0.10,
+ bytestring >= 0.9 && < 0.11,
directory >= 1 && < 1.2,
process >= 1 && < 1.2,
filepath >= 1 && < 1.4,
@@ -44,7 +44,7 @@ Executable ghc
CPP-Options: -DGHCI
GHC-Options: -fno-warn-name-shadowing
Other-Modules: InteractiveUI, GhciMonad, GhciTags
- Build-Depends: mtl, haskeline
+ Build-Depends: transformers, haskeline
Extensions: ForeignFunctionInterface,
UnboxedTuples,
FlexibleInstances,
diff --git a/ghc/ghc.mk b/ghc/ghc.mk
index 022ee85a84..a13f03b875 100644
--- a/ghc/ghc.mk
+++ b/ghc/ghc.mk
@@ -22,6 +22,15 @@ ghc_stage2_CONFIGURE_OPTS += --flags=ghci
ghc_stage3_CONFIGURE_OPTS += --flags=ghci
endif
+ifeq "$(compiler_stage1_VERSION_MUNGED)" "YES"
+# If we munge the stage1 version, and we're using a devel snapshot for
+# stage0, then stage1 may actually have an earlier version than stage0
+# (e.g. boot with ghc-7.5.20120316, building ghc-7.5). We therefore
+# need to tell Cabal to use version 7.5 of the ghc package when building
+# in ghc/stage1
+ghc_stage1_CONFIGURE_OPTS += --constraint "ghc == $(compiler_stage1_MUNGED_VERSION)"
+endif
+
ghc_stage1_MORE_HC_OPTS = $(GhcStage1HcOpts)
ghc_stage2_MORE_HC_OPTS = $(GhcStage2HcOpts)
ghc_stage3_MORE_HC_OPTS = $(GhcStage3HcOpts)
@@ -148,7 +157,7 @@ INSTALL_LIBS += settings
ifeq "$(Windows)" "NO"
install: install_ghc_link
-.PNONY: install_ghc_link
+.PHONY: install_ghc_link
install_ghc_link:
$(call removeFiles,"$(DESTDIR)$(bindir)/ghc")
$(LN_S) $(CrossCompilePrefix)ghc-$(ProjectVersion) "$(DESTDIR)$(bindir)/$(CrossCompilePrefix)ghc"
diff --git a/ghc/hschooks.c b/ghc/hschooks.c
index 037d4e18be..232ac08045 100644
--- a/ghc/hschooks.c
+++ b/ghc/hschooks.c
@@ -4,6 +4,7 @@ for various bits of the RTS. They are linked
in instead of the defaults.
*/
+#include "../rts/PosixSource.h"
#include "Rts.h"
#include "HsFFI.h"
@@ -31,8 +32,8 @@ defaultsHook (void)
}
void
-StackOverflowHook (unsigned long stack_size) /* in bytes */
+StackOverflowHook (lnat stack_size) /* in bytes */
{
- fprintf(stderr, "GHC stack-space overflow: current limit is %ld bytes.\nUse the `-K<size>' option to increase it.\n", stack_size);
+ fprintf(stderr, "GHC stack-space overflow: current limit is %zu bytes.\nUse the `-K<size>' option to increase it.\n", (size_t)stack_size);
}