eclint
Version:
Validate or fix code that doesn't adhere to EditorConfig settings or infer settings from existing code.
147 lines • 4.75 kB
JavaScript
;
var _ = require("lodash");
var EditorConfigError = require("../editor-config-error");
var IndentSizeRule = require("./indent_size");
var IndentStyle;
(function (IndentStyle) {
IndentStyle[IndentStyle["ignore"] = 0] = "ignore";
IndentStyle[IndentStyle["tab"] = 1] = "tab";
IndentStyle[IndentStyle["space"] = 2] = "space";
})(IndentStyle || (IndentStyle = {}));
function resolve(settings) {
switch (settings.indent_style) {
case 'tab':
return IndentStyle.tab;
case 'space':
return IndentStyle.space;
default:
return IndentStyle.ignore;
}
}
function checkLine(line, indentStyle) {
if (!line.prefix) {
return;
}
if (indentStyle === IndentStyle.tab && line.blockCommentStart && /^\t* +$/.test(line.prefix)) {
return;
}
function searchString(searchValue) {
var index = line.prefix.indexOf(searchValue);
if (index < 0) {
return 0;
}
return index + searchValue.length;
}
var tabColumnNumber = searchString('\t');
var spaceColumnNumber = searchString(' ');
var errorMessage;
var errorColumnNumber;
if (indentStyle === IndentStyle.space) {
errorColumnNumber = tabColumnNumber;
errorMessage = 'invalid indent style: tab, expected: space';
}
else if (indentStyle === IndentStyle.tab) {
errorColumnNumber = spaceColumnNumber;
errorMessage = 'invalid indent style: space, expected: tab';
}
if (!errorColumnNumber && tabColumnNumber && spaceColumnNumber) {
errorColumnNumber = Math.max(tabColumnNumber, spaceColumnNumber);
errorMessage = 'invalid indent style: mixed tabs with spaces';
}
if (errorColumnNumber) {
var error = new EditorConfigError(errorMessage);
error.lineNumber = line.number;
error.columnNumber = errorColumnNumber;
error.rule = 'indent_style';
error.source = line.text;
return error;
}
}
function check(settings, document) {
var indentStyle = resolve(settings);
return document.lines.map(function (line) {
return checkLine(line, indentStyle);
}).filter(Boolean);
}
function identifyIndentation(indentSize, line) {
var spaceCount = 0;
var hardTabCount = line.prefix.replace(/ /g, function () {
spaceCount++;
return '';
}).length;
var softTabCount = 0;
if (spaceCount) {
softTabCount = spaceCount / indentSize;
if (indentSize > 2 && softTabCount % 0.5) {
softTabCount = Math.round(softTabCount);
}
else {
softTabCount = Math.floor(softTabCount);
}
}
return hardTabCount + softTabCount;
}
function getTabWidth(settings, document) {
var tabWidth = IndentSizeRule.resolve(settings);
if (isNaN(tabWidth)) {
tabWidth = IndentSizeRule.infer(document);
}
return tabWidth;
}
function fixLine(line, indentStyle, tabWidth) {
var fixedIndentation;
if (line.isBlockComment) {
fixedIndentation = line.blockCommentStart.prefix + _.repeat(' ', line.padSize);
}
else if (indentStyle !== IndentStyle.ignore && tabWidth) {
var indentCount = identifyIndentation(tabWidth, line);
switch (indentStyle) {
case IndentStyle.space:
fixedIndentation = _.repeat(' ', indentCount * tabWidth);
break;
case IndentStyle.tab:
fixedIndentation = _.repeat('\t', indentCount);
break;
}
}
if (fixedIndentation) {
line.prefix = fixedIndentation;
}
return line;
}
function fix(settings, document) {
var indentStyle = resolve(settings);
var tabWidth = getTabWidth(settings, document);
document.lines.map(function (line) {
return fixLine(line, indentStyle, tabWidth);
});
return document;
}
function infer(document) {
var tabCount = 0;
var spaceCount = 0;
document.lines.forEach(function (line) {
if (!line.prefix) {
return;
}
else if (line.prefix[0] === '\t') {
tabCount++;
}
else if (!line.isBlockComment || line.prefix.length > line.padSize) {
spaceCount++;
}
});
if (!spaceCount && !tabCount) {
return;
}
return spaceCount > tabCount ? 'space' : 'tab';
}
var IndentStyleRule = {
check: check,
fix: fix,
infer: infer,
resolve: resolve,
type: 'DocumentRule',
};
module.exports = IndentStyleRule;
//# sourceMappingURL=indent_style.js.map