Blame view
node_modules/eslint/lib/rules/no-lone-blocks.js
2.94 KB
c39994410
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
/** * @fileoverview Rule to flag blocks with no reason to exist * @author Brandon Mills * @copyright 2015 Roberto Vidal. All rights reserved. * @copyright 2014 Brandon Mills. All rights reserved. */ "use strict"; //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = function(context) { // A stack of lone blocks to be checked for block-level bindings var loneBlocks = [], ruleDef; /** * Reports a node as invalid. * @param {ASTNode} node - The node to be reported. * @returns {void} */ function report(node) { var parent = context.getAncestors().pop(); context.report(node, parent.type === "Program" ? "Block is redundant." : "Nested block is redundant." ); } /** * Checks for any ocurrence of BlockStatement > BlockStatement or Program > BlockStatement * @returns {boolean} True if the current node is a lone block. */ function isLoneBlock() { var parent = context.getAncestors().pop(); return parent.type === "BlockStatement" || parent.type === "Program"; } /** * Checks the enclosing block of the current node for block-level bindings, * and "marks it" as valid if any. * @returns {void} */ function markLoneBlock() { if (loneBlocks.length === 0) { return; } var block = context.getAncestors().pop(); if (loneBlocks[loneBlocks.length - 1] === block) { loneBlocks.pop(); } } // Default rule definition: report all lone blocks ruleDef = { BlockStatement: function(node) { if (isLoneBlock(node)) { report(node); } } }; // ES6: report blocks without block-level bindings if (context.ecmaFeatures.blockBindings || context.ecmaFeatures.classes) { ruleDef = { "BlockStatement": function(node) { if (isLoneBlock(node)) { loneBlocks.push(node); } }, "BlockStatement:exit": function(node) { if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) { loneBlocks.pop(); report(node); } } }; } if (context.ecmaFeatures.blockBindings) { ruleDef.VariableDeclaration = function(node) { if (node.kind === "let" || node.kind === "const") { markLoneBlock(node); } }; ruleDef.FunctionDeclaration = function(node) { if (context.getScope().isStrict) { markLoneBlock(node); } }; } if (context.ecmaFeatures.classes) { ruleDef.ClassDeclaration = markLoneBlock; } return ruleDef; }; module.exports.schema = []; |