diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:01:11 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:02:09 +0200 |
commit | 363723fc84f7b8477592e0105aeb331ec9a017af (patch) | |
tree | 29f92724f34131bac64d6a318dd7e30612e631c7 /node_modules/tslint/lib/rules/indentRule.js | |
parent | 5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff) |
node_modules
Diffstat (limited to 'node_modules/tslint/lib/rules/indentRule.js')
-rw-r--r-- | node_modules/tslint/lib/rules/indentRule.js | 223 |
1 files changed, 84 insertions, 139 deletions
diff --git a/node_modules/tslint/lib/rules/indentRule.js b/node_modules/tslint/lib/rules/indentRule.js index 7d133a13b..7aa3459ba 100644 --- a/node_modules/tslint/lib/rules/indentRule.js +++ b/node_modules/tslint/lib/rules/indentRule.js @@ -17,6 +17,7 @@ */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); +var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); var OPTION_USE_TABS = "tabs"; @@ -28,152 +29,96 @@ var Rule = (function (_super) { function Rule() { return _super !== null && _super.apply(this, arguments) || this; } + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = function (expected) { + return expected + " indentation expected"; + }; Rule.prototype.apply = function (sourceFile) { - return this.applyWithWalker(new IndentWalker(sourceFile, this.getOptions())); + var options = parseOptions(this.ruleArguments); + return options === undefined ? [] : this.applyWithFunction(sourceFile, walk, options); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "indent", + description: "Enforces indentation with tabs or spaces.", + rationale: (_a = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], _a.raw = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], Lint.Utils.dedent(_a)), + optionsDescription: (_b = ["\n One of the following arguments must be provided:\n\n * `", "` enforces consistent spaces.\n * `", "` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * `", "` enforces 2 space indentation.\n * `", "` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], _b.raw = ["\n One of the following arguments must be provided:\n\n * \\`", "\\` enforces consistent spaces.\n * \\`", "\\` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * \\`", "\\` enforces 2 space indentation.\n * \\`", "\\` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], Lint.Utils.dedent(_b, OPTION_USE_SPACES, OPTION_USE_TABS, OPTION_INDENT_SIZE_2.toString(), OPTION_INDENT_SIZE_4.toString())), + options: { + type: "array", + items: [ + { + type: "string", + enum: [OPTION_USE_TABS, OPTION_USE_SPACES], + }, + { + type: "number", + enum: [OPTION_INDENT_SIZE_2, OPTION_INDENT_SIZE_4], + }, + ], + minLength: 0, + maxLength: 5, + }, + optionExamples: [ + [true, OPTION_USE_SPACES], + [true, OPTION_USE_SPACES, OPTION_INDENT_SIZE_4], + [true, OPTION_USE_TABS, OPTION_INDENT_SIZE_2], + ], + type: "maintainability", + typescriptOnly: false, }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "indent", - description: "Enforces indentation with tabs or spaces.", - rationale: (_a = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], _a.raw = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], Lint.Utils.dedent(_a)), - optionsDescription: (_b = ["\n One of the following arguments must be provided:\n\n * `", "` enforces consistent spaces.\n * `", "` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * `", "` enforces 2 space indentation.\n * `", "` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], _b.raw = ["\n One of the following arguments must be provided:\n\n * \\`", "\\` enforces consistent spaces.\n * \\`", "\\` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * \\`", "\\` enforces 2 space indentation.\n * \\`", "\\` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], Lint.Utils.dedent(_b, OPTION_USE_SPACES, OPTION_USE_TABS, OPTION_INDENT_SIZE_2.toString(), OPTION_INDENT_SIZE_4.toString())), - options: { - type: "array", - items: [ - { - type: "string", - enum: [OPTION_USE_TABS, OPTION_USE_SPACES], - }, - { - type: "number", - enum: [OPTION_INDENT_SIZE_2, OPTION_INDENT_SIZE_4], - }, - ], - minLength: 0, - maxLength: 5, - }, - optionExamples: [ - [true, OPTION_USE_SPACES], - [true, OPTION_USE_SPACES, OPTION_INDENT_SIZE_4], - [true, OPTION_USE_TABS, OPTION_INDENT_SIZE_2], - ], - type: "maintainability", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_TABS = "tab indentation expected"; -Rule.FAILURE_STRING_SPACES = "space indentation expected"; exports.Rule = Rule; -// visit every token and enforce that only the right character is used for indentation -var IndentWalker = (function (_super) { - tslib_1.__extends(IndentWalker, _super); - function IndentWalker(sourceFile, options) { - var _this = _super.call(this, sourceFile, options) || this; - // fixer is only provided with the indent size arg - if (_this.getOptions().length === 2 && typeof _this.getOptions()[1] === "number" - && (_this.getOptions()[1] === OPTION_INDENT_SIZE_2 || _this.getOptions()[1] === OPTION_INDENT_SIZE_4)) { - // tslint:disable-next-line:no-unsafe-any - var size_1 = _this.getOptions()[1]; - var replaceRegExp_1; - var replaceIndent_1; - if (_this.hasOption(OPTION_USE_TABS)) { - _this.regExp = new RegExp(" ".repeat(size_1)); - _this.failureString = Rule.FAILURE_STRING_TABS; - // we want to find every group of `size` spaces, plus up to one 'incomplete' group - replaceRegExp_1 = new RegExp("^( {" + size_1 + "})+( {1," + (size_1 - 1) + "})?", "g"); - replaceIndent_1 = "\t"; - } - else if (_this.hasOption(OPTION_USE_SPACES)) { - _this.regExp = new RegExp("\t"); - _this.failureString = size_1 + " " + Rule.FAILURE_STRING_SPACES; - replaceRegExp_1 = new RegExp("\t", "g"); - replaceIndent_1 = " ".repeat(size_1); - } - _this.replacementFactory = function (lineStart, fullLeadingWhitespace) { - return new Lint.Replacement(lineStart, fullLeadingWhitespace.length, fullLeadingWhitespace.replace(replaceRegExp_1, function (match) { return replaceIndent_1.repeat(Math.ceil(match.length / size_1)); })); - }; +function parseOptions(ruleArguments) { + var type = ruleArguments[0]; + if (type !== OPTION_USE_TABS && type !== OPTION_USE_SPACES) { + return undefined; + } + var size = ruleArguments[1]; + return { + size: size === OPTION_INDENT_SIZE_2 || size === OPTION_INDENT_SIZE_4 ? size : undefined, + tabs: type === OPTION_USE_TABS, + }; +} +function walk(ctx) { + var sourceFile = ctx.sourceFile, _a = ctx.options, tabs = _a.tabs, size = _a.size; + var regExp = tabs ? new RegExp(" ".repeat(size === undefined ? 1 : size)) : /\t/; + var failure = Rule.FAILURE_STRING(tabs ? "tab" : size === undefined ? "space" : size + " space"); + for (var _i = 0, _b = tsutils_1.getLineRanges(sourceFile); _i < _b.length; _i++) { + var _c = _b[_i], pos = _c.pos, contentLength = _c.contentLength; + if (contentLength === 0) { + continue; } - else { - if (_this.hasOption(OPTION_USE_TABS)) { - _this.regExp = new RegExp(" "); - _this.failureString = Rule.FAILURE_STRING_TABS; - } - else if (_this.hasOption(OPTION_USE_SPACES)) { - _this.regExp = new RegExp("\t"); - _this.failureString = Rule.FAILURE_STRING_SPACES; - } - _this.replacementFactory = function () { return undefined; }; + var line = sourceFile.text.substr(pos, contentLength); + var indentEnd = line.search(/\S/); + if (indentEnd === 0) { + continue; } - return _this; - } - IndentWalker.prototype.visitSourceFile = function (node) { - if (!this.hasOption(OPTION_USE_TABS) && !this.hasOption(OPTION_USE_SPACES)) { - // if we don't have either option, no need to check anything, and no need to call super, so just return - return; + if (indentEnd === -1) { + indentEnd = contentLength; } - var endOfComment = -1; - var endOfTemplateString = -1; - var scanner = ts.createScanner(ts.ScriptTarget.ES5, false, ts.LanguageVariant.Standard, node.text); - for (var _i = 0, _a = node.getLineStarts(); _i < _a.length; _i++) { - var lineStart = _a[_i]; - if (lineStart < endOfComment || lineStart < endOfTemplateString) { - // skip checking lines inside multi-line comments or template strings - continue; - } - scanner.setTextPos(lineStart); - var currentScannedType = scanner.scan(); - var fullLeadingWhitespace = ""; - var lastStartPos = -1; - while (currentScannedType === ts.SyntaxKind.WhitespaceTrivia) { - var startPos = scanner.getStartPos(); - if (startPos === lastStartPos) { - break; - } - lastStartPos = startPos; - fullLeadingWhitespace += scanner.getTokenText(); - currentScannedType = scanner.scan(); - } - var commentRanges = ts.getTrailingCommentRanges(node.text, lineStart); - if (commentRanges !== undefined) { - endOfComment = commentRanges[commentRanges.length - 1].end; - } - else { - var scanType = currentScannedType; - // scan until we reach end of line, skipping over template strings - while (scanType !== ts.SyntaxKind.NewLineTrivia && scanType !== ts.SyntaxKind.EndOfFileToken) { - if (scanType === ts.SyntaxKind.NoSubstitutionTemplateLiteral) { - // template string without expressions - skip past it - endOfTemplateString = scanner.getStartPos() + scanner.getTokenText().length; - } - else if (scanType === ts.SyntaxKind.TemplateHead) { - // find end of template string containing expressions... - while (scanType !== ts.SyntaxKind.TemplateTail && scanType !== ts.SyntaxKind.EndOfFileToken) { - scanType = scanner.scan(); - if (scanType === ts.SyntaxKind.CloseBraceToken) { - scanType = scanner.reScanTemplateToken(); - } - } - // ... and skip past it - endOfTemplateString = scanner.getStartPos() + scanner.getTokenText().length; - } - scanType = scanner.scan(); - } - } - switch (currentScannedType) { - case ts.SyntaxKind.SingleLineCommentTrivia: - case ts.SyntaxKind.MultiLineCommentTrivia: - case ts.SyntaxKind.NewLineTrivia: - // ignore lines that have comments before the first token - continue; - } - if (this.regExp.test(fullLeadingWhitespace)) { - this.addFailureAt(lineStart, fullLeadingWhitespace.length, this.failureString, this.replacementFactory(lineStart, fullLeadingWhitespace)); - } + var whitespace = line.slice(0, indentEnd); + if (!regExp.test(whitespace)) { + continue; } - // no need to call super to visit the rest of the nodes, so don't call super here - }; - return IndentWalker; -}(Lint.RuleWalker)); + var token = tsutils_1.getTokenAtPosition(sourceFile, pos); + if (token.kind !== ts.SyntaxKind.JsxText && + (pos >= token.getStart(sourceFile) || tsutils_1.isPositionInComment(sourceFile, pos, token))) { + continue; + } + ctx.addFailureAt(pos, indentEnd, failure, createFix(pos, whitespace, tabs, size)); + } +} +function createFix(lineStart, fullLeadingWhitespace, tabs, size) { + if (size === undefined) { + return undefined; + } + var replaceRegExp = tabs + ? new RegExp("^( {" + size + "})+( {1," + (size - 1) + "})?", "g") + : /\t/g; + var replacement = fullLeadingWhitespace.replace(replaceRegExp, function (match) { + return (tabs ? "\t" : " ".repeat(size)).repeat(Math.ceil(match.length / size)); + }); + return new Lint.Replacement(lineStart, fullLeadingWhitespace.length, replacement); +} var _a, _b; |