Skip to content

Commit 14d7832

Browse files
feat: support ESLint 8.x (#792)
* feat: support ESLint 8.x and Node 17 BREAKING CHANGE: - This update requires the disabling of the `jsdoc/check-examples` rule! We can hopefully restore this rule after eslint/eslint#14745 - Requires ESLint@^7.0.0 || ^8.0.0 - Updates `jsdoc-type-pratt-parser` and `jsdoccomment` Co-authored-by: Brett Zamir <[email protected]>
1 parent 45f8ff8 commit 14d7832

12 files changed

+118
-59
lines changed

.README/rules/check-examples.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
### `check-examples`
22

3+
> **NOTE**: This rule currently does not work in ESLint 8 (we are waiting for
4+
> [issue 14745](https://github.com/eslint/eslint/issues/14745)).
5+
36
Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules. Also
47
has options to lint the default values of optional `@param`/`@arg`/`@argument`
58
and `@property`/`@prop` tags or the values of `@default`/`@defaultvalue` tags.

.travis.yml

+14-15
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,27 @@ dist: xenial
33
language: node_js
44

55
node_js:
6+
- "17"
67
- "16"
78
- "14.14.0"
89
- "12.20.0"
910

1011
before_install:
1112
- npm config set depth 0
13+
install:
14+
- echo "Avoid Travis's npm auto-install"
1215
before_script: >
1316
node_version=$(node -v);
14-
if [ ${node_version:3:1} = "." ]; then
15-
echo "Node 10+"
16-
if [ ${ESLINT} = "6" ]; then
17-
npm install --legacy-peer-deps --no-save "eslint@${ESLINT}" [email protected]
18-
else
19-
npm install --legacy-peer-deps --no-save "eslint@${ESLINT}"
20-
fi
21-
else
22-
echo "Node 8+"
23-
npm install --legacy-peer-deps --no-save "eslint@${ESLINT}" [email protected] [email protected] [email protected]
24-
fi
17+
if [ ${node_version:1:2} = "17" ]; then
18+
echo "Deadsnakes"
19+
sudo add-apt-repository --yes ppa:deadsnakes/ppa
20+
echo "Update apt-get"
21+
sudo apt-get update
22+
echo "Install Python3"
23+
sudo apt-get --assume-yes install python3.6
24+
sudo ln -sf /usr/bin/python3.6 /usr/bin/python3
25+
fi;
26+
npm install --legacy-peer-deps --no-save "eslint@${ESLINT}"
2527
notifications:
2628
email: false
2729
script:
@@ -30,16 +32,13 @@ script:
3032
- npm run build
3133
env:
3234
jobs:
35+
- ESLINT=8
3336
- ESLINT=7
34-
- ESLINT=6
3537
jobs:
3638
fast_finish: true
3739
include:
3840
- node_js: 'lts/*'
3941
env: LINT=true
40-
exclude:
41-
- node_js: 8
42-
env: ESLINT=7
4342
after_success:
4443
- export NODE_ENV=production
4544
- npm run build

README.md

+13-4
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,9 @@ function quux (foo) {
945945
<a name="eslint-plugin-jsdoc-rules-check-examples"></a>
946946
### <code>check-examples</code>
947947

948+
> **NOTE**: This rule currently does not work in ESLint 8 (we are waiting for
949+
> [issue 14745](https://github.com/eslint/eslint/issues/14745)).
950+
948951
Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules. Also
949952
has options to lint the default values of optional `@param`/`@arg`/`@argument`
950953
and `@property`/`@prop` tags or the values of `@default`/`@defaultvalue` tags.
@@ -6914,7 +6917,7 @@ class MyClass {
69146917
*/
69156918
myClassField = 1
69166919
}
6917-
// "jsdoc/match-description": ["error"|"warn", {"contexts":["ClassProperty"]}]
6920+
// "jsdoc/match-description": ["error"|"warn", {"contexts":["PropertyDefinition"]}]
69186921
// Message: JSDoc description does not satisfy the regex pattern.
69196922
69206923
/**
@@ -7182,7 +7185,7 @@ class MyClass {
71827185
*/
71837186
myClassField = 1
71847187
}
7185-
// "jsdoc/match-description": ["error"|"warn", {"contexts":["ClassProperty"]}]
7188+
// "jsdoc/match-description": ["error"|"warn", {"contexts":["PropertyDefinition"]}]
71867189
71877190
/**
71887191
* Foo.
@@ -12813,7 +12816,7 @@ class Animal {
1281312816
@SomeAnnotation('optionalParameter')
1281412817
tail: boolean;
1281512818
}
12816-
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["ClassProperty"]}]
12819+
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["PropertyDefinition"]}]
1281712820
// Message: Missing JSDoc comment.
1281812821

1281912822
@Entity('users')
@@ -12907,7 +12910,7 @@ export class MyComponentComponent {
1290712910
@Input()
1290812911
public value = new EventEmitter();
1290912912
}
12910-
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["ClassProperty:has(Decorator[expression.callee.name=\"Input\"])"]}]
12913+
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["PropertyDefinition > Decorator[expression.callee.name=\"Input\"]"]}]
1291112914
// Message: Missing JSDoc comment.
1291212915

1291312916
requestAnimationFrame(draw)
@@ -12951,6 +12954,12 @@ function comment () {
1295112954
}
1295212955
// "jsdoc/require-jsdoc": ["error"|"warn", {"enableFixer":false,"fixerMessage":" TODO: add comment"}]
1295312956
// Message: Missing JSDoc comment.
12957+
12958+
export class InovaAutoCompleteComponent {
12959+
public disabled = false;
12960+
}
12961+
// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["PropertyDefinition"],"publicOnly":true}]
12962+
// Message: Missing JSDoc comment.
1295412963
````
1295512964

1295612965
The following patterns are not considered problems:

package.json

+18-15
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
"url": "http://gajus.com"
66
},
77
"dependencies": {
8-
"@es-joy/jsdoccomment": "0.10.8",
8+
"@es-joy/jsdoccomment": "0.12.0",
99
"comment-parser": "1.2.4",
1010
"debug": "^4.3.2",
1111
"esquery": "^1.4.0",
12-
"jsdoc-type-pratt-parser": "^1.2.0",
12+
"jsdoc-type-pratt-parser": "^2.0.0",
1313
"lodash": "^4.17.21",
1414
"regextras": "^0.8.0",
1515
"semver": "^7.3.5",
@@ -26,26 +26,26 @@
2626
"@babel/preset-env": "^7.15.8",
2727
"@babel/register": "^7.15.3",
2828
"@hkdobrev/run-if-changed": "^0.3.1",
29-
"@typescript-eslint/parser": "^4.33.0",
29+
"@typescript-eslint/parser": "^5.1.0",
3030
"babel-plugin-add-module-exports": "^1.0.4",
31-
"babel-plugin-istanbul": "^6.0.0",
31+
"babel-plugin-istanbul": "^6.1.1",
3232
"chai": "^4.3.4",
3333
"cross-env": "^7.0.3",
34-
"eslint": "7.32.0",
35-
"eslint-config-canonical": "^28.0.0",
34+
"eslint": "^8.1.0",
35+
"eslint-config-canonical": "^30.1.0",
3636
"gitdown": "^3.1.4",
3737
"glob": "^7.2.0",
38-
"husky": "^7.0.2",
39-
"lint-staged": "^11.2.1",
40-
"mocha": "^9.1.2",
38+
"husky": "^7.0.4",
39+
"lint-staged": "^11.2.3",
40+
"mocha": "^9.1.3",
4141
"nyc": "^15.1.0",
4242
"open-editor": "^3.0.0",
4343
"rimraf": "^3.0.2",
4444
"semantic-release": "^18.0.0",
45-
"typescript": "^4.4.3"
45+
"typescript": "^4.4.4"
4646
},
4747
"engines": {
48-
"node": "^12 || ^14 || ^16"
48+
"node": "^12 || ^14 || ^16 || ^17"
4949
},
5050
"lint-staged": {
5151
".eslintignore": "npm run lint",
@@ -65,7 +65,7 @@
6565
"main": "./dist/index.js",
6666
"name": "eslint-plugin-jsdoc",
6767
"peerDependencies": {
68-
"eslint": "^6.0.0 || ^7.0.0"
68+
"eslint": "^7.0.0 || ^8.0.0"
6969
},
7070
"repository": {
7171
"type": "git",
@@ -80,10 +80,10 @@
8080
"lint-fix": "eslint --report-unused-disable-directives --fix ./src ./test",
8181
"lint": "eslint --report-unused-disable-directives --ignore-pattern '!.ncurc.js' ./src ./test .ncurc.js",
8282
"lint-arg": "eslint --report-unused-disable-directives",
83-
"test-cov": "cross-env BABEL_ENV=test nyc mocha --parallel --reporter dot --recursive --require @babel/register --timeout 12000",
84-
"test-no-cov": "cross-env BABEL_ENV=test mocha --parallel --reporter dot --recursive --require @babel/register --timeout 12000",
83+
"test-cov": "cross-env BABEL_ENV=test nyc mocha --reporter dot --recursive --require @babel/register --timeout 12000",
84+
"test-no-cov": "cross-env BABEL_ENV=test mocha --reporter dot --recursive --require @babel/register --timeout 12000",
8585
"test-index": "cross-env BABEL_ENV=test mocha --recursive --require @babel/register --reporter progress --timeout 12000 test/rules/index.js",
86-
"test": "cross-env BABEL_ENV=test nyc --reporter text-summary mocha --parallel --reporter dot --recursive --require @babel/register --timeout 12000",
86+
"test": "cross-env BABEL_ENV=test nyc --reporter text-summary mocha --reporter dot --recursive --require @babel/register --timeout 12000",
8787
"prepare": "husky install"
8888
},
8989
"nyc": {
@@ -95,6 +95,9 @@
9595
"include": [
9696
"src/"
9797
],
98+
"exclude": [
99+
"src/rules/checkExamples.js"
100+
],
98101
"check-coverage": true,
99102
"branches": 100,
100103
"lines": 100,

src/iterateJsdoc.js

+3
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,9 @@ const makeReport = (context, commentNode) => {
708708
end: {line: lineNumber},
709709
start: {line: lineNumber},
710710
};
711+
712+
// Todo: Remove ignore once `check-examples` can be restored for ESLint 8+
713+
// istanbul ignore if
711714
if (jsdocLoc.column) {
712715
const colNumber = commentNode.loc.start.column + jsdocLoc.column;
713716

src/jsdocUtils.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,8 @@ const hasNonEmptyResolverCall = (node, resolverName) => {
718718
case 'ObjectProperty':
719719
/* eslint-disable no-fallthrough */
720720
// istanbul ignore next -- In Babel?
721+
case 'PropertyDefinition':
722+
// istanbul ignore next -- In Babel?
721723
case 'ClassProperty':
722724
/* eslint-enable no-fallthrough */
723725
case 'Property':
@@ -908,9 +910,11 @@ const hasNonFunctionYield = (node, checkYieldReturnValue) => {
908910
});
909911
910912
// istanbul ignore next -- In Babel?
911-
case 'ObjectProperty':
913+
case 'PropertyDefinition':
912914
/* eslint-disable no-fallthrough */
913915
// istanbul ignore next -- In Babel?
916+
case 'ObjectProperty':
917+
// istanbul ignore next -- In Babel?
914918
case 'ClassProperty':
915919
/* eslint-enable no-fallthrough */
916920
case 'Property':

src/rules/checkExamples.js

+15-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
// Todo: When peerDeps bump to ESLint 7, see about replacing `CLIEngine`
2-
// with non-deprecated `ESLint` class:
1+
// Todo: When replace `CLIEngine` with `ESLint` when feature set complete per https://github.com/eslint/eslint/issues/14745
32
// https://github.com/eslint/eslint/blob/master/docs/user-guide/migrating-to-7.0.0.md#-the-cliengine-class-has-been-deprecated
43
import {
5-
CLIEngine,
4+
CLIEngine, ESLint,
65
} from 'eslint';
6+
import semver from 'semver';
77
import iterateJsdoc from '../iterateJsdoc';
88

99
const zeroBasedLineIndexAdjust = -1;
@@ -85,6 +85,17 @@ export default iterateJsdoc(({
8585
context,
8686
globalState,
8787
}) => {
88+
if (semver.gte(ESLint.version, '8.0.0')) {
89+
report(
90+
'This rule cannot yet be supported for ESLint 8; you ' +
91+
'should either downgrade to ESLint 7 or disable this rule. The ' +
92+
'possibility for ESLint 8 support is being tracked at https://github.com/eslint/eslint/issues/14745',
93+
{column: 1, line: 1},
94+
);
95+
96+
return;
97+
}
98+
8899
if (!globalState.has('checkExamples-matchingFileName')) {
89100
globalState.set('checkExamples-matchingFileName', new Map());
90101
}
@@ -196,8 +207,7 @@ export default iterateJsdoc(({
196207
matchingFileNameMap.set(fileNameMapKey, cliFile);
197208
}
198209

199-
const {results: [{messages}]} =
200-
cliFile.executeOnText(src);
210+
const {results: [{messages}]} = cliFile.executeOnText(src);
201211

202212
if (!('line' in tag)) {
203213
tag.line = tag.source[0].number;

src/rules/requireDescriptionCompleteSentence.js

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const extractSentences = (text, abbreviationsRegex) => {
2626
.replace(abbreviationsRegex, '');
2727

2828
const sentenceEndGrouping = /([.?!])(?:\s+|$)/u;
29+
30+
// eslint-disable-next-line unicorn/no-array-method-this-argument
2931
const puncts = RegExtras(sentenceEndGrouping).map(txt, (punct) => {
3032
return punct;
3133
});

src/rules/requireJsdoc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ export default {
308308

309309
if (
310310
['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) ||
311-
['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value
311+
['Property', 'ObjectProperty', 'ClassProperty', 'PropertyDefinition'].includes(node.parent.type) && node === node.parent.value
312312
) {
313313
checkJsDoc({isFunctionContext: true}, null, node);
314314
}
@@ -351,7 +351,7 @@ export default {
351351

352352
if (
353353
['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) ||
354-
['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value
354+
['Property', 'ObjectProperty', 'ClassProperty', 'PropertyDefinition'].includes(node.parent.type) && node === node.parent.value
355355
) {
356356
checkJsDoc({isFunctionContext: true}, null, node);
357357
}

test/rules/assertions/matchDescription.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ export default {
794794
options: [
795795
{
796796
contexts: [
797-
'ClassProperty',
797+
'PropertyDefinition',
798798
],
799799
},
800800
],
@@ -1269,7 +1269,7 @@ export default {
12691269
options: [
12701270
{
12711271
contexts: [
1272-
'ClassProperty',
1272+
'PropertyDefinition',
12731273
],
12741274
},
12751275
],

0 commit comments

Comments
 (0)