diff --git a/.README/rules/check-examples.md b/.README/rules/check-examples.md
index 2b3cf7d68..d3f12321c 100644
--- a/.README/rules/check-examples.md
+++ b/.README/rules/check-examples.md
@@ -1,5 +1,8 @@
### `check-examples`
+> **NOTE**: This rule currently does not work in ESLint 8 (we are waiting for
+> [issue 14745](https://github.com/eslint/eslint/issues/14745)).
+
Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules. Also
has options to lint the default values of optional `@param`/`@arg`/`@argument`
and `@property`/`@prop` tags or the values of `@default`/`@defaultvalue` tags.
diff --git a/.travis.yml b/.travis.yml
index 8cf348fcd..161316f20 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,25 +3,27 @@ dist: xenial
language: node_js
node_js:
+ - "17"
- "16"
- "14.14.0"
- "12.20.0"
before_install:
- npm config set depth 0
+install:
+ - echo "Avoid Travis's npm auto-install"
before_script: >
node_version=$(node -v);
- if [ ${node_version:3:1} = "." ]; then
- echo "Node 10+"
- if [ ${ESLINT} = "6" ]; then
- npm install --legacy-peer-deps --no-save "eslint@${ESLINT}" eslint-config-canonical@24.4.4
- else
- npm install --legacy-peer-deps --no-save "eslint@${ESLINT}"
- fi
- else
- echo "Node 8+"
- npm install --legacy-peer-deps --no-save "eslint@${ESLINT}" husky@3.1.0 semantic-release@15.14.0 eslint-config-canonical@18.1.1
- fi
+ if [ ${node_version:1:2} = "17" ]; then
+ echo "Deadsnakes"
+ sudo add-apt-repository --yes ppa:deadsnakes/ppa
+ echo "Update apt-get"
+ sudo apt-get update
+ echo "Install Python3"
+ sudo apt-get --assume-yes install python3.6
+ sudo ln -sf /usr/bin/python3.6 /usr/bin/python3
+ fi;
+ npm install --legacy-peer-deps --no-save "eslint@${ESLINT}"
notifications:
email: false
script:
@@ -30,16 +32,13 @@ script:
- npm run build
env:
jobs:
+ - ESLINT=8
- ESLINT=7
- - ESLINT=6
jobs:
fast_finish: true
include:
- node_js: 'lts/*'
env: LINT=true
- exclude:
- - node_js: 8
- env: ESLINT=7
after_success:
- export NODE_ENV=production
- npm run build
diff --git a/README.md b/README.md
index 5f98799be..ce447c451 100644
--- a/README.md
+++ b/README.md
@@ -945,6 +945,9 @@ function quux (foo) {
### check-examples
+> **NOTE**: This rule currently does not work in ESLint 8 (we are waiting for
+> [issue 14745](https://github.com/eslint/eslint/issues/14745)).
+
Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules. Also
has options to lint the default values of optional `@param`/`@arg`/`@argument`
and `@property`/`@prop` tags or the values of `@default`/`@defaultvalue` tags.
@@ -6914,7 +6917,7 @@ class MyClass {
*/
myClassField = 1
}
-// "jsdoc/match-description": ["error"|"warn", {"contexts":["ClassProperty"]}]
+// "jsdoc/match-description": ["error"|"warn", {"contexts":["PropertyDefinition"]}]
// Message: JSDoc description does not satisfy the regex pattern.
/**
@@ -7182,7 +7185,7 @@ class MyClass {
*/
myClassField = 1
}
-// "jsdoc/match-description": ["error"|"warn", {"contexts":["ClassProperty"]}]
+// "jsdoc/match-description": ["error"|"warn", {"contexts":["PropertyDefinition"]}]
/**
* Foo.
@@ -12813,7 +12816,7 @@ class Animal {
@SomeAnnotation('optionalParameter')
tail: boolean;
}
-// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["ClassProperty"]}]
+// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["PropertyDefinition"]}]
// Message: Missing JSDoc comment.
@Entity('users')
@@ -12907,7 +12910,7 @@ export class MyComponentComponent {
@Input()
public value = new EventEmitter();
}
-// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["ClassProperty:has(Decorator[expression.callee.name=\"Input\"])"]}]
+// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["PropertyDefinition > Decorator[expression.callee.name=\"Input\"]"]}]
// Message: Missing JSDoc comment.
requestAnimationFrame(draw)
@@ -12951,6 +12954,12 @@ function comment () {
}
// "jsdoc/require-jsdoc": ["error"|"warn", {"enableFixer":false,"fixerMessage":" TODO: add comment"}]
// Message: Missing JSDoc comment.
+
+export class InovaAutoCompleteComponent {
+ public disabled = false;
+}
+// "jsdoc/require-jsdoc": ["error"|"warn", {"contexts":["PropertyDefinition"],"publicOnly":true}]
+// Message: Missing JSDoc comment.
````
The following patterns are not considered problems:
diff --git a/package.json b/package.json
index 10c679dca..b69c7409c 100644
--- a/package.json
+++ b/package.json
@@ -5,11 +5,11 @@
"url": "http://gajus.com"
},
"dependencies": {
- "@es-joy/jsdoccomment": "0.10.8",
+ "@es-joy/jsdoccomment": "0.12.0",
"comment-parser": "1.2.4",
"debug": "^4.3.2",
"esquery": "^1.4.0",
- "jsdoc-type-pratt-parser": "^1.2.0",
+ "jsdoc-type-pratt-parser": "^2.0.0",
"lodash": "^4.17.21",
"regextras": "^0.8.0",
"semver": "^7.3.5",
@@ -26,26 +26,26 @@
"@babel/preset-env": "^7.15.8",
"@babel/register": "^7.15.3",
"@hkdobrev/run-if-changed": "^0.3.1",
- "@typescript-eslint/parser": "^4.33.0",
+ "@typescript-eslint/parser": "^5.1.0",
"babel-plugin-add-module-exports": "^1.0.4",
- "babel-plugin-istanbul": "^6.0.0",
+ "babel-plugin-istanbul": "^6.1.1",
"chai": "^4.3.4",
"cross-env": "^7.0.3",
- "eslint": "7.32.0",
- "eslint-config-canonical": "^28.0.0",
+ "eslint": "^8.1.0",
+ "eslint-config-canonical": "^30.1.0",
"gitdown": "^3.1.4",
"glob": "^7.2.0",
- "husky": "^7.0.2",
- "lint-staged": "^11.2.1",
- "mocha": "^9.1.2",
+ "husky": "^7.0.4",
+ "lint-staged": "^11.2.3",
+ "mocha": "^9.1.3",
"nyc": "^15.1.0",
"open-editor": "^3.0.0",
"rimraf": "^3.0.2",
"semantic-release": "^18.0.0",
- "typescript": "^4.4.3"
+ "typescript": "^4.4.4"
},
"engines": {
- "node": "^12 || ^14 || ^16"
+ "node": "^12 || ^14 || ^16 || ^17"
},
"lint-staged": {
".eslintignore": "npm run lint",
@@ -65,7 +65,7 @@
"main": "./dist/index.js",
"name": "eslint-plugin-jsdoc",
"peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0"
+ "eslint": "^7.0.0 || ^8.0.0"
},
"repository": {
"type": "git",
@@ -80,10 +80,10 @@
"lint-fix": "eslint --report-unused-disable-directives --fix ./src ./test",
"lint": "eslint --report-unused-disable-directives --ignore-pattern '!.ncurc.js' ./src ./test .ncurc.js",
"lint-arg": "eslint --report-unused-disable-directives",
- "test-cov": "cross-env BABEL_ENV=test nyc mocha --parallel --reporter dot --recursive --require @babel/register --timeout 12000",
- "test-no-cov": "cross-env BABEL_ENV=test mocha --parallel --reporter dot --recursive --require @babel/register --timeout 12000",
+ "test-cov": "cross-env BABEL_ENV=test nyc mocha --reporter dot --recursive --require @babel/register --timeout 12000",
+ "test-no-cov": "cross-env BABEL_ENV=test mocha --reporter dot --recursive --require @babel/register --timeout 12000",
"test-index": "cross-env BABEL_ENV=test mocha --recursive --require @babel/register --reporter progress --timeout 12000 test/rules/index.js",
- "test": "cross-env BABEL_ENV=test nyc --reporter text-summary mocha --parallel --reporter dot --recursive --require @babel/register --timeout 12000",
+ "test": "cross-env BABEL_ENV=test nyc --reporter text-summary mocha --reporter dot --recursive --require @babel/register --timeout 12000",
"prepare": "husky install"
},
"nyc": {
@@ -95,6 +95,9 @@
"include": [
"src/"
],
+ "exclude": [
+ "src/rules/checkExamples.js"
+ ],
"check-coverage": true,
"branches": 100,
"lines": 100,
diff --git a/src/iterateJsdoc.js b/src/iterateJsdoc.js
index 5b52dde27..b2c50119b 100644
--- a/src/iterateJsdoc.js
+++ b/src/iterateJsdoc.js
@@ -708,6 +708,9 @@ const makeReport = (context, commentNode) => {
end: {line: lineNumber},
start: {line: lineNumber},
};
+
+ // Todo: Remove ignore once `check-examples` can be restored for ESLint 8+
+ // istanbul ignore if
if (jsdocLoc.column) {
const colNumber = commentNode.loc.start.column + jsdocLoc.column;
diff --git a/src/jsdocUtils.js b/src/jsdocUtils.js
index 6c4ac63fa..5d6c07383 100644
--- a/src/jsdocUtils.js
+++ b/src/jsdocUtils.js
@@ -718,6 +718,8 @@ const hasNonEmptyResolverCall = (node, resolverName) => {
case 'ObjectProperty':
/* eslint-disable no-fallthrough */
// istanbul ignore next -- In Babel?
+ case 'PropertyDefinition':
+ // istanbul ignore next -- In Babel?
case 'ClassProperty':
/* eslint-enable no-fallthrough */
case 'Property':
@@ -908,9 +910,11 @@ const hasNonFunctionYield = (node, checkYieldReturnValue) => {
});
// istanbul ignore next -- In Babel?
- case 'ObjectProperty':
+ case 'PropertyDefinition':
/* eslint-disable no-fallthrough */
// istanbul ignore next -- In Babel?
+ case 'ObjectProperty':
+ // istanbul ignore next -- In Babel?
case 'ClassProperty':
/* eslint-enable no-fallthrough */
case 'Property':
diff --git a/src/rules/checkExamples.js b/src/rules/checkExamples.js
index 84cffd26e..7cc177782 100644
--- a/src/rules/checkExamples.js
+++ b/src/rules/checkExamples.js
@@ -1,9 +1,9 @@
-// Todo: When peerDeps bump to ESLint 7, see about replacing `CLIEngine`
-// with non-deprecated `ESLint` class:
+// Todo: When replace `CLIEngine` with `ESLint` when feature set complete per https://github.com/eslint/eslint/issues/14745
// https://github.com/eslint/eslint/blob/master/docs/user-guide/migrating-to-7.0.0.md#-the-cliengine-class-has-been-deprecated
import {
- CLIEngine,
+ CLIEngine, ESLint,
} from 'eslint';
+import semver from 'semver';
import iterateJsdoc from '../iterateJsdoc';
const zeroBasedLineIndexAdjust = -1;
@@ -85,6 +85,17 @@ export default iterateJsdoc(({
context,
globalState,
}) => {
+ if (semver.gte(ESLint.version, '8.0.0')) {
+ report(
+ 'This rule cannot yet be supported for ESLint 8; you ' +
+ 'should either downgrade to ESLint 7 or disable this rule. The ' +
+ 'possibility for ESLint 8 support is being tracked at https://github.com/eslint/eslint/issues/14745',
+ {column: 1, line: 1},
+ );
+
+ return;
+ }
+
if (!globalState.has('checkExamples-matchingFileName')) {
globalState.set('checkExamples-matchingFileName', new Map());
}
@@ -196,8 +207,7 @@ export default iterateJsdoc(({
matchingFileNameMap.set(fileNameMapKey, cliFile);
}
- const {results: [{messages}]} =
- cliFile.executeOnText(src);
+ const {results: [{messages}]} = cliFile.executeOnText(src);
if (!('line' in tag)) {
tag.line = tag.source[0].number;
diff --git a/src/rules/requireDescriptionCompleteSentence.js b/src/rules/requireDescriptionCompleteSentence.js
index bf59c12c4..0676b59c1 100644
--- a/src/rules/requireDescriptionCompleteSentence.js
+++ b/src/rules/requireDescriptionCompleteSentence.js
@@ -26,6 +26,8 @@ const extractSentences = (text, abbreviationsRegex) => {
.replace(abbreviationsRegex, '');
const sentenceEndGrouping = /([.?!])(?:\s+|$)/u;
+
+ // eslint-disable-next-line unicorn/no-array-method-this-argument
const puncts = RegExtras(sentenceEndGrouping).map(txt, (punct) => {
return punct;
});
diff --git a/src/rules/requireJsdoc.js b/src/rules/requireJsdoc.js
index 20fe68c4f..8c123c74e 100644
--- a/src/rules/requireJsdoc.js
+++ b/src/rules/requireJsdoc.js
@@ -308,7 +308,7 @@ export default {
if (
['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) ||
- ['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value
+ ['Property', 'ObjectProperty', 'ClassProperty', 'PropertyDefinition'].includes(node.parent.type) && node === node.parent.value
) {
checkJsDoc({isFunctionContext: true}, null, node);
}
@@ -351,7 +351,7 @@ export default {
if (
['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) ||
- ['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value
+ ['Property', 'ObjectProperty', 'ClassProperty', 'PropertyDefinition'].includes(node.parent.type) && node === node.parent.value
) {
checkJsDoc({isFunctionContext: true}, null, node);
}
diff --git a/test/rules/assertions/matchDescription.js b/test/rules/assertions/matchDescription.js
index c2c2973a1..725f17f7c 100644
--- a/test/rules/assertions/matchDescription.js
+++ b/test/rules/assertions/matchDescription.js
@@ -794,7 +794,7 @@ export default {
options: [
{
contexts: [
- 'ClassProperty',
+ 'PropertyDefinition',
],
},
],
@@ -1269,7 +1269,7 @@ export default {
options: [
{
contexts: [
- 'ClassProperty',
+ 'PropertyDefinition',
],
},
],
diff --git a/test/rules/assertions/requireJsdoc.js b/test/rules/assertions/requireJsdoc.js
index f82ccbe2f..236771061 100644
--- a/test/rules/assertions/requireJsdoc.js
+++ b/test/rules/assertions/requireJsdoc.js
@@ -2,10 +2,6 @@
* @see https://github.com/eslint/eslint/blob/master/tests/lib/rules/require-jsdoc.js
*/
-import {
- CLIEngine,
-} from 'eslint';
-
export default {
invalid: [
{
@@ -2591,7 +2587,7 @@ function quux (foo) {
],
options: [
{
- contexts: ['ClassProperty'],
+ contexts: ['PropertyDefinition'],
},
],
output: `
@@ -3016,15 +3012,7 @@ function quux (foo) {
},
],
options: [{
- contexts: [
- // Only fixed to support `:has()` with TS later in ESLint 7, but
- // for our testing of ESLint 6, we use `>` which is equivalent in
- // this case; after having peerDeps. to ESLint 7+, we can remove
- // this check and use of `CLIEngine`
- CLIEngine.version.startsWith('6') ?
- 'ClassProperty > Decorator[expression.callee.name="Input"]' :
- 'ClassProperty:has(Decorator[expression.callee.name="Input"])',
- ],
+ contexts: ['PropertyDefinition > Decorator[expression.callee.name="Input"]'],
}],
output: `
export class MyComponentComponent {
@@ -3262,6 +3250,37 @@ function quux (foo) {
}
`,
},
+ {
+ code: `
+ export class InovaAutoCompleteComponent {
+ public disabled = false;
+ }
+ `,
+ errors: [
+ {
+ line: 3,
+ message: 'Missing JSDoc comment.',
+ },
+ ],
+ options: [
+ {
+ contexts: ['PropertyDefinition'],
+ publicOnly: true,
+ },
+ ],
+ output: `
+ export class InovaAutoCompleteComponent {
+ /**
+ *
+ */
+ public disabled = false;
+ }
+ `,
+ parser: require.resolve('@typescript-eslint/parser'),
+ parserOptions: {
+ sourceType: 'module',
+ },
+ },
],
valid: [{
code: `
diff --git a/test/rules/index.js b/test/rules/index.js
index 8a1828c7d..fe851da0e 100644
--- a/test/rules/index.js
+++ b/test/rules/index.js
@@ -1,13 +1,20 @@
import {
- RuleTester,
+ ESLint, RuleTester,
} from 'eslint';
import _ from 'lodash';
+import semver from 'semver';
import config from '../../src';
import ruleNames from './ruleNames.json';
const ruleTester = new RuleTester();
(process.env.npm_config_rule ? process.env.npm_config_rule.split(',') : ruleNames).forEach(async (ruleName) => {
+ if (semver.gte(ESLint.version, '8.0.0') && ruleName === 'check-examples') {
+ // This rule cannot yet be supported for ESLint 8;
+ // The possibility for ESLint 8 support is being tracked at https://github.com/eslint/eslint/issues/14745
+ return;
+ }
+
const rule = config.rules[ruleName];
const parserOptions = {