Skip to content

Commit

Permalink
Port to node 0.10
Browse files Browse the repository at this point in the history
  • Loading branch information
wbinnssmith committed Mar 10, 2017
1 parent aa423d9 commit 7ba0eaa
Show file tree
Hide file tree
Showing 4 changed files with 405 additions and 401 deletions.
1 change: 0 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"env": {
"es6": true,
"node": true
},
ecmaFeatures: {
Expand Down
80 changes: 40 additions & 40 deletions lib/rules/no-unused-state.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,57 +59,57 @@ module.exports = {
// not yet encountered any use of this.state which we have chosen not to
// analyze. If we encounter any such usage (like this.state being spread as
// JSX attributes), then this is again set to null.
let classInfo = null;
var classInfo = null;

// Returns true if the given node is possibly a reference to `this.state`.
function isStateReference(node) {
node = uncast(node);

const isDirectStateReference =
var isDirectStateReference =
node.type === 'MemberExpression' &&
isThisExpression(node.object) &&
node.property.name === 'state';

const isAliasedStateReference =
var isAliasedStateReference =
node.type === 'Identifier' &&
classInfo.aliases &&
classInfo.aliases.has(node.name);
classInfo.aliases.indexOf(node.name) >= 0;

return isDirectStateReference || isAliasedStateReference;
}

// Takes an ObjectExpression node and adds all named Property nodes to the
// current set of state fields.
function addStateFields(node) {
for (let prop of node.properties) {
node.properties.forEach(function(prop) {
if (prop.type === 'Property' && getName(prop.key) !== null) {
classInfo.stateFields.add(prop);
classInfo.stateFields.push(prop);
}
}
});
}

// Adds the name of the given node as a used state field if the node is an
// Identifier or a Literal. Other node types are ignored.
function addUsedStateField(node) {
let name = getName(node);
var name = getName(node);
if (name) {
classInfo.usedStateFields.add(name);
classInfo.usedStateFields.push(name);
}
}

// Records used state fields and new aliases for an ObjectPattern which
// destructures `this.state`.
function handleStateDestructuring(node) {
for (let prop of node.properties) {
node.properties.forEach(function(prop) {
if (prop.type === 'Property') {
addUsedStateField(prop.key);
} else if (
prop.type === 'ExperimentalRestProperty' &&
classInfo.aliases
) {
classInfo.aliases.add(getName(prop.argument));
classInfo.aliases.push(getName(prop.argument));
}
}
});
}

// Used to record used state fields and new aliases for both
Expand All @@ -118,23 +118,23 @@ module.exports = {
switch (left.type) {
case 'Identifier':
if (isStateReference(right) && classInfo.aliases) {
classInfo.aliases.add(left.name);
classInfo.aliases.push(left.name);
}
break;
case 'ObjectPattern':
if (isStateReference(right)) {
handleStateDestructuring(left);
} else if (isThisExpression(right) && classInfo.aliases) {
for (let prop of left.properties) {
left.properties.forEach(function(prop) {
if (prop.type === 'Property' && getName(prop.key) === 'state') {
let name = getName(prop.value);
var name = getName(prop.value);
if (name) {
classInfo.aliases.add(name);
classInfo.aliases.push(name);
} else if (prop.value.type === 'ObjectPattern') {
handleStateDestructuring(prop.value);
}
}
}
});
}
break;
default:
Expand All @@ -143,19 +143,19 @@ module.exports = {
}

return {
ClassDeclaration(node) {
ClassDeclaration: function(node) {
// Simple heuristic for determining whether we're in a React component.
const isReactComponent = node.body.body.some(
child => isMethodDefinitionWithName(child, 'render')
);
var isReactComponent = node.body.body.some(function(child) {
return isMethodDefinitionWithName(child, 'render');
});

if (isReactComponent) {
classInfo = {
// Set of nodes where state fields were defined.
stateFields: new Set(),
stateFields: [],

// Set of names of state fields that we've seen used.
usedStateFields: new Set(),
usedStateFields: [],

// Names of local variables that may be pointing to this.state. To
// track this properly, we would need to keep track of all locals,
Expand All @@ -167,21 +167,21 @@ module.exports = {
}
},

'ClassDeclaration:exit'() {
'ClassDeclaration:exit': function() {
if (!classInfo) {
return;
}
// Report all unused state fields.
for (let node of classInfo.stateFields) {
let name = getName(node.key);
if (!classInfo.usedStateFields.has(name)) {
context.report(node, `Unused state field: '${name}'`);
classInfo.stateFields.forEach(function(node) {
var name = getName(node.key);
if (classInfo.usedStateFields.indexOf(name) < 0) {
context.report(node, 'Unused state field: \'' + name + '\'');
}
}
});
classInfo = null;
},

CallExpression(node) {
CallExpression: function(node) {
if (!classInfo) {
return;
}
Expand All @@ -198,7 +198,7 @@ module.exports = {
}
},

ClassProperty(node) {
ClassProperty: function(node) {
if (!classInfo) {
return;
}
Expand All @@ -214,23 +214,23 @@ module.exports = {
}
},

MethodDefinition() {
MethodDefinition: function() {
if (!classInfo) {
return;
}
// Create a new set for this.state aliases local to this method.
classInfo.aliases = new Set();
classInfo.aliases = [];
},

'MethodDefinition:exit'() {
'MethodDefinition:exit': function() {
if (!classInfo) {
return;
}
// Forget our set of local aliases.
classInfo.aliases = null;
},

AssignmentExpression(node) {
AssignmentExpression: function(node) {
if (!classInfo) {
return;
}
Expand All @@ -242,7 +242,7 @@ module.exports = {
node.right.type === 'ObjectExpression'
) {
// Find the nearest function expression containing this assignment.
let fn = node;
var fn = node;
while (fn.type !== 'FunctionExpression' && fn.parent) {
fn = fn.parent;
}
Expand All @@ -261,14 +261,14 @@ module.exports = {
}
},

VariableDeclarator(node) {
VariableDeclarator: function(node) {
if (!classInfo || !node.init) {
return;
}
handleAssignment(node.id, node.init);
},

MemberExpression(node) {
MemberExpression: function(node) {
if (!classInfo) {
return;
}
Expand All @@ -283,13 +283,13 @@ module.exports = {
}
},

JSXSpreadAttribute(node) {
JSXSpreadAttribute: function(node) {
if (classInfo && isStateReference(node.argument)) {
classInfo = null;
}
},

ExperimentalSpreadProperty(node) {
ExperimentalSpreadProperty: function(node) {
if (classInfo && isStateReference(node.argument)) {
classInfo = null;
}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
"object.assign": "^4.0.4"
},
"devDependencies": {
"babel-eslint": "7.1.1",
"babel-eslint": "7.0.0",
"coveralls": "2.11.15",
"eslint": "^2.0.0 || ^3.0.0",
"eslint": "^2.0.0",
"istanbul": "0.4.5",
"mocha": "3.2.0"
},
Expand Down
Loading

0 comments on commit 7ba0eaa

Please sign in to comment.