wesl-link 0.6.1 → 0.6.2

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 (2) hide show
  1. package/bin/wesl-link +248 -200
  2. package/package.json +4 -4
package/bin/wesl-link CHANGED
@@ -2302,12 +2302,10 @@ function logInternalSrc(log2, src, pos, ...msgs) {
2302
2302
  log2(caret);
2303
2303
  }
2304
2304
  function carets(linePos, linePos2) {
2305
- const firstCaret = " ".repeat(linePos) + "^";
2306
- let secondCaret = "";
2307
- if (linePos2 && linePos2 > linePos) {
2308
- secondCaret = " ".repeat(linePos2 - linePos - 1) + "^";
2309
- }
2310
- return firstCaret + secondCaret;
2305
+ const indent = " ".repeat(linePos);
2306
+ const numCarets = linePos2 ? linePos2 - linePos : 1;
2307
+ const carets2 = "^".repeat(numCarets);
2308
+ return indent + carets2;
2311
2309
  }
2312
2310
  var startCache = /* @__PURE__ */ new Map();
2313
2311
  function srcLine(src, position) {
@@ -2563,6 +2561,18 @@ function opt(arg) {
2563
2561
  }
2564
2562
  );
2565
2563
  }
2564
+ function not(arg) {
2565
+ const p = parserArg(arg);
2566
+ return parser2("not", function _not(state) {
2567
+ const pos = state.stream.checkpoint();
2568
+ const result = p._run(state);
2569
+ if (result === null) {
2570
+ state.stream.reset(pos);
2571
+ return { value: true };
2572
+ }
2573
+ return null;
2574
+ });
2575
+ }
2566
2576
  function repeat(arg) {
2567
2577
  const p = parserArg(arg);
2568
2578
  return parser2("repeat", repeatWhileFilter(p));
@@ -3438,6 +3448,110 @@ function errorHighlight(source, span2) {
3438
3448
  ];
3439
3449
  }
3440
3450
 
3451
+ // ../wesl/src/vlq/vlq.ts
3452
+ var char_to_integer = {};
3453
+ var integer_to_char = {};
3454
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").forEach((char, i) => {
3455
+ char_to_integer[char] = i;
3456
+ integer_to_char[i] = char;
3457
+ });
3458
+ function encodeVlq(value) {
3459
+ if (typeof value === "number") {
3460
+ return encode_integer(value);
3461
+ }
3462
+ let result = "";
3463
+ for (let i = 0; i < value.length; i += 1) {
3464
+ result += encode_integer(value[i]);
3465
+ }
3466
+ return result;
3467
+ }
3468
+ function encode_integer(num) {
3469
+ let result = "";
3470
+ if (num < 0) {
3471
+ num = -num << 1 | 1;
3472
+ } else {
3473
+ num <<= 1;
3474
+ }
3475
+ do {
3476
+ let clamped = num & 31;
3477
+ num >>>= 5;
3478
+ if (num > 0) {
3479
+ clamped |= 32;
3480
+ }
3481
+ result += integer_to_char[clamped];
3482
+ } while (num > 0);
3483
+ return result;
3484
+ }
3485
+
3486
+ // ../wesl/src/ClickableError.ts
3487
+ function throwClickableError(params) {
3488
+ const { url, text: text2, lineNumber, lineColumn, length, error } = params;
3489
+ const mappings = encodeVlq([
3490
+ 0,
3491
+ 0,
3492
+ Math.max(0, lineNumber - 1),
3493
+ Math.max(0, lineColumn - 1)
3494
+ ]) + "," + // Sadly no browser makes use of this info to map the error properly
3495
+ encodeVlq([
3496
+ 18,
3497
+ // Arbitrary number that is high enough
3498
+ 0,
3499
+ Math.max(0, lineNumber - 1),
3500
+ Math.max(0, lineColumn - 1) + length
3501
+ ]);
3502
+ const sourceMap = {
3503
+ version: 3,
3504
+ file: null,
3505
+ sources: [url],
3506
+ sourcesContent: [text2 ?? null],
3507
+ names: [],
3508
+ mappings
3509
+ };
3510
+ let generatedCode = `throw new Error(${JSON.stringify(error.message + "")})`;
3511
+ generatedCode += "\n//# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
3512
+ generatedCode += "\n//# sourceURL=" + sourceMap.sources[0];
3513
+ let oldLimit = 0;
3514
+ if ("stackTraceLimit" in Error) {
3515
+ oldLimit = Error.stackTraceLimit;
3516
+ Error.stackTraceLimit = 1;
3517
+ }
3518
+ try {
3519
+ (0, eval)(generatedCode);
3520
+ } catch (e) {
3521
+ if ("stackTraceLimit" in Error) {
3522
+ Error.stackTraceLimit = oldLimit;
3523
+ }
3524
+ error.message = "";
3525
+ if (tracing) e.cause = error;
3526
+ throw e;
3527
+ }
3528
+ }
3529
+ function failIdent(ident2, msg) {
3530
+ const { refIdentElem, originalName } = ident2;
3531
+ const baseMessage = msg ?? `'${originalName}'`;
3532
+ if (refIdentElem) {
3533
+ failIdentElem(refIdentElem, baseMessage);
3534
+ } else {
3535
+ throw new Error(baseMessage);
3536
+ }
3537
+ }
3538
+ function failIdentElem(identElem, msg = "") {
3539
+ const { srcModule, start, end } = identElem;
3540
+ const { debugFilePath, src } = srcModule;
3541
+ const detailedMessage = `${msg} in file: ${debugFilePath}`;
3542
+ srcLog(src, [start, end], detailedMessage);
3543
+ const [lineNumber, lineColumn] = offsetToLineNumber(start, src);
3544
+ const length = end - start;
3545
+ throwClickableError({
3546
+ url: debugFilePath,
3547
+ text: src,
3548
+ lineNumber,
3549
+ lineColumn,
3550
+ length,
3551
+ error: new Error(detailedMessage)
3552
+ });
3553
+ }
3554
+
3441
3555
  // ../wesl/src/Conditions.ts
3442
3556
  function elementValid(elem, conditions) {
3443
3557
  const attributes = elem.attributes;
@@ -3460,10 +3574,10 @@ function evaluateIfAttribute(ifAttribute, conditions) {
3460
3574
  }
3461
3575
  function evaluateIfExpression(expression2, conditions) {
3462
3576
  const { kind: kind2 } = expression2;
3463
- if (kind2 == "unary-expression") {
3577
+ if (kind2 === "unary-expression") {
3464
3578
  assertThatDebug(expression2.operator.value === "!");
3465
3579
  return !evaluateIfExpression(expression2.expression, conditions);
3466
- } else if (kind2 == "binary-expression") {
3580
+ } else if (kind2 === "binary-expression") {
3467
3581
  const op = expression2.operator.value;
3468
3582
  assertThatDebug(op === "||" || op === "&&");
3469
3583
  const leftResult = evaluateIfExpression(expression2.left, conditions);
@@ -3474,11 +3588,11 @@ function evaluateIfExpression(expression2, conditions) {
3474
3588
  } else {
3475
3589
  assertUnreachable2(op);
3476
3590
  }
3477
- } else if (kind2 == "literal") {
3591
+ } else if (kind2 === "literal") {
3478
3592
  const { value } = expression2;
3479
3593
  assertThatDebug(value === "true" || value === "false");
3480
3594
  return value === "true";
3481
- } else if (kind2 == "parenthesized-expression") {
3595
+ } else if (kind2 === "parenthesized-expression") {
3482
3596
  return evaluateIfExpression(expression2.expression, conditions);
3483
3597
  } else if (kind2 === "translate-time-feature") {
3484
3598
  return conditions[expression2.name];
@@ -3726,7 +3840,7 @@ function importElem(cc) {
3726
3840
  function addToOpenElem(cc, elem) {
3727
3841
  const weslContext = cc.app.context;
3728
3842
  const { openElems } = weslContext;
3729
- if (openElems && openElems.length) {
3843
+ if (openElems?.length) {
3730
3844
  const open = openElems[openElems.length - 1];
3731
3845
  open.contents.push(elem);
3732
3846
  }
@@ -3888,7 +4002,7 @@ var fnCollect = collectElem(
3888
4002
  mergeScope(mergedScope, bodyScope);
3889
4003
  const filtered = [];
3890
4004
  for (const e of fnScope.contents) {
3891
- if (e === headerScope || e == returnScope) {
4005
+ if (e === headerScope || e === returnScope) {
3892
4006
  continue;
3893
4007
  } else if (e === bodyScope) {
3894
4008
  filtered.push(mergedScope);
@@ -3989,7 +4103,7 @@ var typeRefCollect = collectElem(
3989
4103
  "type",
3990
4104
  // @ts-ignore
3991
4105
  (cc, openElem) => {
3992
- let templateParamsTemp = cc.tags.templateParam?.flat(3);
4106
+ const templateParamsTemp = cc.tags.templateParam?.flat(3);
3993
4107
  const typeRef = cc.tags.typeRefName?.[0];
3994
4108
  const name2 = typeof typeRef === "string" ? typeRef : typeRef.ident;
3995
4109
  const partElem = {
@@ -4024,7 +4138,7 @@ var memberRefCollect = collectElem(
4024
4138
  "memberRef",
4025
4139
  (cc, openElem) => {
4026
4140
  const { component, structRef, extra_components } = cc.tags;
4027
- const member = component[0];
4141
+ const member = component?.[0];
4028
4142
  const name2 = structRef?.flat()[0];
4029
4143
  const extraComponents = extra_components?.flat()[0];
4030
4144
  const partElem = {
@@ -4120,7 +4234,10 @@ function coverWithText(cc, elem) {
4120
4234
  // ../wesl/src/parse/WeslBaseGrammar.ts
4121
4235
  var word = kind("word");
4122
4236
  var keyword = kind("keyword");
4123
- var qualified_ident = withSepPlus("::", or(word, "package", "super"));
4237
+ var qualified_ident = withSepPlus(
4238
+ "::",
4239
+ or(word, keyword, "package", "super")
4240
+ );
4124
4241
  var number = kind("number");
4125
4242
 
4126
4243
  // ../wesl/src/parse/ImportGrammar.ts
@@ -4144,8 +4261,10 @@ function prependSegments(segments, statement2) {
4144
4261
  return statement2;
4145
4262
  }
4146
4263
  var import_collection = null;
4264
+ var segment_blacklist = or("super", "package", "import", "as");
4265
+ var packageWord = preceded(not(segment_blacklist), or(word, keyword));
4147
4266
  var import_path_or_item = seq(
4148
- word,
4267
+ packageWord,
4149
4268
  or(
4150
4269
  preceded(
4151
4270
  "::",
@@ -4305,7 +4424,7 @@ var WeslStream = class {
4305
4424
  this.stream.reset(this.skipBlockComment(token2.span[1]));
4306
4425
  }
4307
4426
  } else if (kind2 === "word") {
4308
- let returnToken = token2;
4427
+ const returnToken = token2;
4309
4428
  if (keywordOrReserved.has(token2.text)) {
4310
4429
  returnToken.kind = "keyword";
4311
4430
  }
@@ -4393,7 +4512,7 @@ var WeslStream = class {
4393
4512
  if (nextToken.text === "<") {
4394
4513
  pendingCounter += 1;
4395
4514
  } else if (nextToken.text[0] === ">") {
4396
- if (nextToken.text === ">" || nextToken.text == ">=") {
4515
+ if (nextToken.text === ">" || nextToken.text === ">=") {
4397
4516
  pendingCounter -= 1;
4398
4517
  } else if (nextToken.text === ">>=" || nextToken.text === ">>") {
4399
4518
  pendingCounter -= 2;
@@ -4633,11 +4752,25 @@ var special_attribute = tagScope(
4633
4752
  "@",
4634
4753
  or(
4635
4754
  // These attributes have no arguments
4636
- or("compute", "const", "fragment", "invariant", "must_use", "vertex").map((name2) => makeStandardAttribute([name2, []])),
4755
+ or("compute", "const", "fragment", "invariant", "must_use", "vertex").map(
4756
+ (name2) => makeStandardAttribute([name2, []])
4757
+ ),
4637
4758
  // These attributes have arguments, but the argument doesn't have any identifiers
4638
- preceded("interpolate", req(delimited("(", name_list, ")"), "invalid @interpolate, expected '('")).map(makeInterpolateAttribute),
4639
- preceded("builtin", req(delimited("(", name, ")"), "invalid @builtin, expected '('")).map(makeBuiltinAttribute),
4640
- preceded("diagnostic", req(diagnostic_control, "invalid @diagnostic, expected '('")).map(makeDiagnosticAttribute)
4759
+ preceded(
4760
+ "interpolate",
4761
+ req(
4762
+ delimited("(", name_list, ")"),
4763
+ "invalid @interpolate, expected '('"
4764
+ )
4765
+ ).map(makeInterpolateAttribute),
4766
+ preceded(
4767
+ "builtin",
4768
+ req(delimited("(", name, ")"), "invalid @builtin, expected '('")
4769
+ ).map(makeBuiltinAttribute),
4770
+ preceded(
4771
+ "diagnostic",
4772
+ req(diagnostic_control, "invalid @diagnostic, expected '('")
4773
+ ).map(makeDiagnosticAttribute)
4641
4774
  ).ptag("attr_variant")
4642
4775
  ).collect(specialAttribute)
4643
4776
  );
@@ -4673,7 +4806,7 @@ var normal_attribute = tagScope(
4673
4806
  ),
4674
4807
  // Everything else is also a normal attribute, optional expression list
4675
4808
  seq(
4676
- // we don't want this to interfere with if_attribute,
4809
+ // we don't want this to interfere with if_attribute,
4677
4810
  // but not("if") isn't necessary for now, since 'if' is a keyword, not a word
4678
4811
  word.ptag("name"),
4679
4812
  opt(() => attribute_argument_list)
@@ -4690,10 +4823,9 @@ var attribute_argument_list = delimited(
4690
4823
  ),
4691
4824
  req(")", "invalid attribute arguments, expected ')'")
4692
4825
  );
4693
- var attribute_no_if = or(
4694
- special_attribute,
4695
- normal_attribute
4696
- ).ctag("attribute");
4826
+ var attribute_no_if = or(special_attribute, normal_attribute).ctag(
4827
+ "attribute"
4828
+ );
4697
4829
  var attribute_incl_if = or(
4698
4830
  if_attribute,
4699
4831
  special_attribute,
@@ -4734,7 +4866,10 @@ var struct_member = tagScope(
4734
4866
  ).collect(collectStructMember)
4735
4867
  ).ctag("members");
4736
4868
  var struct_decl = seq(
4737
- weslExtension(opt_attributes).collect((cc) => cc.tags.attribute, "attributes"),
4869
+ weslExtension(opt_attributes).collect(
4870
+ (cc) => cc.tags.attribute,
4871
+ "attributes"
4872
+ ),
4738
4873
  "struct",
4739
4874
  req(globalTypeNameDecl, "invalid struct, expected name"),
4740
4875
  seq(
@@ -4752,7 +4887,12 @@ var fnParam = tagScope(
4752
4887
  seq(
4753
4888
  opt_attributes.collect((cc) => cc.tags.attribute, "attributes"),
4754
4889
  word.collect(declCollect, "decl_elem"),
4755
- opt(seq(":", req(type_specifier, "invalid fn parameter, expected type specifier"))).collect(typedDecl, "param_name")
4890
+ opt(
4891
+ seq(
4892
+ ":",
4893
+ req(type_specifier, "invalid fn parameter, expected type specifier")
4894
+ )
4895
+ ).collect(typedDecl, "param_name")
4756
4896
  ).collect(collectFnParam)
4757
4897
  ).ctag("fn_param");
4758
4898
  var fnParamList = seq("(", withSep(",", fnParam), ")");
@@ -4944,16 +5084,10 @@ var regular_statement = or(
4944
5084
  )
4945
5085
  );
4946
5086
  var conditional_statement = tagScope(
4947
- seq(
4948
- opt_attributes,
4949
- regular_statement
4950
- ).collect(statementCollect).collect(partialScopeCollect)
5087
+ seq(opt_attributes, regular_statement).collect(statementCollect).collect(partialScopeCollect)
4951
5088
  );
4952
5089
  var unconditional_statement = tagScope(
4953
- seq(
4954
- opt_attributes_no_if,
4955
- regular_statement
4956
- )
5090
+ seq(opt_attributes_no_if, regular_statement)
4957
5091
  );
4958
5092
  var statement = or(
4959
5093
  compound_statement,
@@ -4962,10 +5096,7 @@ var statement = or(
4962
5096
  );
4963
5097
  var lhs_expression = or(
4964
5098
  simple_component_reference,
4965
- seq(
4966
- qualified_ident.collect(refIdent),
4967
- opt(component_or_swizzle)
4968
- ),
5099
+ seq(qualified_ident.collect(refIdent), opt(component_or_swizzle)),
4969
5100
  seq(
4970
5101
  "(",
4971
5102
  () => lhs_expression,
@@ -4981,7 +5112,12 @@ var variable_or_value_statement = tagScope(
4981
5112
  or(
4982
5113
  // Also covers the = expression case
4983
5114
  local_variable_decl,
4984
- seq("const", req_optionally_typed_ident, req("=", "invalid const declaration, expected '='"), expression),
5115
+ seq(
5116
+ "const",
5117
+ req_optionally_typed_ident,
5118
+ req("=", "invalid const declaration, expected '='"),
5119
+ expression
5120
+ ),
4985
5121
  seq(
4986
5122
  "let",
4987
5123
  req_optionally_typed_ident,
@@ -5000,22 +5136,24 @@ var variable_updating_statement = or(
5000
5136
  seq("_", "=", expression)
5001
5137
  );
5002
5138
  var fn_decl = seq(
5003
- tagScope(
5004
- opt_attributes.collect((cc) => cc.tags.attribute || [])
5005
- ).ctag("fn_attributes"),
5139
+ tagScope(opt_attributes.collect((cc) => cc.tags.attribute || [])).ctag(
5140
+ "fn_attributes"
5141
+ ),
5006
5142
  text("fn"),
5007
5143
  req(fnNameDecl, "invalid fn, expected function name"),
5008
5144
  seq(
5009
- req(fnParamList, "invalid fn, expected function parameters").collect(scopeCollect, "header_scope"),
5010
- opt(seq(
5011
- "->",
5012
- opt_attributes.collect((cc) => cc.tags.attribute, "return_attributes"),
5013
- type_specifier.ctag("return_type").collect(scopeCollect, "return_scope")
5014
- )),
5015
- req(
5016
- unscoped_compound_statement,
5017
- "invalid fn, expected function body"
5018
- ).ctag("body_statement").collect(scopeCollect, "body_scope")
5145
+ req(fnParamList, "invalid fn, expected function parameters").collect(
5146
+ scopeCollect,
5147
+ "header_scope"
5148
+ ),
5149
+ opt(
5150
+ seq(
5151
+ "->",
5152
+ opt_attributes.collect((cc) => cc.tags.attribute, "return_attributes"),
5153
+ type_specifier.ctag("return_type").collect(scopeCollect, "return_scope")
5154
+ )
5155
+ ),
5156
+ req(unscoped_compound_statement, "invalid fn, expected function body").ctag("body_statement").collect(scopeCollect, "body_scope")
5019
5157
  )
5020
5158
  ).collect(partialScopeCollect, "fn_partial_scope").collect(fnCollect);
5021
5159
  var global_value_decl = or(
@@ -5036,11 +5174,20 @@ var global_value_decl = or(
5036
5174
  ).collect(collectVarLike("const"))
5037
5175
  ).collect(partialScopeCollect);
5038
5176
  var global_alias = seq(
5039
- weslExtension(opt_attributes).collect((cc) => cc.tags.attribute, "attributes"),
5177
+ weslExtension(opt_attributes).collect(
5178
+ (cc) => cc.tags.attribute,
5179
+ "attributes"
5180
+ ),
5040
5181
  "alias",
5041
- req(word, "invalid alias, expected name").collect(globalDeclCollect, "alias_name"),
5182
+ req(word, "invalid alias, expected name").collect(
5183
+ globalDeclCollect,
5184
+ "alias_name"
5185
+ ),
5042
5186
  req("=", "invalid alias, expected '='"),
5043
- req(type_specifier, "invalid alias, expected type").collect(scopeCollect, "alias_scope"),
5187
+ req(type_specifier, "invalid alias, expected type").collect(
5188
+ scopeCollect,
5189
+ "alias_scope"
5190
+ ),
5044
5191
  req(";", "invalid alias, expected ';'")
5045
5192
  ).collect(aliasCollect);
5046
5193
  var const_assert = tagScope(
@@ -5255,91 +5402,6 @@ if (tracing) {
5255
5402
  });
5256
5403
  }
5257
5404
 
5258
- // ../wesl/src/vlq/vlq.ts
5259
- var char_to_integer = {};
5260
- var integer_to_char = {};
5261
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").forEach(function(char, i) {
5262
- char_to_integer[char] = i;
5263
- integer_to_char[i] = char;
5264
- });
5265
- function encodeVlq(value) {
5266
- if (typeof value === "number") {
5267
- return encode_integer(value);
5268
- }
5269
- let result = "";
5270
- for (let i = 0; i < value.length; i += 1) {
5271
- result += encode_integer(value[i]);
5272
- }
5273
- return result;
5274
- }
5275
- function encode_integer(num) {
5276
- let result = "";
5277
- if (num < 0) {
5278
- num = -num << 1 | 1;
5279
- } else {
5280
- num <<= 1;
5281
- }
5282
- do {
5283
- let clamped = num & 31;
5284
- num >>>= 5;
5285
- if (num > 0) {
5286
- clamped |= 32;
5287
- }
5288
- result += integer_to_char[clamped];
5289
- } while (num > 0);
5290
- return result;
5291
- }
5292
-
5293
- // ../wesl/src/WeslDevice.ts
5294
- function throwClickableError({
5295
- url,
5296
- text: text2,
5297
- lineNumber,
5298
- lineColumn,
5299
- length,
5300
- error
5301
- }) {
5302
- let mappings = encodeVlq([
5303
- 0,
5304
- 0,
5305
- Math.max(0, lineNumber - 1),
5306
- Math.max(0, lineColumn - 1)
5307
- ]) + "," + // Sadly no browser makes use of this info to map the error properly
5308
- encodeVlq([
5309
- 18,
5310
- // Arbitrary number that is high enough
5311
- 0,
5312
- Math.max(0, lineNumber - 1),
5313
- Math.max(0, lineColumn - 1) + length
5314
- ]);
5315
- const sourceMap = {
5316
- version: 3,
5317
- file: null,
5318
- sources: [url],
5319
- sourcesContent: [text2 ?? null],
5320
- names: [],
5321
- mappings
5322
- };
5323
- let generatedCode = `throw new Error(${JSON.stringify(error.message + "")})`;
5324
- generatedCode += "\n//# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
5325
- generatedCode += "\n//# sourceURL=" + sourceMap.sources[0];
5326
- let oldLimit = 0;
5327
- if ("stackTraceLimit" in Error) {
5328
- oldLimit = Error.stackTraceLimit;
5329
- Error.stackTraceLimit = 1;
5330
- }
5331
- try {
5332
- (0, eval)(generatedCode);
5333
- } catch (e) {
5334
- if ("stackTraceLimit" in Error) {
5335
- Error.stackTraceLimit = oldLimit;
5336
- }
5337
- error.message = "";
5338
- e.cause = error;
5339
- throw e;
5340
- }
5341
- }
5342
-
5343
5405
  // ../wesl/src/ParseWESL.ts
5344
5406
  var WeslParseError = class extends Error {
5345
5407
  constructor(opts) {
@@ -5526,7 +5588,7 @@ function findValidRootDecls(rootScope, conditions) {
5526
5588
  return found;
5527
5589
  }
5528
5590
  function bindIdentsRecursive(scope, bindContext, liveDecls, isRoot = false) {
5529
- const { conditions, foundScopes } = bindContext;
5591
+ const { dontFollowDecls, foundScopes } = bindContext;
5530
5592
  if (foundScopes.has(scope)) return [];
5531
5593
  foundScopes.add(scope);
5532
5594
  const newGlobals = [];
@@ -5546,7 +5608,12 @@ function bindIdentsRecursive(scope, bindContext, liveDecls, isRoot = false) {
5546
5608
  }
5547
5609
  }
5548
5610
  });
5549
- const newFromRefs = newGlobals.flatMap((decl) => {
5611
+ const newFromRefs = dontFollowDecls ? [] : handleDecls(newGlobals, bindContext);
5612
+ return [newGlobals, newFromChildren, newFromRefs].flat();
5613
+ }
5614
+ function handleDecls(newGlobals, bindContext) {
5615
+ const { conditions } = bindContext;
5616
+ return newGlobals.flatMap((decl) => {
5550
5617
  const foundsScope = decl.dependentScope;
5551
5618
  if (foundsScope) {
5552
5619
  const rootDecls = globalDeclToRootLiveDecls(decl, conditions);
@@ -5557,7 +5624,6 @@ function bindIdentsRecursive(scope, bindContext, liveDecls, isRoot = false) {
5557
5624
  }
5558
5625
  return [];
5559
5626
  });
5560
- return [newGlobals, newFromChildren, newFromRefs].flat();
5561
5627
  }
5562
5628
  function handleRef(ident2, liveDecls, bindContext) {
5563
5629
  const { registry, conditions, unbound } = bindContext;
@@ -5570,7 +5636,7 @@ function handleRef(ident2, liveDecls, bindContext) {
5570
5636
  } else if (stdWgsl(ident2.originalName)) {
5571
5637
  ident2.std = true;
5572
5638
  } else if (!unbound) {
5573
- failMissingIdent(ident2);
5639
+ failIdent(ident2, `unresolved identifier '${ident2.originalName}'`);
5574
5640
  }
5575
5641
  }
5576
5642
  }
@@ -5619,16 +5685,6 @@ function globalDeclToRootLiveDecls(decl, conditions) {
5619
5685
  root._scopeDecls = liveDecls;
5620
5686
  return liveDecls;
5621
5687
  }
5622
- function failMissingIdent(ident2) {
5623
- const { refIdentElem } = ident2;
5624
- if (refIdentElem) {
5625
- const { srcModule, start, end } = refIdentElem;
5626
- const { debugFilePath: filePath } = srcModule;
5627
- const msg = `unresolved identifier '${ident2.originalName}' in file: ${filePath}`;
5628
- srcLog(srcModule.src, [start, end], msg);
5629
- throw new Error(msg);
5630
- }
5631
- }
5632
5688
  function setMangledName(proposedName, decl, globalNames, srcModule, mangler) {
5633
5689
  if (!decl.mangledName) {
5634
5690
  let mangledName;
@@ -5674,8 +5730,8 @@ function findQualifiedImport(refIdent2, parsed, conditions, virtuals, unbound) {
5674
5730
  if (unbound) {
5675
5731
  unbound.push(modulePathParts);
5676
5732
  } else {
5677
- const msg = `ident ${modulePathParts.join("::")}, but module not found`;
5678
- console.log(msg);
5733
+ const msg = `module not found for '${modulePathParts.join("::")}'`;
5734
+ failIdent(refIdent2, msg);
5679
5735
  }
5680
5736
  }
5681
5737
  return result;
@@ -5753,16 +5809,21 @@ function lowerAndEmitElem(e, ctx) {
5753
5809
  return;
5754
5810
  // terminal elements copy strings to the output
5755
5811
  case "text":
5756
- return emitText(e, ctx);
5812
+ emitText(e, ctx);
5813
+ return;
5757
5814
  case "name":
5758
- return emitName(e, ctx);
5815
+ emitName(e, ctx);
5816
+ return;
5759
5817
  case "synthetic":
5760
- return emitSynthetic(e, ctx);
5818
+ emitSynthetic(e, ctx);
5819
+ return;
5761
5820
  // identifiers are copied to the output, but with potentially mangled names
5762
5821
  case "ref":
5763
- return emitRefIdent(e, ctx);
5822
+ emitRefIdent(e, ctx);
5823
+ return;
5764
5824
  case "decl":
5765
- return emitDeclIdent(e, ctx);
5825
+ emitDeclIdent(e, ctx);
5826
+ return;
5766
5827
  // container elements just emit their child elements
5767
5828
  case "param":
5768
5829
  case "var":
@@ -5776,7 +5837,8 @@ function lowerAndEmitElem(e, ctx) {
5776
5837
  case "statement":
5777
5838
  case "stuff":
5778
5839
  case "switch-clause":
5779
- return emitContents(e, ctx);
5840
+ emitContents(e, ctx);
5841
+ return;
5780
5842
  // root level container elements get some extra newlines to make the output prettier
5781
5843
  case "override":
5782
5844
  case "const":
@@ -5784,17 +5846,22 @@ function lowerAndEmitElem(e, ctx) {
5784
5846
  case "alias":
5785
5847
  case "gvar":
5786
5848
  emitRootElemNl(ctx);
5787
- return emitContents(e, ctx);
5849
+ emitContents(e, ctx);
5850
+ return;
5788
5851
  case "fn":
5789
5852
  emitRootElemNl(ctx);
5790
- return emitFn(e, ctx);
5853
+ emitFn(e, ctx);
5854
+ return;
5791
5855
  case "struct":
5792
5856
  emitRootElemNl(ctx);
5793
- return emitStruct(e, ctx);
5857
+ emitStruct(e, ctx);
5858
+ return;
5794
5859
  case "attribute":
5795
- return emitAttribute(e, ctx);
5860
+ emitAttribute(e, ctx);
5861
+ return;
5796
5862
  case "directive":
5797
- return emitDirective(e, ctx);
5863
+ emitDirective(e, ctx);
5864
+ return;
5798
5865
  default:
5799
5866
  assertUnreachable2(e);
5800
5867
  }
@@ -5843,7 +5910,9 @@ function emitAttributes(attributes, ctx) {
5843
5910
  function emitStruct(e, ctx) {
5844
5911
  const { name: name2, members, start, end } = e;
5845
5912
  const { srcBuilder } = ctx;
5846
- const validMembers = members.filter((m) => conditionsValid(m, ctx.conditions));
5913
+ const validMembers = members.filter(
5914
+ (m) => conditionsValid(m, ctx.conditions)
5915
+ );
5847
5916
  const validLength = validMembers.length;
5848
5917
  if (validLength === 0) {
5849
5918
  warnEmptyStruct(e);
@@ -5869,12 +5938,8 @@ function emitStruct(e, ctx) {
5869
5938
  function warnEmptyStruct(e) {
5870
5939
  const { name: name2, members } = e;
5871
5940
  const condStr = members.length ? "(with current conditions)" : "";
5872
- const { debugFilePath: filePath } = name2.srcModule;
5873
- srcLog(
5874
- name2.srcModule.src,
5875
- e.start,
5876
- `struct ${name2.ident.originalName} in ${filePath} has no members ${condStr}`
5877
- );
5941
+ const message = `struct '${name2.ident.originalName}' has no members ${condStr}`;
5942
+ failIdentElem(name2, message);
5878
5943
  }
5879
5944
  function emitSynthetic(e, ctx) {
5880
5945
  const { text: text2 } = e;
@@ -6319,7 +6384,7 @@ var LinkedWesl = class {
6319
6384
  code: this.dest
6320
6385
  });
6321
6386
  device.popErrorScope();
6322
- let { promise, resolve: resolve5 } = Promise.withResolvers();
6387
+ const { promise, resolve: resolve5 } = Promise.withResolvers();
6323
6388
  device.injectError("validation", promise);
6324
6389
  module.getCompilationInfo().then((compilationInfo) => {
6325
6390
  if (compilationInfo.messages.length === 0) {
@@ -6363,7 +6428,7 @@ var LinkedWesl = class {
6363
6428
  const srcPosition = srcMap.destToSrc(message.offset);
6364
6429
  const srcEndPosition = message.length > 0 ? srcMap.destToSrc(message.offset + message.length) : srcPosition;
6365
6430
  const length = srcEndPosition.position - srcPosition.position;
6366
- let [lineNum, linePos] = offsetToLineNumber(
6431
+ const [lineNum, linePos] = offsetToLineNumber(
6367
6432
  srcPosition.position,
6368
6433
  srcPosition.src.text
6369
6434
  );
@@ -6386,7 +6451,7 @@ function compilationInfoToErrorMessage(compilationInfo, shaderModule) {
6386
6451
  if (compilationInfo.messages.length === 0) return null;
6387
6452
  let result = `Compilation log for [Invalid ShaderModule (${shaderModule.label || "unlabled"})]:
6388
6453
  `;
6389
- let errorCount = compilationInfo.messages.filter(
6454
+ const errorCount = compilationInfo.messages.filter(
6390
6455
  (v) => v.type === "error"
6391
6456
  ).length;
6392
6457
  if (errorCount > 0) {
@@ -6497,7 +6562,8 @@ async function link(params) {
6497
6562
  const registry = parsedRegistry();
6498
6563
  parseIntoRegistry(weslSrc, registry, "package", debugWeslRoot);
6499
6564
  parseLibsIntoRegistry(libs, registry);
6500
- return new LinkedWesl(linkRegistry({ registry, ...params }));
6565
+ const srcMap = linkRegistry({ registry, ...params });
6566
+ return new LinkedWesl(srcMap);
6501
6567
  }
6502
6568
  function linkRegistry(params) {
6503
6569
  const bound = bindAndTransform(params);
@@ -6521,7 +6587,7 @@ function bindAndTransform(params) {
6521
6587
  if (constants) {
6522
6588
  virtualLibs = { ...virtualLibs, constants: constantsGenerator(constants) };
6523
6589
  }
6524
- let virtuals = virtualLibs && mapValues(virtualLibs, (fn2) => ({ fn: fn2 }));
6590
+ const virtuals = virtualLibs && mapValues(virtualLibs, (fn2) => ({ fn: fn2 }));
6525
6591
  const bindParams = { rootAst, registry, conditions, virtuals, mangler };
6526
6592
  const bindResults = bindIdents(bindParams);
6527
6593
  const { globalNames, decls: newDecls, newStatements } = bindResults;
@@ -9897,26 +9963,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
9897
9963
  /*! Bundled license information:
9898
9964
 
9899
9965
  yargs-parser/build/lib/string-utils.js:
9900
- (**
9901
- * @license
9902
- * Copyright (c) 2016, Contributors
9903
- * SPDX-License-Identifier: ISC
9904
- *)
9905
-
9906
9966
  yargs-parser/build/lib/tokenize-arg-string.js:
9907
- (**
9908
- * @license
9909
- * Copyright (c) 2016, Contributors
9910
- * SPDX-License-Identifier: ISC
9911
- *)
9912
-
9913
9967
  yargs-parser/build/lib/yargs-parser-types.js:
9914
- (**
9915
- * @license
9916
- * Copyright (c) 2016, Contributors
9917
- * SPDX-License-Identifier: ISC
9918
- *)
9919
-
9920
9968
  yargs-parser/build/lib/yargs-parser.js:
9921
9969
  (**
9922
9970
  * @license
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wesl-link",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "type": "module",
5
5
  "repository": "https://github.com/wgsl-tooling-wg/wesl-js/tree/main/packages/cli",
6
6
  "homepage": "https://github.com/wgsl-tooling-wg/wesl-js/tree/main/packages/cli#readme",
@@ -9,12 +9,12 @@
9
9
  ],
10
10
  "bin": "bin/wesl-link",
11
11
  "dependencies": {
12
- "@types/diff": "^7.0.1",
12
+ "@types/diff": "^7.0.2",
13
13
  "diff": "^7.0.0",
14
- "wesl": "0.6.1"
14
+ "wesl": "0.6.2"
15
15
  },
16
16
  "devDependencies": {
17
- "mini-parse": "0.6.1"
17
+ "mini-parse": "0.6.2"
18
18
  },
19
19
  "scripts": {
20
20
  "echo": "echo",