Skip to content

Commit

Permalink
eslint-plugin: Add rule no-unused-vars-before-return
Browse files Browse the repository at this point in the history
  • Loading branch information
aduth committed Dec 12, 2018
1 parent 41b93b5 commit fddb736
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/eslint-plugin/configs/custom.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
module.exports = {
plugins: [
'@wordpress',
],
rules: {
'@wordpress/no-unused-vars-before-return': 'error',
'no-restricted-syntax': [
'error',
{
Expand Down
1 change: 1 addition & 0 deletions packages/eslint-plugin/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module.exports = {
configs: require( './configs' ),
rules: require( './rules' ),
};
1 change: 1 addition & 0 deletions packages/eslint-plugin/rules/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require( 'requireindex' )( __dirname );
55 changes: 55 additions & 0 deletions packages/eslint-plugin/rules/no-unused-vars-before-return.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
module.exports = {
meta: {
type: 'problem',
schema: [],
},
create( context ) {
return {
ReturnStatement( node ) {
let functionScope = context.getScope();
while ( functionScope.type !== 'function' && functionScope.upper ) {
functionScope = functionScope.upper;
}

if ( ! functionScope ) {
return;
}

for ( const variable of functionScope.variables ) {
const isAssignmentCandidate = variable.defs.some( ( def ) => {
return (
def.node.type === 'VariableDeclarator' &&
// Allow declarations which are not initialized.
def.node.init &&
// Target function calls as "expensive".
def.node.init.type === 'CallExpression' &&
// Allow unused if part of an object destructuring.
def.node.id.type !== 'ObjectPattern' &&
// Only target assignments preceding `return`.
def.node.end < node.end
);
} );

if ( ! isAssignmentCandidate ) {
continue;
}

// The first entry in `references` is the declaration
// itself, which can be ignored.
const isUsedBeforeReturn = variable.references.slice( 1 ).some( ( reference ) => {
return reference.identifier.end < node.end;
} );

if ( isUsedBeforeReturn ) {
continue;
}

context.report(
node,
`Declared variable \`${ variable.name }\` is unused before a return path`
);
}
},
};
},
};

0 comments on commit fddb736

Please sign in to comment.