src/language-js/printer-estree.js/printClass
function printClass(path, options, print) {
  const n = path.getValue();
  const parts = [];

  if (n.type === "TSAbstractClassDeclaration") {
    parts.push("abstract ");
  }

  parts.push("class");

  if (n.id) {
    parts.push(" ", path.call(print, "id"));
  }

  parts.push(path.call(print, "typeParameters"));

  const partsGroup = [];
  if (n.superClass) {
    const printed = concat([
      "extends ",
      path.call(print, "superClass"),
      path.call(print, "superTypeParameters")
    ]);
    // Keep old behaviour of extends in same line
    // If there is only on extends and there are not comments
    if (
      (!n.implements || n.implements.length === 0) &&
      (!n.superClass.comments || n.superClass.comments.length === 0)
    ) {
      parts.push(
        concat([
          " ",
          path.call(
            superClass =>
              comments.printComments(superClass, () => printed, options),
            "superClass"
          )
        ])
      );
    } else {
      partsGroup.push(
        group(
          concat([
            line,
            path.call(
              superClass =>
                comments.printComments(superClass, () => printed, options),
              "superClass"
            )
          ])
        )
      );
    }
  } else if (n.extends && n.extends.length > 0) {
    parts.push(" extends ", join(", ", path.map(print, "extends")));
  }

  if (n["implements"] && n["implements"].length > 0) {
    partsGroup.push(
      line,
      "implements",
      group(
        indent(
          concat([
            line,
            join(concat([",", line]), path.map(print, "implements"))
          ])
        )
      )
    );
  }

  if (n["mixins"] && n["mixins"].length > 0) {
    partsGroup.push(
      line,
      "mixins ",
      group(indent(join(concat([",", line]), path.map(print, "mixins"))))
    );
  }

  if (partsGroup.length > 0) {
    parts.push(group(indent(concat(partsGroup))));
  }

  if (
    n.body &&
    n.body.comments &&
    hasLeadingOwnLineComment(options.originalText, n.body, options)
  ) {
    parts.push(hardline);
  } else {
    parts.push(" ");
  }
  parts.push(path.call(print, "body"));

  return parts;
}