Skip to content

Commit

Permalink
Added shadowing reporting to no-reassign.
Browse files Browse the repository at this point in the history
  • Loading branch information
benmosher committed Mar 25, 2015
1 parent a919971 commit 4008082
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 7 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,5 @@ Also, will report for computed references (i.e. `foo["bar"]()`).

### `no-reassign`

Reports on assignment to an imported name (or a member of an imported namespace). Does not consider scope or shadowing, so failure to adhere to ESLint's `no-shadow` may result in spurious warnings.
Reports on assignment to an imported name (or a member of an imported namespace).
Will also report shadowing (i.e. redeclaration as a variable, function, or parameter);
35 changes: 33 additions & 2 deletions lib/rules/no-reassign.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@

var Set = require("es6-set");

function message(name) {
return "Reassignment of local imported name '" + name + "'.";
}

module.exports = function (context) {
var
locals = new Set(),
namespaces = new Set();

function checkIdentifier(id) {
if (locals.has(id.name)) context.report(id, message(id.name));
}

return {
"ImportSpecifier": function (node) {
locals.add(node.local.name);
Expand All @@ -23,8 +32,7 @@ module.exports = function (context) {
"AssignmentExpression": function (node) {
switch (node.left.type) {
case "Identifier":
if (locals.has(node.left.name)) context.report(node.left,
"Reassignment of local imported name '" + node.left.name + "'.");
checkIdentifier(node.left);
break;

case "MemberExpression":
Expand All @@ -33,6 +41,29 @@ module.exports = function (context) {
"Assignment to member of namespace '" + node.left.object.name + "'.");
break;
}
},

"FunctionDeclaration": function (fn) {
checkIdentifier(fn.id);

fn.params.forEach(function (p) {
if (p.type !== "Identifier") return;
checkIdentifier(p);
});
},

"VariableDeclarator": function (vr) {
if (vr.id.type !== "Identifier") return;
checkIdentifier(vr.id);
}

// todo: destructuring assignment
// "ObjectPattern": function (o) {

// },

// "ArrayPattern": function (a) {

// }
};
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-import",
"version": "0.3.9",
"version": "0.3.10",
"description": "Import with sanity.",
"main": "index.js",
"directories": {
Expand Down
12 changes: 9 additions & 3 deletions tests/lib/rules/no-reassign.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ var test = require("../../utils").test;
eslintTester.addRuleTest("lib/rules/no-reassign", {
valid: [
test({code: "import { foo } from './bar'; bar = 42;"}),
// may shadow
test({code: "import { foo } from './bar'; function bar(foo) {};"}),
// may assign to imported names' members
test({code: "import { foo } from './bar'; foo.x = 42; "}),
// may assign to imported namespaces' names' members
Expand All @@ -21,7 +19,7 @@ eslintTester.addRuleTest("lib/rules/no-reassign", {
invalid: [
// assignment to shadow is invalid
test({
code: "import { foo } from './bar'; function bar(foo) { foo = 42; };",
code: "import { foo } from './bar'; function bar(foo) { };",
errors: [{ message: "Reassignment of local imported name 'foo'."}]}),

test({
Expand All @@ -36,6 +34,14 @@ eslintTester.addRuleTest("lib/rules/no-reassign", {
code: "import * as foo from './bar'; foo = 42;",
errors: [{ message: "Reassignment of local imported name 'foo'." }]}),

test({
code: "import { foo } from './bar';\nfunction foo() { return false; }",
errors: [{ message: "Reassignment of local imported name 'foo'." }]}),

test({
code: "import { foo } from './bar';\nvar bar = 32, foo = function() { return false; }",
errors: [{ message: "Reassignment of local imported name 'foo'." }]}),

test({
code: "import * as foo from './bar'; foo.x = 'y';",
errors: [{ message: "Assignment to member of namespace 'foo'."}]
Expand Down

0 comments on commit 4008082

Please sign in to comment.