src/language-js/print/assignment.js/chooseLayout
function chooseLayout(path, options, print, leftDoc, rightPropertyName) {
  const node = path.getValue();
  const rightNode = node[rightPropertyName];

  if (!rightNode) {
    return "only-left";
  }

  // Short assignment chains (only 2 segments) are NOT formatted as chains.
  //   1) a = b = c; (expression statements)
  //   2) var/let/const a = b = c;

  const isTail = !isAssignment(rightNode);
  const shouldUseChainFormatting = path.match(
    isAssignment,
    isAssignmentOrVariableDeclarator,
    (node) =>
      !isTail ||
      (node.type !== "ExpressionStatement" &&
        node.type !== "VariableDeclaration")
  );
  if (shouldUseChainFormatting) {
    return !isTail
      ? "chain"
      : rightNode.type === "ArrowFunctionExpression" &&
        rightNode.body.type === "ArrowFunctionExpression"
      ? "chain-tail-arrow-chain"
      : "chain-tail";
  }
  const isHeadOfLongChain = !isTail && isAssignment(rightNode.right);

  if (
    isHeadOfLongChain ||
    hasLeadingOwnLineComment(options.originalText, rightNode)
  ) {
    return "break-after-operator";
  }

  if (
    (rightNode.type === "CallExpression" &&
      rightNode.callee.name === "require") ||
    // do not put values on a separate line from the key in json
    options.parser === "json5" ||
    options.parser === "json"
  ) {
    return "never-break-after-operator";
  }

  if (
    isComplexDestructuring(node) ||
    isComplexTypeAliasParams(node) ||
    hasComplexTypeAnnotation(node) ||
    (isArrowFunctionVariableDeclarator(node) && canBreak(leftDoc))
  ) {
    return "break-lhs";
  }

  // wrapping object properties with very short keys usually doesn't add much value
  const hasShortKey = isObjectPropertyWithShortKey(node, leftDoc, options);

  if (
    path.call(
      () => shouldBreakAfterOperator(path, options, print, hasShortKey),
      rightPropertyName
    )
  ) {
    return "break-after-operator";
  }

  if (
    hasShortKey ||
    rightNode.type === "TemplateLiteral" ||
    rightNode.type === "TaggedTemplateExpression" ||
    rightNode.type === "BooleanLiteral" ||
    isNumericLiteral(rightNode) ||
    rightNode.type === "ClassExpression"
  ) {
    return "never-break-after-operator";
  }

  return "fluid";
}