Repository: eslint/eslint (JavaScript)

Issue:
[array-bracket-newline] doesn't handle inline comments properly
**Tell us about your environment**

* **ESLint Version:** 6.5.1
* **Node Version:** 10.15.0
* **npm Version:** 6.4.1

**What parser (default, Babel-ESLint, etc.) are you using?**

`@typescript-eslint/parser`

**Please show your full configuration:**

[Here](https://pastebin.com/Ni7HyKHL) it is, just uncomment the "array-bracket-newline" rule.

**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**

```js
const asd = [ // comment
  123,
  123
];
```

```bash
npx eslint src --ext '.ts, .tsx'
```

**What did you expect to happen?**

No error detected.

**What actually happened? Please include the actual, raw output from ESLint.**

Adding an inline comment like that trips this rule, the array is actually consistently written as far as I'm concerned but the rule is kind of considering the inline comment as an item of the array.

**Are you willing to submit a pull request to fix this bug?**

I'm not too familiar with the AST, but with some pointers perhaps I can help.


Discussion:
This is related to the `consistent` option only.

[Online Demo Link](https://eslint.org/demo#eyJ0ZXh0IjoiLyplc2xpbnQgYXJyYXktYnJhY2tldC1uZXdsaW5lOiBbXCJlcnJvclwiLCBcImNvbnNpc3RlbnRcIl0qL1xuXG5jb25zdCBhc2QgPSBbIC8vIGNvbW1lbnRcbiAgMTIzLFxuICAxMjNcbl07Iiwib3B0aW9ucyI6eyJwYXJzZXJPcHRpb25zIjp7ImVjbWFWZXJzaW9uIjo2LCJzb3VyY2VUeXBlIjoic2NyaXB0IiwiZWNtYUZlYXR1cmVzIjp7fX0sInJ1bGVzIjp7fSwiZW52Ijp7fX19)

```js
/*eslint array-bracket-newline: ["error", "consistent"]*/

const asd = [ // comment
  123,
  123
];
```

```
3:13 - There should be no linebreak after '['. (array-bracket-newline)
6:1 - There should be no linebreak before ']'. (array-bracket-newline)
```

This looks like a bug to me. The above example is auto-fixed to:

```js
/*eslint array-bracket-newline: ["error", "consistent"]*/

const asd = [ // comment
  123,
  123];
```

where the rule still reports the first error. This could be manually fixed to not report the error like this:

```js
/*eslint array-bracket-newline: ["error", "consistent"]*/

const asd = [123, // comment
  123];
```

or like this:

```js
/*eslint array-bracket-newline: ["error", "consistent"]*/

const asd = [ 
  // comment
  123,
  123
];
```

I don't think that the rule intends to enforce neither of those fixes, given how the other options work. In particular, `always` doesn't report an error for the same example:

```js
/*eslint array-bracket-newline: ["error", "always"]*/

const asd = [ // comment
  123,
  123
];
```

It seems inconsistent that `always` sees the same example as two correct linebreaks after/before the brackets, while `consistent` doesn't.

The code for the `consistent` option checks if there is a linebreak between `[` and the first token inside (including comments). Based on the result, it requires/disallows linebreaks between brackets and other tokens (not including comments).

Couldn't find anything specific about this in #9136 and #9206 where the option is implemented and there are no test cases with the `consistent` option and some comments.

I think that this should be accepted as a bug.

Bug fix would be to check for a linebreak between the `[` and the first non-comment token. I'm not 100% sure but it seems that this fix even can't produce more errors in other cases.


> It seems inconsistent that always sees the same example as two correct linebreaks after/before the brackets, while consistent doesn't.

Yeah I didn't even know that. Btw this might be a good idea for discovering new bugs, if something that passes an "always" or "never" rule doesn't pass a "consistent" rule there's probably an issue.
The proposed fix is to change the logic that applies only when the option is `consistent`.

Instead of checking for a linebreak between `[` and the first following token (incl. comments), the fixed code would check for a linebreak between `[` and the first non-comment token.

I can't make an example where this change would produce new (potentially unwanted) warnings on an array that doesn't have any warnings at the moment. It seems impossible.

So, this looks like a bug and the fix looks safe. But, I'll leave this open for some time before accepting, maybe other team members have a different opinion.


Agreed that this seems like a bug.
I'm working on this.



Patch:
diff --git a/lib/rules/array-bracket-newline.js b/lib/rules/array-bracket-newline.js
index 21463177762d..b4b4dd430f65 100644
--- a/lib/rules/array-bracket-newline.js
+++ b/lib/rules/array-bracket-newline.js
@@ -216,7 +216,7 @@ module.exports = {
                 ) ||
                 (
                     options.consistent &&
-                    firstIncComment.loc.start.line !== openBracket.loc.end.line
+                    openBracket.loc.end.line !== first.loc.start.line
                 )
             );
 


Test patch:
diff --git a/tests/lib/rules/array-bracket-newline.js b/tests/lib/rules/array-bracket-newline.js
index b1603fcd5a81..d20c365dbc4e 100644
--- a/tests/lib/rules/array-bracket-newline.js
+++ b/tests/lib/rules/array-bracket-newline.js
@@ -65,6 +65,10 @@ ruleTester.run("array-bracket-newline", rule, {
         { code: "var a = [\n]", options: ["consistent"] },
         { code: "var a = [1]", options: ["consistent"] },
         { code: "var a = [\n1\n]", options: ["consistent"] },
+        { code: "var a = [//\n1\n]", options: ["consistent"] },
+        { code: "var a = [/**/\n1\n]", options: ["consistent"] },
+        { code: "var a = [/*\n*/1\n]", options: ["consistent"] },
+        { code: "var a = [//\n]", options: ["consistent"] },
 
         // { multiline: true }
         { code: "var foo = [];", options: [{ multiline: true }] },
@@ -156,6 +160,10 @@ ruleTester.run("array-bracket-newline", rule, {
         { code: "var [\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
         { code: "var [a] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
         { code: "var [\na\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var [//\na\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var [/**/\na\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var [/*\n*/a\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var [//\n] = foo", options: ["consistent"], parserOptions: { ecmaVersion: 6 } },
 
         // { multiline: true }
         { code: "var [] = foo;", options: [{ multiline: true }], parserOptions: { ecmaVersion: 6 } },
@@ -529,6 +537,21 @@ ruleTester.run("array-bracket-newline", rule, {
                 }
             ]
         },
+        {
+            code: "var foo = [//\n1]",
+            output: "var foo = [//\n1\n]",
+            options: ["consistent"],
+            errors: [
+                {
+                    messageId: "missingClosingLinebreak",
+                    type: "ArrayExpression",
+                    line: 2,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 3
+                }
+            ]
+        },
 
         // { multiline: true }
         {
@@ -1459,6 +1482,22 @@ ruleTester.run("array-bracket-newline", rule, {
                 }
             ]
         },
+        {
+            code: "var [//\na] = foo",
+            output: "var [//\na\n] = foo",
+            options: ["consistent"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    messageId: "missingClosingLinebreak",
+                    type: "ArrayPattern",
+                    line: 2,
+                    column: 2,
+                    endLine: 2,
+                    endColumn: 3
+                }
+            ]
+        },
 
         // { minItems: 2 }
         {