wesl 0.7.17 → 0.7.20

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 CHANGED
@@ -994,6 +994,8 @@ interface BindContext {
994
994
  /** Construct unique identifier names for global declarations. */
995
995
  mangler: ManglerFn;
996
996
  virtuals?: VirtualLibrarySet;
997
+ /** Host package name for resolving package:: in virtual modules. */
998
+ packageName: string;
997
999
  /** Unbound identifiers if accumulateUnbound is true. */
998
1000
  unbound?: UnboundRef[];
999
1001
  /** Don't follow references from declarations (for library dependency detection). */
package/dist/index.js CHANGED
@@ -832,7 +832,7 @@ function emitStandardAttribute(e, ctx) {
832
832
  }
833
833
  ctx.srcBuilder.add("@" + e.attribute.name + "(", e.start, params[0].start);
834
834
  for (let i = 0; i < params.length; i++) {
835
- ctx.srcBuilder.addCopy(params[i].start, params[i].end);
835
+ emitContents(params[i], ctx);
836
836
  if (i < params.length - 1) ctx.srcBuilder.add(",", params[i].end, params[i + 1].start);
837
837
  }
838
838
  ctx.srcBuilder.add(")", params[params.length - 1].end, e.end);
@@ -3701,6 +3701,7 @@ const wgslStandardAttributes = new Set([
3701
3701
  function bindIdents(params) {
3702
3702
  const { rootAst, resolver, virtuals, accumulateUnbound } = params;
3703
3703
  const { conditions = {}, mangler = minimalMangle } = params;
3704
+ const packageName = rootAst.srcModule.modulePath.split("::")[0];
3704
3705
  const validRootDecls = findValidRootDecls(rootAst.rootScope, conditions);
3705
3706
  const { globalNames, knownDecls } = initRootDecls(validRootDecls);
3706
3707
  const bindContext = {
@@ -3709,6 +3710,7 @@ function bindIdents(params) {
3709
3710
  knownDecls,
3710
3711
  virtuals,
3711
3712
  mangler,
3713
+ packageName,
3712
3714
  foundScopes: /* @__PURE__ */ new Set(),
3713
3715
  globalNames,
3714
3716
  globalStatements: /* @__PURE__ */ new Map(),
@@ -3883,25 +3885,25 @@ function matchingImport(identParts, imports) {
3883
3885
  }
3884
3886
  /** @return an exported root declIdent for the provided path. */
3885
3887
  function findExport(pathParts, srcModule, ctx) {
3886
- const { resolver, conditions, virtuals } = ctx;
3887
3888
  const modulePath = resolveModulePath(pathParts, srcModule.modulePath.split("::")).slice(0, -1).join("::");
3888
- const moduleAst = resolver.resolveModule(modulePath) ?? virtualModule(pathParts[0], conditions, virtuals);
3889
+ const moduleAst = ctx.resolver.resolveModule(modulePath) ?? virtualModule(pathParts[0], ctx);
3889
3890
  if (!moduleAst) return void 0;
3890
- const decl = publicDecl(moduleAst.rootScope, last(pathParts), conditions);
3891
+ const decl = publicDecl(moduleAst.rootScope, last(pathParts), ctx.conditions);
3891
3892
  if (decl) return {
3892
3893
  decl,
3893
3894
  moduleAst
3894
3895
  };
3895
3896
  }
3896
3897
  /** @return AST for a virtual module. */
3897
- function virtualModule(moduleName, conditions = {}, virtuals) {
3898
- const found = virtuals?.[moduleName];
3898
+ function virtualModule(moduleName, ctx) {
3899
+ const found = ctx.virtuals?.[moduleName];
3899
3900
  if (!found) return void 0;
3900
3901
  if (found.ast) return found.ast;
3902
+ const src = found.fn(ctx.conditions);
3901
3903
  found.ast = parseSrcModule({
3902
- modulePath: moduleName,
3904
+ modulePath: ctx.packageName + "::" + moduleName,
3903
3905
  debugFilePath: moduleName,
3904
- src: found.fn(conditions)
3906
+ src
3905
3907
  });
3906
3908
  return found.ast;
3907
3909
  }
@@ -3971,6 +3973,7 @@ function findUnboundRefs(resolver) {
3971
3973
  globalNames: /* @__PURE__ */ new Set(),
3972
3974
  globalStatements: /* @__PURE__ */ new Map(),
3973
3975
  mangler: minimalMangle,
3976
+ packageName: "package",
3974
3977
  unbound: [],
3975
3978
  dontFollowDecls: true
3976
3979
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wesl",
3
- "version": "0.7.17",
3
+ "version": "0.7.20",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -27,7 +27,7 @@
27
27
  "wrangler": "^4.22.0"
28
28
  },
29
29
  "peerDependencies": {
30
- "random_wgsl": "^0.6.66"
30
+ "random_wgsl": "^0.6.68"
31
31
  },
32
32
  "peerDependenciesMeta": {
33
33
  "random_wgsl": {
package/src/BindIdents.ts CHANGED
@@ -118,6 +118,7 @@ export interface BindIdentsParams
118
118
  export function bindIdents(params: BindIdentsParams): BindResults {
119
119
  const { rootAst, resolver, virtuals, accumulateUnbound } = params;
120
120
  const { conditions = {}, mangler = minimalMangle } = params;
121
+ const packageName = rootAst.srcModule.modulePath.split("::")[0];
121
122
 
122
123
  const validRootDecls = findValidRootDecls(rootAst.rootScope, conditions);
123
124
  const { globalNames, knownDecls } = initRootDecls(validRootDecls);
@@ -128,6 +129,7 @@ export function bindIdents(params: BindIdentsParams): BindResults {
128
129
  knownDecls,
129
130
  virtuals,
130
131
  mangler,
132
+ packageName,
131
133
  foundScopes: new Set<Scope>(),
132
134
  globalNames,
133
135
  globalStatements: new Map<AbstractElem, EmittableElem>(),
@@ -234,6 +236,9 @@ interface BindContext {
234
236
 
235
237
  virtuals?: VirtualLibrarySet;
236
238
 
239
+ /** Host package name for resolving package:: in virtual modules. */
240
+ packageName: string;
241
+
237
242
  /** Unbound identifiers if accumulateUnbound is true. */
238
243
  unbound?: UnboundRef[];
239
244
 
@@ -428,32 +433,33 @@ function findExport(
428
433
  srcModule: SrcModule,
429
434
  ctx: BindContext,
430
435
  ): FoundDecl | undefined {
431
- const { resolver, conditions, virtuals } = ctx;
432
436
  const srcParts = srcModule.modulePath.split("::");
433
437
  const fqParts = resolveModulePath(pathParts, srcParts);
434
438
  const modulePath = fqParts.slice(0, -1).join("::");
435
439
 
436
440
  const moduleAst =
437
- resolver.resolveModule(modulePath) ??
438
- virtualModule(pathParts[0], conditions, virtuals);
441
+ ctx.resolver.resolveModule(modulePath) ?? virtualModule(pathParts[0], ctx);
439
442
  if (!moduleAst) return undefined;
440
443
 
441
- const decl = publicDecl(moduleAst.rootScope, last(pathParts)!, conditions);
444
+ const decl = publicDecl(
445
+ moduleAst.rootScope,
446
+ last(pathParts)!,
447
+ ctx.conditions,
448
+ );
442
449
  if (decl) return { decl, moduleAst };
443
450
  }
444
451
 
445
452
  /** @return AST for a virtual module. */
446
453
  function virtualModule(
447
454
  moduleName: string,
448
- conditions: Conditions = {},
449
- virtuals?: VirtualLibrarySet,
455
+ ctx: BindContext,
450
456
  ): WeslAST | undefined {
451
- const found = virtuals?.[moduleName];
457
+ const found = ctx.virtuals?.[moduleName];
452
458
  if (!found) return undefined;
453
459
  if (found.ast) return found.ast;
454
460
 
455
- const src = found.fn(conditions);
456
- const modulePath = moduleName;
461
+ const src = found.fn(ctx.conditions);
462
+ const modulePath = ctx.packageName + "::" + moduleName;
457
463
  const debugFilePath = moduleName;
458
464
  found.ast = parseSrcModule({ modulePath, debugFilePath, src });
459
465
  return found.ast;
@@ -504,7 +504,7 @@ function emitStandardAttribute(e: AttributeElem, ctx: EmitContext): void {
504
504
 
505
505
  ctx.srcBuilder.add("@" + e.attribute.name + "(", e.start, params[0].start);
506
506
  for (let i = 0; i < params.length; i++) {
507
- ctx.srcBuilder.addCopy(params[i].start, params[i].end);
507
+ emitContents(params[i], ctx);
508
508
  if (i < params.length - 1) {
509
509
  ctx.srcBuilder.add(",", params[i].end, params[i + 1].start);
510
510
  }
@@ -35,6 +35,7 @@ export function findUnboundRefs(resolver: BatchModuleResolver): UnboundRef[] {
35
35
  globalNames: new Set<string>(),
36
36
  globalStatements: new Map<AbstractElem, EmittableElem>(),
37
37
  mangler: minimalMangle,
38
+ packageName: "package",
38
39
  unbound: [] as UnboundRef[],
39
40
  dontFollowDecls: true,
40
41
  };
@@ -57,6 +57,34 @@ test("inline constant in array template param", async () => {
57
57
  expect(result).toContain("const size = 4");
58
58
  });
59
59
 
60
+ test("constant in @binding attribute", async () => {
61
+ const src = `
62
+ @group(0) @binding(constants::slot) var<uniform> u: f32;
63
+ `;
64
+ const result = await linkTestOpts({ constants: { slot: 0 } }, src);
65
+ expect(result).toContain("const slot = 0");
66
+ expect(result).toContain("@binding(slot)");
67
+ });
68
+
69
+ test("package:: import from virtual module", async () => {
70
+ const src = `
71
+ import virt::helper;
72
+ fn main() { let x = helper(); }
73
+ `;
74
+ const file1 = `fn util_fn() -> u32 { return 1; }`;
75
+ const opts = {
76
+ virtualLibs: {
77
+ virt: () => `
78
+ import package::file1::util_fn;
79
+ fn helper() -> u32 { return util_fn(); }
80
+ `,
81
+ },
82
+ };
83
+ const result = await linkTestOpts(opts, src, file1);
84
+ expect(result).toContain("fn helper()");
85
+ expect(result).toContain("fn util_fn()");
86
+ });
87
+
60
88
  test("function call with inline ref in template param", async () => {
61
89
  const src = `
62
90
  fn main() {