packages feed

diagnostician 0.1.0.0 → 0.1.1.0

raw patch · 2 files changed

+38/−29 lines, 2 filesdep ~containers

Dependency ranges changed: containers

Files

diagnostician.cabal view
@@ -1,11 +1,11 @@ cabal-version:   3.4 name:            diagnostician-description:     A minimal, opinionated library for compiler error messages-version:         0.1.0.0+version:         0.1.1.0 license:         MPL-2.0 license-file:    LICENSE maintainer:      root@owenlynch.org author:          Owen Lynch+description:     A minimal, opinionated library for compiler error messages category:        Language build-type:      Simple extra-doc-files: CHANGELOG.md@@ -44,5 +44,5 @@     ghc-options:        -Wall     build-depends:         base ^>=4.21.0.0,-        containers >=0.7,+        containers,         diagnostician
src/Diagnostician.hs view
@@ -1,5 +1,7 @@ module Diagnostician where +import Data.Functor.Contravariant+import Data.IORef (IORef, atomicModifyIORef) import Data.Map (Map) import Data.Map qualified as Map import Data.Maybe (maybeToList)@@ -75,6 +77,8 @@  type LineNum = Int +type ColNum = Int+ lineStart :: File -> LineNum -> Pos lineStart f l = (f.lineBreaks UV.! l) + 1 @@ -87,19 +91,20 @@ lineContents :: File -> LineNum -> T.Text lineContents f l = sliceWord8 (lineStart f l) (lineEnd f l) f.contents -lineOf :: File -> Pos -> LineNum-lineOf f i =+srcOf :: File -> Pos -> (LineNum, ColNum)+srcOf f i =   seq-    (0 <= i && i < TU.lengthWord8 f.contents || error "position out of bounds")+    (0 <= i && i <= TU.lengthWord8 f.contents || error "position out of bounds")     (go 0 (UV.length f.lineBreaks - 1))   where     go l r-      | l == r = l+      | l == r = (l, c l)       | i < lineStart f m = go l m       | i > lineEnd f m = go m r-      | otherwise = m+      | otherwise = (m, c m)       where         m = (l + r) `div` 2+        c lineNo = i - lineStart f lineNo  repeated :: Int -> Char -> Doc ann repeated n c@@ -136,22 +141,37 @@     | l <- [ls .. le]     ]   where-    ls = lineOf f s-    le = lineOf f e+    ls = fst $ srcOf f s+    le = fst $ srcOf f e     numWidth = max (numDigits ls) (numDigits le)  -- Reporter -------------------------------------------------------------------------------- --- | A @Reporter@ is a destination for diagnostic messages. Currently this is--- very simplistic; it's just a byte sink. The @reporterFancy@ flag is in theory--- used to configure whether colors should be used, but we don't even look at--- that yet.-data Reporter = Reporter-  { handle :: Handle,-    fancy :: Bool-  }+-- | A @Reporter@ is a destination for diagnostic messages. It corresponds+-- to an IO action `reportIO` that logs a diagnostic+newtype Reporter a = Reporter {reportIO :: Diagnostic a -> IO ()} +reportTo :: Reporter a -> Diagnostic a -> IO ()+reportTo r d = r.reportIO d++instance Contravariant Reporter where+  contramap f (Reporter r) = Reporter $ r . fmap f++-- | Create a `Reporter` that writes the prettyprinted diagnostic to a file+fileReporter :: (Code a) => Handle -> Reporter a+fileReporter handle =+  Reporter+    { reportIO = \d -> hPutDoc handle (hardline <> dpretty d <> hardline)+    }++-- | Create a `Reporter` that appends a diagnostic to a list+pureReporter :: (Code a) => IORef [Diagnostic a] -> Reporter a+pureReporter ref =+  Reporter+    { reportIO = \d -> atomicModifyIORef ref (\ds -> (d : ds, ()))+    }+ -- Diagnostics -------------------------------------------------------------------------------- @@ -213,14 +233,3 @@   dpretty d =     vsep $       (prtCode d.code <> ": " <> unAnnotate d.summary) : (map dpretty d.notes)--reportIO :: (Code a) => Reporter -> Diagnostic a -> IO ()-reportIO r d = hPutDoc r.handle (hardline <> dpretty d <> hardline)--data ReporterFor a-  = forall c.-  (Code c) =>-  ReporterFor {translator :: a -> c, reporter :: Reporter}--reportTo :: ReporterFor a -> Diagnostic a -> IO ()-reportTo (ReporterFor t r) d = reportIO r (fmap t d)