From 6afb16bdca931ed9d8f2e351c4015de1488d684a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel?= Date: Fri, 13 May 2022 16:44:13 +0200 Subject: [PATCH 1/6] feat: add no-early-return base rule --- docs/rules/no-early-return.md | 103 +++++++++++++++ lib/rules/no-early-return.js | 72 ++++++++++ tests/lib/rules/no-early-return.js | 203 +++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 docs/rules/no-early-return.md create mode 100644 lib/rules/no-early-return.js create mode 100644 tests/lib/rules/no-early-return.js diff --git a/docs/rules/no-early-return.md b/docs/rules/no-early-return.md new file mode 100644 index 000000000..56939eb5d --- /dev/null +++ b/docs/rules/no-early-return.md @@ -0,0 +1,103 @@ +--- +pageClass: rule-details +sidebarDepth: 0 +title: vue/no-early-return +description: disallow early returns in setup and data functions +--- +# vue/no-early-return + +> disallow early returns in setup and data functions + +- :exclamation: ***This rule has not been released yet.*** + +## :book: Rule Details + +This rule helps to identify accidental `return` statements in the `setup` block of a Vue component, these are `return` statements that would exit the `setup` block skipping part of the block itself (not allowing to each the end of the block). + +On the other hand, the rule checks the `data` block too, applying the same logic. + + + +```vue + + +``` + + + + + +```vue + + +``` + + + + + +```vue + + +``` + + + + + +```vue + + +``` + + + +## :wrench: Options + +Nothing. + +## :mag: Implementation + +- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-early-return.js) +- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-early-return.js) diff --git a/lib/rules/no-early-return.js b/lib/rules/no-early-return.js new file mode 100644 index 000000000..50f376e1d --- /dev/null +++ b/lib/rules/no-early-return.js @@ -0,0 +1,72 @@ +/** + * @author *****your name***** + * See LICENSE file in root directory for full license. + */ +'use strict' + +// ------------------------------------------------------------------------------ +// Requirements +// ------------------------------------------------------------------------------ + +const utils = require('../utils') + +// ------------------------------------------------------------------------------ +// Rule Definition +// ------------------------------------------------------------------------------ + +module.exports = { + meta: { + type: 'problem', + docs: { + description: 'disallow early returns in setup and data functions', + categories: undefined, + url: '' + }, + fixable: null, + schema: [] + }, + + /** @param {RuleContext} context */ + create(context) { + const rStatementLocs = [] + return utils.compositingVisitors( + utils.defineVueVisitor(context, { + ReturnStatement (node) { + if (context.getScope().type === 'function') { + return + } + rStatementLocs.push(node.loc) + }, + + onSetupFunctionExit() { + if (!rStatementLocs.length) { + return + } + + for (const loc of rStatementLocs) { + context.report({ + loc, + message: 'Extra return statement in setup function.' + }) + } + }, + onVueObjectEnter(node) { + const dataProperty = utils.findProperty(node, 'data') + if ( + !dataProperty || + (dataProperty.value.type !== 'FunctionExpression' && + dataProperty.value.type !== 'ArrowFunctionExpression') + ) { + return + } + if (context.getSourceCode().ast.tokens.filter(t => t.value === 'return').length > 1) { + context.report({ + node, + message: 'Extra return statement in data function.' + }) + } + }, + }) + ) + } +} diff --git a/tests/lib/rules/no-early-return.js b/tests/lib/rules/no-early-return.js new file mode 100644 index 000000000..f027b1467 --- /dev/null +++ b/tests/lib/rules/no-early-return.js @@ -0,0 +1,203 @@ +/** + * @author *****your name***** + * See LICENSE file in root directory for full license. + */ +'use strict' + +const RuleTester = require('eslint').RuleTester +const rule = require('../../../lib/rules/no-early-return') + +const tester = new RuleTester({ + parser: require.resolve('vue-eslint-parser'), + parserOptions: { + ecmaVersion: 2020, + sourceType: 'module' + } +}) + +tester.run('no-early-return', rule, { + valid: [ + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, + ], + invalid: [ + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + message: 'Extra return statement in setup function.', + line: 13 + }, + { + message: 'Extra return statement in setup function.', + line: 18 + }, + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + message: 'Extra return statement in setup function.', + line: 8 + }, + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + message: 'Extra return statement in data function.', + line: 3 + }, + ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + message: 'Extra return statement in data function.', + line: 3 + }, + ] + } + ] +}) From 7929a2c4fcab9325f3f9133f536c04c86bdebede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel?= Date: Fri, 13 May 2022 16:48:19 +0200 Subject: [PATCH 2/6] lint: no-early-return files --- lib/rules/no-early-return.js | 18 +++++++++++------- tests/lib/rules/no-early-return.js | 14 +++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/lib/rules/no-early-return.js b/lib/rules/no-early-return.js index 50f376e1d..f9247d2d7 100644 --- a/lib/rules/no-early-return.js +++ b/lib/rules/no-early-return.js @@ -20,7 +20,7 @@ module.exports = { docs: { description: 'disallow early returns in setup and data functions', categories: undefined, - url: '' + url: 'https://eslint.vuejs.org/rules/no-early-return.html' }, fixable: null, schema: [] @@ -31,7 +31,7 @@ module.exports = { const rStatementLocs = [] return utils.compositingVisitors( utils.defineVueVisitor(context, { - ReturnStatement (node) { + ReturnStatement(node) { if (context.getScope().type === 'function') { return } @@ -39,7 +39,7 @@ module.exports = { }, onSetupFunctionExit() { - if (!rStatementLocs.length) { + if (rStatementLocs.length === 0) { return } @@ -59,13 +59,17 @@ module.exports = { ) { return } - if (context.getSourceCode().ast.tokens.filter(t => t.value === 'return').length > 1) { + if ( + context + .getSourceCode() + .ast.tokens.filter((t) => t.value === 'return').length > 1 + ) { context.report({ - node, - message: 'Extra return statement in data function.' + node, + message: 'Extra return statement in data function.' }) } - }, + } }) ) } diff --git a/tests/lib/rules/no-early-return.js b/tests/lib/rules/no-early-return.js index f027b1467..6fe3bca12 100644 --- a/tests/lib/rules/no-early-return.js +++ b/tests/lib/rules/no-early-return.js @@ -94,10 +94,10 @@ tester.run('no-early-return', rule, { } ` - }, + } ], invalid: [ - { + { filename: 'test.vue', code: ` ` }, + { + filename: 'test.vue', + code: ` + + ` + }, + { + filename: 'test.vue', + code: ` + + ` + }, { filename: 'test.vue', code: ` @@ -94,6 +118,16 @@ tester.run('no-early-return', rule, { } ` + }, + { + filename: 'test.vue', + code: ` + + ` } ], invalid: [ @@ -182,6 +216,28 @@ tester.run('no-early-return', rule, { } ] }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'extraReturnStatement', + data: { functionType: 'data' }, + line: 3 + } + ] + }, { filename: 'test.vue', code: ` @@ -203,6 +259,28 @@ tester.run('no-early-return', rule, { line: 3 } ] + }, + { + filename: 'test.vue', + code: ` + + `, + errors: [ + { + messageId: 'extraReturnStatement', + data: { functionType: 'data' }, + line: 3 + } + ] } ] }) From d63afa8f8b9a6d177abf9fa7819d86f1d1702e0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20=C3=81ngel?= Date: Fri, 13 May 2022 18:22:22 +0200 Subject: [PATCH 6/6] tests: found test that makes the rule to fail :( --- tests/lib/rules/no-early-return.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/lib/rules/no-early-return.js b/tests/lib/rules/no-early-return.js index 8c9f3b729..64d79e8ab 100644 --- a/tests/lib/rules/no-early-return.js +++ b/tests/lib/rules/no-early-return.js @@ -128,6 +128,22 @@ tester.run('no-early-return', rule, { } ` + }, + { + filename: 'test.vue', + code: ` + + ` } ], invalid: [