Skip to content

Commit ba5f792

Browse files
fix(minifier): don't use reserved words for mangled identifiers (#30)
1 parent 43d13ad commit ba5f792

File tree

3 files changed

+18
-1
lines changed

3 files changed

+18
-1
lines changed

src/minifier.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { type Token, tokenize } from './tokenizer.js'
2+
import { GLSL_KEYWORDS, WGSL_KEYWORDS } from './constants.js'
23

34
export type MangleMatcher = (token: Token, index: number, tokens: Token[]) => boolean
45

@@ -19,6 +20,9 @@ const isStorage = /* @__PURE__ */ RegExp.prototype.test.bind(
1920
/^(binding|group|layout|uniform|in|out|attribute|varying)$/,
2021
)
2122

23+
// Checks for WGSL-specific `fn foo(`, `var bar =`, `let baz =`, `const qux =`
24+
const WGSL_REGEX = /\bfn\s+\w+\s*\(|\b(var|let|const)\s+\w+\s*[:=]/
25+
2226
const NEWLINE_REGEX = /\\\s+/gm
2327
const DIRECTIVE_REGEX = /(^\s*#[^\\]*?)(\n|\/[\/\*])/gm
2428

@@ -35,6 +39,8 @@ export function minify(
3539
// Escape newlines after directives, skip comments
3640
code = code.replace(DIRECTIVE_REGEX, '$1\\$2')
3741

42+
const KEYWORDS = WGSL_REGEX.test(code) ? WGSL_KEYWORDS : GLSL_KEYWORDS
43+
3844
const mangleCache = new Map()
3945
const tokens: Token[] = tokenize(code).filter((token) => token.type !== 'whitespace' && token.type !== 'comment')
4046

@@ -127,7 +133,7 @@ export function minify(
127133
(tokens[i - 1]?.value === 'fn' && (tokens[i - 2]?.value === ')' || tokens[i - 3]?.value === '@'))
128134
const cache = isExternal ? mangleMap : mangleCache
129135

130-
while (!renamed || cache.has(renamed)) {
136+
while (!renamed || cache.has(renamed) || KEYWORDS.includes(renamed)) {
131137
renamed = ''
132138
mangleIndex++
133139

tests/__snapshots__/index.test.ts.snap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3+
exports[`minify > avoids reserved words like as during mangle 1`] = `"var a=0;var b=0;var c=0;var d=0;var e=0;var f=0;var g=0;var h=0;var u8=0;var i=0;var j=0;var k=0;var l=0;var m=0;var n=0;var o=0;var u16=0;var p=0;var q=0;var r=0;var s=0;var t=0;var u=0;var v=0;var w=0;var x=0;var y=0;var az=0;var aa=0;var ab=0;var ac=0;var ad=0;var u32=0;var ae=0;var af=0;var ag=0;var ah=0;var ai=0;var aj=0;var ak=0;var al=0;var am=0;var an=0;var ao=0;var ap=0;var aq=0;var ar=0;var at=0;var au=0;var av=0;var aw=0;var ax=0;var ay=0;"`;
4+
5+
exports[`minify > avoids reserved words like as during mangle 2`] = `Map {}`;
6+
37
exports[`minify > can mangle GLSL 1`] = `
48
"#version 300 es
59
precision mediump float;

tests/index.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,11 @@ describe('minify', () => {
183183
expect(minify(shader, { mangle: true, mangleExternals: true, mangleMap })).toMatchSnapshot()
184184
expect(mangleMap).toMatchSnapshot()
185185
})
186+
187+
it('avoids reserved words like as during mangle', () => {
188+
const mangleMap = new Map()
189+
const shader = /* glsl */ `${Array.from({ length: 53 }, (_, i) => `var u${i} = 0;`).join('')}`
190+
expect(minify(shader, { mangle: true, mangleExternals: true, mangleMap })).toMatchSnapshot()
191+
expect(mangleMap).toMatchSnapshot()
192+
})
186193
})

0 commit comments

Comments
 (0)