Skip to content

Commit

Permalink
feat: support ESLint 8.x
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Requires ESLint@^7.0.0 || ^8.0.0
  • Loading branch information
MichaelDeBoey committed Oct 13, 2021
1 parent f0c1e44 commit 4418543
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 55 deletions.
3 changes: 3 additions & 0 deletions .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.
Expand Down
23 changes: 6 additions & 17 deletions .travis.yml
Expand Up @@ -9,37 +9,26 @@ node_js:

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
npm install --legacy-peer-deps --no-save "eslint@${ESLINT}"
notifications:
email: false
script:
- npm run test
- 'if [ -n "${LINT-}" ]; then npm run lint; fi'
# Disable until eslint-config-canonical fixed
# - 'if [ -n "${LINT-}" ]; then npm run lint; fi'
- 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
Expand Down
17 changes: 13 additions & 4 deletions README.md
Expand Up @@ -945,6 +945,9 @@ function quux (foo) {
<a name="eslint-plugin-jsdoc-rules-check-examples"></a>
### <code>check-examples</code>

> **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.
Expand Down Expand Up @@ -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.
/**
Expand Down Expand Up @@ -7182,7 +7185,7 @@ class MyClass {
*/
myClassField = 1
}
// "jsdoc/match-description": ["error"|"warn", {"contexts":["ClassProperty"]}]
// "jsdoc/match-description": ["error"|"warn", {"contexts":["PropertyDefinition"]}]
/**
* Foo.
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
19 changes: 11 additions & 8 deletions package.json
Expand Up @@ -5,7 +5,7 @@
"url": "http://gajus.com"
},
"dependencies": {
"@es-joy/jsdoccomment": "0.10.8",
"@es-joy/jsdoccomment": "0.11.0",
"comment-parser": "1.2.4",
"debug": "^4.3.2",
"esquery": "^1.4.0",
Expand All @@ -26,12 +26,12 @@
"@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.0.0",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-plugin-istanbul": "^6.0.0",
"chai": "^4.3.4",
"cross-env": "^7.0.3",
"eslint": "7.32.0",
"eslint": "^8.0.0",
"eslint-config-canonical": "^28.0.0",
"gitdown": "^3.1.4",
"glob": "^7.2.0",
Expand All @@ -48,10 +48,10 @@
"node": "^12 || ^14 || ^16"
},
"lint-staged": {
".eslintignore": "npm run lint",
"./*.js": "npm run lint-arg --",
"src/**/*.js": "npm run lint-arg --",
"test/**/*.js": "npm run lint-arg --"
"DISABLE.eslintignore": "npm run lint",
"DISABLE./*.js": "npm run lint-arg --",
"DISABLEsrc/**/*.js": "npm run lint-arg --",
"DISABLEtest/**/*.js": "npm run lint-arg --"
},
"run-if-changed": {
"package-lock.json": "npm run install-offline"
Expand All @@ -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",
Expand Down Expand Up @@ -95,6 +95,9 @@
"include": [
"src/"
],
"exclude": [
"src/rules/checkExamples.js"
],
"check-coverage": true,
"branches": 100,
"lines": 100,
Expand Down
2 changes: 2 additions & 0 deletions src/iterateJsdoc.js
Expand Up @@ -708,6 +708,8 @@ const makeReport = (context, commentNode) => {
end: {line: lineNumber},
start: {line: lineNumber},
};
// Todo: Remove once `check-examples` can be restored for ESLint 8+
// istanbul ignore if
if (jsdocLoc.column) {
const colNumber = commentNode.loc.start.column + jsdocLoc.column;

Expand Down
6 changes: 6 additions & 0 deletions src/jsdocUtils.js
Expand Up @@ -718,6 +718,9 @@ const hasNonEmptyResolverCall = (node, resolverName) => {
case 'ObjectProperty':
/* eslint-disable no-fallthrough */
// istanbul ignore next -- In Babel?
case 'PropertyDefinition':
/* eslint-disable no-fallthrough */
// istanbul ignore next -- In Babel?
case 'ClassProperty':
/* eslint-enable no-fallthrough */
case 'Property':
Expand Down Expand Up @@ -907,6 +910,9 @@ const hasNonFunctionYield = (node, checkYieldReturnValue) => {
return hasNonFunctionYield(property, checkYieldReturnValue);
});

// istanbul ignore next -- In Babel?
case 'PropertyDefinition':
/* eslint-disable no-fallthrough */
// istanbul ignore next -- In Babel?
case 'ObjectProperty':
/* eslint-disable no-fallthrough */
Expand Down
16 changes: 11 additions & 5 deletions 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;
Expand Down Expand Up @@ -85,6 +85,13 @@ export default iterateJsdoc(({
context,
globalState,
}) => {
if (semver.gte(ESLint.version, '8.0.0')) {
return report({
loc: { start: { column: 1, line: 1 } },
message: `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`,
});
}

if (!globalState.has('checkExamples-matchingFileName')) {
globalState.set('checkExamples-matchingFileName', new Map());
}
Expand Down Expand Up @@ -196,8 +203,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;
Expand Down
4 changes: 2 additions & 2 deletions src/rules/requireJsdoc.js
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions test/rules/assertions/matchDescription.js
Expand Up @@ -794,7 +794,7 @@ export default {
options: [
{
contexts: [
'ClassProperty',
'PropertyDefinition',
],
},
],
Expand Down Expand Up @@ -1269,7 +1269,7 @@ export default {
options: [
{
contexts: [
'ClassProperty',
'PropertyDefinition',
],
},
],
Expand Down
47 changes: 33 additions & 14 deletions test/rules/assertions/requireJsdoc.js
Expand Up @@ -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: [
{
Expand Down Expand Up @@ -2591,7 +2587,7 @@ function quux (foo) {
],
options: [
{
contexts: ['ClassProperty'],
contexts: ['PropertyDefinition'],
},
],
output: `
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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: `
Expand Down
11 changes: 8 additions & 3 deletions test/rules/index.js
@@ -1,13 +1,18 @@
import {
RuleTester,
} from 'eslint';
import { 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 = {
Expand Down

0 comments on commit 4418543

Please sign in to comment.