Skip to content

Commit

Permalink
Add support for unused_exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
zmillman authored and za-creature committed May 23, 2018
1 parent ae9ccc6 commit fbd4eae
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 4 deletions.
3 changes: 2 additions & 1 deletion coffeelint.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@
"hoist_local": false,
"hoist_parent": true,
"unused_variables": true,
"unused_arguments": false
"unused_arguments": false,
"unused_exceptions": ["_.+"]
},
"prefer_double_quotes": {
"module": "coffeelint-prefer-double-quotes",
Expand Down
6 changes: 5 additions & 1 deletion src/Scope.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,14 @@ module.exports = class Scope
@options["unused_variables"]) or \
type is "Class" and @options["unused_classes"] or \
type is "Argument" and @options["unused_arguments"]
then do ->
then do =>
if reads.length or innerReads.length
return # variable was read at least once

for exception in @options["unused_exceptions"] or []
if (new RegExp("^#{exception}$")).test(name)
return # variable is allowed to be unused

for {locationData}, index in writes.concat(innerWrites)
# issue a variable-is-assigned-but-never-read warning every
# time it is accessed (here and in all child scopes)
Expand Down
32 changes: 30 additions & 2 deletions src/index.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ module.exports = class Coffeescope2
<dt><code>shadow_exceptions</code></dt>
<dd>A list of regular expressions that further customizes the
behavior of <code>shadow</code> by allowing one or more
names to be extempt from shadowing warnings. The default
names to be exempt from shadowing warnings. The default
value is <samp>["err", "next"]</samp> to allow nesting of
Node.JS-style continuations. To be skipped, the name must
match the entire expression:
Expand Down Expand Up @@ -184,6 +184,33 @@ module.exports = class Coffeescope2
this warning. Defaults to <samp>true</samp> because of
historical reasons and the low rate of false positives
generated on most codebases.</dd>
<dt><code>unused_exceptions</code></dt>
<dd>A list of regular expressions that further customizes the
behavior of <code>unused_</code> by allowing one or more
names to be exempt from unused warnings. The default value
is <samp>["_.+"]</samp> to skip names starting with
underscores. To be skipped, the name must match the entire
expression:
<ul>
<li>
<samp>"ba."</samp>
will match
<code>"bar"</code> and
<code>"baz"</code>
but not
<code>"bard"</code> or
<code>"foobar"</code>.
</li>
<li>
<samp>"ba.*"</samp>
will match
<code>"ba"</code> and
<code>"bar"</code> and
<code>"bard"</code>.
</li>
</ul>
</dd>
</dl>
"""
level: "warn"
Expand All @@ -198,7 +225,7 @@ module.exports = class Coffeescope2

shadow: true # warn when overwriting a variable from outer scope
shadow_builtins: false # don't warn when "assigning to" a superglobal
shadow_exceptions: ["err", "next"] # list of args that may be shadowed
shadow_exceptions: ["err", "next"] # list of args that may be shadowed

undefined: true # warn when accessing an undefined variable
hoist_local: true # allow same-scope hoisting
Expand All @@ -207,6 +234,7 @@ module.exports = class Coffeescope2
unused_variables: true # warn when a variable is not accessed
unused_arguments: false # warn when an argument is not accessed
unused_classes: true # warn when a class is not instantiated or copied
unused_exceptions: ["_.+"] # list of names that can be unused

lintAST: (root, {config, createError}) ->
for spec in ScopeLinter.default().lint(root, config[@rule.name])
Expand Down
27 changes: 27 additions & 0 deletions test/ScopeLinter/unused.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,30 @@ describe "ScopeLinter/unused", ->
unused_variables: true
unused_classes: true
}).should.have.length(0)

it "allows exceptions when instructed", ->
ScopeLinter.default().lint(nodes(
"""
_foo = "bar"
class _UnusedKlass
method: (_arg) ->
"""
), {
unused_variables: true
unused_arguments: true
unused_classes: true
unused_exceptions: ["_.+"]
}).should.have.length(0)

ScopeLinter.default().lint(nodes(
"""
_foo = "bar"
class _UnusedKlass
method: (_arg) ->
"""
), {
unused_variables: true
unused_arguments: true
unused_classes: true
unused_exceptions: ["_..."]
}).should.have.length(1) # only catches the unused class

0 comments on commit fbd4eae

Please sign in to comment.