Blame view
node_modules/eslint/lib/internal-rules/internal-no-invalid-meta.js
5.97 KB
f7563de62
|
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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
/** * @fileoverview Internal rule to prevent missing or invalid meta property in core rules. * @author Vitor Balocco */ "use strict"; //------------------------------------------------------------------------------ // Helpers //------------------------------------------------------------------------------ /** * Gets the property of the Object node passed in that has the name specified. * * @param {string} property Name of the property to return. * @param {ASTNode} node The ObjectExpression node. * @returns {ASTNode} The Property node or null if not found. */ function getPropertyFromObject(property, node) { const properties = node.properties; for (let i = 0; i < properties.length; i++) { if (properties[i].key.name === property) { return properties[i]; } } return null; } /** * Extracts the `meta` property from the ObjectExpression that all rules export. * * @param {ASTNode} exportsNode ObjectExpression node that the rule exports. * @returns {ASTNode} The `meta` Property node or null if not found. */ function getMetaPropertyFromExportsNode(exportsNode) { return getPropertyFromObject("meta", exportsNode); } /** * Whether this `meta` ObjectExpression has a `docs` property defined or not. * * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. * @returns {boolean} `true` if a `docs` property exists. */ function hasMetaDocs(metaPropertyNode) { return Boolean(getPropertyFromObject("docs", metaPropertyNode.value)); } /** * Whether this `meta` ObjectExpression has a `docs.description` property defined or not. * * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. * @returns {boolean} `true` if a `docs.description` property exists. */ function hasMetaDocsDescription(metaPropertyNode) { const metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); return metaDocs && getPropertyFromObject("description", metaDocs.value); } /** * Whether this `meta` ObjectExpression has a `docs.category` property defined or not. * * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. * @returns {boolean} `true` if a `docs.category` property exists. */ function hasMetaDocsCategory(metaPropertyNode) { const metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); return metaDocs && getPropertyFromObject("category", metaDocs.value); } /** * Whether this `meta` ObjectExpression has a `docs.recommended` property defined or not. * * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. * @returns {boolean} `true` if a `docs.recommended` property exists. */ function hasMetaDocsRecommended(metaPropertyNode) { const metaDocs = getPropertyFromObject("docs", metaPropertyNode.value); return metaDocs && getPropertyFromObject("recommended", metaDocs.value); } /** * Whether this `meta` ObjectExpression has a `schema` property defined or not. * * @param {ASTNode} metaPropertyNode The `meta` ObjectExpression for this rule. * @returns {boolean} `true` if a `schema` property exists. */ function hasMetaSchema(metaPropertyNode) { return getPropertyFromObject("schema", metaPropertyNode.value); } /** * Checks the validity of the meta definition of this rule and reports any errors found. * * @param {RuleContext} context The ESLint rule context. * @param {ASTNode} exportsNode ObjectExpression node that the rule exports. * @param {boolean} ruleIsFixable whether the rule is fixable or not. * @returns {void} */ function checkMetaValidity(context, exportsNode) { const metaProperty = getMetaPropertyFromExportsNode(exportsNode); if (!metaProperty) { context.report(exportsNode, "Rule is missing a meta property."); return; } if (!hasMetaDocs(metaProperty)) { context.report(metaProperty, "Rule is missing a meta.docs property."); return; } if (!hasMetaDocsDescription(metaProperty)) { context.report(metaProperty, "Rule is missing a meta.docs.description property."); return; } if (!hasMetaDocsCategory(metaProperty)) { context.report(metaProperty, "Rule is missing a meta.docs.category property."); return; } if (!hasMetaDocsRecommended(metaProperty)) { context.report(metaProperty, "Rule is missing a meta.docs.recommended property."); return; } if (!hasMetaSchema(metaProperty)) { context.report(metaProperty, "Rule is missing a meta.schema property."); } } /** * Whether this node is the correct format for a rule definition or not. * * @param {ASTNode} node node that the rule exports. * @returns {boolean} `true` if the exported node is the correct format for a rule definition */ function isCorrectExportsFormat(node) { return node.type === "ObjectExpression"; } //------------------------------------------------------------------------------ // Rule Definition //------------------------------------------------------------------------------ module.exports = { meta: { docs: { description: "enforce correct use of `meta` property in core rules", category: "Internal", recommended: false }, schema: [] }, create(context) { let exportsNode; return { AssignmentExpression(node) { if (node.left && node.right && node.left.type === "MemberExpression" && node.left.object.name === "module" && node.left.property.name === "exports") { exportsNode = node.right; } }, "Program:exit"() { if (!isCorrectExportsFormat(exportsNode)) { context.report({ node: exportsNode, message: "Rule does not export an Object. Make sure the rule follows the new rule format." }); return; } checkMetaValidity(context, exportsNode); } }; } }; |