summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2018-05-13 11:39:34 -0400
committerBen Gamari <ben@smart-cactus.org>2018-05-13 18:30:43 -0400
commit6ab7cf995dafcc9196e87bbde76b4f6937507592 (patch)
tree499b36d722e3caa22b07fcc73f2138fd37f8b033 /compiler/main
parent00049e2dce93b1e468c3fde3287371eb988aafdc (diff)
downloadhaskell-6ab7cf995dafcc9196e87bbde76b4f6937507592.tar.gz
Simplify -ddump-json implementation
This patch takes the much simpler route of whenever the compiler tries to output something. We just dump a JSON document there and then. I think this should be sufficient to work with and anything more refined quickly got complicated as it was necessary to demarcate message scopes and so on. Reviewers: bgamari, dfeuer Reviewed By: bgamari Subscribers: Phyx, dfeuer, rwbarton, thomie, carter GHC Trac Issues: #14078 Differential Revision: https://phabricator.haskell.org/D4532
Diffstat (limited to 'compiler/main')
-rw-r--r--compiler/main/DriverPipeline.hs3
-rw-r--r--compiler/main/DynFlags.hs87
-rw-r--r--compiler/main/GHC.hs8
3 files changed, 25 insertions, 73 deletions
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index 1d78bee14a..0ed65d39fd 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -266,8 +266,7 @@ compileOne' m_tc_result mHscMessage
prevailing_dflags = hsc_dflags hsc_env0
dflags =
dflags1 { includePaths = addQuoteInclude old_paths [current_dir]
- , log_action = log_action prevailing_dflags
- , log_finaliser = log_finaliser prevailing_dflags }
+ , log_action = log_action prevailing_dflags }
-- use the prevailing log_action / log_finaliser,
-- not the one cached in the summary. This is so
-- that we can change the log_action without having
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index 6e839cc390..c80f55213c 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -24,7 +24,7 @@ module DynFlags (
WarningFlag(..), WarnReason(..),
Language(..),
PlatformConstants(..),
- FatalMessager, LogAction, LogFinaliser, FlushOut(..), FlushErr(..),
+ FatalMessager, LogAction, FlushOut(..), FlushErr(..),
ProfAuto(..),
glasgowExtsFlags,
warningGroups, warningHierarchies,
@@ -203,7 +203,7 @@ import Outputable
import Foreign.C ( CInt(..) )
import System.IO.Unsafe ( unsafeDupablePerformIO )
import {-# SOURCE #-} ErrUtils ( Severity(..), MsgDoc, mkLocMessageAnn
- , getCaretDiagnostic, dumpSDoc )
+ , getCaretDiagnostic )
import Json
import SysTools.Terminal ( stderrSupportsAnsiColors )
import SysTools.BaseDir ( expandToolDir, expandTopDir )
@@ -1036,9 +1036,7 @@ data DynFlags = DynFlags {
ghciHistSize :: Int,
-- | MsgDoc output action: use "ErrUtils" instead of this if you can
- initLogAction :: IO (Maybe LogOutput),
log_action :: LogAction,
- log_finaliser :: LogFinaliser,
flushOut :: FlushOut,
flushErr :: FlushErr,
@@ -1872,10 +1870,7 @@ defaultDynFlags mySettings myLlvmTargets =
-- Logging
- initLogAction = defaultLogOutput,
-
log_action = defaultLogAction,
- log_finaliser = \ _ -> return (),
flushOut = defaultFlushOut,
flushErr = defaultFlushErr,
@@ -1936,9 +1931,10 @@ interpreterDynamic dflags
-- Note [JSON Error Messages]
--
-- When the user requests the compiler output to be dumped as json
--- we modify the log_action to collect all the messages in an IORef
--- and then finally in GHC.withCleanupSession the log_finaliser is
--- called which prints out the messages together.
+-- we used to collect them all in an IORef and then print them at the end.
+-- This doesn't work very well with GHCi. (See #14078) So instead we now
+-- use the simpler method of just outputting a JSON document inplace to
+-- stdout.
--
-- Before the compiler calls log_action, it has already turned the `ErrMsg`
-- into a formatted message. This means that we lose some possible
@@ -1948,14 +1944,6 @@ interpreterDynamic dflags
type FatalMessager = String -> IO ()
-data LogOutput = LogOutput
- { getLogAction :: LogAction
- , getLogFinaliser :: LogFinaliser
- }
-
-defaultLogOutput :: IO (Maybe LogOutput)
-defaultLogOutput = return $ Nothing
-
type LogAction = DynFlags
-> WarnReason
-> Severity
@@ -1964,41 +1952,24 @@ type LogAction = DynFlags
-> MsgDoc
-> IO ()
-type LogFinaliser = DynFlags -> IO ()
-
defaultFatalMessager :: FatalMessager
defaultFatalMessager = hPutStrLn stderr
-- See Note [JSON Error Messages]
-jsonLogOutput :: IO (Maybe LogOutput)
-jsonLogOutput = do
- ref <- newIORef []
- return . Just $ LogOutput (jsonLogAction ref) (jsonLogFinaliser ref)
-
-jsonLogAction :: IORef [SDoc] -> LogAction
-jsonLogAction iref dflags reason severity srcSpan style msg
+--
+jsonLogAction :: LogAction
+jsonLogAction dflags reason severity srcSpan _style msg
= do
- addMessage . withPprStyle (mkCodeStyle CStyle) . renderJSON $
- JSObject [ ( "span", json srcSpan )
- , ( "doc" , JSString (showSDoc dflags msg) )
- , ( "severity", json severity )
- , ( "reason" , json reason )
- ]
- defaultLogAction dflags reason severity srcSpan style msg
- where
- addMessage m = modifyIORef iref (m:)
-
-
-jsonLogFinaliser :: IORef [SDoc] -> DynFlags -> IO ()
-jsonLogFinaliser iref dflags = do
- msgs <- readIORef iref
- let fmt_msgs = brackets $ pprWithCommas (blankLine $$) msgs
- output fmt_msgs
- where
- -- dumpSDoc uses log_action to output the dump
- dflags' = dflags { log_action = defaultLogAction }
- output doc = dumpSDoc dflags' neverQualify Opt_D_dump_json "" doc
+ defaultLogActionHPutStrDoc dflags stdout (doc $$ text "")
+ (mkCodeStyle CStyle)
+ where
+ doc = renderJSON $
+ JSObject [ ( "span", json srcSpan )
+ , ( "doc" , JSString (showSDoc dflags msg) )
+ , ( "severity", json severity )
+ , ( "reason" , json reason )
+ ]
defaultLogAction :: LogAction
@@ -2395,7 +2366,7 @@ setDynOutputFile f d = d { dynOutputFile = f}
setOutputHi f d = d { outputHi = f}
setJsonLogAction :: DynFlags -> DynFlags
-setJsonLogAction d = d { initLogAction = jsonLogOutput }
+setJsonLogAction d = d { log_action = jsonLogAction }
thisComponentId :: DynFlags -> ComponentId
thisComponentId dflags =
@@ -2614,27 +2585,11 @@ parseDynamicFlagsFull activeFlags cmdline dflags0 args = do
Just x -> liftIO (setHeapSize x)
_ -> return ()
- dflags7 <- liftIO $ setLogAction dflags5
-
- liftIO $ setUnsafeGlobalDynFlags dflags7
+ liftIO $ setUnsafeGlobalDynFlags dflags5
let warns' = map (Warn Cmd.NoReason) (consistency_warnings ++ sh_warns)
- return (dflags7, leftover, warns' ++ warns)
-
-setLogAction :: DynFlags -> IO DynFlags
-setLogAction dflags = do
- mlogger <- initLogAction dflags
- return $
- maybe
- dflags
- (\logger ->
- dflags
- { log_action = getLogAction logger
- , log_finaliser = getLogFinaliser logger
- , initLogAction = return $ Nothing -- Don't initialise it twice
- })
- mlogger
+ return (dflags5, leftover, warns' ++ warns)
-- | Write an error or warning to the 'LogOutput'.
putLogMsg :: DynFlags -> WarnReason -> Severity -> SrcSpan -> PprStyle
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs
index 1e54f0efac..5f1eba5310 100644
--- a/compiler/main/GHC.hs
+++ b/compiler/main/GHC.hs
@@ -472,7 +472,6 @@ withCleanupSession ghc = ghc `gfinally` cleanup
cleanTempFiles dflags
cleanTempDirs dflags
stopIServ hsc_env -- shut down the IServ
- log_finaliser dflags dflags
-- exceptions will be blocked while we clean the temporary files,
-- so there shouldn't be any difficulty if we receive further
-- signals.
@@ -592,12 +591,11 @@ setProgramDynFlags dflags = setProgramDynFlags_ True dflags
-- | Set the action taken when the compiler produces a message. This
-- can also be accomplished using 'setProgramDynFlags', but using
-- 'setLogAction' avoids invalidating the cached module graph.
-setLogAction :: GhcMonad m => LogAction -> LogFinaliser -> m ()
-setLogAction action finaliser = do
+setLogAction :: GhcMonad m => LogAction -> m ()
+setLogAction action = do
dflags' <- getProgramDynFlags
void $ setProgramDynFlags_ False $
- dflags' { log_action = action
- , log_finaliser = finaliser }
+ dflags' { log_action = action }
setProgramDynFlags_ :: GhcMonad m => Bool -> DynFlags -> m [InstalledUnitId]
setProgramDynFlags_ invalidate_needed dflags = do