wesl 0.6.48 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +295 -214
- package/dist/index.js +2947 -1550
- package/package.json +6 -8
- package/src/AbstractElems.ts +81 -81
- package/src/Assertions.ts +5 -5
- package/src/BindIdents.ts +193 -319
- package/src/ClickableError.ts +3 -2
- package/src/Conditions.ts +2 -2
- package/src/LinkedWesl.ts +1 -1
- package/src/Linker.ts +4 -3
- package/src/LinkerUtil.ts +1 -1
- package/src/Logging.ts +165 -0
- package/src/LowerAndEmit.ts +278 -110
- package/src/ModulePathUtil.ts +59 -0
- package/src/ModuleResolver.ts +26 -62
- package/src/ParseError.ts +9 -0
- package/src/ParseWESL.ts +30 -94
- package/src/RawEmit.ts +1 -4
- package/src/Reflection.ts +1 -1
- package/src/Scope.ts +3 -0
- package/src/Span.ts +2 -0
- package/src/SrcMap.ts +208 -0
- package/src/Stream.ts +30 -0
- package/src/TransformBindingStructs.ts +2 -2
- package/src/Util.ts +1 -1
- package/src/debug/ASTtoString.ts +84 -135
- package/src/discovery/FindUnboundIdents.ts +14 -5
- package/src/index.ts +5 -0
- package/src/parse/ContentsHelpers.ts +70 -0
- package/src/parse/ExpressionUtil.ts +121 -0
- package/src/parse/Keywords.ts +12 -12
- package/src/parse/OperatorBinding.ts +146 -0
- package/src/parse/ParseAttribute.ts +272 -0
- package/src/parse/ParseCall.ts +77 -0
- package/src/parse/ParseControlFlow.ts +129 -0
- package/src/parse/ParseDirective.ts +105 -0
- package/src/parse/ParseExpression.ts +288 -0
- package/src/parse/ParseFn.ts +151 -0
- package/src/parse/ParseGlobalVar.ts +131 -0
- package/src/parse/ParseIdent.ts +77 -0
- package/src/parse/ParseImport.ts +160 -0
- package/src/parse/ParseLocalVar.ts +69 -0
- package/src/parse/ParseLoop.ts +112 -0
- package/src/parse/ParseModule.ts +116 -0
- package/src/parse/ParseSimpleStatement.ts +162 -0
- package/src/parse/ParseStatement.ts +215 -0
- package/src/parse/ParseStruct.ts +89 -0
- package/src/parse/ParseType.ts +71 -0
- package/src/parse/ParseUtil.ts +174 -0
- package/src/parse/ParseValueDeclaration.ts +130 -0
- package/src/parse/ParseWesl.ts +51 -0
- package/src/parse/ParsingContext.ts +93 -0
- package/src/parse/WeslStream.ts +63 -20
- package/src/parse/stream/CachingStream.ts +48 -0
- package/src/parse/stream/MatchersStream.ts +85 -0
- package/src/parse/stream/RegexHelpers.ts +38 -0
- package/src/test/BevyLink.test.ts +100 -0
- package/src/test/BindStdTypes.test.ts +110 -0
- package/src/test/{BindWESL.test.ts → BindWESLV2.test.ts} +21 -22
- package/src/test/BulkTests.test.ts +11 -12
- package/src/test/ConditionLinking.test.ts +107 -0
- package/src/test/ConditionalElif.test.ts +1 -13
- package/src/test/ConditionalTranslationCases.test.ts +5 -0
- package/src/test/ErrorLogging.test.ts +2 -2
- package/src/test/ImportCasesV2.test.ts +63 -0
- package/src/test/LinkFails.test.ts +69 -0
- package/src/test/LinkPackage.test.ts +1 -1
- package/src/test/Linker.test.ts +75 -2
- package/src/test/LogCatcher.ts +53 -0
- package/src/test/Mangling.test.ts +1 -1
- package/src/test/ParseComments.test.ts +1 -2
- package/src/test/{ParseConditions.test.ts → ParseConditionsV2.test.ts} +57 -49
- package/src/test/ParseErrorV2.test.ts +73 -0
- package/src/test/{ParseWESL.test.ts → ParseWeslV2.test.ts} +288 -370
- package/src/test/{ScopeWESL.test.ts → ScopeWESLV2.test.ts} +205 -176
- package/src/test/TestLink.ts +51 -51
- package/src/test/TestSetup.ts +9 -3
- package/src/test/TestUtil.ts +47 -77
- package/src/test/TrimmedMatch.ts +40 -0
- package/src/test/VirtualModules.test.ts +33 -2
- package/src/test/WeslDevice.test.ts +9 -2
- package/src/test/__snapshots__/ParseWeslV2.test.ts.snap +67 -0
- package/src/test-util.ts +7 -0
- package/src/WESLCollect.ts +0 -656
- package/src/parse/AttributeGrammar.ts +0 -232
- package/src/parse/ImportGrammar.ts +0 -195
- package/src/parse/WeslBaseGrammar.ts +0 -11
- package/src/parse/WeslExpression.ts +0 -231
- package/src/parse/WeslGrammar.ts +0 -739
- package/src/test/Expression.test.ts +0 -22
- package/src/test/ImportSyntaxCases.test.ts +0 -24
- package/src/test/ParseError.test.ts +0 -45
- package/src/test/Reflection.test.ts +0 -176
- package/src/test/TransformBindingStructs.test.ts +0 -238
- /package/src/test/{ParseElif.test.ts → ParseElifV2.test.ts} +0 -0
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { eof, seq } from "mini-parse";
|
|
2
|
-
import { expect, test } from "vitest";
|
|
3
|
-
import { expression } from "../parse/WeslExpression.ts";
|
|
4
|
-
import { testAppParse } from "./TestUtil.ts";
|
|
5
|
-
|
|
6
|
-
test("parse number", () => {
|
|
7
|
-
const src = "3";
|
|
8
|
-
const { parsed } = testAppParse(seq(expression, eof), src);
|
|
9
|
-
expect(parsed).not.toBeNull();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
test("parse comparisons with && ||", () => {
|
|
13
|
-
const src = "a<3 && 4>(5)";
|
|
14
|
-
const { parsed } = testAppParse(seq(expression, eof), src);
|
|
15
|
-
expect(parsed).not.toBeNull();
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
test("parse vec templated type", () => {
|
|
19
|
-
const src = "vec2<f32>";
|
|
20
|
-
const { parsed } = testAppParse(seq(expression, eof), src);
|
|
21
|
-
expect(parsed).not.toBeNull();
|
|
22
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { withLogSpy } from "mini-parse/test-util";
|
|
2
|
-
import { expect, test } from "vitest";
|
|
3
|
-
import { importSyntaxCases } from "wesl-testsuite";
|
|
4
|
-
import { weslImports } from "../parse/ImportGrammar.ts";
|
|
5
|
-
import { testAppParse } from "./TestUtil.ts";
|
|
6
|
-
|
|
7
|
-
function expectParseFail(src: string): void {
|
|
8
|
-
withLogSpy(() => {
|
|
9
|
-
expect(() => testAppParse(weslImports, src)).toThrow(); // LATER catch specific error only
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function expectParses(src: string): void {
|
|
14
|
-
const result = testAppParse(weslImports, src);
|
|
15
|
-
expect(result.stable.imports.length).toBeGreaterThan(0);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
importSyntaxCases.forEach(c => {
|
|
19
|
-
if (c.fails) {
|
|
20
|
-
test(c.src, () => expectParseFail(c.src));
|
|
21
|
-
} else {
|
|
22
|
-
test(c.src, () => expectParses(c.src));
|
|
23
|
-
}
|
|
24
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
2
|
-
import { errorHighlight } from "../Util.ts";
|
|
3
|
-
import { parseTest } from "./TestUtil.ts";
|
|
4
|
-
|
|
5
|
-
test("parse fn foo() { invalid }", () => {
|
|
6
|
-
const src = "fn foo() { let }";
|
|
7
|
-
expect(() => parseTest(src)).toThrowErrorMatchingInlineSnapshot(`
|
|
8
|
-
[Error: ./test.wesl:1:15 error: invalid ident
|
|
9
|
-
fn foo() { let }
|
|
10
|
-
^^]
|
|
11
|
-
`);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test("parse invalid if", () => {
|
|
15
|
-
const src = `fn foo() {
|
|
16
|
-
let a = 3;
|
|
17
|
-
if(1<1) { 🐈⬛ } else { }
|
|
18
|
-
}`;
|
|
19
|
-
expect(() => parseTest(src)).toThrowErrorMatchingInlineSnapshot(`
|
|
20
|
-
[Error: ./test.wesl:3:13 error: Invalid token 🐈
|
|
21
|
-
|
|
22
|
-
if(1<1) { 🐈⬛ } else { }
|
|
23
|
-
^^]
|
|
24
|
-
`);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
test("parse invalid name", () => {
|
|
28
|
-
const src = "var package = 3;";
|
|
29
|
-
expect(() => parseTest(src)).toThrowErrorMatchingInlineSnapshot(`
|
|
30
|
-
[Error: ./test.wesl:1:4 error: expected identifier
|
|
31
|
-
var package = 3;
|
|
32
|
-
^^^^^^^^]
|
|
33
|
-
`);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
test("error highlight", () => {
|
|
37
|
-
expect(errorHighlight("foo", [0, 2]).join("\n")).toBe(`foo
|
|
38
|
-
^^`);
|
|
39
|
-
expect(errorHighlight("foo", [0, 1]).join("\n")).toBe(`foo
|
|
40
|
-
^`);
|
|
41
|
-
expect(errorHighlight("foo", [0, 0]).join("\n")).toBe(`foo
|
|
42
|
-
^`);
|
|
43
|
-
expect(errorHighlight("foo", [1, 2]).join("\n")).toBe(`foo
|
|
44
|
-
^`);
|
|
45
|
-
});
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
import { expect, test } from "vitest";
|
|
2
|
-
import type { BindingStructElem, StructElem } from "../AbstractElems.ts";
|
|
3
|
-
import { astToString } from "../debug/ASTtoString.ts";
|
|
4
|
-
import {
|
|
5
|
-
bindingGroupLayoutTs,
|
|
6
|
-
reportBindingStructsPlugin,
|
|
7
|
-
} from "../Reflection.ts";
|
|
8
|
-
import { bindingStructsPlugin } from "../TransformBindingStructs.ts";
|
|
9
|
-
import { linkTestOpts } from "./TestUtil.ts";
|
|
10
|
-
|
|
11
|
-
test("extract binding struct", () => {
|
|
12
|
-
const src = `
|
|
13
|
-
struct Bindings {
|
|
14
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
@compute fn main(b: Bindings) {
|
|
18
|
-
let x = b.particles;
|
|
19
|
-
}
|
|
20
|
-
`;
|
|
21
|
-
let found: StructElem[] | undefined;
|
|
22
|
-
const config = {
|
|
23
|
-
plugins: [
|
|
24
|
-
bindingStructsPlugin(),
|
|
25
|
-
reportBindingStructsPlugin(report => {
|
|
26
|
-
found = report;
|
|
27
|
-
}),
|
|
28
|
-
],
|
|
29
|
-
};
|
|
30
|
-
linkTestOpts({ config }, src);
|
|
31
|
-
|
|
32
|
-
// verify struct found
|
|
33
|
-
expect(found).toBeDefined();
|
|
34
|
-
const s = found?.[0] as StructElem;
|
|
35
|
-
expect(s).toBeDefined();
|
|
36
|
-
expect(astToString(s)).toMatchInlineSnapshot(`
|
|
37
|
-
"struct Bindings
|
|
38
|
-
text 'struct '
|
|
39
|
-
decl %Bindings
|
|
40
|
-
text ' {
|
|
41
|
-
'
|
|
42
|
-
member @group @binding particles: ptr<storage, array<f32>, read_write>
|
|
43
|
-
attribute @group('0')
|
|
44
|
-
expression '0'
|
|
45
|
-
text '0'
|
|
46
|
-
text ' '
|
|
47
|
-
attribute @binding('0')
|
|
48
|
-
expression '0'
|
|
49
|
-
text '0'
|
|
50
|
-
text ' '
|
|
51
|
-
name particles
|
|
52
|
-
text ': '
|
|
53
|
-
type ptr<storage, array<f32>, read_write>
|
|
54
|
-
ref ptr
|
|
55
|
-
text '<'
|
|
56
|
-
type storage
|
|
57
|
-
ref storage
|
|
58
|
-
text ', '
|
|
59
|
-
type array<f32>
|
|
60
|
-
ref array
|
|
61
|
-
text '<'
|
|
62
|
-
type f32
|
|
63
|
-
ref f32
|
|
64
|
-
text '>'
|
|
65
|
-
text ', '
|
|
66
|
-
type read_write
|
|
67
|
-
ref read_write
|
|
68
|
-
text '>'
|
|
69
|
-
text ',
|
|
70
|
-
}'"
|
|
71
|
-
`);
|
|
72
|
-
expect(s.bindingStruct).toBeTruthy();
|
|
73
|
-
expect((s as BindingStructElem).entryFn).toBeDefined();
|
|
74
|
-
|
|
75
|
-
// verify struct members
|
|
76
|
-
const members = s.members.filter(e => e.kind === "member");
|
|
77
|
-
const membersAst = members.map(e => astToString(e)).join("\n");
|
|
78
|
-
expect(membersAst).toMatchInlineSnapshot(
|
|
79
|
-
`
|
|
80
|
-
"member @group @binding particles: ptr<storage, array<f32>, read_write>
|
|
81
|
-
attribute @group('0')
|
|
82
|
-
expression '0'
|
|
83
|
-
text '0'
|
|
84
|
-
text ' '
|
|
85
|
-
attribute @binding('0')
|
|
86
|
-
expression '0'
|
|
87
|
-
text '0'
|
|
88
|
-
text ' '
|
|
89
|
-
name particles
|
|
90
|
-
text ': '
|
|
91
|
-
type ptr<storage, array<f32>, read_write>
|
|
92
|
-
ref ptr
|
|
93
|
-
text '<'
|
|
94
|
-
type storage
|
|
95
|
-
ref storage
|
|
96
|
-
text ', '
|
|
97
|
-
type array<f32>
|
|
98
|
-
ref array
|
|
99
|
-
text '<'
|
|
100
|
-
type f32
|
|
101
|
-
ref f32
|
|
102
|
-
text '>'
|
|
103
|
-
text ', '
|
|
104
|
-
type read_write
|
|
105
|
-
ref read_write
|
|
106
|
-
text '>'"
|
|
107
|
-
`,
|
|
108
|
-
);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test("binding struct to ts", () => {
|
|
112
|
-
const src = `
|
|
113
|
-
struct Uniforms {
|
|
114
|
-
foo: u32
|
|
115
|
-
}
|
|
116
|
-
struct MyBindings {
|
|
117
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
118
|
-
@group(0) @binding(1) uniforms: ptr<uniform, Uniforms>,
|
|
119
|
-
@group(0) @binding(2) tex: texture_2d<f32>,
|
|
120
|
-
@group(0) @binding(3) samp: sampler,
|
|
121
|
-
@group(0) @binding(4) stTex: texture_storage_2d<rgba8unorm, read>,
|
|
122
|
-
}
|
|
123
|
-
@compute fn main(b: MyBindings) {
|
|
124
|
-
let x = b.particles;
|
|
125
|
-
}
|
|
126
|
-
`;
|
|
127
|
-
let found: StructElem[] | undefined;
|
|
128
|
-
const config = {
|
|
129
|
-
plugins: [
|
|
130
|
-
bindingStructsPlugin(),
|
|
131
|
-
reportBindingStructsPlugin(report => {
|
|
132
|
-
found = report;
|
|
133
|
-
}),
|
|
134
|
-
],
|
|
135
|
-
};
|
|
136
|
-
linkTestOpts({ config }, src);
|
|
137
|
-
const ts = bindingGroupLayoutTs(found?.[0] as BindingStructElem);
|
|
138
|
-
expect(ts).toMatchInlineSnapshot(`
|
|
139
|
-
"
|
|
140
|
-
const myBindingsEntries = [
|
|
141
|
-
{
|
|
142
|
-
binding: 0,
|
|
143
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
144
|
-
buffer: { type: "storage" }
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
binding: 1,
|
|
148
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
149
|
-
buffer: { type: "uniform" }
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
binding: 2,
|
|
153
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
154
|
-
texture: { sampleType: "float" }
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
binding: 3,
|
|
158
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
159
|
-
sampler: { type: "filtering" }
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
binding: 4,
|
|
163
|
-
visibility: GPUShaderStage.COMPUTE,
|
|
164
|
-
storageTexture: { format: "rgba8unorm", sampleType: "float", access: "read-only" }
|
|
165
|
-
} ];
|
|
166
|
-
function myBindingsLayout(device: GPUDevice): GPUBindGroupLayout {
|
|
167
|
-
return device.createBindGroupLayout({
|
|
168
|
-
entries: myBindingsEntries
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
export const layoutFunctions = { myBindingsLayout };
|
|
173
|
-
export const layouts = { myBindingsEntries };
|
|
174
|
-
"
|
|
175
|
-
`);
|
|
176
|
-
});
|
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import { SrcMapBuilder } from "mini-parse";
|
|
2
|
-
import { expectTrimmedMatch } from "mini-parse/vitest-util";
|
|
3
|
-
import { expect, test } from "vitest";
|
|
4
|
-
import { bindIdents } from "../BindIdents.ts";
|
|
5
|
-
import { astToString } from "../debug/ASTtoString.ts";
|
|
6
|
-
import { lowerAndEmit } from "../LowerAndEmit.ts";
|
|
7
|
-
import { RecordResolver } from "../ModuleResolver.ts";
|
|
8
|
-
import {
|
|
9
|
-
bindingStructsPlugin,
|
|
10
|
-
findRefsToBindingStructs,
|
|
11
|
-
lowerBindingStructs,
|
|
12
|
-
markBindingStructs,
|
|
13
|
-
transformBindingReference,
|
|
14
|
-
transformBindingStruct,
|
|
15
|
-
} from "../TransformBindingStructs.ts";
|
|
16
|
-
import { linkTestOpts, parseTest } from "./TestUtil.ts";
|
|
17
|
-
|
|
18
|
-
test("markBindingStructs true", () => {
|
|
19
|
-
const src = `
|
|
20
|
-
struct Bindings {
|
|
21
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
24
|
-
|
|
25
|
-
const ast = parseTest(src);
|
|
26
|
-
const structs = markBindingStructs(ast.moduleElem);
|
|
27
|
-
expect(structs.length).toBe(1);
|
|
28
|
-
expect(structs[0].bindingStruct).toBe(true);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test("markBindingStructs false", () => {
|
|
32
|
-
const src = `
|
|
33
|
-
struct Bindings {
|
|
34
|
-
particles: ptr<storage, array<f32>, read_write>,
|
|
35
|
-
}
|
|
36
|
-
`;
|
|
37
|
-
|
|
38
|
-
const ast = parseTest(src);
|
|
39
|
-
const structs = markBindingStructs(ast.moduleElem);
|
|
40
|
-
expect(structs.length).toBe(0);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
test("transformBindingStruct", () => {
|
|
44
|
-
const src = `
|
|
45
|
-
struct Bindings {
|
|
46
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
47
|
-
}
|
|
48
|
-
`;
|
|
49
|
-
|
|
50
|
-
const rootAst = parseTest(src);
|
|
51
|
-
bindIdents({ rootAst, resolver: new RecordResolver({}) });
|
|
52
|
-
const bindingStruct = markBindingStructs(rootAst.moduleElem)[0];
|
|
53
|
-
const newVars = transformBindingStruct(bindingStruct, new Set());
|
|
54
|
-
|
|
55
|
-
const srcBuilder = new SrcMapBuilder({ text: rootAst.srcModule.src });
|
|
56
|
-
lowerAndEmit({ srcBuilder, rootElems: newVars, conditions: {} });
|
|
57
|
-
const linked = SrcMapBuilder.build([srcBuilder]).dest.text;
|
|
58
|
-
expect(linked).toMatchInlineSnapshot(
|
|
59
|
-
`
|
|
60
|
-
"@group(0) @binding(0) var<storage, read_write> particles : array<f32>;
|
|
61
|
-
"
|
|
62
|
-
`,
|
|
63
|
-
);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
test("findRefsToBindingStructs", () => {
|
|
67
|
-
const src = `
|
|
68
|
-
struct Bindings {
|
|
69
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
70
|
-
}
|
|
71
|
-
struct NotBindings { a: i32 }
|
|
72
|
-
var y: NotBindings;
|
|
73
|
-
|
|
74
|
-
fn main(b: Bindings) {
|
|
75
|
-
let x = b.particles;
|
|
76
|
-
let z = y.a;
|
|
77
|
-
}
|
|
78
|
-
`;
|
|
79
|
-
|
|
80
|
-
const rootAst = parseTest(src);
|
|
81
|
-
bindIdents({ rootAst, resolver: new RecordResolver({}) });
|
|
82
|
-
markBindingStructs(rootAst.moduleElem);
|
|
83
|
-
const found = findRefsToBindingStructs(rootAst.moduleElem);
|
|
84
|
-
expect(found.length).toBe(1);
|
|
85
|
-
const foundAst = astToString(found[0].memberRef);
|
|
86
|
-
expect(foundAst).toMatchInlineSnapshot(`
|
|
87
|
-
"memberRef b.particles
|
|
88
|
-
ref b
|
|
89
|
-
text '.'
|
|
90
|
-
name particles"
|
|
91
|
-
`);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("transformBindingReference", () => {
|
|
95
|
-
const src = `
|
|
96
|
-
struct Bindings {
|
|
97
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
98
|
-
}
|
|
99
|
-
fn main(b: Bindings) {
|
|
100
|
-
let x = b.particles;
|
|
101
|
-
}
|
|
102
|
-
`;
|
|
103
|
-
|
|
104
|
-
const rootAst = parseTest(src);
|
|
105
|
-
bindIdents({ rootAst, resolver: new RecordResolver({}) });
|
|
106
|
-
const bindingStruct = markBindingStructs(rootAst.moduleElem)[0];
|
|
107
|
-
transformBindingStruct(bindingStruct, new Set());
|
|
108
|
-
const found = findRefsToBindingStructs(rootAst.moduleElem);
|
|
109
|
-
expect(found.length).toBe(1);
|
|
110
|
-
const { memberRef, struct } = found[0];
|
|
111
|
-
const synthElem = transformBindingReference(memberRef, struct);
|
|
112
|
-
const synthAst = astToString(synthElem);
|
|
113
|
-
expect(synthAst).toMatchInlineSnapshot(`"synthetic 'particles'"`);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
test("lower binding structs", () => {
|
|
117
|
-
const src = `
|
|
118
|
-
struct Bindings {
|
|
119
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
120
|
-
}
|
|
121
|
-
fn main(b: Bindings) {
|
|
122
|
-
let x = b.particles;
|
|
123
|
-
}
|
|
124
|
-
`;
|
|
125
|
-
|
|
126
|
-
const expected = `
|
|
127
|
-
@group(0) @binding(0) var<storage, read_write> particles : array<f32>;
|
|
128
|
-
|
|
129
|
-
fn main() {
|
|
130
|
-
let x = particles;
|
|
131
|
-
}
|
|
132
|
-
`;
|
|
133
|
-
const rootAst = parseTest(src);
|
|
134
|
-
const { globalNames } = bindIdents({
|
|
135
|
-
rootAst,
|
|
136
|
-
resolver: new RecordResolver({}),
|
|
137
|
-
});
|
|
138
|
-
const tAst = { ...rootAst, globalNames, notableElems: {} };
|
|
139
|
-
const lowered = lowerBindingStructs(tAst);
|
|
140
|
-
|
|
141
|
-
const loweredAst = astToString(lowered.moduleElem);
|
|
142
|
-
expect(loweredAst).toMatchInlineSnapshot(`
|
|
143
|
-
"module
|
|
144
|
-
synthetic '@group(0) @binding(0) var<storage, read_write> particles : array<f32>;
|
|
145
|
-
'
|
|
146
|
-
text '
|
|
147
|
-
'
|
|
148
|
-
text '
|
|
149
|
-
'
|
|
150
|
-
fn main(b: Bindings)
|
|
151
|
-
decl %main
|
|
152
|
-
param
|
|
153
|
-
statement
|
|
154
|
-
text '{
|
|
155
|
-
let '
|
|
156
|
-
typeDecl %x
|
|
157
|
-
decl %x
|
|
158
|
-
text ' = '
|
|
159
|
-
memberRef b.particles
|
|
160
|
-
synthetic 'particles'
|
|
161
|
-
text ';
|
|
162
|
-
}'
|
|
163
|
-
text '
|
|
164
|
-
'"
|
|
165
|
-
`);
|
|
166
|
-
|
|
167
|
-
const srcBuilder = new SrcMapBuilder({ text: lowered.srcModule.src });
|
|
168
|
-
lowerAndEmit({
|
|
169
|
-
srcBuilder,
|
|
170
|
-
rootElems: [lowered.moduleElem],
|
|
171
|
-
conditions: {},
|
|
172
|
-
extracting: false,
|
|
173
|
-
});
|
|
174
|
-
const linked = SrcMapBuilder.build([srcBuilder]).dest.text;
|
|
175
|
-
expectTrimmedMatch(linked, expected);
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
test("lower binding structs with conflicting root name", async () => {
|
|
179
|
-
const src = `
|
|
180
|
-
struct Bindings {
|
|
181
|
-
@group(0) @binding(0) particles: ptr<storage, array<f32>, read_write>,
|
|
182
|
-
}
|
|
183
|
-
const particles = 7;
|
|
184
|
-
fn main(b: Bindings) {
|
|
185
|
-
let x = b.particles;
|
|
186
|
-
}
|
|
187
|
-
`;
|
|
188
|
-
|
|
189
|
-
const expected = `
|
|
190
|
-
@group(0) @binding(0) var<storage, read_write> particles0 : array<f32>;
|
|
191
|
-
|
|
192
|
-
const particles = 7;
|
|
193
|
-
fn main() {
|
|
194
|
-
let x = particles0;
|
|
195
|
-
}
|
|
196
|
-
`;
|
|
197
|
-
|
|
198
|
-
const opts = { config: { plugins: [bindingStructsPlugin()] } };
|
|
199
|
-
const linked = await linkTestOpts(opts, src);
|
|
200
|
-
expectTrimmedMatch(linked, expected);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("lower 5 bindings", async () => {
|
|
204
|
-
const src = `
|
|
205
|
-
struct Uniforms {
|
|
206
|
-
foo: u32
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
struct MyBindings {
|
|
210
|
-
@group(0) @binding(0) particles: ptr<storage, array<u32>, read_write>,
|
|
211
|
-
@group(0) @binding(1) uniforms: ptr<uniform, Uniforms>,
|
|
212
|
-
@group(0) @binding(2) tex: texture_2d<rgba8unorm>,
|
|
213
|
-
@group(0) @binding(3) samp: sampler,
|
|
214
|
-
@group(0) @binding(4) stTex: texture_storage_2d<rgba8unorm, read>,
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
@compute fn main(b: MyBindings) {
|
|
218
|
-
b.particles[0] = b.uniforms.foo;
|
|
219
|
-
}
|
|
220
|
-
`;
|
|
221
|
-
|
|
222
|
-
const expected = `
|
|
223
|
-
@group(0) @binding(0) var<storage, read_write> particles : array<u32>;
|
|
224
|
-
@group(0) @binding(1) var<uniform> uniforms : Uniforms;
|
|
225
|
-
@group(0) @binding(2) var tex : texture_2d<rgba8unorm>;
|
|
226
|
-
@group(0) @binding(3) var samp : sampler;
|
|
227
|
-
@group(0) @binding(4) var stTex : texture_storage_2d<rgba8unorm, read>;
|
|
228
|
-
|
|
229
|
-
struct Uniforms { foo: u32 }
|
|
230
|
-
@compute fn main() {
|
|
231
|
-
particles[0] = uniforms.foo;
|
|
232
|
-
}
|
|
233
|
-
`;
|
|
234
|
-
|
|
235
|
-
const opts = { config: { plugins: [bindingStructsPlugin()] } };
|
|
236
|
-
const linked = await linkTestOpts(opts, src);
|
|
237
|
-
expectTrimmedMatch(linked, expected);
|
|
238
|
-
});
|
|
File without changes
|