📦 Optimized packaging
This commit is contained in:
@@ -0,0 +1,598 @@
|
||||
import { builders, utils } from "prettier/doc";
|
||||
import { call, definedKeys, each, findBaseIndent, flatMap, hasLeadingComments, indentInParentheses, isBinaryExpression, isNonTerminal, isTerminal, map, onlyDefinedKey, printDanglingComments, printList, printName, printSingle } from "./helpers.js";
|
||||
const { breakParent, conditionalGroup, group, hardline, ifBreak, indent, indentIfBreak, join, line, lineSuffixBoundary, softline } = builders;
|
||||
const { removeLines, willBreak } = utils;
|
||||
export default {
|
||||
expression: printSingle,
|
||||
lambdaExpression(path, print, _, args = {}) {
|
||||
var _a;
|
||||
const hug = (_a = args.hug) !== null && _a !== void 0 ? _a : false;
|
||||
const parameters = call(path, print, "lambdaParameters");
|
||||
const expression = [hug ? removeLines(parameters) : parameters, " ->"];
|
||||
const lambdaExpression = path.node.children.lambdaBody[0].children.expression;
|
||||
const body = call(path, print, "lambdaBody");
|
||||
if (lambdaExpression) {
|
||||
const suffix = indent([line, body]);
|
||||
expression.push(group(hug ? [suffix, softline] : suffix));
|
||||
}
|
||||
else {
|
||||
expression.push(" ", body);
|
||||
}
|
||||
return expression;
|
||||
},
|
||||
lambdaParameters(path, print, options) {
|
||||
const parameters = printSingle(path, print);
|
||||
return !path.node.children.lambdaParametersWithBraces &&
|
||||
options.arrowParens === "always"
|
||||
? ["(", parameters, ")"]
|
||||
: parameters;
|
||||
},
|
||||
lambdaParametersWithBraces(path, print, options) {
|
||||
var _a;
|
||||
const { lambdaParameterList } = path.node.children;
|
||||
if (!lambdaParameterList) {
|
||||
return "()";
|
||||
}
|
||||
const { conciseLambdaParameterList, normalLambdaParameterList } = lambdaParameterList[0].children;
|
||||
const parameterCount = ((_a = conciseLambdaParameterList === null || conciseLambdaParameterList === void 0 ? void 0 : conciseLambdaParameterList[0].children.conciseLambdaParameter) !== null && _a !== void 0 ? _a : normalLambdaParameterList === null || normalLambdaParameterList === void 0 ? void 0 : normalLambdaParameterList[0].children.normalLambdaParameter).length;
|
||||
const parameters = call(path, print, "lambdaParameterList");
|
||||
if (parameterCount > 1) {
|
||||
return indentInParentheses(parameters);
|
||||
}
|
||||
return conciseLambdaParameterList && options.arrowParens === "avoid"
|
||||
? parameters
|
||||
: ["(", parameters, ")"];
|
||||
},
|
||||
lambdaParameterList: printSingle,
|
||||
conciseLambdaParameterList(path, print) {
|
||||
return printList(path, print, "conciseLambdaParameter");
|
||||
},
|
||||
normalLambdaParameterList(path, print) {
|
||||
return printList(path, print, "normalLambdaParameter");
|
||||
},
|
||||
normalLambdaParameter: printSingle,
|
||||
regularLambdaParameter(path, print) {
|
||||
return join(" ", [
|
||||
...map(path, print, "variableModifier"),
|
||||
call(path, print, "lambdaParameterType"),
|
||||
call(path, print, "variableDeclaratorId")
|
||||
]);
|
||||
},
|
||||
lambdaParameterType: printSingle,
|
||||
conciseLambdaParameter: printSingle,
|
||||
lambdaBody: printSingle,
|
||||
conditionalExpression(path, print) {
|
||||
var _a;
|
||||
const binaryExpression = call(path, print, "binaryExpression");
|
||||
if (!path.node.children.QuestionMark) {
|
||||
return binaryExpression;
|
||||
}
|
||||
const expressions = map(path, print, "expression");
|
||||
const contents = indent(join(line, [
|
||||
binaryExpression,
|
||||
["? ", expressions[0]],
|
||||
[": ", expressions[1]]
|
||||
]));
|
||||
const isNestedTernary = ((_a = path.getNode(4)) === null || _a === void 0 ? void 0 : _a.name) ===
|
||||
"conditionalExpression";
|
||||
return isNestedTernary ? contents : group(contents);
|
||||
},
|
||||
binaryExpression(path, print, options) {
|
||||
var _a, _b;
|
||||
const { children } = path.node;
|
||||
const operands = flatMap(path, print, definedKeys(children, [
|
||||
"expression",
|
||||
"pattern",
|
||||
"referenceType",
|
||||
"unaryExpression"
|
||||
]));
|
||||
const operators = flatMap(path, operatorPath => {
|
||||
const { node } = operatorPath;
|
||||
let image;
|
||||
if (isTerminal(node)) {
|
||||
image = node.image;
|
||||
}
|
||||
else if (node.children.Less) {
|
||||
image = "<<";
|
||||
}
|
||||
else {
|
||||
image = node.children.Greater.length === 2 ? ">>" : ">>>";
|
||||
}
|
||||
return { image, doc: print(operatorPath) };
|
||||
}, definedKeys(children, [
|
||||
"AssignmentOperator",
|
||||
"BinaryOperator",
|
||||
"Instanceof",
|
||||
"shiftOperator"
|
||||
]));
|
||||
const hasNonAssignmentOperators = (operators.length > 0 && !children.AssignmentOperator) ||
|
||||
(children.expression !== undefined &&
|
||||
isBinaryExpression(children.expression[0]));
|
||||
const isInList = ((_a = path.getNode(4)) === null || _a === void 0 ? void 0 : _a.name) === "elementValue" ||
|
||||
((_b = path.getNode(6)) === null || _b === void 0 ? void 0 : _b.name) === "argumentList";
|
||||
return binary(operands, operators, {
|
||||
hasNonAssignmentOperators,
|
||||
isInList,
|
||||
isRoot: true,
|
||||
operatorPosition: options.experimentalOperatorPosition
|
||||
});
|
||||
},
|
||||
unaryExpression(path, print) {
|
||||
return [
|
||||
...map(path, print, "UnaryPrefixOperator"),
|
||||
call(path, print, "primary"),
|
||||
...map(path, print, "UnarySuffixOperator")
|
||||
];
|
||||
},
|
||||
unaryExpressionNotPlusMinus(path, print) {
|
||||
const { children } = path.node;
|
||||
const expression = [];
|
||||
if (children.UnaryPrefixOperatorNotPlusMinus) {
|
||||
expression.push(...map(path, print, "UnaryPrefixOperatorNotPlusMinus"));
|
||||
}
|
||||
expression.push(call(path, print, "primary"));
|
||||
if (children.UnarySuffixOperator) {
|
||||
expression.push(...map(path, print, "UnarySuffixOperator"));
|
||||
}
|
||||
return join(" ", expression);
|
||||
},
|
||||
primary(path, print) {
|
||||
var _a, _b;
|
||||
const { children } = path.node;
|
||||
if (!children.primarySuffix) {
|
||||
return call(path, print, "primaryPrefix");
|
||||
}
|
||||
const methodInvocations = children.primarySuffix
|
||||
.filter(({ children }) => children.methodInvocationSuffix)
|
||||
.map(({ children }) => children.methodInvocationSuffix[0].children);
|
||||
const hasLambdaMethodParameter = methodInvocations.some(({ argumentList }) => argumentList === null || argumentList === void 0 ? void 0 : argumentList[0].children.expression.some(({ children }) => children.lambdaExpression));
|
||||
const prefixIsCallExpression = children.primaryPrefix[0].children.newExpression;
|
||||
const callExpressionCount = methodInvocations.length +
|
||||
(prefixIsCallExpression ? 1 : 0) +
|
||||
children.primarySuffix.filter(({ children }) => children.unqualifiedClassInstanceCreationExpression).length;
|
||||
const fqnOrRefType = (_a = children.primaryPrefix[0].children.fqnOrRefType) === null || _a === void 0 ? void 0 : _a[0].children;
|
||||
const prefixIsMethodInvocation = (fqnOrRefType === null || fqnOrRefType === void 0 ? void 0 : fqnOrRefType.fqnOrRefTypePartRest) !== undefined &&
|
||||
((_b = children.primarySuffix) === null || _b === void 0 ? void 0 : _b[0].children.methodInvocationSuffix) !== undefined;
|
||||
const prefixIsStaticMethodInvocation = prefixIsMethodInvocation && isCapitalizedIdentifier(fqnOrRefType);
|
||||
const prefixIsInstanceMethodInvocation = prefixIsMethodInvocation && !prefixIsStaticMethodInvocation;
|
||||
const mustBreakForCallExpressions = methodInvocations.length > 2 && hasLambdaMethodParameter;
|
||||
const separator = mustBreakForCallExpressions ? hardline : softline;
|
||||
const prefix = [
|
||||
call(path, prefixPath => print(prefixPath, {
|
||||
lastSeparator: prefixIsStaticMethodInvocation ||
|
||||
(prefixIsInstanceMethodInvocation && callExpressionCount === 1)
|
||||
? ""
|
||||
: separator
|
||||
}), "primaryPrefix")
|
||||
];
|
||||
const canBreakForCallExpressions = callExpressionCount > 2 ||
|
||||
(callExpressionCount === 2 && prefixIsInstanceMethodInvocation) ||
|
||||
willBreak(prefix);
|
||||
const suffixes = [];
|
||||
each(path, suffixPath => {
|
||||
const { node, previous } = suffixPath;
|
||||
const suffix = print(suffixPath);
|
||||
if (node.children.Dot) {
|
||||
if ((canBreakForCallExpressions &&
|
||||
((!previous && prefixIsCallExpression) ||
|
||||
(previous === null || previous === void 0 ? void 0 : previous.children.methodInvocationSuffix) ||
|
||||
(previous === null || previous === void 0 ? void 0 : previous.children.unqualifiedClassInstanceCreationExpression))) ||
|
||||
(!node.children.templateArgument && willBreak(suffix))) {
|
||||
suffixes.push(separator);
|
||||
}
|
||||
suffixes.push(suffix);
|
||||
}
|
||||
else if (previous) {
|
||||
suffixes.push(suffix);
|
||||
}
|
||||
else {
|
||||
prefix.push(prefixIsInstanceMethodInvocation && callExpressionCount >= 2
|
||||
? indent(suffix)
|
||||
: suffix);
|
||||
}
|
||||
}, "primarySuffix");
|
||||
const hasSuffixComments = children.primarySuffix.some(suffix => hasLeadingComments(suffix));
|
||||
return group(canBreakForCallExpressions || hasSuffixComments
|
||||
? [prefix, indent(suffixes)]
|
||||
: [prefix, ...suffixes]);
|
||||
},
|
||||
primaryPrefix: printSingle,
|
||||
primarySuffix(path, print) {
|
||||
const { children } = path.node;
|
||||
if (!children.Dot) {
|
||||
return printSingle(path, print);
|
||||
}
|
||||
const suffix = ["."];
|
||||
if (children.This) {
|
||||
suffix.push("this");
|
||||
}
|
||||
else if (children.Identifier) {
|
||||
if (children.typeArguments) {
|
||||
suffix.push(call(path, print, "typeArguments"));
|
||||
}
|
||||
suffix.push(call(path, print, "Identifier"));
|
||||
}
|
||||
else {
|
||||
const suffixKey = onlyDefinedKey(children, [
|
||||
"templateArgument",
|
||||
"unqualifiedClassInstanceCreationExpression"
|
||||
]);
|
||||
suffix.push(call(path, print, suffixKey));
|
||||
}
|
||||
return suffix;
|
||||
},
|
||||
fqnOrRefType(path, print, _, args) {
|
||||
var _a;
|
||||
const lastSeparator = (_a = args.lastSeparator) !== null && _a !== void 0 ? _a : "";
|
||||
const fqnOrRefType = [
|
||||
call(path, print, "fqnOrRefTypePartFirst"),
|
||||
...map(path, partPath => {
|
||||
const part = print(partPath);
|
||||
return partPath.isLast
|
||||
? [willBreak(part) ? hardline : lastSeparator, part]
|
||||
: part;
|
||||
}, "fqnOrRefTypePartRest")
|
||||
];
|
||||
fqnOrRefType.push(indent(fqnOrRefType.pop()));
|
||||
return path.node.children.dims
|
||||
? [fqnOrRefType, call(path, print, "dims")]
|
||||
: fqnOrRefType;
|
||||
},
|
||||
fqnOrRefTypePartFirst(path, print) {
|
||||
return join(" ", [
|
||||
...map(path, print, "annotation"),
|
||||
call(path, print, "fqnOrRefTypePartCommon")
|
||||
]);
|
||||
},
|
||||
fqnOrRefTypePartRest(path, print) {
|
||||
const common = call(path, print, "fqnOrRefTypePartCommon");
|
||||
const type = path.node.children.typeArguments
|
||||
? [call(path, print, "typeArguments"), common]
|
||||
: common;
|
||||
return [".", ...join(" ", [...map(path, print, "annotation"), type])];
|
||||
},
|
||||
fqnOrRefTypePartCommon(path, print) {
|
||||
const { children } = path.node;
|
||||
const keywordKey = onlyDefinedKey(children, ["Identifier", "Super"]);
|
||||
const keyword = call(path, print, keywordKey);
|
||||
return children.typeArguments
|
||||
? [keyword, call(path, print, "typeArguments")]
|
||||
: keyword;
|
||||
},
|
||||
parenthesisExpression(path, print) {
|
||||
var _a;
|
||||
const expression = call(path, print, "expression");
|
||||
const ancestorName = (_a = path.getNode(14)) === null || _a === void 0 ? void 0 : _a.name;
|
||||
const binaryExpression = path.getNode(8);
|
||||
return ancestorName &&
|
||||
["guard", "returnStatement"].includes(ancestorName) &&
|
||||
binaryExpression &&
|
||||
binaryExpression.name === "binaryExpression" &&
|
||||
Object.keys(binaryExpression.children).length === 1
|
||||
? indentInParentheses(expression)
|
||||
: ["(", indent(expression), ")"];
|
||||
},
|
||||
castExpression: printSingle,
|
||||
primitiveCastExpression(path, print) {
|
||||
return [
|
||||
"(",
|
||||
call(path, print, "primitiveType"),
|
||||
") ",
|
||||
call(path, print, "unaryExpression")
|
||||
];
|
||||
},
|
||||
referenceTypeCastExpression(path, print) {
|
||||
const { children } = path.node;
|
||||
const type = call(path, print, "referenceType");
|
||||
const cast = children.additionalBound
|
||||
? indentInParentheses(join(line, [type, ...map(path, print, "additionalBound")]))
|
||||
: ["(", type, ")"];
|
||||
const expressionKey = onlyDefinedKey(children, [
|
||||
"lambdaExpression",
|
||||
"unaryExpressionNotPlusMinus"
|
||||
]);
|
||||
return [cast, " ", call(path, print, expressionKey)];
|
||||
},
|
||||
newExpression: printSingle,
|
||||
unqualifiedClassInstanceCreationExpression(path, print) {
|
||||
const { children } = path.node;
|
||||
const expression = ["new "];
|
||||
if (children.typeArguments) {
|
||||
expression.push(call(path, print, "typeArguments"));
|
||||
}
|
||||
expression.push(call(path, print, "classOrInterfaceTypeToInstantiate"), children.argumentList
|
||||
? group(["(", call(path, print, "argumentList"), ")"])
|
||||
: "()");
|
||||
if (children.classBody) {
|
||||
expression.push(" ", call(path, print, "classBody"));
|
||||
}
|
||||
return expression;
|
||||
},
|
||||
classOrInterfaceTypeToInstantiate(path, print) {
|
||||
const { children } = path.node;
|
||||
const type = children.annotation
|
||||
? flatMap(path, childPath => [
|
||||
print(childPath),
|
||||
isNonTerminal(childPath.node) ? " " : "."
|
||||
], ["annotation", "Identifier"])
|
||||
: printName(path, print);
|
||||
if (children.typeArgumentsOrDiamond) {
|
||||
type.push(call(path, print, "typeArgumentsOrDiamond"));
|
||||
}
|
||||
return type;
|
||||
},
|
||||
typeArgumentsOrDiamond: printSingle,
|
||||
diamond() {
|
||||
return "<>";
|
||||
},
|
||||
methodInvocationSuffix(path, print) {
|
||||
return path.node.children.argumentList
|
||||
? group(["(", call(path, print, "argumentList"), ")"])
|
||||
: indentInParentheses(printDanglingComments(path), { shouldBreak: true });
|
||||
},
|
||||
argumentList(path, print) {
|
||||
var _a, _b, _c, _d;
|
||||
const expressions = path.node.children.expression;
|
||||
const lastExpression = expressions.at(-1);
|
||||
const lastExpressionLambdaBodyExpression = (_b = (_a = lastExpression.children.lambdaExpression) === null || _a === void 0 ? void 0 : _a[0].children.lambdaBody[0].children.expression) === null || _b === void 0 ? void 0 : _b[0].children;
|
||||
const lastExpressionLambdaBodyTernaryExpression = (_c = lastExpressionLambdaBodyExpression === null || lastExpressionLambdaBodyExpression === void 0 ? void 0 : lastExpressionLambdaBodyExpression.conditionalExpression) === null || _c === void 0 ? void 0 : _c[0].children;
|
||||
const isHuggable = !lastExpression.comments &&
|
||||
(!lastExpressionLambdaBodyExpression ||
|
||||
(lastExpressionLambdaBodyTernaryExpression === null || lastExpressionLambdaBodyTernaryExpression === void 0 ? void 0 : lastExpressionLambdaBodyTernaryExpression.QuestionMark) !== undefined ||
|
||||
((_d = lastExpressionLambdaBodyTernaryExpression === null || lastExpressionLambdaBodyTernaryExpression === void 0 ? void 0 : lastExpressionLambdaBodyTernaryExpression.binaryExpression) === null || _d === void 0 ? void 0 : _d[0].children.unaryExpression.length) === 1) &&
|
||||
expressions.findIndex(({ children }) => children.lambdaExpression) ===
|
||||
expressions.length - 1;
|
||||
const args = map(path, print, "expression");
|
||||
const allArgsExpandable = [
|
||||
indent([softline, ...join([",", line], args)]),
|
||||
softline
|
||||
];
|
||||
if (!isHuggable || willBreak(args.at(-1)[0])) {
|
||||
return allArgsExpandable;
|
||||
}
|
||||
const headArgs = args.slice(0, -1);
|
||||
const huggedLastArg = path.call(argPath => print(argPath, { hug: true }), "children", "expression", args.length - 1);
|
||||
const lastArgExpanded = join(", ", [
|
||||
...headArgs,
|
||||
group(huggedLastArg, { shouldBreak: true })
|
||||
]);
|
||||
if (willBreak(huggedLastArg)) {
|
||||
return [
|
||||
breakParent,
|
||||
conditionalGroup([lastArgExpanded, allArgsExpandable])
|
||||
];
|
||||
}
|
||||
return conditionalGroup([
|
||||
join(", ", [...headArgs, huggedLastArg]),
|
||||
lastArgExpanded,
|
||||
allArgsExpandable
|
||||
]);
|
||||
},
|
||||
arrayCreationExpression(path, print) {
|
||||
const { children } = path.node;
|
||||
const typeKey = onlyDefinedKey(children, [
|
||||
"classOrInterfaceType",
|
||||
"primitiveType"
|
||||
]);
|
||||
const suffixKey = onlyDefinedKey(children, [
|
||||
"arrayCreationExpressionWithoutInitializerSuffix",
|
||||
"arrayCreationWithInitializerSuffix"
|
||||
]);
|
||||
return ["new ", call(path, print, typeKey), call(path, print, suffixKey)];
|
||||
},
|
||||
arrayCreationExpressionWithoutInitializerSuffix(path, print) {
|
||||
const expressions = call(path, print, "dimExprs");
|
||||
return path.node.children.dims
|
||||
? [expressions, call(path, print, "dims")]
|
||||
: expressions;
|
||||
},
|
||||
arrayCreationWithInitializerSuffix(path, print) {
|
||||
return [
|
||||
call(path, print, "dims"),
|
||||
" ",
|
||||
call(path, print, "arrayInitializer")
|
||||
];
|
||||
},
|
||||
dimExprs(path, print) {
|
||||
return map(path, print, "dimExpr");
|
||||
},
|
||||
dimExpr(path, print) {
|
||||
return join(" ", [
|
||||
...map(path, print, "annotation"),
|
||||
["[", call(path, print, "expression"), "]"]
|
||||
]);
|
||||
},
|
||||
classLiteralSuffix(path, print) {
|
||||
const lSquares = map(path, print, "LSquare");
|
||||
const rSquares = map(path, print, "RSquare");
|
||||
return [
|
||||
...lSquares.flatMap((lSquare, index) => [lSquare, rSquares[index]]),
|
||||
".class"
|
||||
];
|
||||
},
|
||||
arrayAccessSuffix(path, print) {
|
||||
return ["[", call(path, print, "expression"), "]"];
|
||||
},
|
||||
methodReferenceSuffix(path, print) {
|
||||
const { children } = path.node;
|
||||
const reference = ["::"];
|
||||
if (children.typeArguments) {
|
||||
reference.push(call(path, print, "typeArguments"));
|
||||
}
|
||||
reference.push(call(path, print, onlyDefinedKey(children, ["Identifier", "New"])));
|
||||
return reference;
|
||||
},
|
||||
templateArgument: printSingle,
|
||||
template: printSingle,
|
||||
stringTemplate(path, print) {
|
||||
return printTemplate(path, print, "StringTemplateBegin", "StringTemplateMid", "StringTemplateEnd");
|
||||
},
|
||||
textBlockTemplate(path, print) {
|
||||
return printTemplate(path, print, "TextBlockTemplateBegin", "TextBlockTemplateMid", "TextBlockTemplateEnd");
|
||||
},
|
||||
embeddedExpression: printSingle,
|
||||
pattern: printSingle,
|
||||
typePattern: printSingle,
|
||||
recordPattern(path, print) {
|
||||
const patterns = path.node.children.componentPatternList
|
||||
? indentInParentheses(call(path, print, "componentPatternList"))
|
||||
: "()";
|
||||
return [call(path, print, "referenceType"), patterns];
|
||||
},
|
||||
componentPatternList(path, print) {
|
||||
return printList(path, print, "componentPattern");
|
||||
},
|
||||
componentPattern: printSingle,
|
||||
matchAllPattern: printSingle,
|
||||
guard(path, print) {
|
||||
var _a;
|
||||
const expression = call(path, print, "expression");
|
||||
const hasParentheses = ((_a = path.node.children.expression[0].children.conditionalExpression) === null || _a === void 0 ? void 0 : _a[0].children.binaryExpression[0].children.unaryExpression[0].children.primary[0].children.primaryPrefix[0].children.parenthesisExpression) !==
|
||||
undefined;
|
||||
return [
|
||||
"when ",
|
||||
hasParentheses
|
||||
? expression
|
||||
: group([
|
||||
ifBreak("("),
|
||||
indent([softline, expression]),
|
||||
softline,
|
||||
ifBreak(")")
|
||||
])
|
||||
];
|
||||
}
|
||||
};
|
||||
function binary(operands, operators, { hasNonAssignmentOperators = false, isInList = false, isRoot = false, operatorPosition }) {
|
||||
let levelOperator;
|
||||
let levelPrecedence;
|
||||
let level = [];
|
||||
while (operators.length) {
|
||||
const nextOperator = operators[0].image;
|
||||
const nextPrecedence = getOperatorPrecedence(nextOperator);
|
||||
if (levelPrecedence === undefined || nextPrecedence === levelPrecedence) {
|
||||
const { image: operator, doc: operatorDoc } = operators.shift();
|
||||
level.push(operands.shift());
|
||||
if (levelOperator !== undefined &&
|
||||
needsParentheses(levelOperator, operator)) {
|
||||
level = [["(", group(indent(level)), ")"]];
|
||||
}
|
||||
const parts = [" ", operatorDoc, line];
|
||||
if (operatorPosition === "start" && !isAssignmentOperator(operator)) {
|
||||
parts.reverse();
|
||||
}
|
||||
level.push(parts);
|
||||
levelOperator = operator;
|
||||
levelPrecedence = nextPrecedence;
|
||||
}
|
||||
else if (nextPrecedence < levelPrecedence) {
|
||||
if (!isRoot) {
|
||||
break;
|
||||
}
|
||||
level.push(operands.shift());
|
||||
const content = group(indent(level));
|
||||
operands.unshift(levelOperator !== undefined &&
|
||||
needsParentheses(levelOperator, nextOperator)
|
||||
? ["(", content, ")"]
|
||||
: content);
|
||||
level = [];
|
||||
levelOperator = undefined;
|
||||
levelPrecedence = undefined;
|
||||
}
|
||||
else {
|
||||
const content = binary(operands, operators, { operatorPosition });
|
||||
operands.unshift(levelOperator !== undefined &&
|
||||
needsParentheses(nextOperator, levelOperator)
|
||||
? ["(", indent(content), ")"]
|
||||
: content);
|
||||
}
|
||||
}
|
||||
level.push(operands.shift());
|
||||
if (!levelOperator ||
|
||||
(!isInList &&
|
||||
!isAssignmentOperator(levelOperator) &&
|
||||
levelOperator !== "instanceof")) {
|
||||
return group(level);
|
||||
}
|
||||
if (!isRoot || hasNonAssignmentOperators) {
|
||||
return group(indent(level));
|
||||
}
|
||||
const groupId = Symbol("assignment");
|
||||
return group([
|
||||
level[0],
|
||||
group(indent(level[1]), { id: groupId }),
|
||||
indentIfBreak(level[2], { groupId })
|
||||
]);
|
||||
}
|
||||
const precedencesByOperator = new Map([
|
||||
["||"],
|
||||
["&&"],
|
||||
["|"],
|
||||
["^"],
|
||||
["&"],
|
||||
["==", "!="],
|
||||
["<", ">", "<=", ">=", "instanceof"],
|
||||
["<<", ">>", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%"]
|
||||
].flatMap((operators, index) => operators.map(operator => [operator, index])));
|
||||
function getOperatorPrecedence(operator) {
|
||||
var _a;
|
||||
return (_a = precedencesByOperator.get(operator)) !== null && _a !== void 0 ? _a : -1;
|
||||
}
|
||||
function needsParentheses(operator, parentOperator) {
|
||||
return ((operator === "&&" && parentOperator === "||") ||
|
||||
(["|", "^", "&", "<<", ">>", ">>>"].includes(parentOperator) &&
|
||||
getOperatorPrecedence(operator) >
|
||||
getOperatorPrecedence(parentOperator)) ||
|
||||
[operator, parentOperator].every(o => ["==", "!="].includes(o)) ||
|
||||
[operator, parentOperator].every(o => ["<<", ">>", ">>>"].includes(o)) ||
|
||||
(operator === "*" && parentOperator === "/") ||
|
||||
(operator === "/" && parentOperator === "*") ||
|
||||
(operator === "%" && ["+", "-", "*", "/"].includes(parentOperator)) ||
|
||||
(["*", "/"].includes(operator) && parentOperator === "%"));
|
||||
}
|
||||
const assignmentOperators = new Set([
|
||||
"=",
|
||||
"*=",
|
||||
"/=",
|
||||
"%=",
|
||||
"+=",
|
||||
"-=",
|
||||
"<<=",
|
||||
">>=",
|
||||
">>>=",
|
||||
"&=",
|
||||
"^=",
|
||||
"|="
|
||||
]);
|
||||
function isAssignmentOperator(operator) {
|
||||
return assignmentOperators.has(operator);
|
||||
}
|
||||
function isCapitalizedIdentifier(fqnOrRefType) {
|
||||
var _a, _b, _c;
|
||||
const nextToLastIdentifier = (_c = (_b = [
|
||||
fqnOrRefType.fqnOrRefTypePartFirst[0],
|
||||
...((_a = fqnOrRefType.fqnOrRefTypePartRest) !== null && _a !== void 0 ? _a : [])
|
||||
].at(-2)) === null || _b === void 0 ? void 0 : _b.children.fqnOrRefTypePartCommon[0].children.Identifier) === null || _c === void 0 ? void 0 : _c[0].image;
|
||||
return /^\p{Uppercase_Letter}/u.test(nextToLastIdentifier !== null && nextToLastIdentifier !== void 0 ? nextToLastIdentifier : "");
|
||||
}
|
||||
function printTemplate(path, print, beginKey, midKey, endKey) {
|
||||
const begin = call(path, ({ node }) => node.image, beginKey);
|
||||
const mids = map(path, ({ node }) => node.image, midKey);
|
||||
const end = call(path, ({ node }) => node.image, endKey);
|
||||
const lines = [begin, ...mids, end].join("").split("\n").slice(1);
|
||||
const baseIndent = findBaseIndent(lines);
|
||||
const prefix = "\n" + " ".repeat(baseIndent);
|
||||
const parts = [begin, ...mids, end].map(image => join(hardline, image.split(prefix)));
|
||||
return indent([
|
||||
parts[0],
|
||||
...map(path, (expressionPath, index) => {
|
||||
const expression = group([
|
||||
indent([softline, print(expressionPath), lineSuffixBoundary]),
|
||||
softline
|
||||
]);
|
||||
return index === 0 ? expression : [parts[index], expression];
|
||||
}, "embeddedExpression"),
|
||||
parts.at(-1)
|
||||
]);
|
||||
}
|
||||
Reference in New Issue
Block a user