function report()

in packages/eslint-plugin-fb-flow/rules/use-indexed-access-type.js [31:124]


function report(context, sourceCode, node) {
  const util = node.id.name;
  const {typeParameters} = node;

  // Defaults if we can't produce a fix.
  let fix = undefined;
  let objectText = 'Obj';
  let indexText = util === '$ElementType' ? 'K' : "'prop'";

  if (
    typeParameters != null &&
    typeParameters.type === 'TypeParameterInstantiation' &&
    Array.isArray(typeParameters.params) &&
    typeParameters.params.length === 2
  ) {
    const [objectNode, indexNode] = typeParameters.params;
    const objectNeedsParens = doesObjectNeedsParens(objectNode);
    const objectSource = sourceCode.getText(objectNode).trim();
    objectText = objectNeedsParens ? `(${objectSource})` : objectSource;
    indexText = sourceCode.getText(indexNode).trim();

    // Don't supply a fix if there are comments, which we don't handle
    if (sourceCode.getCommentsInside(node).length === 0) {
      const openingAngleBracket = sourceCode.getTokenAfter(
        node.id,
        token => token.type === 'Punctuator' && token.value === '<',
      );
      if (openingAngleBracket == null) {
        return;
      }
      const tokenAfterOpeningAngleBracket =
        sourceCode.getTokenAfter(openingAngleBracket);
      if (tokenAfterOpeningAngleBracket == null) {
        return;
      }
      const closingAngleBracket = sourceCode.getLastToken(
        node,
        token => token.type === 'Punctuator' && token.value === '>',
      );
      if (closingAngleBracket == null) {
        return;
      }
      const indexEndToken = sourceCode.getTokenBefore(
        closingAngleBracket,
        token => !(token.type === 'Punctuator' && token.value === ','),
      );
      if (indexEndToken == null) {
        return;
      }
      const comma = sourceCode.getTokenAfter(
        objectNode,
        token => token.type === 'Punctuator' && token.value === ',',
      );
      if (comma == null) {
        return;
      }
      const tokenAfterComma = sourceCode.getTokenAfter(comma);
      if (tokenAfterComma == null) {
        return;
      }

      fix = fixer => [
        objectNeedsParens
          ? fixer.replaceTextRange(
              [node.range[0], tokenAfterOpeningAngleBracket.range[0]],
              '(',
            )
          : fixer.removeRange([
              node.range[0],
              tokenAfterOpeningAngleBracket.range[0],
            ]),
        fixer.replaceTextRange(
          [comma.range[0], tokenAfterComma.range[0]],
          objectNeedsParens ? ')[' : '[',
        ),
        fixer.replaceTextRange(
          [indexEndToken.range[1], closingAngleBracket.range[1]],
          ']',
        ),
      ];
    }
  }

  context.report({
    node,
    messageId: 'useIndexedAccess',
    data: {
      util: node.id.name,
      object: objectText,
      index: indexText,
    },
    fix,
  });
}