All files / src/utils isReactComponentClass.js

100% Statements 14/14
100% Branches 18/18
100% Functions 2/2
100% Lines 14/14
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                                  9x     33x                           465x 465x   279x       186x 6x       180x 5x   175x 175x 2x   173x 173x    
/*
 * 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.
 *
 * @flow
 */
 
import isReactModuleName from './isReactModuleName';
import match from './match';
import recast from 'recast';
import resolveToModule from './resolveToModule';
import resolveToValue from './resolveToValue';
 
var {types: {namedTypes: types}} = recast;
 
function isRenderMethod(node) {
  return types.MethodDefinition.check(node) &&
    !node.computed &&
    !node.static &&
    (node.kind === '' || node.kind === 'method') &&
    node.key.name === 'render';
}
 
/**
 * Returns `true` of the path represents a class definition which either extends
 * `React.Component` or implements a `render()` method.
 */
export default function isReactComponentClass(
  path: NodePath
): bool {
  var node = path.node;
  if (!types.ClassDeclaration.check(node) &&
    !types.ClassExpression.check(node)) {
    return false;
  }
 
  // render method
  if (node.body.body.some(isRenderMethod)) {
    return true;
  }
 
  // extends ReactComponent?
  if (!node.superClass) {
    return false;
  }
  var superClass = resolveToValue(path.get('superClass'));
  if (!match(superClass.node, {property: {name: 'Component'}})) {
    return false;
  }
  var module = resolveToModule(superClass);
  return !!module && isReactModuleName(module);
}