Skip to content

Commit 7c291b3

Browse files
committed
New: no-use rule.
1 parent f8c3a30 commit 7c291b3

File tree

5 files changed

+277
-2
lines changed

5 files changed

+277
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
[![codecov](https://codecov.io/gh/mysticatea/eslint-plugin-eslint-comments/branch/master/graph/badge.svg)](https://codecov.io/gh/mysticatea/eslint-plugin-eslint-comments)
77
[![Dependency Status](https://david-dm.org/mysticatea/eslint-plugin-eslint-comments.svg)](https://david-dm.org/mysticatea/eslint-plugin-eslint-comments)
88

9-
Additional ESLint rules for ESLint's directive comments (e.g. `//eslint-disable-line`).
9+
Additional ESLint rules for ESLint's directive-comments (e.g. `//eslint-disable-line`).
1010

1111
## :cd: Installation
1212

@@ -49,7 +49,7 @@ Write in your ESLint configurations: http://eslint.org/docs/user-guide/configuri
4949
- [eslint-comments/no-duplicate-disable](docs/rules/no-duplicate-disable.md) disallows duplicate `eslint-disable` comments.
5050
- [eslint-comments/no-unlimited-disable](docs/rules/no-unlimited-disable.md) disallows `eslint-disable` comments without rule names.
5151
- [eslint-comments/no-unused-disable](docs/rules/no-unused-disable.md) disallows unused `eslint-disable` comments.
52-
- [eslint-comments/no-use](docs/rules/no-use.md) disallows ESLint directive comments.
52+
- [eslint-comments/no-use](docs/rules/no-use.md) disallows ESLint directive-comments.
5353
- [eslint-comments/no-useless-enable](docs/rules/no-useless-enable.md) disallows useless `eslint-enable` comments.
5454

5555
## :anchor: Semantic Versioning Policy

docs/rules/no-use.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# disallows ESLint directive-comments (eslint-comments/no-use)
2+
3+
Abuse of directive-comments may cause to overlook bugs or upset of coding style.
4+
This rule disallows a use of directive-comments.
5+
6+
## Rule Details
7+
8+
Examples of :thumbsdown: **incorrect** code for this rule:
9+
10+
```js
11+
/*eslint eslint-comments/no-use: error */
12+
13+
/* eslint no-undef: off */
14+
/* eslint-env browser */
15+
/* eslint-enable */
16+
/* eslint-disable */
17+
// eslint-disable-line
18+
// eslint-disable-next-line
19+
/* exported foo */
20+
/* global $ */
21+
/* globals a, b, c */
22+
```
23+
24+
## Options
25+
26+
You can specify allowed directive-comments.
27+
28+
```json
29+
{
30+
"eslint-comments/no-use": ["error", {"allow": []}]
31+
}
32+
```
33+
34+
- `allow` option is an array to allow specified directive-comments. The value of the array is some of the following strings:
35+
- `"eslint"`
36+
- `"eslint-disable"`
37+
- `"eslint-disable-line"`
38+
- `"eslint-disable-next-line"`
39+
- `"eslint-enable"`
40+
- `"eslint-env"`
41+
- `"exported"`
42+
- `"global"`
43+
- `"globals"`
44+
45+
## Known Limitations
46+
47+
This rule cannot prevent the following case:
48+
49+
```js
50+
/* eslint eslint-comments/no-use: off */
51+
```
52+
53+
Because ESLint addresses the directive-comment before parsing.

lib/rules/no-use.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* @author Toru Nagashima
3+
* @copyright 2016 Toru Nagashima. All rights reserved.
4+
* See LICENSE file in root directory for full license.
5+
*/
6+
"use strict"
7+
8+
//------------------------------------------------------------------------------
9+
// Requirements
10+
//------------------------------------------------------------------------------
11+
12+
const utils = require("../utils")
13+
14+
//------------------------------------------------------------------------------
15+
// Helpers
16+
//------------------------------------------------------------------------------
17+
18+
const BLOCK_COMMENT_DIRECTIVE = /^\s*(eslint(?:-disable|-enable|-env)?|exported|globals?)(?:\s|$)/
19+
const LINE_COMMENT_DIRECTIVE = /^\s*(eslint-disable(?:-next)?-line)(?:\s|$)/
20+
const MESSAGE = "Unexpected ESLint directive comment."
21+
const NOT_FOUND = -1
22+
23+
//------------------------------------------------------------------------------
24+
// Rule Definition
25+
//------------------------------------------------------------------------------
26+
27+
module.exports = {
28+
meta: {
29+
docs: {
30+
description: "disallows ESLint directive-comments",
31+
category: "Best Practices",
32+
recommended: false,
33+
},
34+
fixable: false,
35+
schema: [{
36+
type: "object",
37+
properties: {
38+
allow: {
39+
type: "array",
40+
items: {
41+
enum: [
42+
"eslint",
43+
"eslint-disable",
44+
"eslint-disable-line",
45+
"eslint-disable-next-line",
46+
"eslint-enable",
47+
"eslint-env",
48+
"exported",
49+
"global",
50+
"globals",
51+
],
52+
},
53+
additionalItems: false,
54+
uniqueItems: true,
55+
},
56+
},
57+
additionalProperties: false,
58+
}],
59+
},
60+
61+
create(context) {
62+
const allowed = (context.options[0] && context.options[0].allow) || []
63+
64+
return {
65+
BlockComment(token) {
66+
const m = BLOCK_COMMENT_DIRECTIVE.exec(token.value)
67+
if (m != null && allowed.indexOf(m[1]) === NOT_FOUND) {
68+
context.report({
69+
loc: utils.toForceLocation(token.loc),
70+
message: MESSAGE,
71+
})
72+
}
73+
},
74+
75+
LineComment(token) {
76+
const m = LINE_COMMENT_DIRECTIVE.exec(token.value)
77+
if (m != null && allowed.indexOf(m[1]) === NOT_FOUND) {
78+
context.report({
79+
loc: utils.toForceLocation(token.loc),
80+
message: MESSAGE,
81+
})
82+
}
83+
},
84+
}
85+
},
86+
}

lib/utils.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* @author Toru Nagashima
3+
* @copyright 2016 Toru Nagashima. All rights reserved.
4+
* See LICENSE file in root directory for full license.
5+
*/
6+
"use strict"
7+
8+
//------------------------------------------------------------------------------
9+
// Exports
10+
//------------------------------------------------------------------------------
11+
12+
module.exports = {
13+
/**
14+
* Make the location ignoring `eslint-disable` comments.
15+
*
16+
* @param {object} location - The location to convert.
17+
* @returns {object} Converted location.
18+
*/
19+
toForceLocation(location) {
20+
return {
21+
start: {
22+
line: location.start.line,
23+
column: -1,
24+
},
25+
end: location.end,
26+
}
27+
},
28+
}

tests/lib/rules/no-use.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**
2+
* @author Toru Nagashima
3+
* @copyright 2016 Toru Nagashima. All rights reserved.
4+
* See LICENSE file in root directory for full license.
5+
*/
6+
"use strict"
7+
8+
//------------------------------------------------------------------------------
9+
// Requirements
10+
//------------------------------------------------------------------------------
11+
12+
const RuleTester = require("eslint").RuleTester
13+
const rule = require("../../../lib/rules/no-use")
14+
15+
//------------------------------------------------------------------------------
16+
// Tests
17+
//------------------------------------------------------------------------------
18+
19+
const tester = new RuleTester()
20+
21+
tester.run("no-use", rule, {
22+
valid: [
23+
"// eslint foo",
24+
"// eslint-disable",
25+
"// eslint-enable",
26+
"// exported",
27+
"// global",
28+
"// globals",
29+
"// eslint-env",
30+
"/* eslint-disable-line */",
31+
"/* eslint-disable-next-line */",
32+
"/* just eslint in a normal comment */",
33+
{
34+
code: "/* eslint */",
35+
options: [{allow: ["eslint"]}],
36+
},
37+
{
38+
code: "/* eslint-env */",
39+
options: [{allow: ["eslint-env"]}],
40+
},
41+
{
42+
code: "/* eslint-enable */",
43+
options: [{allow: ["eslint-enable"]}],
44+
},
45+
{
46+
code: "/* eslint-disable */",
47+
options: [{allow: ["eslint-disable"]}],
48+
},
49+
{
50+
code: "// eslint-disable-line",
51+
options: [{allow: ["eslint-disable-line"]}],
52+
},
53+
{
54+
code: "// eslint-disable-next-line",
55+
options: [{allow: ["eslint-disable-next-line"]}],
56+
},
57+
{
58+
code: "/* exported */",
59+
options: [{allow: ["exported"]}],
60+
},
61+
{
62+
code: "/* global */",
63+
options: [{allow: ["global"]}],
64+
},
65+
{
66+
code: "/* globals */",
67+
options: [{allow: ["globals"]}],
68+
},
69+
],
70+
invalid: [
71+
{
72+
code: "/* eslint */",
73+
errors: ["Unexpected ESLint directive comment."],
74+
},
75+
{
76+
code: "/* eslint-env */",
77+
errors: ["Unexpected ESLint directive comment."],
78+
},
79+
{
80+
code: "/* eslint-enable */",
81+
errors: ["Unexpected ESLint directive comment."],
82+
},
83+
{
84+
code: "/* eslint-disable */",
85+
errors: ["Unexpected ESLint directive comment."],
86+
},
87+
{
88+
code: "// eslint-disable-line",
89+
errors: ["Unexpected ESLint directive comment."],
90+
},
91+
{
92+
code: "// eslint-disable-next-line",
93+
errors: ["Unexpected ESLint directive comment."],
94+
},
95+
{
96+
code: "/* exported */",
97+
errors: ["Unexpected ESLint directive comment."],
98+
},
99+
{
100+
code: "/* global */",
101+
errors: ["Unexpected ESLint directive comment."],
102+
},
103+
{
104+
code: "/* globals */",
105+
errors: ["Unexpected ESLint directive comment."],
106+
},
107+
],
108+
})

0 commit comments

Comments
 (0)