@@ -2,7 +2,10 @@
2module Reporting.Error.Type where
2module Reporting.Error.Type where
4import qualified Data.Maybe as Maybe
4import qualified Data.Maybe as Maybe
5−import Text.PrettyPrint.ANSI.Leijen (Doc, (<+>), equals, indent, text)
5+import Text.PrettyPrint.ANSI.Leijen
6+ ( Doc, (<>), (<+>), colon, dullyellow, equals
7+ , fillSep, hang, indent, text, underline, vcat
7import qualified AST.Type as Type
10import qualified AST.Type as Type
8import qualified AST.Variable as Var
11import qualified AST.Variable as Var
@@ -111,11 +114,11 @@ mismatchToReport localizer (MismatchInfo hint leftType rightType maybeReason) =
112 Report.report "TYPE MISMATCH"
115 Report.report "TYPE MISMATCH"
115− Maybe.maybeToList (fmap reasonToString maybeReason)
117 cmpHint leftWords rightWords extraHints =
117 cmpHint leftWords rightWords extraHints =
118− comparisonHint localizer leftType rightType leftWords rightWords (extraHints ++ reasonHints)
118+ comparisonHint localizer leftType rightType leftWords rightWords
119+ ( map toHint extraHints
120+ ++ Maybe.maybeToList (fmap reasonToString maybeReason)
120 case hint of
123 case hint of
121 CaseBranch branchNumber region ->
124 CaseBranch branchNumber region ->
@@ -377,7 +380,7 @@ comparisonHint
377 -> Type.Canonical
380 -> Type.Canonical
378 -> String
381 -> String
379 -> String
382 -> String
380− -> [String]
383+ -> [Doc]
382comparisonHint localizer leftType rightType leftWords rightWords finalHints =
385comparisonHint localizer leftType rightType leftWords rightWords finalHints =
@@ -391,7 +394,11 @@ comparisonHint localizer leftType rightType leftWords rightWords finalHints =
391 , indent 4 rightDoc
394 , indent 4 rightDoc
394− map Help.reflowParagraph finalHints
397+ finalHints
397ordinalPair :: Int -> String
404ordinalPair :: Int -> String
@@ -399,33 +406,44 @@ ordinalPair number =
399 Help.ordinalize (number -1 ) ++ " and " ++ Help.ordinalize number
406 Help.ordinalize (number -1 ) ++ " and " ++ Help.ordinalize number
409+prettyName :: Var.Canonical -> String
410+prettyName (Var.Canonical _ opName) =
411+ Help.functionName opName
414+funcName :: Maybe Var.Canonical -> String
406−reasonToString :: Reason -> String
420+ Just var ->
407−reasonToString reason =
421+ "function " ++ prettyName var
409− MessyFields expecteds [] ->
410− genericMissingFieldsMessage "former" expecteds
412− MessyFields [] actuals ->
413− genericMissingFieldsMessage "latter" actuals
415− MessyFields expecteds actuals ->
416− case concatMap (similarNames actuals) expecteds of
418− "These records look pretty different."
420− [(ex,ac)] ->
425+-- MISMTACH REASONS
421− "Looks like a misspelling between field " ++ ex ++ " and " ++ ac ++ "."
423− potentialTypos ->
427+
424− "There are some potential typos in the record field names.\n"
428+reasonToString :: Reason -> Doc
425− ++ concatMap (\(ex,ac) -> "\n " ++ ex ++ " <=> " ++ ac) potentialTypos
429+reasonToString reason =
431+ MessyFields leftOnly rightOnly ->
434+ do let typos = RenderType.findPotentialTypos leftOnly rightOnly
435+ RenderType.vetTypos typos
436+ misspellingMessage typos
438+ case maybeMessage of
427 NotRecord ->
445 NotRecord ->
428− "A record cannot be merged with other types of values."
446+ toHint "A record cannot be merged with other types of values."
430 TooLongComparableTuple len ->
448 TooLongComparableTuple len ->
431 error "TODO"
449 error "TODO"
@@ -434,30 +452,38 @@ reasonToString reason =
434 error "TODO"
452 error "TODO"
437−similarNames :: [String] -> String -> [(String,String)]
455+hintDoc :: Doc
438−similarNames otherKeys key =
456+hintDoc =
439− map ((,) key) (filter (\key' -> Help.distance key key' == 1) otherKeys)
457+ underline (text "Hint") <> colon
442−genericMissingFieldsMessage :: String -> [String] -> String
460+toHint :: String -> Doc
443−genericMissingFieldsMessage latterOrFormer fields =
461+toHint str =
444− "A record in the " ++ latterOrFormer ++ " type is missing field"
462+ fillSep (hintDoc : map text (words str))
445− ++ Help.commaSep fields
448−prettyName :: Var.Canonical -> String
465+misspellingMessage :: [(String,String)] -> Maybe Doc
449−prettyName (Var.Canonical _ opName) =
466+misspellingMessage typos =
450− Help.functionName opName
467+ if null typos then
473+ maximum (map (length . fst) typos)
475+ Just $ hang 4 $ vcat $
476+ toHint "I compared the record fields and found some potential typos."
478+ : map (pad maxLen) typos
453−funcName :: Maybe Var.Canonical -> String
459− Just var ->
481+pad :: Int -> (String, String) -> Doc
460− "function " ++ prettyName var
482+pad maxLen (leftField, rightField) =
483+ text (replicate (maxLen - length leftField) ' ')
484+ <> dullyellow (text leftField)
486+ <+> dullyellow (text rightField)