UNPKG

tolkfmt-test-dev

Version:

Code formatter for the Tolk programming language

346 lines 18.4 kB
"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