function getImportedComponentClassPattern()

in packages/flow-upgrade/src/codemods/ReactUtils.js [84:144]


  function getImportedComponentClassPattern(path: any): Function | null {
    // All of the places where we want to treat as React.
    const REACT_MODULES = new Set([
      'React',
      'react',
      'react/addons',
      'react-native',
    ]);
    // The names of the exports from `REACT_MODULES` that are components
    // classes.
    const COMPONENT_CLASSES = new Set(['Component', 'PureComponent']);
    // Do we require React?
    const requiresReact =
      path
        .findVariableDeclarators()
        .filter(
          j.filters.VariableDeclarator.requiresModule(
            Array.from(REACT_MODULES),
          ),
        )
        .size() > 0;
    // Do we import React?
    const importsReact =
      path
        .find(j.ImportDeclaration, {
          type: 'ImportDeclaration',
          source: {
            type: 'Literal',
            value: value => REACT_MODULES.has(value),
          },
        })
        .size() > 0;
    // If we neither require React or import React then we cannot get a
    // component class pattern.
    if (!requiresReact && !importsReact) {
      return null;
    }
    // We want to match two different patterns so we jump straight to a
    // function.
    //
    // For now we use a simple implementation where we assume Component and/or
    // PureComponent has not been renamed. In the future if it becomes a problem
    // then we should check to see if Component and/or PureComponent were
    // renamed.
    return (node: any) =>
      node &&
      // Matches: `Component`.
      ((node.type === 'Identifier' && COMPONENT_CLASSES.has(node.name)) ||
        // Matches: `React.Component`.
        (node.type === 'MemberExpression' &&
          node.object.type === 'Identifier' &&
          node.object.name === 'React' &&
          node.property.type === 'Identifier' &&
          COMPONENT_CLASSES.has(node.property.name)) ||
        // Matches: `React.Component` but in the type position.
        (node.type === 'QualifiedTypeIdentifier' &&
          node.qualification.type === 'Identifier' &&
          node.qualification.name === 'React' &&
          node.id.type === 'Identifier' &&
          COMPONENT_CLASSES.has(node.id.name)));
  }