-
-
Notifications
You must be signed in to change notification settings - Fork 697
Add rule require-render-return.
#114
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 1 commit
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,37 @@ | ||
| # Enforces render function to always return value (require-render-return) | ||
|
|
||
| This rule aims to enforce render function to allways return value | ||
|
|
||
| ## :book: Rule Details | ||
|
|
||
| :-1: Examples of **incorrect** code for this rule: | ||
|
|
||
| ```js | ||
| export default { | ||
| render () { | ||
| } | ||
| } | ||
| ``` | ||
| ```js | ||
| export default { | ||
| render (h) { | ||
| if (foo) { | ||
| return | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| :+1: Examples of **correct** code for this rule: | ||
|
|
||
| ```js | ||
| export default { | ||
| render (h) { | ||
| return | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## :wrench: Options | ||
|
|
||
| Nothing. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| /** | ||
| * @fileoverview Enforces render function to always return value. | ||
| * @author Armano | ||
| */ | ||
| 'use strict' | ||
|
|
||
| const utils = require('../utils') | ||
|
|
||
| function create (context) { | ||
| const forbiddenNodes = [] | ||
|
|
||
| // ---------------------------------------------------------------------- | ||
| // Public | ||
| // ---------------------------------------------------------------------- | ||
|
|
||
| return Object.assign({}, | ||
| utils.findMissingReturns(forbiddenNodes, true), | ||
| utils.executeOnVue(context, obj => { | ||
| const node = obj.properties.find(item => item.type === 'Property' && | ||
| utils.getStaticPropertyName(item) === 'render' && | ||
| (item.value.type === 'ArrowFunctionExpression' || item.value.type === 'FunctionExpression') && | ||
| !item.value.expression // render: () => test | ||
| ) | ||
| if (!node) return | ||
|
|
||
| forbiddenNodes.forEach(el => { | ||
| if ( | ||
| el.loc.start.line >= node.value.loc.start.line && | ||
| el.loc.end.line <= node.value.loc.end.line | ||
| ) { | ||
| context.report({ | ||
| node: node.key, | ||
| message: 'Expected to return a value in render function.' | ||
| }) | ||
| } | ||
| }) | ||
| }) | ||
| ) | ||
| } | ||
|
|
||
| // ------------------------------------------------------------------------------ | ||
| // Rule Definition | ||
| // ------------------------------------------------------------------------------ | ||
|
|
||
| module.exports = { | ||
| meta: { | ||
| docs: { | ||
| description: 'Enforces render function to always return value.', | ||
| category: 'Possible Errors', | ||
| recommended: false | ||
| }, | ||
| fixable: null, // or "code" or "whitespace" | ||
| schema: [] | ||
| }, | ||
|
|
||
| create | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -520,5 +520,56 @@ module.exports = { | |
| } | ||
| } | ||
| } | ||
| }, | ||
|
|
||
| /** | ||
| * Find all function witch do not allways return values | ||
| * @param {Array} nodes an array nodes | ||
| * @param {boolean} treatUndefinedAsUnspecified | ||
| */ | ||
| findMissingReturns (nodes, treatUndefinedAsUnspecified) { | ||
|
||
| let funcInfo = { | ||
| funcInfo: null, | ||
| codePath: null, | ||
| hasReturn: false, | ||
| hasReturnValue: false, | ||
| node: null | ||
| } | ||
|
|
||
| function isValidReturn () { | ||
| if (!funcInfo.hasReturn) { | ||
| return false | ||
| } | ||
| return !treatUndefinedAsUnspecified || funcInfo.hasReturnValue | ||
| } | ||
|
|
||
| return { | ||
| onCodePathStart (codePath, node) { | ||
| funcInfo = { | ||
| codePath, | ||
| funcInfo: funcInfo, | ||
| hasReturn: false, | ||
| hasReturnValue: false, | ||
| node | ||
| } | ||
| }, | ||
| onCodePathEnd () { | ||
| funcInfo = funcInfo.funcInfo | ||
| }, | ||
| ReturnStatement (node) { | ||
| funcInfo.hasReturn = true | ||
| funcInfo.hasReturnValue = Boolean(node.argument) | ||
| }, | ||
| 'ArrowFunctionExpression:exit' (node) { | ||
| if (!isValidReturn()) { | ||
| nodes.push(funcInfo.node) | ||
| } | ||
| }, | ||
| 'FunctionExpression:exit' (node) { | ||
| if (!isValidReturn()) { | ||
| nodes.push(funcInfo.node) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,124 @@ | ||
| /** | ||
| * @fileoverview Enforces render function to always return value. | ||
| * @author Armano | ||
| */ | ||
| 'use strict' | ||
|
|
||
| // ------------------------------------------------------------------------------ | ||
| // Requirements | ||
| // ------------------------------------------------------------------------------ | ||
|
|
||
| const rule = require('../../../lib/rules/require-render-return') | ||
| const RuleTester = require('eslint').RuleTester | ||
|
|
||
| const parserOptions = { | ||
| ecmaVersion: 6, | ||
| sourceType: 'module', | ||
| ecmaFeatures: { experimentalObjectRestSpread: true, jsx: true } | ||
| } | ||
|
|
||
| // ------------------------------------------------------------------------------ | ||
| // Tests | ||
| // ------------------------------------------------------------------------------ | ||
|
|
||
| const ruleTester = new RuleTester() | ||
| ruleTester.run('require-render-return', rule, { | ||
| valid: [ | ||
| { | ||
| code: `Vue.component('test', { | ||
| render() { | ||
| return {} | ||
| } | ||
| })`, | ||
| parserOptions | ||
| }, | ||
| { | ||
| code: `Vue.component('test', { | ||
| foo() { | ||
| return {} | ||
| } | ||
| })`, | ||
| parserOptions | ||
| }, | ||
| { | ||
| code: `Vue.component('test', { | ||
| foo: {} | ||
| })`, | ||
| parserOptions | ||
| }, | ||
| { | ||
| code: `Vue.component('test', { | ||
| render: foo | ||
| })`, | ||
| parserOptions | ||
| }, | ||
| { | ||
| code: `Vue.component('test', { | ||
| render() { | ||
| return <div></div> | ||
| } | ||
| })`, | ||
| parserOptions | ||
| }, | ||
| { | ||
| filename: 'test.vue', | ||
| code: `export default { | ||
| render() { | ||
| return {} | ||
| } | ||
| }`, | ||
| parserOptions | ||
| }, | ||
| { | ||
| filename: 'test.vue', | ||
| code: `export default { | ||
| render: () => null | ||
| }`, | ||
| parserOptions | ||
| }, | ||
| { | ||
| filename: 'test.vue', | ||
| code: `export default { | ||
| render() { | ||
| if (a) { | ||
| return \`<div>a</div>\` | ||
| } else { | ||
| return \`<span>a</span>\` | ||
| } | ||
| } | ||
| }`, | ||
| parserOptions | ||
| } | ||
|
Member
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. Could you add tests that this rule does not report functions which are not the |
||
| ], | ||
|
|
||
| invalid: [ | ||
| { | ||
| filename: 'test.vue', | ||
| code: `export default { | ||
| render() { | ||
| } | ||
| }`, | ||
| parserOptions, | ||
| errors: [{ | ||
| message: 'Expected to return a value in render function.', | ||
| type: 'Identifier', | ||
| line: 2 | ||
| }] | ||
| }, | ||
| { | ||
| code: `Vue.component('test', { | ||
| render: function () { | ||
| if (a) { | ||
| return | ||
|
Member
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. and what about: ?
Contributor
Author
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. @michalsnik i forgot about this case, thank you 🍡 |
||
| } | ||
| } | ||
| })`, | ||
| parserOptions, | ||
| errors: [{ | ||
| message: 'Expected to return a value in render function.', | ||
| type: 'Identifier', | ||
| line: 2 | ||
| }] | ||
| } | ||
| ] | ||
| }) | ||
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.
Should be:
Find all functions which do not always return values