You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
2.5 KiB

/**
* @fileoverview Rule to flag use of variables before they are defined
* @author Ilya Volodin
* @copyright 2013 Ilya Volodin. All rights reserved.
*/
"use strict";
//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------
var NO_FUNC = "nofunc";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
function findDeclaration(name, scope) {
// try searching in the current scope first
for (var i = 0, l = scope.variables.length; i < l; i++) {
if (scope.variables[i].name === name) {
return scope.variables[i];
}
}
// check if there's upper scope and call recursivly till we find the variable
if (scope.upper) {
return findDeclaration(name, scope.upper);
}
}
function findVariables() {
var scope = context.getScope();
var typeOption = context.options[0];
function checkLocationAndReport(reference, declaration) {
if (typeOption !== NO_FUNC || declaration.defs[0].type !== "FunctionName") {
if (declaration.identifiers[0].range[1] > reference.identifier.range[1]) {
context.report(reference.identifier, "{{a}} was used before it was defined", {a: reference.identifier.name});
}
}
}
scope.references.forEach(function(reference) {
// if the reference is resolved check for declaration location
// if not, it could be function invocation, try to find manually
if (reference.resolved && reference.resolved.identifiers.length > 0) {
checkLocationAndReport(reference, reference.resolved);
} else {
var declaration = findDeclaration(reference.identifier.name, scope);
// if there're no identifiers, this is a global environment variable
if (declaration && declaration.identifiers.length !== 0) {
checkLocationAndReport(reference, declaration);
}
}
});
}
return {
"Program": findVariables,
"FunctionExpression": findVariables,
"FunctionDeclaration": findVariables,
"ArrowFunctionExpression": findVariables
};
};