├── .npmignore ├── index.js ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── package.json ├── README.md ├── LICENSE ├── rules └── consistent-return.js └── tests └── consistent-return.js /.npmignore: -------------------------------------------------------------------------------- 1 | # Everything 2 | * 3 | 4 | !index.js 5 | !rules/* 6 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview The consistent-return rule from ESLint 1.x. 3 | * @author Nicholas C. Zakas 4 | * @author Erik Desjardins 5 | */ 6 | 'use strict'; 7 | 8 | module.exports = { 9 | rules: { 10 | 'consistent-return': require('./rules/consistent-return') 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | tags: 8 | - v*.*.* 9 | pull_request: 10 | 11 | jobs: 12 | build: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@v1 16 | - uses: actions/setup-node@v1 17 | with: 18 | node-version: '12.x' 19 | registry-url: 'https://registry.npmjs.org' 20 | - run: npm install 21 | - run: npm test 22 | - run: npm publish 23 | if: startsWith(github.ref, 'refs/tags/') 24 | env: 25 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directory 27 | node_modules 28 | 29 | # Optional npm cache directory 30 | .npm 31 | 32 | # Optional REPL history 33 | .node_repl_history 34 | 35 | # IntelliJ 36 | *.iml 37 | .idea 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-consistent-return-legacy", 3 | "version": "1.0.1", 4 | "description": "The consistent-return rule from ESLint 1.x.", 5 | "keywords": [ 6 | "eslint", 7 | "eslintplugin", 8 | "eslint-plugin" 9 | ], 10 | "author": "Erik Desjardins", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/erikdesjardins/eslint-plugin-consistent-return-legacy.git" 14 | }, 15 | "main": "index.js", 16 | "scripts": { 17 | "test": "mocha ./tests/*.js" 18 | }, 19 | "peerDependencies": { 20 | "eslint": ">=2.0.0" 21 | }, 22 | "devDependencies": { 23 | "eslint": "^6.6.0", 24 | "mocha": "^6.2.2" 25 | }, 26 | "license": "MIT" 27 | } 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eslint-plugin-consistent-return-legacy 2 | 3 | The consistent-return rule from ESLint 1.x. 4 | 5 | In ESLint 1.x (as in this plugin), the rule only verifies that all or none of the return statements return a value. 6 | 7 | For example, this would be legal: 8 | 9 | ```js 10 | function() { 11 | if (foo) return foo; 12 | 13 | if (bar) return bar; 14 | } 15 | ``` 16 | 17 | In ESLint 2+, it verifies that all or none of the *code paths* return a value. 18 | 19 | So the first example would not be legal; you'd need to do this: 20 | 21 | ```js 22 | function() { 23 | if (foo) return foo; 24 | 25 | if (bar) return bar; 26 | 27 | return baz; 28 | } 29 | ``` 30 | 31 | In some code the new behavior may produce many false negatives, e.g. when returning `false` in jQuery event handlers. 32 | 33 | ## Usage 34 | 35 | `npm i --save-dev eslint-plugin-consistent-return-legacy` 36 | 37 | ```json 38 | { 39 | "plugins": [ 40 | "consistent-return-legacy" 41 | ], 42 | "rules": { 43 | "consistent-return-legacy/consistent-return": 2 44 | } 45 | } 46 | ``` 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ESLint 2 | Copyright (c) 2013 Nicholas C. Zakas. All rights reserved. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in 12 | all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /rules/consistent-return.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Rule to flag consistent return values 3 | * @author Nicholas C. Zakas 4 | */ 5 | "use strict"; 6 | 7 | //------------------------------------------------------------------------------ 8 | // Rule Definition 9 | //------------------------------------------------------------------------------ 10 | 11 | module.exports = function(context) { 12 | 13 | var functions = []; 14 | 15 | //-------------------------------------------------------------------------- 16 | // Helpers 17 | //-------------------------------------------------------------------------- 18 | 19 | /** 20 | * Marks entrance into a function by pushing a new object onto the functions 21 | * stack. 22 | * @returns {void} 23 | * @private 24 | */ 25 | function enterFunction() { 26 | functions.push({}); 27 | } 28 | 29 | /** 30 | * Marks exit of a function by popping off the functions stack. 31 | * @returns {void} 32 | * @private 33 | */ 34 | function exitFunction() { 35 | functions.pop(); 36 | } 37 | 38 | 39 | //-------------------------------------------------------------------------- 40 | // Public 41 | //-------------------------------------------------------------------------- 42 | 43 | return { 44 | 45 | "Program": enterFunction, 46 | "FunctionDeclaration": enterFunction, 47 | "FunctionExpression": enterFunction, 48 | "ArrowFunctionExpression": enterFunction, 49 | 50 | "Program:exit": exitFunction, 51 | "FunctionDeclaration:exit": exitFunction, 52 | "FunctionExpression:exit": exitFunction, 53 | "ArrowFunctionExpression:exit": exitFunction, 54 | 55 | "ReturnStatement": function(node) { 56 | 57 | var returnInfo = functions[functions.length - 1], 58 | returnTypeDefined = "type" in returnInfo; 59 | 60 | if (returnTypeDefined) { 61 | 62 | if (returnInfo.type !== !!node.argument) { 63 | context.report(node, "Expected " + (returnInfo.type ? "a" : "no") + " return value."); 64 | } 65 | 66 | } else { 67 | returnInfo.type = !!node.argument; 68 | } 69 | 70 | } 71 | }; 72 | 73 | }; 74 | 75 | module.exports.schema = []; 76 | -------------------------------------------------------------------------------- /tests/consistent-return.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Tests for consistent-return rule. 3 | * @author Raphael Pigulla 4 | */ 5 | 6 | "use strict"; 7 | 8 | //------------------------------------------------------------------------------ 9 | // Requirements 10 | //------------------------------------------------------------------------------ 11 | var rule = require('../rules/consistent-return'); 12 | var RuleTester = require("eslint").RuleTester; 13 | 14 | //------------------------------------------------------------------------------ 15 | // Tests 16 | //------------------------------------------------------------------------------ 17 | 18 | var ruleTester = new RuleTester(); 19 | ruleTester.run("consistent-return", rule, { 20 | 21 | valid: [ 22 | "function foo() { return; }", 23 | "function foo() { if (true) return; else return; }", 24 | "function foo() { if (true) return true; else return false; }", 25 | "f(function() { return; })", 26 | "f(function() { if (true) return; else return; })", 27 | "f(function() { if (true) return true; else return false; })", 28 | "function foo() { function bar() { return true; } return; }", 29 | "function foo() { function bar() { return; } return false; }", 30 | { code: "var x = () => { return {}; };", parserOptions: { ecmaVersion: 6 } }, 31 | { code: "if (true) { return 1; } return 0;", parserOptions: { ecmaFeatures: { globalReturn: true } } } 32 | ], 33 | 34 | invalid: [ 35 | { 36 | code: "function foo() { if (true) return true; else return; }", 37 | errors: [ 38 | { 39 | message: "Expected a return value.", 40 | type: "ReturnStatement" 41 | } 42 | ] 43 | }, 44 | { 45 | code: "var foo = () => { if (true) return true; else return; }", 46 | parserOptions: { ecmaVersion: 6 }, 47 | errors: [ 48 | { 49 | message: "Expected a return value.", 50 | type: "ReturnStatement" 51 | } 52 | ] 53 | }, 54 | { 55 | code: "function foo() { if (true) return; else return false; }", 56 | errors: [ 57 | { 58 | message: "Expected no return value.", 59 | type: "ReturnStatement" 60 | } 61 | ] 62 | }, 63 | { 64 | code: "f(function () { if (true) return true; else return; })", 65 | errors: [ 66 | { 67 | message: "Expected a return value.", 68 | type: "ReturnStatement" 69 | } 70 | ] 71 | }, 72 | { 73 | code: "f(function () { if (true) return; else return false; })", 74 | errors: [ 75 | { 76 | message: "Expected no return value.", 77 | type: "ReturnStatement" 78 | } 79 | ] 80 | }, 81 | { 82 | code: "f(a => { if (true) return; else return false; })", 83 | parserOptions: { ecmaVersion: 6 }, 84 | errors: [ 85 | { 86 | message: "Expected no return value.", 87 | type: "ReturnStatement" 88 | } 89 | ] 90 | }, 91 | { 92 | code: "if (true) { return 1; } return;", 93 | parserOptions: { ecmaFeatures: { globalReturn: true } }, 94 | errors: [ 95 | { 96 | message: "Expected a return value.", 97 | type: "ReturnStatement" 98 | } 99 | ] 100 | } 101 | ] 102 | }); 103 | --------------------------------------------------------------------------------