on 5a1caab 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.PrettyPrint as P
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 :: P.Dealiaser -> Error -> Report.Report
25toReport dealiaser 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>"