jscs
Version:
JavaScript Style Checker
160 lines (145 loc) • 3.84 kB
JavaScript
var colors = require('colors');
/**
* Set of errors for specified file.
*
* @name Errors
*/
var Errors = function(file) {
this._errorList = [];
this._file = file;
};
Errors.prototype = {
/**
* Adds style error to the list
*
* @param {String} message
* @param {Number|Object} line
* @param {Number} [column]
*/
add: function(message, line, column) {
if (typeof line === 'object') {
column = line.column;
line = line.line;
}
this._errorList.push({
message: message,
line: line,
column: column
});
},
/**
* Returns style error list.
*
* @returns {Object[]}
*/
getErrorList: function() {
return this._errorList;
},
/**
* Returns filename of file this error list is for.
*
* @returns {String}
*/
getFilename: function() {
return this._file.getFilename();
},
/**
* Returns true if no errors are added.
*
* @returns {Boolean}
*/
isEmpty: function() {
return this._errorList.length === 0;
},
/**
* Returns amount of errors added by the rules.
*
* @returns {Number}
*/
getErrorCount: function () {
return this._errorList.length;
},
/**
* Formats error for futher output.
*
* @param {Object} error
* @param {Boolean} colorize
* @returns {String}
*/
explainError: function(error, colorize) {
var lineNumber = error.line - 1;
var lines = this._file.getLines();
var result = [
renderLine(lineNumber, lines[lineNumber], colorize),
renderPointer(error.column, colorize)
];
var i = lineNumber - 1;
var linesAround = 2;
while (i >= 0 && i >= (lineNumber - linesAround)) {
result.unshift(renderLine(i, lines[i], colorize));
i--;
}
i = lineNumber + 1;
while (i < lines.length && i <= (lineNumber + linesAround)) {
result.push(renderLine(i, lines[i], colorize));
i++;
}
result.unshift(formatErrorMessage(error.message, this.getFilename(), colorize));
return result.join('\n');
}
};
/**
* Formats error message header.
*
* @param {String} message
* @param {String} filename
* @param {Boolean} colorize
* @returns {String}
*/
function formatErrorMessage(message, filename, colorize) {
return (colorize ? colors.bold(message) : message) +
' at ' +
(colorize ? colors.green(filename) : filename) + ' :';
}
/**
* Simple util for prepending spaces to the string until it fits specified size.
*
* @param {String} s
* @param {Number} len
* @returns {String}
*/
function prependSpaces(s, len) {
while (s.length < len) {
s = ' ' + s;
}
return s;
}
/**
* Renders single line of code in style error formatted output.
*
* @param {Number} n line number
* @param {String} line
* @param {Boolean} colorize
* @returns {String}
*/
function renderLine(n, line, colorize) {
// Convert tabs to spaces, so errors in code lines with tabs as indention symbol
// could be correctly rendered, plus it will provide less verbose output
line = line.replace(/\t/g, ' ');
// "n + 1" to print lines in human way (counted from 1)
var lineNumber = prependSpaces((n + 1).toString(), 5) + ' |';
return ' ' + (colorize ? colors.grey(lineNumber) : lineNumber) + line;
}
/**
* Renders pointer:
* ---------------^
*
* @param {Number} column
* @param {Boolean} colorize
* @returns {String}
*/
function renderPointer(column, colorize) {
var res = (new Array(column + 9)).join('-') + '^';
return colorize ? colors.grey(res) : res;
}
module.exports = Errors;