Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
New rule: disallowUnusedVariables
Browse files Browse the repository at this point in the history
Fixes #2076
Closes gh-2199
  • Loading branch information
schempy authored and markelog committed Apr 13, 2016
1 parent c5f4aa2 commit df355fa
Show file tree
Hide file tree
Showing 2 changed files with 470 additions and 0 deletions.
140 changes: 140 additions & 0 deletions lib/rules/disallow-unused-variables.js
@@ -0,0 +1,140 @@
/**
* Disallows unused variables defined with var, let or const.
*
* Types: `Boolean`
*
* Values: `true`
*
* #### Example
*
* ```js
* "disallowUnusedVariables": true
* ```
*
* ##### Valid
*
* ```js
* var x=1;
*
* function getX() {
* return x;
* }
*
* ```
*
* ##### Invalid
*
* ```js
* var x=1;
*
* function getX() {
* return true;
* }
*
* ```
*/

var assert = require('assert');

module.exports = function() {};

module.exports.prototype = {
configure: function(options) {
assert(
options === true,
this.getOptionName() + ' option requires a true value or should be removed'
);
},

getOptionName: function() {
return 'disallowUnusedVariables';
},

check: function(file, errors) {
var program = file.getProgram();
var variableList = [];
var nodesToCheck = [];
var unusedNodes = [];

function reportError(node) {
errors.add('Variable `' + node.name + '` is not used', node);
}

function isVariableGood(variable) {
var parentCheck = function(node) {
if (node.parentElement) {
if (node.parentElement.type === 'VariableDeclaration') {
var grandparentElement = node.parentElement.parentElement;

return grandparentElement.type !== 'ExportNamedDeclaration';
} else {
return parentCheck(node.parentElement);
}
} else {
return false;
}
}

var useVariable = variable.definitions.some(function checkVariableDefinition(definition) {
return parentCheck(definition.node);
});


return useVariable;
}

function getVariablesInAllScopes(scope) {
var variableList = [];

var iterateChildScopes = function(scope) {
scope.variables.forEach(function(variable) {
variableList.push(variable);
});

scope.childScopes.forEach(function(childScope){
return iterateChildScopes(childScope);
});
};

iterateChildScopes(scope);

return variableList;
}

// Get all variables in all scopes.
variableList = getVariablesInAllScopes(file.getScopes().acquire(program));

// Check if variables are what we want to check..
variableList.reduce(function(acc, variable) {
if (isVariableGood(variable)) {
acc.push(variable);
}

return acc;
}, nodesToCheck);

// Check if variables are used.
nodesToCheck.reduce(function checkVariableReferences(acc, variable) {
if (variable.references.length === 1) {
variable.definitions.forEach(function addUnusedVariable(definition) {
acc.push(definition.node);
});
}

return acc;
}, unusedNodes);

unusedNodes.forEach(reportError);
},

_fix: function(file, error) {
var node = error.element;

while(node.type !== 'VariableDeclaration') {
node = node.parentElement;
}

node.parentElement.removeChild(node);
error.fixed = true;
}
};

0 comments on commit df355fa

Please sign in to comment.