2022-02-21 15:53:02 +08:00
|
|
|
import { printDanglingComments } from "../../main/comments.js";
|
2022-04-29 14:04:17 +08:00
|
|
|
import {
|
|
|
|
|
line,
|
|
|
|
|
softline,
|
|
|
|
|
group,
|
|
|
|
|
indent,
|
|
|
|
|
ifBreak,
|
|
|
|
|
hardline,
|
|
|
|
|
} from "../../document/builders.js";
|
2022-02-21 15:53:02 +08:00
|
|
|
import {
|
2021-01-20 15:01:16 +09:00
|
|
|
getLast,
|
|
|
|
|
hasNewlineInRange,
|
|
|
|
|
hasNewline,
|
|
|
|
|
isNonEmptyArray,
|
2022-02-21 15:53:02 +08:00
|
|
|
} from "../../common/util.js";
|
|
|
|
|
import {
|
2020-11-19 08:59:25 +08:00
|
|
|
shouldPrintComma,
|
2020-11-25 22:14:27 +08:00
|
|
|
hasComment,
|
|
|
|
|
getComments,
|
|
|
|
|
CommentCheckFlags,
|
2020-12-18 10:14:14 +08:00
|
|
|
isNextLineEmpty,
|
2022-02-21 15:53:02 +08:00
|
|
|
} from "../utils/index.js";
|
|
|
|
|
import { locStart, locEnd } from "../loc.js";
|
2020-11-19 08:59:25 +08:00
|
|
|
|
2022-02-21 15:53:02 +08:00
|
|
|
import { printOptionalToken, printTypeAnnotation } from "./misc.js";
|
|
|
|
|
import { shouldHugFunctionParameters } from "./function-parameters.js";
|
|
|
|
|
import { shouldHugType } from "./type-annotation.js";
|
|
|
|
|
import { printHardlineAfterHeritage } from "./class.js";
|
|
|
|
|
|
2022-05-07 01:37:40 +08:00
|
|
|
/** @typedef {import("../../document/builders.js").Doc} Doc */
|
2020-11-19 08:59:25 +08:00
|
|
|
|
2022-08-02 18:11:34 +08:00
|
|
|
function printObject(path, options, print) {
|
2020-11-19 08:59:25 +08:00
|
|
|
const semi = options.semi ? ";" : "";
|
2021-03-11 04:14:08 +08:00
|
|
|
const node = path.getValue();
|
2020-11-19 08:59:25 +08:00
|
|
|
|
2021-03-11 04:14:08 +08:00
|
|
|
const isTypeAnnotation = node.type === "ObjectTypeAnnotation";
|
2022-08-28 22:47:31 +03:00
|
|
|
const fields = [
|
|
|
|
|
node.type === "TSTypeLiteral"
|
|
|
|
|
? "members"
|
|
|
|
|
: node.type === "TSInterfaceBody"
|
|
|
|
|
? "body"
|
|
|
|
|
: "properties",
|
|
|
|
|
];
|
2020-11-19 08:59:25 +08:00
|
|
|
if (isTypeAnnotation) {
|
|
|
|
|
fields.push("indexers", "callProperties", "internalSlots");
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-28 22:47:31 +03:00
|
|
|
// Unfortunately, things grouped together in the ast can be
|
|
|
|
|
// interleaved in the source code. So we need to reorder them before
|
|
|
|
|
// printing them.
|
|
|
|
|
const propsAndLoc = fields.flatMap((field) =>
|
|
|
|
|
path.map((childPath) => {
|
|
|
|
|
const node = childPath.getValue();
|
|
|
|
|
return {
|
|
|
|
|
node,
|
|
|
|
|
printed: print(),
|
|
|
|
|
loc: locStart(node),
|
|
|
|
|
};
|
|
|
|
|
}, field)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (fields.length > 1) {
|
|
|
|
|
propsAndLoc.sort((a, b) => a.loc - b.loc);
|
|
|
|
|
}
|
2020-11-19 08:59:25 +08:00
|
|
|
|
|
|
|
|
const parent = path.getParentNode(0);
|
|
|
|
|
const isFlowInterfaceLikeBody =
|
|
|
|
|
isTypeAnnotation &&
|
|
|
|
|
parent &&
|
|
|
|
|
(parent.type === "InterfaceDeclaration" ||
|
|
|
|
|
parent.type === "DeclareInterface" ||
|
|
|
|
|
parent.type === "DeclareClass") &&
|
|
|
|
|
path.getName() === "body";
|
|
|
|
|
const shouldBreak =
|
2021-03-11 04:14:08 +08:00
|
|
|
node.type === "TSInterfaceBody" ||
|
2020-11-19 08:59:25 +08:00
|
|
|
isFlowInterfaceLikeBody ||
|
2021-03-11 04:14:08 +08:00
|
|
|
(node.type === "ObjectPattern" &&
|
2020-11-19 08:59:25 +08:00
|
|
|
parent.type !== "FunctionDeclaration" &&
|
|
|
|
|
parent.type !== "FunctionExpression" &&
|
|
|
|
|
parent.type !== "ArrowFunctionExpression" &&
|
|
|
|
|
parent.type !== "ObjectMethod" &&
|
|
|
|
|
parent.type !== "ClassMethod" &&
|
|
|
|
|
parent.type !== "ClassPrivateMethod" &&
|
|
|
|
|
parent.type !== "AssignmentPattern" &&
|
|
|
|
|
parent.type !== "CatchClause" &&
|
2021-03-11 04:14:08 +08:00
|
|
|
node.properties.some(
|
2020-11-19 08:59:25 +08:00
|
|
|
(property) =>
|
|
|
|
|
property.value &&
|
|
|
|
|
(property.value.type === "ObjectPattern" ||
|
|
|
|
|
property.value.type === "ArrayPattern")
|
|
|
|
|
)) ||
|
2021-03-11 04:14:08 +08:00
|
|
|
(node.type !== "ObjectPattern" &&
|
2022-08-28 22:47:31 +03:00
|
|
|
propsAndLoc.length > 0 &&
|
2020-11-19 08:59:25 +08:00
|
|
|
hasNewlineInRange(
|
|
|
|
|
options.originalText,
|
2021-03-11 04:14:08 +08:00
|
|
|
locStart(node),
|
2022-08-28 22:47:31 +03:00
|
|
|
propsAndLoc[0].loc
|
2020-11-19 08:59:25 +08:00
|
|
|
));
|
|
|
|
|
|
|
|
|
|
const separator = isFlowInterfaceLikeBody
|
|
|
|
|
? ";"
|
2021-03-11 04:14:08 +08:00
|
|
|
: node.type === "TSInterfaceBody" || node.type === "TSTypeLiteral"
|
2020-11-19 08:59:25 +08:00
|
|
|
? ifBreak(semi, ";")
|
|
|
|
|
: ",";
|
2021-03-11 04:14:08 +08:00
|
|
|
const leftBrace =
|
|
|
|
|
node.type === "RecordExpression" ? "#{" : node.exact ? "{|" : "{";
|
|
|
|
|
const rightBrace = node.exact ? "|}" : "}";
|
2020-11-19 08:59:25 +08:00
|
|
|
|
2021-01-04 10:04:30 +08:00
|
|
|
/** @type {Doc[]} */
|
2020-11-19 08:59:25 +08:00
|
|
|
let separatorParts = [];
|
2021-04-12 05:20:27 +03:00
|
|
|
const props = propsAndLoc.map((prop) => {
|
|
|
|
|
const result = [...separatorParts, group(prop.printed)];
|
|
|
|
|
separatorParts = [separator, line];
|
|
|
|
|
if (
|
|
|
|
|
(prop.node.type === "TSPropertySignature" ||
|
|
|
|
|
prop.node.type === "TSMethodSignature" ||
|
|
|
|
|
prop.node.type === "TSConstructSignatureDeclaration") &&
|
|
|
|
|
hasComment(prop.node, CommentCheckFlags.PrettierIgnore)
|
|
|
|
|
) {
|
|
|
|
|
separatorParts.shift();
|
|
|
|
|
}
|
|
|
|
|
if (isNextLineEmpty(prop.node, options)) {
|
|
|
|
|
separatorParts.push(hardline);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
});
|
2020-11-19 08:59:25 +08:00
|
|
|
|
2021-03-11 04:14:08 +08:00
|
|
|
if (node.inexact) {
|
2020-11-19 08:59:25 +08:00
|
|
|
let printed;
|
2021-03-11 04:14:08 +08:00
|
|
|
if (hasComment(node, CommentCheckFlags.Dangling)) {
|
|
|
|
|
const hasLineComments = hasComment(node, CommentCheckFlags.Line);
|
2020-11-19 08:59:25 +08:00
|
|
|
const printedDanglingComments = printDanglingComments(
|
|
|
|
|
path,
|
|
|
|
|
options,
|
|
|
|
|
/* sameIndent */ true
|
|
|
|
|
);
|
2021-01-11 13:46:05 +08:00
|
|
|
printed = [
|
2020-11-19 08:59:25 +08:00
|
|
|
printedDanglingComments,
|
|
|
|
|
hasLineComments ||
|
2021-03-11 04:14:08 +08:00
|
|
|
hasNewline(options.originalText, locEnd(getLast(getComments(node))))
|
2020-11-19 08:59:25 +08:00
|
|
|
? hardline
|
|
|
|
|
: line,
|
|
|
|
|
"...",
|
2021-01-11 13:46:05 +08:00
|
|
|
];
|
2020-11-19 08:59:25 +08:00
|
|
|
} else {
|
2021-01-26 09:46:14 +08:00
|
|
|
printed = ["..."];
|
2020-11-19 08:59:25 +08:00
|
|
|
}
|
2021-01-26 09:46:14 +08:00
|
|
|
props.push([...separatorParts, ...printed]);
|
2020-11-19 08:59:25 +08:00
|
|
|
}
|
|
|
|
|
|
2022-08-28 22:47:31 +03:00
|
|
|
const lastElem = getLast(propsAndLoc)?.node;
|
2020-11-19 08:59:25 +08:00
|
|
|
|
|
|
|
|
const canHaveTrailingSeparator = !(
|
2021-03-11 04:14:08 +08:00
|
|
|
node.inexact ||
|
2020-11-19 08:59:25 +08:00
|
|
|
(lastElem &&
|
2022-08-28 22:47:31 +03:00
|
|
|
(lastElem.type === "RestElement" ||
|
|
|
|
|
((lastElem.type === "TSPropertySignature" ||
|
|
|
|
|
lastElem.type === "TSCallSignatureDeclaration" ||
|
|
|
|
|
lastElem.type === "TSMethodSignature" ||
|
|
|
|
|
lastElem.type === "TSConstructSignatureDeclaration") &&
|
|
|
|
|
hasComment(lastElem, CommentCheckFlags.PrettierIgnore))))
|
2020-11-19 08:59:25 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let content;
|
|
|
|
|
if (props.length === 0) {
|
2021-03-11 04:14:08 +08:00
|
|
|
if (!hasComment(node, CommentCheckFlags.Dangling)) {
|
2022-08-02 18:11:34 +08:00
|
|
|
return [leftBrace, rightBrace, printTypeAnnotation(path, options, print)];
|
2020-11-19 08:59:25 +08:00
|
|
|
}
|
|
|
|
|
|
2021-01-11 13:46:05 +08:00
|
|
|
content = group([
|
2020-11-19 08:59:25 +08:00
|
|
|
leftBrace,
|
2021-01-11 13:46:05 +08:00
|
|
|
printDanglingComments(path, options),
|
|
|
|
|
softline,
|
|
|
|
|
rightBrace,
|
|
|
|
|
printOptionalToken(path),
|
2022-08-02 18:11:34 +08:00
|
|
|
printTypeAnnotation(path, options, print),
|
2021-01-11 13:46:05 +08:00
|
|
|
]);
|
|
|
|
|
} else {
|
|
|
|
|
content = [
|
2021-03-11 04:14:08 +08:00
|
|
|
isFlowInterfaceLikeBody && isNonEmptyArray(node.properties)
|
2021-01-20 15:01:16 +09:00
|
|
|
? printHardlineAfterHeritage(parent)
|
|
|
|
|
: "",
|
2021-01-11 13:46:05 +08:00
|
|
|
leftBrace,
|
|
|
|
|
indent([options.bracketSpacing ? line : softline, ...props]),
|
2020-11-19 08:59:25 +08:00
|
|
|
ifBreak(
|
|
|
|
|
canHaveTrailingSeparator &&
|
|
|
|
|
(separator !== "," || shouldPrintComma(options))
|
|
|
|
|
? separator
|
|
|
|
|
: ""
|
|
|
|
|
),
|
2021-01-11 10:19:13 +08:00
|
|
|
options.bracketSpacing ? line : softline,
|
|
|
|
|
rightBrace,
|
2020-11-19 08:59:25 +08:00
|
|
|
printOptionalToken(path),
|
2022-08-02 18:11:34 +08:00
|
|
|
printTypeAnnotation(path, options, print),
|
2021-01-11 13:46:05 +08:00
|
|
|
];
|
2020-11-19 08:59:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we inline the object as first argument of the parent, we don't want
|
|
|
|
|
// to create another group so that the object breaks before the return
|
|
|
|
|
// type
|
|
|
|
|
if (
|
|
|
|
|
path.match(
|
|
|
|
|
(node) => node.type === "ObjectPattern" && !node.decorators,
|
|
|
|
|
(node, name, number) =>
|
|
|
|
|
shouldHugFunctionParameters(node) &&
|
|
|
|
|
(name === "params" ||
|
|
|
|
|
name === "parameters" ||
|
|
|
|
|
name === "this" ||
|
|
|
|
|
name === "rest") &&
|
|
|
|
|
number === 0
|
|
|
|
|
) ||
|
|
|
|
|
path.match(
|
|
|
|
|
shouldHugType,
|
|
|
|
|
(node, name) => name === "typeAnnotation",
|
|
|
|
|
(node, name) => name === "typeAnnotation",
|
|
|
|
|
(node, name, number) =>
|
|
|
|
|
shouldHugFunctionParameters(node) &&
|
|
|
|
|
(name === "params" ||
|
|
|
|
|
name === "parameters" ||
|
|
|
|
|
name === "this" ||
|
|
|
|
|
name === "rest") &&
|
|
|
|
|
number === 0
|
2021-04-06 12:59:14 +03:00
|
|
|
) ||
|
|
|
|
|
// Assignment printing logic (printAssignment) is responsible
|
|
|
|
|
// for adding a group if needed
|
|
|
|
|
(!shouldBreak &&
|
|
|
|
|
path.match(
|
|
|
|
|
(node) => node.type === "ObjectPattern",
|
|
|
|
|
(node) =>
|
|
|
|
|
node.type === "AssignmentExpression" ||
|
|
|
|
|
node.type === "VariableDeclarator"
|
|
|
|
|
))
|
2020-11-19 08:59:25 +08:00
|
|
|
) {
|
|
|
|
|
return content;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return group(content, { shouldBreak });
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-21 15:53:02 +08:00
|
|
|
export { printObject };
|