on 55ba05f help sign in
elk/src/Reporting/Error/Pattern.hs
131 lines 4.1 kB history raw
1{-# OPTIONS_GHC -Wall #-}
2module Reporting.Error.Pattern where
4import qualified AST.Module.Name as ModuleName
5import qualified AST.Variable as Var
6import qualified Nitpick.Pattern as Pattern
7import qualified Reporting.Render.Type as RenderType
8import qualified Reporting.Report as Report
11data Error
12 = Incomplete Origin [Pattern.Pattern]
13 | Redundant
16data Origin
17 = Arg
18 | LetBound
19 | Case
22-- TO REPORT
24toReport :: RenderType.Localizer -> Error -> Report.Report
25toReport _localizer err =
26 case err of
27 Incomplete Arg unhandled ->
28 Report.simple
29 "PARTIAL PATTERN"
30 "This argument does not cover all possible inputs."
31 ( "Any of these patterns can cause a crash:\n"
32 ++ viewPatternList unhandled
33 ++ "\n\n"
34 ++ partialExplanation unhandled
35 )
37 Incomplete LetBound unhandled ->
38 Report.simple
39 "PARTIAL PATTERN"
40 "The pattern used here does not cover all possible values."
41 ( "Any of these patterns can cause a crash:\n"
42 ++ viewPatternList unhandled
43 ++ "\n\n"
44 ++ partialExplanation unhandled
45 )
47 Incomplete Case unhandled ->
48 Report.simple
49 "INCOMPLETE PATTERN MATCH"
50 "This `case` does not have branches for all possibilities."
51 ( "Any of these patterns can cause a crash:\n"
52 ++ viewPatternList unhandled
53 ++ "\n\n"
54 ++ incompleteExplanation
55 )
57 Redundant ->
58 Report.simple
59 "REDUNDANT PATTERN"
60 "The following pattern is redundant."
61 "Any value with this shape will be handled by a previous pattern."
64viewPatternList :: [Pattern.Pattern] -> String
65viewPatternList unhandledPatterns =
66 let
67 (showPatterns, rest) =
68 splitAt 4 unhandledPatterns
69 in
70 concatMap ((++) "\n ") $
71 map (Pattern.toString False) showPatterns
72 ++ if null rest then [] else ["..."]
75partialExplanation :: [Pattern.Pattern] -> String
76partialExplanation unhandledPatterns =
78 "You probably want to switch to a `case` expression to handle all possible\n"
79 ++ "patterns in a simple way. If you think some cases are impossible, you can use\n"
80 ++ "`Debug.crash` to make that thinking explicit in your code.\n"
81 ++ "<http://package.elm-lang.org/packages/elm-lang/core/latest/Debug#crash>"
82 ++
84 if isNothing unhandledPatterns then
86 "\n\nSometimes you *know* a value will never be Nothing, though such cases are very\n"
87 ++ "rare. If you are certain you are in that case and that there is no better way\n"
88 ++ "to do things, I'd recommend creating a function `unsafe` that makes the danger\n"
89 ++ "explicit in the code. <https://github.com/elm-lang/core/issues/215>"
91 else if isEmptyList unhandledPatterns then
93 "\n\nSometimes you *know* a list cannot be empty, though such cases are relatively\n"
94 ++ "rare. If you are certain you are in that case and that there is no better\n"
95 ++ "way to do things, I'd recommend creating a function like `unsafe` that makes\n"
96 ++ "the danger explicit in the code. <https://github.com/elm-lang/core/issues/215>"
98 else
100 ""
103isNothing :: [Pattern.Pattern] -> Bool
104isNothing unhandledPatterns =
105 case unhandledPatterns of
106 [Pattern.Data (Var.Canonical (Var.Module moduleName) "Nothing") []] ->
107 moduleName == ModuleName.inCore ["Maybe"]
109 _ ->
110 False
113isEmptyList :: [Pattern.Pattern] -> Bool
114isEmptyList unhandledPatterns =
115 case unhandledPatterns of
116 [Pattern.Data (Var.Canonical Var.BuiltIn "[]") []] ->
117 True
119 _ ->
120 False
123incompleteExplanation :: String
124incompleteExplanation =
125 "Did you add a new tag to a union type? Add how it should be handled here and\n"
126 ++ "you will be all set!\n"
127 ++ "\n"
128 ++ "If you want to go quick and implement this later, you may want to look into\n"
129 ++ "using `Debug.crash` which has some cool error reporting abilities.\n"
130 ++ "<http://package.elm-lang.org/packages/elm-lang/core/latest/Debug#crash>"