|
19 | 19 | module Language.PureScript.Errors where |
20 | 20 |
|
21 | 21 | import Data.Either (lefts, rights) |
22 | | -import Data.List (intercalate, elemIndex) |
| 22 | +import Data.List (intercalate) |
| 23 | +import Data.Function (on) |
23 | 24 | import Data.Monoid |
24 | 25 | import Data.Foldable (fold, foldMap) |
25 | 26 |
|
| 27 | +import qualified Data.Map as M |
| 28 | + |
26 | 29 | import Control.Monad |
27 | 30 | import Control.Monad.Error.Class (MonadError(..)) |
28 | 31 | import Control.Monad.Unify |
@@ -252,18 +255,24 @@ errorMessage err = MultipleErrors [err] |
252 | 255 | onErrorMessages :: (ErrorMessage -> ErrorMessage) -> MultipleErrors -> MultipleErrors |
253 | 256 | onErrorMessages f = MultipleErrors . map f . runMultipleErrors |
254 | 257 |
|
255 | | -replaceUnknowns :: Type -> State [Unknown] Type |
256 | | -replaceUnknowns = everywhereOnTypesM replaceUnknowns' |
257 | | - where |
258 | | - lookupTable :: Unknown -> [Unknown] -> (Unknown, [Unknown]) |
259 | | - lookupTable x table = case (elemIndex x table) of |
260 | | - Nothing -> (length table, table ++ [x]) |
261 | | - Just i -> (i, table) |
| 258 | +-- | The various types of things which might need to be relabelled in errors messages. |
| 259 | +data LabelType = TypeLabel | SkolemLabel String deriving (Show, Eq, Ord) |
262 | 260 |
|
263 | | - replaceUnknowns' :: Type -> State [Unknown] Type |
264 | | - replaceUnknowns' (TUnknown u) = state $ first TUnknown . lookupTable u |
265 | | - replaceUnknowns' other = return other |
| 261 | +-- | A map from rigid type variable name/unknown variable pairs to new variables. |
| 262 | +type UnknownMap = M.Map (LabelType, Unknown) Unknown |
| 263 | + |
| 264 | +replaceUnknowns :: Type -> State UnknownMap Type |
| 265 | +replaceUnknowns = everywhereOnTypesM replaceTypes |
| 266 | + where |
| 267 | + lookupTable :: (LabelType, Unknown) -> UnknownMap -> (Unknown, UnknownMap) |
| 268 | + lookupTable x m = case M.lookup x m of |
| 269 | + Nothing -> let i = length (filter (on (==) fst x) (M.keys m)) in (i, M.insert x i m) |
| 270 | + Just i -> (i, m) |
266 | 271 |
|
| 272 | + replaceTypes :: Type -> State UnknownMap Type |
| 273 | + replaceTypes (TUnknown u) = state $ first TUnknown . lookupTable (TypeLabel, u) |
| 274 | + replaceTypes (Skolem name s sko) = state $ first (flip (Skolem name) sko) . lookupTable (SkolemLabel name, s) |
| 275 | + replaceTypes other = return other |
267 | 276 |
|
268 | 277 | onTypesInErrorMessageM :: (Applicative m) => (Type -> m Type) -> ErrorMessage -> m ErrorMessage |
269 | 278 | onTypesInErrorMessageM f = g |
@@ -298,7 +307,7 @@ onTypesInErrorMessageM f = g |
298 | 307 | -- | |
299 | 308 | -- Pretty print a single error, simplifying if necessary |
300 | 309 | -- |
301 | | -prettyPrintSingleError :: Bool -> ErrorMessage -> State [Unknown] Box.Box |
| 310 | +prettyPrintSingleError :: Bool -> ErrorMessage -> State UnknownMap Box.Box |
302 | 311 | prettyPrintSingleError full e = prettyPrintErrorMessage <$> onTypesInErrorMessageM replaceUnknowns (if full then e else simplifyErrorMessage e) |
303 | 312 | where |
304 | 313 | -- | |
@@ -569,15 +578,15 @@ prettyPrintSingleError full e = prettyPrintErrorMessage <$> onTypesInErrorMessag |
569 | 578 | -- Pretty print multiple errors |
570 | 579 | -- |
571 | 580 | prettyPrintMultipleErrors :: Bool -> MultipleErrors -> String |
572 | | -prettyPrintMultipleErrors full = flip evalState [] . prettyPrintMultipleErrorsWith "Error:" "Multiple errors:" full |
| 581 | +prettyPrintMultipleErrors full = flip evalState M.empty . prettyPrintMultipleErrorsWith "Error:" "Multiple errors:" full |
573 | 582 |
|
574 | 583 | -- | |
575 | 584 | -- Pretty print multiple warnings |
576 | 585 | -- |
577 | 586 | prettyPrintMultipleWarnings :: Bool -> MultipleErrors -> String |
578 | | -prettyPrintMultipleWarnings full = flip evalState [] . prettyPrintMultipleErrorsWith "Warning:" "Multiple warnings:" full |
| 587 | +prettyPrintMultipleWarnings full = flip evalState M.empty . prettyPrintMultipleErrorsWith "Warning:" "Multiple warnings:" full |
579 | 588 |
|
580 | | -prettyPrintMultipleErrorsWith :: String -> String -> Bool -> MultipleErrors -> State [Unknown] String |
| 589 | +prettyPrintMultipleErrorsWith :: String -> String -> Bool -> MultipleErrors -> State UnknownMap String |
581 | 590 | prettyPrintMultipleErrorsWith intro _ full (MultipleErrors [e]) = do |
582 | 591 | result <- prettyPrintSingleError full e |
583 | 592 | return $ renderBox $ |
|
0 commit comments