coffeelint-callback-handle-error
Version:
Coffeelint rule finds instances of error objects passed through a callback not being handled
136 lines (124 loc) • 4.36 kB
JavaScript
// Generated by CoffeeScript 1.12.6
(function() {
var CallbackHandleError, getNodeType;
getNodeType = function(node) {
return node.constructor.name;
};
module.exports = CallbackHandleError = (function() {
function CallbackHandleError() {}
CallbackHandleError.prototype.rule = {
name: 'callback_handle_error',
level: 'error',
message: 'Error in callback not handled',
description: 'Finds instances of error objects passed through a callback not being handled',
patterns: ["^err(or)?", "[Ee]rr(or)?$"]
};
CallbackHandleError.prototype.lintAST = function(node, astApi) {
var pattern, patterns, ref;
this.astApi = astApi;
patterns = (ref = this.astApi.config.patterns) != null ? ref : this.rule.patterns;
this.errorVariablePatterns = (function() {
var i, len, results;
results = [];
for (i = 0, len = patterns.length; i < len; i++) {
pattern = patterns[i];
results.push(new RegExp(pattern));
}
return results;
})();
this.lintNode(node);
};
CallbackHandleError.prototype.lintNode = function(node) {
var i, j, len, len1, node_type, param, pattern, ref, ref1, ref2, var_name;
node_type = getNodeType(node);
switch (node_type) {
case 'Code':
ref = node.params;
for (i = 0, len = ref.length; i < len; i++) {
param = ref[i];
var_name = (ref1 = param.name) != null ? ref1.value : void 0;
ref2 = this.errorVariablePatterns;
for (j = 0, len1 = ref2.length; j < len1; j++) {
pattern = ref2[j];
if (pattern.test(var_name) && !this.handlesError(node, var_name)) {
this.throwError(node, "Error object '" + var_name + "' in callback not handled");
break;
}
}
}
}
node.eachChild((function(_this) {
return function(child) {
_this.lintNode(child);
};
})(this));
};
CallbackHandleError.prototype.handlesError = function(code_node, var_name) {
var found_usage;
found_usage = false;
code_node.traverseChildren(true, function(child) {
var arg, i, inner_child_type, j, len, len1, node_type, param, ref, ref1;
node_type = getNodeType(child);
switch (node_type) {
case 'If':
child.condition.traverseChildren(false, function(inner_child) {
var inner_type;
inner_type = getNodeType(inner_child);
switch (inner_type) {
case 'Literal':
case 'IdentifierLiteral':
if (inner_child.value === var_name) {
found_usage = true;
return false;
}
}
});
break;
case 'Call':
ref = child.args;
for (i = 0, len = ref.length; i < len; i++) {
arg = ref[i];
arg.traverseChildren(false, function(inner_child) {
var inner_type;
inner_type = getNodeType(inner_child);
switch (inner_type) {
case 'Literal':
case 'IdentifierLiteral':
if (inner_child.value === var_name) {
found_usage = true;
return false;
}
}
});
}
return;
case 'Code':
ref1 = child.params;
for (j = 0, len1 = ref1.length; j < len1; j++) {
param = ref1[j];
inner_child_type = getNodeType(param);
if (inner_child_type === 'Param') {
if (param.name.value === var_name) {
return false;
}
}
}
}
if (found_usage) {
return false;
}
});
return found_usage;
};
CallbackHandleError.prototype.throwError = function(node, message) {
var err;
err = this.astApi.createError({
lineNumber: node.locationData.first_line + 1,
message: message
});
this.errors.push(err);
};
return CallbackHandleError;
})();
}).call(this);
//# sourceMappingURL=index.js.map