src/language-js/parse-postprocess.js/postprocess
function postprocess(ast, options) {
  if (
    options.parser === "typescript" ||
    options.parser === "flow" ||
    options.parser === "espree"
  ) {
    includeShebang(ast, options);
  }

  // Invalid decorators are removed since `@typescript-eslint/typescript-estree` v4
  // https://github.com/typescript-eslint/typescript-eslint/pull/2375
  if (options.parser === "typescript" && options.originalText.includes("@")) {
    const {
      esTreeNodeToTSNodeMap,
      tsNodeToESTreeNodeMap,
    } = options.tsParseResult;
    ast = visitNode(ast, (node) => {
      const tsNode = esTreeNodeToTSNodeMap.get(node);
      if (!tsNode) {
        return;
      }
      const tsDecorators = tsNode.decorators;
      if (!Array.isArray(tsDecorators)) {
        return;
      }
      // `esTreeNodeToTSNodeMap.get(ClassBody)` and `esTreeNodeToTSNodeMap.get(ClassDeclaration)` has the same tsNode
      const esTreeNode = tsNodeToESTreeNodeMap.get(tsNode);
      if (esTreeNode !== node) {
        return;
      }
      const esTreeDecorators = esTreeNode.decorators;
      if (
        !Array.isArray(esTreeDecorators) ||
        esTreeDecorators.length !== tsDecorators.length ||
        tsDecorators.some((tsDecorator) => {
          const esTreeDecorator = tsNodeToESTreeNodeMap.get(tsDecorator);
          return (
            !esTreeDecorator || !esTreeDecorators.includes(esTreeDecorator)
          );
        })
      ) {
        const { start, end } = esTreeNode.loc;
        throw createError(
          "Leading decorators must be attached to a class declaration",
          {
            start: { line: start.line, column: start.column + 1 },
            end: { line: end.line, column: end.column + 1 },
          }
        );
      }
    });
  }

  // Keep Babel's non-standard ParenthesizedExpression nodes only if they have Closure-style type cast comments.
  if (
    options.parser !== "typescript" &&
    options.parser !== "flow" &&
    options.parser !== "espree" &&
    options.parser !== "meriyah"
  ) {
    const startOffsetsOfTypeCastedNodes = new Set();

    // Comments might be attached not directly to ParenthesizedExpression but to its ancestor.
    // E.g.: /** @type {Foo} */ (foo).bar();
    // Let's use the fact that those ancestors and ParenthesizedExpression have the same start offset.

    ast = visitNode(ast, (node) => {
      if (
        node.leadingComments &&
        node.leadingComments.some(isTypeCastComment)
      ) {
        startOffsetsOfTypeCastedNodes.add(locStart(node));
      }
    });

    ast = visitNode(ast, (node) => {
      if (node.type === "ParenthesizedExpression") {
        const { expression } = node;

        // Align range with `flow`
        if (expression.type === "TypeCastExpression") {
          expression.range = node.range;
          return expression;
        }

        const start = locStart(node);
        if (!startOffsetsOfTypeCastedNodes.has(start)) {
          expression.extra = { ...expression.extra, parenthesized: true };
          return expression;
        }
      }
    });
  }

  ast = visitNode(ast, (node) => {
    switch (node.type) {
      // Espree
      case "ChainExpression": {
        return transformChainExpression(node.expression);
      }
      case "LogicalExpression": {
        // We remove unneeded parens around same-operator LogicalExpressions
        if (isUnbalancedLogicalTree(node)) {
          return rebalanceLogicalTree(node);
        }
        break;
      }
      // fix unexpected locEnd caused by --no-semi style
      case "VariableDeclaration": {
        const lastDeclaration = getLast(node.declarations);
        if (lastDeclaration && lastDeclaration.init) {
          overrideLocEnd(node, lastDeclaration);
        }
        break;
      }
      // remove redundant TypeScript nodes
      case "TSParenthesizedType": {
        node.typeAnnotation.range = composeLoc(node);
        return node.typeAnnotation;
      }
      case "TSUnionType":
      case "TSIntersectionType":
        if (node.types.length === 1) {
          const [firstType] = node.types;
          // override loc, so that comments are attached properly
          firstType.range = composeLoc(node);
          return firstType;
        }
        break;
      case "TSTypeParameter":
        // babel-ts
        if (typeof node.name === "string") {
          node.name = {
            type: "Identifier",
            name: node.name,
            range: composeLoc(node, node.name.length),
          };
        }
        break;
      case "SequenceExpression": {
        // Babel (unlike other parsers) includes spaces and comments in the range. Let's unify this.
        const lastExpression = getLast(node.expressions);
        if (locEnd(node) > locEnd(lastExpression)) {
          node.range = composeLoc(node, lastExpression);
        }
        break;
      }
      case "ClassProperty":
        // TODO: Temporary auto-generated node type. To remove when typescript-estree has proper support for private fields.
        if (
          node.key &&
          node.key.type === "TSPrivateIdentifier" &&
          getNextNonSpaceNonCommentCharacter(
            options.originalText,
            node.key,
            locEnd
          ) === "?"
        ) {
          node.optional = true;
        }
        break;
    }
  });

  return ast;

  /**
   * - `toOverrideNode` must be the last thing in `toBeOverriddenNode`
   * - do nothing if there's a semicolon on `toOverrideNode.end` (no need to fix)
   */
  function overrideLocEnd(toBeOverriddenNode, toOverrideNode) {
    if (options.originalText[locEnd(toOverrideNode)] === ";") {
      return;
    }
    toBeOverriddenNode.range = composeLoc(toBeOverriddenNode, toOverrideNode);
  }
}