Repository: eslint/eslint
Pull request #15775 (2022-04-11 13:36:56)

fix: update `astUtils.isDirectiveComment` with `globals` and `exported`
<!--
    Thank you for contributing!

    ESLint adheres to the [JS Foundation Code of Conduct](https://eslint.org/conduct).
-->

#### Prerequisites checklist

- [x] I have read the [contributing guidelines](https://github.com/eslint/eslint/blob/HEAD/CONTRIBUTING.md).

#### What is the purpose of this pull request? (put an "X" next to an item)

<!--
    The following template is intentionally not a markdown checkbox list for the reasons
    explained in https://github.com/eslint/eslint/pull/12848#issuecomment-580302888
-->

[ ] Documentation update
[x] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/HEAD/templates/rule-change-proposal.md))
[ ] Add autofix to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

**Tell us about your environment:**

* **ESLint Version:** v8.13.0
* **Node Version:** 16.14.0
* **npm Version:** 8.3.1

**What parser (default, `@babel/eslint-parser`, `@typescript-eslint/parser`, etc.) are you using?**

default

**Please show your full configuration:**

<details>
<summary>Configuration</summary>

<!-- Paste your configuration below: -->
```js
module.exports = {
    parserOptions: {
        ecmaVersion: 2015
    }
};

```

</details>

**What did you do? Please include the actual source code causing the issue.**

[Online Demo](https://eslint.org/demo#eyJ0ZXh0IjoiLyplc2xpbnQgbm8taW5saW5lLWNvbW1lbnRzOiBcImVycm9yXCIgKi9cblxuZm9vKCk7IC8qIGdsb2JhbCBmb28gKi9cbiAgXG5iYXIoKTsgLyogZ2xvYmFscyBiYXIgKi9cblxudmFyIGJhejsgLyogZXhwb3J0ZWQgYmF6ICovIiwib3B0aW9ucyI6eyJwYXJzZXJPcHRpb25zIjp7ImVjbWFWZXJzaW9uIjo2LCJzb3VyY2VUeXBlIjoic2NyaXB0IiwiZWNtYUZlYXR1cmVzIjp7fX0sInJ1bGVzIjp7fSwiZW52Ijp7fX19)

```js
/*eslint no-inline-comments: "error" */

foo(); /* global foo */
  
bar(); /* globals bar */

var baz; /* exported baz */
```

**What did you expect to happen?**

No errors because this rule ignores eslint directives.

**What actually happened? Please include the actual, raw output from ESLint.**

`/* global */` comment is allowed as expected, but `/* globals */` and `/* exported */` are disallowed.

```
  5:8   error  Unexpected comment inline with code  no-inline-comments
  7:10  error  Unexpected comment inline with code  no-inline-comments

✖ 2 problems (2 errors, 0 warnings)
```

<!--
    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)

Fixed `astUtils.isDirectiveComment` to treat `/* globals ... */` and `/* exported ... */` as directives.

#### Is there anything you'd like reviewers to focus on?

* We noticed and fixed this bug in https://github.com/eslint/eslint/pull/14656, but that change was reverted in https://github.com/eslint/eslint/pull/14973.
*  `astUtils.isDirectiveComment` is used only in `no-inline-comments` and `no-warning-comments`. In both rules this change can produce only fewer warnings.

<!-- markdownlint-disable-file MD004 -->


nzakas: @mdjermanovic you’re not using a different email on this commit are you? EasyCLA looks unhappy. 

Patch:
diff --git a/lib/rules/utils/ast-utils.js b/lib/rules/utils/ast-utils.js
index ecde099fa..21742366c 100644
--- a/lib/rules/utils/ast-utils.js
+++ b/lib/rules/utils/ast-utils.js
@@ -32,6 +32,7 @@ const thisTagPattern = /^[\s*]*@this/mu;
 
 
 const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/u;
+const ESLINT_DIRECTIVE_PATTERN = /^(?:eslint[- ]|(?:globals?|exported) )/u;
 const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]);
 
 // A set of node types that can contain a list of statements
@@ -908,12 +909,8 @@ module.exports = {
         const comment = node.value.trim();
 
         return (
-            node.type === "Line" && comment.indexOf("eslint-") === 0 ||
-            node.type === "Block" && (
-                comment.indexOf("global ") === 0 ||
-                comment.indexOf("eslint ") === 0 ||
-                comment.indexOf("eslint-") === 0
-            )
+            node.type === "Line" && comment.startsWith("eslint-") ||
+            node.type === "Block" && ESLINT_DIRECTIVE_PATTERN.test(comment)
         );
     },
 
diff --git a/package.json b/package.json
index eea1405b9..395dd3927 100644
--- a/package.json
+++ b/package.json
@@ -32,7 +32,7 @@
   },
   "lint-staged": {
     "*.js": "eslint --fix",
-    "*.md": "markdownlint"
+    "*.md": "markdownlint --fix"
   },
   "files": [
     "LICENSE",


Test patch:
diff --git a/tests/lib/rules/no-inline-comments.js b/tests/lib/rules/no-inline-comments.js
index 463c86eea..7eb0cac73 100644
--- a/tests/lib/rules/no-inline-comments.js
+++ b/tests/lib/rules/no-inline-comments.js
@@ -39,6 +39,9 @@ ruleTester.run("no-inline-comments", rule, {
         "// A solitary comment",
         "var a = 1; // eslint-disable-line no-debugger",
         "var a = 1; /* eslint-disable-line no-debugger */",
+        "foo(); /* global foo */",
+        "foo(); /* globals foo */",
+        "var foo; /* exported foo */",
 
         // JSX exception
         `var a = (
diff --git a/tests/lib/rules/utils/ast-utils.js b/tests/lib/rules/utils/ast-utils.js
index 7789de774..1cd8727b4 100644
--- a/tests/lib/rules/utils/ast-utils.js
+++ b/tests/lib/rules/utils/ast-utils.js
@@ -204,7 +204,10 @@ describe("ast-utils", () => {
                 "// lalala I'm a normal comment",
                 "// trying to confuse eslint ",
                 "//trying to confuse eslint-directive-detection",
-                "//eslint is awesome"
+                "//eslint is awesome",
+                "//global line comment is not a directive",
+                "//globals line comment is not a directive",
+                "//exported line comment is not a directive"
             ].join("\n");
             const ast = espree.parse(code, ESPREE_CONFIG);
             const sourceCode = new SourceCode(code, ast);
@@ -247,7 +250,10 @@ describe("ast-utils", () => {
                 "/*eslint-enable no-undef*/",
                 "/* eslint-env {\"es6\": true} */",
                 "/* eslint foo */",
-                "/*eslint bar*/"
+                "/*eslint bar*/",
+                "/*global foo*/",
+                "/*globals foo*/",
+                "/*exported foo*/"
             ].join("\n");
             const ast = espree.parse(code, ESPREE_CONFIG);
             const sourceCode = new SourceCode(code, ast);