@@ -1,26 +1,54 @@
11{-# OPTIONS_GHC -Wall #-}
22module Reporting.Error.Pattern where
33
4+import qualified AST.Module.Name as ModuleName
5+import qualified AST.Variable as Var
46import qualified Nitpick.Pattern as Pattern
57import qualified Reporting.PrettyPrint as P
68import qualified Reporting.Report as Report
79
810
911data Error
10− = Incomplete [Pattern.Pattern]
12+ = Incomplete Origin [Pattern.Pattern]
1113 | Redundant
1214
1315
16+data Origin
17+ = Arg
18+ | LetBound
19+ | Case
20+
21+
1422-- TO REPORT
1523
1624toReport :: P.Dealiaser -> Error -> Report.Report
1725toReport dealiaser err =
1826 case err of
19− Incomplete unhandled ->
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+ )
36+
37+ Incomplete LetBound unhandled ->
2038 Report.simple
21− "MISSING PATTERN"
22− "The following `case` does not handle all possible inputs."
23− ( "The following patterns are not being handled:\n"
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+ )
46+
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"
2452 ++ viewPatternList unhandled
2553 ++ "\n\n"
2654 ++ incompleteExplanation
@@ -44,25 +72,60 @@ viewPatternList unhandledPatterns =
4472 ++ if null rest then [] else ["..."]
4573
4674
75+partialExplanation :: [Pattern.Pattern] -> String
76+partialExplanation unhandledPatterns =
77+
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+ ++
83+
84+ if isNothing unhandledPatterns then
85+
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>"
90+
91+ else if isEmptyList unhandledPatterns then
92+
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>"
97+
98+ else
99+
100+ ""
101+
102+
103+isNothing :: [Pattern.Pattern] -> Bool
104+isNothing unhandledPatterns =
105+ case unhandledPatterns of
106+ [Pattern.Data (Var.Canonical (Var.Module moduleName) "Nothing") []] ->
107+ moduleName == ModuleName.inCore ["Maybe"]
108+
109+ _ ->
110+ False
111+
112+
113+isEmptyList :: [Pattern.Pattern] -> Bool
114+isEmptyList unhandledPatterns =
115+ case unhandledPatterns of
116+ [Pattern.Data (Var.Canonical Var.BuiltIn "[]") []] ->
117+ True
118+
119+ _ ->
120+ False
121+
122+
47123incompleteExplanation :: String
48124incompleteExplanation =
49− unlines
50− [ "Did you add a new tag to a union type? Add how it should be handled here and"
51− , "you will be all set!"
52− , ""
53− , "If you want to go quick and implement this later, you can end the pattern with:"
54− , ""
55− , " _ ->"
56− , " Debug.crash \"TODO\""
57− , ""
58− , "When I see cases that end with this pattern, I augment the runtime error with"
59− , "the module name, the relevant line numbers, and the value led down that branch."
60− , ""
61− , "That said, you almost never want this in production code. If you think there"
62− , "are certain cases that are impossible in practice, consider refining how you"
63− , "model the data. If it can never happen in practice, you can probably define a"
64− , "union type such that the \"impossible\" cannot even be constructed in the"
65− , "first place. That is how you make something \"impossible\" truly impossible."
66− , ""
67− , "I won't say \"I told you so\" in the runtime error, but I'll be thinking it ;)"
68− ]
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>"
131+