fix: Make numeric names valid#2598
Conversation
|
pkg.pr.new packages benchmark commit |
📊 Bundle Size Comparison
👀 Notable resultsStatic test results:No major changes. Dynamic test results:
📋 All resultsClick to reveal the results table (355 entries).
If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu. |
Resolution Time Benchmark---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.89, 1.70, 3.57, 5.26, 6.09, 9.54, 18.31, 19.85]
line [0.83, 1.59, 3.76, 5.92, 6.24, 9.70, 18.46, 21.27]
line [0.79, 1.69, 3.42, 5.40, 6.23, 9.84, 18.14, 23.55]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.33, 0.47, 0.71, 0.80, 1.04, 1.11, 1.31, 1.41]
line [0.33, 0.52, 0.66, 0.76, 1.05, 1.10, 1.28, 1.34]
line [0.33, 0.54, 0.64, 0.79, 1.01, 1.08, 1.36, 1.42]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
y-axis "time (ms)"
line [0.86, 1.82, 3.56, 5.58, 10.50, 22.11, 48.11, 98.69]
line [0.76, 1.83, 3.66, 5.47, 10.28, 22.30, 47.04, 97.14]
line [0.73, 1.70, 3.48, 5.33, 10.62, 22.56, 49.33, 96.52]
|
There was a problem hiding this comment.
Pull request overview
This PR tightens identifier sanitization/validation to ensure generated WGSL identifiers don’t start from invalid “primers” (e.g. empty strings or numeric names), and updates/extends WGSL generator tests to cover these cases.
Changes:
- Extend
sanitizePrimer/validateIdentifierso invalid primers (e.g.'','0','__') fall back toitem. - Add WGSL generator tests for item renaming and for invalid struct property keys; remove an obsolete test that relied on numeric struct keys.
- Refactor
validatePropto reusevalidateIdentifierbefore applying reserved-word checks.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| packages/typegpu/tests/tgsl/wgslGenerator.test.ts | Adds coverage for invalid item names and invalid struct property identifiers; removes a now-obsolete numeric-key test. |
| packages/typegpu/src/nameUtils.ts | Updates identifier sanitization/validation to align with WGSL identifier rules and handle numeric/empty primers. |
Comments suppressed due to low confidence (1)
packages/typegpu/src/nameUtils.ts:446
validatePropchecksbannedTokens.has(ident)but the error message says identifiers cannot start with reserved keywords. As written, names likestruct_1/loop_1would be allowed even though the message (and previous behavior) implies they should be rejected. Either update the message/tests to match exact-keyword-only behavior, or restore the prefix-based check here.
if (bannedTokens.has(ident)) {
return {
success: false,
error: `Identifiers cannot start with reserved keywords.`,
};
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }; | ||
| } | ||
| const prefix = ident.split('_')[0] as string; | ||
| if (bannedTokens.has(prefix) || builtins.has(prefix)) { |
There was a problem hiding this comment.
We can't simply delete this check.
import { expect } from 'vitest';
import { it } from 'typegpu-testing-utility';
import tgpu, { d } from '../../src/index.js';
it('reserved keyword in compute fn', () => {
const f = tgpu.computeFn({
in: { loop: d.builtin.globalInvocationId },
workgroupSize: [1],
})`{
let x = loop.x;
}`;
expect(tgpu.resolve([f])).toMatchInlineSnapshot(`
"@compute @workgroup_size(1) fn f(@builtin(global_invocation_id) loop: vec3u) {
let x = loop.x;
}"
`);
});
it('reserved keyword in fragment fn', () => {
const f = tgpu.fragmentFn({
in: { loop: d.builtin.position },
out: d.vec4f,
})`{
return vec4f(loop.x);
}`;
expect(tgpu.resolve([f])).toMatchInlineSnapshot(`
"@fragment fn f(@builtin(position) loop: vec4f) -> @location(0) vec4f {
return vec4f(loop.x);
}"
`);
});The unused argument pruning will save as, but we should validate input props with more attention.
There was a problem hiding this comment.
I added an explicit check for this, see if you see this solution fit
There was a problem hiding this comment.
Nice! I assume that it still generally works because builtins and banned tokens are considered "taken", so they're being skipped when searching for a unique identifier
Co-authored-by: Szymon Szulc <103948576+cieplypolar@users.noreply.github.com>
| }; | ||
| } | ||
| const prefix = ident.split('_')[0] as string; | ||
| if (bannedTokens.has(prefix) || builtins.has(prefix)) { |
There was a problem hiding this comment.
Nice! I assume that it still generally works because builtins and banned tokens are considered "taken", so they're being skipped when searching for a unique identifier
Co-authored-by: Iwo Plaza <iwoplaza@gmail.com>
No description provided.