Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New: multiline-comment-style rule (fixes #8320) #9389

Merged
merged 5 commits into from Oct 14, 2017

Conversation

aladdin-add
Copy link
Member

What is the purpose of this pull request? (put an "X" next to item)

[x] New rule (template)

What changes did you make? (Give an overview)
fixes #8320

Is there anything you'd like reviewers to focus on?

@not-an-aardvark not-an-aardvark added accepted There is consensus among the team that this change meets the criteria for inclusion feature This change adds a new feature to ESLint rule Relates to ESLint's core rules labels Oct 5, 2017
not-an-aardvark and others added 2 commits October 6, 2017 22:07
This code is currently messy and incomplete. There are also some edge cases that the rule's design needs to address (e.g. allowing "banner" comments which are created from several consecutive line comments).
@aladdin-add aladdin-add changed the title WIP: New: multiline-comment-style rule (fixes #8320) New: multiline-comment-style rule (fixes #8320) Oct 6, 2017
Copy link
Member

@not-an-aardvark not-an-aardvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! This mostly looks good -- I just noticed a small bug.

`,
options: ["bare-block"],
errors: [{ message: EXPECTED_BLOCK_ERROR, line: 2 }]
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a test where a single-line comment contains */? I think this will currently cause invalid syntax.

/* eslint multiline-comment-style: [error, bare-block] */

// foo */
// bar

: MISSING_STAR_ERROR,
fix(fixer) {

// TODO: Make this more readable, possibly by splitting it into two separate cases.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment still needed?

},
message: EXPECTED_BLOCK_ERROR,
fix(fixer) {
return fixer.replaceTextRange([commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]], convertToBlock(commentGroup[0], commentLines.filter(line => line)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Can you split this onto multiple lines?

return fixer.replaceTextRange(
    [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]],
    convertToBlock(commentGroup[0], commentLines.filter(line => line))
);

(As a separate note, maybe we should enable max-len on the codebase.)

// prohibits block comments from having a * at the beginning of each line.
if (commentGroup[0].type === "Block") {
const block = commentGroup[0];
const lines = block.value.split(astUtils.LINEBREAK_MATCHER).slice(1, -1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is .slice(1, -1) used here? It seems like this will omit the last line if someone does this:

/* foo
 * bar */

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is to skip the first line and last line in some cases like this:

/*
* foo
* bar
*/

but seems not ideal. 😂

},
message: EXPECTED_LINES_ERROR,
fix(fixer) {
return fixer.replaceTextRange(block.range, convertToSeparateLines(block, commentLines.filter(line => line)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: This could be

return fixer.replaceText(block, convertToSeparateLines(block, commentLines.filter(line => line)));

},
message: EXPECTED_BLOCK_ERROR,
fix(fixer) {
return fixer.replaceTextRange(block.range, convertToBlock(block, commentLines.filter(line => line)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: This could be

return fixer.replaceText(block, convertToBlock(block, commentLines.filter(line => line)));

(Maybe we should create a new rule in eslint-plugin-eslint-plugin for it 😃)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good idea!

},
{
code: `
/* this blockk
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: There is a typo here (this should just say block).

});
}

// TODO: clean this up
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment still needed?

薛定谔的猫 and others added 2 commits October 11, 2017 20:13
Squashed commits:
[914bea1] fix: fixer would cause invalid syntax.
[a4dd76c] Fix: isJSDoc checking each line starts with "*".
[e16985a] prefer fixer.replaceText().

 .
@eslintbot
Copy link

LGTM

Copy link
Member

@not-an-aardvark not-an-aardvark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thanks!

@eslint eslint deleted a comment from eslintbot Oct 13, 2017
@eslint eslint deleted a comment from eslintbot Oct 13, 2017
@eslint eslint deleted a comment from eslintbot Oct 13, 2017
@eslint eslint deleted a comment from eslintbot Oct 13, 2017
@eslint eslint deleted a comment from eslintbot Oct 13, 2017
Copy link
Member

@kaicataldo kaicataldo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great! Just a few comments/questions.

return {
Program() {
return sourceCode.getAllComments()
.filter(comment => comment.type !== "Shebang")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Is there a reason all these checks can't happen in one .filter() to cut down on the number of times we have to iterate over the comments array?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't feel strong about this. will update if you like it~ 😄


// disallows consecutive line comments in favor of using a block comment.
if (commentGroup[0].type === "Line" && commentLines.length > 1 &&
!commentLines.some(value => value.includes("*/"))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this check necessary? Example of something that would be ignored that I'm not sure should be:

// Here's some regex /\w*/ in
// a comment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answered by #9389 (comment)

"starred-block"(commentGroup) {
const commentLines = getCommentLines(commentGroup);

if (commentLines.some(value => value.includes("*/"))) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this check necessary? Example of something that would be ignored that I'm not sure should be:

// Here's some regex /\w*/ in
// a comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*/ cannot exsist in a block comment, e.g.

/* Here's some regex /\w*/ in
a comment. */

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm mistaken, can't commentLines also include Line comments? Or maybe a better question is this: what would happen for the example I listed above? Apologies if I'm misreading or misunderstanding something!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part of the rule looks at line comments and reports an error to indicate that they should be converted to block comments. However, line comments that contain */ can't be converted to block comments, so it doesn't make sense for the rule to report them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, right - got it! Thanks!

function isJSDoc(commentGroup) {
const lines = commentGroup[0].value.split(astUtils.LINEBREAK_MATCHER);

return commentGroup[0].type === "Block" &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should make extract this into ast-utils so we can reuse it?

Another place we do a similar (though less rigorous) check that we could unify: https://github.com/eslint/eslint/blob/master/lib/util/source-code.js#L295

@ilyavolodin ilyavolodin merged commit 8eb4aae into eslint:master Oct 14, 2017
@kaicataldo
Copy link
Member

Thanks for contributing to ESLint!

@aladdin-add aladdin-add deleted the issue8320 branch April 1, 2018 13:20
@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Apr 13, 2018
@eslint-deprecated eslint-deprecated bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Apr 13, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
accepted There is consensus among the team that this change meets the criteria for inclusion archived due to age This issue has been archived; please open a new issue for any further discussion feature This change adds a new feature to ESLint rule Relates to ESLint's core rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rule proposal: multiline-comment-style
5 participants