ember-template-lint
Version:
Linter for Ember or Handlebars templates.
80 lines (62 loc) • 2.35 kB
JavaScript
const Rule = require('./base');
const CONFIG_ERROR_MESSAGE = 'Invalid rule configuration for `no-multiple-empty-lines` found';
module.exports = class NoMultipleEmptyLines extends Rule {
parseConfig(config) {
return parseConfig(config);
}
visitor() {
// Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue
let allLines =
this.source[this.source.length - 1] === '' ? this.source.slice(0, -1) : this.source;
return {
Template: {
exit() {
let max = 'max' in this.config ? this.config.max : 1;
allLines
// Given a list of lines, first get a list of line numbers that are non-empty.
.reduce((nonEmptyLineNumbers, line, index) => {
if (line.trim()) {
nonEmptyLineNumbers.push(index + 1);
}
return nonEmptyLineNumbers;
}, [])
// Add a value at the end to allow trailing empty lines to be checked.
.concat(allLines.length + 1) // eslint-disable-line unicorn/prefer-spread
// Given two line numbers of non-empty lines, report the lines between if the difference is too large.
.reduce((lastLineNumber, lineNumber) => {
if (lineNumber - lastLineNumber - 1 > max) {
let message = `More than ${max} blank ${max === 1 ? 'line' : 'lines'} not allowed.`;
let loc = {
start: { line: lastLineNumber + max, column: 0 },
end: { line: lineNumber, column: 0 },
};
this.log({
message,
line: loc.start.line,
column: loc.start.column,
source: this.sourceForLoc(loc),
});
}
return lineNumber;
}, 0);
},
},
};
}
};
function parseConfig(config) {
if (config === true) {
return { max: 1 };
}
if (typeof config !== 'object' || config === null) {
throw new Error(CONFIG_ERROR_MESSAGE);
}
let max = config.max;
if (typeof max !== 'number') {
throw new TypeError(CONFIG_ERROR_MESSAGE);
}
return { max };
}
module.exports.parseConfig = parseConfig;
module.exports.CONFIG_ERROR_MESSAGE = CONFIG_ERROR_MESSAGE;
;