async function updateSuppressionsInText()

in packages/flow-dev-tools/src/update-suppressions/update-suppressionsRunner.js [275:355]


async function updateSuppressionsInText(
  contents: Buffer,
  allRoots: Set<RootName>,
  numBins: number,
  errorsByLine: Map<number, ErrorsForLine>,
  comment: string,
  flowBinPath: string,
): Promise<Buffer> {
  const errors = Array.from(errorsByLine);
  // Sort in reverse order so that we remove comments later in the file first. Otherwise, the
  // removal of comments earlier in the file would outdate the locations for comments later in the
  // file.
  errors.sort(([line1, _errs1], [line2, _errs2]) => line2 - line1);

  const ast = await getAst(contents.toString('utf8'), flowBinPath);

  for (const [
    _line,
    {loc: errorLoc, errorCodes, unusedSuppressions},
  ] of errors) {
    // For each line we:
    // 1. Get the start of the line. All changes will go _AFTER_ this line.
    // 2. Remove the unused supressions from the line
    // 3. Add the error suppressions at the original start of the line.
    // This ensures that we do not disrupt any offsets for errors coming before this one in the file.
    const beginningOfLine = findStartOfLine(contents, errorLoc.start.offset);

    /* Check if suppression is unused in all binaries */
    if (
      unusedSuppressions != null &&
      unusedSuppressions.bins.size === numBins
    ) {
      // Need to remove a suppression
      const loc = unusedSuppressions.loc;
      const origStart = loc.start.offset;
      const origEnd = loc.end.offset;
      let commentAST;
      for (const comment of ast.comments) {
        const [commentStartOffset, commentEndOffset] = comment.range;
        if (origStart >= commentStartOffset && origEnd <= commentEndOffset) {
          commentAST = comment;
          break;
        }
      }

      contents = updateErrorSuppression(
        contents,
        origStart,
        origEnd,
        commentAST,
        ast,
        allRoots,
        unusedSuppressions.roots,
      );
    }
    if (errorCodes.size > 0) {
      /* Need to add a suppression.
       * First of all, we want to know if we can add a comment to the line before
       * the error. So we need to see if we're in a JSX children block or inside a
       * template string when we reach the line with the error */
      const path = getPathToLoc(errorLoc, ast);
      if (path != null) {
        const [inside, ast] = getContext(errorLoc, path);
        const suppressionComments = Array.from(errorCodes).map(code =>
          comment !== ''
            ? `$FlowFixMe[${code}] ${comment}`
            : `$FlowFixMe[${code}]`,
        );
        contents = addCommentToText(
          contents,
          errorLoc,
          inside,
          suppressionComments,
          ast,
          beginningOfLine,
        );
      }
    }
  }
  return contents;
}