@luma.gl/engine 9.0.15 → 9.0.17

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/dist.dev.js CHANGED
@@ -1833,7 +1833,7 @@ void main() {
1833
1833
  // ../shadertools/src/lib/wgsl/get-shader-layout-wgsl.ts
1834
1834
  var import_core4 = __toESM(require_core(), 1);
1835
1835
 
1836
- // ../shadertools/src/libs/wgsl-reflect/wgsl_reflect.module.js
1836
+ // ../../node_modules/wgsl_reflect/wgsl_reflect.module.js
1837
1837
  var ParseContext = class {
1838
1838
  constructor() {
1839
1839
  this.constants = /* @__PURE__ */ new Map();
@@ -1856,23 +1856,50 @@ void main() {
1856
1856
  evaluateString(context) {
1857
1857
  return this.evaluate(context).toString();
1858
1858
  }
1859
+ search(callback) {
1860
+ }
1861
+ searchBlock(block, callback) {
1862
+ if (block) {
1863
+ callback(_BlockStart.instance);
1864
+ for (const node of block) {
1865
+ if (node instanceof Array) {
1866
+ this.searchBlock(node, callback);
1867
+ } else {
1868
+ node.search(callback);
1869
+ }
1870
+ }
1871
+ callback(_BlockEnd.instance);
1872
+ }
1873
+ }
1874
+ };
1875
+ var _BlockStart = class extends Node {
1876
+ };
1877
+ _BlockStart.instance = new _BlockStart();
1878
+ var _BlockEnd = class extends Node {
1859
1879
  };
1880
+ _BlockEnd.instance = new _BlockEnd();
1860
1881
  var Statement = class extends Node {
1861
1882
  constructor() {
1862
1883
  super();
1863
1884
  }
1864
1885
  };
1865
1886
  var Function = class extends Statement {
1866
- constructor(name, args, returnType, body) {
1887
+ constructor(name, args, returnType, body, startLine, endLine) {
1867
1888
  super();
1889
+ this.calls = /* @__PURE__ */ new Set();
1868
1890
  this.name = name;
1869
1891
  this.args = args;
1870
1892
  this.returnType = returnType;
1871
1893
  this.body = body;
1894
+ this.startLine = startLine;
1895
+ this.endLine = endLine;
1872
1896
  }
1873
1897
  get astNodeType() {
1874
1898
  return "function";
1875
1899
  }
1900
+ search(callback) {
1901
+ this.searchBlock(this.body, callback);
1902
+ }
1876
1903
  };
1877
1904
  var StaticAssert = class extends Statement {
1878
1905
  constructor(expression) {
@@ -1882,6 +1909,9 @@ void main() {
1882
1909
  get astNodeType() {
1883
1910
  return "staticAssert";
1884
1911
  }
1912
+ search(callback) {
1913
+ this.expression.search(callback);
1914
+ }
1885
1915
  };
1886
1916
  var While = class extends Statement {
1887
1917
  constructor(condition, body) {
@@ -1892,6 +1922,10 @@ void main() {
1892
1922
  get astNodeType() {
1893
1923
  return "while";
1894
1924
  }
1925
+ search(callback) {
1926
+ this.condition.search(callback);
1927
+ this.searchBlock(this.body, callback);
1928
+ }
1895
1929
  };
1896
1930
  var Continuing = class extends Statement {
1897
1931
  constructor(body) {
@@ -1901,6 +1935,9 @@ void main() {
1901
1935
  get astNodeType() {
1902
1936
  return "continuing";
1903
1937
  }
1938
+ search(callback) {
1939
+ this.searchBlock(this.body, callback);
1940
+ }
1904
1941
  };
1905
1942
  var For = class extends Statement {
1906
1943
  constructor(init, condition, increment, body) {
@@ -1913,6 +1950,13 @@ void main() {
1913
1950
  get astNodeType() {
1914
1951
  return "for";
1915
1952
  }
1953
+ search(callback) {
1954
+ var _a2, _b, _c;
1955
+ (_a2 = this.init) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1956
+ (_b = this.condition) === null || _b === void 0 ? void 0 : _b.search(callback);
1957
+ (_c = this.increment) === null || _c === void 0 ? void 0 : _c.search(callback);
1958
+ this.searchBlock(this.body, callback);
1959
+ }
1916
1960
  };
1917
1961
  var Var = class extends Statement {
1918
1962
  constructor(name, type, storage, access, value) {
@@ -1926,6 +1970,11 @@ void main() {
1926
1970
  get astNodeType() {
1927
1971
  return "var";
1928
1972
  }
1973
+ search(callback) {
1974
+ var _a2;
1975
+ callback(this);
1976
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1977
+ }
1929
1978
  };
1930
1979
  var Override = class extends Statement {
1931
1980
  constructor(name, type, value) {
@@ -1937,6 +1986,10 @@ void main() {
1937
1986
  get astNodeType() {
1938
1987
  return "override";
1939
1988
  }
1989
+ search(callback) {
1990
+ var _a2;
1991
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1992
+ }
1940
1993
  };
1941
1994
  var Let = class extends Statement {
1942
1995
  constructor(name, type, storage, access, value) {
@@ -1950,6 +2003,11 @@ void main() {
1950
2003
  get astNodeType() {
1951
2004
  return "let";
1952
2005
  }
2006
+ search(callback) {
2007
+ var _a2;
2008
+ callback(this);
2009
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
2010
+ }
1953
2011
  };
1954
2012
  var Const = class extends Statement {
1955
2013
  constructor(name, type, storage, access, value) {
@@ -1966,6 +2024,11 @@ void main() {
1966
2024
  evaluate(context) {
1967
2025
  return this.value.evaluate(context);
1968
2026
  }
2027
+ search(callback) {
2028
+ var _a2;
2029
+ callback(this);
2030
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
2031
+ }
1969
2032
  };
1970
2033
  var IncrementOperator;
1971
2034
  (function(IncrementOperator2) {
@@ -1990,6 +2053,9 @@ void main() {
1990
2053
  get astNodeType() {
1991
2054
  return "increment";
1992
2055
  }
2056
+ search(callback) {
2057
+ this.variable.search(callback);
2058
+ }
1993
2059
  };
1994
2060
  var AssignOperator;
1995
2061
  (function(AssignOperator2) {
@@ -2008,9 +2074,10 @@ void main() {
2008
2074
  (function(AssignOperator2) {
2009
2075
  function parse(val) {
2010
2076
  const key = val;
2011
- if (key == "parse")
2077
+ if (key == "parse") {
2012
2078
  throw new Error("Invalid value for AssignOperator");
2013
- return AssignOperator2[key];
2079
+ }
2080
+ return key;
2014
2081
  }
2015
2082
  AssignOperator2.parse = parse;
2016
2083
  })(AssignOperator || (AssignOperator = {}));
@@ -2024,6 +2091,10 @@ void main() {
2024
2091
  get astNodeType() {
2025
2092
  return "assign";
2026
2093
  }
2094
+ search(callback) {
2095
+ this.variable.search(callback);
2096
+ this.value.search(callback);
2097
+ }
2027
2098
  };
2028
2099
  var Call = class extends Statement {
2029
2100
  constructor(name, args) {
@@ -2034,6 +2105,12 @@ void main() {
2034
2105
  get astNodeType() {
2035
2106
  return "call";
2036
2107
  }
2108
+ search(callback) {
2109
+ for (const node of this.args) {
2110
+ node.search(callback);
2111
+ }
2112
+ callback(this);
2113
+ }
2037
2114
  };
2038
2115
  var Loop = class extends Statement {
2039
2116
  constructor(body, continuing) {
@@ -2066,6 +2143,12 @@ void main() {
2066
2143
  get astNodeType() {
2067
2144
  return "if";
2068
2145
  }
2146
+ search(callback) {
2147
+ this.condition.search(callback);
2148
+ this.searchBlock(this.body, callback);
2149
+ this.searchBlock(this.elseif, callback);
2150
+ this.searchBlock(this.else, callback);
2151
+ }
2069
2152
  };
2070
2153
  var Return = class extends Statement {
2071
2154
  constructor(value) {
@@ -2075,6 +2158,10 @@ void main() {
2075
2158
  get astNodeType() {
2076
2159
  return "return";
2077
2160
  }
2161
+ search(callback) {
2162
+ var _a2;
2163
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
2164
+ }
2078
2165
  };
2079
2166
  var Enable = class extends Statement {
2080
2167
  constructor(name) {
@@ -2085,6 +2172,25 @@ void main() {
2085
2172
  return "enable";
2086
2173
  }
2087
2174
  };
2175
+ var Requires = class extends Statement {
2176
+ constructor(extensions) {
2177
+ super();
2178
+ this.extensions = extensions;
2179
+ }
2180
+ get astNodeType() {
2181
+ return "requires";
2182
+ }
2183
+ };
2184
+ var Diagnostic = class extends Statement {
2185
+ constructor(severity, rule) {
2186
+ super();
2187
+ this.severity = severity;
2188
+ this.rule = rule;
2189
+ }
2190
+ get astNodeType() {
2191
+ return "diagnostic";
2192
+ }
2193
+ };
2088
2194
  var Alias = class extends Statement {
2089
2195
  constructor(name, type) {
2090
2196
  super();
@@ -2135,9 +2241,11 @@ void main() {
2135
2241
  }
2136
2242
  };
2137
2243
  var Struct = class extends Type {
2138
- constructor(name, members) {
2244
+ constructor(name, members, startLine, endLine) {
2139
2245
  super(name);
2140
2246
  this.members = members;
2247
+ this.startLine = startLine;
2248
+ this.endLine = endLine;
2141
2249
  }
2142
2250
  get astNodeType() {
2143
2251
  return "struct";
@@ -2228,6 +2336,12 @@ void main() {
2228
2336
  get astNodeType() {
2229
2337
  return "createExpr";
2230
2338
  }
2339
+ search(callback) {
2340
+ callback(this);
2341
+ for (const node of this.args) {
2342
+ node.search(callback);
2343
+ }
2344
+ }
2231
2345
  };
2232
2346
  var CallExpr = class extends Expression {
2233
2347
  constructor(name, args) {
@@ -2321,6 +2435,12 @@ void main() {
2321
2435
  throw new Error("Non const function: " + this.name);
2322
2436
  }
2323
2437
  }
2438
+ search(callback) {
2439
+ for (const node of this.args) {
2440
+ node.search(callback);
2441
+ }
2442
+ callback(this);
2443
+ }
2324
2444
  };
2325
2445
  var VariableExpr = class extends Expression {
2326
2446
  constructor(name) {
@@ -2330,6 +2450,19 @@ void main() {
2330
2450
  get astNodeType() {
2331
2451
  return "varExpr";
2332
2452
  }
2453
+ search(callback) {
2454
+ callback(this);
2455
+ if (this.postfix) {
2456
+ this.postfix.search(callback);
2457
+ }
2458
+ }
2459
+ evaluate(context) {
2460
+ const constant = context.constants.get(this.name);
2461
+ if (!constant) {
2462
+ throw new Error("Cannot evaluate node");
2463
+ }
2464
+ return constant.evaluate(context);
2465
+ }
2333
2466
  };
2334
2467
  var ConstExpr = class extends Expression {
2335
2468
  constructor(name, initializer) {
@@ -2355,6 +2488,9 @@ void main() {
2355
2488
  }
2356
2489
  return this.initializer.evaluate(context);
2357
2490
  }
2491
+ search(callback) {
2492
+ this.initializer.search(callback);
2493
+ }
2358
2494
  };
2359
2495
  var LiteralExpr = class extends Expression {
2360
2496
  constructor(value) {
@@ -2377,6 +2513,9 @@ void main() {
2377
2513
  get astNodeType() {
2378
2514
  return "bitcastExpr";
2379
2515
  }
2516
+ search(callback) {
2517
+ this.value.search(callback);
2518
+ }
2380
2519
  };
2381
2520
  var TypecastExpr = class extends Expression {
2382
2521
  constructor(type, args) {
@@ -2390,6 +2529,9 @@ void main() {
2390
2529
  evaluate(context) {
2391
2530
  return this.args[0].evaluate(context);
2392
2531
  }
2532
+ search(callback) {
2533
+ this.searchBlock(this.args, callback);
2534
+ }
2393
2535
  };
2394
2536
  var GroupingExpr = class extends Expression {
2395
2537
  constructor(contents) {
@@ -2402,6 +2544,18 @@ void main() {
2402
2544
  evaluate(context) {
2403
2545
  return this.contents[0].evaluate(context);
2404
2546
  }
2547
+ search(callback) {
2548
+ this.searchBlock(this.contents, callback);
2549
+ }
2550
+ };
2551
+ var ArrayIndex = class extends Expression {
2552
+ constructor(index2) {
2553
+ super();
2554
+ this.index = index2;
2555
+ }
2556
+ search(callback) {
2557
+ this.index.search(callback);
2558
+ }
2405
2559
  };
2406
2560
  var Operator = class extends Expression {
2407
2561
  constructor() {
@@ -2431,6 +2585,9 @@ void main() {
2431
2585
  throw new Error("Unknown unary operator: " + this.operator);
2432
2586
  }
2433
2587
  }
2588
+ search(callback) {
2589
+ this.right.search(callback);
2590
+ }
2434
2591
  };
2435
2592
  var BinaryOperator = class extends Operator {
2436
2593
  constructor(operator, left, right) {
@@ -2474,6 +2631,10 @@ void main() {
2474
2631
  throw new Error(`Unknown operator ${this.operator}`);
2475
2632
  }
2476
2633
  }
2634
+ search(callback) {
2635
+ this.left.search(callback);
2636
+ this.right.search(callback);
2637
+ }
2477
2638
  };
2478
2639
  var SwitchCase = class extends Node {
2479
2640
  constructor() {
@@ -2489,6 +2650,9 @@ void main() {
2489
2650
  get astNodeType() {
2490
2651
  return "case";
2491
2652
  }
2653
+ search(callback) {
2654
+ this.searchBlock(this.body, callback);
2655
+ }
2492
2656
  };
2493
2657
  var Default = class extends SwitchCase {
2494
2658
  constructor(body) {
@@ -2498,6 +2662,9 @@ void main() {
2498
2662
  get astNodeType() {
2499
2663
  return "default";
2500
2664
  }
2665
+ search(callback) {
2666
+ this.searchBlock(this.body, callback);
2667
+ }
2501
2668
  };
2502
2669
  var Argument = class extends Node {
2503
2670
  constructor(name, type, attributes) {
@@ -2519,6 +2686,10 @@ void main() {
2519
2686
  get astNodeType() {
2520
2687
  return "elseif";
2521
2688
  }
2689
+ search(callback) {
2690
+ this.condition.search(callback);
2691
+ this.searchBlock(this.body, callback);
2692
+ }
2522
2693
  };
2523
2694
  var Member = class extends Node {
2524
2695
  constructor(name, type, attributes) {
@@ -2633,6 +2804,7 @@ void main() {
2633
2804
  continue: new TokenType("continue", TokenClass.keyword, "continue"),
2634
2805
  continuing: new TokenType("continuing", TokenClass.keyword, "continuing"),
2635
2806
  default: new TokenType("default", TokenClass.keyword, "default"),
2807
+ diagnostic: new TokenType("diagnostic", TokenClass.keyword, "diagnostic"),
2636
2808
  discard: new TokenType("discard", TokenClass.keyword, "discard"),
2637
2809
  else: new TokenType("else", TokenClass.keyword, "else"),
2638
2810
  enable: new TokenType("enable", TokenClass.keyword, "enable"),
@@ -2650,6 +2822,7 @@ void main() {
2650
2822
  read: new TokenType("read", TokenClass.keyword, "read"),
2651
2823
  read_write: new TokenType("read_write", TokenClass.keyword, "read_write"),
2652
2824
  return: new TokenType("return", TokenClass.keyword, "return"),
2825
+ requires: new TokenType("requires", TokenClass.keyword, "requires"),
2653
2826
  storage: new TokenType("storage", TokenClass.keyword, "storage"),
2654
2827
  switch: new TokenType("switch", TokenClass.keyword, "switch"),
2655
2828
  true: new TokenType("true", TokenClass.keyword, "true"),
@@ -2708,13 +2881,11 @@ void main() {
2708
2881
  hex_float_literal: new TokenType("hex_float_literal", TokenClass.token, /-?0x((([0-9a-fA-F]*\.[0-9a-fA-F]+|[0-9a-fA-F]+\.[0-9a-fA-F]*)((p|P)(\+|-)?[0-9]+f?)?)|([0-9a-fA-F]+(p|P)(\+|-)?[0-9]+f?))/),
2709
2882
  int_literal: new TokenType("int_literal", TokenClass.token, /-?0x[0-9a-fA-F]+|0i?|-?[1-9][0-9]*i?/),
2710
2883
  uint_literal: new TokenType("uint_literal", TokenClass.token, /0x[0-9a-fA-F]+u|0u|[1-9][0-9]*u/),
2711
- ident: new TokenType("ident", TokenClass.token, /[a-zA-Z][0-9a-zA-Z_]*/),
2884
+ ident: new TokenType("ident", TokenClass.token, /[_a-zA-Z][0-9a-zA-Z_]*/),
2712
2885
  and: new TokenType("and", TokenClass.token, "&"),
2713
2886
  and_and: new TokenType("and_and", TokenClass.token, "&&"),
2714
2887
  arrow: new TokenType("arrow ", TokenClass.token, "->"),
2715
2888
  attr: new TokenType("attr", TokenClass.token, "@"),
2716
- attr_left: new TokenType("attr_left", TokenClass.token, "[["),
2717
- attr_right: new TokenType("attr_right", TokenClass.token, "]]"),
2718
2889
  forward_slash: new TokenType("forward_slash", TokenClass.token, "/"),
2719
2890
  bang: new TokenType("bang", TokenClass.token, "!"),
2720
2891
  bracket_left: new TokenType("bracket_left", TokenClass.token, "["),
@@ -2758,6 +2929,63 @@ void main() {
2758
2929
  shift_right_equal: new TokenType("shift_right_equal", TokenClass.token, ">>="),
2759
2930
  shift_left_equal: new TokenType("shift_left_equal", TokenClass.token, "<<=")
2760
2931
  };
2932
+ TokenTypes.simpleTokens = {
2933
+ "@": _a.tokens.attr,
2934
+ "{": _a.tokens.brace_left,
2935
+ "}": _a.tokens.brace_right,
2936
+ ":": _a.tokens.colon,
2937
+ ",": _a.tokens.comma,
2938
+ "(": _a.tokens.paren_left,
2939
+ ")": _a.tokens.paren_right,
2940
+ ";": _a.tokens.semicolon
2941
+ };
2942
+ TokenTypes.literalTokens = {
2943
+ "&": _a.tokens.and,
2944
+ "&&": _a.tokens.and_and,
2945
+ "->": _a.tokens.arrow,
2946
+ "/": _a.tokens.forward_slash,
2947
+ "!": _a.tokens.bang,
2948
+ "[": _a.tokens.bracket_left,
2949
+ "]": _a.tokens.bracket_right,
2950
+ "=": _a.tokens.equal,
2951
+ "==": _a.tokens.equal_equal,
2952
+ "!=": _a.tokens.not_equal,
2953
+ ">": _a.tokens.greater_than,
2954
+ ">=": _a.tokens.greater_than_equal,
2955
+ ">>": _a.tokens.shift_right,
2956
+ "<": _a.tokens.less_than,
2957
+ "<=": _a.tokens.less_than_equal,
2958
+ "<<": _a.tokens.shift_left,
2959
+ "%": _a.tokens.modulo,
2960
+ "-": _a.tokens.minus,
2961
+ "--": _a.tokens.minus_minus,
2962
+ ".": _a.tokens.period,
2963
+ "+": _a.tokens.plus,
2964
+ "++": _a.tokens.plus_plus,
2965
+ "|": _a.tokens.or,
2966
+ "||": _a.tokens.or_or,
2967
+ "*": _a.tokens.star,
2968
+ "~": _a.tokens.tilde,
2969
+ "_": _a.tokens.underscore,
2970
+ "^": _a.tokens.xor,
2971
+ "+=": _a.tokens.plus_equal,
2972
+ "-=": _a.tokens.minus_equal,
2973
+ "*=": _a.tokens.times_equal,
2974
+ "/=": _a.tokens.division_equal,
2975
+ "%=": _a.tokens.modulo_equal,
2976
+ "&=": _a.tokens.and_equal,
2977
+ "|=": _a.tokens.or_equal,
2978
+ "^=": _a.tokens.xor_equal,
2979
+ ">>=": _a.tokens.shift_right_equal,
2980
+ "<<=": _a.tokens.shift_left_equal
2981
+ };
2982
+ TokenTypes.regexTokens = {
2983
+ decimal_float_literal: _a.tokens.decimal_float_literal,
2984
+ hex_float_literal: _a.tokens.hex_float_literal,
2985
+ int_literal: _a.tokens.int_literal,
2986
+ uint_literal: _a.tokens.uint_literal,
2987
+ ident: _a.tokens.ident
2988
+ };
2761
2989
  TokenTypes.storage_class = [
2762
2990
  _a.keywords.function,
2763
2991
  _a.keywords.private,
@@ -2880,7 +3108,7 @@ void main() {
2880
3108
  _a.keywords.bitcast,
2881
3109
  ..._a.any_texture_type
2882
3110
  ];
2883
- TokenTypes.attribute_name = [_a.tokens.ident, _a.keywords.block];
3111
+ TokenTypes.attribute_name = [_a.tokens.ident, _a.keywords.block, _a.keywords.diagnostic];
2884
3112
  TokenTypes.assignment_operators = [
2885
3113
  _a.tokens.equal,
2886
3114
  _a.tokens.plus_equal,
@@ -2929,8 +3157,9 @@ void main() {
2929
3157
  scanTokens() {
2930
3158
  while (!this._isAtEnd()) {
2931
3159
  this._start = this._current;
2932
- if (!this.scanToken())
3160
+ if (!this.scanToken()) {
2933
3161
  throw `Invalid syntax at line ${this._line}`;
3162
+ }
2934
3163
  }
2935
3164
  this._tokens.push(new Token(TokenTypes.eof, "", this._line));
2936
3165
  return this._tokens;
@@ -2948,8 +3177,9 @@ void main() {
2948
3177
  if (lexeme == "/") {
2949
3178
  if (this._peekAhead() == "/") {
2950
3179
  while (lexeme != "\n") {
2951
- if (this._isAtEnd())
3180
+ if (this._isAtEnd()) {
2952
3181
  return true;
3182
+ }
2953
3183
  lexeme = this._advance();
2954
3184
  }
2955
3185
  this._line++;
@@ -2958,8 +3188,9 @@ void main() {
2958
3188
  this._advance();
2959
3189
  let commentLevel = 1;
2960
3190
  while (commentLevel > 0) {
2961
- if (this._isAtEnd())
3191
+ if (this._isAtEnd()) {
2962
3192
  return true;
3193
+ }
2963
3194
  lexeme = this._advance();
2964
3195
  if (lexeme == "\n") {
2965
3196
  this._line++;
@@ -2981,7 +3212,32 @@ void main() {
2981
3212
  return true;
2982
3213
  }
2983
3214
  }
3215
+ const simpleToken = TokenTypes.simpleTokens[lexeme];
3216
+ if (simpleToken) {
3217
+ this._addToken(simpleToken);
3218
+ return true;
3219
+ }
2984
3220
  let matchType = TokenTypes.none;
3221
+ const isAlpha = this._isAlpha(lexeme);
3222
+ const isUnderscore = lexeme === "_";
3223
+ if (this._isAlphaNumeric(lexeme)) {
3224
+ let nextChar = this._peekAhead();
3225
+ while (this._isAlphaNumeric(nextChar)) {
3226
+ lexeme += this._advance();
3227
+ nextChar = this._peekAhead();
3228
+ }
3229
+ }
3230
+ if (isAlpha) {
3231
+ const matchedType = TokenTypes.keywords[lexeme];
3232
+ if (matchedType) {
3233
+ this._addToken(matchedType);
3234
+ return true;
3235
+ }
3236
+ }
3237
+ if (isAlpha || isUnderscore) {
3238
+ this._addToken(TokenTypes.tokens.ident);
3239
+ return true;
3240
+ }
2985
3241
  for (; ; ) {
2986
3242
  let matchedType = this._findType(lexeme);
2987
3243
  const nextLexeme = this._peekAhead();
@@ -3014,8 +3270,9 @@ void main() {
3014
3270
  }
3015
3271
  }
3016
3272
  if (matchedType === TokenTypes.none) {
3017
- if (matchType === TokenTypes.none)
3273
+ if (matchType === TokenTypes.none) {
3018
3274
  return false;
3275
+ }
3019
3276
  this._current--;
3020
3277
  this._addToken(matchType);
3021
3278
  return true;
@@ -3024,45 +3281,43 @@ void main() {
3024
3281
  this._current += lookAhead + 1;
3025
3282
  }
3026
3283
  matchType = matchedType;
3027
- if (this._isAtEnd())
3284
+ if (this._isAtEnd()) {
3028
3285
  break;
3286
+ }
3029
3287
  lexeme += this._advance();
3030
3288
  }
3031
- if (matchType === TokenTypes.none)
3289
+ if (matchType === TokenTypes.none) {
3032
3290
  return false;
3291
+ }
3033
3292
  this._addToken(matchType);
3034
3293
  return true;
3035
3294
  }
3036
3295
  _findType(lexeme) {
3037
- for (const name in TokenTypes.keywords) {
3038
- const type = TokenTypes.keywords[name];
3039
- if (this._match(lexeme, type.rule)) {
3040
- return type;
3296
+ for (const name in TokenTypes.regexTokens) {
3297
+ const type2 = TokenTypes.regexTokens[name];
3298
+ if (this._match(lexeme, type2.rule)) {
3299
+ return type2;
3041
3300
  }
3042
3301
  }
3043
- for (const name in TokenTypes.tokens) {
3044
- const type = TokenTypes.tokens[name];
3045
- if (this._match(lexeme, type.rule)) {
3046
- return type;
3047
- }
3302
+ const type = TokenTypes.literalTokens[lexeme];
3303
+ if (type) {
3304
+ return type;
3048
3305
  }
3049
3306
  return TokenTypes.none;
3050
3307
  }
3051
3308
  _match(lexeme, rule) {
3052
- if (typeof rule === "string") {
3053
- if (rule == lexeme) {
3054
- return true;
3055
- }
3056
- } else {
3057
- const match = rule.exec(lexeme);
3058
- if (match && match.index == 0 && match[0] == lexeme)
3059
- return true;
3060
- }
3061
- return false;
3309
+ const match = rule.exec(lexeme);
3310
+ return match && match.index == 0 && match[0] == lexeme;
3062
3311
  }
3063
3312
  _isAtEnd() {
3064
3313
  return this._current >= this._source.length;
3065
3314
  }
3315
+ _isAlpha(c) {
3316
+ return c >= "a" && c <= "z" || c >= "A" && c <= "Z";
3317
+ }
3318
+ _isAlphaNumeric(c) {
3319
+ return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c == "_" || c >= "0" && c <= "9";
3320
+ }
3066
3321
  _isWhitespace(c) {
3067
3322
  return c == " " || c == " " || c == "\r";
3068
3323
  }
@@ -3075,8 +3330,9 @@ void main() {
3075
3330
  }
3076
3331
  _peekAhead(offset = 0) {
3077
3332
  offset = offset || 0;
3078
- if (this._current + offset >= this._source.length)
3333
+ if (this._current + offset >= this._source.length) {
3079
3334
  return "\0";
3335
+ }
3080
3336
  return this._source[this._current + offset];
3081
3337
  }
3082
3338
  _addToken(type) {
@@ -3088,17 +3344,40 @@ void main() {
3088
3344
  constructor() {
3089
3345
  this._tokens = [];
3090
3346
  this._current = 0;
3347
+ this._currentLine = 0;
3091
3348
  this._context = new ParseContext();
3349
+ this._deferArrayCountEval = [];
3092
3350
  }
3093
3351
  parse(tokensOrCode) {
3094
3352
  this._initialize(tokensOrCode);
3095
- let statements = [];
3353
+ this._deferArrayCountEval.length = 0;
3354
+ const statements = [];
3096
3355
  while (!this._isAtEnd()) {
3097
3356
  const statement = this._global_decl_or_directive();
3098
- if (!statement)
3357
+ if (!statement) {
3099
3358
  break;
3359
+ }
3100
3360
  statements.push(statement);
3101
3361
  }
3362
+ if (this._deferArrayCountEval.length > 0) {
3363
+ for (const arrayDecl of this._deferArrayCountEval) {
3364
+ const arrayType = arrayDecl["arrayType"];
3365
+ const countNode = arrayDecl["countNode"];
3366
+ if (countNode instanceof VariableExpr) {
3367
+ const variable = countNode;
3368
+ const name = variable.name;
3369
+ const constant = this._context.constants.get(name);
3370
+ if (constant) {
3371
+ try {
3372
+ const count = constant.evaluate(this._context);
3373
+ arrayType.count = count;
3374
+ } catch (e) {
3375
+ }
3376
+ }
3377
+ }
3378
+ }
3379
+ this._deferArrayCountEval.length = 0;
3380
+ }
3102
3381
  return statements;
3103
3382
  }
3104
3383
  _initialize(tokensOrCode) {
@@ -3115,7 +3394,6 @@ void main() {
3115
3394
  this._current = 0;
3116
3395
  }
3117
3396
  _error(token, message) {
3118
- console.error(token, message);
3119
3397
  return {
3120
3398
  token,
3121
3399
  message,
@@ -3145,24 +3423,29 @@ void main() {
3145
3423
  return false;
3146
3424
  }
3147
3425
  _consume(types, message) {
3148
- if (this._check(types))
3426
+ if (this._check(types)) {
3149
3427
  return this._advance();
3428
+ }
3150
3429
  throw this._error(this._peek(), message);
3151
3430
  }
3152
3431
  _check(types) {
3153
- if (this._isAtEnd())
3432
+ if (this._isAtEnd()) {
3154
3433
  return false;
3434
+ }
3155
3435
  const tk = this._peek();
3156
3436
  if (types instanceof Array) {
3157
- let t = tk.type;
3158
- let index2 = types.indexOf(t);
3437
+ const t = tk.type;
3438
+ const index2 = types.indexOf(t);
3159
3439
  return index2 != -1;
3160
3440
  }
3161
3441
  return tk.type == types;
3162
3442
  }
3163
3443
  _advance() {
3164
- if (!this._isAtEnd())
3444
+ var _a2, _b;
3445
+ this._currentLine = (_b = (_a2 = this._peek()) === null || _a2 === void 0 ? void 0 : _a2.line) !== null && _b !== void 0 ? _b : -1;
3446
+ if (!this._isAtEnd()) {
3165
3447
  this._current++;
3448
+ }
3166
3449
  return this._previous();
3167
3450
  }
3168
3451
  _peek() {
@@ -3179,6 +3462,16 @@ void main() {
3179
3462
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
3180
3463
  return type;
3181
3464
  }
3465
+ if (this._match(TokenTypes.keywords.diagnostic)) {
3466
+ const directive = this._diagnostic();
3467
+ this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
3468
+ return directive;
3469
+ }
3470
+ if (this._match(TokenTypes.keywords.requires)) {
3471
+ const requires = this._requires_directive();
3472
+ this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
3473
+ return requires;
3474
+ }
3182
3475
  if (this._match(TokenTypes.keywords.enable)) {
3183
3476
  const enable = this._enable_directive();
3184
3477
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
@@ -3187,56 +3480,65 @@ void main() {
3187
3480
  const attrs = this._attribute();
3188
3481
  if (this._check(TokenTypes.keywords.var)) {
3189
3482
  const _var = this._global_variable_decl();
3190
- if (_var != null)
3483
+ if (_var != null) {
3191
3484
  _var.attributes = attrs;
3485
+ }
3192
3486
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
3193
3487
  return _var;
3194
3488
  }
3195
3489
  if (this._check(TokenTypes.keywords.override)) {
3196
3490
  const _override = this._override_variable_decl();
3197
- if (_override != null)
3491
+ if (_override != null) {
3198
3492
  _override.attributes = attrs;
3493
+ }
3199
3494
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
3200
3495
  return _override;
3201
3496
  }
3202
3497
  if (this._check(TokenTypes.keywords.let)) {
3203
3498
  const _let = this._global_let_decl();
3204
- if (_let != null)
3499
+ if (_let != null) {
3205
3500
  _let.attributes = attrs;
3501
+ }
3206
3502
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
3207
3503
  return _let;
3208
3504
  }
3209
3505
  if (this._check(TokenTypes.keywords.const)) {
3210
3506
  const _const = this._global_const_decl();
3211
- if (_const != null)
3507
+ if (_const != null) {
3212
3508
  _const.attributes = attrs;
3509
+ }
3213
3510
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
3214
3511
  return _const;
3215
3512
  }
3216
3513
  if (this._check(TokenTypes.keywords.struct)) {
3217
3514
  const _struct = this._struct_decl();
3218
- if (_struct != null)
3515
+ if (_struct != null) {
3219
3516
  _struct.attributes = attrs;
3517
+ }
3220
3518
  return _struct;
3221
3519
  }
3222
3520
  if (this._check(TokenTypes.keywords.fn)) {
3223
3521
  const _fn = this._function_decl();
3224
- if (_fn != null)
3522
+ if (_fn != null) {
3225
3523
  _fn.attributes = attrs;
3524
+ }
3226
3525
  return _fn;
3227
3526
  }
3228
3527
  return null;
3229
3528
  }
3230
3529
  _function_decl() {
3231
- if (!this._match(TokenTypes.keywords.fn))
3530
+ if (!this._match(TokenTypes.keywords.fn)) {
3232
3531
  return null;
3532
+ }
3533
+ const startLine = this._currentLine;
3233
3534
  const name = this._consume(TokenTypes.tokens.ident, "Expected function name.").toString();
3234
3535
  this._consume(TokenTypes.tokens.paren_left, "Expected '(' for function arguments.");
3235
3536
  const args = [];
3236
3537
  if (!this._check(TokenTypes.tokens.paren_right)) {
3237
3538
  do {
3238
- if (this._check(TokenTypes.tokens.paren_right))
3539
+ if (this._check(TokenTypes.tokens.paren_right)) {
3239
3540
  break;
3541
+ }
3240
3542
  const argAttrs = this._attribute();
3241
3543
  const name2 = this._consume(TokenTypes.tokens.ident, "Expected argument name.").toString();
3242
3544
  this._consume(TokenTypes.tokens.colon, "Expected ':' for argument type.");
@@ -3253,19 +3555,22 @@ void main() {
3253
3555
  if (this._match(TokenTypes.tokens.arrow)) {
3254
3556
  const attrs = this._attribute();
3255
3557
  _return = this._type_decl();
3256
- if (_return != null)
3558
+ if (_return != null) {
3257
3559
  _return.attributes = attrs;
3560
+ }
3258
3561
  }
3259
3562
  const body = this._compound_statement();
3260
- return new Function(name, args, _return, body);
3563
+ const endLine = this._currentLine;
3564
+ return new Function(name, args, _return, body, startLine, endLine);
3261
3565
  }
3262
3566
  _compound_statement() {
3263
3567
  const statements = [];
3264
3568
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for block.");
3265
3569
  while (!this._check(TokenTypes.tokens.brace_right)) {
3266
3570
  const statement = this._statement();
3267
- if (statement !== null)
3571
+ if (statement !== null) {
3268
3572
  statements.push(statement);
3573
+ }
3269
3574
  }
3270
3575
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' for block.");
3271
3576
  return statements;
@@ -3273,65 +3578,85 @@ void main() {
3273
3578
  _statement() {
3274
3579
  while (this._match(TokenTypes.tokens.semicolon) && !this._isAtEnd())
3275
3580
  ;
3276
- if (this._check(TokenTypes.keywords.if))
3581
+ if (this._check(TokenTypes.tokens.attr)) {
3582
+ this._attribute();
3583
+ }
3584
+ if (this._check(TokenTypes.keywords.if)) {
3277
3585
  return this._if_statement();
3278
- if (this._check(TokenTypes.keywords.switch))
3586
+ }
3587
+ if (this._check(TokenTypes.keywords.switch)) {
3279
3588
  return this._switch_statement();
3280
- if (this._check(TokenTypes.keywords.loop))
3589
+ }
3590
+ if (this._check(TokenTypes.keywords.loop)) {
3281
3591
  return this._loop_statement();
3282
- if (this._check(TokenTypes.keywords.for))
3592
+ }
3593
+ if (this._check(TokenTypes.keywords.for)) {
3283
3594
  return this._for_statement();
3284
- if (this._check(TokenTypes.keywords.while))
3595
+ }
3596
+ if (this._check(TokenTypes.keywords.while)) {
3285
3597
  return this._while_statement();
3286
- if (this._check(TokenTypes.keywords.continuing))
3598
+ }
3599
+ if (this._check(TokenTypes.keywords.continuing)) {
3287
3600
  return this._continuing_statement();
3288
- if (this._check(TokenTypes.keywords.static_assert))
3601
+ }
3602
+ if (this._check(TokenTypes.keywords.static_assert)) {
3289
3603
  return this._static_assert_statement();
3290
- if (this._check(TokenTypes.tokens.brace_left))
3604
+ }
3605
+ if (this._check(TokenTypes.tokens.brace_left)) {
3291
3606
  return this._compound_statement();
3607
+ }
3292
3608
  let result = null;
3293
- if (this._check(TokenTypes.keywords.return))
3609
+ if (this._check(TokenTypes.keywords.return)) {
3294
3610
  result = this._return_statement();
3295
- else if (this._check([
3611
+ } else if (this._check([
3296
3612
  TokenTypes.keywords.var,
3297
3613
  TokenTypes.keywords.let,
3298
3614
  TokenTypes.keywords.const
3299
- ]))
3615
+ ])) {
3300
3616
  result = this._variable_statement();
3301
- else if (this._match(TokenTypes.keywords.discard))
3617
+ } else if (this._match(TokenTypes.keywords.discard)) {
3302
3618
  result = new Discard();
3303
- else if (this._match(TokenTypes.keywords.break))
3619
+ } else if (this._match(TokenTypes.keywords.break)) {
3304
3620
  result = new Break();
3305
- else if (this._match(TokenTypes.keywords.continue))
3621
+ } else if (this._match(TokenTypes.keywords.continue)) {
3306
3622
  result = new Continue();
3307
- else
3623
+ } else {
3308
3624
  result = this._increment_decrement_statement() || this._func_call_statement() || this._assignment_statement();
3309
- if (result != null)
3625
+ }
3626
+ if (result != null) {
3310
3627
  this._consume(TokenTypes.tokens.semicolon, "Expected ';' after statement.");
3628
+ }
3311
3629
  return result;
3312
3630
  }
3313
3631
  _static_assert_statement() {
3314
- if (!this._match(TokenTypes.keywords.static_assert))
3632
+ if (!this._match(TokenTypes.keywords.static_assert)) {
3315
3633
  return null;
3316
- let expression = this._optional_paren_expression();
3634
+ }
3635
+ const expression = this._optional_paren_expression();
3317
3636
  return new StaticAssert(expression);
3318
3637
  }
3319
3638
  _while_statement() {
3320
- if (!this._match(TokenTypes.keywords.while))
3639
+ if (!this._match(TokenTypes.keywords.while)) {
3321
3640
  return null;
3322
- let condition = this._optional_paren_expression();
3641
+ }
3642
+ const condition = this._optional_paren_expression();
3643
+ if (this._check(TokenTypes.tokens.attr)) {
3644
+ this._attribute();
3645
+ }
3323
3646
  const block = this._compound_statement();
3324
3647
  return new While(condition, block);
3325
3648
  }
3326
3649
  _continuing_statement() {
3327
- if (!this._match(TokenTypes.keywords.continuing))
3650
+ if (!this._match(TokenTypes.keywords.continuing)) {
3328
3651
  return null;
3652
+ }
3329
3653
  const block = this._compound_statement();
3330
3654
  return new Continuing(block);
3331
3655
  }
3332
3656
  _for_statement() {
3333
- if (!this._match(TokenTypes.keywords.for))
3657
+ if (!this._match(TokenTypes.keywords.for)) {
3334
3658
  return null;
3659
+ }
3335
3660
  this._consume(TokenTypes.tokens.paren_left, "Expected '('.");
3336
3661
  const init = !this._check(TokenTypes.tokens.semicolon) ? this._for_init() : null;
3337
3662
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
@@ -3339,6 +3664,9 @@ void main() {
3339
3664
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
3340
3665
  const increment = !this._check(TokenTypes.tokens.paren_right) ? this._for_increment() : null;
3341
3666
  this._consume(TokenTypes.tokens.paren_right, "Expected ')'.");
3667
+ if (this._check(TokenTypes.tokens.attr)) {
3668
+ this._attribute();
3669
+ }
3342
3670
  const body = this._compound_statement();
3343
3671
  return new For(init, condition, increment, body);
3344
3672
  }
@@ -3351,11 +3679,13 @@ void main() {
3351
3679
  _variable_statement() {
3352
3680
  if (this._check(TokenTypes.keywords.var)) {
3353
3681
  const _var = this._variable_decl();
3354
- if (_var === null)
3682
+ if (_var === null) {
3355
3683
  throw this._error(this._peek(), "Variable declaration expected.");
3684
+ }
3356
3685
  let value = null;
3357
- if (this._match(TokenTypes.tokens.equal))
3686
+ if (this._match(TokenTypes.tokens.equal)) {
3358
3687
  value = this._short_circuit_or_expression();
3688
+ }
3359
3689
  return new Var(_var.name, _var.type, _var.storage, _var.access, value);
3360
3690
  }
3361
3691
  if (this._match(TokenTypes.keywords.let)) {
@@ -3364,8 +3694,9 @@ void main() {
3364
3694
  if (this._match(TokenTypes.tokens.colon)) {
3365
3695
  const typeAttrs = this._attribute();
3366
3696
  type = this._type_decl();
3367
- if (type != null)
3697
+ if (type != null) {
3368
3698
  type.attributes = typeAttrs;
3699
+ }
3369
3700
  }
3370
3701
  this._consume(TokenTypes.tokens.equal, "Expected '=' for let.");
3371
3702
  const value = this._short_circuit_or_expression();
@@ -3377,8 +3708,9 @@ void main() {
3377
3708
  if (this._match(TokenTypes.tokens.colon)) {
3378
3709
  const typeAttrs = this._attribute();
3379
3710
  type = this._type_decl();
3380
- if (type != null)
3711
+ if (type != null) {
3381
3712
  type.attributes = typeAttrs;
3713
+ }
3382
3714
  }
3383
3715
  this._consume(TokenTypes.tokens.equal, "Expected '=' for const.");
3384
3716
  const value = this._short_circuit_or_expression();
@@ -3389,8 +3721,9 @@ void main() {
3389
3721
  _increment_decrement_statement() {
3390
3722
  const savedPos = this._current;
3391
3723
  const _var = this._unary_expression();
3392
- if (_var == null)
3724
+ if (_var == null) {
3393
3725
  return null;
3726
+ }
3394
3727
  if (!this._check(TokenTypes.increment_operators)) {
3395
3728
  this._current = savedPos;
3396
3729
  return null;
@@ -3400,20 +3733,24 @@ void main() {
3400
3733
  }
3401
3734
  _assignment_statement() {
3402
3735
  let _var = null;
3403
- if (this._check(TokenTypes.tokens.brace_right))
3736
+ if (this._check(TokenTypes.tokens.brace_right)) {
3404
3737
  return null;
3738
+ }
3405
3739
  let isUnderscore = this._match(TokenTypes.tokens.underscore);
3406
- if (!isUnderscore)
3740
+ if (!isUnderscore) {
3407
3741
  _var = this._unary_expression();
3408
- if (!isUnderscore && _var == null)
3742
+ }
3743
+ if (!isUnderscore && _var == null) {
3409
3744
  return null;
3745
+ }
3410
3746
  const type = this._consume(TokenTypes.assignment_operators, "Expected assignment operator.");
3411
3747
  const value = this._short_circuit_or_expression();
3412
3748
  return new Assign(AssignOperator.parse(type.lexeme), _var, value);
3413
3749
  }
3414
3750
  _func_call_statement() {
3415
- if (!this._check(TokenTypes.tokens.ident))
3751
+ if (!this._check(TokenTypes.tokens.ident)) {
3416
3752
  return null;
3753
+ }
3417
3754
  const savedPos = this._current;
3418
3755
  const name = this._consume(TokenTypes.tokens.ident, "Expected function name.");
3419
3756
  const args = this._argument_expression_list();
@@ -3424,8 +3761,12 @@ void main() {
3424
3761
  return new Call(name.lexeme, args);
3425
3762
  }
3426
3763
  _loop_statement() {
3427
- if (!this._match(TokenTypes.keywords.loop))
3764
+ if (!this._match(TokenTypes.keywords.loop)) {
3428
3765
  return null;
3766
+ }
3767
+ if (this._check(TokenTypes.tokens.attr)) {
3768
+ this._attribute();
3769
+ }
3429
3770
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for loop.");
3430
3771
  const statements = [];
3431
3772
  let statement = this._statement();
@@ -3440,19 +3781,25 @@ void main() {
3440
3781
  statement = this._statement();
3441
3782
  }
3442
3783
  let continuing = null;
3443
- if (this._match(TokenTypes.keywords.continuing))
3784
+ if (this._match(TokenTypes.keywords.continuing)) {
3444
3785
  continuing = this._compound_statement();
3786
+ }
3445
3787
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' for loop.");
3446
3788
  return new Loop(statements, continuing);
3447
3789
  }
3448
3790
  _switch_statement() {
3449
- if (!this._match(TokenTypes.keywords.switch))
3791
+ if (!this._match(TokenTypes.keywords.switch)) {
3450
3792
  return null;
3793
+ }
3451
3794
  const condition = this._optional_paren_expression();
3795
+ if (this._check(TokenTypes.tokens.attr)) {
3796
+ this._attribute();
3797
+ }
3452
3798
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for switch.");
3453
3799
  const body = this._switch_body();
3454
- if (body == null || body.length == 0)
3800
+ if (body == null || body.length == 0) {
3455
3801
  throw this._error(this._previous(), "Expected 'case' or 'default'.");
3802
+ }
3456
3803
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' for switch.");
3457
3804
  return new Switch(condition, body);
3458
3805
  }
@@ -3461,6 +3808,9 @@ void main() {
3461
3808
  if (this._match(TokenTypes.keywords.case)) {
3462
3809
  const selector = this._case_selectors();
3463
3810
  this._match(TokenTypes.tokens.colon);
3811
+ if (this._check(TokenTypes.tokens.attr)) {
3812
+ this._attribute();
3813
+ }
3464
3814
  this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch case.");
3465
3815
  const body = this._case_body();
3466
3816
  this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch case.");
@@ -3468,6 +3818,9 @@ void main() {
3468
3818
  }
3469
3819
  if (this._match(TokenTypes.keywords.default)) {
3470
3820
  this._match(TokenTypes.tokens.colon);
3821
+ if (this._check(TokenTypes.tokens.attr)) {
3822
+ this._attribute();
3823
+ }
3471
3824
  this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch default.");
3472
3825
  const body = this._case_body();
3473
3826
  this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch default.");
@@ -3480,12 +3833,12 @@ void main() {
3480
3833
  return cases;
3481
3834
  }
3482
3835
  _case_selectors() {
3483
- var _a2, _b, _c, _d;
3484
3836
  const selectors = [
3485
- (_b = (_a2 = this._shift_expression()) === null || _a2 === void 0 ? void 0 : _a2.evaluate(this._context).toString()) !== null && _b !== void 0 ? _b : ""
3837
+ this._shift_expression()
3838
+ //?.evaluate(this._context).toString() ?? "",
3486
3839
  ];
3487
3840
  while (this._match(TokenTypes.tokens.comma)) {
3488
- selectors.push((_d = (_c = this._shift_expression()) === null || _c === void 0 ? void 0 : _c.evaluate(this._context).toString()) !== null && _d !== void 0 ? _d : "");
3841
+ selectors.push(this._shift_expression());
3489
3842
  }
3490
3843
  return selectors;
3491
3844
  }
@@ -3495,28 +3848,41 @@ void main() {
3495
3848
  return [];
3496
3849
  }
3497
3850
  let statement = this._statement();
3498
- if (statement == null)
3851
+ if (statement == null) {
3499
3852
  return [];
3853
+ }
3500
3854
  if (!(statement instanceof Array)) {
3501
3855
  statement = [statement];
3502
3856
  }
3503
3857
  const nextStatement = this._case_body();
3504
- if (nextStatement.length == 0)
3858
+ if (nextStatement.length == 0) {
3505
3859
  return statement;
3860
+ }
3506
3861
  return [...statement, nextStatement[0]];
3507
3862
  }
3508
3863
  _if_statement() {
3509
- if (!this._match(TokenTypes.keywords.if))
3864
+ if (!this._match(TokenTypes.keywords.if)) {
3510
3865
  return null;
3866
+ }
3511
3867
  const condition = this._optional_paren_expression();
3868
+ if (this._check(TokenTypes.tokens.attr)) {
3869
+ this._attribute();
3870
+ }
3512
3871
  const block = this._compound_statement();
3513
3872
  let elseif = [];
3514
3873
  if (this._match_elseif()) {
3874
+ if (this._check(TokenTypes.tokens.attr)) {
3875
+ this._attribute();
3876
+ }
3515
3877
  elseif = this._elseif_statement(elseif);
3516
3878
  }
3517
3879
  let _else = null;
3518
- if (this._match(TokenTypes.keywords.else))
3880
+ if (this._match(TokenTypes.keywords.else)) {
3881
+ if (this._check(TokenTypes.tokens.attr)) {
3882
+ this._attribute();
3883
+ }
3519
3884
  _else = this._compound_statement();
3885
+ }
3520
3886
  return new If(condition, block, elseif, _else);
3521
3887
  }
3522
3888
  _match_elseif() {
@@ -3532,13 +3898,17 @@ void main() {
3532
3898
  const block = this._compound_statement();
3533
3899
  elseif.push(new ElseIf(condition, block));
3534
3900
  if (this._match_elseif()) {
3901
+ if (this._check(TokenTypes.tokens.attr)) {
3902
+ this._attribute();
3903
+ }
3535
3904
  this._elseif_statement(elseif);
3536
3905
  }
3537
3906
  return elseif;
3538
3907
  }
3539
3908
  _return_statement() {
3540
- if (!this._match(TokenTypes.keywords.return))
3909
+ if (!this._match(TokenTypes.keywords.return)) {
3541
3910
  return null;
3911
+ }
3542
3912
  const value = this._short_circuit_or_expression();
3543
3913
  return new Return(value);
3544
3914
  }
@@ -3636,25 +4006,29 @@ void main() {
3636
4006
  _singular_expression() {
3637
4007
  const expr = this._primary_expression();
3638
4008
  const p = this._postfix_expression();
3639
- if (p)
4009
+ if (p) {
3640
4010
  expr.postfix = p;
4011
+ }
3641
4012
  return expr;
3642
4013
  }
3643
4014
  _postfix_expression() {
3644
4015
  if (this._match(TokenTypes.tokens.bracket_left)) {
3645
4016
  const expr = this._short_circuit_or_expression();
3646
4017
  this._consume(TokenTypes.tokens.bracket_right, "Expected ']'.");
4018
+ const arrayIndex = new ArrayIndex(expr);
3647
4019
  const p = this._postfix_expression();
3648
- if (p)
3649
- expr.postfix = p;
3650
- return expr;
4020
+ if (p) {
4021
+ arrayIndex.postfix = p;
4022
+ }
4023
+ return arrayIndex;
3651
4024
  }
3652
4025
  if (this._match(TokenTypes.tokens.period)) {
3653
4026
  const name = this._consume(TokenTypes.tokens.ident, "Expected member name.");
3654
4027
  const p = this._postfix_expression();
3655
4028
  const expr = new StringExpr(name.lexeme);
3656
- if (p)
4029
+ if (p) {
3657
4030
  expr.postfix = p;
4031
+ }
3658
4032
  return expr;
3659
4033
  }
3660
4034
  return null;
@@ -3705,12 +4079,14 @@ void main() {
3705
4079
  return new TypecastExpr(type, args);
3706
4080
  }
3707
4081
  _argument_expression_list() {
3708
- if (!this._match(TokenTypes.tokens.paren_left))
4082
+ if (!this._match(TokenTypes.tokens.paren_left)) {
3709
4083
  return null;
4084
+ }
3710
4085
  const args = [];
3711
4086
  do {
3712
- if (this._check(TokenTypes.tokens.paren_right))
4087
+ if (this._check(TokenTypes.tokens.paren_right)) {
3713
4088
  break;
4089
+ }
3714
4090
  const arg = this._short_circuit_or_expression();
3715
4091
  args.push(arg);
3716
4092
  } while (this._match(TokenTypes.tokens.comma));
@@ -3730,8 +4106,10 @@ void main() {
3730
4106
  return new GroupingExpr([expr]);
3731
4107
  }
3732
4108
  _struct_decl() {
3733
- if (!this._match(TokenTypes.keywords.struct))
4109
+ if (!this._match(TokenTypes.keywords.struct)) {
3734
4110
  return null;
4111
+ }
4112
+ const startLine = this._currentLine;
3735
4113
  const name = this._consume(TokenTypes.tokens.ident, "Expected name for struct.").toString();
3736
4114
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for struct body.");
3737
4115
  const members = [];
@@ -3741,8 +4119,9 @@ void main() {
3741
4119
  this._consume(TokenTypes.tokens.colon, "Expected ':' for struct member type.");
3742
4120
  const typeAttrs = this._attribute();
3743
4121
  const memberType = this._type_decl();
3744
- if (memberType != null)
4122
+ if (memberType != null) {
3745
4123
  memberType.attributes = typeAttrs;
4124
+ }
3746
4125
  if (!this._check(TokenTypes.tokens.brace_right))
3747
4126
  this._consume(TokenTypes.tokens.comma, "Expected ',' for struct member.");
3748
4127
  else
@@ -3750,32 +4129,37 @@ void main() {
3750
4129
  members.push(new Member(memberName, memberType, memberAttrs));
3751
4130
  }
3752
4131
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' after struct body.");
3753
- const structNode = new Struct(name, members);
4132
+ const endLine = this._currentLine;
4133
+ const structNode = new Struct(name, members, startLine, endLine);
3754
4134
  this._context.structs.set(name, structNode);
3755
4135
  return structNode;
3756
4136
  }
3757
4137
  _global_variable_decl() {
3758
4138
  const _var = this._variable_decl();
3759
- if (_var && this._match(TokenTypes.tokens.equal))
4139
+ if (_var && this._match(TokenTypes.tokens.equal)) {
3760
4140
  _var.value = this._const_expression();
4141
+ }
3761
4142
  return _var;
3762
4143
  }
3763
4144
  _override_variable_decl() {
3764
4145
  const _override = this._override_decl();
3765
- if (_override && this._match(TokenTypes.tokens.equal))
4146
+ if (_override && this._match(TokenTypes.tokens.equal)) {
3766
4147
  _override.value = this._const_expression();
4148
+ }
3767
4149
  return _override;
3768
4150
  }
3769
4151
  _global_const_decl() {
3770
- if (!this._match(TokenTypes.keywords.const))
4152
+ if (!this._match(TokenTypes.keywords.const)) {
3771
4153
  return null;
4154
+ }
3772
4155
  const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
3773
4156
  let type = null;
3774
4157
  if (this._match(TokenTypes.tokens.colon)) {
3775
4158
  const attrs = this._attribute();
3776
4159
  type = this._type_decl();
3777
- if (type != null)
4160
+ if (type != null) {
3778
4161
  type.attributes = attrs;
4162
+ }
3779
4163
  }
3780
4164
  let value = null;
3781
4165
  if (this._match(TokenTypes.tokens.equal)) {
@@ -3798,15 +4182,17 @@ void main() {
3798
4182
  return c;
3799
4183
  }
3800
4184
  _global_let_decl() {
3801
- if (!this._match(TokenTypes.keywords.let))
4185
+ if (!this._match(TokenTypes.keywords.let)) {
3802
4186
  return null;
4187
+ }
3803
4188
  const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
3804
4189
  let type = null;
3805
4190
  if (this._match(TokenTypes.tokens.colon)) {
3806
4191
  const attrs = this._attribute();
3807
4192
  type = this._type_decl();
3808
- if (type != null)
4193
+ if (type != null) {
3809
4194
  type.attributes = attrs;
4195
+ }
3810
4196
  }
3811
4197
  let value = null;
3812
4198
  if (this._match(TokenTypes.tokens.equal)) {
@@ -3815,23 +4201,26 @@ void main() {
3815
4201
  return new Let(name.toString(), type, "", "", value);
3816
4202
  }
3817
4203
  _const_expression() {
3818
- if (this._match(TokenTypes.const_literal))
4204
+ if (this._match(TokenTypes.const_literal)) {
3819
4205
  return new StringExpr(this._previous().toString());
4206
+ }
3820
4207
  const type = this._type_decl();
3821
4208
  this._consume(TokenTypes.tokens.paren_left, "Expected '('.");
3822
4209
  let args = [];
3823
4210
  while (!this._check(TokenTypes.tokens.paren_right)) {
3824
4211
  args.push(this._const_expression());
3825
- if (!this._check(TokenTypes.tokens.comma))
4212
+ if (!this._check(TokenTypes.tokens.comma)) {
3826
4213
  break;
4214
+ }
3827
4215
  this._advance();
3828
4216
  }
3829
4217
  this._consume(TokenTypes.tokens.paren_right, "Expected ')'.");
3830
4218
  return new CreateExpr(type, args);
3831
4219
  }
3832
4220
  _variable_decl() {
3833
- if (!this._match(TokenTypes.keywords.var))
4221
+ if (!this._match(TokenTypes.keywords.var)) {
3834
4222
  return null;
4223
+ }
3835
4224
  let storage = "";
3836
4225
  let access = "";
3837
4226
  if (this._match(TokenTypes.tokens.less_than)) {
@@ -3845,28 +4234,47 @@ void main() {
3845
4234
  if (this._match(TokenTypes.tokens.colon)) {
3846
4235
  const attrs = this._attribute();
3847
4236
  type = this._type_decl();
3848
- if (type != null)
4237
+ if (type != null) {
3849
4238
  type.attributes = attrs;
4239
+ }
3850
4240
  }
3851
4241
  return new Var(name.toString(), type, storage, access, null);
3852
4242
  }
3853
4243
  _override_decl() {
3854
- if (!this._match(TokenTypes.keywords.override))
4244
+ if (!this._match(TokenTypes.keywords.override)) {
3855
4245
  return null;
4246
+ }
3856
4247
  const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
3857
4248
  let type = null;
3858
4249
  if (this._match(TokenTypes.tokens.colon)) {
3859
4250
  const attrs = this._attribute();
3860
4251
  type = this._type_decl();
3861
- if (type != null)
4252
+ if (type != null) {
3862
4253
  type.attributes = attrs;
4254
+ }
3863
4255
  }
3864
4256
  return new Override(name.toString(), type, null);
3865
4257
  }
4258
+ _diagnostic() {
4259
+ this._consume(TokenTypes.tokens.paren_left, "Expected '('");
4260
+ const severity = this._consume(TokenTypes.tokens.ident, "Expected severity control name.");
4261
+ this._consume(TokenTypes.tokens.comma, "Expected ','");
4262
+ const rule = this._consume(TokenTypes.tokens.ident, "Expected diagnostic rule name.");
4263
+ this._consume(TokenTypes.tokens.paren_right, "Expected ')'");
4264
+ return new Diagnostic(severity.toString(), rule.toString());
4265
+ }
3866
4266
  _enable_directive() {
3867
4267
  const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
3868
4268
  return new Enable(name.toString());
3869
4269
  }
4270
+ _requires_directive() {
4271
+ const extensions = [this._consume(TokenTypes.tokens.ident, "identity expected.").toString()];
4272
+ while (this._match(TokenTypes.tokens.comma)) {
4273
+ const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
4274
+ extensions.push(name.toString());
4275
+ }
4276
+ return new Requires(extensions);
4277
+ }
3870
4278
  _type_alias() {
3871
4279
  const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
3872
4280
  this._consume(TokenTypes.tokens.equal, "Expected '=' for type alias.");
@@ -3901,8 +4309,9 @@ void main() {
3901
4309
  return new Type(type2.toString());
3902
4310
  }
3903
4311
  let type = this._texture_sampler_types();
3904
- if (type)
4312
+ if (type) {
3905
4313
  return type;
4314
+ }
3906
4315
  if (this._check(TokenTypes.template_types)) {
3907
4316
  let type2 = this._advance().toString();
3908
4317
  let format = null;
@@ -3910,8 +4319,9 @@ void main() {
3910
4319
  if (this._match(TokenTypes.tokens.less_than)) {
3911
4320
  format = this._type_decl();
3912
4321
  access = null;
3913
- if (this._match(TokenTypes.tokens.comma))
4322
+ if (this._match(TokenTypes.tokens.comma)) {
3914
4323
  access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString();
4324
+ }
3915
4325
  this._consume(TokenTypes.tokens.greater_than, "Expected '>' for type.");
3916
4326
  }
3917
4327
  return new TemplateType(type2, format, access);
@@ -3923,8 +4333,9 @@ void main() {
3923
4333
  this._consume(TokenTypes.tokens.comma, "Expected ',' for pointer.");
3924
4334
  const decl = this._type_decl();
3925
4335
  let access = null;
3926
- if (this._match(TokenTypes.tokens.comma))
4336
+ if (this._match(TokenTypes.tokens.comma)) {
3927
4337
  access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString();
4338
+ }
3928
4339
  this._consume(TokenTypes.tokens.greater_than, "Expected '>' for pointer.");
3929
4340
  return new PointerType(pointer, storage.toString(), decl, access);
3930
4341
  }
@@ -3933,6 +4344,7 @@ void main() {
3933
4344
  let format = null;
3934
4345
  let countInt = -1;
3935
4346
  const array = this._previous();
4347
+ let countNode = null;
3936
4348
  if (this._match(TokenTypes.tokens.less_than)) {
3937
4349
  format = this._type_decl();
3938
4350
  if (this._context.aliases.has(format.name)) {
@@ -3940,21 +4352,32 @@ void main() {
3940
4352
  }
3941
4353
  let count = "";
3942
4354
  if (this._match(TokenTypes.tokens.comma)) {
3943
- let c = this._shift_expression();
3944
- count = c.evaluate(this._context).toString();
4355
+ countNode = this._shift_expression();
4356
+ try {
4357
+ count = countNode.evaluate(this._context).toString();
4358
+ countNode = null;
4359
+ } catch (e) {
4360
+ count = "1";
4361
+ }
3945
4362
  }
3946
4363
  this._consume(TokenTypes.tokens.greater_than, "Expected '>' for array.");
3947
4364
  countInt = count ? parseInt(count) : 0;
3948
4365
  }
3949
- return new ArrayType(array.toString(), attrs, format, countInt);
4366
+ const arrayType = new ArrayType(array.toString(), attrs, format, countInt);
4367
+ if (countNode) {
4368
+ this._deferArrayCountEval.push({ arrayType, countNode });
4369
+ }
4370
+ return arrayType;
3950
4371
  }
3951
4372
  return null;
3952
4373
  }
3953
4374
  _texture_sampler_types() {
3954
- if (this._match(TokenTypes.sampler_type))
4375
+ if (this._match(TokenTypes.sampler_type)) {
3955
4376
  return new SamplerType(this._previous().toString(), null, null);
3956
- if (this._match(TokenTypes.depth_texture_type))
4377
+ }
4378
+ if (this._match(TokenTypes.depth_texture_type)) {
3957
4379
  return new SamplerType(this._previous().toString(), null, null);
4380
+ }
3958
4381
  if (this._match(TokenTypes.sampled_texture_type) || this._match(TokenTypes.multisampled_texture_type)) {
3959
4382
  const sampler = this._previous();
3960
4383
  this._consume(TokenTypes.tokens.less_than, "Expected '<' for sampler type.");
@@ -3994,31 +4417,9 @@ void main() {
3994
4417
  }
3995
4418
  attributes.push(attr);
3996
4419
  }
3997
- while (this._match(TokenTypes.tokens.attr_left)) {
3998
- if (!this._check(TokenTypes.tokens.attr_right)) {
3999
- do {
4000
- const name = this._consume(TokenTypes.attribute_name, "Expected attribute name");
4001
- const attr = new Attribute(name.toString(), null);
4002
- if (this._match(TokenTypes.tokens.paren_left)) {
4003
- attr.value = [
4004
- this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString()
4005
- ];
4006
- if (this._check(TokenTypes.tokens.comma)) {
4007
- this._advance();
4008
- do {
4009
- const v = this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString();
4010
- attr.value.push(v);
4011
- } while (this._match(TokenTypes.tokens.comma));
4012
- }
4013
- this._consume(TokenTypes.tokens.paren_right, "Expected ')'");
4014
- }
4015
- attributes.push(attr);
4016
- } while (this._match(TokenTypes.tokens.comma));
4017
- }
4018
- this._consume(TokenTypes.tokens.attr_right, "Expected ']]' after attribute declarations");
4019
- }
4020
- if (attributes.length == 0)
4420
+ if (attributes.length == 0) {
4021
4421
  return null;
4422
+ }
4022
4423
  return attributes;
4023
4424
  }
4024
4425
  };
@@ -4076,6 +4477,9 @@ void main() {
4076
4477
  super(name, attributes);
4077
4478
  this.members = [];
4078
4479
  this.align = 0;
4480
+ this.startLine = -1;
4481
+ this.endLine = -1;
4482
+ this.inUse = false;
4079
4483
  }
4080
4484
  get isStruct() {
4081
4485
  return true;
@@ -4181,6 +4585,11 @@ void main() {
4181
4585
  this.stage = null;
4182
4586
  this.inputs = [];
4183
4587
  this.outputs = [];
4588
+ this.resources = [];
4589
+ this.startLine = -1;
4590
+ this.endLine = -1;
4591
+ this.inUse = false;
4592
+ this.calls = /* @__PURE__ */ new Set();
4184
4593
  this.name = name;
4185
4594
  this.stage = stage;
4186
4595
  }
@@ -4200,6 +4609,14 @@ void main() {
4200
4609
  this.id = id;
4201
4610
  }
4202
4611
  };
4612
+ var _FunctionResources = class {
4613
+ constructor(node) {
4614
+ this.resources = null;
4615
+ this.inUse = false;
4616
+ this.info = null;
4617
+ this.node = node;
4618
+ }
4619
+ };
4203
4620
  var WgslReflect = class {
4204
4621
  constructor(code) {
4205
4622
  this.uniforms = [];
@@ -4210,7 +4627,9 @@ void main() {
4210
4627
  this.overrides = [];
4211
4628
  this.structs = [];
4212
4629
  this.entry = new EntryFunctions();
4630
+ this.functions = [];
4213
4631
  this._types = /* @__PURE__ */ new Map();
4632
+ this._functions = /* @__PURE__ */ new Map();
4214
4633
  if (code) {
4215
4634
  this.update(code);
4216
4635
  }
@@ -4221,14 +4640,20 @@ void main() {
4221
4640
  update(code) {
4222
4641
  const parser = new WgslParser();
4223
4642
  const ast = parser.parse(code);
4643
+ for (const node of ast) {
4644
+ if (node instanceof Function) {
4645
+ this._functions.set(node.name, new _FunctionResources(node));
4646
+ }
4647
+ }
4224
4648
  for (const node of ast) {
4225
4649
  if (node instanceof Struct) {
4226
4650
  const info = this._getTypeInfo(node, null);
4227
4651
  if (info instanceof StructInfo) {
4228
4652
  this.structs.push(info);
4229
4653
  }
4230
- continue;
4231
4654
  }
4655
+ }
4656
+ for (const node of ast) {
4232
4657
  if (node instanceof Alias) {
4233
4658
  this.aliases.push(this._getAliasInfo(node));
4234
4659
  continue;
@@ -4287,8 +4712,15 @@ void main() {
4287
4712
  const fragmentStage = this._getAttribute(node, "fragment");
4288
4713
  const computeStage = this._getAttribute(node, "compute");
4289
4714
  const stage = vertexStage || fragmentStage || computeStage;
4715
+ const fn = new FunctionInfo(node.name, stage === null || stage === void 0 ? void 0 : stage.name);
4716
+ fn.startLine = node.startLine;
4717
+ fn.endLine = node.endLine;
4718
+ this.functions.push(fn);
4719
+ this._functions.get(node.name).info = fn;
4290
4720
  if (stage) {
4291
- const fn = new FunctionInfo(node.name, stage.name);
4721
+ this._functions.get(node.name).inUse = true;
4722
+ fn.inUse = true;
4723
+ fn.resources = this._findResources(node, !!stage);
4292
4724
  fn.inputs = this._getInputs(node.args);
4293
4725
  fn.outputs = this._getOutputs(node.returnType);
4294
4726
  this.entry[stage.name].push(fn);
@@ -4296,16 +4728,180 @@ void main() {
4296
4728
  continue;
4297
4729
  }
4298
4730
  }
4731
+ for (const fn of this._functions.values()) {
4732
+ if (fn.info) {
4733
+ fn.info.inUse = fn.inUse;
4734
+ this._addCalls(fn.node, fn.info.calls);
4735
+ }
4736
+ }
4737
+ for (const u of this.uniforms) {
4738
+ this._markStructsInUse(u.type);
4739
+ }
4740
+ for (const s of this.storage) {
4741
+ this._markStructsInUse(s.type);
4742
+ }
4743
+ }
4744
+ _markStructsInUse(type) {
4745
+ if (type.isStruct) {
4746
+ type.inUse = true;
4747
+ for (const m of type.members) {
4748
+ this._markStructsInUse(m.type);
4749
+ }
4750
+ } else if (type.isArray) {
4751
+ this._markStructsInUse(type.format);
4752
+ } else if (type.isTemplate) {
4753
+ this._markStructsInUse(type.format);
4754
+ } else {
4755
+ const alias = this._getAlias(type.name);
4756
+ if (alias) {
4757
+ this._markStructsInUse(alias);
4758
+ }
4759
+ }
4760
+ }
4761
+ _addCalls(fn, calls) {
4762
+ var _a2;
4763
+ for (const call of fn.calls) {
4764
+ const info = (_a2 = this._functions.get(call.name)) === null || _a2 === void 0 ? void 0 : _a2.info;
4765
+ if (info) {
4766
+ calls.add(info);
4767
+ }
4768
+ }
4769
+ }
4770
+ /// Find a resource by its group and binding.
4771
+ findResource(group, binding) {
4772
+ for (const u of this.uniforms) {
4773
+ if (u.group == group && u.binding == binding) {
4774
+ return u;
4775
+ }
4776
+ }
4777
+ for (const s of this.storage) {
4778
+ if (s.group == group && s.binding == binding) {
4779
+ return s;
4780
+ }
4781
+ }
4782
+ for (const t of this.textures) {
4783
+ if (t.group == group && t.binding == binding) {
4784
+ return t;
4785
+ }
4786
+ }
4787
+ for (const s of this.samplers) {
4788
+ if (s.group == group && s.binding == binding) {
4789
+ return s;
4790
+ }
4791
+ }
4792
+ return null;
4793
+ }
4794
+ _findResource(name) {
4795
+ for (const u of this.uniforms) {
4796
+ if (u.name == name) {
4797
+ return u;
4798
+ }
4799
+ }
4800
+ for (const s of this.storage) {
4801
+ if (s.name == name) {
4802
+ return s;
4803
+ }
4804
+ }
4805
+ for (const t of this.textures) {
4806
+ if (t.name == name) {
4807
+ return t;
4808
+ }
4809
+ }
4810
+ for (const s of this.samplers) {
4811
+ if (s.name == name) {
4812
+ return s;
4813
+ }
4814
+ }
4815
+ return null;
4816
+ }
4817
+ _markStructsFromAST(type) {
4818
+ const info = this._getTypeInfo(type, null);
4819
+ this._markStructsInUse(info);
4820
+ }
4821
+ _findResources(fn, isEntry) {
4822
+ const resources = [];
4823
+ const self = this;
4824
+ const varStack = [];
4825
+ fn.search((node) => {
4826
+ if (node instanceof _BlockStart) {
4827
+ varStack.push({});
4828
+ } else if (node instanceof _BlockEnd) {
4829
+ varStack.pop();
4830
+ } else if (node instanceof Var) {
4831
+ const v = node;
4832
+ if (isEntry && v.type !== null) {
4833
+ this._markStructsFromAST(v.type);
4834
+ }
4835
+ if (varStack.length > 0) {
4836
+ varStack[varStack.length - 1][v.name] = v;
4837
+ }
4838
+ } else if (node instanceof CreateExpr) {
4839
+ const c = node;
4840
+ if (isEntry && c.type !== null) {
4841
+ this._markStructsFromAST(c.type);
4842
+ }
4843
+ } else if (node instanceof Let) {
4844
+ const v = node;
4845
+ if (isEntry && v.type !== null) {
4846
+ this._markStructsFromAST(v.type);
4847
+ }
4848
+ if (varStack.length > 0) {
4849
+ varStack[varStack.length - 1][v.name] = v;
4850
+ }
4851
+ } else if (node instanceof VariableExpr) {
4852
+ const v = node;
4853
+ if (varStack.length > 0) {
4854
+ const varInfo2 = varStack[varStack.length - 1][v.name];
4855
+ if (varInfo2) {
4856
+ return;
4857
+ }
4858
+ }
4859
+ const varInfo = self._findResource(v.name);
4860
+ if (varInfo) {
4861
+ resources.push(varInfo);
4862
+ }
4863
+ } else if (node instanceof CallExpr) {
4864
+ const c = node;
4865
+ const callFn = self._functions.get(c.name);
4866
+ if (callFn) {
4867
+ if (isEntry) {
4868
+ callFn.inUse = true;
4869
+ }
4870
+ fn.calls.add(callFn.node);
4871
+ if (callFn.resources === null) {
4872
+ callFn.resources = self._findResources(callFn.node, isEntry);
4873
+ }
4874
+ resources.push(...callFn.resources);
4875
+ }
4876
+ } else if (node instanceof Call) {
4877
+ const c = node;
4878
+ const callFn = self._functions.get(c.name);
4879
+ if (callFn) {
4880
+ if (isEntry) {
4881
+ callFn.inUse = true;
4882
+ }
4883
+ fn.calls.add(callFn.node);
4884
+ if (callFn.resources === null) {
4885
+ callFn.resources = self._findResources(callFn.node, isEntry);
4886
+ }
4887
+ resources.push(...callFn.resources);
4888
+ }
4889
+ }
4890
+ });
4891
+ return [...new Map(resources.map((r) => [r.name, r])).values()];
4299
4892
  }
4300
4893
  getBindGroups() {
4301
4894
  const groups = [];
4302
4895
  function _makeRoom(group, binding) {
4303
- if (group >= groups.length)
4896
+ if (group >= groups.length) {
4304
4897
  groups.length = group + 1;
4305
- if (groups[group] === void 0)
4898
+ }
4899
+ if (groups[group] === void 0) {
4306
4900
  groups[group] = [];
4307
- if (binding >= groups[group].length)
4901
+ }
4902
+ if (binding >= groups[group].length) {
4308
4903
  groups[group].length = binding + 1;
4904
+ }
4309
4905
  }
4310
4906
  for (const u of this.uniforms) {
4311
4907
  _makeRoom(u.group, u.binding);
@@ -4330,14 +4926,16 @@ void main() {
4330
4926
  return groups;
4331
4927
  }
4332
4928
  _getOutputs(type, outputs = void 0) {
4333
- if (outputs === void 0)
4929
+ if (outputs === void 0) {
4334
4930
  outputs = [];
4931
+ }
4335
4932
  if (type instanceof Struct) {
4336
4933
  this._getStructOutputs(type, outputs);
4337
4934
  } else {
4338
4935
  const output = this._getOutputInfo(type);
4339
- if (output !== null)
4936
+ if (output !== null) {
4340
4937
  outputs.push(output);
4938
+ }
4341
4939
  }
4342
4940
  return outputs;
4343
4941
  }
@@ -4367,15 +4965,17 @@ void main() {
4367
4965
  return null;
4368
4966
  }
4369
4967
  _getInputs(args, inputs = void 0) {
4370
- if (inputs === void 0)
4968
+ if (inputs === void 0) {
4371
4969
  inputs = [];
4970
+ }
4372
4971
  for (const arg of args) {
4373
4972
  if (arg.type instanceof Struct) {
4374
4973
  this._getStructInputs(arg.type, inputs);
4375
4974
  } else {
4376
4975
  const input = this._getInputInfo(arg);
4377
- if (input !== null)
4976
+ if (input !== null) {
4378
4977
  inputs.push(input);
4978
+ }
4379
4979
  }
4380
4980
  }
4381
4981
  return inputs;
@@ -4386,8 +4986,9 @@ void main() {
4386
4986
  this._getStructInputs(m.type, inputs);
4387
4987
  } else {
4388
4988
  const input = this._getInputInfo(m);
4389
- if (input !== null)
4989
+ if (input !== null) {
4390
4990
  inputs.push(input);
4991
+ }
4391
4992
  }
4392
4993
  }
4393
4994
  }
@@ -4420,8 +5021,9 @@ void main() {
4420
5021
  }
4421
5022
  _getAlias(name) {
4422
5023
  for (const a of this.aliases) {
4423
- if (a.name == name)
5024
+ if (a.name == name) {
4424
5025
  return a.type;
5026
+ }
4425
5027
  }
4426
5028
  return null;
4427
5029
  }
@@ -4445,6 +5047,8 @@ void main() {
4445
5047
  if (type instanceof Struct) {
4446
5048
  const s = type;
4447
5049
  const info2 = new StructInfo(s.name, attributes);
5050
+ info2.startLine = s.startLine;
5051
+ info2.endLine = s.endLine;
4448
5052
  for (const m of s.members) {
4449
5053
  const t = this._getTypeInfo(m.type, m.attributes);
4450
5054
  info2.members.push(new MemberInfo(m.name, t, m.attributes));
@@ -4497,8 +5101,9 @@ void main() {
4497
5101
  for (let mi = 0, ml = struct.members.length; mi < ml; ++mi) {
4498
5102
  const member = struct.members[mi];
4499
5103
  const sizeInfo = this._getTypeSize(member);
4500
- if (!sizeInfo)
5104
+ if (!sizeInfo) {
4501
5105
  continue;
5106
+ }
4502
5107
  (_a2 = this._getAlias(member.type.name)) !== null && _a2 !== void 0 ? _a2 : member.type;
4503
5108
  const align = sizeInfo.align;
4504
5109
  const size = sizeInfo.size;
@@ -4515,12 +5120,14 @@ void main() {
4515
5120
  }
4516
5121
  _getTypeSize(type) {
4517
5122
  var _a2;
4518
- if (type === null || type === void 0)
5123
+ if (type === null || type === void 0) {
4519
5124
  return null;
5125
+ }
4520
5126
  const explicitSize = this._getAttributeNum(type.attributes, "size", 0);
4521
5127
  const explicitAlign = this._getAttributeNum(type.attributes, "align", 0);
4522
- if (type instanceof MemberInfo)
5128
+ if (type instanceof MemberInfo) {
4523
5129
  type = type.type;
5130
+ }
4524
5131
  if (type instanceof TypeInfo) {
4525
5132
  const alias = this._getAlias(type.name);
4526
5133
  if (alias !== null) {
@@ -4553,8 +5160,9 @@ void main() {
4553
5160
  const N = arrayType.count;
4554
5161
  const stride = this._getAttributeNum((_a2 = type === null || type === void 0 ? void 0 : type.attributes) !== null && _a2 !== void 0 ? _a2 : null, "stride", this._roundUp(align, size));
4555
5162
  size = N * stride;
4556
- if (explicitSize)
5163
+ if (explicitSize) {
4557
5164
  size = explicitSize;
5165
+ }
4558
5166
  return new _TypeSize(Math.max(explicitAlign, align), Math.max(explicitSize, size));
4559
5167
  }
4560
5168
  if (type instanceof StructInfo) {
@@ -4591,18 +5199,21 @@ void main() {
4591
5199
  }
4592
5200
  _getAttribute(node, name) {
4593
5201
  const obj = node;
4594
- if (!obj || !obj["attributes"])
5202
+ if (!obj || !obj["attributes"]) {
4595
5203
  return null;
5204
+ }
4596
5205
  const attrs = obj["attributes"];
4597
5206
  for (let a of attrs) {
4598
- if (a.name == name)
5207
+ if (a.name == name) {
4599
5208
  return a;
5209
+ }
4600
5210
  }
4601
5211
  return null;
4602
5212
  }
4603
5213
  _getAttributeNum(attributes, name, defaultValue) {
4604
- if (attributes === null)
5214
+ if (attributes === null) {
4605
5215
  return defaultValue;
5216
+ }
4606
5217
  for (let a of attributes) {
4607
5218
  if (a.name == name) {
4608
5219
  let v = a !== null && a.value !== null ? a.value : defaultValue;
@@ -4662,10 +5273,10 @@ void main() {
4662
5273
  }
4663
5274
  for (const uniform of parsedWGSL.uniforms) {
4664
5275
  const members = [];
4665
- for (const member of uniform.type.members) {
5276
+ for (const attribute of uniform.type?.members || []) {
4666
5277
  members.push({
4667
- name: member.name,
4668
- type: getType(member.type)
5278
+ name: attribute.name,
5279
+ type: getType(attribute.type)
4669
5280
  });
4670
5281
  }
4671
5282
  shaderLayout.bindings.push({
@@ -4685,7 +5296,7 @@ void main() {
4685
5296
  const type = getType(wgslAttribute.type);
4686
5297
  shaderLayout.attributes.push({
4687
5298
  name: wgslAttribute.name,
4688
- location: wgslAttribute.location,
5299
+ location: Number(wgslAttribute.location),
4689
5300
  type
4690
5301
  });
4691
5302
  }
@@ -6890,7 +7501,7 @@ void main() {
6890
7501
  }
6891
7502
  const oldUniforms = this.moduleUniforms[moduleName];
6892
7503
  const oldBindings = this.moduleBindings[moduleName];
6893
- const uniformsAndBindings = module.getUniforms?.(moduleProps, this.moduleUniforms[moduleName]) || moduleProps;
7504
+ const uniformsAndBindings = module.getUniforms?.(moduleProps, oldUniforms) || moduleProps;
6894
7505
  const { uniforms, bindings } = (0, import_core6.splitUniformsAndBindings)(uniformsAndBindings);
6895
7506
  this.moduleUniforms[moduleName] = { ...oldUniforms, ...uniforms };
6896
7507
  this.moduleBindings[moduleName] = { ...oldBindings, ...bindings };