packages feed

diagnose 1.8.1 → 1.8.2

raw patch · 4 files changed

+141/−67 lines, 4 filesdep ~textPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: text

API changes (from Hackage documentation)

Files

diagnose.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           diagnose-version:        1.8.1+version:        1.8.2 synopsis:       Beautiful error reporting done easily description:    This package provides a simple way of getting beautiful compiler/interpreter errors                 using a very simple interface for the programmer.@@ -69,7 +69,6 @@     , hashable >=1.3 && <2     , prettyprinter >=1.7.0 && <2     , prettyprinter-ansi-terminal >=1.1.0 && <2-    , text >=1.2 && <2     , unordered-containers ==0.2.*     , wcwidth >=0.0.1 && <1   if flag(json)@@ -111,7 +110,7 @@     , hashable >=1.3 && <2     , prettyprinter >=1.7.0 && <2     , prettyprinter-ansi-terminal >=1.1.0 && <2-    , text >=1.2 && <2+    , text >=1.2 && <3     , unordered-containers ==0.2.*     , wcwidth >=0.0.1 && <1   if flag(json)@@ -150,7 +149,7 @@     , hashable >=1.3 && <2     , prettyprinter >=1.7.0 && <2     , prettyprinter-ansi-terminal >=1.1.0 && <2-    , text >=1.2 && <2+    , text >=1.2 && <3     , unordered-containers ==0.2.*     , wcwidth >=0.0.1 && <1   if flag(json)@@ -188,7 +187,6 @@     , hashable >=1.3 && <2     , prettyprinter >=1.7.0 && <2     , prettyprinter-ansi-terminal >=1.1.0 && <2-    , text >=1.2 && <2     , unordered-containers ==0.2.*     , wcwidth >=0.0.1 && <1   if flag(json)
src/Error/Diagnose/Position.hs view
@@ -18,7 +18,6 @@ #endif import Data.Default (Default, def) import Data.Hashable (Hashable)-import Data.Text (Text) import GHC.Generics (Generic (..)) import Prettyprinter (Pretty (..), colon) @@ -50,8 +49,8 @@ instance Pretty Position where   pretty (Position (bl, bc) (el, ec) f) = pretty f <> at <> pretty bl <> colon <> pretty bc <> dash <> pretty el <> colon <> pretty ec     where-      at = pretty @Text "@"-      dash = pretty @Text "-"+      at = pretty @String "@"+      dash = pretty @String "-"  instance Hashable Position 
src/Error/Diagnose/Report/Internal.hs view
@@ -252,6 +252,18 @@    in annotate (bold <> color Black) $ mempty <+> pad (leftLen - lineNoLen) ' ' mempty <> pretty lineNo <+> if withUnicode then "│" else "|" {-# INLINE linePrefix #-} +-- | Creates an ellipsis-prefix, when some line numbers are not consecutive.+--+--   Pretty printing yields those results:+--+--   [with unicode] "@␣␣␣␣␣⋮␣@"+--   [without unicode] "@␣␣␣␣...@"+ellipsisPrefix ::+  Int ->+  Bool ->+  Doc AnsiStyle+ellipsisPrefix leftLen withUnicode = pad leftLen ' ' mempty <> annotate (bold <> color Black) (if withUnicode then space <> "⋮" else "...")+ groupMarkersPerFile ::   Pretty msg =>   [(Position, Marker msg)] ->@@ -346,75 +358,94 @@   [(Position, Marker msg)] ->   [Int] ->   Doc AnsiStyle-prettyAllLines _ _ _ _ _ _ [] [] = mempty-prettyAllLines _ withUnicode isError _ leftLen _ multiline [] =-  let colorOfLastMultilineMarker = maybe mempty (markerColor isError . snd) (List.safeLast multiline)-      -- take the color of the last multiline marker in case we need to add additional bars+prettyAllLines files withUnicode isError tabSize leftLen inline multiline lineNumbers =+  case lineNumbers of+    [] ->+      showMultiline True multiline+    [l] ->+      let (ms, doc) = showForLine True l+       in doc+            <> prettyAllLines files withUnicode isError tabSize leftLen inline ms []+    l1 : l2 : ls ->+      let (ms, doc) = showForLine False l1+       in doc+            <> (if l2 /= l1 + 1 then hardline <+> dotPrefix leftLen withUnicode else mempty)+            <> prettyAllLines files withUnicode isError tabSize leftLen inline ms (l2 : ls)+  where+    showForLine isLastLine line =+      {-+          A line of code is composed of:+          (1)     <line> | <source code>+          (2)            : <markers>+          (3)            : <marker messages> -      prefix = hardline <+> dotPrefix leftLen withUnicode <> space-      prefixWithBar color = prefix <> annotate color (if withUnicode then "│ " else "| ")+          Multline markers may also take additional space (2 characters) on the right of the bar+      -}+      let allInlineMarkersInLine = snd =<< filter ((==) line . fst) inline -      showMultilineMarkerMessage (_, marker) isLast =-        annotate (markerColor isError marker) $-          ( if isLast-              then if withUnicode then "╰╸ " else "`- "-              else if withUnicode then "├╸ " else "|- "-          )-            <> replaceLinesWith (if isLast then prefix <> "   " else prefixWithBar (markerColor isError marker) <> space) (pretty $ markerMessage marker)+          allMultilineMarkersInLine = flip filter multiline \(Position (bl, _) (el, _) _, _) -> bl == line || el == line -      showMultilineMarkerMessages [] = []-      showMultilineMarkerMessages [m] = [showMultilineMarkerMessage m True]-      showMultilineMarkerMessages (m : ms) = showMultilineMarkerMessage m False : showMultilineMarkerMessages ms-   in prefixWithBar colorOfLastMultilineMarker <> prefix <> fold (List.intersperse prefix $ showMultilineMarkerMessages $ reverse multiline)-prettyAllLines files withUnicode isError tabSize leftLen inline multiline (line : ls) =-  {--      A line of code is composed of:-      (1)     <line> | <source code>-      (2)            : <markers>-      (3)            : <marker messages>+          allMultilineMarkersSpanningLine = flip filter multiline \(Position (bl, _) (el, _) _, _) -> bl < line && el > line -      Multline markers may also take additional space (2 characters) on the right of the bar-  -}-  let allInlineMarkersInLine = snd =<< filter ((==) line . fst) inline+          inSpanOfMultiline = flip any multiline \(Position (bl, _) (el, _) _, _) -> bl <= line && el >= line -      allMultilineMarkersInLine = flip filter multiline \(Position (bl, _) (el, _) _, _) -> bl == line || el == line+          colorOfFirstMultilineMarker = maybe id (annotate . markerColor isError . snd) (List.safeHead $ allMultilineMarkersInLine <> allMultilineMarkersSpanningLine)+          -- take the first multiline marker to color the entire line, if there is one -      allMultilineMarkersSpanningLine = flip filter multiline \(Position (bl, _) (el, _) _, _) -> bl < line && el > line+          (multilineEndingOnLine, otherMultilines) = flip List.partition multiline \(Position _ (el, _) _, _) -> el == line -      inSpanOfMultiline = flip any multiline \(Position (bl, _) (el, _) _, _) -> bl <= line && el >= line+          !additionalPrefix = case allMultilineMarkersInLine of+            [] ->+              if not $ null multiline+                then+                  if not $ null allMultilineMarkersSpanningLine+                    then colorOfFirstMultilineMarker if withUnicode then "│  " else "|  "+                    else "   "+                else mempty+            (p@(Position _ (el, _) _), marker) : _ ->+              let hasPredecessor = el == line || maybe False ((/=) p . fst . fst) (List.safeUncons multiline)+               in colorOfFirstMultilineMarker+                    ( if+                          | hasPredecessor && withUnicode -> "├"+                          | hasPredecessor -> "|"+                          | withUnicode -> "╭"+                          | otherwise -> "+"+                    )+                    <> annotate (markerColor isError marker) (if withUnicode then "┤" else ">")+                    <> space -      colorOfFirstMultilineMarker = maybe id (annotate . markerColor isError . snd) (List.safeHead $ allMultilineMarkersInLine <> allMultilineMarkersSpanningLine)-      -- take the first multiline marker to color the entire line, if there is one+          allMarkersInLine = {- List.sortOn fst $ -} allInlineMarkersInLine <> allMultilineMarkersInLine -      !additionalPrefix = case allMultilineMarkersInLine of-        [] ->-          if not $ null multiline-            then-              if not $ null allMultilineMarkersSpanningLine-                then colorOfFirstMultilineMarker if withUnicode then "│  " else "|  "-                else "   "-            else mempty-        (p@(Position _ (el, _) _), marker) : _ ->-          let hasPredecessor = el == line || maybe False ((/=) p . fst . fst) (List.safeUncons multiline)-           in colorOfFirstMultilineMarker-                ( if-                      | hasPredecessor && withUnicode -> "├"-                      | hasPredecessor -> "|"-                      | withUnicode -> "╭"-                      | otherwise -> "+"-                )-                <> annotate (markerColor isError marker) (if withUnicode then "┤" else ">")-                <> space+          (widths, renderedCode) = getLine_ files (allMarkersInLine <> allMultilineMarkersSpanningLine) line tabSize isError+       in ( otherMultilines,+            hardline+              <> {- (1) -} linePrefix leftLen line withUnicode <+> additionalPrefix+              <> renderedCode+              <> {- (2) -} showAllMarkersInLine (not $ null multiline) inSpanOfMultiline colorOfFirstMultilineMarker withUnicode isError leftLen widths allInlineMarkersInLine+              <> showMultiline (isLastLine || List.safeLast multilineEndingOnLine == List.safeLast multiline) multilineEndingOnLine+          ) -      allMarkersInLine = {- List.sortOn fst $ -} allInlineMarkersInLine <> allMultilineMarkersInLine+    showMultiline _ [] = mempty+    showMultiline isLastMultiline multiline =+      let colorOfLastMultilineMarker = maybe mempty (markerColor isError . snd) (List.safeLast multiline)+          -- take the color of the last multiline marker in case we need to add additional bars -      (widths, renderedCode) = getLine_ files (allMarkersInLine <> allMultilineMarkersSpanningLine) line tabSize isError-   in hardline-        <> {- (1) -} linePrefix leftLen line withUnicode <+> additionalPrefix-        <> renderedCode-        <> {- (2) -} showAllMarkersInLine (not $ null multiline) inSpanOfMultiline colorOfFirstMultilineMarker withUnicode isError leftLen widths allInlineMarkersInLine-        <> {- (3) -} prettyAllLines files withUnicode isError tabSize leftLen inline multiline ls+          prefix = hardline <+> dotPrefix leftLen withUnicode <> space+          prefixWithBar color = prefix <> annotate color (if withUnicode then "│ " else "| ") +          showMultilineMarkerMessage (_, marker) isLast =+            annotate (markerColor isError marker) $+              ( if isLast && isLastMultiline+                  then if withUnicode then "╰╸ " else "`- "+                  else if withUnicode then "├╸ " else "|- "+              )+                <> replaceLinesWith (if isLast then prefix <> "   " else prefixWithBar (markerColor isError marker) <> space) (pretty $ markerMessage marker)++          showMultilineMarkerMessages [] = []+          showMultilineMarkerMessages [m] = [showMultilineMarkerMessage m True]+          showMultilineMarkerMessages (m : ms) = showMultilineMarkerMessage m False : showMultilineMarkerMessages ms+       in prefixWithBar colorOfLastMultilineMarker <> prefix <> fold (List.intersperse prefix $ showMultilineMarkerMessages $ reverse multiline)+ -- | getLine_ :: HashMap FilePath [String] -> [(Position, Marker msg)] -> Int -> Int -> Bool -> (IntMap.HashMap Int Int, Doc AnsiStyle) getLine_ files markers line tabSize isError = case List.safeIndex (line - 1) =<< (HashMap.!?) files . file . fst =<< List.safeHead markers of@@ -430,7 +461,7 @@                     \(Position (bl, bc) (el, ec) _, _) ->                       if bl == el                         then n >= bc && n < ec-                        else (bl == line && n >= bc) || (el == line && n < ec)+                        else (bl == line && n >= bc) || (el == line && n < ec) || (bl < line && el > line)                in maybe id ((\m -> annotate (bold <> markerColor isError m)) . snd) (List.safeHead colorizingMarkers) (pretty c)         )   where
test/rendering/Spec.hs view
@@ -31,7 +31,9 @@             ("somefile.zc", "let id<a>(x : a) : a := x\n  + 1"),             ("err.nst", "\n\n\n\n    = jmp g\n\n    g: forall(s: Ts, e: Tc).{ %r0: *s64 | s -> e }"),             ("unsized.nst", "main: forall(a: Ta, s: Ts, e: Tc).{ %r5: forall().{| s -> e } | s -> %r5 }\n    = salloc a\n    ; sfree\n"),-            ("unicode.txt", "±⅀\t★♲♥🎉汉⑳⓴ჳᏁℳ爪")+            ("unicode.txt", "±⅀\t★♲♥🎉汉⑳⓴ჳᏁℳ爪"),+            ("gaps.txt", "abc\ndef\nghi\njkl\nmno\npqr"),+            ("repro3.file", "\n\n  ayo yoa\n    a b\n      c d e f g\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nlayer qwertyy using yoooo: \"a\" \"b\" \"c\"\n")           ]    let reports =@@ -64,6 +66,10 @@           errorMultipleFiles,           errorWithCode,           errorWithStrangeUnicodeInput,+          errorWithMultilineMarkerOn3Lines,+          errorMultilineMarkerNotAtEnd,+          errorWithLineGap,+          repro3,           beautifulExample         ] @@ -356,5 +362,45 @@     "ⓈⓉⓇⒶⓃⒼⒺ ⓊⓃⒾⒸⓄⒹⒺ"     [ (Position (1, 1) (1, 7) "unicode.txt", This "should work fine 🎉"),       (Position (1, 7) (1, 9) "unicode.txt", Where "After TAB")+    ]+    []++errorWithMultilineMarkerOn3Lines :: Report String+errorWithMultilineMarkerOn3Lines =+  err+    Nothing+    "Multiline marker on 3 lines"+    [(Position (1, 3) (3, 10) "test.zc", This "should color all 3 lines correctly")]+    []++errorMultilineMarkerNotAtEnd :: Report String+errorMultilineMarkerNotAtEnd =+  err+    Nothing+    "Multiline marker not at end of report"+    [ (Position (1, 10) (2, 3) "test.zc", This "is a multline marker"),+      (Position (3, 5) (3, 13) "test.zc", Where "inline marker found after")+    ]+    []++errorWithLineGap :: Report String+errorWithLineGap =+  err+    Nothing+    "Error with line gaps between two markers"+    [ (Position (1, 1) (1, 3) "gaps.txt", Where "is a first marker"),+      (Position (5, 2) (5, 4) "gaps.txt", This "is the main marker")+    ]+    []++repro3 :: Report String+repro3 =+  err+    (Just "WrongStaticLayerLength")+    "The length of the static layer does not match the length of the template it uses"+    [ (Position (3, 3) (5, 16) "repro3.file", Where "This template has 9 elements"),+      (Position (24, 28) (24, 39) "repro3.file", This "... but this layer only has 3 members"),+      (Position (24, 21) (24, 26) "repro3.file", Where "This is the template being used"),+      (Position (24, 7) (24, 15) "repro3.file", Where "while checking this static layer")     ]     []