Repository: eslint/eslint (js)

Issue:
Docs: no-mixed-operators - allowSamePrecedence option docs improvement
**Tell us about your environment**
N/A (macOS Sierra 10.12.6)

* **ESLint Version:**
v4.17.0

* **Node Version:**
N/A (v8.9.1)

* **npm Version:**
N/A (v5.5.1)

**What parser (default, Babel-ESLint, etc.) are you using?**
N/A (default)

**Please show your full configuration:**
N/A

**What did you expect to happen?**
The `allowSamePrecedence` option of the `no-mixed-operators` rule should correctly document "Examples of incorrect code for this rule with `{"allowSamePrecedence": false}` option".

**What actually happened? Please include the actual, raw output from ESLint.**
The documentation is incorrect, as it is the same as "Examples of correct code for this rule with {"allowSamePrecedence": true} option":
```js
/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": true}]*/

// + and - have the same precedence.
var foo = a + b - c;
```
```js
/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/

// + and - have the same precedence.
var foo = a + b - c;
```

This should simply be changed to something like this:
```js
/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/

// + and * have different precedence.
var foo = a + b * c;
```


Pull request:
Docs: no-mixed-operators - fixes #9962
**What is the purpose of this pull request? (put an "X" next to item)**

[x ] Documentation update
[ ] Bug fix ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/bug-report.md))
[ ] New rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-proposal.md))
[ ] Changes an existing rule ([template](https://raw.githubusercontent.com/eslint/eslint/master/templates/rule-change-proposal.md))
[ ] Add autofixing to a rule
[ ] Add a CLI option
[ ] Add something to the core
[ ] Other, please explain:

**What changes did you make? (Give an overview)**
Improved documentation for `no-mixed-operators` rule - `allowSamePrecedence` option.

**Is there anything you'd like reviewers to focus on?**
N/A




Patch:
diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md
index c774666e0..4988f2696 100644
--- a/docs/developer-guide/nodejs-api.md
+++ b/docs/developer-guide/nodejs-api.md
@@ -496,7 +496,7 @@ If the operation ends with a parsing error, you will get a single message for th
             warningCount: 0,
             fixableErrorCount: 0,
             fixableWarningCount: 0,
-            source: "fucntion foo() {}"
+            source: "function foo() {}"
         }
     ],
     errorCount: 1,
diff --git a/docs/rules/key-spacing.md b/docs/rules/key-spacing.md
index 2c4afae8c..6e2b90541 100644
--- a/docs/rules/key-spacing.md
+++ b/docs/rules/key-spacing.md
@@ -10,14 +10,18 @@ This rule enforces consistent spacing between keys and values in object literal
 
 This rule has an object option:
 
-* `"beforeColon": false` (default) disallows spaces between the key and the colon in object literals.
-* `"beforeColon": true` requires at least one space between the key and the colon in object literals.
-* `"afterColon": true` (default) requires at least one space between the colon and the value in object literals.
-* `"afterColon": false` disallows spaces between the colon and the value in object literals.
-* `"mode": "strict"` (default) enforces exactly one space before or after colons in object literals.
-* `"mode": "minimum"` enforces one or more spaces before or after colons in object literals.
-* `"align": "value"` enforces horizontal alignment of values in object literals.
-* `"align": "colon"` enforces horizontal alignment of both colons and values in object literals.
+* `"beforeColon": false (default) | true`
+    * `false`: disallows spaces between the key and the colon in object literals.
+    * `true`: requires at least one space between the key and the colon in object literals.
+* `"afterColon": true (default) | false`
+    * `true`: requires at least one space between the colon and the value in object literals.
+    * `false`: disallows spaces between the colon and the value in object literals.
+* `"mode": "strict" (default) | "miniumum"`
+    * `"strict"`: enforces exactly one space before or after colons in object literals.
+    * `"minimum"`: enforces one or more spaces before or after colons in object literals.
+* `"align": "value" | "colon"`
+    * `"value"`: enforces horizontal alignment of values in object literals.
+    * `"colon"` enforces horizontal alignment of both colons and values in object literals.
 * `"align"` with an object value allows for fine-grained spacing when values are being aligned in object literals.
 * `"singleLine"` specifies a spacing style for single-line object literals.
 * `"multiLine"` specifies a spacing style for multi-line object literals.
diff --git a/docs/rules/no-mixed-operators.md b/docs/rules/no-mixed-operators.md
index 1746c5ed6..3c0bb2fab 100644
--- a/docs/rules/no-mixed-operators.md
+++ b/docs/rules/no-mixed-operators.md
@@ -138,10 +138,19 @@ Examples of **incorrect** code for this rule with `{"allowSamePrecedence": false
 var foo = a + b - c;
 ```
 
+Examples of **correct** code for this rule with `{"allowSamePrecedence": false}` option:
+
+```js
+/*eslint no-mixed-operators: ["error", {"allowSamePrecedence": false}]*/
+
+// + and - have the same precedence.
+var foo = (a + b) - c;
+```
+
 ## When Not To Use It
 
 If you don't want to be notified about mixed operators, then it's safe to disable this rule.
 
 ## Related Rules
 
-* [no-extra-parens](no-extra-parens.md)
\ No newline at end of file
+* [no-extra-parens](no-extra-parens.md)
diff --git a/docs/rules/valid-typeof.md b/docs/rules/valid-typeof.md
index 2ce02b490..60539eecb 100644
--- a/docs/rules/valid-typeof.md
+++ b/docs/rules/valid-typeof.md
@@ -20,7 +20,7 @@ Examples of **incorrect** code for this rule:
 typeof foo === "strnig"
 typeof foo == "undefimed"
 typeof bar != "nunber"
-typeof bar !== "fucntion"
+typeof bar !== "function"
 ```
 
 Examples of **correct** code for this rule:
diff --git a/docs/user-guide/configuring.md b/docs/user-guide/configuring.md
index 098fcdf43..5d4f93d55 100644
--- a/docs/user-guide/configuring.md
+++ b/docs/user-guide/configuring.md
@@ -394,13 +394,18 @@ You can also disable or enable specific rules for an entire file:
 alert('foo');
 ```
 
-To disable all rules on a specific line, use a line comment in one of the following formats:
+To disable all rules on a specific line, use a line or block comment in one of the following formats:
 
 ```js
 alert('foo'); // eslint-disable-line
 
 // eslint-disable-next-line
 alert('foo');
+
+/* eslint-disable-next-line */
+alert('foo');
+
+alert('foo'); /* eslint-disable-line */
 ```
 
 To disable a specific rule on a specific line:
@@ -410,6 +415,11 @@ alert('foo'); // eslint-disable-line no-alert
 
 // eslint-disable-next-line no-alert
 alert('foo');
+
+alert('foo'); /* eslint-disable-line no-alert */
+
+/* eslint-disable-next-line no-alert */
+alert('foo');
 ```
 
 To disable multiple rules on a specific line:
@@ -419,12 +429,18 @@ alert('foo'); // eslint-disable-line no-alert, quotes, semi
 
 // eslint-disable-next-line no-alert, quotes, semi
 alert('foo');
+
+alert('foo'); /* eslint-disable-line no-alert, quotes, semi */
+
+/* eslint-disable-next-line no-alert, quotes, semi */
+alert('foo');
 ```
 
 All of the above methods also work for plugin rules. For example, to disable `eslint-plugin-example`'s `rule-name` rule, combine the plugin's name (`example`) and the rule's name (`rule-name`) into `example/rule-name`:
 
 ```js
 foo(); // eslint-disable-line example/rule-name
+foo(); /* eslint-disable-line example/rule-name */
 ```
 
 **Note:** Comments that disable warnings for a portion of a file tell ESLint not to report rule violations for the disabled code. ESLint still parses the entire file, however, so disabled code still needs to be syntactically valid JavaScript.
diff --git a/lib/linter.js b/lib/linter.js
index d71a79a7c..8e95c3a71 100755
--- a/lib/linter.js
+++ b/lib/linter.js
@@ -307,7 +307,6 @@ function modifyConfigsFromComments(filename, ast, config, ruleMapper) {
 
         if (match) {
             value = value.slice(match.index + match[1].length);
-
             if (comment.type === "Block") {
                 switch (match[1]) {
                     case "exported":
@@ -323,6 +322,18 @@ function modifyConfigsFromComments(filename, ast, config, ruleMapper) {
                         [].push.apply(disableDirectives, createDisableDirectives("disable", comment.loc.start, value));
                         break;
 
+                    case "eslint-disable-line":
+                        if (comment.loc.start.line === comment.loc.end.line) {
+                            [].push.apply(disableDirectives, createDisableDirectives("disable-line", comment.loc.start, value));
+                        }
+                        break;
+
+                    case "eslint-disable-next-line":
+                        if (comment.loc.start.line === comment.loc.end.line) {
+                            [].push.apply(disableDirectives, createDisableDirectives("disable-next-line", comment.loc.start, value));
+                        }
+                        break;
+
                     case "eslint-enable":
                         [].push.apply(disableDirectives, createDisableDirectives("enable", comment.loc.start, value));
                         break;


Test patch:
diff --git a/tests/lib/linter.js b/tests/lib/linter.js
index fc4298d56..5f42ffd9c 100644
--- a/tests/lib/linter.js
+++ b/tests/lib/linter.js
@@ -1889,7 +1889,7 @@ describe("Linter", () => {
         });
     });
 
-    describe("when evaluating code with comments to ignore reporting on of specific rules on a specific line", () => {
+    describe("when evaluating code with comments to ignore reporting on specific rules on a specific line", () => {
 
         describe("eslint-disable-line", () => {
             it("should report a violation", () => {
@@ -1931,14 +1931,15 @@ describe("Linter", () => {
                 assert.strictEqual(messages[0].ruleId, "no-alert");
             });
 
-            it("should report a violation", () => {
+            it("should report a violation if eslint-disable-line in a block comment is not on a single line", () => {
                 const code = [
-                    "alert('test'); // eslint-disable-line no-alert",
-                    "alert('test'); /*eslint-disable-line no-alert*/" // here
+                    "/* eslint-disable-line",
+                    "*",
+                    "*/ console.log('test');" // here
                 ].join("\n");
                 const config = {
                     rules: {
-                        "no-alert": 1
+                        "no-console": 1
                     }
                 };
 
@@ -1946,7 +1947,44 @@ describe("Linter", () => {
 
                 assert.strictEqual(messages.length, 1);
 
+                assert.strictEqual(messages[0].ruleId, "no-console");
+            });
+
+            it("should report a violation if eslint-disable-line in a block comment is not on a single line", () => {
+                const code = [
+                    "alert('test'); /* eslint-disable-line ",
+                    "no-alert */"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1,
+                        quotes: [1, "double"],
+                        semi: [1, "always"]
+                    }
+                };
+
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 2);
+
                 assert.strictEqual(messages[0].ruleId, "no-alert");
+                assert.strictEqual(messages[1].ruleId, "quotes");
+            });
+
+            it("should not report a violation for eslint-disable-line in block comment", () => {
+                const code = [
+                    "alert('test'); // eslint-disable-line no-alert",
+                    "alert('test'); /*eslint-disable-line no-alert*/"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1
+                    }
+                };
+
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 0);
             });
 
             it("should not report a violation", () => {
@@ -1984,6 +2022,40 @@ describe("Linter", () => {
 
                 assert.strictEqual(messages.length, 0);
             });
+
+            it("should not report a violation", () => {
+                const code = [
+                    "alert('test') /* eslint-disable-line no-alert, quotes, semi */",
+                    "console.log('test'); /* eslint-disable-line */"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1,
+                        quotes: [1, "double"],
+                        semi: [1, "always"],
+                        "no-console": 1
+                    }
+                };
+
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 0);
+            });
+
+            it("should ignore violations of multiple rules when specified in mixed comments", () => {
+                const code = [
+                    " alert(\"test\"); /* eslint-disable-line no-alert */ // eslint-disable-line quotes"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1,
+                        quotes: [1, "single"]
+                    }
+                };
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 0);
+            });
         });
 
         describe("eslint-disable-next-line", () => {
@@ -2005,6 +2077,54 @@ describe("Linter", () => {
                 assert.strictEqual(messages[0].ruleId, "no-console");
             });
 
+            it("should ignore violation of specified rule if eslint-disable-next-line is a block comment", () => {
+                const code = [
+                    "/* eslint-disable-next-line no-alert */",
+                    "alert('test');",
+                    "console.log('test');"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1,
+                        "no-console": 1
+                    }
+                };
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 1);
+                assert.strictEqual(messages[0].ruleId, "no-console");
+            });
+            it("should ignore violation of specified rule if eslint-disable-next-line is a block comment", () => {
+                const code = [
+                    "/* eslint-disable-next-line no-alert */",
+                    "alert('test');"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1
+                    }
+                };
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 0);
+            });
+
+            it("should not ignore violation if block comment is not on a single line", () => {
+                const code = [
+                    "/* eslint-disable-next-line",
+                    "no-alert */alert('test');"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1
+                    }
+                };
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 1);
+                assert.strictEqual(messages[0].ruleId, "no-alert");
+            });
+
             it("should ignore violations only of specified rule", () => {
                 const code = [
                     "// eslint-disable-next-line no-console",
@@ -2043,6 +2163,22 @@ describe("Linter", () => {
                 assert.strictEqual(messages[0].ruleId, "no-console");
             });
 
+            it("should ignore violations of multiple rules when specified in mixed comments", () => {
+                const code = [
+                    "/* eslint-disable-next-line no-alert */ // eslint-disable-next-line quotes",
+                    "alert(\"test\");"
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1,
+                        quotes: [1, "single"]
+                    }
+                };
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 0);
+            });
+
             it("should ignore violations of only the specified rule on next line", () => {
                 const code = [
                     "// eslint-disable-next-line quotes",
@@ -2103,7 +2239,7 @@ describe("Linter", () => {
                 assert.strictEqual(messages[0].ruleId, "no-console");
             });
 
-            it("should not ignore violations if comment is in block quotes", () => {
+            it("should ignore violations if eslint-disable-next-line is a block comment", () => {
                 const code = [
                     "alert('test');",
                     "/* eslint-disable-next-line no-alert */",
@@ -2118,10 +2254,30 @@ describe("Linter", () => {
                 };
                 const messages = linter.verify(code, config, filename);
 
-                assert.strictEqual(messages.length, 3);
+                assert.strictEqual(messages.length, 2);
                 assert.strictEqual(messages[0].ruleId, "no-alert");
-                assert.strictEqual(messages[1].ruleId, "no-alert");
-                assert.strictEqual(messages[2].ruleId, "no-console");
+                assert.strictEqual(messages[1].ruleId, "no-console");
+            });
+
+            it("should report a violation", () => {
+                const code = [
+                    "/* eslint-disable-next-line",
+                    "*",
+                    "*/",
+                    "console.log('test');" // here
+                ].join("\n");
+                const config = {
+                    rules: {
+                        "no-alert": 1,
+                        "no-console": 1
+                    }
+                };
+
+                const messages = linter.verify(code, config, filename);
+
+                assert.strictEqual(messages.length, 1);
+
+                assert.strictEqual(messages[0].ruleId, "no-console");
             });
 
             it("should not ignore violations if comment is of the type Shebang", () => {