diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2017-01-30 11:53:17 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-01-30 14:00:23 -0500 |
commit | 91691117fc194c525f58ccd5b266dd1d10493e5a (patch) | |
tree | c9fd4334d5bb2441ad4c75a57697cd80462f492e /compiler/utils/Json.hs | |
parent | 7363d5380e600e2ef868a069d5df6857d9e5c17e (diff) | |
download | haskell-91691117fc194c525f58ccd5b266dd1d10493e5a.tar.gz |
Add a flag to emit error messages as JSON
This patch adds the flag `-ddump-json` which dumps all the compiler
output as a JSON array. This allows tooling to more easily parse GHC's
output to display to users.
The flag is currently experimental and will hopefully be refined for the
next release. In particular I have avoided any changes which involve
significant refactoring and provided what is easy given the current
infrastructure.
Reviewers: austin, bgamari
Reviewed By: bgamari
Subscribers: DanielG, gracjan, thomie
Differential Revision: https://phabricator.haskell.org/D3010
GHC Trac Issues: #13190
Diffstat (limited to 'compiler/utils/Json.hs')
-rw-r--r-- | compiler/utils/Json.hs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/compiler/utils/Json.hs b/compiler/utils/Json.hs new file mode 100644 index 0000000000..1318ce2611 --- /dev/null +++ b/compiler/utils/Json.hs @@ -0,0 +1,54 @@ +{-# LANGUAGE GADTs #-} +module Json where + +import Outputable +import Data.Char +import Numeric + +-- | Simple data type to represent JSON documents. +data JsonDoc where + JSNull :: JsonDoc + JSBool :: Bool -> JsonDoc + JSInt :: Int -> JsonDoc + JSString :: String -> JsonDoc + JSArray :: [JsonDoc] -> JsonDoc + JSObject :: [(String, JsonDoc)] -> JsonDoc + + +-- This is simple and slow as it is only used for error reporting +renderJSON :: JsonDoc -> SDoc +renderJSON d = + case d of + JSNull -> text "null" + JSBool b -> text $ if b then "true" else "false" + JSInt n -> ppr n + JSString s -> doubleQuotes $ text $ escapeJsonString s + JSArray as -> brackets $ pprList renderJSON as + JSObject fs -> braces $ pprList renderField fs + where + renderField :: (String, JsonDoc) -> SDoc + renderField (s, j) = doubleQuotes (text s) <> colon <+> renderJSON j + + pprList pp xs = hcat (punctuate comma (map pp xs)) + +escapeJsonString :: String -> String +escapeJsonString = concatMap escapeChar + where + escapeChar '\b' = "\\b" + escapeChar '\f' = "\\f" + escapeChar '\n' = "\\n" + escapeChar '\r' = "\\r" + escapeChar '\t' = "\\t" + escapeChar '"' = "\"" + escapeChar '\\' = "\\\\" + escapeChar c | isControl c || fromEnum c >= 0x7f = uni_esc c + escapeChar c = [c] + + uni_esc c = "\\u" ++ (pad 4 (showHex (fromEnum c) "")) + + pad n cs | len < n = replicate (n-len) '0' ++ cs + | otherwise = cs + where len = length cs + +class ToJson a where + json :: a -> JsonDoc |