From 98ee84005c640aceda14af41d7e04bfa6b318f9f Mon Sep 17 00:00:00 2001 From: huymobile Date: Thu, 27 Aug 2026 05:24:36 +0700 Subject: [PATCH 1/2] fix: indent standalone tseynit blocks --- packages/typegpu/src/shared/tseynit.ts | 12 +++++----- .../typegpu/tests/internal/tseynit.test.ts | 22 +++++++++++++++++++ .../unplugin-typegpu/test/obfuscation.test.ts | 6 ++--- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/packages/typegpu/src/shared/tseynit.ts b/packages/typegpu/src/shared/tseynit.ts index c272e988b5..e2efb06567 100644 --- a/packages/typegpu/src/shared/tseynit.ts +++ b/packages/typegpu/src/shared/tseynit.ts @@ -16,7 +16,7 @@ function stringifyStatement(node: tinyest.Statement, ident: string): string { if (node[0] === NODE.block) { const statements = node[1].map((n) => stringifyStatement(n, ident + ' ')); - return `{\n${statements.join('\n')}\n${ident}}`; + return `${ident}{\n${statements.join('\n')}\n${ident}}`; } if (node[0] === NODE.return) { @@ -26,10 +26,10 @@ function stringifyStatement(node: tinyest.Statement, ident: string): string { if (node[0] === NODE.if) { const cond = stringifyExpression(node[1], ident); - const then = stringifyStatement(node[2], ident); + const then = stringifyStatement(node[2], ident).trimStart(); const base = `${ident}if (${cond}) ${then}`; if (node[3] !== undefined) { - return `${base} else ${stringifyStatement(node[3], ident)}`; + return `${base} else ${stringifyStatement(node[3], ident).trimStart()}`; } return base; } @@ -52,13 +52,13 @@ function stringifyStatement(node: tinyest.Statement, ident: string): string { const init = node[1] ? stringifyStatement(node[1], '') : ';'; const cond = node[2] ? stringifyExpression(node[2], ident) : ''; const update = node[3] ? stringifyStatement(node[3], '') : ''; - const body = stringifyStatement(node[4], ident); + const body = stringifyStatement(node[4], ident).trimStart(); return `${ident}for (${init} ${cond}; ${update.slice(0, -1) /* trim the ';' */}) ${body}`; } if (node[0] === NODE.while) { const cond = stringifyExpression(node[1], ident); - const body = stringifyStatement(node[2], ident); + const body = stringifyStatement(node[2], ident).trimStart(); return `${ident}while (${cond}) ${body}`; } @@ -74,7 +74,7 @@ function stringifyStatement(node: tinyest.Statement, ident: string): string { const leftKind = node[1][0] === NODE.const ? 'const' : 'let'; const leftName = node[1][1]; const right = stringifyExpression(node[2], ident); - const body = stringifyStatement(node[3], ident); + const body = stringifyStatement(node[3], ident).trimStart(); return `${ident}for (${leftKind} ${leftName} of ${right}) ${body}`; } diff --git a/packages/typegpu/tests/internal/tseynit.test.ts b/packages/typegpu/tests/internal/tseynit.test.ts index 8fe16839e9..8e6eb306e4 100644 --- a/packages/typegpu/tests/internal/tseynit.test.ts +++ b/packages/typegpu/tests/internal/tseynit.test.ts @@ -180,6 +180,28 @@ describe('ast to JS transformation', () => { `); }); + it('indents standalone nested blocks without adding spaces to control-flow blocks', () => { + const fn = () => { + 'use gpu'; + { + [1, 2]; + } + if (true) { + [3, 4]; + } + }; + expect(stringifyNode(getBodyAst(fn))).toMatchInlineSnapshot(` + "{ + { + [1, 2]; + } + if (true) { + [3, 4]; + } + }" + `); + }); + it('handles declarations', () => { const fn = () => { 'use gpu'; diff --git a/packages/unplugin-typegpu/test/obfuscation.test.ts b/packages/unplugin-typegpu/test/obfuscation.test.ts index e0f47931b6..adbc364e72 100644 --- a/packages/unplugin-typegpu/test/obfuscation.test.ts +++ b/packages/unplugin-typegpu/test/obfuscation.test.ts @@ -504,7 +504,7 @@ describe('obfuscate', () => { expect(stringifyNode(body)).toMatchInlineSnapshot(` "{ const a = 1; - { + { const a = 2; if (false) { return a; @@ -540,7 +540,7 @@ describe('obfuscate', () => { `); expect(stringifyNode(body)).toMatchInlineSnapshot(` "{ - { + { const a = 2; if (false) { return a; @@ -569,7 +569,7 @@ describe('obfuscate', () => { expect(stringifyNode(body)).toMatchInlineSnapshot(` "{ const a = b; - { + { const b = 1; return b; } From 214b4ebb89d23f734d8c09643533174c26856a3c Mon Sep 17 00:00:00 2001 From: huymobile Date: Thu, 27 Aug 2026 18:57:23 +0700 Subject: [PATCH 2/2] fix: stringify control flow without trimming --- packages/typegpu/src/shared/tseynit.ts | 44 +++++++++++++++----------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/packages/typegpu/src/shared/tseynit.ts b/packages/typegpu/src/shared/tseynit.ts index e2efb06567..a1032115cc 100644 --- a/packages/typegpu/src/shared/tseynit.ts +++ b/packages/typegpu/src/shared/tseynit.ts @@ -9,73 +9,79 @@ export function stringifyNode(node: tinyest.AnyNode): string { return stringifyStatement(node, ''); } -function stringifyStatement(node: tinyest.Statement, ident: string): string { +function stringifyStatement( + node: tinyest.Statement, + ident: string, + omitInitialIndent = false, +): string { + const initialIndent = omitInitialIndent ? '' : ident; + if (isExpression(node)) { - return `${ident}${stringifyExpression(node, ident)};`; + return `${initialIndent}${stringifyExpression(node, ident)};`; } if (node[0] === NODE.block) { const statements = node[1].map((n) => stringifyStatement(n, ident + ' ')); - return `${ident}{\n${statements.join('\n')}\n${ident}}`; + return `${initialIndent}{\n${statements.join('\n')}\n${ident}}`; } if (node[0] === NODE.return) { const expr = node[1] === undefined ? '' : ` ${stringifyExpression(node[1], '')}`; - return `${ident}return${expr};`; + return `${initialIndent}return${expr};`; } if (node[0] === NODE.if) { const cond = stringifyExpression(node[1], ident); - const then = stringifyStatement(node[2], ident).trimStart(); - const base = `${ident}if (${cond}) ${then}`; + const then = stringifyStatement(node[2], ident, true); + const base = `${initialIndent}if (${cond}) ${then}`; if (node[3] !== undefined) { - return `${base} else ${stringifyStatement(node[3], ident).trimStart()}`; + return `${base} else ${stringifyStatement(node[3], ident, true)}`; } return base; } if (node[0] === NODE.let) { if (node[2] !== undefined) { - return `${ident}let ${node[1]} = ${stringifyExpression(node[2], ident)};`; + return `${initialIndent}let ${node[1]} = ${stringifyExpression(node[2], ident)};`; } - return `${ident}let ${node[1]};`; + return `${initialIndent}let ${node[1]};`; } if (node[0] === NODE.const) { if (node[2] !== undefined) { - return `${ident}const ${node[1]} = ${stringifyExpression(node[2], ident)};`; + return `${initialIndent}const ${node[1]} = ${stringifyExpression(node[2], ident)};`; } - return `${ident}const ${node[1]};`; + return `${initialIndent}const ${node[1]};`; } if (node[0] === NODE.for) { const init = node[1] ? stringifyStatement(node[1], '') : ';'; const cond = node[2] ? stringifyExpression(node[2], ident) : ''; const update = node[3] ? stringifyStatement(node[3], '') : ''; - const body = stringifyStatement(node[4], ident).trimStart(); - return `${ident}for (${init} ${cond}; ${update.slice(0, -1) /* trim the ';' */}) ${body}`; + const body = stringifyStatement(node[4], ident, true); + return `${initialIndent}for (${init} ${cond}; ${update.slice(0, -1) /* trim the ';' */}) ${body}`; } if (node[0] === NODE.while) { const cond = stringifyExpression(node[1], ident); - const body = stringifyStatement(node[2], ident).trimStart(); - return `${ident}while (${cond}) ${body}`; + const body = stringifyStatement(node[2], ident, true); + return `${initialIndent}while (${cond}) ${body}`; } if (node[0] === NODE.continue) { - return `${ident}continue;`; + return `${initialIndent}continue;`; } if (node[0] === NODE.break) { - return `${ident}break;`; + return `${initialIndent}break;`; } if (node[0] === NODE.forOf) { const leftKind = node[1][0] === NODE.const ? 'const' : 'let'; const leftName = node[1][1]; const right = stringifyExpression(node[2], ident); - const body = stringifyStatement(node[3], ident).trimStart(); - return `${ident}for (${leftKind} ${leftName} of ${right}) ${body}`; + const body = stringifyStatement(node[3], ident, true); + return `${initialIndent}for (${leftKind} ${leftName} of ${right}) ${body}`; } assertExhaustive(node);