UNPKG

react-native-web-headroom

Version:
174 lines (128 loc) 5.7 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = isStatelessComponent; var _getPropertyValuePath = require('./getPropertyValuePath'); var _getPropertyValuePath2 = _interopRequireDefault(_getPropertyValuePath); var _isReactComponentClass = require('./isReactComponentClass'); var _isReactComponentClass2 = _interopRequireDefault(_isReactComponentClass); var _isReactCreateClassCall = require('./isReactCreateClassCall'); var _isReactCreateClassCall2 = _interopRequireDefault(_isReactCreateClassCall); var _isReactCreateElementCall = require('./isReactCreateElementCall'); var _isReactCreateElementCall2 = _interopRequireDefault(_isReactCreateElementCall); var _isReactCloneElementCall = require('./isReactCloneElementCall'); var _isReactCloneElementCall2 = _interopRequireDefault(_isReactCloneElementCall); var _isReactChildrenElementCall = require('./isReactChildrenElementCall'); var _isReactChildrenElementCall2 = _interopRequireDefault(_isReactChildrenElementCall); var _recast = require('recast'); var _recast2 = _interopRequireDefault(_recast); var _resolveToValue = require('./resolveToValue'); var _resolveToValue2 = _interopRequireDefault(_resolveToValue); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* * Copyright (c) 2015, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * * */ var types = _recast2.default.types.namedTypes; var reNonLexicalBlocks = /^If|^Else|^Switch/; var validPossibleStatelessComponentTypes = ['Property', 'FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression']; function isJSXElementOrReactCreateElement(path) { return path.node.type === 'JSXElement' || path.node.type === 'CallExpression' && (0, _isReactCreateElementCall2.default)(path) || path.node.type === 'CallExpression' && (0, _isReactCloneElementCall2.default)(path) || path.node.type === 'CallExpression' && (0, _isReactChildrenElementCall2.default)(path); } function returnsJSXElementOrReactCreateElementCall(path) { var visited = false; // early exit for ArrowFunctionExpressions if (isJSXElementOrReactCreateElement(path.get('body'))) { return true; } function isSameBlockScope(p) { var block = p; do { block = block.parent; // jump over non-lexical blocks if (reNonLexicalBlocks.test(block.parent.node.type)) { block = block.parent; } } while (!types.BlockStatement.check(block.node) && /Function|Property/.test(block.parent.parent.node.type) && !reNonLexicalBlocks.test(block.parent.node.type)); // special case properties if (types.Property.check(path.node)) { return block.node === path.get('value', 'body').node; } return block.node === path.get('body').node; } _recast2.default.visit(path, { visitReturnStatement(returnPath) { var resolvedPath = (0, _resolveToValue2.default)(returnPath.get('argument')); if (isJSXElementOrReactCreateElement(resolvedPath) && isSameBlockScope(returnPath)) { visited = true; return false; } if (resolvedPath.node.type === 'CallExpression') { var calleeValue = (0, _resolveToValue2.default)(resolvedPath.get('callee')); if (returnsJSXElementOrReactCreateElementCall(calleeValue)) { visited = true; return false; } var resolvedValue = void 0; var namesToResolve = [calleeValue.get('property')]; if (calleeValue.node.type === 'MemberExpression') { if (calleeValue.get('object').node.type === 'Identifier') { resolvedValue = (0, _resolveToValue2.default)(calleeValue.get('object')); } else if (types.MemberExpression.check(calleeValue.node)) { do { calleeValue = calleeValue.get('object'); namesToResolve.unshift(calleeValue.get('property')); } while (types.MemberExpression.check(calleeValue.node)); resolvedValue = (0, _resolveToValue2.default)(calleeValue.get('object')); } } if (resolvedValue && types.ObjectExpression.check(resolvedValue.node)) { var resolvedMemberExpression = namesToResolve.reduce(function (result, path) { // eslint-disable-line no-shadow if (!path) { return result; } if (result) { result = (0, _getPropertyValuePath2.default)(result, path.node.name); if (result && types.Identifier.check(result.node)) { return (0, _resolveToValue2.default)(result); } } return result; }, resolvedValue); if (!resolvedMemberExpression || returnsJSXElementOrReactCreateElementCall(resolvedMemberExpression)) { visited = true; return false; } } } this.traverse(returnPath); } }); return visited; } /** * Returns `true` if the path represents a function which returns a JSXElement */ function isStatelessComponent(path) { var node = path.node; if (validPossibleStatelessComponentTypes.indexOf(node.type) === -1) { return false; } if (node.type === 'Property') { if ((0, _isReactCreateClassCall2.default)(path.parent) || (0, _isReactComponentClass2.default)(path.parent)) { return false; } } if (returnsJSXElementOrReactCreateElementCall(path)) { return true; } return false; }