@@ -50,6 +50,9 @@ import Language.PureScript.Kinds
50import qualified Text.PrettyPrint.Boxes as Box
50import qualified Text.PrettyPrint.Boxes as Box
52import qualified Text.Parsec as P
52import qualified Text.Parsec as P
53+import qualified Text.Parsec.Error as PE
54+import Text.Parsec.Error (Message(..))
55+import Data.List (nub)
55-- A type of error messages
58-- A type of error messages
@@ -412,7 +415,7 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
413 goSimple (ErrorParsingExterns err) =
416 goSimple (ErrorParsingExterns err) =
414 paras [ lineWithLevel "parsing externs files: "
417 paras [ lineWithLevel "parsing externs files: "
415− , indent . line . show $ err
418+ , indent . prettyPrintParseError $ err
417 goSimple (ErrorParsingFFIModule path) =
420 goSimple (ErrorParsingFFIModule path) =
418 paras [ line "Unable to parse module from FFI file: "
421 paras [ line "Unable to parse module from FFI file: "
@@ -420,7 +423,7 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
421 goSimple (ErrorParsingModule err) =
424 goSimple (ErrorParsingModule err) =
422 paras [ line "Unable to parse module: "
425 paras [ line "Unable to parse module: "
423− , indent . line . show $ err
426+ , indent . prettyPrintParseError $ err
425 goSimple (MissingFFIModule mn) =
428 goSimple (MissingFFIModule mn) =
426 line $ "Missing FFI implementations for module " ++ show mn
429 line $ "Missing FFI implementations for module " ++ show mn
@@ -722,9 +725,6 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
723 go (SimpleErrorWrapper sem) = goSimple sem
726 go (SimpleErrorWrapper sem) = goSimple sem
725− line :: String -> Box.Box
728 lineWithLevel :: String -> Box.Box
728 lineWithLevel :: String -> Box.Box
729 lineWithLevel text = line $ show level ++ " " ++ text
729 lineWithLevel text = line $ show level ++ " " ++ text
@@ -742,9 +742,6 @@ prettyPrintSingleError full level e = prettyPrintErrorMessage <$> onTypesInError
742 paras :: [Box.Box] -> Box.Box
742 paras :: [Box.Box] -> Box.Box
743 paras = Box.vcat Box.left
743 paras = Box.vcat Box.left
745− indent :: Box.Box -> Box.Box
746− indent = Box.moveRight 2
749 -- Pretty print and export declaration
746 -- Pretty print and export declaration
@@ -822,6 +819,60 @@ prettyPrintMultipleErrorsWith level _ intro full (MultipleErrors es) = do
822 , Box.vsep 1 Box.left result
819 , Box.vsep 1 Box.left result
822+-- | Pretty print a Parsec ParseError as a Box
823+prettyPrintParseError :: P.ParseError -> Box.Box
824+prettyPrintParseError = (prettyPrintParseErrorMessages "or" "unknown parse error" "expecting" "unexpected" "end of input") . PE.errorMessages
827+-- Pretty print ParseError detail messages.
829+-- Adapted from 'Text.Parsec.Error.showErrorMessages', see <https://github.com/aslatter/parsec/blob/v3.1.9/Text/Parsec/Error.hs#L173>.
831+prettyPrintParseErrorMessages :: String -> String -> String -> String -> String -> [Message] -> Box.Box
832+prettyPrintParseErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEndOfInput msgs
833+ | null msgs = Box.text msgUnknown
834+ | otherwise = Box.vcat Box.left $ map Box.text $ clean [showSysUnExpect,showUnExpect,showExpect,showMessages]
837+ (sysUnExpect,msgs1) = span ((SysUnExpect "") ==) msgs
838+ (unExpect,msgs2) = span ((UnExpect "") ==) msgs1
839+ (expect,messages) = span ((Expect "") ==) msgs2
841+ showExpect = showMany msgExpecting expect
842+ showUnExpect = showMany msgUnExpected unExpect
843+ showSysUnExpect | not (null unExpect) ||
844+ null sysUnExpect = ""
845+ | null firstMsg = msgUnExpected ++ " " ++ msgEndOfInput
846+ | otherwise = msgUnExpected ++ " " ++ firstMsg
848+ firstMsg = PE.messageString (head sysUnExpect)
850+ showMessages = showMany "" messages
853+ showMany pre msgs' = case clean (map PE.messageString msgs') of
855+ ms | null pre -> commasOr ms
856+ | otherwise -> pre ++ " " ++ commasOr ms
860+ commasOr ms = commaSep (init ms) ++ " " ++ msgOr ++ " " ++ last ms
862+ commaSep = separate ", " . clean
866+ separate sep (m:ms) = m ++ sep ++ separate sep ms
868+ clean = nub . filter (not . null)
870+indent :: Box.Box -> Box.Box
871+indent = Box.moveRight 2
873+line :: String -> Box.Box
825renderBox :: Box.Box -> String
876renderBox :: Box.Box -> String
826renderBox = unlines . map trimEnd . lines . Box.render
877renderBox = unlines . map trimEnd . lines . Box.render