Repository: eslint/eslint (js)

Issue:
object-curly-spacing warns on trailing comments, fixer deletes
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).

    This template is for bug reports. If you are here for another reason, please see below:

    1. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
    2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
    3. To request a change that is not a bug fix, rule change, or new rule: https://eslint.org/docs/developer-guide/contributing/changes
    4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint

    Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**Tell us about your environment**

* **ESLint Version:** v5.15.1
* **Node Version:** v10.15.3
* **npm Version:** v6.4.1

**What parser (default, Babel-ESLint, etc.) are you using?**
default

**Please show your full configuration:**


<details>
<summary>Configuration</summary>

<!-- Paste your configuration below: -->
```js
{
	"root": true,
	"parserOptions": {
		"ecmaVersion": 9,
		"sourceType": "script",
		"ecmaFeatures": {
			"globalReturn": true
		}
	},
	"env": {
		"es6": true,
		"node": true
	},
	"rules": {
		"object-curly-spacing": ["error", "never"]
	}
}

```

</details>

**What did you do? Please include the actual source code causing the issue, as well as the command that you used to run ESLint.**

<!-- Paste the source code below: -->
```js
"use strict";

function foo(data) {
	const {bar /* number */} = data;
}

```

<!-- Paste the command you used to run ESLint: -->
```bash
eslint eslint-testcase.js
```

**What did you expect to happen?**
Lint passes.

**What actually happened? Please include the actual, raw output from ESLint.**
Rule ``object-curly-spacing`` detected a false positive.

C:\Users\W7\Desktop\osu-accuracy\eslint-testcase.js
  4:25  error  There should be no space before '}'  object-curly-spacing

✖ 1 problem (1 error, 0 warnings)
  1 error and 0 warnings potentially fixable with the `--fix` option.

Note that running with ``--fix`` deletes the comment ``/* number */``:

```diff
4c4
< 	const {bar /* number */} = data;
---
> 	const {bar} = data;
```

**Are you willing to submit a pull request to fix this bug?**
No

Pull request description:
Fix: consider comments in object-curly-spacing (fixes #11656)
<!--
    ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[x] Bug fix

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
    - Include tests for this change
    - Update documentation for this change (if appropriate)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**
Fixes #11656 

**Is there anything you'd like reviewers to focus on?**
No.



Patch:
diff --git a/lib/rules/no-cond-assign.js b/lib/rules/no-cond-assign.js
index aed3e4a7a..62a73a6b1 100644
--- a/lib/rules/no-cond-assign.js
+++ b/lib/rules/no-cond-assign.js
@@ -86,7 +86,7 @@ module.exports = {
                 nextToken = sourceCode.getTokenAfter(node, 1);
 
             return astUtils.isParenthesised(sourceCode, node) &&
-                astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] &&
+                previousToken && astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] &&
                 astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1];
         }
 
diff --git a/lib/rules/object-curly-spacing.js b/lib/rules/object-curly-spacing.js
index bde4f1425..c4f2077f6 100644
--- a/lib/rules/object-curly-spacing.js
+++ b/lib/rules/object-curly-spacing.js
@@ -82,7 +82,7 @@ module.exports = {
                     token: token.value
                 },
                 fix(fixer) {
-                    const nextToken = context.getSourceCode().getTokenAfter(token);
+                    const nextToken = context.getSourceCode().getTokenAfter(token, { includeComments: true });
 
                     return fixer.removeRange([token.range[1], nextToken.range[0]]);
                 }
@@ -104,7 +104,7 @@ module.exports = {
                     token: token.value
                 },
                 fix(fixer) {
-                    const previousToken = context.getSourceCode().getTokenBefore(token);
+                    const previousToken = context.getSourceCode().getTokenBefore(token, { includeComments: true });
 
                     return fixer.removeRange([previousToken.range[1], token.range[0]]);
                 }
@@ -225,8 +225,8 @@ module.exports = {
 
             const first = sourceCode.getFirstToken(node),
                 last = getClosingBraceOfObject(node),
-                second = sourceCode.getTokenAfter(first),
-                penultimate = sourceCode.getTokenBefore(last);
+                second = sourceCode.getTokenAfter(first, { includeComments: true }),
+                penultimate = sourceCode.getTokenBefore(last, { includeComments: true });
 
             validateBraceSpacing(node, first, second, penultimate, last);
         }
@@ -253,8 +253,8 @@ module.exports = {
 
             const first = sourceCode.getTokenBefore(firstSpecifier),
                 last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken),
-                second = sourceCode.getTokenAfter(first),
-                penultimate = sourceCode.getTokenBefore(last);
+                second = sourceCode.getTokenAfter(first, { includeComments: true }),
+                penultimate = sourceCode.getTokenBefore(last, { includeComments: true });
 
             validateBraceSpacing(node, first, second, penultimate, last);
         }
@@ -273,8 +273,8 @@ module.exports = {
                 lastSpecifier = node.specifiers[node.specifiers.length - 1],
                 first = sourceCode.getTokenBefore(firstSpecifier),
                 last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken),
-                second = sourceCode.getTokenAfter(first),
-                penultimate = sourceCode.getTokenBefore(last);
+                second = sourceCode.getTokenAfter(first, { includeComments: true }),
+                penultimate = sourceCode.getTokenBefore(last, { includeComments: true });
 
             validateBraceSpacing(node, first, second, penultimate, last);
         }
diff --git a/package.json b/package.json
index e795d2515..9f514558a 100644
--- a/package.json
+++ b/package.json
@@ -28,7 +28,7 @@
   },
   "lint-staged": {
     "*.js": [
-      "node ./bin/eslint.js --fix",
+      "eslint --fix",
       "git add"
     ],
     "*.md": "markdownlint"
@@ -95,6 +95,7 @@
     "coveralls": "^3.0.3",
     "dateformat": "^3.0.3",
     "ejs": "^2.6.1",
+    "eslint": "file:.",
     "eslint-config-eslint": "file:packages/eslint-config-eslint",
     "eslint-plugin-eslint-plugin": "^2.0.1",
     "eslint-plugin-internal-rules": "file:tools/internal-rules",


Test patch:
diff --git a/tests/lib/rules/no-cond-assign.js b/tests/lib/rules/no-cond-assign.js
index 8b8e1ae56..f6fb77b32 100644
--- a/tests/lib/rules/no-cond-assign.js
+++ b/tests/lib/rules/no-cond-assign.js
@@ -61,6 +61,7 @@ ruleTester.run("no-cond-assign", rule, {
         { code: "while ((x = 0)) { }", options: ["always"], errors: [{ messageId: "unexpected", data: { type: "a 'while' statement" }, type: "WhileStatement" }] },
         { code: "do { } while ((x = x + 1));", options: ["always"], errors: [{ messageId: "unexpected", data: { type: "a 'do...while' statement" }, type: "DoWhileStatement" }] },
         { code: "for(; (x = y); ) { }", options: ["always"], errors: [{ messageId: "unexpected", data: { type: "a 'for' statement" }, type: "ForStatement" }] },
-        { code: "var x; var b = (x = 0) ? 1 : 0;", errors: [{ messageId: "missing", type: "ConditionalExpression" }] }
+        { code: "var x; var b = (x = 0) ? 1 : 0;", errors: [{ messageId: "missing", type: "ConditionalExpression" }] },
+        { code: "(((3496.29)).bkufyydt = 2e308) ? foo : bar;", errors: [{ messageId: "missing", type: "ConditionalExpression" }] }
     ]
 });
diff --git a/tests/lib/rules/object-curly-spacing.js b/tests/lib/rules/object-curly-spacing.js
index 3595ff6b5..d7e7d061b 100644
--- a/tests/lib/rules/object-curly-spacing.js
+++ b/tests/lib/rules/object-curly-spacing.js
@@ -84,6 +84,8 @@ ruleTester.run("object-curly-spacing", rule, {
         { code: "var obj = {foo: {\nbar: quxx}, baz: qux\n};", options: ["never"] },
         { code: "var obj = {foo: {\nbar: quxx\n}, baz: qux};", options: ["never"] },
         { code: "var obj = {\nfoo: bar,\nbaz: qux\n};", options: ["never"] },
+        { code: "var obj = {foo: bar, baz: qux /* */};", options: ["never"] },
+        { code: "var obj = {/* */ foo: bar, baz: qux};", options: ["never"] },
 
         // never - destructuring
         { code: "var {x} = y", options: ["never"], parserOptions: { ecmaVersion: 6 } },
@@ -97,12 +99,18 @@ ruleTester.run("object-curly-spacing", rule, {
         { code: "var {\ny,\n} = x", options: ["never"], parserOptions: { ecmaVersion: 6 } },
         { code: "var {y,} = x", options: ["never"], parserOptions: { ecmaVersion: 6 } },
         { code: "var {y:x} = x", options: ["never"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var {/* */ y} = x", options: ["never"], parserOptions: { ecmaVersion: 6 } },
+        { code: "var {y /* */} = x", options: ["never"], parserOptions: { ecmaVersion: 6 } },
 
         // never - import / export
         { code: "import door from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
         { code: "import * as door from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
         { code: "import {door} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
         { code: "export {door} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
+        { code: "import {/* */ door} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
+        { code: "export {/* */ door} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
+        { code: "import {door /* */} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
+        { code: "export {door /* */} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
         { code: "import {\ndoor} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
         { code: "export {\ndoor\n} from 'room'", options: ["never"], parserOptions: { sourceType: "module" } },
         { code: "import {house,mouse} from 'caravan'", options: ["never"], parserOptions: { sourceType: "module" } },
@@ -235,6 +243,34 @@ ruleTester.run("object-curly-spacing", rule, {
 
             ]
         },
+        {
+            code: "import x, { bar/* */} from 'foo';",
+            output: "import x, { bar/* */ } from 'foo';",
+            options: ["always"],
+            parserOptions: { sourceType: "module" },
+            errors: [
+                {
+                    message: "A space is required before '}'.",
+                    type: "ImportDeclaration",
+                    line: 1,
+                    column: 21
+                }
+            ]
+        },
+        {
+            code: "import x, {/* */bar } from 'foo';",
+            output: "import x, { /* */bar } from 'foo';",
+            options: ["always"],
+            parserOptions: { sourceType: "module" },
+            errors: [
+                {
+                    message: "A space is required after '{'.",
+                    type: "ImportDeclaration",
+                    line: 1,
+                    column: 11
+                }
+            ]
+        },
         {
             code: "import x, { bar, baz} from 'foo';",
             output: "import x, { bar, baz } from 'foo';",
@@ -332,6 +368,26 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "import { /* */ bar, /* */ } from 'foo';",
+            output: "import {/* */ bar, /* */} from 'foo';",
+            options: ["never"],
+            parserOptions: { sourceType: "module" },
+            errors: [
+                {
+                    message: "There should be no space after '{'.",
+                    type: "ImportDeclaration",
+                    line: 1,
+                    column: 8
+                },
+                {
+                    message: "There should be no space before '}'.",
+                    type: "ImportDeclaration",
+                    line: 1,
+                    column: 27
+                }
+            ]
+        },
         {
             code: "var bar = 0;\nexport {bar};",
             output: "var bar = 0;\nexport { bar };",
@@ -352,6 +408,26 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "var bar = 0;\nexport { /* */ bar /* */ };",
+            output: "var bar = 0;\nexport {/* */ bar /* */};",
+            options: ["never"],
+            parserOptions: { sourceType: "module" },
+            errors: [
+                {
+                    message: "There should be no space after '{'.",
+                    type: "ExportNamedDeclaration",
+                    line: 2,
+                    column: 8
+                },
+                {
+                    message: "There should be no space before '}'.",
+                    type: "ExportNamedDeclaration",
+                    line: 2,
+                    column: 26
+                }
+            ]
+        },
 
         // always - arraysInObjects
         {
@@ -530,6 +606,19 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "var obj = {/* */foo: bar, baz: qux };",
+            output: "var obj = { /* */foo: bar, baz: qux };",
+            options: ["always"],
+            errors: [
+                {
+                    message: "A space is required after '{'.",
+                    type: "ObjectExpression",
+                    line: 1,
+                    column: 11
+                }
+            ]
+        },
         {
             code: "var obj = { foo: bar, baz: qux};",
             output: "var obj = { foo: bar, baz: qux };",
@@ -543,6 +632,19 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "var obj = { foo: bar, baz: qux/* */};",
+            output: "var obj = { foo: bar, baz: qux/* */ };",
+            options: ["always"],
+            errors: [
+                {
+                    message: "A space is required before '}'.",
+                    type: "ObjectExpression",
+                    line: 1,
+                    column: 36
+                }
+            ]
+        },
         {
             code: "var obj = { foo: bar, baz: qux };",
             output: "var obj = {foo: bar, baz: qux};",
@@ -575,6 +677,19 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "var obj = {foo: bar, baz: qux /* */ };",
+            output: "var obj = {foo: bar, baz: qux /* */};",
+            options: ["never"],
+            errors: [
+                {
+                    message: "There should be no space before '}'.",
+                    type: "ObjectExpression",
+                    line: 1,
+                    column: 37
+                }
+            ]
+        },
         {
             code: "var obj = { foo: bar, baz: qux};",
             output: "var obj = {foo: bar, baz: qux};",
@@ -588,6 +703,19 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "var obj = { /* */ foo: bar, baz: qux};",
+            output: "var obj = {/* */ foo: bar, baz: qux};",
+            options: ["never"],
+            errors: [
+                {
+                    message: "There should be no space after '{'.",
+                    type: "ObjectExpression",
+                    line: 1,
+                    column: 11
+                }
+            ]
+        },
         {
             code: "var obj = { foo: { bar: quxx}, baz: qux};",
             output: "var obj = {foo: {bar: quxx}, baz: qux};",
@@ -676,6 +804,34 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "var { x, y/* */} = y",
+            output: "var { x, y/* */ } = y",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    message: "A space is required before '}'.",
+                    type: "ObjectPattern",
+                    line: 1,
+                    column: 16
+                }
+            ]
+        },
+        {
+            code: "var {/* */x, y } = y",
+            output: "var { /* */x, y } = y",
+            options: ["always"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    message: "A space is required after '{'.",
+                    type: "ObjectPattern",
+                    line: 1,
+                    column: 5
+                }
+            ]
+        },
         {
             code: "var { x, y } = y",
             output: "var {x, y} = y",
@@ -710,6 +866,34 @@ ruleTester.run("object-curly-spacing", rule, {
                 }
             ]
         },
+        {
+            code: "var {x, y/* */ } = y",
+            output: "var {x, y/* */} = y",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    message: "There should be no space before '}'.",
+                    type: "ObjectPattern",
+                    line: 1,
+                    column: 16
+                }
+            ]
+        },
+        {
+            code: "var { /* */x, y} = y",
+            output: "var {/* */x, y} = y",
+            options: ["never"],
+            parserOptions: { ecmaVersion: 6 },
+            errors: [
+                {
+                    message: "There should be no space after '{'.",
+                    type: "ObjectPattern",
+                    line: 1,
+                    column: 5
+                }
+            ]
+        },
         {
             code: "var { x=10} = y",
             output: "var { x=10 } = y",