Skip to content

Commit

Permalink
ESLint Plugin: Exempt React hooks from no-unused-vars-before-return (#…
Browse files Browse the repository at this point in the history
…16737)

* ESLint Plugin: No Unused Vars Before Return: Add option excludePattern

* ESLint Plugin: Exempt hooks from recommended react configuration

* Components: Remove unneccessary ESLint disabling
  • Loading branch information
aduth authored Jul 25, 2019
1 parent e65c55d commit 9fcccb3
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 3 deletions.
1 change: 0 additions & 1 deletion packages/components/src/font-size-picker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ function FontSizePicker( {
value,
withSlider = false,
} ) {
// eslint-disable-next-line @wordpress/no-unused-vars-before-return
const [ currentSelectValue, setCurrentSelectValue ] = useState( getSelectValueFromFontSize( fontSizes, value ) );

if ( disableCustomFontSizes && ! fontSizes.length ) {
Expand Down
10 changes: 10 additions & 0 deletions packages/eslint-plugin/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 2.4.0 (Unreleased)

### New Features

- [`@wordpress/no-unused-vars-before-return`](https://github.com/WordPress/gutenberg/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars-before-return.md) now supports an `excludePattern` option to exempt function calls by name.

### Improvements

- The recommended `react` configuration specifies an option to [`@wordpress/no-unused-vars-before-return`](https://github.com/WordPress/gutenberg/blob/master/packages/eslint-plugin/docs/rules/react-unused-vars-before-return.md) to exempt React hooks usage, by convention of hooks beginning with "use" prefix.

## 2.3.0 (2019-06-12)

### Bug Fix
Expand Down
3 changes: 3 additions & 0 deletions packages/eslint-plugin/configs/react.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ module.exports = {
'react-hooks',
],
rules: {
'@wordpress/no-unused-vars-before-return': [ 'error', {
excludePattern: '^use',
} ],
'react/display-name': 'off',
'react/jsx-curly-spacing': [ 'error', {
when: 'always',
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin/configs/recommended.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ module.exports = {
parser: 'babel-eslint',
extends: [
require.resolve( './jsx-a11y.js' ),
require.resolve( './react.js' ),
require.resolve( './custom.js' ),
require.resolve( './react.js' ),
require.resolve( './esnext.js' ),
],
env: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,9 @@ function example( number ) {
return number + foo;
}
```

## Options

This rule accepts a single options argument:

- Set the `excludePattern` option to a regular expression string to exempt specific function calls by name.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ function example( number ) {
return number + foo;
}`,
},
{
code: `
function example() {
const foo = doSomeCostlyOperation();
if ( number > 10 ) {
return number + 1;
}
return number + foo;
}`,
options: [ { excludePattern: '^do' } ],
},
],
invalid: [
{
Expand All @@ -41,5 +53,18 @@ function example( number ) {
}`,
errors: [ { message: 'Variables should not be assigned until just prior its first reference. An early return statement may leave this variable unused.' } ],
},
{
code: `
function example() {
const foo = doSomeCostlyOperation();
if ( number > 10 ) {
return number + 1;
}
return number + foo;
}`,
options: [ { excludePattern: '^run' } ],
errors: [ { message: 'Variables should not be assigned until just prior its first reference. An early return statement may leave this variable unused.' } ],
},
],
} );
22 changes: 21 additions & 1 deletion packages/eslint-plugin/rules/no-unused-vars-before-return.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
module.exports = {
meta: {
type: 'problem',
schema: [],
schema: [
{
type: 'object',
properties: {
excludePattern: {
type: 'string',
},
},
additionalProperties: false,
},
],
},
create( context ) {
const options = context.options[ 0 ] || {};
const { excludePattern } = options;

return {
ReturnStatement( node ) {
let functionScope = context.getScope();
Expand Down Expand Up @@ -34,6 +47,13 @@ module.exports = {
continue;
}

if (
excludePattern !== undefined &&
new RegExp( excludePattern ).test( declaratorCandidate.node.init.callee.name )
) {
return;
}

// The first entry in `references` is the declaration
// itself, which can be ignored.
const isUsedBeforeReturn = variable.references.slice( 1 ).some( ( reference ) => {
Expand Down

0 comments on commit 9fcccb3

Please sign in to comment.