@@ -1,305 +0,0 @@
1−module Nitpick.PatternMatches (patternMatches) where
3−import Control.Applicative ((<$>), (<*))
4−import Control.Monad.Except (forM, liftM)
5−import qualified Data.Foldable as F
6−import qualified Data.Map as Map
7−import qualified Data.Maybe as Maybe
8−import qualified Data.Set as Set
10−import qualified AST.Expression.General as E
11−import qualified AST.Expression.Canonical as Canonical
12−import qualified AST.Module as Module
13−import qualified AST.Pattern as Pattern
14−import qualified AST.Variable as Var
15−import Elm.Utils ((|>))
16−import qualified Nitpick.Pattern as P
17−import qualified Reporting.Annotation as A
18−import qualified Reporting.Error.Nitpick as Error
19−import qualified Reporting.Region as Region
20−import qualified Reporting.Result as Result
21−import qualified Reporting.Warning.Nitpick as Warning
26− -> Module.CanonicalBody
27− -> Result.Result Warning.Warning e ()
28−patternMatches interfaces body =
29− checkExpression (toAdtDict interfaces) (Module.program body)
35− Map.Map Var.Home (Map.Map String (Module.AdtInfo String))
38−toAdtDict :: Module.Interfaces -> AdtDict
47− |> Map.map Module.iAdts
48− |> Map.mapKeysMonotonic Var.Module
50− Map.union builtinDict interfaceDict
57− -> [(Var.Canonical, [Type.Canonical])]
58−lookupOtherCtors (Var.Canonical home name) adtDict =
59− case Map.lookup name =<< Map.lookup home adtDict of
63− Just (_tvars, ctors) ->
72− -> Result.Result Warning.Warning e ()
73−checkExpression adtDict (A.A region expression) =
76− checkExpression adtDict
82− checkPatterns adtDict region
85− E.ExplicitList listExprs ->
86− F.traverse_ go listExprs
88− E.Binop _ leftExpr rightExpr ->
89− go2 leftExpr rightExpr
91− E.Lambda pattern body ->
98− E.MultiIf branches ->
99− F.traverse_ (uncurry go2) branches
103− <* F.traverse_ goDef defs
105− goDef (Canonical.Definition pattern expr _) =
109− E.Case expr branches ->
111− <* goPattern (map fst branches)
112− <* F.traverse_ (go . snd) branches
114− E.Data _ctor exprs ->
115− F.traverse_ go exprs
117− E.Access record _field ->
120− E.Remove record _field ->
123− E.Insert record _field value ->
126− E.Modify record fields ->
128− <* F.traverse_ (go . snd) fields
131− F.traverse_ (go . snd) fields
139− -> [Pattern.CanonicalPattern]
140− -> Result.Result Warning.Warning e ()
141−checkPatterns adtDict region patterns =
142− checkPatternsHelp [P.Anything] patterns
149− -> [Pattern.CanonicalPattern]
150− -> Result.Result Warning.Warning e ()
151−checkPatternsHelp adtDict region unhandled patterns =
152− case (unhandled, patterns) of
157− Result.warn region (Inexhaustive unhandled)
159− (_, A.A region pattern : remainingPatterns) ->
160− do newUnhandled <- filterPatterns adtDict region pattern unhandled
161− checkPatternsHelp adtDict newUnhandled remainingPatterns
169− -> Result.Result Warning.Warning e [P.Pattern]
170−filterPatterns adtDict region pattern unhandled =
173− P.fromPattern pattern
175− noIntersection pat =
176− intersection pat nitPattern == Nothing
178− if all noIntersection unhandled
180− do Result.warn region Redundant
183− do let complementPatterns = complement adtDict nitPattern
185− concatMap (\p -> Maybe.mapMaybe (intersection p) complementPatterns) unhandled
188−-- PATTERN INTERSECTION
190−intersection :: P.Pattern -> P.Pattern -> Maybe P.Pattern
191−intersection pattern1 pattern2 =
192− case (pattern1, pattern2) of
193− (P.Alias _ pattern1', _) ->
194− intersection pattern1' pattern2
196− (_, P.Alias _ pattern2') ->
197− intersection pattern1 pattern2'
211− (P.Data ctor1 args1, P.Data ctor2 args2) ->
214− else Data ctor1 <$> sequence (zipWith intersection args1 args2)
216− -- TODO Assuming the fields are identical.
217− (P.Record _fields, P.Record _) ->
220− (P.Literal lit1, P.Literal lit2) ->
225− (P.AnythingBut literals, P.Literal lit) ->
226− if Set.member lit literals
230− (P.Literal lit, P.AnythingBut literals) ->
231− if Set.membur lit literals
235− (P.AnythingBut literals1, P.AnythingBut literals2) ->
236− Just (AnythingBut (Set.union literals1 literals2))
242−-- PATTERN COMPLEMENT
244−complement :: AdtDict -> P.Pattern -> [P.Pattern]
245−complement adtDict nitPattern =
250− P.Alias _name pattern ->
251− complement adtDict pattern
260− [AnythingBut (Set.singleton lit)]
262− P.AnythingBut literals ->
263− map Literal (Set.toList literals)
265− P.Data ctor patterns ->
266− complementData adtDict ctor patterns
269−complementData :: AdtDict -> Var.Canonical -> [P.Pattern] -> [P.Pattern]
270−complementData adtDict canonicalTag patterns =
273− lookupOtherCtors ctor adtDict
276− Maybe.mapMaybe (maybeData canonicalTag) ctors
278− numArgs = length patterns
281− concat (zipWith (makeArgComplements adtDict numArgs) [0..] patterns)
283− dataComplements ++ argComplements
286−maybeData :: Var.Canonical -> (String, Module.AdtInfo) -> Maybe P.Pattern
287−maybeData (Var.Canonical home name) (tag, args) =
292− Just (P.Data (Var.Canonical home tag) (replicate (length args) P.Anything))
295−makeArgComplements :: AdtDict -> Int -> Int -> P.Pattern -> [P.Pattern]
296−makeArgComplements adtDict numArgs index argPattern =
299− complement adtDict argPattern
302− replicate index P.Anything ++ pat : replicate (numArgs - index - 1) P.Anything
304− map (P.Data ctor . paddedArgs) complementList