Skip to content

Commit

Permalink
Update: Correctly indent JSXText with trailing linebreaks (fixes #9878)…
Browse files Browse the repository at this point in the history
… (#10055)

This fixes a bug in the `indent` rule where a line comparison with the end of a token would use the end location of any trailing whitespace in the token, rather than the location of the last non-whitespace character in the token. This behavior went against user intuition for tokens with trailing whitespace.
  • Loading branch information
not-an-aardvark committed Mar 6, 2018
1 parent 2a4c838 commit 72ca5b3
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
19 changes: 18 additions & 1 deletion lib/rules/indent.js
Expand Up @@ -779,6 +779,19 @@ module.exports = {
return (statement.type === "ExpressionStatement" || statement.type === "VariableDeclaration") && statement.parent.type === "Program";
}

/**
* Counts the number of linebreaks that follow the last non-whitespace character in a string
* @param {string} string The string to check
* @returns {number} The number of JavaScript linebreaks that follow the last non-whitespace character,
* or the total number of linebreaks if the string is all whitespace.
*/
function countTrailingLinebreaks(string) {
const trailingWhitespace = string.match(/\s*$/)[0];
const linebreakMatches = trailingWhitespace.match(astUtils.createGlobalLinebreakMatcher());

return linebreakMatches === null ? 0 : linebreakMatches.length;
}

/**
* Check indentation for lists of elements (arrays, objects, function params)
* @param {ASTNode[]} elements List of elements that should be offset
Expand Down Expand Up @@ -836,8 +849,12 @@ module.exports = {
} else {
const previousElement = elements[index - 1];
const firstTokenOfPreviousElement = previousElement && getFirstToken(previousElement);
const previousElementLastToken = previousElement && sourceCode.getLastToken(previousElement);

if (previousElement && sourceCode.getLastToken(previousElement).loc.end.line > startToken.loc.end.line) {
if (
previousElement &&
previousElementLastToken.loc.end.line - countTrailingLinebreaks(previousElementLastToken.value) > startToken.loc.end.line
) {
offsets.setDesiredOffsets(element.range, firstTokenOfPreviousElement, 0);
}
}
Expand Down
36 changes: 36 additions & 0 deletions tests/lib/rules/indent.js
Expand Up @@ -4607,6 +4607,16 @@ ruleTester.run("indent", rule, {
);
}
`,
unIndent`
<div>foo
<div>bar</div>
</div>
`,
unIndent`
<small>Foo bar&nbsp;
<a>baz qux</a>.
</small>
`,
{
code: unIndent`
a(b
Expand Down Expand Up @@ -9136,6 +9146,32 @@ ruleTester.run("indent", rule, {
`,
errors: expectedErrors([3, 8, 6, "Block"])
},
{
code: unIndent`
<div>foo
<div>bar</div>
</div>
`,
output: unIndent`
<div>foo
<div>bar</div>
</div>
`,
errors: expectedErrors([2, 4, 0, "Punctuator"])
},
{
code: unIndent`
<small>Foo bar&nbsp;
<a>baz qux</a>.
</small>
`,
output: unIndent`
<small>Foo bar&nbsp;
<a>baz qux</a>.
</small>
`,
errors: expectedErrors([2, 4, 0, "Punctuator"])
},
{
code: unIndent`
({
Expand Down

0 comments on commit 72ca5b3

Please sign in to comment.