Skip to content

Commit

Permalink
Fix starred-block alignment/missing star fixer
Browse files Browse the repository at this point in the history
  • Loading branch information
kaicataldo committed Oct 25, 2019
1 parent 0f9dd1e commit 1cec21f
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 40 deletions.
66 changes: 50 additions & 16 deletions lib/rules/multiline-comment-style.js
Expand Up @@ -42,6 +42,36 @@ module.exports = {
// Helpers
//----------------------------------------------------------------------

/**
* Checks if a comment line is starred.
* @param {string} line A string representing a comment line.
* @returns {boolean} Whether or not the comment line is starred.
*/
function isStarredCommentLine(line) {
return /^\s*\*/u.test(line);
}

/**
* Calculate the column that should be used to align other lines.
* @param {string[]} lines An array of strings that represent each comment line.
* @returns {number} The column to align with.
*/
function getColumnToAlignWith(lines) {
let columnToAlignWith = Infinity;

for (const line of lines) {
const [, prefix = null] = line.match(isStarredCommentLine(line) ? /^(\s*\*\s*)\S+/u : /^(\s*)\S+/u) || [];

if (prefix) {
if (prefix.length < columnToAlignWith) {
columnToAlignWith = prefix.length;
}
}
}

return columnToAlignWith;
}

/**
* Checks if a comment group is in starred-block form.
* @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment.
Expand Down Expand Up @@ -271,32 +301,36 @@ module.exports = {
});
}

const columnToAlignWith = getColumnToAlignWith(sourceCode.lines.slice(firstComment.loc.start.line, lines.length));

for (let lineNumber = firstComment.loc.start.line + 1; lineNumber <= firstComment.loc.end.line; lineNumber++) {
const lineText = sourceCode.lines[lineNumber - 1];
const errorType = isStarredCommentLine(lineText)
? "alignment"
: "missingStar";

if (!lineText.startsWith(expectedLinePrefix)) {
context.report({
loc: {
start: { line: lineNumber, column: 0 },
end: { line: lineNumber, column: sourceCode.lines[lineNumber - 1].length }
end: { line: lineNumber, column: lineText.length }
},
messageId: /^\s*\*/u.test(lineText)
? "alignment"
: "missingStar",
messageId: errorType,
fix(fixer) {
const lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 });
const [linePrefix, whitespaceBefore, whitespaceAfter] = lineText.match(/^(\s*)\*?(\s*)/u);
const leadingWhitespace = whitespaceAfter.length && whitespaceAfter || ` ${
whitespaceBefore.startsWith(expectedLeadingWhitespace)
? whitespaceBefore.replace(expectedLeadingWhitespace, "")
: ""
}`;
const replacementText = lineNumber === firstComment.loc.end.line || lineText.length === linePrefix.length
? expectedLinePrefix
: `${expectedLinePrefix}${leadingWhitespace}`;
const commentStartIndex = lineStartIndex + linePrefix.length;

return fixer.replaceTextRange([lineStartIndex, commentStartIndex], replacementText);

if (errorType === "alignment") {
const [, commentTextPrefix = ""] = lineText.match(/^(\s*\*)/u) || [];
const commentTextStartIndex = lineStartIndex + commentTextPrefix.length;

return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], expectedLinePrefix);
}

const [, commentTextPrefix = ""] = lineText.match(/^(\s*)/u) || [];
const commentTextStartIndex = lineStartIndex + commentTextPrefix.length;
const offset = commentTextPrefix.slice(columnToAlignWith);

return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], `${expectedLinePrefix}${offset}`);
}
});
}
Expand Down
63 changes: 39 additions & 24 deletions tests/lib/rules/multiline-comment-style.js
Expand Up @@ -471,7 +471,7 @@ ruleTester.run("multiline-comment-style", rule, {
code: `
/*
* the following line
is missing a '*' at the start
is missing a '*' at the start
*/
`,
output: `
Expand All @@ -492,7 +492,22 @@ ruleTester.run("multiline-comment-style", rule, {
output: `
/*
* the following line
* is missing a '*' at the start
*is missing a '*' at the start
*/
`,
errors: [{ messageId: "missingStar", line: 4 }]
},
{
code: `
/*
* the following line
is missing a '*' at the start
*/
`,
output: `
/*
* the following line
*is missing a '*' at the start
*/
`,
errors: [{ messageId: "missingStar", line: 4 }]
Expand Down Expand Up @@ -784,10 +799,10 @@ ruleTester.run("multiline-comment-style", rule, {
`,
output: `
/*
* {
* "foo": 1,
* "bar": 2
* }
*{
* "foo": 1,
* "bar": 2
*}
*/
`,
errors: [
Expand All @@ -809,10 +824,10 @@ ruleTester.run("multiline-comment-style", rule, {
`,
output: `
/*
* {
* \t"foo": 1,
* \t"bar": 2
* }
*{
*\t"foo": 1,
*\t"bar": 2
*}
*/
`,
errors: [
Expand All @@ -834,10 +849,10 @@ ruleTester.run("multiline-comment-style", rule, {
`,
output: `
/*
* {
* \t "foo": 1,
* \t "bar": 2
* }
*{
*\t "foo": 1,
*\t "bar": 2
*}
*/
`,
errors: [
Expand All @@ -859,10 +874,10 @@ ruleTester.run("multiline-comment-style", rule, {
`,
output: `
/*
* {
* "foo": 1,
* "bar": 2
* }
*{
*"foo": 1,
*"bar": 2
*}
*/
`,
errors: [
Expand All @@ -884,10 +899,10 @@ ruleTester.run("multiline-comment-style", rule, {
`,
output: `
\t /*
\t * {
\t * "foo": 1,
\t * "bar": 2
\t * }
\t * \t {
\t * \t "foo": 1,
\t *\t "bar": 2
\t *}
\t */
`,
errors: [
Expand Down Expand Up @@ -1291,7 +1306,7 @@ ${" "}
/*
* foo
*
* bar
* bar${" "}
*/
`,
options: ["starred-block"],
Expand All @@ -1312,7 +1327,7 @@ ${" "}
/*
* foo
*
* bar
* bar${" "}
*/
`,
options: ["starred-block"],
Expand Down

0 comments on commit 1cec21f

Please sign in to comment.