tolkfmt-test-dev
Version:
Code formatter for the Tolk programming language
346 lines • 18.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.printIfStatement = void 0;
exports.printSetAssignment = printSetAssignment;
exports.printBlockStatement = printBlockStatement;
exports.printExpressionStatement = printExpressionStatement;
exports.printReturnStatement = printReturnStatement;
exports.printBreakStatement = printBreakStatement;
exports.printContinueStatement = printContinueStatement;
exports.printThrowStatement = printThrowStatement;
exports.printWhileStatement = printWhileStatement;
exports.printDoWhileStatement = printDoWhileStatement;
exports.printRepeatStatement = printRepeatStatement;
exports.printLocalVarsDeclaration = printLocalVarsDeclaration;
exports.printVarDeclaration = printVarDeclaration;
exports.printTupleVarsDeclaration = printTupleVarsDeclaration;
exports.printTensorVarsDeclaration = printTensorVarsDeclaration;
exports.printEmptyStatement = printEmptyStatement;
exports.printAssertStatement = printAssertStatement;
exports.printTryCatchStatement = printTryCatchStatement;
exports.printCatchClause = printCatchClause;
exports.printMatchStatement = printMatchStatement;
exports.printAssignment = printAssignment;
const node_1 = require("./node");
const doc_1 = require("../doc");
const comments_1 = require("../comments");
const expr_1 = require("./expr");
const printIfStatement = (node, ctx) => {
const conditionN = node.childForFieldName("condition");
const bodyN = node.childForFieldName("body");
if (!conditionN || !bodyN)
return undefined;
const condition = (0, node_1.printNode)(conditionN, ctx) ?? (0, doc_1.empty)();
const body = (0, node_1.printNode)(bodyN, ctx) ?? (0, doc_1.empty)();
const alternativeN = node.childForFieldName("alternative");
const alternative = alternativeN
? [(0, doc_1.text)(" else "), (0, node_1.printNode)(alternativeN, ctx) ?? (0, doc_1.empty)()]
: [];
return (0, doc_1.group)([
(0, doc_1.group)([(0, doc_1.text)("if ("), (0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.softLine)(), condition])), (0, doc_1.softLine)(), (0, doc_1.text)(") ")]),
body,
...alternative,
]);
};
exports.printIfStatement = printIfStatement;
function printSetAssignment(node, ctx) {
const leftN = node.childForFieldName("left");
const rightN = node.childForFieldName("right");
const operatorN = node.childForFieldName("operator_name");
if (!leftN || !rightN || !operatorN)
return undefined;
const left = (0, node_1.printNode)(leftN, ctx) ?? (0, doc_1.empty)();
const right = (0, node_1.printNode)(rightN, ctx) ?? (0, doc_1.empty)();
const operator = operatorN.text;
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
return (0, doc_1.group)([left, (0, doc_1.text)(" "), (0, doc_1.text)(operator), (0, doc_1.text)(" "), right, ...trailing]);
}
function printBlockStatement(node, ctx) {
const statements = node.namedChildren
.filter(it => it !== null)
.filter(it => it.type !== "comment");
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
const dangling = (0, comments_1.takeDangling)(node, ctx.comments);
const danglingDoc = (0, node_1.formatDangling)(dangling);
if (statements.length === 0 && leading.length === 0 && dangling.length === 0) {
return (0, doc_1.text)("{}");
}
const nonEmptyStatements = statements.filter(stmt => {
if (stmt.type === "empty_statement" && (0, comments_1.getTrailing)(stmt, ctx.comments).length === 0) {
// skip `;` in `match (a) { ... };`
return false;
}
// non empty statement
return true;
});
const docs = [];
for (let i = 0; i < nonEmptyStatements.length; i++) {
const statement = nonEmptyStatements[i];
if ((0, node_1.hasFmtIgnoreDirective)((0, comments_1.getLeading)(statement, ctx.comments))) {
docs.push((0, node_1.printOriginalNodeText)(statement, ctx));
}
else {
const stmtLeading = (0, comments_1.takeLeading)(statement, ctx.comments);
const leadingDoc = stmtLeading.map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
const doc = (0, doc_1.concat)([...leadingDoc, (0, node_1.printNode)(statement, ctx) ?? (0, doc_1.empty)()]);
docs.push(doc);
}
if (i < nonEmptyStatements.length - 1) {
docs.push((0, doc_1.blank)((0, doc_1.blankLinesBetween)(statement, nonEmptyStatements[i + 1], ctx.comments)));
}
}
return (0, doc_1.concat)([
(0, doc_1.text)("{"),
(0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.hardLine)(), ...leading, ...docs, ...danglingDoc])),
(0, doc_1.hardLine)(),
(0, doc_1.text)("}"),
]);
}
function printExpressionStatement(node, ctx) {
const expr = node.firstChild;
if (!expr)
return undefined;
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.lineSuffix)((0, doc_1.text)(c.text)), (0, doc_1.breakParent)()]));
return (0, doc_1.concat)([(0, node_1.printNode)(expr, ctx) ?? (0, doc_1.empty)(), (0, doc_1.text)(";"), ...trailing]);
}
function printReturnStatement(node, ctx) {
const exprN = node.childForFieldName("body");
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
const inMatchArm = node.parent?.type === "match_arm";
const endSemicolon = inMatchArm ? "" : ";";
if (exprN) {
const expr = (0, node_1.printNode)(exprN, ctx) ?? (0, doc_1.empty)();
return (0, doc_1.concat)([...leading, (0, doc_1.text)("return "), expr, (0, doc_1.text)(endSemicolon), ...trailing]);
}
else {
return (0, doc_1.concat)([...leading, (0, doc_1.text)(`return${endSemicolon}`), ...trailing]);
}
}
function printBreakStatement(node, ctx) {
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
return (0, doc_1.concat)([...leading, (0, doc_1.text)("break"), ...trailing]);
}
function printContinueStatement(node, ctx) {
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
return (0, doc_1.concat)([...leading, (0, doc_1.text)("continue"), ...trailing]);
}
function printThrowStatement(node, ctx) {
const exprN = node.firstNamedChild; // The expression to throw
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
const inMatchArm = node.parent?.type === "match_arm";
const endSemicolon = inMatchArm ? "" : ";";
if (exprN) {
const expr = (0, node_1.printNode)(exprN, ctx) ?? (0, doc_1.empty)();
return (0, doc_1.concat)([...leading, (0, doc_1.text)("throw "), expr, (0, doc_1.text)(endSemicolon), ...trailing]);
}
else {
return (0, doc_1.concat)([...leading, (0, doc_1.text)(`throw${endSemicolon}`), ...trailing]);
}
}
function printWhileStatement(node, ctx) {
const conditionN = node.childForFieldName("condition");
const bodyN = node.childForFieldName("body");
if (!conditionN || !bodyN)
return undefined;
const condition = (0, node_1.printNode)(conditionN, ctx) ?? (0, doc_1.empty)();
const body = (0, node_1.printNode)(bodyN, ctx) ?? (0, doc_1.empty)();
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
return (0, doc_1.concat)([
...leading,
(0, doc_1.group)([(0, doc_1.text)("while ("), (0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.softLine)(), condition])), (0, doc_1.softLine)(), (0, doc_1.text)(") ")]),
body,
]);
}
function printDoWhileStatement(node, ctx) {
const conditionN = node.childForFieldName("condition");
const bodyN = node.childForFieldName("body");
if (!conditionN || !bodyN)
return undefined;
const condition = (0, node_1.printNode)(conditionN, ctx) ?? (0, doc_1.empty)();
const body = (0, node_1.printNode)(bodyN, ctx) ?? (0, doc_1.empty)();
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
return (0, doc_1.concat)([
...leading,
(0, doc_1.text)("do "),
body,
(0, doc_1.group)([(0, doc_1.text)(" while ("), (0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.softLine)(), condition])), (0, doc_1.softLine)(), (0, doc_1.text)(");")]),
]);
}
function printRepeatStatement(node, ctx) {
const countN = node.childForFieldName("count");
const bodyN = node.childForFieldName("body");
if (!countN || !bodyN)
return undefined;
const count = (0, node_1.printNode)(countN, ctx) ?? (0, doc_1.empty)();
const body = (0, node_1.printNode)(bodyN, ctx) ?? (0, doc_1.empty)();
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
return (0, doc_1.concat)([
...leading,
(0, doc_1.group)([(0, doc_1.text)("repeat ("), (0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.softLine)(), count])), (0, doc_1.softLine)(), (0, doc_1.text)(") ")]),
body,
]);
}
function printLocalVarsDeclaration(node, ctx) {
const kindN = node.childForFieldName("kind");
const lhsN = node.childForFieldName("lhs");
const assignedValN = node.childForFieldName("assigned_val");
if (!kindN || !lhsN)
return undefined;
const isMatchExpression = node.parent?.type === "match_expression";
const kind = kindN.text; // "var" or "val"
const lhs = (0, node_1.printNode)(lhsN, ctx) ?? (0, doc_1.empty)();
const leading = (0, comments_1.takeLeading)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(c.text), (0, doc_1.hardLine)()]));
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
if (assignedValN) {
const assignedVal = (0, node_1.printNode)(assignedValN, ctx) ?? (0, doc_1.empty)();
return (0, doc_1.concat)([
...leading,
(0, doc_1.text)(kind),
(0, doc_1.text)(" "),
lhs,
(0, doc_1.text)(" = "),
assignedVal,
isMatchExpression ? (0, doc_1.empty)() : (0, doc_1.text)(";"),
...trailing,
]);
}
else {
return (0, doc_1.concat)([...leading, (0, doc_1.text)(kind), (0, doc_1.text)(" "), lhs, (0, doc_1.text)(";"), ...trailing]);
}
}
function printVarDeclaration(node, ctx) {
const nameN = node.childForFieldName("name");
const typeN = node.childForFieldName("type");
const redefN = node.childForFieldName("redef");
if (!nameN)
return undefined;
const name = (0, node_1.printNode)(nameN, ctx) ?? (0, doc_1.empty)();
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
if (redefN) {
return (0, doc_1.concat)([name, (0, doc_1.text)(" redef"), ...trailing]);
}
else if (typeN) {
const type = (0, node_1.printNode)(typeN, ctx) ?? (0, doc_1.empty)();
return (0, doc_1.concat)([name, (0, doc_1.text)(": "), type, ...trailing]);
}
else {
return (0, doc_1.concat)([name, ...trailing]);
}
}
function printTupleVarsDeclaration(node, ctx) {
const varsN = node.childrenForFieldName("vars");
// Extract all vars from the vars field
const vars = varsN.filter(child => child !== null).filter(child => child.isNamed);
const parts = vars.map(v => (0, node_1.printNode)(v, ctx) ?? (0, doc_1.empty)());
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
if (parts.length === 1) {
return (0, doc_1.concat)([(0, doc_1.text)("["), parts[0], (0, doc_1.text)("]"), ...trailing]);
}
const [first, ...rest] = parts;
const tailDocs = rest.map(part => (0, doc_1.concat)([(0, doc_1.text)(", "), part]));
return (0, doc_1.group)([
(0, doc_1.text)("["),
(0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.softLine)(), first, ...tailDocs])),
(0, doc_1.softLine)(),
(0, doc_1.text)("]"),
...trailing,
]);
}
function printTensorVarsDeclaration(node, ctx) {
const varsN = node.childrenForFieldName("vars");
// Extract all vars from the vars field
const vars = varsN.filter(child => child !== null).filter(child => child.isNamed);
const parts = vars.map(v => (0, node_1.printNode)(v, ctx) ?? (0, doc_1.empty)());
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
if (parts.length === 1) {
return (0, doc_1.concat)([(0, doc_1.text)("("), parts[0], (0, doc_1.text)(")"), ...trailing]);
}
const [first, ...rest] = parts;
const tailDocs = rest.map(part => (0, doc_1.concat)([(0, doc_1.text)(", "), part]));
return (0, doc_1.group)([
(0, doc_1.text)("("),
(0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.softLine)(), first, ...tailDocs])),
(0, doc_1.softLine)(),
(0, doc_1.text)(")"),
...trailing,
]);
}
function printEmptyStatement(node, ctx) {
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
if (trailing.length === 0) {
return (0, doc_1.empty)();
}
return (0, doc_1.concat)([(0, doc_1.text)(";"), ...trailing]);
}
function printAssertStatement(node, ctx) {
const conditionN = node.childForFieldName("condition");
const excNoN = node.childForFieldName("excNo");
if (!conditionN || !excNoN)
return undefined;
const condition = (0, node_1.printNode)(conditionN, ctx) ?? (0, doc_1.empty)();
const excNo = (0, node_1.printNode)(excNoN, ctx) ?? (0, doc_1.empty)();
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
// Check if it's the throw form: assert(...) throw ...
const hasThrow = node.children.some(child => child?.text === "throw");
return hasThrow
? (0, doc_1.group)([
(0, doc_1.text)("assert ("),
(0, doc_1.indent)((0, doc_1.concat)([(0, doc_1.softLine)(), condition])),
(0, doc_1.softLine)(),
(0, doc_1.text)(") throw "),
excNo,
(0, doc_1.text)(";"),
...trailing,
])
: (0, doc_1.group)([(0, doc_1.text)("assert("), condition, (0, doc_1.text)(", "), excNo, (0, doc_1.text)(");"), ...trailing]);
}
function printTryCatchStatement(node, ctx) {
const tryBodyN = node.childForFieldName("try_body");
const catchN = node.childForFieldName("catch");
if (!tryBodyN || !catchN)
return undefined;
const tryBody = (0, node_1.printNode)(tryBodyN, ctx) ?? (0, doc_1.empty)();
const catchClause = (0, node_1.printNode)(catchN, ctx) ?? (0, doc_1.empty)();
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
return (0, doc_1.concat)([(0, doc_1.text)("try "), tryBody, (0, doc_1.text)(" catch "), catchClause, ...trailing]);
}
function printCatchClause(node, ctx) {
const catchBodyN = node.childForFieldName("catch_body");
const catchVar1N = node.childForFieldName("catch_var1");
const catchVar2N = node.childForFieldName("catch_var2");
if (!catchBodyN)
return undefined;
const catchBody = (0, node_1.printNode)(catchBodyN, ctx) ?? (0, doc_1.empty)();
const catchVar1 = catchVar1N ? ((0, node_1.printNode)(catchVar1N, ctx) ?? (0, doc_1.empty)()) : (0, doc_1.empty)();
const catchVar2 = catchVar2N ? ((0, node_1.printNode)(catchVar2N, ctx) ?? (0, doc_1.empty)()) : (0, doc_1.empty)();
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
let vars = (0, doc_1.empty)();
if (catchVar1.$ !== "Empty") {
vars =
catchVar2.$ === "Empty"
? (0, doc_1.concat)([(0, doc_1.text)("("), catchVar1, (0, doc_1.text)(") ")])
: (0, doc_1.concat)([(0, doc_1.text)("("), catchVar1, (0, doc_1.text)(", "), catchVar2, (0, doc_1.text)(") ")]);
}
return (0, doc_1.concat)([vars, catchBody, ...trailing]);
}
function printMatchStatement(node, ctx) {
const expr = node.firstChild;
if (!expr)
return undefined;
return (0, expr_1.printMatchExpression)(expr, ctx);
}
function printAssignment(node, ctx) {
const leftN = node.childForFieldName("left");
const rightN = node.childForFieldName("right");
if (!leftN || !rightN)
return undefined;
const left = (0, node_1.printNode)(leftN, ctx) ?? (0, doc_1.empty)();
const right = (0, node_1.printNode)(rightN, ctx) ?? (0, doc_1.empty)();
const trailing = (0, comments_1.takeTrailing)(node, ctx.comments).map(c => (0, doc_1.concat)([(0, doc_1.text)(" "), (0, doc_1.text)(c.text)]));
return (0, doc_1.concat)([left, (0, doc_1.text)(" = "), right, ...trailing]);
}
//# sourceMappingURL=stmts.js.map