-
-
Notifications
You must be signed in to change notification settings - Fork 681
Add rule vue/no-early-return #1889
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6afb16b
7929a2c
85b54cb
7c05299
156b817
d63afa8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
--- | ||
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: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge> | ||
|
||
## :book: Rule Details | ||
|
||
The `setup` and `data` functions of Vue components (and [`asyncData`](https://nuxtjs.org/docs/directory-structure/pages/#asyncdata) of Nuxt.js page components) should only have a single (unconditional) return statement at the end. This rule reports early `return` statements, i.e. those that would exit the function early without allowing to reach the end of the function body. | ||
|
||
<eslint-code-block :rules="{'vue/no-early-return': ['error']}"> | ||
|
||
```vue | ||
<!-- ✓ GOOD --> | ||
<script> | ||
export default { | ||
setup () { | ||
const foo = ref() | ||
return { foo } | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
<eslint-code-block :rules="{'vue/no-early-return': ['error']}"> | ||
|
||
```vue | ||
<!-- ✗ BAD --> | ||
<script> | ||
export default { | ||
setup () { | ||
const foo = ref() | ||
|
||
if (maybe) { | ||
return | ||
} | ||
|
||
for (const t of foo.value) { | ||
if (t) { | ||
return | ||
} | ||
} | ||
|
||
return { foo } | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
<eslint-code-block :rules="{'vue/no-early-return': ['error']}"> | ||
|
||
```vue | ||
<!-- ✓ GOOD --> | ||
<script> | ||
export default { | ||
data () { | ||
return { foo: true } | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
<eslint-code-block :rules="{'vue/no-early-return': ['error']}"> | ||
|
||
```vue | ||
<!-- ✗ BAD --> | ||
<script> | ||
export default { | ||
data () { | ||
if (maybe) { | ||
return { foo: false } | ||
} | ||
|
||
return { foo: true } | ||
} | ||
} | ||
</script> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :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) |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,85 @@ | ||||||||
/** | ||||||||
* @author *****your name***** | ||||||||
* See LICENSE file in root directory for full license. | ||||||||
*/ | ||||||||
'use strict' | ||||||||
|
||||||||
// ------------------------------------------------------------------------------ | ||||||||
// Requirements | ||||||||
// ------------------------------------------------------------------------------ | ||||||||
|
||||||||
const utils = require('../utils') | ||||||||
|
||||||||
const PROPERTIES_NEED_CHECKING = new Set(['data', 'asyncData']) | ||||||||
|
||||||||
// ------------------------------------------------------------------------------ | ||||||||
// Rule Definition | ||||||||
// ------------------------------------------------------------------------------ | ||||||||
|
||||||||
module.exports = { | ||||||||
meta: { | ||||||||
type: 'problem', | ||||||||
docs: { | ||||||||
description: 'disallow early `returns` in `setup` and `data` functions', | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
categories: undefined, | ||||||||
url: 'https://eslint.vuejs.org/rules/no-early-return.html' | ||||||||
}, | ||||||||
fixable: null, | ||||||||
schema: [], | ||||||||
messages: { | ||||||||
extraReturnStatement: | ||||||||
'Only one (unconditional) return statement is allowed in {{ functionType }} function.' | ||||||||
} | ||||||||
}, | ||||||||
|
||||||||
/** @param {RuleContext} context */ | ||||||||
create(context) { | ||||||||
const returnStatementLocations = [] | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
return utils.defineVueVisitor(context, { | ||||||||
ReturnStatement(node) { | ||||||||
if (context.getScope().type === 'function') { | ||||||||
return | ||||||||
} | ||||||||
returnStatementLocations.push(node.loc) | ||||||||
}, | ||||||||
|
||||||||
onSetupFunctionExit() { | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't the logic for |
||||||||
if (returnStatementLocations.length === 0) { | ||||||||
return | ||||||||
} | ||||||||
|
||||||||
for (const loc of returnStatementLocations) { | ||||||||
context.report({ | ||||||||
loc, | ||||||||
messageId: 'extraReturnStatement', | ||||||||
data: { functionType: 'setup' } | ||||||||
}) | ||||||||
} | ||||||||
}, | ||||||||
onVueObjectEnter(node) { | ||||||||
for (const property of PROPERTIES_NEED_CHECKING) { | ||||||||
const dataProperty = utils.findProperty(node, property) | ||||||||
if ( | ||||||||
!dataProperty || | ||||||||
(dataProperty.value.type !== 'FunctionExpression' && | ||||||||
dataProperty.value.type !== 'ArrowFunctionExpression') | ||||||||
) { | ||||||||
continue | ||||||||
} | ||||||||
if ( | ||||||||
context | ||||||||
.getSourceCode() | ||||||||
.ast.tokens.filter((t) => t.value === 'return').length > 1 | ||||||||
) { | ||||||||
context.report({ | ||||||||
node, | ||||||||
messageId: 'extraReturnStatement', | ||||||||
data: { functionType: 'data' } | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should mention
Suggested change
|
||||||||
}) | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
}) | ||||||||
} | ||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please fill in your name or username here :)