on 2c8bd43 help sign in
elk/src/Reporting/Report.hs
114 lines 2.9 kB history raw
1module Reporting.Report
2 ( Report(Report)
3 , simple
4 , toString
5 ) where
7import Elm.Utils ((|>))
8import qualified Reporting.Region as R
11data Report = Report
12 { highlight :: Maybe R.Region
13 , preHint :: String
14 , postHint :: String
15 }
18simple :: String -> String -> Report
19simple pre post =
20 Report Nothing pre post
23toString :: String -> String -> R.Region -> Report -> String -> String
24toString tag location region report source =
25 concat
26 [ messageBar tag location
27 , preHint report ++ "\n\n"
28 , grabRegion (highlight report) region source ++ "\n"
29 , postHint report ++ "\n\n\n"
30 ]
33-- REPORT HEADER
35messageBar :: String -> String -> String
36messageBar tag location =
37 let usedSpace = 4 + length tag + 1 + length location
38 in
39 "-- " ++ tag ++ " "
40 ++ replicate (max 1 (80 - usedSpace)) '-'
41 ++ " " ++ location ++ "\n\n"
44-- REGIONS
46grabRegion :: Maybe R.Region -> R.Region -> String -> String
47grabRegion maybeSubRegion (R.Region start end) source =
48 let
49 (R.Position startLine startColumn) = start
50 (R.Position endLine endColumn) = end
52 relevantLines =
53 lines source
54 |> drop (startLine - 1)
55 |> take (endLine - startLine + 1)
56 in
57 case relevantLines of
58 [] ->
59 error "something has gone badly wrong with reporting source locations"
61 [theLine] ->
62 let
63 n = startLine
64 w = length (show (n + 1))
65 underline =
66 replicate (startColumn - 1) ' '
67 ++ replicate (max 1 (endColumn - startColumn)) '^'
68 number =
69 addLineNumber Nothing w
70 in
71 unlines
72 [ number (n-1) ""
73 , number n theLine
74 , number (n+1) underline
75 ]
77 firstLine : rest ->
78 let
79 filteredFirstLine =
80 replicate (startColumn - 1) ' '
81 ++ drop (startColumn - 1) firstLine
83 filteredLastLine =
84 take (endColumn) (last rest)
86 focusedRelevantLines =
87 filteredFirstLine : init rest ++ [filteredLastLine]
89 lineNumbersWidth =
90 length (show (endLine + 1))
92 numberedLines =
93 zipWith
94 (addLineNumber maybeSubRegion lineNumbersWidth)
95 [startLine - 1 .. endLine + 1]
96 ("" : focusedRelevantLines ++ [""])
97 in
98 unlines numberedLines
101addLineNumber :: Maybe R.Region -> Int -> Int -> String -> String
102addLineNumber maybeSubRegion width n line =
103 let
104 number =
105 if n < 0 then " " else show n
107 spacer (R.Region start end) =
108 if R.line start <= n && n <= R.line end
109 then ">"
110 else " "
111 in
112 replicate (width - length number) ' ' ++ number
113 ++ "|" ++ maybe " " spacer maybeSubRegion
114 ++ line