on master help sign in
Give warnings on unused bindings and variables
commitdfaef1811281c743b3a2734a9fea69e75af43d85 authorEvan Czaplicki <evancz@users.noreply.github.com> dateWed 1 Nov 2017, 12:52 (9 years ago) parent3592fd8
3 files changed+40−23
src/Canonicalize/Expression.hs+30−15 src/Canonicalize/Module.hs+4−2 src/Reporting/Warning.hs+6−6
src/Canonicalize/Expression.hs+30−15
@@ -18,6 +18,7 @@ import qualified Canonicalize.Environment as Env
1818import qualified Canonicalize.Environment.Dups as Dups
1919import qualified Canonicalize.Pattern as Pattern
2020import qualified Canonicalize.Type as Type
21+import qualified Data.Bag as Bag
2122import qualified Elm.Name as N
2223import qualified Reporting.Annotation as A
2324import qualified Reporting.Error.Canonicalize as Error
@@ -69,7 +70,7 @@ canonicalize env (A.A region expression) =
6970 addLocals $
7071 do cargs@(Can.Args _ destructors) <- Pattern.canonicalizeArgs env args
7172 newEnv <- Env.addLocals destructors env
72− removeLocals destructors $
73+ removeLocals Warning.Pattern destructors $
7374 Can.Lambda cargs <$> canonicalize newEnv body
7475
7576 Valid.Call func args ->
@@ -159,7 +160,7 @@ canonicalizeCaseBranch env (pattern, expr) =
159160 addLocals $
160161 do match@(Can.Match _ destructors) <- Pattern.canonicalizeMatch env pattern
161162 newEnv <- Env.addLocals destructors env
162− removeLocals destructors $
163+ removeLocals Warning.Pattern destructors $
163164 (,) match <$> canonicalize newEnv expr
164165
165166
@@ -257,7 +258,7 @@ canonicalizeLet region env defs body =
257258 newEnv <- Env.addLocals boundNames env
258259 let defKeys = Map.map A.drop boundNames
259260 nodes <- Result.untracked $ traverse (bindingToNode defKeys newEnv) bindings
260− removeLocals defKeys $
261+ removeLocals Warning.Binding boundNames $
261262 do cbody <- canonicalize env body
262263 detectCycles region (Graph.stronglyConnComp nodes) cbody
263264
@@ -272,18 +273,32 @@ addLocals (Result.Result () warnings answer) =
272273 Result.Result Set.empty warnings (Result.Err err)
273274
274275
275−removeLocals :: Map.Map N.Name a -> Result FreeLocals expr -> Result () (expr, FreeLocals)
276−removeLocals boundNames (Result.Result freeLocals warnings answer) =
277− Result.Result () warnings $
278− case answer of
279− Result.Ok value ->
280− Result.Ok
281− ( value
282− , Set.difference freeLocals (Map.keysSet boundNames)
283− )
284−
285− Result.Err err ->
286− Result.Err err
276+removeLocals :: Warning.Unused -> Map.Map N.Name (A.Located a) -> Result FreeLocals expr -> Result () (expr, FreeLocals)
277+removeLocals unused boundNames (Result.Result freeLocals warnings answer) =
278+ case answer of
279+ Result.Err err ->
280+ Result.Result () warnings (Result.Err err)
281+
282+ Result.Ok value ->
283+ let
284+ newFreeLocals =
285+ Set.difference freeLocals (Map.keysSet boundNames)
286+
287+ newWarnings =
288+ -- NOTE: check for unused variables without any large allocations.
289+ -- This relies on the fact that Map.size and Set.size are O(1)
290+ if Set.size freeLocals - Map.size boundNames == Set.size newFreeLocals then
291+ warnings
292+ else
293+ Bag.append warnings $ Bag.fromList (toUnusedWarning unused) $
294+ Map.toList (Map.withoutKeys boundNames freeLocals)
295+ in
296+ Result.Result () newWarnings (Result.Ok (value, newFreeLocals))
297+
298+
299+toUnusedWarning :: Warning.Unused -> (N.Name, A.Located a) -> A.Located Warning.Warning
300+toUnusedWarning unused (name, A.A region _) =
301+ A.A region (Warning.UnusedVariable unused name)
287302
288303
289304
src/Canonicalize/Module.hs+4−2
@@ -160,14 +160,16 @@ toNode env (A.A region (Valid.Decl name@(A.A _ key) args body tipe)) =
160160 case args of
161161 [] ->
162162 do ctipe <- traverse (Type.canonicalize env) tipe
163− (cbody, freeLocals) <- Expr.removeLocals Map.empty $ Expr.canonicalize env body
163+ (cbody, freeLocals) <- Expr.removeLocals Warning.Pattern Map.empty $
164+ Expr.canonicalize env body
164165 return (Value region name cbody ctipe, key, Set.toList freeLocals)
165166
166167 _ ->
167168 do ctipe <- traverse (Type.canonicalize env) tipe
168169 cargs@(Can.Args _ destructors) <- Pattern.canonicalizeArgs env args
169170 newEnv <- Env.addLocals destructors env
170− (cbody, freeLocals) <- Expr.removeLocals destructors $ Expr.canonicalize newEnv body
171+ (cbody, freeLocals) <- Expr.removeLocals Warning.Pattern destructors $
172+ Expr.canonicalize newEnv body
171173 return (Function key cargs cbody ctipe, key, Set.toList freeLocals)
172174
173175
src/Reporting/Warning.hs+6−6
@@ -31,7 +31,7 @@ data Warning
3131 | MissingTypeAnnotation Text Type.Canonical
3232
3333
34−data Unused = Argument | Binding
34+data Unused = Pattern | Binding
3535
3636
3737
@@ -48,14 +48,14 @@ toReport localizer warning =
4848 ("Nothing from the `" <> moduleName <> "` module is used in this file.")
4949 (text "I recommend removing unused imports.")
5050
51− UnusedVariable Argument name ->
51+ UnusedVariable Pattern name ->
5252 Report.report
53− "unused argument"
53+ "unused variable"
5454 Nothing
55− ("The `" <> name <> "` argument is unused.")
55+ ("The `" <> name <> "` variable is unused.")
5656 ( Help.reflowParagraph $
57− "Maybe this indicates there is a mistake around here? Switching the\
58− \ argument to a _ will indicate that it is intentionally unused."
57+ "Maybe this indicates there is a mistake around here? Switching `"
58+ <> name <> "` to _ will indicate that it is intentionally unused."
5959 )
6060
6161 UnusedVariable Binding name ->