Skip to content

Commit 681d522

Browse files
committed
- Add rule implements-on-classes to prevent @implements on non-constructor functions; fixes #218
1 parent 2c3c596 commit 681d522

File tree

7 files changed

+156
-0
lines changed

7 files changed

+156
-0
lines changed

.README/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ Finally, enable all of the rules that you would like to use.
8282
"jsdoc/check-syntax": 1,
8383
"jsdoc/check-tag-names": 1,
8484
"jsdoc/check-types": 1,
85+
"jsdoc/implements-on-classes": 1,
8586
"jsdoc/match-description": 1,
8687
"jsdoc/newline-after-description": 1,
8788
"jsdoc/no-undefined-types": 1,
@@ -312,6 +313,7 @@ Finally, the following rule pertains to inline disable directives:
312313
{"gitdown": "include", "file": "./rules/check-syntax.md"}
313314
{"gitdown": "include", "file": "./rules/check-tag-names.md"}
314315
{"gitdown": "include", "file": "./rules/check-types.md"}
316+
{"gitdown": "include", "file": "./rules/implements-on-classes.md"}
315317
{"gitdown": "include", "file": "./rules/match-description.md"}
316318
{"gitdown": "include", "file": "./rules/newline-after-description.md"}
317319
{"gitdown": "include", "file": "./rules/no-undefined-types.md"}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### `implements-on-classes`
2+
3+
Reports an issue with any non-constructor function using `@implements`.
4+
5+
Constructor functions, whether marked with `@class`, `@constructs`, or being
6+
an ES6 class constructor, will not be flagged.
7+
8+
|||
9+
|---|---|
10+
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
11+
|Tags|`implements` (prevented)|
12+
13+
<!-- assertions implementsOnClasses -->

README.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ JSDoc linting rules for ESLint.
3030
* [`check-syntax`](#eslint-plugin-jsdoc-rules-check-syntax)
3131
* [`check-tag-names`](#eslint-plugin-jsdoc-rules-check-tag-names)
3232
* [`check-types`](#eslint-plugin-jsdoc-rules-check-types)
33+
* [`implements-on-classes`](#eslint-plugin-jsdoc-rules-implements-on-classes)
3334
* [`match-description`](#eslint-plugin-jsdoc-rules-match-description)
3435
* [`newline-after-description`](#eslint-plugin-jsdoc-rules-newline-after-description)
3536
* [`no-undefined-types`](#eslint-plugin-jsdoc-rules-no-undefined-types)
@@ -125,6 +126,7 @@ Finally, enable all of the rules that you would like to use.
125126
"jsdoc/check-syntax": 1,
126127
"jsdoc/check-tag-names": 1,
127128
"jsdoc/check-types": 1,
129+
"jsdoc/implements-on-classes": 1,
128130
"jsdoc/match-description": 1,
129131
"jsdoc/newline-after-description": 1,
130132
"jsdoc/no-undefined-types": 1,
@@ -1360,6 +1362,64 @@ function qux(foo) {
13601362
````
13611363

13621364

1365+
<a name="eslint-plugin-jsdoc-rules-implements-on-classes"></a>
1366+
### <code>implements-on-classes</code>
1367+
1368+
Reports an issue with any non-constructor function using `@implements`.
1369+
1370+
Constructor functions, whether marked with `@class`, `@constructs`, or being
1371+
an ES6 class constructor, will not be flagged.
1372+
1373+
|||
1374+
|---|---|
1375+
|Context|`ArrowFunctionExpression`, `FunctionDeclaration`, `FunctionExpression`|
1376+
|Tags|`implements` (prevented)|
1377+
1378+
The following patterns are considered problems:
1379+
1380+
````js
1381+
/**
1382+
* @implements {SomeClass}
1383+
*/
1384+
function quux () {
1385+
1386+
}
1387+
// Message: @implements used on a non-constructor function
1388+
````
1389+
1390+
The following patterns are not considered problems:
1391+
1392+
````js
1393+
/**
1394+
* @implements {SomeClass}
1395+
* @class
1396+
*/
1397+
function quux () {
1398+
1399+
}
1400+
1401+
/**
1402+
* @implements {SomeClass}
1403+
* @constructor
1404+
*/
1405+
function quux () {
1406+
1407+
}
1408+
1409+
/**
1410+
*
1411+
*/
1412+
class quux {
1413+
/**
1414+
* @implements {SomeClass}
1415+
*/
1416+
constructor () {
1417+
1418+
}
1419+
}
1420+
````
1421+
1422+
13631423
<a name="eslint-plugin-jsdoc-rules-match-description"></a>
13641424
### <code>match-description</code>
13651425

src/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import checkParamNames from './rules/checkParamNames';
66
import checkSyntax from './rules/checkSyntax';
77
import checkTagNames from './rules/checkTagNames';
88
import checkTypes from './rules/checkTypes';
9+
import implementsOnClasses from './rules/implementsOnClasses';
910
import matchDescription from './rules/matchDescription';
1011
import newlineAfterDescription from './rules/newlineAfterDescription';
1112
import noUndefinedTypes from './rules/noUndefinedTypes';
@@ -35,6 +36,8 @@ export default {
3536
'jsdoc/check-syntax': 'off',
3637
'jsdoc/check-tag-names': 'warn',
3738
'jsdoc/check-types': 'warn',
39+
'jsdoc/implements-on-classes': 'warn',
40+
'jsdoc/match-description': 'off',
3841
'jsdoc/newline-after-description': 'warn',
3942
'jsdoc/no-undefined-types': 'warn',
4043
'jsdoc/require-description': 'off',
@@ -62,6 +65,7 @@ export default {
6265
'check-syntax': checkSyntax,
6366
'check-tag-names': checkTagNames,
6467
'check-types': checkTypes,
68+
'implements-on-classes': implementsOnClasses,
6569
'match-description': matchDescription,
6670
'newline-after-description': newlineAfterDescription,
6771
'no-undefined-types': noUndefinedTypes,

src/rules/implementsOnClasses.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import iterateJsdoc from '../iterateJsdoc';
2+
3+
export default iterateJsdoc(({
4+
report,
5+
utils
6+
}) => {
7+
if (
8+
utils.hasATag([
9+
'class',
10+
'constructor'
11+
]) ||
12+
utils.isConstructor()
13+
) {
14+
return;
15+
}
16+
17+
report('@implements used on a non-constructor function');
18+
});
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
export default {
2+
invalid: [
3+
{
4+
code: `
5+
/**
6+
* @implements {SomeClass}
7+
*/
8+
function quux () {
9+
10+
}
11+
`,
12+
errors: [
13+
{
14+
message: '@implements used on a non-constructor function'
15+
}
16+
]
17+
}
18+
],
19+
valid: [
20+
{
21+
code: `
22+
/**
23+
* @implements {SomeClass}
24+
* @class
25+
*/
26+
function quux () {
27+
28+
}
29+
`
30+
},
31+
{
32+
code: `
33+
/**
34+
* @implements {SomeClass}
35+
* @constructor
36+
*/
37+
function quux () {
38+
39+
}
40+
`
41+
},
42+
{
43+
code: `
44+
/**
45+
*
46+
*/
47+
class quux {
48+
/**
49+
* @implements {SomeClass}
50+
*/
51+
constructor () {
52+
53+
}
54+
}
55+
`
56+
}
57+
]
58+
};

test/rules/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const ruleTester = new RuleTester();
1414
'check-syntax',
1515
'check-tag-names',
1616
'check-types',
17+
'implements-on-classes',
1718
'match-description',
1819
'newline-after-description',
1920
'no-undefined-types',

0 commit comments

Comments
 (0)