From a61a7dd8f889dc9b7407d83e4ab273c6ffcfd0f0 Mon Sep 17 00:00:00 2001 From: Robin Houston Date: Thu, 5 Oct 2017 07:10:47 +0100 Subject: [PATCH] indent: ignored nodes should accept any indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a node is ignored by the indent rule, it ought not to matter how it’s indented. But the ignoring of nodes was implemented in such a way that the *type* of indentation (tabs vs spaces) was being checked. For example in "tab" mode, an ignored line indented by four spaces would cause the error “Expected indentation of 4 tabs but found 4 spaces”. In particular, this is a problem with “tabs for indentation, spaces for alignment” styles, where we want to allow code like: var x = 1, y = 2; where the second line is aligned using four spaces. This commit marks ignored indents by making them instances of the IgnoredTokenIndent class, and explicitly ignoring the indentation of such lines. All tests pass. Fixes #9392. --- lib/rules/indent.js | 32 +++++++++++++++++++++++++++++--- tests/lib/rules/indent.js | 17 +++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/lib/rules/indent.js b/lib/rules/indent.js index 0f6468a7e15f..3c22ad03c43b 100644 --- a/lib/rules/indent.js +++ b/lib/rules/indent.js @@ -227,6 +227,27 @@ class TokenInfo { } } +/** + * A class to store information on a token we are ignoring + */ +class IgnoredTokenIndent { + + /** + * @param {number} indent The observed indent + */ + constructor(indent) { + this._indent = indent; + } + + /** + * @returns {number} The indent + */ + valueOf() { + return this._indent; + } +} + + /** * A class to store information on desired offsets of tokens from each other */ @@ -415,9 +436,10 @@ class OffsetStorage { if (this._ignoredTokens.has(token)) { - // If the token is ignored, use the actual indent of the token as the desired indent. - // This ensures that no errors are reported for this token. - this._desiredIndentCache.set(token, this._tokenInfo.getTokenIndent(token).length / this._indentSize); + // If the token is ignored, set the desired indent to an IgnoredTokenIndent + const observedIndent = this._tokenInfo.getTokenIndent(token).length / this._indentSize; + + this._desiredIndentCache.set(token, new IgnoredTokenIndent(observedIndent)); } else if (this._lockedFirstTokens.has(token)) { const firstToken = this._lockedFirstTokens.get(token); @@ -722,6 +744,10 @@ module.exports = { * @returns {boolean} `true` if the token's indentation is correct */ function validateTokenIndent(token, desiredIndentLevel) { + if (desiredIndentLevel instanceof IgnoredTokenIndent) { + return true; + } + const indentation = tokenInfo.getTokenIndent(token); const expectedChar = indentType === "space" ? " " : "\t"; diff --git a/tests/lib/rules/indent.js b/tests/lib/rules/indent.js index 006d7f1dd678..af646431ef00 100644 --- a/tests/lib/rules/indent.js +++ b/tests/lib/rules/indent.js @@ -4744,6 +4744,23 @@ ruleTester.run("indent", rule, { `, options: [4, { ignoredNodes: ["JSXOpeningElement"] }] + }, + { + code: unIndent` + { + \tvar x = 1, + \t y = 2; + } + `, + options: ["tab"] + }, + { + code: unIndent` + var x = 1, + y = 2; + var z; + `, + options: ["tab", { ignoredNodes: ["VariableDeclarator"] }] } ],