PHP 7.4.33
Preview: defaultProps.js Size: 8.30 KB
/var/www/uibuilder.cmshelp.dk/httpdocs/node_modules/eslint-plugin-react/lib/util/defaultProps.js
/**
 * @fileoverview Common defaultProps detection functionality.
 */

'use strict';

const fromEntries = require('object.fromentries');
const astUtil = require('./ast');
const componentUtil = require('./componentUtil');
const propsUtil = require('./props');
const variableUtil = require('./variable');
const propWrapperUtil = require('./propWrapper');
const getText = require('./eslint').getText;

const QUOTES_REGEX = /^["']|["']$/g;

module.exports = function defaultPropsInstructions(context, components, utils) {
  /**
   * Try to resolve the node passed in to a variable in the current scope. If the node passed in is not
   * an Identifier, then the node is simply returned.
   * @param   {ASTNode} node The node to resolve.
   * @returns {ASTNode|null} Return null if the value could not be resolved, ASTNode otherwise.
   */
  function resolveNodeValue(node) {
    if (node.type === 'Identifier') {
      return variableUtil.findVariableByName(context, node, node.name);
    }
    if (
      astUtil.isCallExpression(node)
      && propWrapperUtil.isPropWrapperFunction(context, node.callee.name)
      && node.arguments && node.arguments[0]
    ) {
      return resolveNodeValue(node.arguments[0]);
    }
    return node;
  }

  /**
   * Extracts a DefaultProp from an ObjectExpression node.
   * @param   {ASTNode} objectExpression ObjectExpression node.
   * @returns {Object|string}            Object representation of a defaultProp, to be consumed by
   *                                     `addDefaultPropsToComponent`, or string "unresolved", if the defaultProps
   *                                     from this ObjectExpression can't be resolved.
   */
  function getDefaultPropsFromObjectExpression(objectExpression) {
    const hasSpread = objectExpression.properties.find((property) => property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement');

    if (hasSpread) {
      return 'unresolved';
    }

    return objectExpression.properties.map((defaultProp) => ({
      name: getText(context, defaultProp.key).replace(QUOTES_REGEX, ''),
      node: defaultProp,
    }));
  }

  /**
   * Marks a component's DefaultProps declaration as "unresolved". A component's DefaultProps is
   * marked as "unresolved" if we cannot safely infer the values of its defaultProps declarations
   * without risking false negatives.
   * @param   {Object} component The component to mark.
   * @returns {void}
   */
  function markDefaultPropsAsUnresolved(component) {
    components.set(component.node, {
      defaultProps: 'unresolved',
    });
  }

  /**
   * Adds defaultProps to the component passed in.
   * @param   {ASTNode}         component    The component to add the defaultProps to.
   * @param   {Object[]|'unresolved'} defaultProps defaultProps to add to the component or the string "unresolved"
   *                                         if this component has defaultProps that can't be resolved.
   * @returns {void}
   */
  function addDefaultPropsToComponent(component, defaultProps) {
    // Early return if this component's defaultProps is already marked as "unresolved".
    if (component.defaultProps === 'unresolved') {
      return;
    }

    if (defaultProps === 'unresolved') {
      markDefaultPropsAsUnresolved(component);
      return;
    }

    const defaults = component.defaultProps || {};
    const newDefaultProps = Object.assign(
      {},
      defaults,
      fromEntries(defaultProps.map((prop) => [prop.name, prop]))
    );

    components.set(component.node, {
      defaultProps: newDefaultProps,
    });
  }

  return {
    MemberExpression(node) {
      const isDefaultProp = propsUtil.isDefaultPropsDeclaration(node);

      if (!isDefaultProp) {
        return;
      }

      // find component this defaultProps belongs to
      const component = utils.getRelatedComponent(node);
      if (!component) {
        return;
      }

      // e.g.:
      // MyComponent.propTypes = {
      //   foo: React.PropTypes.string.isRequired,
      //   bar: React.PropTypes.string
      // };
      //
      // or:
      //
      // MyComponent.propTypes = myPropTypes;
      if (node.parent.type === 'AssignmentExpression') {
        const expression = resolveNodeValue(node.parent.right);
        if (!expression || expression.type !== 'ObjectExpression') {
          // If a value can't be found, we mark the defaultProps declaration as "unresolved", because
          // we should ignore this component and not report any errors for it, to avoid false-positives
          // with e.g. external defaultProps declarations.
          if (isDefaultProp) {
            markDefaultPropsAsUnresolved(component);
          }

          return;
        }

        addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(expression));

        return;
      }

      // e.g.:
      // MyComponent.propTypes.baz = React.PropTypes.string;
      if (node.parent.type === 'MemberExpression' && node.parent.parent
        && node.parent.parent.type === 'AssignmentExpression') {
        addDefaultPropsToComponent(component, [{
          name: node.parent.property.name,
          node: node.parent.parent,
        }]);
      }
    },

    // e.g.:
    // class Hello extends React.Component {
    //   static get defaultProps() {
    //     return {
    //       name: 'Dean'
    //     };
    //   }
    //   render() {
    //     return <div>Hello {this.props.name}</div>;
    //   }
    // }
    MethodDefinition(node) {
      if (!node.static || node.kind !== 'get') {
        return;
      }

      if (!propsUtil.isDefaultPropsDeclaration(node)) {
        return;
      }

      // find component this propTypes/defaultProps belongs to
      const component = components.get(componentUtil.getParentES6Component(context, node));
      if (!component) {
        return;
      }

      const returnStatement = utils.findReturnStatement(node);
      if (!returnStatement) {
        return;
      }

      const expression = resolveNodeValue(returnStatement.argument);
      if (!expression || expression.type !== 'ObjectExpression') {
        return;
      }

      addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(expression));
    },

    // e.g.:
    // class Greeting extends React.Component {
    //   render() {
    //     return (
    //       <h1>Hello, {this.props.foo} {this.props.bar}</h1>
    //     );
    //   }
    //   static defaultProps = {
    //     foo: 'bar',
    //     bar: 'baz'
    //   };
    // }
    'ClassProperty, PropertyDefinition'(node) {
      if (!(node.static && node.value)) {
        return;
      }

      const propName = astUtil.getPropertyName(node);
      const isDefaultProp = propName === 'defaultProps' || propName === 'getDefaultProps';

      if (!isDefaultProp) {
        return;
      }

      // find component this propTypes/defaultProps belongs to
      const component = components.get(componentUtil.getParentES6Component(context, node));
      if (!component) {
        return;
      }

      const expression = resolveNodeValue(node.value);
      if (!expression || expression.type !== 'ObjectExpression') {
        return;
      }

      addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(expression));
    },

    // e.g.:
    // React.createClass({
    //   render: function() {
    //     return <div>{this.props.foo}</div>;
    //   },
    //   getDefaultProps: function() {
    //     return {
    //       foo: 'default'
    //     };
    //   }
    // });
    ObjectExpression(node) {
      // find component this propTypes/defaultProps belongs to
      const component = componentUtil.isES5Component(node, context) && components.get(node);
      if (!component) {
        return;
      }

      // Search for the proptypes declaration
      node.properties.forEach((property) => {
        if (property.type === 'ExperimentalSpreadProperty' || property.type === 'SpreadElement') {
          return;
        }

        const isDefaultProp = propsUtil.isDefaultPropsDeclaration(property);

        if (isDefaultProp && property.value.type === 'FunctionExpression') {
          const returnStatement = utils.findReturnStatement(property);
          if (!returnStatement || returnStatement.argument.type !== 'ObjectExpression') {
            return;
          }

          addDefaultPropsToComponent(component, getDefaultPropsFromObjectExpression(returnStatement.argument));
        }
      });
    },
  };
};

Directory Contents

Dirs: 0 × Files: 84
Name Size Perms Modified Actions
390 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
155 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.06 KB lrw-r--r-- 2025-03-28 11:04:36
Edit Download
5.06 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.11 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
11.91 KB lrw-r--r-- 2025-03-28 11:04:36
Edit Download
2.34 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
466 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
29.37 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.36 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
517 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
4.71 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
311 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
128 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
8.30 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
104 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
112 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
173 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
207 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
131 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
308 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
413 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
169 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.27 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
327 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
188 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
428 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
115 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
150 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.18 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
133 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
160 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
894 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
182 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
201 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
2.64 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
123 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
167 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
387 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.93 KB lrw-r--r-- 2025-03-28 11:04:38
Edit Download
480 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
5.25 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
140 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
119 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
611 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
172 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
137 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.48 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
201 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
127 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
302 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
233 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
241 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
3.66 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
214 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
117 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
266 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
400 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
231 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
2.17 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
2.65 KB lrw-r--r-- 2025-03-28 11:04:38
Edit Download
501 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
4.14 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
799 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
176 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
45.31 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.89 KB lrw-r--r-- 2025-03-28 11:04:38
Edit Download
419 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
7.18 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
398 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
168 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.81 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
143 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
111 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
235 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
638 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
168 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
18.14 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
1.68 KB lrw-r--r-- 2025-03-28 11:04:38
Edit Download
359 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
2.81 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
319 B lrw-r--r-- 2025-03-28 11:04:38
Edit Download
158 B lrw-r--r-- 2025-03-28 11:04:37
Edit Download
6.80 KB lrw-r--r-- 2025-03-28 11:04:37
Edit Download
If ZipArchive is unavailable, a .tar will be created (no compression).