diff --git a/docs/rules/return-in-computed-property.md b/docs/rules/return-in-computed-property.md
index d25225798..0ade8e5ae 100644
--- a/docs/rules/return-in-computed-property.md
+++ b/docs/rules/return-in-computed-property.md
@@ -2,18 +2,18 @@
pageClass: rule-details
sidebarDepth: 0
title: vue/return-in-computed-property
-description: enforce that a return statement is present in computed property
+description: enforce that a return statement is present in computed property and function
since: v3.7.0
---
# vue/return-in-computed-property
-> enforce that a return statement is present in computed property
+> enforce that a return statement is present in computed property and function
- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `"plugin:vue/essential"`, `"plugin:vue/vue3-strongly-recommended"`, `"plugin:vue/strongly-recommended"`, `"plugin:vue/vue3-recommended"` and `"plugin:vue/recommended"`.
## :book: Rule Details
-This rule enforces that a `return` statement is present in `computed` properties.
+This rule enforces that a `return` statement is present in `computed` properties and functions.
@@ -46,6 +46,39 @@ export default {
+
+
+```vue
+
+```
+
+
+
## :wrench: Options
```json
diff --git a/lib/rules/return-in-computed-property.js b/lib/rules/return-in-computed-property.js
index 770e0c597..9908fe4fe 100644
--- a/lib/rules/return-in-computed-property.js
+++ b/lib/rules/return-in-computed-property.js
@@ -3,7 +3,7 @@
* @author Armano
*/
'use strict'
-
+const { ReferenceTracker } = require('eslint-utils')
const utils = require('../utils')
/**
@@ -47,13 +47,36 @@ module.exports = {
* @type {Set}
*/
const computedProperties = new Set()
+ /** @type {(FunctionExpression | ArrowFunctionExpression)[]} */
+ const computedFunctionNodes = []
// ----------------------------------------------------------------------
// Public
// ----------------------------------------------------------------------
return Object.assign(
- {},
+ {
+ Program() {
+ const tracker = new ReferenceTracker(context.getScope())
+ const traceMap = utils.createCompositionApiTraceMap({
+ [ReferenceTracker.ESM]: true,
+ computed: {
+ [ReferenceTracker.CALL]: true
+ }
+ })
+
+ for (const { node } of tracker.iterateEsmReferences(traceMap)) {
+ if (node.type !== 'CallExpression') {
+ continue
+ }
+
+ const getter = utils.getGetterBodyFromComputedFunction(node)
+ if (getter) {
+ computedFunctionNodes.push(getter)
+ }
+ }
+ }
+ },
utils.defineVueVisitor(context, {
onVueObjectEnter(obj) {
for (const computedProperty of utils.getComputedProperties(obj)) {
@@ -76,6 +99,14 @@ module.exports = {
})
}
})
+ computedFunctionNodes.forEach((cf) => {
+ if (cf === node) {
+ context.report({
+ node,
+ message: 'Expected to return a value in computed function.'
+ })
+ }
+ })
}
)
)
diff --git a/tests/lib/rules/return-in-computed-property.js b/tests/lib/rules/return-in-computed-property.js
index a7c14a51f..df6b1b680 100644
--- a/tests/lib/rules/return-in-computed-property.js
+++ b/tests/lib/rules/return-in-computed-property.js
@@ -104,6 +104,56 @@ ruleTester.run('return-in-computed-property', rule, {
`,
parserOptions,
options: [{ treatUndefinedAsUnspecified: false }]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ import {computed} from 'vue'
+ export default {
+ setup() {
+ const foo = computed(() => true)
+ const bar = computed(function() {
+ return false
+ })
+ const bar3 = computed({
+ set: () => true,
+ get: () => true
+ })
+ const bar4 = computed(() => {
+ if (foo) {
+ return true
+ } else {
+ return false
+ }
+ })
+ const foo2 = computed(() => {
+ const options = []
+ this.matches.forEach((match) => {
+ options.push(match)
+ })
+ return options
+ })
+ }
+ }
+ `,
+ parserOptions
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ import {computed} from 'vue'
+ export default {
+ setup() {
+ const foo = computed({
+ get: () => {
+ return
+ }
+ })
+ }
+ }
+ `,
+ parserOptions,
+ options: [{ treatUndefinedAsUnspecified: false }]
}
],
@@ -272,6 +322,78 @@ ruleTester.run('return-in-computed-property', rule, {
line: 5
}
]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ import {computed} from 'vue'
+ export default {
+ setup() {
+ const foo = computed(() => {})
+ const foo2 = computed(function() {})
+ const foo3 = computed(() => {
+ if (a) {
+ return
+ }
+ })
+ const foo4 = computed({
+ set: () => {},
+ get: () => {}
+ })
+ const foo5 = computed(() => {
+ const bar = () => {
+ return this.baz * 2
+ }
+ bar()
+ })
+ }
+ }
+ `,
+ parserOptions,
+ errors: [
+ {
+ message: 'Expected to return a value in computed function.',
+ line: 5
+ },
+ {
+ message: 'Expected to return a value in computed function.',
+ line: 6
+ },
+ {
+ message: 'Expected to return a value in computed function.',
+ line: 7
+ },
+ {
+ message: 'Expected to return a value in computed function.',
+ line: 14
+ },
+ {
+ message: 'Expected to return a value in computed function.',
+ line: 16
+ }
+ ]
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ import {computed} from 'vue'
+ export default {
+ setup() {
+ const foo = computed(() => {})
+ const baz = computed(() => {
+ return
+ })
+ }
+ }
+ `,
+ parserOptions,
+ options: [{ treatUndefinedAsUnspecified: false }],
+ errors: [
+ {
+ message: 'Expected to return a value in computed function.',
+ line: 5
+ }
+ ]
}
]
})