on master help sign in
Improve error pretty printing
62cbd42mrkkrp
src/Ormolu.hs+1−1
@@ -67,7 +67,7 @@ ormolu cfg path str = do
67 (T.unpack txt)
67 (T.unpack txt)
68 case diff result0 result1 of
68 case diff result0 result1 of
69 Same -> return ()
69 Same -> return ()
70− Different ss -> liftIO $ throwIO (OrmoluASTDiffers ss str txt)
70+ Different ss -> liftIO $ throwIO (OrmoluASTDiffers path ss)
71 return txt
71 return txt
72
72
73-- | Load a file and format it. The file stays intact and the rendered
73-- | Load a file and format it. The file stays intact and the rendered
src/Ormolu/Diff.hs+4−2
@@ -84,6 +84,8 @@ matchIgnoringSrcSpans = genericQuery
84 maybe id appendSpan (cast mspn) (genericQuery x y)
84 maybe id appendSpan (cast mspn) (genericQuery x y)
85
85
86 appendSpan :: SrcSpan -> Diff -> Diff
86 appendSpan :: SrcSpan -> Diff -> Diff
87− appendSpan s (Different ss) | fresh = Different (s:ss)
87+ appendSpan s (Different ss) | fresh && helpful = Different (s:ss)
88+ where
88− where fresh = not $ any (flip isSubspanOf s) ss
89+ fresh = not $ any (flip isSubspanOf s) ss
90+ helpful = isGoodSrcSpan s
89 appendSpan _ d = d
91 appendSpan _ d = d
src/Ormolu/Exception.hs+25−15
@@ -9,7 +9,6 @@ module Ormolu.Exception
9where
9where
10
10
11import Control.Exception
11import Control.Exception
12−import Data.Text (Text)
13import Ormolu.Utils (showOutputable)
12import Ormolu.Utils (showOutputable)
14import System.Exit (ExitCode (..), exitWith)
13import System.Exit (ExitCode (..), exitWith)
15import System.IO
14import System.IO
@@ -18,29 +17,35 @@ import qualified GHC
18-- | Ormolu exception representing all cases when Ormolu can fail.
17-- | Ormolu exception representing all cases when Ormolu can fail.
19
18
20data OrmoluException
19data OrmoluException
21− = OrmoluCppEnabled
20+ = OrmoluCppEnabled FilePath
22 -- ^ Ormolu does not work with source files that use CPP
21 -- ^ Ormolu does not work with source files that use CPP
23 | OrmoluParsingFailed GHC.SrcSpan String
22 | OrmoluParsingFailed GHC.SrcSpan String
24 -- ^ Parsing of original source code failed
23 -- ^ Parsing of original source code failed
25 | OrmoluOutputParsingFailed GHC.SrcSpan String
24 | OrmoluOutputParsingFailed GHC.SrcSpan String
26 -- ^ Parsing of formatted source code failed
25 -- ^ Parsing of formatted source code failed
27− | OrmoluASTDiffers [GHC.SrcSpan] String Text
26+ | OrmoluASTDiffers FilePath [GHC.SrcSpan]
28− -- ^ Original and resulting ASTs differ, first argument is the original
27+ -- ^ Original and resulting ASTs differ
29− -- source code, second argument is rendered source code
30 deriving (Eq, Show)
28 deriving (Eq, Show)
31
29
32instance Exception OrmoluException where
30instance Exception OrmoluException where
33 displayException = \case
31 displayException = \case
32+ OrmoluCppEnabled path -> unlines
34− OrmoluCppEnabled -> "CPP is not supported"
33+ [ "CPP is not supported:"
34+ , withIndent path
35+ ]
35 OrmoluParsingFailed s e ->
36 OrmoluParsingFailed s e ->
36 showParsingErr "Parsing of source code failed:" s e
37 showParsingErr "Parsing of source code failed:" s e
37 OrmoluOutputParsingFailed s e ->
38 OrmoluOutputParsingFailed s e ->
38 showParsingErr "Parsing of formatted code failed:" s e ++
39 showParsingErr "Parsing of formatted code failed:" s e ++
39− "Please, consider reporting the bug."
40+ "Please, consider reporting the bug.\n"
40− OrmoluASTDiffers ss _ _ -> unlines $
41+ OrmoluASTDiffers path ss -> unlines $
41− ["AST of input and AST of formatted code differ."]
42+ [ "AST of input and AST of formatted code differ."
43+ ]
42− ++ map (\s -> " at " ++ showOutputable s) ss ++
44+ ++ (fmap withIndent $ case fmap (\s -> "at " ++ showOutputable s) ss of
45+ [] -> ["in " ++ path]
46+ xs -> xs) ++
43− ["Please, consider reporting the bug."]
47+ [ "Please, consider reporting the bug."
48+ ]
44
49
45-- | Inside this wrapper 'OrmoluException' will be caught and displayed
50-- | Inside this wrapper 'OrmoluException' will be caught and displayed
46-- nicely using 'displayException'.
51-- nicely using 'displayException'.
@@ -56,10 +61,10 @@ withPrettyOrmoluExceptions m = m `catch` h
56 exitWith . ExitFailure $
61 exitWith . ExitFailure $
57 case e of
62 case e of
58 -- Error code 1 is for `error` or `notImplemented`
63 -- Error code 1 is for `error` or `notImplemented`
59− OrmoluCppEnabled -> 2
64+ OrmoluCppEnabled _ -> 2
60 OrmoluParsingFailed _ _ -> 3
65 OrmoluParsingFailed _ _ -> 3
61 OrmoluOutputParsingFailed _ _ -> 4
66 OrmoluOutputParsingFailed _ _ -> 4
62− OrmoluASTDiffers _ _ _ -> 5
67+ OrmoluASTDiffers _ _ -> 5
63
68
64----------------------------------------------------------------------------
69----------------------------------------------------------------------------
65-- Helpers
70-- Helpers
@@ -69,6 +74,11 @@ withPrettyOrmoluExceptions m = m `catch` h
69showParsingErr :: String -> GHC.SrcSpan -> String -> String
74showParsingErr :: String -> GHC.SrcSpan -> String -> String
70showParsingErr msg spn err = unlines
75showParsingErr msg spn err = unlines
71 [ msg
76 [ msg
72− , showOutputable spn
77+ , withIndent (showOutputable spn)
73− , err
78+ , withIndent err
74 ]
79 ]
80+
81+-- | Indent with 2 spaces for readability.
82+
83+withIndent :: String -> String
84+withIndent txt = " " ++ txt
src/Ormolu/Parser.hs+1−1
@@ -54,7 +54,7 @@ parseModule dynOpts path input' = liftIO $ do
54 -- otherwise the exception will be wrapped as a GHC panic, which we don't
54 -- otherwise the exception will be wrapped as a GHC panic, which we don't
55 -- want.
55 -- want.
56 when (GHC.xopt Cpp dynFlags) $
56 when (GHC.xopt Cpp dynFlags) $
57− throwIO OrmoluCppEnabled
57+ throwIO (OrmoluCppEnabled path)
58 let r = case runParser GHC.parseModule dynFlags path input of
58 let r = case runParser GHC.parseModule dynFlags path input of
59 GHC.PFailed _ ss m ->
59 GHC.PFailed _ ss m ->
60 Left (ss, GHC.showSDoc dynFlags m)
60 Left (ss, GHC.showSDoc dynFlags m)