function componentRule(rule,context){var sourceCode=context.getSourceCode();var components=new Components();// Utilities for component detection
var utils={/**
     * Check if the node is a React ES5 component
     *
     * @param {ASTNode} node The AST node being checked.
     * @returns {Boolean} True if the node is a React ES5 component, false if not
     */isES5Component:function isES5Component(node){if(!node.parent){return false;}return /^(React\.)?createClass$/.test(sourceCode.getText(node.parent.callee));},/**
     * Check if the node is a React ES6 component
     *
     * @param {ASTNode} node The AST node being checked.
     * @returns {Boolean} True if the node is a React ES6 component, false if not
     */isES6Component:function isES6Component(node){if(!node.superClass){return false;}return /^(React\.)?Component$/.test(sourceCode.getText(node.superClass));},/**
     * Check if the node is returning JSX
     *
     * @param {ASTNode} node The AST node being checked (must be a ReturnStatement).
     * @returns {Boolean} True if the node is returning JSX, false if not
     */isReturningJSX:function isReturningJSX(node){var property=void 0;switch(node.type){case'ReturnStatement':property='argument';break;case'ArrowFunctionExpression':property='body';break;default:return false;}var returnsJSX=node[property]&&node[property].type==='JSXElement';var returnsReactCreateElement=node[property]&&node[property].callee&&node[property].callee.property&&node[property].callee.property.name==='createElement';return Boolean(returnsJSX||returnsReactCreateElement);},/**
     * Get the parent component node from the current scope
     *
     * @returns {ASTNode} component node, null if we are not in a component
     */getParentComponent:function getParentComponent(){return utils.getParentES6Component()||utils.getParentES5Component()||utils.getParentStatelessComponent();},/**
     * Get the parent ES5 component node from the current scope
     *
     * @returns {ASTNode} component node, null if we are not in a component
     */getParentES5Component:function getParentES5Component(){var scope=context.getScope();while(scope){var node=scope.block&&scope.block.parent&&scope.block.parent.parent;if(node&&utils.isES5Component(node)){return node;}scope=scope.upper;}return null;},/**
     * Get the parent ES6 component node from the current scope
     *
     * @returns {ASTNode} component node, null if we are not in a component
     */getParentES6Component:function getParentES6Component(){var scope=context.getScope();while(scope&&scope.type!=='class'){scope=scope.upper;}var node=scope&&scope.block;if(!node||!utils.isES6Component(node)){return null;}return node;},/**
     * Get the parent stateless component node from the current scope
     *
     * @returns {ASTNode} component node, null if we are not in a component
     */getParentStatelessComponent:function getParentStatelessComponent(){var scope=context.getScope();while(scope){var node=scope.block;// Ignore non functions
var isFunction=/Function/.test(node.type);// Ignore classes methods
var isNotMethod=!node.parent||node.parent.type!=='MethodDefinition';// Ignore arguments (callback, etc.)
var isNotArgument=!node.parent||node.parent.type!=='CallExpression';if(isFunction&&isNotMethod&&isNotArgument){return node;}scope=scope.upper;}return null;},/**
     * Get the related component from a node
     *
     * @param {ASTNode} node The AST node being checked (must be a MemberExpression).
     * @returns {ASTNode} component node, null if we cannot find the component
     */getRelatedComponent:function getRelatedComponent(node){var currentNode=node;var i=void 0;var j=void 0;var k=void 0;var l=void 0;// Get the component path
var componentPath=[];while(currentNode){if(currentNode.property&&currentNode.property.type==='Identifier'){componentPath.push(currentNode.property.name);}if(currentNode.object&&currentNode.object.type==='Identifier'){componentPath.push(currentNode.object.name);}currentNode=currentNode.object;}componentPath.reverse();// Find the variable in the current scope
var variableName=componentPath.shift();if(!variableName){return null;}var variableInScope=void 0;var variables=context.getScope().variables;for(i=0,j=variables.length;i<j;i++){// eslint-disable-line no-plusplus
if(variables[i].name===variableName){variableInScope=variables[i];break;}}if(!variableInScope){return null;}// Find the variable declaration
var defInScope=void 0;var defs=variableInScope.defs;for(i=0,j=defs.length;i<j;i++){// eslint-disable-line no-plusplus
if(defs[i].type==='ClassName'||defs[i].type==='FunctionName'||defs[i].type==='Variable'){defInScope=defs[i];break;}}if(!defInScope){return null;}currentNode=defInScope.node.init||defInScope.node;// Traverse the node properties to the component declaration
for(i=0,j=componentPath.length;i<j;i++){// eslint-disable-line no-plusplus
if(!currentNode.properties){continue;// eslint-disable-line no-continue
}for(k=0,l=currentNode.properties.length;k<l;k++){// eslint-disable-line no-plusplus, max-len
if(currentNode.properties[k].key.name===componentPath[i]){currentNode=currentNode.properties[k];break;}}if(!currentNode){return null;}currentNode=currentNode.value;}// Return the component
return components.get(currentNode);}};// Component detection instructions
var detectionInstructions={ClassDeclaration:function ClassDeclaration(node){if(!utils.isES6Component(node)){return;}components.add(node,2);},ClassProperty:function ClassProperty(){var node=utils.getParentComponent();if(!node){return;}components.add(node,2);},ObjectExpression:function ObjectExpression(node){if(!utils.isES5Component(node)){return;}components.add(node,2);},FunctionExpression:function FunctionExpression(){var node=utils.getParentComponent();if(!node){return;}components.add(node,1);},FunctionDeclaration:function FunctionDeclaration(){var node=utils.getParentComponent();if(!node){return;}components.add(node,1);},ArrowFunctionExpression:function ArrowFunctionExpression(){var node=utils.getParentComponent();if(!node){return;}if(node.expression&&utils.isReturningJSX(node)){components.add(node,2);}else{components.add(node,1);}},ThisExpression:function ThisExpression(){var node=utils.getParentComponent();if(!node||!/Function/.test(node.type)){return;}// Ban functions with a ThisExpression
components.add(node,0);},ReturnStatement:function ReturnStatement(node){if(!utils.isReturningJSX(node)){return;}var parentNode=utils.getParentComponent();if(!parentNode){return;}components.add(parentNode,2);}};// Update the provided rule instructions to add the component detection
var ruleInstructions=rule(context,components,utils);var updatedRuleInstructions=(0,_assign4.default)({},ruleInstructions);(0,_keys4.default)(detectionInstructions).forEach(function(instruction){updatedRuleInstructions[instruction]=function(node){detectionInstructions[instruction](node);return ruleInstructions[instruction]?ruleInstructions[instruction](node):undefined;};});// Return the updated rule instructions
return updatedRuleInstructions;}
Return the length of the components list
Components for which we are not confident are not counted

@returns {Number} Components list length