Skip to content

Commit

Permalink
indent: ignored nodes should accept any indentation
Browse files Browse the repository at this point in the history
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 eslint#9392.
  • Loading branch information
robinhouston committed Oct 5, 2017
1 parent ee99876 commit a61a7dd
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
32 changes: 29 additions & 3 deletions lib/rules/indent.js
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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";

Expand Down
17 changes: 17 additions & 0 deletions tests/lib/rules/indent.js
Expand Up @@ -4744,6 +4744,23 @@ ruleTester.run("indent", rule, {
</foo>
`,
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"] }]
}
],

Expand Down

0 comments on commit a61a7dd

Please sign in to comment.