wesl 0.6.9 → 0.6.15

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.
Files changed (117) hide show
  1. package/dist/index.d.ts +977 -0
  2. package/dist/index.js +2966 -4353
  3. package/package.json +20 -27
  4. package/src/AbstractElems.ts +13 -2
  5. package/src/BindIdents.ts +268 -220
  6. package/src/ClickableError.ts +1 -1
  7. package/src/Conditions.ts +121 -22
  8. package/src/FlattenTreeImport.ts +2 -2
  9. package/src/LinkedWesl.ts +8 -4
  10. package/src/Linker.ts +17 -6
  11. package/src/LinkerUtil.ts +3 -1
  12. package/src/LiveDeclarations.ts +1 -1
  13. package/src/LowerAndEmit.ts +44 -59
  14. package/src/ParseWESL.ts +34 -8
  15. package/src/ParsedRegistry.ts +11 -10
  16. package/src/RawEmit.ts +4 -0
  17. package/src/Scope.ts +10 -27
  18. package/src/TransformBindingStructs.ts +6 -6
  19. package/src/WESLCollect.ts +26 -25
  20. package/src/debug/ASTtoString.ts +13 -3
  21. package/src/debug/ImportToString.ts +2 -2
  22. package/src/debug/LineWrapper.ts +6 -6
  23. package/src/debug/ScopeToString.ts +2 -2
  24. package/src/index.ts +16 -16
  25. package/src/parse/AttributeGrammar.ts +232 -0
  26. package/src/parse/ImportGrammar.ts +62 -30
  27. package/src/parse/WeslExpression.ts +5 -5
  28. package/src/parse/WeslGrammar.ts +26 -190
  29. package/src/parse/WeslStream.ts +5 -3
  30. package/src/test/BindWESL.test.ts +35 -2
  31. package/src/test/BulkTests.test.ts +51 -0
  32. package/src/test/ConditionLinking.test.ts +23 -0
  33. package/src/test/ConditionalElif.test.ts +235 -0
  34. package/src/test/ConditionalTranslationCases.test.ts +17 -3
  35. package/src/test/FilterValidElements.test.ts +203 -0
  36. package/src/test/ImportCases.test.ts +5 -2
  37. package/src/test/ImportSyntaxCases.test.ts +2 -2
  38. package/src/test/LinkGlob.test.ts +1 -1
  39. package/src/test/Linker.test.ts +2 -2
  40. package/src/test/ParseComments.test.ts +2 -2
  41. package/src/test/ParseConditions.test.ts +257 -0
  42. package/src/test/ParseElif.test.ts +105 -0
  43. package/src/test/PathUtil.test.ts +1 -1
  44. package/src/test/Reflection.test.ts +1 -1
  45. package/src/test/ScopeWESL.test.ts +1 -1
  46. package/src/test/StripWesl.ts +34 -0
  47. package/src/test/TestLink.ts +2 -2
  48. package/src/test/TestUtil.ts +8 -8
  49. package/src/test/Tokenizer.test.ts +34 -34
  50. package/src/test/TransformBindingStructs.test.ts +8 -3
  51. package/src/test/Util.test.ts +1 -1
  52. package/dist/index.js.map +0 -1
  53. package/dist/minified.js +0 -3628
  54. package/dist/minified.js.map +0 -1
  55. package/dist/tools/packages/wesl/src/AbstractElems.d.ts +0 -323
  56. package/dist/tools/packages/wesl/src/Assertions.d.ts +0 -27
  57. package/dist/tools/packages/wesl/src/BindIdents.d.ts +0 -78
  58. package/dist/tools/packages/wesl/src/ClickableError.d.ts +0 -22
  59. package/dist/tools/packages/wesl/src/Conditions.d.ts +0 -6
  60. package/dist/tools/packages/wesl/src/FlattenTreeImport.d.ts +0 -11
  61. package/dist/tools/packages/wesl/src/LinkedWesl.d.ts +0 -50
  62. package/dist/tools/packages/wesl/src/Linker.d.ts +0 -88
  63. package/dist/tools/packages/wesl/src/LinkerUtil.d.ts +0 -3
  64. package/dist/tools/packages/wesl/src/LiveDeclarations.d.ts +0 -12
  65. package/dist/tools/packages/wesl/src/LowerAndEmit.d.ts +0 -31
  66. package/dist/tools/packages/wesl/src/Mangler.d.ts +0 -39
  67. package/dist/tools/packages/wesl/src/ParseWESL.d.ts +0 -59
  68. package/dist/tools/packages/wesl/src/ParsedRegistry.d.ts +0 -24
  69. package/dist/tools/packages/wesl/src/PathUtil.d.ts +0 -6
  70. package/dist/tools/packages/wesl/src/RawEmit.d.ts +0 -6
  71. package/dist/tools/packages/wesl/src/Reflection.d.ts +0 -45
  72. package/dist/tools/packages/wesl/src/Scope.d.ts +0 -91
  73. package/dist/tools/packages/wesl/src/StandardTypes.d.ts +0 -13
  74. package/dist/tools/packages/wesl/src/TransformBindingStructs.d.ts +0 -52
  75. package/dist/tools/packages/wesl/src/Util.d.ts +0 -43
  76. package/dist/tools/packages/wesl/src/WESLCollect.d.ts +0 -103
  77. package/dist/tools/packages/wesl/src/WeslBundle.d.ts +0 -13
  78. package/dist/tools/packages/wesl/src/WeslDevice.d.ts +0 -29
  79. package/dist/tools/packages/wesl/src/debug/ASTtoString.d.ts +0 -5
  80. package/dist/tools/packages/wesl/src/debug/ImportToString.d.ts +0 -2
  81. package/dist/tools/packages/wesl/src/debug/LineWrapper.d.ts +0 -21
  82. package/dist/tools/packages/wesl/src/debug/ScopeToString.d.ts +0 -6
  83. package/dist/tools/packages/wesl/src/index.d.ts +0 -16
  84. package/dist/tools/packages/wesl/src/parse/ImportGrammar.d.ts +0 -5
  85. package/dist/tools/packages/wesl/src/parse/Keywords.d.ts +0 -4
  86. package/dist/tools/packages/wesl/src/parse/WeslBaseGrammar.d.ts +0 -5
  87. package/dist/tools/packages/wesl/src/parse/WeslExpression.d.ts +0 -18
  88. package/dist/tools/packages/wesl/src/parse/WeslGrammar.d.ts +0 -80
  89. package/dist/tools/packages/wesl/src/parse/WeslStream.d.ts +0 -45
  90. package/dist/tools/packages/wesl/src/test/BindWESL.test.d.ts +0 -1
  91. package/dist/tools/packages/wesl/src/test/ConditionLinking.test.d.ts +0 -1
  92. package/dist/tools/packages/wesl/src/test/ConditionalTranslationCases.test.d.ts +0 -1
  93. package/dist/tools/packages/wesl/src/test/ErrorLogging.test.d.ts +0 -1
  94. package/dist/tools/packages/wesl/src/test/Expression.test.d.ts +0 -1
  95. package/dist/tools/packages/wesl/src/test/FlattenTreeImport.test.d.ts +0 -1
  96. package/dist/tools/packages/wesl/src/test/ImportCases.test.d.ts +0 -1
  97. package/dist/tools/packages/wesl/src/test/ImportSyntaxCases.test.d.ts +0 -1
  98. package/dist/tools/packages/wesl/src/test/LinkGlob.test.d.ts +0 -1
  99. package/dist/tools/packages/wesl/src/test/LinkPackage.test.d.ts +0 -1
  100. package/dist/tools/packages/wesl/src/test/Linker.test.d.ts +0 -1
  101. package/dist/tools/packages/wesl/src/test/Mangling.test.d.ts +0 -1
  102. package/dist/tools/packages/wesl/src/test/ParseComments.test.d.ts +0 -1
  103. package/dist/tools/packages/wesl/src/test/ParseConditions.test.d.ts +0 -1
  104. package/dist/tools/packages/wesl/src/test/ParseError.test.d.ts +0 -1
  105. package/dist/tools/packages/wesl/src/test/ParseWESL.test.d.ts +0 -1
  106. package/dist/tools/packages/wesl/src/test/PathUtil.test.d.ts +0 -1
  107. package/dist/tools/packages/wesl/src/test/Reflection.test.d.ts +0 -1
  108. package/dist/tools/packages/wesl/src/test/ScopeWESL.test.d.ts +0 -1
  109. package/dist/tools/packages/wesl/src/test/TestLink.d.ts +0 -21
  110. package/dist/tools/packages/wesl/src/test/TestSetup.d.ts +0 -1
  111. package/dist/tools/packages/wesl/src/test/TestUtil.d.ts +0 -42
  112. package/dist/tools/packages/wesl/src/test/Tokenizer.test.d.ts +0 -1
  113. package/dist/tools/packages/wesl/src/test/TransformBindingStructs.test.d.ts +0 -1
  114. package/dist/tools/packages/wesl/src/test/Util.test.d.ts +0 -1
  115. package/dist/tools/packages/wesl/src/test/VirtualModules.test.d.ts +0 -1
  116. package/dist/tools/packages/wesl/src/test/WeslDevice.test.d.ts +0 -1
  117. package/dist/tools/packages/wesl/src/vlq/vlq.d.ts +0 -11
@@ -0,0 +1,977 @@
1
+ import { AppState, ParseError, Span, SrcMap, Stream, TypedToken } from "mini-parse";
2
+
3
+ //#region src/LiveDeclarations.d.ts
4
+ /** decls currently visible in this scope */
5
+ interface LiveDecls {
6
+ /** decls currently visible in this scope */
7
+ decls: Map<string, DeclIdent>;
8
+ /** live decls in the parent scope. null for the modue root scope */
9
+ parent?: LiveDecls | null;
10
+ }
11
+ //#endregion
12
+ //#region src/FlattenTreeImport.d.ts
13
+ interface FlatImport {
14
+ importPath: string[];
15
+ modulePath: string[];
16
+ }
17
+ //#endregion
18
+ //#region src/WESLCollect.d.ts
19
+ type OpenElem<T extends ContainerElem = ContainerElem> = Pick<T, "kind" | "contents">;
20
+ //#endregion
21
+ //#region src/ParseWESL.d.ts
22
+ /** result of a parse for one wesl module (e.g. one .wesl file)
23
+ *
24
+ * The parser constructs the AST constructed into three sections
25
+ * for convenient access by the binding stage.
26
+ * - import statements
27
+ * - language elements (fn, struct, etc)
28
+ * - scopes
29
+ *
30
+ */
31
+ interface WeslAST {
32
+ /** source text for this module */
33
+ srcModule: SrcModule;
34
+ /** root module element */
35
+ moduleElem: ModuleElem;
36
+ /** root scope for this module */
37
+ rootScope: Scope;
38
+ /** imports found in this module */
39
+ imports: ImportStatement[];
40
+ /** module level const_assert statements */
41
+ moduleAsserts?: ConstAssertElem[];
42
+ }
43
+ /** an extended version of the AST */
44
+ interface BindingAST extends WeslAST {
45
+ _flatImports?: FlatImport[];
46
+ }
47
+ /** stable and unstable state used during parsing */
48
+ interface WeslParseState extends AppState<WeslParseContext, StableState> {
49
+ context: WeslParseContext;
50
+ stable: StableState;
51
+ }
52
+ /** stable values used or accumulated during parsing */
53
+ type StableState = WeslAST;
54
+ /** unstable values used during parse collection */
55
+ interface WeslParseContext {
56
+ scope: Scope;
57
+ openElems: OpenElem[];
58
+ }
59
+ /**
60
+ * An error when parsing WESL fails. Designed to be human-readable.
61
+ */
62
+ declare class WeslParseError extends Error {
63
+ span: Span;
64
+ src: SrcModule;
65
+ constructor(opts: {
66
+ cause: ParseError;
67
+ src: SrcModule;
68
+ });
69
+ }
70
+ /** Parse a WESL file. Throws on error. */
71
+ declare function parseSrcModule(srcModule: SrcModule): WeslAST;
72
+ declare function blankWeslParseState(srcModule: SrcModule): WeslParseState;
73
+ declare function syntheticWeslParseState(): WeslParseState;
74
+ /** @return a flattened form of the import tree for convenience in binding idents. */
75
+ declare function flatImports(ast: BindingAST, conditions?: Conditions): FlatImport[];
76
+ //#endregion
77
+ //#region src/Scope.d.ts
78
+ interface SrcModule {
79
+ /** module path "rand_pkg::sub::foo", or "package::main" */
80
+ modulePath: string;
81
+ /** file path to the module for user error reporting e.g "rand_pkg:sub/foo.wesl", or "./sub/foo.wesl" */
82
+ debugFilePath: string;
83
+ /** original src for module */
84
+ src: string;
85
+ }
86
+ /** a src declaration or reference to an ident */
87
+ type Ident = DeclIdent | RefIdent;
88
+ /** LATER change this to a Map, so that `toString` isn't accidentally a condition */
89
+ type Conditions = Record<string, boolean>;
90
+ interface IdentBase {
91
+ originalName: string;
92
+ id?: number;
93
+ }
94
+ interface RefIdent extends IdentBase {
95
+ kind: "ref";
96
+ refersTo?: Ident;
97
+ std?: true;
98
+ ast: WeslAST;
99
+ refIdentElem: RefIdentElem;
100
+ }
101
+ interface DeclIdent extends IdentBase {
102
+ kind: "decl";
103
+ /** name in the output code */
104
+ mangledName?: string;
105
+ /** link to AST so that we can traverse scopes and know what elems to emit */
106
+ declElem?: DeclarationElem;
107
+ /** scope in which this declaration is found */
108
+ containingScope: Scope;
109
+ /** scope for the references within this declaration
110
+ * (only needed for global decls.)
111
+ * if this decl is included in the link, dependentScope holds other refIdents that should be included too */
112
+ dependentScope?: Scope;
113
+ /** true if this is a global declaration (e.g. not a local variable) */
114
+ isGlobal: boolean;
115
+ /** To figure out which module this declaration is from. */
116
+ srcModule: SrcModule;
117
+ }
118
+ /** tree of ident references, organized by lexical scope and partialScope . */
119
+ type Scope = LexicalScope | PartialScope;
120
+ /** A wgsl scope */
121
+ interface LexicalScope extends ScopeBase {
122
+ kind: "scope";
123
+ /**
124
+ * Efficient access to declarations in this scope.
125
+ * constructed on demand, for module root scopes only */
126
+ _scopeDecls?: LiveDecls;
127
+ /** Cached list of valid root declarations after conditional filtering.
128
+ * Populated on first access for module root scopes. */
129
+ _validRootDecls?: DeclIdent[];
130
+ }
131
+ /** A synthetic partial scope to contain @if conditioned idents.
132
+ * PartialScope idents are considered to be in the wgsl lexical scope of their parent. */
133
+ interface PartialScope extends ScopeBase {
134
+ kind: "partial";
135
+ }
136
+ /** common scope elements */
137
+ interface ScopeBase {
138
+ /** id for debugging */
139
+ id: number;
140
+ /** null for root scope in a module */
141
+ parent: Scope | null;
142
+ contents: (Ident | Scope)[];
143
+ /** Conditional attribute (@if or @else) for this scope */
144
+ condAttribute?: IfAttribute | ElifAttribute | ElseAttribute;
145
+ }
146
+ /** Combine two scope siblings.
147
+ * The first scope is mutated to append the contents of the second. */
148
+ declare function mergeScope(a: Scope, b: Scope | undefined): void;
149
+ /** reset scope and ident debugging ids */
150
+ declare function resetScopeIds(): void;
151
+ declare function nextIdentId(): number;
152
+ /** make a new Scope object */
153
+ declare function emptyScope(parent: Scope | null, kind?: Scope["kind"]): Omit<Scope, "condAttribute">;
154
+ /** For debugging,
155
+ * @return true if a scope is in the rootScope tree somewhere */
156
+ declare function containsScope(rootScope: Scope, scope: Scope): boolean;
157
+ /** @returns true if the provided element of a Scope
158
+ * is itself a Scope (and not an Ident) */
159
+ declare function childScope(child: Scope | Ident): child is Scope;
160
+ /** @returns true if the provided element of a Scope
161
+ * is an Ident (and not a child Scope) */
162
+ declare function childIdent(child: Scope | Ident): child is Ident;
163
+ //#endregion
164
+ //#region src/AbstractElems.d.ts
165
+ /**
166
+ * Structures to describe the 'interesting' parts of a WESL source file.
167
+ *
168
+ * The parts of the source that need to analyze further in the linker
169
+ * are pulled out into these structures.
170
+ *
171
+ * The parts that are uninteresting the the linker are recorded
172
+ * as 'TextElem' nodes, which are generally just copied to the output WGSL
173
+ * along with their containing element.
174
+ */
175
+ type AbstractElem = GrammarElem | SyntheticElem;
176
+ type GrammarElem = ContainerElem | TerminalElem;
177
+ type ContainerElem = AttributeElem | AliasElem | ConstAssertElem | ConstElem | UnknownExpressionElem | SimpleMemberRef | FnElem | TypedDeclElem | GlobalVarElem | LetElem | ModuleElem | OverrideElem | FnParamElem | StructElem | StructMemberElem | StuffElem | TypeRefElem | VarElem | StatementElem | SwitchClauseElem;
178
+ /** Inspired by https://github.com/wgsl-tooling-wg/wesl-rs/blob/3b2434eac1b2ebda9eb8bfb25f43d8600d819872/crates/wgsl-parse/src/syntax.rs#L364 */
179
+ type ExpressionElem = Literal | TranslateTimeFeature | RefIdentElem | ParenthesizedExpression | ComponentExpression | ComponentMemberExpression | UnaryExpression | BinaryExpression | FunctionCallExpression;
180
+ type TerminalElem = DirectiveElem | DeclIdentElem | NameElem | RefIdentElem | TextElem | ImportElem;
181
+ type GlobalDeclarationElem = AliasElem | ConstElem | FnElem | GlobalVarElem | OverrideElem | StructElem;
182
+ type DeclarationElem = GlobalDeclarationElem | FnParamElem | VarElem;
183
+ type ElemWithAttributes = Extract<AbstractElem, HasAttributes>;
184
+ interface AbstractElemBase {
185
+ kind: AbstractElem["kind"];
186
+ start: number;
187
+ end: number;
188
+ }
189
+ interface ElemWithContentsBase extends AbstractElemBase {
190
+ contents: AbstractElem[];
191
+ }
192
+ interface HasAttributes {
193
+ attributes?: AttributeElem[];
194
+ }
195
+ /**
196
+ * a raw bit of text in WESL source that's typically copied to the linked WGSL.
197
+ * e.g. a keyword like 'var'
198
+ * or a phrase we needn't analyze further like '@diagnostic(off,derivative_uniformity)'
199
+ */
200
+ interface TextElem extends AbstractElemBase {
201
+ kind: "text";
202
+ srcModule: SrcModule;
203
+ }
204
+ /** a name that doesn't need to be an Ident
205
+ * e.g.
206
+ * - a struct member name
207
+ * - a diagnostic rule name
208
+ * - an enable-extension name
209
+ * - an interpolation sampling name
210
+ */
211
+ interface NameElem extends AbstractElemBase {
212
+ kind: "name";
213
+ name: string;
214
+ }
215
+ /** an identifier that 'refers to' a declaration (aka a symbol reference) */
216
+ interface RefIdentElem extends AbstractElemBase {
217
+ kind: RefIdent["kind"];
218
+ ident: RefIdent;
219
+ srcModule: SrcModule;
220
+ }
221
+ /** a declaration identifier (aka a symbol declaration) */
222
+ interface DeclIdentElem extends AbstractElemBase {
223
+ kind: DeclIdent["kind"];
224
+ ident: DeclIdent;
225
+ srcModule: SrcModule;
226
+ }
227
+ /** Holds an import statement, and has a span */
228
+ interface ImportElem extends AbstractElemBase, HasAttributes {
229
+ kind: "import";
230
+ imports: ImportStatement;
231
+ }
232
+ /**
233
+ * An import statement, which is tree shaped.
234
+ * `import foo::bar::{baz, cat as neko};
235
+ */
236
+ interface ImportStatement {
237
+ kind: "import-statement";
238
+ segments: ImportSegment[];
239
+ finalSegment: ImportCollection | ImportItem;
240
+ }
241
+ /**
242
+ * A collection of import trees.
243
+ * `{baz, cat as neko}`
244
+ */
245
+ interface ImportSegment {
246
+ kind: "import-segment";
247
+ name: string;
248
+ }
249
+ /**
250
+ * A primitive segment in an import statement.
251
+ * `foo`
252
+ */
253
+ interface ImportCollection {
254
+ kind: "import-collection";
255
+ subtrees: ImportStatement[];
256
+ }
257
+ /**
258
+ * A renamed item at the end of an import statement.
259
+ * `cat as neko`
260
+ */
261
+ interface ImportItem {
262
+ kind: "import-item";
263
+ name: string;
264
+ as?: string;
265
+ }
266
+ /** generated element, produced after parsing and binding */
267
+ interface SyntheticElem {
268
+ kind: "synthetic";
269
+ text: string;
270
+ }
271
+ /** a declaration identifer with a possible type */
272
+ interface TypedDeclElem extends ElemWithContentsBase {
273
+ kind: "typeDecl";
274
+ decl: DeclIdentElem;
275
+ typeRef?: TypeRefElem;
276
+ typeScope?: Scope;
277
+ }
278
+ /** an alias statement */
279
+ interface AliasElem extends ElemWithContentsBase, HasAttributes {
280
+ kind: "alias";
281
+ name: DeclIdentElem;
282
+ typeRef: TypeRefElem;
283
+ }
284
+ /** an attribute like '@compute' or '@binding(0)' */
285
+ interface AttributeElem extends ElemWithContentsBase {
286
+ kind: "attribute";
287
+ attribute: Attribute;
288
+ }
289
+ type Attribute = StandardAttribute | InterpolateAttribute | BuiltinAttribute | DiagnosticAttribute | IfAttribute | ElifAttribute | ElseAttribute;
290
+ interface StandardAttribute {
291
+ kind: "@attribute";
292
+ name: string;
293
+ params?: UnknownExpressionElem[];
294
+ }
295
+ interface InterpolateAttribute {
296
+ kind: "@interpolate";
297
+ params: NameElem[];
298
+ }
299
+ interface BuiltinAttribute {
300
+ kind: "@builtin";
301
+ param: NameElem;
302
+ }
303
+ interface DiagnosticAttribute {
304
+ kind: "@diagnostic";
305
+ severity: NameElem;
306
+ rule: [NameElem, NameElem | null];
307
+ }
308
+ interface IfAttribute {
309
+ kind: "@if";
310
+ param: TranslateTimeExpressionElem;
311
+ }
312
+ interface ElifAttribute {
313
+ kind: "@elif";
314
+ param: TranslateTimeExpressionElem;
315
+ }
316
+ interface ElseAttribute {
317
+ kind: "@else";
318
+ }
319
+ /** a const_assert statement */
320
+ interface ConstAssertElem extends ElemWithContentsBase, HasAttributes {
321
+ kind: "assert";
322
+ }
323
+ /** a const declaration */
324
+ interface ConstElem extends ElemWithContentsBase, HasAttributes {
325
+ kind: "const";
326
+ name: TypedDeclElem;
327
+ }
328
+ /** an expression w/o special handling, used inside attribute parameters */
329
+ interface UnknownExpressionElem extends ElemWithContentsBase {
330
+ kind: "expression";
331
+ }
332
+ /** an expression that can be safely evaluated at compile time */
333
+ interface TranslateTimeExpressionElem {
334
+ kind: "translate-time-expression";
335
+ expression: ExpressionElem;
336
+ span: Span;
337
+ }
338
+ /** A literal value in WESL source. A boolean or a number. */
339
+ interface Literal {
340
+ kind: "literal";
341
+ value: string;
342
+ span: Span;
343
+ }
344
+ /** `words`s inside `@if` */
345
+ interface TranslateTimeFeature {
346
+ kind: "translate-time-feature";
347
+ name: string;
348
+ span: Span;
349
+ }
350
+ /** (expr) */
351
+ interface ParenthesizedExpression {
352
+ kind: "parenthesized-expression";
353
+ expression: ExpressionElem;
354
+ }
355
+ /** `foo[expr]` */
356
+ interface ComponentExpression {
357
+ kind: "component-expression";
358
+ base: ExpressionElem;
359
+ access: ExpressionElem;
360
+ }
361
+ /** `foo.member` */
362
+ interface ComponentMemberExpression {
363
+ kind: "component-member-expression";
364
+ base: ExpressionElem;
365
+ access: NameElem;
366
+ }
367
+ /** `+foo` */
368
+ interface UnaryExpression {
369
+ kind: "unary-expression";
370
+ operator: UnaryOperator;
371
+ expression: ExpressionElem;
372
+ }
373
+ /** `foo + bar` */
374
+ interface BinaryExpression {
375
+ kind: "binary-expression";
376
+ operator: BinaryOperator;
377
+ left: ExpressionElem;
378
+ right: ExpressionElem;
379
+ }
380
+ /** `foo(arg, arg)` */
381
+ interface FunctionCallExpression {
382
+ kind: "call-expression";
383
+ function: RefIdentElem;
384
+ arguments: ExpressionElem[];
385
+ }
386
+ interface UnaryOperator {
387
+ value: "!" | "&" | "*" | "-" | "~";
388
+ span: Span;
389
+ }
390
+ interface BinaryOperator {
391
+ value: ("||" | "&&" | "+" | "-" | "*" | "/" | "%" | "==") | ("!=" | "<" | "<=" | ">" | ">=" | "|" | "&" | "^") | ("<<" | ">>");
392
+ span: Span;
393
+ }
394
+ type DirectiveVariant = DiagnosticDirective | EnableDirective | RequiresDirective;
395
+ interface DirectiveElem extends AbstractElemBase, HasAttributes {
396
+ kind: "directive";
397
+ directive: DirectiveVariant;
398
+ }
399
+ interface DiagnosticDirective {
400
+ kind: "diagnostic";
401
+ severity: NameElem;
402
+ rule: [NameElem, NameElem | null];
403
+ }
404
+ interface EnableDirective {
405
+ kind: "enable";
406
+ extensions: NameElem[];
407
+ }
408
+ interface RequiresDirective {
409
+ kind: "requires";
410
+ extensions: NameElem[];
411
+ }
412
+ /** a function declaration */
413
+ interface FnElem extends ElemWithContentsBase, HasAttributes {
414
+ kind: "fn";
415
+ name: DeclIdentElem;
416
+ params: FnParamElem[];
417
+ body: StatementElem;
418
+ returnAttributes?: AttributeElem[];
419
+ returnType?: TypeRefElem;
420
+ }
421
+ /** a global variable declaration (at the root level) */
422
+ interface GlobalVarElem extends ElemWithContentsBase, HasAttributes {
423
+ kind: "gvar";
424
+ name: TypedDeclElem;
425
+ }
426
+ /** an entire file */
427
+ interface ModuleElem extends ElemWithContentsBase {
428
+ kind: "module";
429
+ }
430
+ /** an override declaration */
431
+ interface OverrideElem extends ElemWithContentsBase, HasAttributes {
432
+ kind: "override";
433
+ name: TypedDeclElem;
434
+ }
435
+ /** a parameter in a function declaration */
436
+ interface FnParamElem extends ElemWithContentsBase, HasAttributes {
437
+ kind: "param";
438
+ name: TypedDeclElem;
439
+ }
440
+ /** simple references to structures, like myStruct.bar
441
+ * (used for transforming refs to binding structs) */
442
+ interface SimpleMemberRef extends ElemWithContentsBase {
443
+ kind: "memberRef";
444
+ name: RefIdentElem;
445
+ member: NameElem;
446
+ extraComponents?: StuffElem;
447
+ }
448
+ /** a struct declaration */
449
+ interface StructElem extends ElemWithContentsBase, HasAttributes {
450
+ kind: "struct";
451
+ name: DeclIdentElem;
452
+ members: StructMemberElem[];
453
+ bindingStruct?: true;
454
+ }
455
+ /** generic container of other elements */
456
+ interface StuffElem extends ElemWithContentsBase {
457
+ kind: "stuff";
458
+ }
459
+ /** a struct declaration that's been marked as a bindingStruct */
460
+ interface BindingStructElem extends StructElem {
461
+ bindingStruct: true;
462
+ entryFn?: FnElem;
463
+ }
464
+ /** a member of a struct declaration */
465
+ interface StructMemberElem extends ElemWithContentsBase, HasAttributes {
466
+ kind: "member";
467
+ name: NameElem;
468
+ typeRef: TypeRefElem;
469
+ mangledVarName?: string;
470
+ }
471
+ type TypeTemplateParameter = TypeRefElem | UnknownExpressionElem;
472
+ /** a reference to a type, like 'f32', or 'MyStruct', or 'ptr<storage, array<f32>, read_only>' */
473
+ interface TypeRefElem extends ElemWithContentsBase {
474
+ kind: "type";
475
+ name: RefIdent;
476
+ templateParams?: TypeTemplateParameter[];
477
+ }
478
+ /** a variable declaration */
479
+ interface VarElem extends ElemWithContentsBase, HasAttributes {
480
+ kind: "var";
481
+ name: TypedDeclElem;
482
+ }
483
+ interface LetElem extends ElemWithContentsBase, HasAttributes {
484
+ kind: "let";
485
+ name: TypedDeclElem;
486
+ }
487
+ interface StatementElem extends ElemWithContentsBase, HasAttributes {
488
+ kind: "statement";
489
+ }
490
+ interface SwitchClauseElem extends ElemWithContentsBase, HasAttributes {
491
+ kind: "switch-clause";
492
+ }
493
+ //#endregion
494
+ //#region src/WeslDevice.d.ts
495
+ /**
496
+ * A {@link GPUDevice} with extensions for WESL. Created with {@link makeWeslDevice}.
497
+ * Used to make error reporting point at the orignal WESL sources.
498
+ */
499
+ interface WeslDevice extends GPUDevice {
500
+ /**
501
+ * Attaches an error to the current error scope (created by {@link GPUDevice.pushErrorScope}).
502
+ * If there is no error scope, it reports the error as a `'uncapturederror'`
503
+ */
504
+ injectError(type: GPUErrorFilter, error: Promise<GPUError | null>): void;
505
+ }
506
+ /**
507
+ * Creates {@link WeslDevice} for usage with WESL.
508
+ * Does not impact your existing code, wherever a {@link GPUDevice} can be used,
509
+ * a {@link WeslDevice} is also valid.
510
+ *
511
+ * WESL uses a {@link WeslDevice} to display errors referencing the WESL source
512
+ * instead of referencing the generated WGSL code.
513
+ */
514
+ declare function requestWeslDevice(adapter: GPUAdapter | null, descriptor?: GPUDeviceDescriptor): Promise<WeslDevice>;
515
+ /**
516
+ * Mutates a {@link GPUDevice} for usage with WESL.
517
+ * Does not impact your existing code, wherever a {@link GPUDevice} can be used,
518
+ * a {@link WeslDevice} is also valid.
519
+ *
520
+ * WESL uses a {@link WeslDevice} to display errors referencing the WESL source
521
+ * instead of referencing the generated WGSL code.
522
+ */
523
+ declare function makeWeslDevice(device: GPUDevice): WeslDevice;
524
+ //#endregion
525
+ //#region src/LinkedWesl.d.ts
526
+ /** Results of shader compilation. Has {@link WeslGPUCompilationMessage}
527
+ * which are aware of the WESL module that an error was thrown from. */
528
+ interface WeslGPUCompilationInfo extends GPUCompilationInfo {
529
+ messages: WeslGPUCompilationMessage[];
530
+ }
531
+ interface WeslGPUCompilationMessage extends GPUCompilationMessage {
532
+ module: {
533
+ url: string;
534
+ text?: string;
535
+ };
536
+ }
537
+ /**
538
+ * A {@link GPUValidationError} with an inner error (for a stack trace).
539
+ * Can also point at a WESL source file.
540
+ */
541
+ interface ExtendedGPUValidationError extends GPUValidationError {
542
+ cause?: Error;
543
+ compilationInfo?: WeslGPUCompilationInfo;
544
+ }
545
+ /**
546
+ * Multiple WESL files that have been linked together to produce WGSL code.
547
+ *
548
+ * Call {@link LinkedWesl.createShaderModule} on a {@link WeslDevice}
549
+ * to make the error reporting aware of the WESL code.
550
+ */
551
+ declare class LinkedWesl {
552
+ sourceMap: SrcMap;
553
+ constructor(sourceMap: SrcMap);
554
+ /**
555
+ * Creates a {@link GPUShaderModule}.
556
+ * When errors occur, they will point at the original WESL source code.
557
+ *
558
+ * The compilation info {@link GPUShaderModule.getCompilationInfo}
559
+ * can be remapped with {@link mapGPUCompilationInfo}
560
+ * @param device GPUDevice. Preferably a {@link WeslDevice} for better error reporting.
561
+ * @param descriptor - Description of the {@link GPUShaderModule} to create.
562
+ */
563
+ createShaderModule(device: GPUDevice | WeslDevice, descriptor?: Omit<GPUShaderModuleDescriptor, "code">): GPUShaderModule;
564
+ /**
565
+ * Use {@link LinkedWesl.createShaderModule} for a
566
+ * better error reporting experience.
567
+ */
568
+ get dest(): string;
569
+ /** Turns raw compilation info into compilation info
570
+ * that points at the WESL sources. */
571
+ mapGPUCompilationInfo(compilationInfo: GPUCompilationInfo): WeslGPUCompilationInfo;
572
+ private mapGPUCompilationMessage;
573
+ }
574
+ //#endregion
575
+ //#region src/Mangler.d.ts
576
+ /**
577
+ * A function for constructing a unique identifier name for a global declaration.
578
+ * Global names must be unique in the linked wgsl.
579
+ *
580
+ * Three manglers are currently available:
581
+ * . minimalMangle preserves original source names where possible
582
+ * . underscoreMangle constructs long but predictable names for every declaration
583
+ * . lengthPrefixMangle constructs long but predictable names for every declaration
584
+ */
585
+ type ManglerFn = (/** global declaration that needs a name */
586
+ decl: DeclIdent, /** module that contains the declaration */
587
+ srcModule: SrcModule, /** name at use site (possibly import as renamed from declaration) */
588
+ proposedName: string, /** current set of mangled root level names for the linked result (read only) */
589
+ globalNames: Set<string>) => string;
590
+ /**
591
+ * Construct a globally unique name based on the declaration
592
+ * module path separated by underscores.
593
+ * Corresponds to "Underscore-count mangling" from [NameMangling.md](https://github.com/wgsl-tooling-wg/wesl-spec/blob/main/NameMangling.md)
594
+ */
595
+ declare function underscoreMangle(decl: DeclIdent, srcModule: SrcModule): string;
596
+ /**
597
+ * Construct a globally unique name based on the declaration
598
+ */
599
+ declare function lengthPrefixMangle(decl: DeclIdent, srcModule: SrcModule): string;
600
+ /**
601
+ * ManglerFn to construct a globally unique name
602
+ * using the requested name plus a uniquing number suffix if necessary
603
+ */
604
+ declare function minimalMangle(_d: DeclIdent, _s: SrcModule, proposedName: string, globalNames: Set<string>): string;
605
+ /**
606
+ * Construct a globally unique name by using the requested name if possible
607
+ * and appending a number suffix necessary
608
+ */
609
+ declare function minimallyMangledName(proposedName: string, globalNames: Set<string>): string;
610
+ //#endregion
611
+ //#region src/ParsedRegistry.d.ts
612
+ interface ParsedRegistry {
613
+ modules: Record<string, WeslAST>;
614
+ }
615
+ declare function parsedRegistry(): ParsedRegistry;
616
+ /** for debug */
617
+ declare function registryToString(registry: ParsedRegistry): string;
618
+ /** Look up a module with a flexible selector.
619
+ * :: separated module path, package::util
620
+ * / separated file path ./util.wesl (or ./util)
621
+ * - note: a file path should not include a weslRoot prefix, e.g. not ./shaders/util.wesl
622
+ * simpleName util
623
+ */
624
+ declare function selectModule(parsed: ParsedRegistry, selectPath: string, packageName?: string): WeslAST | undefined;
625
+ /**
626
+ * @param srcFiles map of source strings by file path
627
+ * key is '/' separated relative path (relative to srcRoot, not absolute file path )
628
+ * value is wesl source string
629
+ * @param registry add parsed modules to this registry
630
+ * @param packageName name of package
631
+ */
632
+ declare function parseIntoRegistry(srcFiles: Record<string, string>, registry: ParsedRegistry, packageName?: string, debugWeslRoot?: string): void;
633
+ declare function parseLibsIntoRegistry(libs: WeslBundle[], registry: ParsedRegistry): void;
634
+ //#endregion
635
+ //#region src/WeslBundle.d.ts
636
+ interface WeslBundle {
637
+ /** name of the package, e.g. random_wgsl */
638
+ name: string;
639
+ /** wesl edition of the code e.g. unstable_2025_1 */
640
+ edition: string;
641
+ /** map of wesl/wgsl modules:
642
+ * keys are file paths, relative to package root (e.g. "./lib.wgsl")
643
+ * values are wgsl/wesl code strings
644
+ */
645
+ modules: Record<string, string>;
646
+ /** packages referenced by this package */
647
+ dependencies?: WeslBundle[];
648
+ }
649
+ //#endregion
650
+ //#region src/Linker.d.ts
651
+ type LinkerTransform = (boundAST: TransformedAST) => TransformedAST;
652
+ interface WeslJsPlugin {
653
+ transform?: LinkerTransform;
654
+ }
655
+ interface TransformedAST extends Pick<WeslAST, "srcModule" | "moduleElem"> {
656
+ globalNames: Set<string>;
657
+ notableElems: Record<string, AbstractElem[]>;
658
+ }
659
+ interface LinkConfig {
660
+ plugins?: WeslJsPlugin[];
661
+ }
662
+ interface LinkParams {
663
+ /** record of file paths and wesl text for modules.
664
+ * key is module path or file path
665
+ * `package::foo::bar`, or './foo/bar.wesl', or './foo/bar'
666
+ * value is wesl src
667
+ *
668
+ *
669
+ * Only accepts unix-style, relative filesystem paths that are valid WGSL identifiers
670
+ * - Unix-style: Slashes as separators.
671
+ * - Valid WGSL identifiers: No backslashes, no `..`, or other non-identifier symbols.
672
+ * - Relative paths: They have to be relative to the wesl root.
673
+ */
674
+ weslSrc: Record<string, string>;
675
+ /** name of root wesl module
676
+ * for an app, the root module normally contains the '@compute', '@vertex' or '@fragment' entry points
677
+ * for a library, the root module defines the public api fo the library
678
+ * can be specified as file path (./main.wesl), a module path (package::main), or just a module name (main)
679
+ */
680
+ rootModuleName?: string;
681
+ /** For debug logging. Will be prepended to file paths. */
682
+ debugWeslRoot?: string;
683
+ /** runtime conditions for conditional compiling with @if and friends */
684
+ conditions?: Conditions;
685
+ /** libraries available for the link */
686
+ libs?: WeslBundle[];
687
+ /** generate wesl from code at runtime */
688
+ virtualLibs?: Record<string, VirtualLibraryFn>;
689
+ /** plugins and other configuration to use while linking */
690
+ config?: LinkConfig;
691
+ /** Host (ts/js) provided wgsl constants.
692
+ * Users can import the values from wesl code via the `constants' virtual library:
693
+ * `import constants::num_lights;` */
694
+ constants?: Record<string, string | number>;
695
+ /** function to construct globally unique wgsl identifiers */
696
+ mangler?: ManglerFn;
697
+ }
698
+ /** Generate a virtual WESL module based on a set of conditions. */
699
+ type VirtualLibraryFn = (conditions: Conditions) => string;
700
+ /**
701
+ * Link a set of WESL source modules (typically the text from .wesl files) into a single WGSL string.
702
+ * Linking starts with a specified 'root' source module, and recursively incorporates code
703
+ * referenced from other modules (in local files or libraries).
704
+ *
705
+ * Unreferenced (dead) code outside the root module is not included in the output WGSL.
706
+ * Additionally the caller can specify conditions for to control conditional compilation.
707
+ * Only code that is valid with the current conditions is included in the output.
708
+ */
709
+ declare function link(params: LinkParams): Promise<LinkedWesl>;
710
+ /** linker api for benchmarking */
711
+ declare function _linkSync(params: LinkParams): LinkedWesl;
712
+ interface LinkRegistryParams extends Pick<LinkParams, "rootModuleName" | "conditions" | "virtualLibs" | "config" | "constants" | "mangler"> {
713
+ registry: ParsedRegistry;
714
+ }
715
+ /** Link wesl from a registry of already parsed modules.
716
+ *
717
+ * This entry point is intended for users who want to link multiple times
718
+ * from the same sources. (e.g. linking with different conditions
719
+ * each time, or perhaps to produce multiple wgsl shaders
720
+ * that share some sources.)
721
+ */
722
+ declare function linkRegistry(params: LinkRegistryParams): SrcMap;
723
+ interface BoundAndTransformed {
724
+ transformedAst: TransformedAST;
725
+ newDecls: DeclIdent[];
726
+ newStatements: EmittableElem[];
727
+ }
728
+ /** bind identifers and apply any transform plugins */
729
+ declare function bindAndTransform(params: LinkRegistryParams): BoundAndTransformed;
730
+ //#endregion
731
+ //#region src/BindIdents.d.ts
732
+ /**
733
+ BindIdents pass
734
+
735
+ Goals:
736
+ - link references identifiers to their declaration identifiers.
737
+ - produce a list of declarations that are used (and need to be emitted in the link)
738
+ - create mangled names for global declarations (to avoid name conflicts)
739
+
740
+ BindIdents proceeds as a recursive tree walk of the scope tree, starting from the root module (e.g. main.wesl).
741
+ It traverses the scope tree depth first (and not the syntax tree).
742
+ - For each ref ident, search prior declarations in the current scope, then
743
+ up the scope tree to find a matching declaration
744
+ - If no local match is found, check for partial matches with import statements
745
+ - combine the ident with import statement to match a decl in an exporting module
746
+ - As global declaration identifies are found, also:
747
+ - mutate their mangled name to be globally unique.
748
+ - collect the declarations (they will be emitted)
749
+
750
+ When iterating through the idents inside a scope, we maintain a parallel data structure of
751
+ 'liveDecls', the declarations that are visible in the current scope at the currently
752
+ processed ident, along with a link to parent liveDecls for their current decl visibility.
753
+
754
+ @if/@else Handling:
755
+ The binding phase respects conditional compilation by tracking @else validity state as it
756
+ processes sibling scopes. This prevents references from within filtered @else blocks from
757
+ pulling in declarations that won't be emitted. The algorithm mirrors the emission phase's
758
+ filterValidElements approach but operates on scopes rather than elements.
759
+ */
760
+ /** results returned from binding pass */
761
+ interface BindResults {
762
+ /** root level names (including names mangled due to conflict with earlier names) */
763
+ globalNames: Set<string>;
764
+ /** global declarations that were referenced (these will need to be emitted in the link) */
765
+ decls: DeclIdent[];
766
+ /** additional global statements to include in linked results
767
+ * (e.g. for adding module level const_assert statements) */
768
+ newStatements: EmittableElem[];
769
+ /** if accumulateUnbound is true, collection of unbound module paths */
770
+ unbound?: string[][];
771
+ }
772
+ /** an element that can be directly emitted into the linked result */
773
+ interface EmittableElem {
774
+ srcModule: SrcModule;
775
+ elem: AbstractElem;
776
+ }
777
+ /** virtual package, generated by code generation function. */
778
+ interface VirtualLibrary {
779
+ /** function to generate the module */
780
+ fn: VirtualLibraryFn;
781
+ /** parsed AST for the module (constructed lazily) */
782
+ ast?: WeslAST;
783
+ }
784
+ /** key is virtual module name */
785
+ type VirtualLibrarySet = Record<string, VirtualLibrary>;
786
+ interface BindIdentsParams extends Pick<LinkRegistryParams, "registry" | "conditions" | "mangler"> {
787
+ rootAst: WeslAST;
788
+ virtuals?: VirtualLibrarySet;
789
+ /** if false, throw on unbound identifiers. If true, accumulate unbound identifiers into
790
+ * a BindResults.unbound. */
791
+ accumulateUnbound?: true;
792
+ }
793
+ /**
794
+ * Bind active reference idents to declaration Idents by mutating the refersTo: field
795
+ * Also in this pass, set the mangledName: field for all active global declaration idents.
796
+ *
797
+ * @param parsed
798
+ * @param conditions only bind to/from idents that are valid with the current condition set
799
+ * @return any new declaration elements found (they will need to be emitted)
800
+ */
801
+ declare function bindIdents(params: BindIdentsParams): BindResults;
802
+ /** bind local references in library sources to reveal references to external packages */
803
+ declare function findUnboundIdents(registry: ParsedRegistry): string[][];
804
+ /**
805
+ * Find all conditionally valid declarations at the root level.
806
+ * Declarations are either directly in the root scope or in conditionally valid partial scopes.
807
+ *
808
+ * This function tracks @else state to ensure that declarations in @else blocks are only
809
+ * included when the corresponding @if block is invalid. This is essential for preventing
810
+ * unused declarations from being included in the output.
811
+ *
812
+ * Results are cached on the root scope's _validRootDecls field.
813
+ * Used both for binding and for publicDecl() lookups.
814
+ *
815
+ * @param rootScope The root scope to search
816
+ * @param conditions Current conditional compilation settings
817
+ * @return Array of valid declaration identifiers
818
+ */
819
+ declare function findValidRootDecls(rootScope: Scope, conditions: Conditions): DeclIdent[];
820
+ /** Find a public declaration with the given original name */
821
+ declare function publicDecl(scope: Scope, name: string, conditions: Conditions): DeclIdent | undefined;
822
+ /** @return true if this decl is at the root scope level of a module */
823
+ declare function isGlobal(declIdent: DeclIdent): boolean;
824
+ //#endregion
825
+ //#region src/debug/ASTtoString.d.ts
826
+ declare function astToString(elem: AbstractElem, indent?: number): string;
827
+ /** @return string representation of an attribute (for test/debug) */
828
+ declare function attributeToString(attr: Attribute): string;
829
+ declare function debugContentsToString(elem: StuffElem): string;
830
+ //#endregion
831
+ //#region src/debug/ScopeToString.d.ts
832
+ /** A debugging print of the scope tree with identifiers in nested brackets */
833
+ declare function scopeToString(scope: Scope, indent?: number, shortIdents?: boolean): string;
834
+ /** A debug print of the scope tree with identifiers in long form in nested brackets */
835
+ declare function scopeToStringLong(scope: Scope): string;
836
+ declare function identToString(ident?: Ident): string;
837
+ //#endregion
838
+ //#region src/PathUtil.d.ts
839
+ /** simplistic path manipulation utilities */
840
+ /** return path with ./ and foo/.. elements removed */
841
+ declare function normalize(path: string): string;
842
+ /** return path w/o a suffix.
843
+ * e.g. /foo/bar.wgsl => /foo/bar */
844
+ declare function noSuffix(path: string): string;
845
+ //#endregion
846
+ //#region src/parse/WeslStream.d.ts
847
+ type WeslTokenKind = "word" | "keyword" | "number" | "symbol";
848
+ type WeslToken<Kind extends WeslTokenKind = WeslTokenKind> = TypedToken<Kind>;
849
+ /** A stream that produces WESL tokens, skipping over comments and white space */
850
+ declare class WeslStream implements Stream<WeslToken> {
851
+ private stream;
852
+ /** New line */
853
+ private eolPattern;
854
+ /** Block comments */
855
+ private blockCommentPattern;
856
+ src: string;
857
+ constructor(src: string);
858
+ checkpoint(): number;
859
+ reset(position: number): void;
860
+ nextToken(): WeslToken | null;
861
+ private skipToEol;
862
+ private skipBlockComment;
863
+ /**
864
+ * Only matches the `<` token if it is a template
865
+ * Precondition: An ident was parsed right before this.
866
+ * Runs the [template list discovery algorithm](https://www.w3.org/TR/WGSL/#template-list-discovery).
867
+ */
868
+ nextTemplateStartToken(): (WeslToken & {
869
+ kind: "symbol";
870
+ }) | null;
871
+ nextTemplateEndToken(): (WeslToken & {
872
+ kind: "symbol";
873
+ }) | null;
874
+ isTemplateStart(afterToken: number): boolean;
875
+ /**
876
+ * Call this after consuming an opening bracket.
877
+ * Skips until a closing bracket. This also consumes the closing bracket.
878
+ */
879
+ skipBracketsTo(closingBracket: string): void;
880
+ }
881
+ //#endregion
882
+ //#region src/TransformBindingStructs.d.ts
883
+ declare function bindingStructsPlugin(): WeslJsPlugin;
884
+ /**
885
+ * Transform binding structures into binding variables by mutating the AST.
886
+ *
887
+ * First we find all the binding structs:
888
+ * . find all the structs in the module by filtering the moduleElem.contents
889
+ * . for each struct:
890
+ * . mark any structs with that contain @group or @binding annotations as 'binding structs' and save them in a list
891
+ * . (later) create reverse links from structs to struct members
892
+ * . (later) visit all the binding structs and traverse to referencing structs, marking the referencing structs as binding structs too
893
+ * Generate synethic AST nodes for binding variables
894
+ *
895
+ * Find all references to binding struct members
896
+ * . find the componound idents by traversing moduleElem.contents
897
+ * . filter to find the compound idents that refer to 'binding structs'
898
+ * . go from each ident to its declaration,
899
+ * . declaration to typeRef reference
900
+ * . typeRef to type declaration
901
+ * . check type declaration to see if it's a binding struct
902
+ * . record the intermediate declaration (e.g. a fn param b:Bindings from 'fn(b:Bindings)' )
903
+ * rewrite references to binding struct members as synthetic elements
904
+ *
905
+ * Remove the binding structs from the AST
906
+ * Remove the intermediate fn param declarations from the AST
907
+ * Add the new binding variables to the AST
908
+ *
909
+ * @return the binding structs and the mutated AST
910
+ */
911
+ declare function lowerBindingStructs(ast: TransformedAST): TransformedAST;
912
+ declare function markEntryTypes(moduleElem: ModuleElem, bindingStructs: BindingStructElem[]): void;
913
+ /** mutate the AST, marking StructElems as bindingStructs
914
+ * (if they contain ptrs with @group @binding annotations)
915
+ * @return the binding structs
916
+ */
917
+ declare function markBindingStructs(moduleElem: ModuleElem): BindingStructElem[];
918
+ /** convert each member of the binding struct into a synthetic global variable */
919
+ declare function transformBindingStruct(s: StructElem, globalNames: Set<string>): SyntheticElem[];
920
+ interface MemberRefToStruct extends StructTrace {
921
+ memberRef: SimpleMemberRef;
922
+ }
923
+ interface StructTrace {
924
+ struct: StructElem;
925
+ intermediates: DeclarationElem[];
926
+ }
927
+ /** find all simple member references in the module that refer to binding structs */
928
+ declare function findRefsToBindingStructs(moduleElem: ModuleElem): MemberRefToStruct[];
929
+ /** Mutate the member reference elem to instead contain synthetic elem text.
930
+ * The new text is the mangled var name of the struct member that the memberRef refers to. */
931
+ declare function transformBindingReference(memberRef: SimpleMemberRef, struct: StructElem): SyntheticElem;
932
+ //#endregion
933
+ //#region src/Util.d.ts
934
+ declare function multiKeySet<A, B, V>(m: Map<A, Map<B, V>>, a: A, b: B, v: V): void;
935
+ /** replace strings in a text according to a relacement map
936
+ * replaced strings must be 'tokens', surrounded by spaces or punctuation
937
+ */
938
+ declare function replaceWords(text: string, replace: Record<string, string>): string;
939
+ /** return an array partitioned into possibly overlapping groups */
940
+ declare function grouped<T>(a: T[], size: number, stride?: number): T[][];
941
+ /** group an array into subarrays by a key function */
942
+ declare function groupBy<T, K>(a: T[], key: (t: T) => K): Map<K, T[]>;
943
+ /** partition an array into two parts by a discriminator function */
944
+ declare function partition<T>(a: T[], partFn: (t: T) => boolean): [T[], T[]];
945
+ /** run an carrying function over every element in an array,
946
+ * i.e. an inclusive prefix scan */
947
+ declare function scan<T, U>(array: T[], fn: (a: T, b: U) => U, zero: U): U[];
948
+ /** return a new record by replacing values in 'a' with 'b' as a map.
949
+ * values in 'a' that are not in 'b' are unchanged.
950
+ * e.g. {a: "b", x: 9}, {b: 1} yields {a: 1, x: 9}
951
+ */
952
+ declare function mapForward(a: Record<string, string>, b: Record<string, any>): Record<string, any>;
953
+ /** return the last element of an array or undefined */
954
+ declare function last<T>(a: T[]): T | undefined;
955
+ /**
956
+ * Overlap two arrays, returning the tail of b if a is a prefix of b.
957
+ * Otherwise, return undefined.
958
+ */
959
+ declare function overlapTail<T>(a: T[], b: T[]): T[] | undefined;
960
+ /** filter an array, returning the truthy results of the filter function */
961
+ declare function filterMap<T, U>(arr: T[], fn: (t: T) => U | undefined): U[];
962
+ /** filters an array, returns the first truthy result of the filter function */
963
+ declare function findMap<T, U>(arr: T[], fn: (t: T) => U | undefined): U | undefined;
964
+ /** Run a function over the values in a Record
965
+ * @return a new Record with mapped values. */
966
+ declare function mapValues<T, U>(obj: Record<string, T>, fn: (v: T) => U): Record<string, U>;
967
+ /**
968
+ * Maps an character position in a string to a 1-indexed line number, and 1-indexed column.
969
+ */
970
+ declare function offsetToLineNumber(offset: number, text: string): [lineNum: number, linePos: number];
971
+ /** Highlights an error.
972
+ *
973
+ * Returns a string with the line, and a string with the ^^^^ carets
974
+ */
975
+ declare function errorHighlight(source: string, span: Span): [string, string];
976
+ //#endregion
977
+ export { AbstractElem, AbstractElemBase, AliasElem, Attribute, AttributeElem, BinaryExpression, BinaryOperator, BindIdentsParams, BindResults, BindingAST, BindingStructElem, BoundAndTransformed, BuiltinAttribute, ComponentExpression, ComponentMemberExpression, Conditions, ConstAssertElem, ConstElem, ContainerElem, DeclIdent, DeclIdentElem, DeclarationElem, DiagnosticAttribute, DiagnosticDirective, DirectiveElem, DirectiveVariant, ElemWithAttributes, ElemWithContentsBase, ElifAttribute, ElseAttribute, EmittableElem, EnableDirective, ExpressionElem, ExtendedGPUValidationError, FnElem, FnParamElem, FunctionCallExpression, GlobalDeclarationElem, GlobalVarElem, GrammarElem, HasAttributes, Ident, IfAttribute, ImportCollection, ImportElem, ImportItem, ImportSegment, ImportStatement, InterpolateAttribute, LetElem, LexicalScope, LinkConfig, LinkParams, LinkRegistryParams, LinkedWesl, LinkerTransform, Literal, ManglerFn, ModuleElem, NameElem, OverrideElem, ParenthesizedExpression, ParsedRegistry, PartialScope, RefIdent, RefIdentElem, RequiresDirective, Scope, SimpleMemberRef, SrcModule, StableState, StandardAttribute, StatementElem, StructElem, StructMemberElem, StuffElem, SwitchClauseElem, SyntheticElem, TerminalElem, TextElem, TransformedAST, TranslateTimeExpressionElem, TranslateTimeFeature, TypeRefElem, TypeTemplateParameter, TypedDeclElem, UnaryExpression, UnaryOperator, UnknownExpressionElem, VarElem, VirtualLibrary, VirtualLibraryFn, VirtualLibrarySet, WeslAST, WeslBundle, WeslDevice, WeslGPUCompilationInfo, WeslGPUCompilationMessage, WeslJsPlugin, WeslParseContext, WeslParseError, WeslParseState, WeslStream, _linkSync, astToString, attributeToString, bindAndTransform, bindIdents, bindingStructsPlugin, blankWeslParseState, childIdent, childScope, containsScope, debugContentsToString, emptyScope, errorHighlight, filterMap, findMap, findRefsToBindingStructs, findUnboundIdents, findValidRootDecls, flatImports, groupBy, grouped, identToString, isGlobal, last, lengthPrefixMangle, link, linkRegistry, lowerBindingStructs, makeWeslDevice, mapForward, mapValues, markBindingStructs, markEntryTypes, mergeScope, minimalMangle, minimallyMangledName, multiKeySet, nextIdentId, noSuffix, normalize, offsetToLineNumber, overlapTail, parseIntoRegistry, parseLibsIntoRegistry, parseSrcModule, parsedRegistry, partition, publicDecl, registryToString, replaceWords, requestWeslDevice, resetScopeIds, scan, scopeToString, scopeToStringLong, selectModule, syntheticWeslParseState, transformBindingReference, transformBindingStruct, underscoreMangle };