prettier-plugin-rust
Version:
Prettier plugin for Rust
1,403 lines (1,396 loc) • 155 kB
JavaScript
import { DelimKind, rs, NodeType, TK, PRCD } from 'jinx-rust';
import { start, end, insertNodes, is_BlockCommentKind, is_Snippet, is_Program, each_childNode, is_ExpressionStatement, is_FlowControlExpression, is_ReassignmentNode, reassignNodeProperty, is_ClosureFunctionExpression, is_BlockExpression, is_ExpressionWithBodyOrCases, is_IfBlockExpression, transferAttributes, hasTypeBounds, is_TypeDynBounds, is_TypeImplBounds, unsafe_set_nodeType, is_TypeTraitBound, is_TypeBoundsStandaloneNode, hasAttributes, is_DocCommentAttribute, insertNode, getBodyOrCases, deleteAttributes, is_NodeWithBodyOrCases, is_AttributeOrDocComment, ownStart, is_Attribute, is_StructLiteralProperty, is_Comment, is_MissingNode, is_PunctuationToken, is_MacroInvocation, is_CallExpression, getMacroName, hasMethod, includesTK, is_BareTypeTraitBound, getNodeChildren, is_NodeWithBodyNoBody, is_StructLiteralPropertySpread, nisAnyOf, hasOuterAttributes, is_FunctionDeclaration, is_StatementNode, is_FunctionNode, getLastParameter, is_MacroRule, is_LocArray, is_LineCommentNode, is_BlockCommentNode, is_UnionPattern, is_ExpressionAsTypeCast, is_FlowControlMaybeValueExpression, is_ExpressionWithBodyOrCases_or_BlockLikeMacroInvocation, is_MemberExpression, is_ElseBlock, is_NodeWithMaybePatternNoUnionBody, is_UnaryExpression, is_ReturnExpression, is_YieldExpression, can_have_OuterAttributes, is_Identifier, is_Literal, is_LiteralNumberLike, is_StructLiteral, is_ParenthesizedNode, is_RangeLiteral, is_LogicalExpression, is_PostfixExpression, is_OperationExpression, is_ComparisonExpression, is_LetScrutinee, is_TypeFunctionNode, is_UnaryType, is_PatternVariableDeclaration, is_BitwiseOperator, is_EqualityOperator, getPrecedence, is_multiplicativeOperator, is_bitshiftOperator, getAstPath, is_MatchExpressionCase, is_EnumMemberDeclaration, is_StructPropertyDeclaration, is_StructPatternProperty, is_LineCommentKind, is_CommentOrDocComment, is_ExternSpecifier, hasSuffix, getDelimChars, is_ArrayOrTupleLiteral, is_Node, is_MatchExpression, is_SourceFile, is_MacroGroup, is_DelimGroup, is_MacroParameterDeclaration, is_MacroInlineRuleDeclaration, is_ExpressionPath, is_ReassignmentExpression, is_GenericParameterDeclaration, is_TypeCallNamedArgument, is_VariableDeclarationNode, is_LiteralStringLike, is_UnwrapExpression, is_IdentifierOrIndex, is_ExpressionTypeCast, hasSemiNoBody, is_OrExpression, is_ImplDeclarationNode, is_TupleStructDeclaration, hasParameters, hasSelfParameter, is_ClosureBlock, hasCondition, is_TupleNode, hasProperties, hasItems, is_TupleLiteral, is_TuplePattern, is_RangePattern, is_RestPattern, is_TypeTuple, hasSemiNoProperties, is_StructPattern, is_UnionDeclaration, is_StructDeclaration, is_EnumMemberStructDeclaration, getParameters, is_FunctionParameterDeclaration, isInner, is_FunctionSpread, isTK, hasLetScrutineeCondition, is_ImplicitReturnAbleNode, is_ExpressionWithBody, is_ForInBlockExpression, is_LoopBlockExpression, is_WhileBlockExpression, hasBody, is_MinusExpression, is_StructPatternPropertyDestructured, is_StructProperty, is_LiteralBooleanLike, getOwnChildAstPath } from 'jinx-rust/utils';
import doc from 'prettier/doc.js';
// src/format/plugin.ts
// src/utils/debug.ts
var cwd = typeof process === "object" && typeof (process == null ? void 0 : process.cwd) === "function" ? /* @__PURE__ */ normPath(/* @__PURE__ */ process.cwd() ?? "") : "";
function normPath_strip_cwd(filepath) {
let normFilePath = normPath(filepath);
return normFilePath.startsWith(cwd) ? normFilePath.slice(cwd.length + 1) : normFilePath;
}
var StackLine = class {
constructor(raw) {
({
1: this.callee = "",
2: this.filepath = "",
3: this.line = "",
4: this.col = "",
5: this.other = ""
} = (this.raw = raw).match(/at (?:(.+?)\s+\()?(?:(.+?):([0-9]+)(?::([0-9]+))?|([^)]+))\)?/) ?? ["", "", "", "", "", ""]);
this.url = this.filepath ? normPath_strip_cwd(this.filepath) + (this.line && this.col && `:${this.line}:${this.col}`) : this.other === "native" ? "<native>" : "";
}
};
function getPrintWidth() {
return clamp(0, getTerminalWidth(128), 200) - 4;
}
var StackItem = class extends StackLine {
constructor(stack, i, raw) {
super(raw);
this.stack = stack;
this.i = i;
this.hidden = false;
}
hide() {
this.hidden = true;
return this;
}
hideNext(n) {
var _a;
for (let i = 0; i < n; i++)
(_a = this.at(i)) == null ? void 0 : _a.hide();
}
hideWhileTrue(test) {
let line2 = this;
while (line2 && test(line2))
line2 = line2.hide().next();
}
at(relIndex) {
return this.i + relIndex >= this.stack.length || this.i + relIndex < 0 ? void 0 : this.stack[this.i + relIndex];
}
next() {
return this.at(1);
}
toString() {
var _a, _b, _c, _d;
const url = this.url;
const calleeColor = ((_b = (_a = this.stack.style) == null ? void 0 : _a.callee) == null ? void 0 : _b.call(_a, this.callee, this)) ?? color.cyan;
const urlColor = ((_d = (_c = this.stack.style) == null ? void 0 : _c.url) == null ? void 0 : _d.call(_c, url, this)) ?? color.grey;
return compose2Cols(" at " + calleeColor(this.callee), urlColor(url), getPrintWidth());
}
};
function createStack(message, Error_stack, style) {
for (var STACK = [], i = 0, stack = Error_stack.split("\n").slice(2); i < stack.length; i++)
STACK[i] = new StackItem(STACK, i, stack[i]);
return STACK.message = message, STACK.style = style, STACK;
}
function composeStack(stack) {
var hidden = 0;
var str = stack.message;
for (var item of stack)
item.hidden ? ++hidden : str += "\n" + item.toString();
return str + (hidden > 0 ? "\n" + color.grey(compose2Cols("", `...filtered ${hidden} lines`, getPrintWidth())) : "");
}
function createCustomError({
message = "Unknown Error",
editStack = (stack) => {
},
style = void 0,
stackTraceLimit = 20
}) {
const _stackTraceLimit = Error.stackTraceLimit;
const _prepareStackTrace = Error.prepareStackTrace;
Error.stackTraceLimit = stackTraceLimit;
const _ctx = {};
Error.captureStackTrace(_ctx, createCustomError);
const stack = createStack(message, _ctx.stack, style);
Error.prepareStackTrace = function(err2, calls) {
editStack(stack);
return composeStack(stack);
};
const err = new Error(message);
err.stack = err.stack;
Error.stackTraceLimit = _stackTraceLimit;
Error.prepareStackTrace = _prepareStackTrace;
return err;
}
function compose2Cols(left, right, len = 64, min = 1) {
return left + " ".repeat(clamp(min, len, len - (color.unstyledLength(left) + color.unstyledLength(right)))) + right;
}
function exit(message, ...ctx2) {
if (ctx2.length > 0)
console.log("Error context:", { ...ctx2 });
throw createCustomError({ message });
}
exit.never = function never(...ctx2) {
exit("Reached unreachable code", ...ctx2);
};
function assert(predicate, err, ...ctx2) {
if (false === predicate)
exit(err ?? "Assertion failed", ...ctx2);
}
function Identity(v) {
return v;
}
function last_of(arr) {
return arr[arr.length - 1];
}
function normPath(filepath) {
return filepath.replace(/^file:\/\/\//, "").replace(/\\\\?/g, "/");
}
function binarySearchIn(array, target, toValue) {
if (isEmpty(array))
return -1;
let i = 0;
let low = 0;
let high = array.length - 1;
let value = toValue(array[high]);
if (target >= value)
return high;
else
high--;
while (low <= high) {
i = low + (high - low >> 1);
value = toValue(array[i]);
if (target === value)
return i;
if (target > value)
low = i + 1;
else
high = i - 1;
}
return low - 1;
}
function getTerminalWidth(fallbackWidth = 200) {
var _a, _b;
return ((_b = (_a = globalThis == null ? void 0 : globalThis.process) == null ? void 0 : _a.stdout) == null ? void 0 : _b.columns) ?? fallbackWidth;
}
var isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined";
var color = ((cfn, mfn) => ({
black: cfn(30),
red: cfn(31),
green: cfn(32),
yellow: cfn(33),
blue: cfn(34),
magenta: cfn(35),
cyan: cfn(36),
white: cfn(37),
grey: cfn(90),
bold: mfn(1, 22),
italic: mfn(3, 23),
underline: mfn(4, 24),
hidden: mfn(8, 28),
hiddenCursor: (str) => `\x1B[?25l${str}\x1B[?25h`,
unstyle: (str) => str.replace(/\x1B\[[0-9][0-9]?m/g, ""),
unstyledLength: (str) => str.replace(/\x1B\[[0-9][0-9]?m/g, "").length,
link: (str) => color.underline(color.blue(str))
}))(
(c1) => isBrowser ? Identity : (str) => `\x1B[${c1}m${str.replace(/\x1B\[39m/g, `\x1B[${c1}m`)}\x1B[39m`,
(c1, c2) => isBrowser ? Identity : (str) => `\x1B[${c1}m${str}\x1B[${c2}m`
);
function Map_get(map, key, init) {
if (!map.has(key))
map.set(key, init(key));
return map.get(key);
}
function isEmpty(array) {
return 0 === array.length;
}
function Array_splice(array, target, index = array.indexOf(target)) {
array.splice(index, 1);
}
function Array_replace(array, target, ...replacements) {
array.indexOf(target);
array.splice(array.indexOf(target), 1, ...replacements);
}
function has_key_defined(o, k) {
return k in o && void 0 !== o[k];
}
function is_array(data) {
return Array.isArray(data);
}
function each(data, callback) {
switch (data.constructor) {
case Array: {
let i = 0;
for (; i < data.length; i++)
callback(data[i], i);
return;
}
case Object: {
let k;
for (k in data)
callback(data[k], k);
return;
}
case Set: {
let d;
for (d of data)
callback(d, void 0);
return;
}
case Map: {
let e;
for (e of data)
callback(e[1], e[0]);
return;
}
default: {
let x;
for (x of data)
callback(x, void 0);
return;
}
}
}
function iLast(index, array) {
return 1 + index === array.length;
}
function try_eval(fn) {
try {
return fn();
} catch (e) {
return void 0;
}
}
function clamp(min, max, value) {
return value > min ? value < max ? value : max : min;
}
function flat(arr) {
return arr.flat(Infinity);
}
function map_tagged_template(args, map) {
const arr = [args[0][0]];
for (var i = 1; i < args.length; i++)
arr.push(map(args[i]), args[0][i]);
return arr;
}
function spliceAll(array) {
const r = [...array];
array.length = 0;
return r;
}
function spread(fn) {
return [...fn()];
}
var {
join,
line,
softline,
hardline,
literalline,
group,
conditionalGroup,
fill,
lineSuffix,
lineSuffixBoundary,
cursor,
breakParent,
ifBreak,
trim,
indent,
indentIfBreak,
align,
addAlignmentToDoc,
markAsRoot,
dedentToRoot,
dedent,
hardlineWithoutBreakParent,
literallineWithoutBreakParent,
label
} = doc.builders;
var {
isConcat,
getDocParts,
willBreak,
traverseDoc,
findInDoc,
mapDoc,
propagateBreaks,
removeLines,
stripTrailingHardline,
normalizeParts,
normalizeDoc,
cleanDoc,
canBreak
} = doc.utils;
var Symbol_comments = Symbol.for("comments");
var DCM = /* @__PURE__ */ ((DCM2) => {
DCM2["arguments"] = "arguments";
DCM2["parameters"] = "parameters";
DCM2["items"] = "items";
DCM2["properties"] = "properties";
DCM2["members"] = "members";
DCM2["body"] = "body";
DCM2["cases"] = "cases";
DCM2["typeArguments"] = "typeArguments";
DCM2["ltParameters"] = "ltParameters";
DCM2["generics"] = "generics";
DCM2["specifiers"] = "specifiers";
DCM2["rules"] = "rules";
DCM2["match"] = "match";
DCM2["transform"] = "transform";
DCM2["segments"] = "segments";
return DCM2;
})(DCM || {});
// src/format/complexity.ts
var DEPTH = 0;
var ANCESTRY = [];
var LONE_SHORT_ARGUMENT_THRESHOLD_RATE = 0.25;
function withCheckContext(fn) {
if (0 === DEPTH) {
return fn();
} else {
DEPTH = 0;
const prev = spliceAll(ANCESTRY);
try {
return fn();
} finally {
DEPTH = ANCESTRY.push(...prev);
}
}
}
function is_short(str) {
return str.length <= LONE_SHORT_ARGUMENT_THRESHOLD_RATE * getOptions().printWidth;
}
function print(target) {
const current = getNode();
const keys = [...getAstPath(ANCESTRY[0], getNode())];
for (let i = 1; i < ANCESTRY.length; i++)
keys.push(...getOwnChildAstPath(ANCESTRY[i - 1], ANCESTRY[i]));
keys.push(...getOwnChildAstPath(last_of(ANCESTRY), target));
try {
return getContext().path.call(() => getPrintFn()(), ...keys);
} catch (e) {
console.log({ current, target, keys, ANCESTRY });
throw e;
}
}
function IsSimpleFunction(fn) {
return function(node) {
if (0 !== DEPTH && node === ANCESTRY[DEPTH - 1]) {
return fn(node);
}
if (DEPTH >= 2) {
return isShortBasic(node);
}
try {
return fn(ANCESTRY[DEPTH++] = node);
} finally {
ANCESTRY.length = --DEPTH;
}
};
}
function HasComplexFunction(fn) {
return function(node) {
if (0 !== DEPTH && node === ANCESTRY[DEPTH - 1]) {
return fn(node);
}
if (DEPTH >= 2) {
return !isShortBasic(node);
}
try {
return fn(ANCESTRY[DEPTH++] = node);
} finally {
ANCESTRY.length = --DEPTH;
}
};
}
var isShortBasic = (node) => {
switch (node.nodeType) {
case NodeType.MissingNode:
return true;
case NodeType.Identifier:
case NodeType.Index:
case NodeType.LtIdentifier:
case NodeType.LbIdentifier:
case NodeType.McIdentifier:
return is_short(node.name);
case NodeType.Literal:
return is_short(node.value) && !/\n/.test(node.value);
}
return false;
};
var isSimpleType = IsSimpleFunction((node) => {
switch (node.nodeType) {
case NodeType.MissingNode:
case NodeType.FunctionSpread:
return true;
case NodeType.MacroInvocation:
return false;
case NodeType.Identifier:
case NodeType.TypeNever:
case NodeType.TypeInferred:
return true;
case NodeType.TypePath:
return isShortBasic(node.segment) && (!node.namespace || isSimpleType(node.namespace));
case NodeType.TypeCall:
return isSimpleType(node.typeCallee) && !hasComplexTypeArguments(node);
case NodeType.ExpressionTypeSelector:
return isSimpleType(node.typeTarget) && (!node.typeExpression || isSimpleType(node.typeExpression));
case NodeType.TypeDynBounds:
return !hasComplexTypeBounds(node);
case NodeType.TypeImplBounds:
return !hasComplexTypeBounds(node);
case NodeType.TypeFnPointer: {
const param = node.parameters[0];
return (!node.extern || !node.extern.abi || isShortBasic(node.extern.abi)) && !hasComplexLtParameters(node) && (node.parameters.length === 0 || node.parameters.length === 1 && (is_FunctionSpread(param) || !is_TypeFunctionNode(param.typeAnnotation) && isSimpleType(param.typeAnnotation))) && (!node.returnType || isSimpleType(node.returnType));
}
case NodeType.TypeFunction:
return isSimpleType(node.callee) && node.parameters.every(isSimpleType) && (!node.returnType || isSimpleType(node.returnType));
case NodeType.TypeSizedArray:
return isSimpleType(node.typeExpression) && isShortBasic(node.sizeExpression);
case NodeType.TypeSlice:
return isSimpleType(node.typeExpression);
case NodeType.TypeTuple:
return node.items.length === 0 || node.items.length === 1 && isSimpleType(node.items[0]);
case NodeType.TypeReference:
case NodeType.TypeDereferenceMut:
case NodeType.TypeDereferenceConst:
case NodeType.TypeParenthesized:
return isSimpleType(node.typeExpression);
default:
return false;
}
});
var hasComplexTypeBounds = HasComplexFunction((node) => {
return !!node.typeBounds && node.typeBounds.length > 1 && !node.typeBounds.every(isSimpleTypeBound);
});
var isSimpleTypeBound = (node) => {
switch (node.nodeType) {
case NodeType.TypeParenthesized:
return isSimpleTypeBound(node.typeExpression);
case NodeType.LtIdentifier:
case NodeType.LtElided:
case NodeType.LtStatic:
return true;
case NodeType.TypeTraitBound:
return is_BareTypeTraitBound(node) && isSimpleTypeNamespaceTargetNoSelector(node.typeExpression);
default:
return false;
}
function isSimpleTypeNamespaceTargetNoSelector(node2) {
switch (node2.nodeType) {
case NodeType.Identifier:
return true;
case NodeType.TypePath:
return void 0 === node2.namespace || isSimpleTypeNamespaceTargetNoSelector(node2.namespace);
case NodeType.TypeCall:
return false;
case NodeType.TypeFunction:
return isSimpleTypeNamespaceTargetNoSelector(node2.callee) && node2.parameters.length === 0 && !node2.returnType;
default:
return false;
}
}
};
var hasComplexTypeArguments = HasComplexFunction(
(node) => !node.typeArguments || node.typeArguments.length === 0 ? false : node.typeArguments.length === 1 ? (() => {
const arg = node.typeArguments[0];
return is_TypeBoundsStandaloneNode(arg) || canBreak(print(arg));
})() : true
);
var hasComplexLtParameters = HasComplexFunction((node) => {
const ltParameters = node.ltParameters;
if (!ltParameters || ltParameters.length === 0) {
return false;
}
if (ltParameters.length === 1) {
const arg = ltParameters[0];
if (arg.ltBounds && arg.ltBounds.length > 1) {
return true;
}
return false;
}
return true;
});
var isShortGenericParameterDeclaration = IsSimpleFunction((node) => {
switch (node.nodeType) {
case NodeType.GenericTypeParameterDeclaration:
return !node.typeBounds && !node.typeDefault;
case NodeType.ConstTypeParameterDeclaration:
return (!node.typeAnnotation || is_MissingNode(node)) && !node.typeDefault;
case NodeType.GenericLtParameterDeclaration:
return !node.ltBounds;
default:
exit.never();
}
});
var hasComplexGenerics = HasComplexFunction((node) => {
return has_key_defined(node, "generics") && node.generics.length > 0 && !node.generics.every(isShortGenericParameterDeclaration);
});
var hasComplexTypeAnnotation = HasComplexFunction((node) => {
if (is_VariableDeclarationNode(node) && !is_LetScrutinee(node)) {
const { typeAnnotation } = node;
return !!typeAnnotation && !is_MissingNode(typeAnnotation) && !isSimpleType(typeAnnotation);
} else {
return false;
}
});
function isIdent(node, name) {
return !!node && is_Identifier(node) && node.name === name;
}
function isToken(node, tk) {
return !!node && isTK(node, tk);
}
function isGroup(node, dk) {
return !!node && is_DelimGroup(node) && node.segments.dk === dk;
}
// src/format/macros/cfg_if.ts
function transform_macro_cfg_if(segments) {
const danglingAttributes = [];
const comments = [];
const block = function create_if_block(i) {
if (i >= segments.length)
return void 0;
const _if = segments[i];
const pound = segments[i + 1];
const grp = segments[i + 2];
const block2 = segments[i + 3];
const _else = segments[i + 4];
assert(
isIdent(_if, "if") && isToken(pound, TK["#"]) && isGroup(grp, DelimKind["[]"]) && isGroup(block2, DelimKind["{}"]) && (!_else || isIdent(_else, "else"))
);
return create_block(
block2,
(body) => rs.mockNode(NodeType.IfBlockExpression, block2.loc.cloneFrom(start(_if)), {
label: void 0,
condition: rs.mockNode(NodeType.Attribute, grp.loc.cloneFrom(start(pound)), {
segments: grp.segments,
value: grp.segments.loc.sliceText(),
line: false,
inner: false
}),
body,
else: (_else && iLast(i + 5, segments) ? function create_else_block(i2) {
const block3 = segments[i2];
assert(isGroup(block3, DelimKind["{}"]));
return create_block(
block3,
(body2) => rs.mockNode(NodeType.BlockExpression, body2.loc.clone(), {
label: void 0,
body: body2
})
);
} : create_if_block)(i + 5)
})
);
}(0);
const ast = rs.createLocArray(
segments.dk,
segments.loc,
block && [
rs.mockNode(NodeType.ExpressionStatement, block.loc.clone(), {
expression: block,
semi: false
})
]
);
return rs.mockNode(NodeType.Snippet, segments.loc.clone(), { ast, danglingAttributes, comments });
function create_block(group2, fn) {
const snippet = rs.toBlockBody(group2.segments);
insertNodes(danglingAttributes, snippet.danglingAttributes);
insertNodes(comments, snippet.comments);
const block2 = fn(snippet.ast);
transferAttributes(snippet, block2);
return block2;
}
}
// src/format/transform.ts
function is_CallLikeMacroInvocation(node) {
return is_MacroInvocation(node) && "arguments" in node;
}
function is_BlockLikeMacroInvocation(node) {
return is_MacroInvocation(node) && "body" in node;
}
function is_CallExpression_or_CallLikeMacroInvocation(node) {
return is_CallExpression(node) || is_CallLikeMacroInvocation(node);
}
var IGNORED_MACROS = /* @__PURE__ */ new Set([
"quote"
]);
var HARDCODED_MACRO_DELIMS = /* @__PURE__ */ new Map();
each(
{
[DelimKind["{}"]]: [
"thread_local",
"cfg_if"
],
[DelimKind["()"]]: [
"assert_eq",
"assert_ne",
"assert",
"cfg",
"concat_bytes",
"concat_idents",
"concat",
"debug_assert_eq",
"debug_assert_ne",
"debug_assert",
"eprint",
"eprintln",
"format_args_nl",
"format_args",
"format",
"matches",
"panic",
"print",
"println",
"try",
"unimplemented",
"unreachable",
"write",
"writeln"
],
[DelimKind["[]"]]: [
"vec"
]
},
(names, tk) => each(names, (name) => {
HARDCODED_MACRO_DELIMS.set(name, +tk);
})
);
var _COMMENTS = void 0;
var _DANGLING_ATTRIBUTES = void 0;
function transform_ast(options2) {
try {
_COMMENTS = options2.comments;
_DANGLING_ATTRIBUTES = options2.danglingAttributes;
transformNode(options2.rsParsedFile);
} finally {
_depth = 0;
_COMMENTS = void 0;
_DANGLING_ATTRIBUTES = void 0;
}
}
var _depth = 0;
var isReadingSnippet = () => 0 !== _depth;
function maybe_transform_node(node, read_snippet, fn) {
const snippet = try_eval(read_snippet);
if (snippet) {
++_depth;
transformNode(snippet);
--_depth;
fn(node, snippet);
transformed.add(node);
return node;
}
}
var transformed = /* @__PURE__ */ new WeakSet();
function isTransformed(node) {
return transformed.has(node);
}
var transform = {
[NodeType.Attribute](node) {
maybe_transform_node(
node,
() => rs.toCallExpressionArguments(node.segments),
(node2, snippet) => {
node2.segments = snippet.ast;
}
);
},
[NodeType.MacroInlineRuleDeclaration](node) {
node.match.dk = DelimKind["()"];
node.transform.dk = DelimKind["{}"];
},
[NodeType.MacroInvocation](node) {
const name = getMacroName(node);
if (IGNORED_MACROS.has(name) || node.segments.length === 0 || node.segments.length === 1 && is_PunctuationToken(node.segments[0])) {
return;
}
const tk = transformMacroDelim(name, node);
if (name === "cfg_if") {
transformBlockLike(() => transform_macro_cfg_if(node.segments));
} else if (tk === DelimKind["{}"]) {
transformBlockLike();
} else {
transformCallLike();
}
function transformBlockLike(transform2 = () => rs.toBlockBody(node.segments)) {
return maybe_transform_node(node, transform2, (node2, snippet) => {
const _body = snippet.ast;
_body.dk = tk;
node2.body = _body;
node2.segments = _body;
transferAttributes(snippet, node2);
});
}
function transformCallLike() {
return maybe_transform_node(
node,
() => rs.toCallExpressionArguments(node.segments),
(node2, snippet) => {
const _arguments = snippet.ast;
_arguments.dk = tk;
node2.method = void 0;
node2.typeArguments = void 0;
node2.arguments = _arguments;
node2.segments = _arguments;
}
);
}
},
[NodeType.CallExpression](node) {
if (hasMethod(node)) {
node.callee = rs.mockNode(NodeType.MemberExpression, node.method.loc.cloneFrom(start(node.callee)), {
expression: node.callee,
property: node.method,
computed: false
});
node.method = void 0;
getOptions().actuallyMethodNodes.add(node.callee);
}
},
[NodeType.AutoTraitDeclaration](node) {
mockBodyNoBody(node);
},
[NodeType.NegativeImplDeclaration](node) {
mockBodyNoBody(node);
},
[NodeType.StructLiteral](node) {
moveSpreadsToEnd(node);
},
[NodeType.StructPattern](node) {
moveSpreadsToEnd(node);
}
};
function moveSpreadsToEnd(node) {
const props = node.properties;
if (props.some((p, i, a) => is_StructSpread(p) && !iLast(i, a))) {
const spreads = [];
for (let i = 0; i < props.length; i++) {
const prop = props[i];
if (is_StructSpread(prop)) {
Array_splice(props, prop, i--);
spreads.push(prop);
}
}
props.push(...spreads);
}
}
function mockBodyNoBody(node) {
node.body = rs.createLocArray(last_of(rs.toTokens(node).ast).loc.clone(), DelimKind["{}"]);
}
function transformMacroDelim(name, node) {
if (HARDCODED_MACRO_DELIMS.has(name)) {
return HARDCODED_MACRO_DELIMS.get(name);
}
if (node.segments.dk === DelimKind["{}"] && includesTK(node, TK[","])) {
return DelimKind["()"];
}
if (node.segments.dk === DelimKind["()"] && includesTK(node, TK[";"])) {
return DelimKind["{}"];
}
return node.segments.dk;
}
var seen = /* @__PURE__ */ new WeakSet();
function transformNode(node, parent, key, index) {
var _a;
if (!seen.has(node)) {
seen.add(node);
if (is_Snippet(node) || is_Program(node)) {
registerPogramLike(node);
}
each_childNode(node, transformNode);
insert_blocks(node, parent, key, index);
(_a = transform[node.nodeType]) == null ? void 0 : _a.call(transform, node);
flatten_typeBounds(node);
transform_nodeAttributes(node);
}
return node;
}
function insert_blocks(node, parent, key, index) {
if (parent && key) {
if (!is_ExpressionStatement(parent) && (is_FlowControlExpression(node) || !isReadingSnippet() && is_ReassignmentNode(node) && !(is_ReassignmentNode(parent) && parent.left === node))) {
reassignNodeProperty(blockify(node), parent, key, index);
} else if (is_ClosureFunctionExpression(node) && (!!node.returnType && !is_BlockExpression(node.expression) || is_ExpressionWithBodyOrCases(node.expression) && !is_BlockExpression(node.expression) && !is_IfBlockExpression(node.expression))) {
node.expression = blockify(node.expression);
}
}
function blockify(node2) {
const block = rs.mockNode(NodeType.BlockExpression, node2.loc.clone(), {
label: void 0,
body: rs.createLocArray(DelimKind["{}"], node2.loc.clone(), [
rs.mockNode(NodeType.ExpressionStatement, node2.loc.clone(), { semi: false, expression: node2 })
])
});
transferAttributes(node2, block);
return block;
}
}
function flatten_typeBounds(topNode) {
if (hasTypeBounds(topNode)) {
const nestedBounds = topNode.typeBounds.filter(isBoundWithNestedBounds);
const [first, ...subsequent] = nestedBounds;
const flatten = (bound) => Array_replace(topNode.typeBounds, bound, ...bound.typeExpression.typeBounds);
if (nestedBounds.every(isBareBoundWithNestedBoundsNoPrefix)) {
each(nestedBounds, flatten);
} else if (!hasDefinedPrefix(topNode) && first === topNode.typeBounds[0] && !isBareBoundWithNestedBoundsNoPrefix(first) && subsequent.every(isBareBoundWithNestedBoundsNoPrefix)) {
if (is_TypeDynBounds(topNode)) {
if (is_TypeImplBounds(first.typeExpression)) {
unsafe_set_nodeType(topNode, NodeType.TypeImplBounds);
} else {
topNode.dyn = true;
}
each(nestedBounds, flatten);
} else {
each(subsequent, flatten);
first.typeExpression.typeBounds.push(...topNode.typeBounds.slice(1));
topNode.typeBounds.length = 1;
}
}
}
function isBoundWithNestedBounds(bound) {
return is_TypeTraitBound(bound) && is_TypeBoundsStandaloneNode(bound.typeExpression);
}
function isBareBoundWithNestedBounds(bound) {
return isBoundWithNestedBounds(bound) && is_BareTypeTraitBound(bound);
}
function isBareBoundWithNestedBoundsNoPrefix(bound) {
return isBareBoundWithNestedBounds(bound) && !hasDefinedPrefix(bound.typeExpression);
}
function hasDefinedPrefix(node) {
return is_TypeDynBounds(node) && node.dyn || is_TypeImplBounds(node);
}
}
function transform_nodeAttributes(node) {
if (hasAttributes(node)) {
const attrs = node.attributes;
for (let i = 0; i < attrs.length; i++) {
const attr = attrs[i];
if (isReadingSnippet() && is_DocCommentAttribute(attr)) {
const index = binarySearchIn(_COMMENTS, start(attr), start);
_COMMENTS.splice(index, 1);
}
if (attr.inner) {
if (isPrettierIgnoreAttribute(attr)) {
setPrettierIgnoreTarget(is_Program(node) ? node.loc.src : node, attr);
}
insertNode(is_Snippet(node) ? node.ast : getBodyOrCases(node), attr);
Array_splice(attrs, attr, i--);
}
}
if (attrs.length === 0) {
deleteAttributes(node);
}
}
}
function registerPogramLike(program) {
const comments = spliceAll(program.comments);
const danglingAttributes = spliceAll(program.danglingAttributes);
for (let i = 0; i < danglingAttributes.length; i++) {
const attr = danglingAttributes[i];
if (is_DocCommentAttribute(attr)) {
if (isReadingSnippet()) {
const index = binarySearchIn(_COMMENTS, start(attr), start);
_COMMENTS.splice(index, 1);
}
} else {
transformNode(danglingAttributes[i], program, "danglingAttributes", i);
}
}
if (!isReadingSnippet())
insertNodes(_COMMENTS, comments);
insertNodes(_DANGLING_ATTRIBUTES, danglingAttributes);
}
var CommentChildNodes = /* @__PURE__ */ new WeakMap();
function getCommentChildNodes(n) {
const children = Map_get(CommentChildNodes, n, getTransformedNodeChildren);
if (is_NodeWithBodyOrCases(n) || is_BlockLikeMacroInvocation(n)) {
for (let i = 0; i < children.length; i++) {
const attr = children[i];
if (is_AttributeOrDocComment(attr)) {
const target = children.find((n2) => start(n2) <= start(attr) && ownStart(n2) >= end(attr));
if (target) {
children.splice(i--, 1);
insertNode(Map_get(CommentChildNodes, target, getTransformedNodeChildren), attr);
}
}
}
}
return children;
function getTransformedNodeChildren(node) {
if (is_Program(node))
node.comments ?? (node.comments = []);
const children2 = getNodeChildren(node);
if (is_NodeWithBodyNoBody(node)) {
insertNodes(children2, node.body);
}
return children2;
}
}
// src/format/styling.ts
function needsOuterSoftbreakParens(node) {
const parent = getParentNode();
if (!parent)
return false;
if (is_ExpressionAsTypeCast(node)) {
return precedenceNeedsParens(node, parent);
}
if (is_FlowControlMaybeValueExpression(parent) && parent.expression === node && flowControlExpressionNeedsOuterParens(parent)) {
return true;
}
if (is_ExpressionWithBodyOrCases_or_BlockLikeMacroInvocation(node) && (is_MemberExpression(parent) && parent.expression === node || is_ExpressionWithBodyOrCases_or_BlockLikeMacroInvocation(parent) && !is_ElseBlock(node, parent))) {
return true;
}
if (is_UnionPattern(node) && is_NodeWithMaybePatternNoUnionBody(parent)) {
return true;
}
if (hasComment(node)) {
if (is_UnaryExpression(parent)) {
return true;
}
if (hasComment(node, 32 /* Line */)) {
if (is_ReturnExpression(parent) || is_YieldExpression(parent) && parent.expression === node) {
return true;
}
}
if (hasComment(node, 2 /* Leading */, (comment) => is_Attribute(comment) && !comment.inner) && !can_have_OuterAttributes(node, parent, true)) {
return true;
}
}
return false;
}
function needsInnerParens(node) {
if (needsOuterSoftbreakParens(node)) {
return false;
}
const parent = getParentNode();
if (!parent) {
return false;
}
if (is_Identifier(node)) {
return false;
}
if (is_Literal(node)) {
return is_LiteralNumberLike(node) && is_MemberExpression(parent) && node === parent.expression;
}
if (is_CallExpression(parent) && parent.callee === node && is_MemberExpression(node)) {
return !getOptions().actuallyMethodNodes.has(node);
}
if (is_ReassignmentNode(node)) {
if (is_printing_macro()) {
return false;
}
if (is_ClosureFunctionExpression(parent) && node === parent.expression) {
return true;
}
if (is_ExpressionStatement(parent)) {
return is_StructLiteral(node.left);
}
if (is_ReassignmentNode(parent)) {
return false;
}
return true;
}
if (is_ParenthesizedNode(parent)) {
return false;
}
if (is_ExpressionStatement(parent)) {
return false;
}
if (is_RangeLiteral(node)) {
return is_ExpressionAsTypeCast(parent) || is_LogicalExpression(parent) || is_UnaryExpression(parent) || is_PostfixExpression(parent) || is_MemberExpression(parent) && node === parent.expression || is_CallExpression(parent) && node === parent.callee || is_OperationExpression(parent) || is_ComparisonExpression(parent);
}
if (is_LetScrutinee(parent) && is_LogicalExpression(node) && parent.expression === node) {
return true;
}
if (is_UnaryExpression(node)) {
switch (parent.nodeType) {
case NodeType.MemberExpression:
case NodeType.AwaitExpression:
return node === parent.expression;
case NodeType.CallExpression:
return node === parent.callee;
default:
return false;
}
}
if (is_ExpressionWithBodyOrCases_or_BlockLikeMacroInvocation(node)) {
if (is_ExpressionWithBodyOrCases(parent)) {
return !is_ElseBlock(node, parent);
}
if (is_LetScrutinee(parent) && parent.expression === node && is_ExpressionWithBodyOrCases(getGrandParentNode())) {
return true;
}
return is_ExpressionAsTypeCast(parent) || is_LogicalExpression(parent) || is_UnaryExpression(parent) || is_PostfixExpression(parent) || is_MemberExpression(parent) && node === parent.expression || is_CallExpression(parent) && node === parent.callee || is_OperationExpression(parent) || is_ComparisonExpression(parent) || is_RangeLiteral(parent);
}
if (is_StructLiteral(node)) {
if (is_ExpressionWithBodyOrCases(parent)) {
return true;
}
if (is_LetScrutinee(parent) && parent.expression === node && is_ExpressionWithBodyOrCases(getGrandParentNode())) {
return true;
}
if (is_UnaryExpression(parent) || is_PostfixExpression(parent) || is_MemberExpression(parent)) {
return parent.expression === node;
}
if (is_CallExpression(parent)) {
return parent.callee === node;
}
}
if (is_LogicalExpression(node) || is_OperationExpression(node) || is_ComparisonExpression(node) || is_ClosureFunctionExpression(node)) {
return precedenceNeedsParens(node, parent);
}
if (is_TypeFunctionNode(node)) {
const gp = getGrandParentNode();
if (node.returnType && is_TypeTraitBound(parent) && is_TypeBoundsStandaloneNode(gp) && last_of(gp.typeBounds) !== parent) {
return true;
}
}
if (is_TypeBoundsStandaloneNode(node)) {
return is_UnaryType(parent) && node.typeBounds.length > 1 || is_TypeBoundsStandaloneNode(parent) || is_TypeTraitBound(parent) || is_TypeFunctionNode(parent) && parent.returnType === node;
}
if (is_PatternVariableDeclaration(parent)) {
return is_UnionPattern(node);
}
return false;
}
function precedenceNeedsParens(node, parent) {
if (is_UnaryExpression(parent) || is_PostfixExpression(parent))
return true;
if (is_ReassignmentNode(parent))
return parent.left === node;
if (is_MemberExpression(parent))
return parent.expression === node;
if (is_CallExpression(parent))
return parent.callee === node;
if (is_ExpressionAsTypeCast(parent))
return !is_ExpressionAsTypeCast(node);
if (is_LogicalExpression(parent))
return is_LogicalExpression(node) ? parent.nodeType !== node.nodeType : evalPrecedence(node, parent);
if (is_OperationExpression(parent) || is_ComparisonExpression(parent))
return evalPrecedence(node, parent);
return false;
function evalPrecedence(child, parent2) {
if (is_ExpressionAsTypeCast(child) || is_ClosureFunctionExpression(child)) {
return true;
}
function getPrec(node2, bool) {
return getPrecedence(node2, bool);
}
const childPRCD = getPrec(child, is_insideScrutinee(child));
const parentPRCD = getPrec(parent2, is_insideScrutinee(parent2));
if (parentPRCD > childPRCD) {
return true;
}
if (parentPRCD === childPRCD && parent2.right === child) {
return true;
}
if (parentPRCD === childPRCD && !shouldFlatten(parent2, child)) {
return true;
}
if (parentPRCD < childPRCD && child.tk === TK["%"]) {
return parentPRCD === PRCD["+-"];
}
if (is_BitwiseOperator(parent2.tk) || is_BitwiseOperator(child.tk) && is_EqualityOperator(parent2.tk)) {
return true;
}
return false;
}
}
function shouldFlatten(parent, node) {
if (getPrecedence(node, is_insideScrutinee(node)) !== getPrecedence(parent, is_insideScrutinee(parent)))
return false;
if (is_ComparisonExpression(parent) && is_ComparisonExpression(node))
return false;
if (is_OperationExpression(parent) && is_OperationExpression(node)) {
if (node.tk === TK["%"] && is_multiplicativeOperator(parent.tk) || parent.tk === TK["%"] && is_multiplicativeOperator(node.tk) || node.tk !== parent.tk && is_multiplicativeOperator(node.tk) && is_multiplicativeOperator(parent.tk) || is_bitshiftOperator(node.tk) && is_bitshiftOperator(parent.tk))
return false;
}
return true;
}
function needsParens(node) {
return needsOuterSoftbreakParens(node) || needsInnerParens(node);
}
function stmtNeedsSemi(stmt, disregardExprType = false) {
return pathCallParentOf(stmt, (parent) => needsSemi(parent, stmt, disregardExprType));
}
var NoNode = { nodeType: 0 };
function needsSemi(parent, stmt, disregardExprType = false) {
const expr = disregardExprType ? NoNode : stmt.expression;
const hadSemi = !disregardExprType && stmt.semi;
return !!expr && (forcePreserveSemi() ? true : shouldNeverSemi() ? false : shouldPreserveSemi() ? hadSemi || shouldAlwaysSemi() || canAutoCompleteSemi() : true);
function forcePreserveSemi() {
return hadSemi && stmt === last_of(parent.body) && (is_IfBlockExpression(expr) && hasLetScrutineeCondition(expr) && !(is_LetScrutinee(expr.condition) && is_Identifier(expr.condition.expression)) || is_MatchExpression(expr) && !is_Identifier(expr.expression));
}
function shouldNeverSemi() {
return is_ExpressionWithBodyOrCases_or_BlockLikeMacroInvocation(expr);
}
function shouldPreserveSemi() {
return stmt === last_of(parent.body) && (is_ImplicitReturnAbleNode(parent) || is_BlockLikeMacroInvocation(parent));
}
function shouldAlwaysSemi() {
return is_FlowControlExpression(expr) || is_ReassignmentNode(expr);
}
function canAutoCompleteSemi() {
return withPathAt(parent, function checkParent(child) {
return pathCallParentOf(child, (parent2) => {
if (is_IfBlockExpression(parent2) && parent2.else === child) {
return checkParent(parent2);
}
if (is_ExpressionStatement(parent2)) {
if (hasOuterAttributes(parent2))
return false;
return stmtNeedsSemi(parent2, true);
}
if (is_MatchExpressionCase(parent2) && parent2.expression === child) {
return pathCallParentOf(parent2, checkParent);
}
return false;
});
});
}
}
function canInlineBlockBody(node) {
if (!is_ExpressionWithBody(node)) {
return false;
}
const body = node.body;
if (body.length === 0) {
return canInlineInlineable(node);
}
if (body.length === 1) {
const stmt = body[0];
if (is_AttributeOrDocComment(stmt)) {
return true;
}
if (is_ExpressionStatement(stmt) && !needsSemi(node, stmt)) {
const expr = stmt.expression;
if (is_FlowControlExpression(expr) || is_ClosureFunctionExpression(expr) || is_ExpressionWithBodyOrCases_or_BlockLikeMacroInvocation(expr)) {
return false;
}
return canInlineInlineable(node);
}
}
return false;
}
function canInlineInlineable(node) {
if (is_ForInBlockExpression(node) || is_LoopBlockExpression(node)) {
return false;
}
if (is_WhileBlockExpression(node)) {
return true;
}
const parent = getParentNode();
if (is_ExpressionStatement(parent) && (!is_ImplicitReturnAbleNode(node) || pathCallAtParent(parent, (parent2) => stmtNeedsSemi(parent2, true)))) {
return false;
}
if (is_ElseBlock(node, parent)) {
return pathCallAtParent(parent, canInlineBlockBody);
}
if (is_IfBlockExpression(node)) {
if (!node.else || is_ExpressionWithBodyOrCases_or_BlockLikeMacroInvocation(node.condition) || willBreak(getPrintFn()("condition"))) {
return false;
}
const grandparent = getGrandParentNode();
if (is_ExpressionStatement(parent) && hasBody(grandparent) && grandparent.body.length > 1) {
return false;
}
}
return true;
}
function emptyContent(node) {
switch (node.nodeType) {
case NodeType.Program:
case NodeType.MacroRulesDeclaration:
case NodeType.MacroDeclaration:
case NodeType.ExternBlockDeclaration:
case NodeType.ModuleDeclaration:
case NodeType.TraitDeclaration:
case NodeType.StructDeclaration:
case NodeType.MacroInvocation:
case NodeType.FunctionDeclaration:
case NodeType.ImplDeclaration:
case NodeType.UnionDeclaration:
case NodeType.EnumDeclaration:
case NodeType.EnumMemberStructDeclaration:
case NodeType.StructLiteral:
case NodeType.StructPattern:
return "";
case NodeType.BlockExpression:
case NodeType.WhileBlockExpression:
case NodeType.ForInBlockExpression:
case NodeType.TryBlockExpression:
case NodeType.IfBlockExpression:
return canInlineInlineable(node) ? is_IfBlockExpression(node) || is_ElseBlock(node, getParentNode()) ? softline : "" : hardline;
case NodeType.LoopBlockExpression:
case NodeType.MatchExpression:
return hardline;
default:
if (is_NodeWithBodyNoBody(node)) {
return "";
}
return "";
}
}
function is_insideScrutinee(target) {
return withPathAt(target, (n) => stackIncludes("condition") && r(n));
function r(CHILD) {
switch (CHILD.nodeType) {
case NodeType.OrExpression:
case NodeType.AndExpression:
return pathCallParentOf(
CHILD,
(PARENT) => hasCondition(PARENT) && PARENT.condition === CHILD ? hasLetScrutineeCondition(PARENT) : r(PARENT)
);
case NodeType.LetScrutinee:
return true;
default:
return false;
}
}
}
function withPathAt(target, callback) {
if (target === getNode())
return callback(target);
if (target === getParentNode())
return pathCallAtParent(target, () => callback(target));
if (stackIncludes(target))
return pathCallAtParent(getParentNode(), () => withPathAt(target, callback));
return getContext().path.call(() => {
return callback(target);
}, ...getAstPath(getNode(), target));
}
function shouldPrintOuterAttributesAbove(node) {
return is_StatementNode(node) || is_MatchExpressionCase(node) || hasAttributes(node) && node.attributes.some(
canInlineOuterAttribute(node) ? (attr) => is_DocCommentAttribute(attr) || hasBreaklineAfter(attr) : is_DocCommentAttribute
);
function canInlineOuterAttribute(node2) {
return is_EnumMemberDeclaration(node2) || is_StructPropertyDeclaration(node2) || is_StructLiteralProperty(node2) || is_StructPatternProperty(node2);
}
}
// src/format/core.ts
function isNoopExpressionStatement(node) {
return is_ExpressionStatement(node) && void 0 === node.expression && !hasAttributes(node) && !hasComment(node);
}
function is_xVariableEqualishLike(node) {
switch (node.nodeType) {
case NodeType.LetScrutinee:
case NodeType.LetVariableDeclaration:
case NodeType.ConstVariableDeclaration:
case NodeType.StaticVariableDeclaration:
case NodeType.TypeAliasDeclaration:
case NodeType.TraitAliasDeclaration:
return true;
default:
return false;
}
}
function is_BinaryishExpression(node) {
switch (node.nodeType) {
case NodeType.OrExpression:
case NodeType.AndExpression:
case NodeType.OperationExpression:
case NodeType.ComparisonExpression:
return true;
default:
return false;
}
}
function is_StructSpread(node) {
switch (node.nodeType) {
case NodeType.StructLiteralPropertySpread:
case NodeType.StructLiteralRestUnassigned:
case NodeType.RestPattern:
return true;
default:
return false;
}
}
function isConciselyPrintedArray(node) {
return node.items.length > 1 && node.items.every(
(element) => (is_LiteralNumberLike(element) || is_MinusExpression(element) && is_LiteralNumberLike(element.expression) && !hasComment(element.expression)) && !hasComment(element, 4 /* Trailing */ | 32 /* Line */, (comment) => !hasBreaklineBefore(comment))
);
}
function printNumber(rawNumber) {
return rawNumber.toLowerCase().replace(/^([\d.]+e)(?:\+|(-))?0*(\d)/, "$1$2$3").replace(/^(\d+)e[+-]?0+$/, "$1.0").replace(/^([\d.]+)e[+-]?0+$/, "$1").replace(/\.(\d+?)0+(?=e|$)/, ".$1").replace(/\.(?=e|$)/, ".0");
}
function printOnOwnLine(node, printed) {
return [printed, maybeEmptyLine(node)];
}
function maybeEmptyLine(node) {
return isNextLineEmpty(node) ? [hardline, hardline] : hardline;
}
function printBodyOrCases(print4, node) {
const p = [];
if (is_MatchExpression(node)) {
pathCallEach(node, "cases", (mCase) => {
p.push({
node: mCase,
doc: is_MatchExpressionCase(mCase) && !is_ExpressionWithBodyOrCases(mCase.expression) ? [print4(), ","] : print4()
});
});
} else {
pathCallEach(node, "body", (stmt) => {
if (!isNoopExpressionStatement(stmt)) {
p.push({ node: stmt, doc: print4() });
}
});
}
const printed = bumpInnerAttributes(p).map(
({ doc: doc2, node: node2 }, i, a) => iLast(i, a) ? group(doc2) : printOnOwnLine(node2, group(doc2))
);
const comments = printDanglingCommentsForInline(node, "body" /* body */);
if (comments)
printed.push(comments);
const ccomments = printDanglingCommentsForInline(node, "cases" /* cases */);
if (ccomments)
printed.push(ccomments);
if (is_Program(node) && is_SourceFile(getParentNode()) && printed.length > 0 && !comments) {
printed.push(hardline);
}
return printed;
function bumpInnerAttributes(arr) {
return arr.sort((a, b) => ownStart(a.node) - ownStart(b.node));
}
}
function printMacroRules(print4, node) {
return !Array.isArray(node.rules) ? print4("rules") : node.rules.length > 0 ? [" {", indent([hardline, ...print4.join("rules", (rule) => maybeEmptyLine(rule))]), hardline, "}"] : [" {", printDanglingCommentsForInline(node, "rules" /* rules */) || emptyContent(node), "}"];
}
function is_unary_token(item) {
switch (item && is_PunctuationToken(item) ? item.tk : TK.None) {
case TK["-"]:
case TK["*"]:
case TK["&"]:
case TK["#"]:
case TK["!"]:
case TK["~"]:
return true;
case TK["?"]:
return !/\s/.test(getOptions().originalText.charAt(end(item)));
default:
return false;
}
}
function can_unary(node) {
return (!is_PunctuationToken(node) || is_unary_token(node)) && (!is_MacroGroup(node) || is_optional_unary(node));
}
function is_optional_token(item) {
return !!item && is_MacroGroup(item) && item.kind === "?" && item.segments.length === 1 && is_PunctuationToken(item.segments[0]);
}
function is_optional_unary(item) {
return is_optional_token(item) && is_unary_token(item.segments[0]);
}
function printRuleMatch(print4, rule) {
return print_map(rule, "match");
function print_map(node, property) {
const arr = node[property];
const shouldHug = should_hug(arr);
const dline = arr.dk === DelimKind["{}"] ? line : shouldHug ? "" : softline;
const isParamsLike = is_params_like(arr);
const shouldBreak = should_break(arr);
const d = getDelimChars(arr);
if (arr.length === 0)
return [d.left, printDanglingCommentsForInline(node, DCM[property]), d.right];
const printed = flat(print4.map_join(property, print_item, join_item));
return group([d.left, !dline ? printed : [indent([dline, printed]), dline], d.right], {
shouldBreak,
id: getMacroGroupId(node)
});
function should_hug(arr2) {
if (node === rule)
return false;
let has_nonToken = false;
return arr2.every((item) => !is_MacroGroup(item) && (is_PunctuationToken(item) || has_nonToken !== (has_nonToken = true)));
}
function should_break(arr2) {
let has_decl = false;
return arr2.some(
(item, i, a) => is_match_any(item) && arr2.length !== 1 || !iLast(i, a) && isDeclStart(item, a[i + 1]) && has_decl === (has_decl = true)
);
}
function print_item(item, index, arr2) {
switch (item.nodeType) {
case NodeType.Identifier:
case NodeType.LtIdentifier:
case NodeType.Literal:
case NodeType.PunctuationToken:
case NodeType.MacroParameterDeclaration:
return print4();
case NodeType.MacroGroup:
return printComments(["$", print_map(item, "segments"), print4("sep"), item.kind]);
case NodeType.DelimGroup:
return printComments(print_map(item, "segments"));
}
function printComment