@luma.gl/shadertools 9.0.14 → 9.0.16

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
@@ -1247,7 +1247,7 @@ void main() {
1247
1247
  // src/lib/wgsl/get-shader-layout-wgsl.ts
1248
1248
  var import_core = __toESM(require_core(), 1);
1249
1249
 
1250
- // src/libs/wgsl-reflect/wgsl_reflect.module.js
1250
+ // ../../node_modules/wgsl_reflect/wgsl_reflect.module.js
1251
1251
  var ParseContext = class {
1252
1252
  constructor() {
1253
1253
  this.constants = /* @__PURE__ */ new Map();
@@ -1270,23 +1270,50 @@ void main() {
1270
1270
  evaluateString(context) {
1271
1271
  return this.evaluate(context).toString();
1272
1272
  }
1273
+ search(callback) {
1274
+ }
1275
+ searchBlock(block, callback) {
1276
+ if (block) {
1277
+ callback(_BlockStart.instance);
1278
+ for (const node of block) {
1279
+ if (node instanceof Array) {
1280
+ this.searchBlock(node, callback);
1281
+ } else {
1282
+ node.search(callback);
1283
+ }
1284
+ }
1285
+ callback(_BlockEnd.instance);
1286
+ }
1287
+ }
1273
1288
  };
1289
+ var _BlockStart = class extends Node {
1290
+ };
1291
+ _BlockStart.instance = new _BlockStart();
1292
+ var _BlockEnd = class extends Node {
1293
+ };
1294
+ _BlockEnd.instance = new _BlockEnd();
1274
1295
  var Statement = class extends Node {
1275
1296
  constructor() {
1276
1297
  super();
1277
1298
  }
1278
1299
  };
1279
1300
  var Function = class extends Statement {
1280
- constructor(name, args, returnType, body) {
1301
+ constructor(name, args, returnType, body, startLine, endLine) {
1281
1302
  super();
1303
+ this.calls = /* @__PURE__ */ new Set();
1282
1304
  this.name = name;
1283
1305
  this.args = args;
1284
1306
  this.returnType = returnType;
1285
1307
  this.body = body;
1308
+ this.startLine = startLine;
1309
+ this.endLine = endLine;
1286
1310
  }
1287
1311
  get astNodeType() {
1288
1312
  return "function";
1289
1313
  }
1314
+ search(callback) {
1315
+ this.searchBlock(this.body, callback);
1316
+ }
1290
1317
  };
1291
1318
  var StaticAssert = class extends Statement {
1292
1319
  constructor(expression) {
@@ -1296,6 +1323,9 @@ void main() {
1296
1323
  get astNodeType() {
1297
1324
  return "staticAssert";
1298
1325
  }
1326
+ search(callback) {
1327
+ this.expression.search(callback);
1328
+ }
1299
1329
  };
1300
1330
  var While = class extends Statement {
1301
1331
  constructor(condition, body) {
@@ -1306,6 +1336,10 @@ void main() {
1306
1336
  get astNodeType() {
1307
1337
  return "while";
1308
1338
  }
1339
+ search(callback) {
1340
+ this.condition.search(callback);
1341
+ this.searchBlock(this.body, callback);
1342
+ }
1309
1343
  };
1310
1344
  var Continuing = class extends Statement {
1311
1345
  constructor(body) {
@@ -1315,6 +1349,9 @@ void main() {
1315
1349
  get astNodeType() {
1316
1350
  return "continuing";
1317
1351
  }
1352
+ search(callback) {
1353
+ this.searchBlock(this.body, callback);
1354
+ }
1318
1355
  };
1319
1356
  var For = class extends Statement {
1320
1357
  constructor(init, condition, increment, body) {
@@ -1327,6 +1364,13 @@ void main() {
1327
1364
  get astNodeType() {
1328
1365
  return "for";
1329
1366
  }
1367
+ search(callback) {
1368
+ var _a2, _b, _c;
1369
+ (_a2 = this.init) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1370
+ (_b = this.condition) === null || _b === void 0 ? void 0 : _b.search(callback);
1371
+ (_c = this.increment) === null || _c === void 0 ? void 0 : _c.search(callback);
1372
+ this.searchBlock(this.body, callback);
1373
+ }
1330
1374
  };
1331
1375
  var Var = class extends Statement {
1332
1376
  constructor(name, type, storage, access, value) {
@@ -1340,6 +1384,11 @@ void main() {
1340
1384
  get astNodeType() {
1341
1385
  return "var";
1342
1386
  }
1387
+ search(callback) {
1388
+ var _a2;
1389
+ callback(this);
1390
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1391
+ }
1343
1392
  };
1344
1393
  var Override = class extends Statement {
1345
1394
  constructor(name, type, value) {
@@ -1351,6 +1400,10 @@ void main() {
1351
1400
  get astNodeType() {
1352
1401
  return "override";
1353
1402
  }
1403
+ search(callback) {
1404
+ var _a2;
1405
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1406
+ }
1354
1407
  };
1355
1408
  var Let = class extends Statement {
1356
1409
  constructor(name, type, storage, access, value) {
@@ -1364,6 +1417,11 @@ void main() {
1364
1417
  get astNodeType() {
1365
1418
  return "let";
1366
1419
  }
1420
+ search(callback) {
1421
+ var _a2;
1422
+ callback(this);
1423
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1424
+ }
1367
1425
  };
1368
1426
  var Const = class extends Statement {
1369
1427
  constructor(name, type, storage, access, value) {
@@ -1380,6 +1438,11 @@ void main() {
1380
1438
  evaluate(context) {
1381
1439
  return this.value.evaluate(context);
1382
1440
  }
1441
+ search(callback) {
1442
+ var _a2;
1443
+ callback(this);
1444
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1445
+ }
1383
1446
  };
1384
1447
  var IncrementOperator;
1385
1448
  (function(IncrementOperator2) {
@@ -1404,6 +1467,9 @@ void main() {
1404
1467
  get astNodeType() {
1405
1468
  return "increment";
1406
1469
  }
1470
+ search(callback) {
1471
+ this.variable.search(callback);
1472
+ }
1407
1473
  };
1408
1474
  var AssignOperator;
1409
1475
  (function(AssignOperator2) {
@@ -1422,9 +1488,10 @@ void main() {
1422
1488
  (function(AssignOperator2) {
1423
1489
  function parse(val) {
1424
1490
  const key = val;
1425
- if (key == "parse")
1491
+ if (key == "parse") {
1426
1492
  throw new Error("Invalid value for AssignOperator");
1427
- return AssignOperator2[key];
1493
+ }
1494
+ return key;
1428
1495
  }
1429
1496
  AssignOperator2.parse = parse;
1430
1497
  })(AssignOperator || (AssignOperator = {}));
@@ -1438,6 +1505,10 @@ void main() {
1438
1505
  get astNodeType() {
1439
1506
  return "assign";
1440
1507
  }
1508
+ search(callback) {
1509
+ this.variable.search(callback);
1510
+ this.value.search(callback);
1511
+ }
1441
1512
  };
1442
1513
  var Call = class extends Statement {
1443
1514
  constructor(name, args) {
@@ -1448,6 +1519,12 @@ void main() {
1448
1519
  get astNodeType() {
1449
1520
  return "call";
1450
1521
  }
1522
+ search(callback) {
1523
+ for (const node of this.args) {
1524
+ node.search(callback);
1525
+ }
1526
+ callback(this);
1527
+ }
1451
1528
  };
1452
1529
  var Loop = class extends Statement {
1453
1530
  constructor(body, continuing) {
@@ -1480,6 +1557,12 @@ void main() {
1480
1557
  get astNodeType() {
1481
1558
  return "if";
1482
1559
  }
1560
+ search(callback) {
1561
+ this.condition.search(callback);
1562
+ this.searchBlock(this.body, callback);
1563
+ this.searchBlock(this.elseif, callback);
1564
+ this.searchBlock(this.else, callback);
1565
+ }
1483
1566
  };
1484
1567
  var Return = class extends Statement {
1485
1568
  constructor(value) {
@@ -1489,6 +1572,10 @@ void main() {
1489
1572
  get astNodeType() {
1490
1573
  return "return";
1491
1574
  }
1575
+ search(callback) {
1576
+ var _a2;
1577
+ (_a2 = this.value) === null || _a2 === void 0 ? void 0 : _a2.search(callback);
1578
+ }
1492
1579
  };
1493
1580
  var Enable = class extends Statement {
1494
1581
  constructor(name) {
@@ -1499,6 +1586,25 @@ void main() {
1499
1586
  return "enable";
1500
1587
  }
1501
1588
  };
1589
+ var Requires = class extends Statement {
1590
+ constructor(extensions) {
1591
+ super();
1592
+ this.extensions = extensions;
1593
+ }
1594
+ get astNodeType() {
1595
+ return "requires";
1596
+ }
1597
+ };
1598
+ var Diagnostic = class extends Statement {
1599
+ constructor(severity, rule) {
1600
+ super();
1601
+ this.severity = severity;
1602
+ this.rule = rule;
1603
+ }
1604
+ get astNodeType() {
1605
+ return "diagnostic";
1606
+ }
1607
+ };
1502
1608
  var Alias = class extends Statement {
1503
1609
  constructor(name, type) {
1504
1610
  super();
@@ -1549,9 +1655,11 @@ void main() {
1549
1655
  }
1550
1656
  };
1551
1657
  var Struct = class extends Type {
1552
- constructor(name, members) {
1658
+ constructor(name, members, startLine, endLine) {
1553
1659
  super(name);
1554
1660
  this.members = members;
1661
+ this.startLine = startLine;
1662
+ this.endLine = endLine;
1555
1663
  }
1556
1664
  get astNodeType() {
1557
1665
  return "struct";
@@ -1642,6 +1750,12 @@ void main() {
1642
1750
  get astNodeType() {
1643
1751
  return "createExpr";
1644
1752
  }
1753
+ search(callback) {
1754
+ callback(this);
1755
+ for (const node of this.args) {
1756
+ node.search(callback);
1757
+ }
1758
+ }
1645
1759
  };
1646
1760
  var CallExpr = class extends Expression {
1647
1761
  constructor(name, args) {
@@ -1735,6 +1849,12 @@ void main() {
1735
1849
  throw new Error("Non const function: " + this.name);
1736
1850
  }
1737
1851
  }
1852
+ search(callback) {
1853
+ for (const node of this.args) {
1854
+ node.search(callback);
1855
+ }
1856
+ callback(this);
1857
+ }
1738
1858
  };
1739
1859
  var VariableExpr = class extends Expression {
1740
1860
  constructor(name) {
@@ -1744,6 +1864,19 @@ void main() {
1744
1864
  get astNodeType() {
1745
1865
  return "varExpr";
1746
1866
  }
1867
+ search(callback) {
1868
+ callback(this);
1869
+ if (this.postfix) {
1870
+ this.postfix.search(callback);
1871
+ }
1872
+ }
1873
+ evaluate(context) {
1874
+ const constant = context.constants.get(this.name);
1875
+ if (!constant) {
1876
+ throw new Error("Cannot evaluate node");
1877
+ }
1878
+ return constant.evaluate(context);
1879
+ }
1747
1880
  };
1748
1881
  var ConstExpr = class extends Expression {
1749
1882
  constructor(name, initializer) {
@@ -1769,6 +1902,9 @@ void main() {
1769
1902
  }
1770
1903
  return this.initializer.evaluate(context);
1771
1904
  }
1905
+ search(callback) {
1906
+ this.initializer.search(callback);
1907
+ }
1772
1908
  };
1773
1909
  var LiteralExpr = class extends Expression {
1774
1910
  constructor(value) {
@@ -1791,6 +1927,9 @@ void main() {
1791
1927
  get astNodeType() {
1792
1928
  return "bitcastExpr";
1793
1929
  }
1930
+ search(callback) {
1931
+ this.value.search(callback);
1932
+ }
1794
1933
  };
1795
1934
  var TypecastExpr = class extends Expression {
1796
1935
  constructor(type, args) {
@@ -1804,6 +1943,9 @@ void main() {
1804
1943
  evaluate(context) {
1805
1944
  return this.args[0].evaluate(context);
1806
1945
  }
1946
+ search(callback) {
1947
+ this.searchBlock(this.args, callback);
1948
+ }
1807
1949
  };
1808
1950
  var GroupingExpr = class extends Expression {
1809
1951
  constructor(contents) {
@@ -1816,6 +1958,18 @@ void main() {
1816
1958
  evaluate(context) {
1817
1959
  return this.contents[0].evaluate(context);
1818
1960
  }
1961
+ search(callback) {
1962
+ this.searchBlock(this.contents, callback);
1963
+ }
1964
+ };
1965
+ var ArrayIndex = class extends Expression {
1966
+ constructor(index2) {
1967
+ super();
1968
+ this.index = index2;
1969
+ }
1970
+ search(callback) {
1971
+ this.index.search(callback);
1972
+ }
1819
1973
  };
1820
1974
  var Operator = class extends Expression {
1821
1975
  constructor() {
@@ -1845,6 +1999,9 @@ void main() {
1845
1999
  throw new Error("Unknown unary operator: " + this.operator);
1846
2000
  }
1847
2001
  }
2002
+ search(callback) {
2003
+ this.right.search(callback);
2004
+ }
1848
2005
  };
1849
2006
  var BinaryOperator = class extends Operator {
1850
2007
  constructor(operator, left, right) {
@@ -1888,6 +2045,10 @@ void main() {
1888
2045
  throw new Error(`Unknown operator ${this.operator}`);
1889
2046
  }
1890
2047
  }
2048
+ search(callback) {
2049
+ this.left.search(callback);
2050
+ this.right.search(callback);
2051
+ }
1891
2052
  };
1892
2053
  var SwitchCase = class extends Node {
1893
2054
  constructor() {
@@ -1903,6 +2064,9 @@ void main() {
1903
2064
  get astNodeType() {
1904
2065
  return "case";
1905
2066
  }
2067
+ search(callback) {
2068
+ this.searchBlock(this.body, callback);
2069
+ }
1906
2070
  };
1907
2071
  var Default = class extends SwitchCase {
1908
2072
  constructor(body) {
@@ -1912,6 +2076,9 @@ void main() {
1912
2076
  get astNodeType() {
1913
2077
  return "default";
1914
2078
  }
2079
+ search(callback) {
2080
+ this.searchBlock(this.body, callback);
2081
+ }
1915
2082
  };
1916
2083
  var Argument = class extends Node {
1917
2084
  constructor(name, type, attributes) {
@@ -1933,6 +2100,10 @@ void main() {
1933
2100
  get astNodeType() {
1934
2101
  return "elseif";
1935
2102
  }
2103
+ search(callback) {
2104
+ this.condition.search(callback);
2105
+ this.searchBlock(this.body, callback);
2106
+ }
1936
2107
  };
1937
2108
  var Member = class extends Node {
1938
2109
  constructor(name, type, attributes) {
@@ -2047,6 +2218,7 @@ void main() {
2047
2218
  continue: new TokenType("continue", TokenClass.keyword, "continue"),
2048
2219
  continuing: new TokenType("continuing", TokenClass.keyword, "continuing"),
2049
2220
  default: new TokenType("default", TokenClass.keyword, "default"),
2221
+ diagnostic: new TokenType("diagnostic", TokenClass.keyword, "diagnostic"),
2050
2222
  discard: new TokenType("discard", TokenClass.keyword, "discard"),
2051
2223
  else: new TokenType("else", TokenClass.keyword, "else"),
2052
2224
  enable: new TokenType("enable", TokenClass.keyword, "enable"),
@@ -2064,6 +2236,7 @@ void main() {
2064
2236
  read: new TokenType("read", TokenClass.keyword, "read"),
2065
2237
  read_write: new TokenType("read_write", TokenClass.keyword, "read_write"),
2066
2238
  return: new TokenType("return", TokenClass.keyword, "return"),
2239
+ requires: new TokenType("requires", TokenClass.keyword, "requires"),
2067
2240
  storage: new TokenType("storage", TokenClass.keyword, "storage"),
2068
2241
  switch: new TokenType("switch", TokenClass.keyword, "switch"),
2069
2242
  true: new TokenType("true", TokenClass.keyword, "true"),
@@ -2122,13 +2295,11 @@ void main() {
2122
2295
  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?))/),
2123
2296
  int_literal: new TokenType("int_literal", TokenClass.token, /-?0x[0-9a-fA-F]+|0i?|-?[1-9][0-9]*i?/),
2124
2297
  uint_literal: new TokenType("uint_literal", TokenClass.token, /0x[0-9a-fA-F]+u|0u|[1-9][0-9]*u/),
2125
- ident: new TokenType("ident", TokenClass.token, /[a-zA-Z][0-9a-zA-Z_]*/),
2298
+ ident: new TokenType("ident", TokenClass.token, /[_a-zA-Z][0-9a-zA-Z_]*/),
2126
2299
  and: new TokenType("and", TokenClass.token, "&"),
2127
2300
  and_and: new TokenType("and_and", TokenClass.token, "&&"),
2128
2301
  arrow: new TokenType("arrow ", TokenClass.token, "->"),
2129
2302
  attr: new TokenType("attr", TokenClass.token, "@"),
2130
- attr_left: new TokenType("attr_left", TokenClass.token, "[["),
2131
- attr_right: new TokenType("attr_right", TokenClass.token, "]]"),
2132
2303
  forward_slash: new TokenType("forward_slash", TokenClass.token, "/"),
2133
2304
  bang: new TokenType("bang", TokenClass.token, "!"),
2134
2305
  bracket_left: new TokenType("bracket_left", TokenClass.token, "["),
@@ -2172,6 +2343,63 @@ void main() {
2172
2343
  shift_right_equal: new TokenType("shift_right_equal", TokenClass.token, ">>="),
2173
2344
  shift_left_equal: new TokenType("shift_left_equal", TokenClass.token, "<<=")
2174
2345
  };
2346
+ TokenTypes.simpleTokens = {
2347
+ "@": _a.tokens.attr,
2348
+ "{": _a.tokens.brace_left,
2349
+ "}": _a.tokens.brace_right,
2350
+ ":": _a.tokens.colon,
2351
+ ",": _a.tokens.comma,
2352
+ "(": _a.tokens.paren_left,
2353
+ ")": _a.tokens.paren_right,
2354
+ ";": _a.tokens.semicolon
2355
+ };
2356
+ TokenTypes.literalTokens = {
2357
+ "&": _a.tokens.and,
2358
+ "&&": _a.tokens.and_and,
2359
+ "->": _a.tokens.arrow,
2360
+ "/": _a.tokens.forward_slash,
2361
+ "!": _a.tokens.bang,
2362
+ "[": _a.tokens.bracket_left,
2363
+ "]": _a.tokens.bracket_right,
2364
+ "=": _a.tokens.equal,
2365
+ "==": _a.tokens.equal_equal,
2366
+ "!=": _a.tokens.not_equal,
2367
+ ">": _a.tokens.greater_than,
2368
+ ">=": _a.tokens.greater_than_equal,
2369
+ ">>": _a.tokens.shift_right,
2370
+ "<": _a.tokens.less_than,
2371
+ "<=": _a.tokens.less_than_equal,
2372
+ "<<": _a.tokens.shift_left,
2373
+ "%": _a.tokens.modulo,
2374
+ "-": _a.tokens.minus,
2375
+ "--": _a.tokens.minus_minus,
2376
+ ".": _a.tokens.period,
2377
+ "+": _a.tokens.plus,
2378
+ "++": _a.tokens.plus_plus,
2379
+ "|": _a.tokens.or,
2380
+ "||": _a.tokens.or_or,
2381
+ "*": _a.tokens.star,
2382
+ "~": _a.tokens.tilde,
2383
+ "_": _a.tokens.underscore,
2384
+ "^": _a.tokens.xor,
2385
+ "+=": _a.tokens.plus_equal,
2386
+ "-=": _a.tokens.minus_equal,
2387
+ "*=": _a.tokens.times_equal,
2388
+ "/=": _a.tokens.division_equal,
2389
+ "%=": _a.tokens.modulo_equal,
2390
+ "&=": _a.tokens.and_equal,
2391
+ "|=": _a.tokens.or_equal,
2392
+ "^=": _a.tokens.xor_equal,
2393
+ ">>=": _a.tokens.shift_right_equal,
2394
+ "<<=": _a.tokens.shift_left_equal
2395
+ };
2396
+ TokenTypes.regexTokens = {
2397
+ decimal_float_literal: _a.tokens.decimal_float_literal,
2398
+ hex_float_literal: _a.tokens.hex_float_literal,
2399
+ int_literal: _a.tokens.int_literal,
2400
+ uint_literal: _a.tokens.uint_literal,
2401
+ ident: _a.tokens.ident
2402
+ };
2175
2403
  TokenTypes.storage_class = [
2176
2404
  _a.keywords.function,
2177
2405
  _a.keywords.private,
@@ -2294,7 +2522,7 @@ void main() {
2294
2522
  _a.keywords.bitcast,
2295
2523
  ..._a.any_texture_type
2296
2524
  ];
2297
- TokenTypes.attribute_name = [_a.tokens.ident, _a.keywords.block];
2525
+ TokenTypes.attribute_name = [_a.tokens.ident, _a.keywords.block, _a.keywords.diagnostic];
2298
2526
  TokenTypes.assignment_operators = [
2299
2527
  _a.tokens.equal,
2300
2528
  _a.tokens.plus_equal,
@@ -2343,8 +2571,9 @@ void main() {
2343
2571
  scanTokens() {
2344
2572
  while (!this._isAtEnd()) {
2345
2573
  this._start = this._current;
2346
- if (!this.scanToken())
2574
+ if (!this.scanToken()) {
2347
2575
  throw `Invalid syntax at line ${this._line}`;
2576
+ }
2348
2577
  }
2349
2578
  this._tokens.push(new Token(TokenTypes.eof, "", this._line));
2350
2579
  return this._tokens;
@@ -2362,8 +2591,9 @@ void main() {
2362
2591
  if (lexeme == "/") {
2363
2592
  if (this._peekAhead() == "/") {
2364
2593
  while (lexeme != "\n") {
2365
- if (this._isAtEnd())
2594
+ if (this._isAtEnd()) {
2366
2595
  return true;
2596
+ }
2367
2597
  lexeme = this._advance();
2368
2598
  }
2369
2599
  this._line++;
@@ -2372,8 +2602,9 @@ void main() {
2372
2602
  this._advance();
2373
2603
  let commentLevel = 1;
2374
2604
  while (commentLevel > 0) {
2375
- if (this._isAtEnd())
2605
+ if (this._isAtEnd()) {
2376
2606
  return true;
2607
+ }
2377
2608
  lexeme = this._advance();
2378
2609
  if (lexeme == "\n") {
2379
2610
  this._line++;
@@ -2395,7 +2626,32 @@ void main() {
2395
2626
  return true;
2396
2627
  }
2397
2628
  }
2629
+ const simpleToken = TokenTypes.simpleTokens[lexeme];
2630
+ if (simpleToken) {
2631
+ this._addToken(simpleToken);
2632
+ return true;
2633
+ }
2398
2634
  let matchType = TokenTypes.none;
2635
+ const isAlpha = this._isAlpha(lexeme);
2636
+ const isUnderscore = lexeme === "_";
2637
+ if (this._isAlphaNumeric(lexeme)) {
2638
+ let nextChar = this._peekAhead();
2639
+ while (this._isAlphaNumeric(nextChar)) {
2640
+ lexeme += this._advance();
2641
+ nextChar = this._peekAhead();
2642
+ }
2643
+ }
2644
+ if (isAlpha) {
2645
+ const matchedType = TokenTypes.keywords[lexeme];
2646
+ if (matchedType) {
2647
+ this._addToken(matchedType);
2648
+ return true;
2649
+ }
2650
+ }
2651
+ if (isAlpha || isUnderscore) {
2652
+ this._addToken(TokenTypes.tokens.ident);
2653
+ return true;
2654
+ }
2399
2655
  for (; ; ) {
2400
2656
  let matchedType = this._findType(lexeme);
2401
2657
  const nextLexeme = this._peekAhead();
@@ -2428,8 +2684,9 @@ void main() {
2428
2684
  }
2429
2685
  }
2430
2686
  if (matchedType === TokenTypes.none) {
2431
- if (matchType === TokenTypes.none)
2687
+ if (matchType === TokenTypes.none) {
2432
2688
  return false;
2689
+ }
2433
2690
  this._current--;
2434
2691
  this._addToken(matchType);
2435
2692
  return true;
@@ -2438,45 +2695,43 @@ void main() {
2438
2695
  this._current += lookAhead + 1;
2439
2696
  }
2440
2697
  matchType = matchedType;
2441
- if (this._isAtEnd())
2698
+ if (this._isAtEnd()) {
2442
2699
  break;
2700
+ }
2443
2701
  lexeme += this._advance();
2444
2702
  }
2445
- if (matchType === TokenTypes.none)
2703
+ if (matchType === TokenTypes.none) {
2446
2704
  return false;
2705
+ }
2447
2706
  this._addToken(matchType);
2448
2707
  return true;
2449
2708
  }
2450
2709
  _findType(lexeme) {
2451
- for (const name in TokenTypes.keywords) {
2452
- const type = TokenTypes.keywords[name];
2453
- if (this._match(lexeme, type.rule)) {
2454
- return type;
2710
+ for (const name in TokenTypes.regexTokens) {
2711
+ const type2 = TokenTypes.regexTokens[name];
2712
+ if (this._match(lexeme, type2.rule)) {
2713
+ return type2;
2455
2714
  }
2456
2715
  }
2457
- for (const name in TokenTypes.tokens) {
2458
- const type = TokenTypes.tokens[name];
2459
- if (this._match(lexeme, type.rule)) {
2460
- return type;
2461
- }
2716
+ const type = TokenTypes.literalTokens[lexeme];
2717
+ if (type) {
2718
+ return type;
2462
2719
  }
2463
2720
  return TokenTypes.none;
2464
2721
  }
2465
2722
  _match(lexeme, rule) {
2466
- if (typeof rule === "string") {
2467
- if (rule == lexeme) {
2468
- return true;
2469
- }
2470
- } else {
2471
- const match = rule.exec(lexeme);
2472
- if (match && match.index == 0 && match[0] == lexeme)
2473
- return true;
2474
- }
2475
- return false;
2723
+ const match = rule.exec(lexeme);
2724
+ return match && match.index == 0 && match[0] == lexeme;
2476
2725
  }
2477
2726
  _isAtEnd() {
2478
2727
  return this._current >= this._source.length;
2479
2728
  }
2729
+ _isAlpha(c) {
2730
+ return c >= "a" && c <= "z" || c >= "A" && c <= "Z";
2731
+ }
2732
+ _isAlphaNumeric(c) {
2733
+ return c >= "a" && c <= "z" || c >= "A" && c <= "Z" || c == "_" || c >= "0" && c <= "9";
2734
+ }
2480
2735
  _isWhitespace(c) {
2481
2736
  return c == " " || c == " " || c == "\r";
2482
2737
  }
@@ -2489,8 +2744,9 @@ void main() {
2489
2744
  }
2490
2745
  _peekAhead(offset = 0) {
2491
2746
  offset = offset || 0;
2492
- if (this._current + offset >= this._source.length)
2747
+ if (this._current + offset >= this._source.length) {
2493
2748
  return "\0";
2749
+ }
2494
2750
  return this._source[this._current + offset];
2495
2751
  }
2496
2752
  _addToken(type) {
@@ -2502,17 +2758,40 @@ void main() {
2502
2758
  constructor() {
2503
2759
  this._tokens = [];
2504
2760
  this._current = 0;
2761
+ this._currentLine = 0;
2505
2762
  this._context = new ParseContext();
2763
+ this._deferArrayCountEval = [];
2506
2764
  }
2507
2765
  parse(tokensOrCode) {
2508
2766
  this._initialize(tokensOrCode);
2509
- let statements = [];
2767
+ this._deferArrayCountEval.length = 0;
2768
+ const statements = [];
2510
2769
  while (!this._isAtEnd()) {
2511
2770
  const statement = this._global_decl_or_directive();
2512
- if (!statement)
2771
+ if (!statement) {
2513
2772
  break;
2773
+ }
2514
2774
  statements.push(statement);
2515
2775
  }
2776
+ if (this._deferArrayCountEval.length > 0) {
2777
+ for (const arrayDecl of this._deferArrayCountEval) {
2778
+ const arrayType = arrayDecl["arrayType"];
2779
+ const countNode = arrayDecl["countNode"];
2780
+ if (countNode instanceof VariableExpr) {
2781
+ const variable = countNode;
2782
+ const name = variable.name;
2783
+ const constant = this._context.constants.get(name);
2784
+ if (constant) {
2785
+ try {
2786
+ const count = constant.evaluate(this._context);
2787
+ arrayType.count = count;
2788
+ } catch (e) {
2789
+ }
2790
+ }
2791
+ }
2792
+ }
2793
+ this._deferArrayCountEval.length = 0;
2794
+ }
2516
2795
  return statements;
2517
2796
  }
2518
2797
  _initialize(tokensOrCode) {
@@ -2529,7 +2808,6 @@ void main() {
2529
2808
  this._current = 0;
2530
2809
  }
2531
2810
  _error(token, message) {
2532
- console.error(token, message);
2533
2811
  return {
2534
2812
  token,
2535
2813
  message,
@@ -2559,24 +2837,29 @@ void main() {
2559
2837
  return false;
2560
2838
  }
2561
2839
  _consume(types, message) {
2562
- if (this._check(types))
2840
+ if (this._check(types)) {
2563
2841
  return this._advance();
2842
+ }
2564
2843
  throw this._error(this._peek(), message);
2565
2844
  }
2566
2845
  _check(types) {
2567
- if (this._isAtEnd())
2846
+ if (this._isAtEnd()) {
2568
2847
  return false;
2848
+ }
2569
2849
  const tk = this._peek();
2570
2850
  if (types instanceof Array) {
2571
- let t = tk.type;
2572
- let index2 = types.indexOf(t);
2851
+ const t = tk.type;
2852
+ const index2 = types.indexOf(t);
2573
2853
  return index2 != -1;
2574
2854
  }
2575
2855
  return tk.type == types;
2576
2856
  }
2577
2857
  _advance() {
2578
- if (!this._isAtEnd())
2858
+ var _a2, _b;
2859
+ this._currentLine = (_b = (_a2 = this._peek()) === null || _a2 === void 0 ? void 0 : _a2.line) !== null && _b !== void 0 ? _b : -1;
2860
+ if (!this._isAtEnd()) {
2579
2861
  this._current++;
2862
+ }
2580
2863
  return this._previous();
2581
2864
  }
2582
2865
  _peek() {
@@ -2593,6 +2876,16 @@ void main() {
2593
2876
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
2594
2877
  return type;
2595
2878
  }
2879
+ if (this._match(TokenTypes.keywords.diagnostic)) {
2880
+ const directive = this._diagnostic();
2881
+ this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
2882
+ return directive;
2883
+ }
2884
+ if (this._match(TokenTypes.keywords.requires)) {
2885
+ const requires = this._requires_directive();
2886
+ this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
2887
+ return requires;
2888
+ }
2596
2889
  if (this._match(TokenTypes.keywords.enable)) {
2597
2890
  const enable = this._enable_directive();
2598
2891
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'");
@@ -2601,56 +2894,65 @@ void main() {
2601
2894
  const attrs = this._attribute();
2602
2895
  if (this._check(TokenTypes.keywords.var)) {
2603
2896
  const _var = this._global_variable_decl();
2604
- if (_var != null)
2897
+ if (_var != null) {
2605
2898
  _var.attributes = attrs;
2899
+ }
2606
2900
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
2607
2901
  return _var;
2608
2902
  }
2609
2903
  if (this._check(TokenTypes.keywords.override)) {
2610
2904
  const _override = this._override_variable_decl();
2611
- if (_override != null)
2905
+ if (_override != null) {
2612
2906
  _override.attributes = attrs;
2907
+ }
2613
2908
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
2614
2909
  return _override;
2615
2910
  }
2616
2911
  if (this._check(TokenTypes.keywords.let)) {
2617
2912
  const _let = this._global_let_decl();
2618
- if (_let != null)
2913
+ if (_let != null) {
2619
2914
  _let.attributes = attrs;
2915
+ }
2620
2916
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
2621
2917
  return _let;
2622
2918
  }
2623
2919
  if (this._check(TokenTypes.keywords.const)) {
2624
2920
  const _const = this._global_const_decl();
2625
- if (_const != null)
2921
+ if (_const != null) {
2626
2922
  _const.attributes = attrs;
2923
+ }
2627
2924
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
2628
2925
  return _const;
2629
2926
  }
2630
2927
  if (this._check(TokenTypes.keywords.struct)) {
2631
2928
  const _struct = this._struct_decl();
2632
- if (_struct != null)
2929
+ if (_struct != null) {
2633
2930
  _struct.attributes = attrs;
2931
+ }
2634
2932
  return _struct;
2635
2933
  }
2636
2934
  if (this._check(TokenTypes.keywords.fn)) {
2637
2935
  const _fn = this._function_decl();
2638
- if (_fn != null)
2936
+ if (_fn != null) {
2639
2937
  _fn.attributes = attrs;
2938
+ }
2640
2939
  return _fn;
2641
2940
  }
2642
2941
  return null;
2643
2942
  }
2644
2943
  _function_decl() {
2645
- if (!this._match(TokenTypes.keywords.fn))
2944
+ if (!this._match(TokenTypes.keywords.fn)) {
2646
2945
  return null;
2946
+ }
2947
+ const startLine = this._currentLine;
2647
2948
  const name = this._consume(TokenTypes.tokens.ident, "Expected function name.").toString();
2648
2949
  this._consume(TokenTypes.tokens.paren_left, "Expected '(' for function arguments.");
2649
2950
  const args = [];
2650
2951
  if (!this._check(TokenTypes.tokens.paren_right)) {
2651
2952
  do {
2652
- if (this._check(TokenTypes.tokens.paren_right))
2953
+ if (this._check(TokenTypes.tokens.paren_right)) {
2653
2954
  break;
2955
+ }
2654
2956
  const argAttrs = this._attribute();
2655
2957
  const name2 = this._consume(TokenTypes.tokens.ident, "Expected argument name.").toString();
2656
2958
  this._consume(TokenTypes.tokens.colon, "Expected ':' for argument type.");
@@ -2667,19 +2969,22 @@ void main() {
2667
2969
  if (this._match(TokenTypes.tokens.arrow)) {
2668
2970
  const attrs = this._attribute();
2669
2971
  _return = this._type_decl();
2670
- if (_return != null)
2972
+ if (_return != null) {
2671
2973
  _return.attributes = attrs;
2974
+ }
2672
2975
  }
2673
2976
  const body = this._compound_statement();
2674
- return new Function(name, args, _return, body);
2977
+ const endLine = this._currentLine;
2978
+ return new Function(name, args, _return, body, startLine, endLine);
2675
2979
  }
2676
2980
  _compound_statement() {
2677
2981
  const statements = [];
2678
2982
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for block.");
2679
2983
  while (!this._check(TokenTypes.tokens.brace_right)) {
2680
2984
  const statement = this._statement();
2681
- if (statement !== null)
2985
+ if (statement !== null) {
2682
2986
  statements.push(statement);
2987
+ }
2683
2988
  }
2684
2989
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' for block.");
2685
2990
  return statements;
@@ -2687,65 +2992,85 @@ void main() {
2687
2992
  _statement() {
2688
2993
  while (this._match(TokenTypes.tokens.semicolon) && !this._isAtEnd())
2689
2994
  ;
2690
- if (this._check(TokenTypes.keywords.if))
2995
+ if (this._check(TokenTypes.tokens.attr)) {
2996
+ this._attribute();
2997
+ }
2998
+ if (this._check(TokenTypes.keywords.if)) {
2691
2999
  return this._if_statement();
2692
- if (this._check(TokenTypes.keywords.switch))
3000
+ }
3001
+ if (this._check(TokenTypes.keywords.switch)) {
2693
3002
  return this._switch_statement();
2694
- if (this._check(TokenTypes.keywords.loop))
3003
+ }
3004
+ if (this._check(TokenTypes.keywords.loop)) {
2695
3005
  return this._loop_statement();
2696
- if (this._check(TokenTypes.keywords.for))
3006
+ }
3007
+ if (this._check(TokenTypes.keywords.for)) {
2697
3008
  return this._for_statement();
2698
- if (this._check(TokenTypes.keywords.while))
3009
+ }
3010
+ if (this._check(TokenTypes.keywords.while)) {
2699
3011
  return this._while_statement();
2700
- if (this._check(TokenTypes.keywords.continuing))
3012
+ }
3013
+ if (this._check(TokenTypes.keywords.continuing)) {
2701
3014
  return this._continuing_statement();
2702
- if (this._check(TokenTypes.keywords.static_assert))
3015
+ }
3016
+ if (this._check(TokenTypes.keywords.static_assert)) {
2703
3017
  return this._static_assert_statement();
2704
- if (this._check(TokenTypes.tokens.brace_left))
3018
+ }
3019
+ if (this._check(TokenTypes.tokens.brace_left)) {
2705
3020
  return this._compound_statement();
3021
+ }
2706
3022
  let result = null;
2707
- if (this._check(TokenTypes.keywords.return))
3023
+ if (this._check(TokenTypes.keywords.return)) {
2708
3024
  result = this._return_statement();
2709
- else if (this._check([
3025
+ } else if (this._check([
2710
3026
  TokenTypes.keywords.var,
2711
3027
  TokenTypes.keywords.let,
2712
3028
  TokenTypes.keywords.const
2713
- ]))
3029
+ ])) {
2714
3030
  result = this._variable_statement();
2715
- else if (this._match(TokenTypes.keywords.discard))
3031
+ } else if (this._match(TokenTypes.keywords.discard)) {
2716
3032
  result = new Discard();
2717
- else if (this._match(TokenTypes.keywords.break))
3033
+ } else if (this._match(TokenTypes.keywords.break)) {
2718
3034
  result = new Break();
2719
- else if (this._match(TokenTypes.keywords.continue))
3035
+ } else if (this._match(TokenTypes.keywords.continue)) {
2720
3036
  result = new Continue();
2721
- else
3037
+ } else {
2722
3038
  result = this._increment_decrement_statement() || this._func_call_statement() || this._assignment_statement();
2723
- if (result != null)
3039
+ }
3040
+ if (result != null) {
2724
3041
  this._consume(TokenTypes.tokens.semicolon, "Expected ';' after statement.");
3042
+ }
2725
3043
  return result;
2726
3044
  }
2727
3045
  _static_assert_statement() {
2728
- if (!this._match(TokenTypes.keywords.static_assert))
3046
+ if (!this._match(TokenTypes.keywords.static_assert)) {
2729
3047
  return null;
2730
- let expression = this._optional_paren_expression();
3048
+ }
3049
+ const expression = this._optional_paren_expression();
2731
3050
  return new StaticAssert(expression);
2732
3051
  }
2733
3052
  _while_statement() {
2734
- if (!this._match(TokenTypes.keywords.while))
3053
+ if (!this._match(TokenTypes.keywords.while)) {
2735
3054
  return null;
2736
- let condition = this._optional_paren_expression();
3055
+ }
3056
+ const condition = this._optional_paren_expression();
3057
+ if (this._check(TokenTypes.tokens.attr)) {
3058
+ this._attribute();
3059
+ }
2737
3060
  const block = this._compound_statement();
2738
3061
  return new While(condition, block);
2739
3062
  }
2740
3063
  _continuing_statement() {
2741
- if (!this._match(TokenTypes.keywords.continuing))
3064
+ if (!this._match(TokenTypes.keywords.continuing)) {
2742
3065
  return null;
3066
+ }
2743
3067
  const block = this._compound_statement();
2744
3068
  return new Continuing(block);
2745
3069
  }
2746
3070
  _for_statement() {
2747
- if (!this._match(TokenTypes.keywords.for))
3071
+ if (!this._match(TokenTypes.keywords.for)) {
2748
3072
  return null;
3073
+ }
2749
3074
  this._consume(TokenTypes.tokens.paren_left, "Expected '('.");
2750
3075
  const init = !this._check(TokenTypes.tokens.semicolon) ? this._for_init() : null;
2751
3076
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
@@ -2753,6 +3078,9 @@ void main() {
2753
3078
  this._consume(TokenTypes.tokens.semicolon, "Expected ';'.");
2754
3079
  const increment = !this._check(TokenTypes.tokens.paren_right) ? this._for_increment() : null;
2755
3080
  this._consume(TokenTypes.tokens.paren_right, "Expected ')'.");
3081
+ if (this._check(TokenTypes.tokens.attr)) {
3082
+ this._attribute();
3083
+ }
2756
3084
  const body = this._compound_statement();
2757
3085
  return new For(init, condition, increment, body);
2758
3086
  }
@@ -2765,11 +3093,13 @@ void main() {
2765
3093
  _variable_statement() {
2766
3094
  if (this._check(TokenTypes.keywords.var)) {
2767
3095
  const _var = this._variable_decl();
2768
- if (_var === null)
3096
+ if (_var === null) {
2769
3097
  throw this._error(this._peek(), "Variable declaration expected.");
3098
+ }
2770
3099
  let value = null;
2771
- if (this._match(TokenTypes.tokens.equal))
3100
+ if (this._match(TokenTypes.tokens.equal)) {
2772
3101
  value = this._short_circuit_or_expression();
3102
+ }
2773
3103
  return new Var(_var.name, _var.type, _var.storage, _var.access, value);
2774
3104
  }
2775
3105
  if (this._match(TokenTypes.keywords.let)) {
@@ -2778,8 +3108,9 @@ void main() {
2778
3108
  if (this._match(TokenTypes.tokens.colon)) {
2779
3109
  const typeAttrs = this._attribute();
2780
3110
  type = this._type_decl();
2781
- if (type != null)
3111
+ if (type != null) {
2782
3112
  type.attributes = typeAttrs;
3113
+ }
2783
3114
  }
2784
3115
  this._consume(TokenTypes.tokens.equal, "Expected '=' for let.");
2785
3116
  const value = this._short_circuit_or_expression();
@@ -2791,8 +3122,9 @@ void main() {
2791
3122
  if (this._match(TokenTypes.tokens.colon)) {
2792
3123
  const typeAttrs = this._attribute();
2793
3124
  type = this._type_decl();
2794
- if (type != null)
3125
+ if (type != null) {
2795
3126
  type.attributes = typeAttrs;
3127
+ }
2796
3128
  }
2797
3129
  this._consume(TokenTypes.tokens.equal, "Expected '=' for const.");
2798
3130
  const value = this._short_circuit_or_expression();
@@ -2803,8 +3135,9 @@ void main() {
2803
3135
  _increment_decrement_statement() {
2804
3136
  const savedPos = this._current;
2805
3137
  const _var = this._unary_expression();
2806
- if (_var == null)
3138
+ if (_var == null) {
2807
3139
  return null;
3140
+ }
2808
3141
  if (!this._check(TokenTypes.increment_operators)) {
2809
3142
  this._current = savedPos;
2810
3143
  return null;
@@ -2814,20 +3147,24 @@ void main() {
2814
3147
  }
2815
3148
  _assignment_statement() {
2816
3149
  let _var = null;
2817
- if (this._check(TokenTypes.tokens.brace_right))
3150
+ if (this._check(TokenTypes.tokens.brace_right)) {
2818
3151
  return null;
3152
+ }
2819
3153
  let isUnderscore = this._match(TokenTypes.tokens.underscore);
2820
- if (!isUnderscore)
3154
+ if (!isUnderscore) {
2821
3155
  _var = this._unary_expression();
2822
- if (!isUnderscore && _var == null)
3156
+ }
3157
+ if (!isUnderscore && _var == null) {
2823
3158
  return null;
3159
+ }
2824
3160
  const type = this._consume(TokenTypes.assignment_operators, "Expected assignment operator.");
2825
3161
  const value = this._short_circuit_or_expression();
2826
3162
  return new Assign(AssignOperator.parse(type.lexeme), _var, value);
2827
3163
  }
2828
3164
  _func_call_statement() {
2829
- if (!this._check(TokenTypes.tokens.ident))
3165
+ if (!this._check(TokenTypes.tokens.ident)) {
2830
3166
  return null;
3167
+ }
2831
3168
  const savedPos = this._current;
2832
3169
  const name = this._consume(TokenTypes.tokens.ident, "Expected function name.");
2833
3170
  const args = this._argument_expression_list();
@@ -2838,8 +3175,12 @@ void main() {
2838
3175
  return new Call(name.lexeme, args);
2839
3176
  }
2840
3177
  _loop_statement() {
2841
- if (!this._match(TokenTypes.keywords.loop))
3178
+ if (!this._match(TokenTypes.keywords.loop)) {
2842
3179
  return null;
3180
+ }
3181
+ if (this._check(TokenTypes.tokens.attr)) {
3182
+ this._attribute();
3183
+ }
2843
3184
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for loop.");
2844
3185
  const statements = [];
2845
3186
  let statement = this._statement();
@@ -2854,19 +3195,25 @@ void main() {
2854
3195
  statement = this._statement();
2855
3196
  }
2856
3197
  let continuing = null;
2857
- if (this._match(TokenTypes.keywords.continuing))
3198
+ if (this._match(TokenTypes.keywords.continuing)) {
2858
3199
  continuing = this._compound_statement();
3200
+ }
2859
3201
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' for loop.");
2860
3202
  return new Loop(statements, continuing);
2861
3203
  }
2862
3204
  _switch_statement() {
2863
- if (!this._match(TokenTypes.keywords.switch))
3205
+ if (!this._match(TokenTypes.keywords.switch)) {
2864
3206
  return null;
3207
+ }
2865
3208
  const condition = this._optional_paren_expression();
3209
+ if (this._check(TokenTypes.tokens.attr)) {
3210
+ this._attribute();
3211
+ }
2866
3212
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for switch.");
2867
3213
  const body = this._switch_body();
2868
- if (body == null || body.length == 0)
3214
+ if (body == null || body.length == 0) {
2869
3215
  throw this._error(this._previous(), "Expected 'case' or 'default'.");
3216
+ }
2870
3217
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' for switch.");
2871
3218
  return new Switch(condition, body);
2872
3219
  }
@@ -2875,6 +3222,9 @@ void main() {
2875
3222
  if (this._match(TokenTypes.keywords.case)) {
2876
3223
  const selector = this._case_selectors();
2877
3224
  this._match(TokenTypes.tokens.colon);
3225
+ if (this._check(TokenTypes.tokens.attr)) {
3226
+ this._attribute();
3227
+ }
2878
3228
  this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch case.");
2879
3229
  const body = this._case_body();
2880
3230
  this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch case.");
@@ -2882,6 +3232,9 @@ void main() {
2882
3232
  }
2883
3233
  if (this._match(TokenTypes.keywords.default)) {
2884
3234
  this._match(TokenTypes.tokens.colon);
3235
+ if (this._check(TokenTypes.tokens.attr)) {
3236
+ this._attribute();
3237
+ }
2885
3238
  this._consume(TokenTypes.tokens.brace_left, "Exected '{' for switch default.");
2886
3239
  const body = this._case_body();
2887
3240
  this._consume(TokenTypes.tokens.brace_right, "Exected '}' for switch default.");
@@ -2894,12 +3247,12 @@ void main() {
2894
3247
  return cases;
2895
3248
  }
2896
3249
  _case_selectors() {
2897
- var _a2, _b, _c, _d;
2898
3250
  const selectors = [
2899
- (_b = (_a2 = this._shift_expression()) === null || _a2 === void 0 ? void 0 : _a2.evaluate(this._context).toString()) !== null && _b !== void 0 ? _b : ""
3251
+ this._shift_expression()
3252
+ //?.evaluate(this._context).toString() ?? "",
2900
3253
  ];
2901
3254
  while (this._match(TokenTypes.tokens.comma)) {
2902
- selectors.push((_d = (_c = this._shift_expression()) === null || _c === void 0 ? void 0 : _c.evaluate(this._context).toString()) !== null && _d !== void 0 ? _d : "");
3255
+ selectors.push(this._shift_expression());
2903
3256
  }
2904
3257
  return selectors;
2905
3258
  }
@@ -2909,28 +3262,41 @@ void main() {
2909
3262
  return [];
2910
3263
  }
2911
3264
  let statement = this._statement();
2912
- if (statement == null)
3265
+ if (statement == null) {
2913
3266
  return [];
3267
+ }
2914
3268
  if (!(statement instanceof Array)) {
2915
3269
  statement = [statement];
2916
3270
  }
2917
3271
  const nextStatement = this._case_body();
2918
- if (nextStatement.length == 0)
3272
+ if (nextStatement.length == 0) {
2919
3273
  return statement;
3274
+ }
2920
3275
  return [...statement, nextStatement[0]];
2921
3276
  }
2922
3277
  _if_statement() {
2923
- if (!this._match(TokenTypes.keywords.if))
3278
+ if (!this._match(TokenTypes.keywords.if)) {
2924
3279
  return null;
3280
+ }
2925
3281
  const condition = this._optional_paren_expression();
3282
+ if (this._check(TokenTypes.tokens.attr)) {
3283
+ this._attribute();
3284
+ }
2926
3285
  const block = this._compound_statement();
2927
3286
  let elseif = [];
2928
3287
  if (this._match_elseif()) {
3288
+ if (this._check(TokenTypes.tokens.attr)) {
3289
+ this._attribute();
3290
+ }
2929
3291
  elseif = this._elseif_statement(elseif);
2930
3292
  }
2931
3293
  let _else = null;
2932
- if (this._match(TokenTypes.keywords.else))
3294
+ if (this._match(TokenTypes.keywords.else)) {
3295
+ if (this._check(TokenTypes.tokens.attr)) {
3296
+ this._attribute();
3297
+ }
2933
3298
  _else = this._compound_statement();
3299
+ }
2934
3300
  return new If(condition, block, elseif, _else);
2935
3301
  }
2936
3302
  _match_elseif() {
@@ -2946,13 +3312,17 @@ void main() {
2946
3312
  const block = this._compound_statement();
2947
3313
  elseif.push(new ElseIf(condition, block));
2948
3314
  if (this._match_elseif()) {
3315
+ if (this._check(TokenTypes.tokens.attr)) {
3316
+ this._attribute();
3317
+ }
2949
3318
  this._elseif_statement(elseif);
2950
3319
  }
2951
3320
  return elseif;
2952
3321
  }
2953
3322
  _return_statement() {
2954
- if (!this._match(TokenTypes.keywords.return))
3323
+ if (!this._match(TokenTypes.keywords.return)) {
2955
3324
  return null;
3325
+ }
2956
3326
  const value = this._short_circuit_or_expression();
2957
3327
  return new Return(value);
2958
3328
  }
@@ -3050,25 +3420,29 @@ void main() {
3050
3420
  _singular_expression() {
3051
3421
  const expr = this._primary_expression();
3052
3422
  const p = this._postfix_expression();
3053
- if (p)
3423
+ if (p) {
3054
3424
  expr.postfix = p;
3425
+ }
3055
3426
  return expr;
3056
3427
  }
3057
3428
  _postfix_expression() {
3058
3429
  if (this._match(TokenTypes.tokens.bracket_left)) {
3059
3430
  const expr = this._short_circuit_or_expression();
3060
3431
  this._consume(TokenTypes.tokens.bracket_right, "Expected ']'.");
3432
+ const arrayIndex = new ArrayIndex(expr);
3061
3433
  const p = this._postfix_expression();
3062
- if (p)
3063
- expr.postfix = p;
3064
- return expr;
3434
+ if (p) {
3435
+ arrayIndex.postfix = p;
3436
+ }
3437
+ return arrayIndex;
3065
3438
  }
3066
3439
  if (this._match(TokenTypes.tokens.period)) {
3067
3440
  const name = this._consume(TokenTypes.tokens.ident, "Expected member name.");
3068
3441
  const p = this._postfix_expression();
3069
3442
  const expr = new StringExpr(name.lexeme);
3070
- if (p)
3443
+ if (p) {
3071
3444
  expr.postfix = p;
3445
+ }
3072
3446
  return expr;
3073
3447
  }
3074
3448
  return null;
@@ -3119,12 +3493,14 @@ void main() {
3119
3493
  return new TypecastExpr(type, args);
3120
3494
  }
3121
3495
  _argument_expression_list() {
3122
- if (!this._match(TokenTypes.tokens.paren_left))
3496
+ if (!this._match(TokenTypes.tokens.paren_left)) {
3123
3497
  return null;
3498
+ }
3124
3499
  const args = [];
3125
3500
  do {
3126
- if (this._check(TokenTypes.tokens.paren_right))
3501
+ if (this._check(TokenTypes.tokens.paren_right)) {
3127
3502
  break;
3503
+ }
3128
3504
  const arg = this._short_circuit_or_expression();
3129
3505
  args.push(arg);
3130
3506
  } while (this._match(TokenTypes.tokens.comma));
@@ -3144,8 +3520,10 @@ void main() {
3144
3520
  return new GroupingExpr([expr]);
3145
3521
  }
3146
3522
  _struct_decl() {
3147
- if (!this._match(TokenTypes.keywords.struct))
3523
+ if (!this._match(TokenTypes.keywords.struct)) {
3148
3524
  return null;
3525
+ }
3526
+ const startLine = this._currentLine;
3149
3527
  const name = this._consume(TokenTypes.tokens.ident, "Expected name for struct.").toString();
3150
3528
  this._consume(TokenTypes.tokens.brace_left, "Expected '{' for struct body.");
3151
3529
  const members = [];
@@ -3155,8 +3533,9 @@ void main() {
3155
3533
  this._consume(TokenTypes.tokens.colon, "Expected ':' for struct member type.");
3156
3534
  const typeAttrs = this._attribute();
3157
3535
  const memberType = this._type_decl();
3158
- if (memberType != null)
3536
+ if (memberType != null) {
3159
3537
  memberType.attributes = typeAttrs;
3538
+ }
3160
3539
  if (!this._check(TokenTypes.tokens.brace_right))
3161
3540
  this._consume(TokenTypes.tokens.comma, "Expected ',' for struct member.");
3162
3541
  else
@@ -3164,32 +3543,37 @@ void main() {
3164
3543
  members.push(new Member(memberName, memberType, memberAttrs));
3165
3544
  }
3166
3545
  this._consume(TokenTypes.tokens.brace_right, "Expected '}' after struct body.");
3167
- const structNode = new Struct(name, members);
3546
+ const endLine = this._currentLine;
3547
+ const structNode = new Struct(name, members, startLine, endLine);
3168
3548
  this._context.structs.set(name, structNode);
3169
3549
  return structNode;
3170
3550
  }
3171
3551
  _global_variable_decl() {
3172
3552
  const _var = this._variable_decl();
3173
- if (_var && this._match(TokenTypes.tokens.equal))
3553
+ if (_var && this._match(TokenTypes.tokens.equal)) {
3174
3554
  _var.value = this._const_expression();
3555
+ }
3175
3556
  return _var;
3176
3557
  }
3177
3558
  _override_variable_decl() {
3178
3559
  const _override = this._override_decl();
3179
- if (_override && this._match(TokenTypes.tokens.equal))
3560
+ if (_override && this._match(TokenTypes.tokens.equal)) {
3180
3561
  _override.value = this._const_expression();
3562
+ }
3181
3563
  return _override;
3182
3564
  }
3183
3565
  _global_const_decl() {
3184
- if (!this._match(TokenTypes.keywords.const))
3566
+ if (!this._match(TokenTypes.keywords.const)) {
3185
3567
  return null;
3568
+ }
3186
3569
  const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
3187
3570
  let type = null;
3188
3571
  if (this._match(TokenTypes.tokens.colon)) {
3189
3572
  const attrs = this._attribute();
3190
3573
  type = this._type_decl();
3191
- if (type != null)
3574
+ if (type != null) {
3192
3575
  type.attributes = attrs;
3576
+ }
3193
3577
  }
3194
3578
  let value = null;
3195
3579
  if (this._match(TokenTypes.tokens.equal)) {
@@ -3212,15 +3596,17 @@ void main() {
3212
3596
  return c;
3213
3597
  }
3214
3598
  _global_let_decl() {
3215
- if (!this._match(TokenTypes.keywords.let))
3599
+ if (!this._match(TokenTypes.keywords.let)) {
3216
3600
  return null;
3601
+ }
3217
3602
  const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
3218
3603
  let type = null;
3219
3604
  if (this._match(TokenTypes.tokens.colon)) {
3220
3605
  const attrs = this._attribute();
3221
3606
  type = this._type_decl();
3222
- if (type != null)
3607
+ if (type != null) {
3223
3608
  type.attributes = attrs;
3609
+ }
3224
3610
  }
3225
3611
  let value = null;
3226
3612
  if (this._match(TokenTypes.tokens.equal)) {
@@ -3229,23 +3615,26 @@ void main() {
3229
3615
  return new Let(name.toString(), type, "", "", value);
3230
3616
  }
3231
3617
  _const_expression() {
3232
- if (this._match(TokenTypes.const_literal))
3618
+ if (this._match(TokenTypes.const_literal)) {
3233
3619
  return new StringExpr(this._previous().toString());
3620
+ }
3234
3621
  const type = this._type_decl();
3235
3622
  this._consume(TokenTypes.tokens.paren_left, "Expected '('.");
3236
3623
  let args = [];
3237
3624
  while (!this._check(TokenTypes.tokens.paren_right)) {
3238
3625
  args.push(this._const_expression());
3239
- if (!this._check(TokenTypes.tokens.comma))
3626
+ if (!this._check(TokenTypes.tokens.comma)) {
3240
3627
  break;
3628
+ }
3241
3629
  this._advance();
3242
3630
  }
3243
3631
  this._consume(TokenTypes.tokens.paren_right, "Expected ')'.");
3244
3632
  return new CreateExpr(type, args);
3245
3633
  }
3246
3634
  _variable_decl() {
3247
- if (!this._match(TokenTypes.keywords.var))
3635
+ if (!this._match(TokenTypes.keywords.var)) {
3248
3636
  return null;
3637
+ }
3249
3638
  let storage = "";
3250
3639
  let access = "";
3251
3640
  if (this._match(TokenTypes.tokens.less_than)) {
@@ -3259,28 +3648,47 @@ void main() {
3259
3648
  if (this._match(TokenTypes.tokens.colon)) {
3260
3649
  const attrs = this._attribute();
3261
3650
  type = this._type_decl();
3262
- if (type != null)
3651
+ if (type != null) {
3263
3652
  type.attributes = attrs;
3653
+ }
3264
3654
  }
3265
3655
  return new Var(name.toString(), type, storage, access, null);
3266
3656
  }
3267
3657
  _override_decl() {
3268
- if (!this._match(TokenTypes.keywords.override))
3658
+ if (!this._match(TokenTypes.keywords.override)) {
3269
3659
  return null;
3660
+ }
3270
3661
  const name = this._consume(TokenTypes.tokens.ident, "Expected variable name");
3271
3662
  let type = null;
3272
3663
  if (this._match(TokenTypes.tokens.colon)) {
3273
3664
  const attrs = this._attribute();
3274
3665
  type = this._type_decl();
3275
- if (type != null)
3666
+ if (type != null) {
3276
3667
  type.attributes = attrs;
3668
+ }
3277
3669
  }
3278
3670
  return new Override(name.toString(), type, null);
3279
3671
  }
3672
+ _diagnostic() {
3673
+ this._consume(TokenTypes.tokens.paren_left, "Expected '('");
3674
+ const severity = this._consume(TokenTypes.tokens.ident, "Expected severity control name.");
3675
+ this._consume(TokenTypes.tokens.comma, "Expected ','");
3676
+ const rule = this._consume(TokenTypes.tokens.ident, "Expected diagnostic rule name.");
3677
+ this._consume(TokenTypes.tokens.paren_right, "Expected ')'");
3678
+ return new Diagnostic(severity.toString(), rule.toString());
3679
+ }
3280
3680
  _enable_directive() {
3281
3681
  const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
3282
3682
  return new Enable(name.toString());
3283
3683
  }
3684
+ _requires_directive() {
3685
+ const extensions = [this._consume(TokenTypes.tokens.ident, "identity expected.").toString()];
3686
+ while (this._match(TokenTypes.tokens.comma)) {
3687
+ const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
3688
+ extensions.push(name.toString());
3689
+ }
3690
+ return new Requires(extensions);
3691
+ }
3284
3692
  _type_alias() {
3285
3693
  const name = this._consume(TokenTypes.tokens.ident, "identity expected.");
3286
3694
  this._consume(TokenTypes.tokens.equal, "Expected '=' for type alias.");
@@ -3315,8 +3723,9 @@ void main() {
3315
3723
  return new Type(type2.toString());
3316
3724
  }
3317
3725
  let type = this._texture_sampler_types();
3318
- if (type)
3726
+ if (type) {
3319
3727
  return type;
3728
+ }
3320
3729
  if (this._check(TokenTypes.template_types)) {
3321
3730
  let type2 = this._advance().toString();
3322
3731
  let format = null;
@@ -3324,8 +3733,9 @@ void main() {
3324
3733
  if (this._match(TokenTypes.tokens.less_than)) {
3325
3734
  format = this._type_decl();
3326
3735
  access = null;
3327
- if (this._match(TokenTypes.tokens.comma))
3736
+ if (this._match(TokenTypes.tokens.comma)) {
3328
3737
  access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString();
3738
+ }
3329
3739
  this._consume(TokenTypes.tokens.greater_than, "Expected '>' for type.");
3330
3740
  }
3331
3741
  return new TemplateType(type2, format, access);
@@ -3337,8 +3747,9 @@ void main() {
3337
3747
  this._consume(TokenTypes.tokens.comma, "Expected ',' for pointer.");
3338
3748
  const decl = this._type_decl();
3339
3749
  let access = null;
3340
- if (this._match(TokenTypes.tokens.comma))
3750
+ if (this._match(TokenTypes.tokens.comma)) {
3341
3751
  access = this._consume(TokenTypes.access_mode, "Expected access_mode for pointer").toString();
3752
+ }
3342
3753
  this._consume(TokenTypes.tokens.greater_than, "Expected '>' for pointer.");
3343
3754
  return new PointerType(pointer, storage.toString(), decl, access);
3344
3755
  }
@@ -3347,6 +3758,7 @@ void main() {
3347
3758
  let format = null;
3348
3759
  let countInt = -1;
3349
3760
  const array = this._previous();
3761
+ let countNode = null;
3350
3762
  if (this._match(TokenTypes.tokens.less_than)) {
3351
3763
  format = this._type_decl();
3352
3764
  if (this._context.aliases.has(format.name)) {
@@ -3354,21 +3766,32 @@ void main() {
3354
3766
  }
3355
3767
  let count = "";
3356
3768
  if (this._match(TokenTypes.tokens.comma)) {
3357
- let c = this._shift_expression();
3358
- count = c.evaluate(this._context).toString();
3769
+ countNode = this._shift_expression();
3770
+ try {
3771
+ count = countNode.evaluate(this._context).toString();
3772
+ countNode = null;
3773
+ } catch (e) {
3774
+ count = "1";
3775
+ }
3359
3776
  }
3360
3777
  this._consume(TokenTypes.tokens.greater_than, "Expected '>' for array.");
3361
3778
  countInt = count ? parseInt(count) : 0;
3362
3779
  }
3363
- return new ArrayType(array.toString(), attrs, format, countInt);
3780
+ const arrayType = new ArrayType(array.toString(), attrs, format, countInt);
3781
+ if (countNode) {
3782
+ this._deferArrayCountEval.push({ arrayType, countNode });
3783
+ }
3784
+ return arrayType;
3364
3785
  }
3365
3786
  return null;
3366
3787
  }
3367
3788
  _texture_sampler_types() {
3368
- if (this._match(TokenTypes.sampler_type))
3789
+ if (this._match(TokenTypes.sampler_type)) {
3369
3790
  return new SamplerType(this._previous().toString(), null, null);
3370
- if (this._match(TokenTypes.depth_texture_type))
3791
+ }
3792
+ if (this._match(TokenTypes.depth_texture_type)) {
3371
3793
  return new SamplerType(this._previous().toString(), null, null);
3794
+ }
3372
3795
  if (this._match(TokenTypes.sampled_texture_type) || this._match(TokenTypes.multisampled_texture_type)) {
3373
3796
  const sampler = this._previous();
3374
3797
  this._consume(TokenTypes.tokens.less_than, "Expected '<' for sampler type.");
@@ -3408,31 +3831,9 @@ void main() {
3408
3831
  }
3409
3832
  attributes.push(attr);
3410
3833
  }
3411
- while (this._match(TokenTypes.tokens.attr_left)) {
3412
- if (!this._check(TokenTypes.tokens.attr_right)) {
3413
- do {
3414
- const name = this._consume(TokenTypes.attribute_name, "Expected attribute name");
3415
- const attr = new Attribute(name.toString(), null);
3416
- if (this._match(TokenTypes.tokens.paren_left)) {
3417
- attr.value = [
3418
- this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString()
3419
- ];
3420
- if (this._check(TokenTypes.tokens.comma)) {
3421
- this._advance();
3422
- do {
3423
- const v = this._consume(TokenTypes.literal_or_ident, "Expected attribute value").toString();
3424
- attr.value.push(v);
3425
- } while (this._match(TokenTypes.tokens.comma));
3426
- }
3427
- this._consume(TokenTypes.tokens.paren_right, "Expected ')'");
3428
- }
3429
- attributes.push(attr);
3430
- } while (this._match(TokenTypes.tokens.comma));
3431
- }
3432
- this._consume(TokenTypes.tokens.attr_right, "Expected ']]' after attribute declarations");
3433
- }
3434
- if (attributes.length == 0)
3834
+ if (attributes.length == 0) {
3435
3835
  return null;
3836
+ }
3436
3837
  return attributes;
3437
3838
  }
3438
3839
  };
@@ -3490,6 +3891,9 @@ void main() {
3490
3891
  super(name, attributes);
3491
3892
  this.members = [];
3492
3893
  this.align = 0;
3894
+ this.startLine = -1;
3895
+ this.endLine = -1;
3896
+ this.inUse = false;
3493
3897
  }
3494
3898
  get isStruct() {
3495
3899
  return true;
@@ -3595,6 +3999,11 @@ void main() {
3595
3999
  this.stage = null;
3596
4000
  this.inputs = [];
3597
4001
  this.outputs = [];
4002
+ this.resources = [];
4003
+ this.startLine = -1;
4004
+ this.endLine = -1;
4005
+ this.inUse = false;
4006
+ this.calls = /* @__PURE__ */ new Set();
3598
4007
  this.name = name;
3599
4008
  this.stage = stage;
3600
4009
  }
@@ -3614,6 +4023,14 @@ void main() {
3614
4023
  this.id = id;
3615
4024
  }
3616
4025
  };
4026
+ var _FunctionResources = class {
4027
+ constructor(node) {
4028
+ this.resources = null;
4029
+ this.inUse = false;
4030
+ this.info = null;
4031
+ this.node = node;
4032
+ }
4033
+ };
3617
4034
  var WgslReflect = class {
3618
4035
  constructor(code) {
3619
4036
  this.uniforms = [];
@@ -3624,7 +4041,9 @@ void main() {
3624
4041
  this.overrides = [];
3625
4042
  this.structs = [];
3626
4043
  this.entry = new EntryFunctions();
4044
+ this.functions = [];
3627
4045
  this._types = /* @__PURE__ */ new Map();
4046
+ this._functions = /* @__PURE__ */ new Map();
3628
4047
  if (code) {
3629
4048
  this.update(code);
3630
4049
  }
@@ -3635,14 +4054,20 @@ void main() {
3635
4054
  update(code) {
3636
4055
  const parser = new WgslParser();
3637
4056
  const ast = parser.parse(code);
4057
+ for (const node of ast) {
4058
+ if (node instanceof Function) {
4059
+ this._functions.set(node.name, new _FunctionResources(node));
4060
+ }
4061
+ }
3638
4062
  for (const node of ast) {
3639
4063
  if (node instanceof Struct) {
3640
4064
  const info = this._getTypeInfo(node, null);
3641
4065
  if (info instanceof StructInfo) {
3642
4066
  this.structs.push(info);
3643
4067
  }
3644
- continue;
3645
4068
  }
4069
+ }
4070
+ for (const node of ast) {
3646
4071
  if (node instanceof Alias) {
3647
4072
  this.aliases.push(this._getAliasInfo(node));
3648
4073
  continue;
@@ -3701,8 +4126,15 @@ void main() {
3701
4126
  const fragmentStage = this._getAttribute(node, "fragment");
3702
4127
  const computeStage = this._getAttribute(node, "compute");
3703
4128
  const stage = vertexStage || fragmentStage || computeStage;
4129
+ const fn = new FunctionInfo(node.name, stage === null || stage === void 0 ? void 0 : stage.name);
4130
+ fn.startLine = node.startLine;
4131
+ fn.endLine = node.endLine;
4132
+ this.functions.push(fn);
4133
+ this._functions.get(node.name).info = fn;
3704
4134
  if (stage) {
3705
- const fn = new FunctionInfo(node.name, stage.name);
4135
+ this._functions.get(node.name).inUse = true;
4136
+ fn.inUse = true;
4137
+ fn.resources = this._findResources(node, !!stage);
3706
4138
  fn.inputs = this._getInputs(node.args);
3707
4139
  fn.outputs = this._getOutputs(node.returnType);
3708
4140
  this.entry[stage.name].push(fn);
@@ -3710,16 +4142,180 @@ void main() {
3710
4142
  continue;
3711
4143
  }
3712
4144
  }
4145
+ for (const fn of this._functions.values()) {
4146
+ if (fn.info) {
4147
+ fn.info.inUse = fn.inUse;
4148
+ this._addCalls(fn.node, fn.info.calls);
4149
+ }
4150
+ }
4151
+ for (const u of this.uniforms) {
4152
+ this._markStructsInUse(u.type);
4153
+ }
4154
+ for (const s of this.storage) {
4155
+ this._markStructsInUse(s.type);
4156
+ }
4157
+ }
4158
+ _markStructsInUse(type) {
4159
+ if (type.isStruct) {
4160
+ type.inUse = true;
4161
+ for (const m of type.members) {
4162
+ this._markStructsInUse(m.type);
4163
+ }
4164
+ } else if (type.isArray) {
4165
+ this._markStructsInUse(type.format);
4166
+ } else if (type.isTemplate) {
4167
+ this._markStructsInUse(type.format);
4168
+ } else {
4169
+ const alias = this._getAlias(type.name);
4170
+ if (alias) {
4171
+ this._markStructsInUse(alias);
4172
+ }
4173
+ }
4174
+ }
4175
+ _addCalls(fn, calls) {
4176
+ var _a2;
4177
+ for (const call of fn.calls) {
4178
+ const info = (_a2 = this._functions.get(call.name)) === null || _a2 === void 0 ? void 0 : _a2.info;
4179
+ if (info) {
4180
+ calls.add(info);
4181
+ }
4182
+ }
4183
+ }
4184
+ /// Find a resource by its group and binding.
4185
+ findResource(group, binding) {
4186
+ for (const u of this.uniforms) {
4187
+ if (u.group == group && u.binding == binding) {
4188
+ return u;
4189
+ }
4190
+ }
4191
+ for (const s of this.storage) {
4192
+ if (s.group == group && s.binding == binding) {
4193
+ return s;
4194
+ }
4195
+ }
4196
+ for (const t of this.textures) {
4197
+ if (t.group == group && t.binding == binding) {
4198
+ return t;
4199
+ }
4200
+ }
4201
+ for (const s of this.samplers) {
4202
+ if (s.group == group && s.binding == binding) {
4203
+ return s;
4204
+ }
4205
+ }
4206
+ return null;
4207
+ }
4208
+ _findResource(name) {
4209
+ for (const u of this.uniforms) {
4210
+ if (u.name == name) {
4211
+ return u;
4212
+ }
4213
+ }
4214
+ for (const s of this.storage) {
4215
+ if (s.name == name) {
4216
+ return s;
4217
+ }
4218
+ }
4219
+ for (const t of this.textures) {
4220
+ if (t.name == name) {
4221
+ return t;
4222
+ }
4223
+ }
4224
+ for (const s of this.samplers) {
4225
+ if (s.name == name) {
4226
+ return s;
4227
+ }
4228
+ }
4229
+ return null;
4230
+ }
4231
+ _markStructsFromAST(type) {
4232
+ const info = this._getTypeInfo(type, null);
4233
+ this._markStructsInUse(info);
4234
+ }
4235
+ _findResources(fn, isEntry) {
4236
+ const resources = [];
4237
+ const self = this;
4238
+ const varStack = [];
4239
+ fn.search((node) => {
4240
+ if (node instanceof _BlockStart) {
4241
+ varStack.push({});
4242
+ } else if (node instanceof _BlockEnd) {
4243
+ varStack.pop();
4244
+ } else if (node instanceof Var) {
4245
+ const v = node;
4246
+ if (isEntry && v.type !== null) {
4247
+ this._markStructsFromAST(v.type);
4248
+ }
4249
+ if (varStack.length > 0) {
4250
+ varStack[varStack.length - 1][v.name] = v;
4251
+ }
4252
+ } else if (node instanceof CreateExpr) {
4253
+ const c = node;
4254
+ if (isEntry && c.type !== null) {
4255
+ this._markStructsFromAST(c.type);
4256
+ }
4257
+ } else if (node instanceof Let) {
4258
+ const v = node;
4259
+ if (isEntry && v.type !== null) {
4260
+ this._markStructsFromAST(v.type);
4261
+ }
4262
+ if (varStack.length > 0) {
4263
+ varStack[varStack.length - 1][v.name] = v;
4264
+ }
4265
+ } else if (node instanceof VariableExpr) {
4266
+ const v = node;
4267
+ if (varStack.length > 0) {
4268
+ const varInfo2 = varStack[varStack.length - 1][v.name];
4269
+ if (varInfo2) {
4270
+ return;
4271
+ }
4272
+ }
4273
+ const varInfo = self._findResource(v.name);
4274
+ if (varInfo) {
4275
+ resources.push(varInfo);
4276
+ }
4277
+ } else if (node instanceof CallExpr) {
4278
+ const c = node;
4279
+ const callFn = self._functions.get(c.name);
4280
+ if (callFn) {
4281
+ if (isEntry) {
4282
+ callFn.inUse = true;
4283
+ }
4284
+ fn.calls.add(callFn.node);
4285
+ if (callFn.resources === null) {
4286
+ callFn.resources = self._findResources(callFn.node, isEntry);
4287
+ }
4288
+ resources.push(...callFn.resources);
4289
+ }
4290
+ } else if (node instanceof Call) {
4291
+ const c = node;
4292
+ const callFn = self._functions.get(c.name);
4293
+ if (callFn) {
4294
+ if (isEntry) {
4295
+ callFn.inUse = true;
4296
+ }
4297
+ fn.calls.add(callFn.node);
4298
+ if (callFn.resources === null) {
4299
+ callFn.resources = self._findResources(callFn.node, isEntry);
4300
+ }
4301
+ resources.push(...callFn.resources);
4302
+ }
4303
+ }
4304
+ });
4305
+ return [...new Map(resources.map((r) => [r.name, r])).values()];
3713
4306
  }
3714
4307
  getBindGroups() {
3715
4308
  const groups = [];
3716
4309
  function _makeRoom(group, binding) {
3717
- if (group >= groups.length)
4310
+ if (group >= groups.length) {
3718
4311
  groups.length = group + 1;
3719
- if (groups[group] === void 0)
4312
+ }
4313
+ if (groups[group] === void 0) {
3720
4314
  groups[group] = [];
3721
- if (binding >= groups[group].length)
4315
+ }
4316
+ if (binding >= groups[group].length) {
3722
4317
  groups[group].length = binding + 1;
4318
+ }
3723
4319
  }
3724
4320
  for (const u of this.uniforms) {
3725
4321
  _makeRoom(u.group, u.binding);
@@ -3744,14 +4340,16 @@ void main() {
3744
4340
  return groups;
3745
4341
  }
3746
4342
  _getOutputs(type, outputs = void 0) {
3747
- if (outputs === void 0)
4343
+ if (outputs === void 0) {
3748
4344
  outputs = [];
4345
+ }
3749
4346
  if (type instanceof Struct) {
3750
4347
  this._getStructOutputs(type, outputs);
3751
4348
  } else {
3752
4349
  const output = this._getOutputInfo(type);
3753
- if (output !== null)
4350
+ if (output !== null) {
3754
4351
  outputs.push(output);
4352
+ }
3755
4353
  }
3756
4354
  return outputs;
3757
4355
  }
@@ -3781,15 +4379,17 @@ void main() {
3781
4379
  return null;
3782
4380
  }
3783
4381
  _getInputs(args, inputs = void 0) {
3784
- if (inputs === void 0)
4382
+ if (inputs === void 0) {
3785
4383
  inputs = [];
4384
+ }
3786
4385
  for (const arg of args) {
3787
4386
  if (arg.type instanceof Struct) {
3788
4387
  this._getStructInputs(arg.type, inputs);
3789
4388
  } else {
3790
4389
  const input = this._getInputInfo(arg);
3791
- if (input !== null)
4390
+ if (input !== null) {
3792
4391
  inputs.push(input);
4392
+ }
3793
4393
  }
3794
4394
  }
3795
4395
  return inputs;
@@ -3800,8 +4400,9 @@ void main() {
3800
4400
  this._getStructInputs(m.type, inputs);
3801
4401
  } else {
3802
4402
  const input = this._getInputInfo(m);
3803
- if (input !== null)
4403
+ if (input !== null) {
3804
4404
  inputs.push(input);
4405
+ }
3805
4406
  }
3806
4407
  }
3807
4408
  }
@@ -3834,8 +4435,9 @@ void main() {
3834
4435
  }
3835
4436
  _getAlias(name) {
3836
4437
  for (const a of this.aliases) {
3837
- if (a.name == name)
4438
+ if (a.name == name) {
3838
4439
  return a.type;
4440
+ }
3839
4441
  }
3840
4442
  return null;
3841
4443
  }
@@ -3859,6 +4461,8 @@ void main() {
3859
4461
  if (type instanceof Struct) {
3860
4462
  const s = type;
3861
4463
  const info2 = new StructInfo(s.name, attributes);
4464
+ info2.startLine = s.startLine;
4465
+ info2.endLine = s.endLine;
3862
4466
  for (const m of s.members) {
3863
4467
  const t = this._getTypeInfo(m.type, m.attributes);
3864
4468
  info2.members.push(new MemberInfo(m.name, t, m.attributes));
@@ -3911,8 +4515,9 @@ void main() {
3911
4515
  for (let mi = 0, ml = struct.members.length; mi < ml; ++mi) {
3912
4516
  const member = struct.members[mi];
3913
4517
  const sizeInfo = this._getTypeSize(member);
3914
- if (!sizeInfo)
4518
+ if (!sizeInfo) {
3915
4519
  continue;
4520
+ }
3916
4521
  (_a2 = this._getAlias(member.type.name)) !== null && _a2 !== void 0 ? _a2 : member.type;
3917
4522
  const align = sizeInfo.align;
3918
4523
  const size = sizeInfo.size;
@@ -3929,12 +4534,14 @@ void main() {
3929
4534
  }
3930
4535
  _getTypeSize(type) {
3931
4536
  var _a2;
3932
- if (type === null || type === void 0)
4537
+ if (type === null || type === void 0) {
3933
4538
  return null;
4539
+ }
3934
4540
  const explicitSize = this._getAttributeNum(type.attributes, "size", 0);
3935
4541
  const explicitAlign = this._getAttributeNum(type.attributes, "align", 0);
3936
- if (type instanceof MemberInfo)
4542
+ if (type instanceof MemberInfo) {
3937
4543
  type = type.type;
4544
+ }
3938
4545
  if (type instanceof TypeInfo) {
3939
4546
  const alias = this._getAlias(type.name);
3940
4547
  if (alias !== null) {
@@ -3967,8 +4574,9 @@ void main() {
3967
4574
  const N = arrayType.count;
3968
4575
  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));
3969
4576
  size = N * stride;
3970
- if (explicitSize)
4577
+ if (explicitSize) {
3971
4578
  size = explicitSize;
4579
+ }
3972
4580
  return new _TypeSize(Math.max(explicitAlign, align), Math.max(explicitSize, size));
3973
4581
  }
3974
4582
  if (type instanceof StructInfo) {
@@ -4005,18 +4613,21 @@ void main() {
4005
4613
  }
4006
4614
  _getAttribute(node, name) {
4007
4615
  const obj = node;
4008
- if (!obj || !obj["attributes"])
4616
+ if (!obj || !obj["attributes"]) {
4009
4617
  return null;
4618
+ }
4010
4619
  const attrs = obj["attributes"];
4011
4620
  for (let a of attrs) {
4012
- if (a.name == name)
4621
+ if (a.name == name) {
4013
4622
  return a;
4623
+ }
4014
4624
  }
4015
4625
  return null;
4016
4626
  }
4017
4627
  _getAttributeNum(attributes, name, defaultValue) {
4018
- if (attributes === null)
4628
+ if (attributes === null) {
4019
4629
  return defaultValue;
4630
+ }
4020
4631
  for (let a of attributes) {
4021
4632
  if (a.name == name) {
4022
4633
  let v = a !== null && a.value !== null ? a.value : defaultValue;
@@ -4076,10 +4687,10 @@ void main() {
4076
4687
  }
4077
4688
  for (const uniform of parsedWGSL.uniforms) {
4078
4689
  const members = [];
4079
- for (const member of uniform.type.members) {
4690
+ for (const attribute of uniform.type?.members || []) {
4080
4691
  members.push({
4081
- name: member.name,
4082
- type: getType(member.type)
4692
+ name: attribute.name,
4693
+ type: getType(attribute.type)
4083
4694
  });
4084
4695
  }
4085
4696
  shaderLayout.bindings.push({
@@ -4099,7 +4710,7 @@ void main() {
4099
4710
  const type = getType(wgslAttribute.type);
4100
4711
  shaderLayout.attributes.push({
4101
4712
  name: wgslAttribute.name,
4102
- location: wgslAttribute.location,
4713
+ location: Number(wgslAttribute.location),
4103
4714
  type
4104
4715
  });
4105
4716
  }
@@ -7847,17 +8458,11 @@ vec3 geometry_getNormal() {
7847
8458
  printRowMajor: true,
7848
8459
  _cartographicRadians: false
7849
8460
  };
7850
- globalThis.mathgl = globalThis.mathgl || {
7851
- config: {
7852
- ...DEFAULT_CONFIG
7853
- }
7854
- };
8461
+ globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
7855
8462
  var config = globalThis.mathgl.config;
7856
- function formatValue(value, {
7857
- precision = config.precision
7858
- } = {}) {
8463
+ function formatValue(value, { precision = config.precision } = {}) {
7859
8464
  value = round(value);
7860
- return "".concat(parseFloat(value.toPrecision(precision)));
8465
+ return `${parseFloat(value.toPrecision(precision))}`;
7861
8466
  }
7862
8467
  function isArray(value) {
7863
8468
  return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
@@ -7901,28 +8506,12 @@ vec3 geometry_getNormal() {
7901
8506
  }
7902
8507
 
7903
8508
  // ../../node_modules/@math.gl/core/dist/classes/base/math-array.js
7904
- function _extendableBuiltin(cls) {
7905
- function ExtendableBuiltin() {
7906
- var instance = Reflect.construct(cls, Array.from(arguments));
7907
- Object.setPrototypeOf(instance, Object.getPrototypeOf(this));
7908
- return instance;
7909
- }
7910
- ExtendableBuiltin.prototype = Object.create(cls.prototype, {
7911
- constructor: {
7912
- value: cls,
7913
- enumerable: false,
7914
- writable: true,
7915
- configurable: true
7916
- }
7917
- });
7918
- if (Object.setPrototypeOf) {
7919
- Object.setPrototypeOf(ExtendableBuiltin, cls);
7920
- } else {
7921
- ExtendableBuiltin.__proto__ = cls;
7922
- }
7923
- return ExtendableBuiltin;
7924
- }
7925
- var MathArray = class extends _extendableBuiltin(Array) {
8509
+ var MathArray = class extends Array {
8510
+ // Common methods
8511
+ /**
8512
+ * Clone the current object
8513
+ * @returns a new copy of this object
8514
+ */
7926
8515
  clone() {
7927
8516
  return new this.constructor().copy(this);
7928
8517
  }
@@ -7942,7 +8531,10 @@ vec3 geometry_getNormal() {
7942
8531
  return targetObject;
7943
8532
  }
7944
8533
  from(arrayOrObject) {
7945
- return Array.isArray(arrayOrObject) ? this.copy(arrayOrObject) : this.fromObject(arrayOrObject);
8534
+ return Array.isArray(arrayOrObject) ? this.copy(arrayOrObject) : (
8535
+ // @ts-ignore
8536
+ this.fromObject(arrayOrObject)
8537
+ );
7946
8538
  }
7947
8539
  to(arrayOrObject) {
7948
8540
  if (arrayOrObject === this) {
@@ -7953,18 +8545,20 @@ vec3 geometry_getNormal() {
7953
8545
  toTarget(target) {
7954
8546
  return target ? this.to(target) : this;
7955
8547
  }
8548
+ /** @deprecated */
7956
8549
  toFloat32Array() {
7957
8550
  return new Float32Array(this);
7958
8551
  }
7959
8552
  toString() {
7960
8553
  return this.formatString(config);
7961
8554
  }
8555
+ /** Formats string according to options */
7962
8556
  formatString(opts) {
7963
8557
  let string = "";
7964
8558
  for (let i = 0; i < this.ELEMENTS; ++i) {
7965
8559
  string += (i > 0 ? ", " : "") + formatValue(this[i], opts);
7966
8560
  }
7967
- return "".concat(opts.printTypes ? this.constructor.name : "", "[").concat(string, "]");
8561
+ return `${opts.printTypes ? this.constructor.name : ""}[${string}]`;
7968
8562
  }
7969
8563
  equals(array) {
7970
8564
  if (!array || this.length !== array.length) {
@@ -7988,6 +8582,8 @@ vec3 geometry_getNormal() {
7988
8582
  }
7989
8583
  return true;
7990
8584
  }
8585
+ // Modifiers
8586
+ /** Negates all values in this object */
7991
8587
  negate() {
7992
8588
  for (let i = 0; i < this.ELEMENTS; ++i) {
7993
8589
  this[i] = -this[i];
@@ -8005,12 +8601,14 @@ vec3 geometry_getNormal() {
8005
8601
  }
8006
8602
  return this.check();
8007
8603
  }
8604
+ /** Minimal */
8008
8605
  min(vector) {
8009
8606
  for (let i = 0; i < this.ELEMENTS; ++i) {
8010
8607
  this[i] = Math.min(vector[i], this[i]);
8011
8608
  }
8012
8609
  return this.check();
8013
8610
  }
8611
+ /** Maximal */
8014
8612
  max(vector) {
8015
8613
  for (let i = 0; i < this.ELEMENTS; ++i) {
8016
8614
  this[i] = Math.max(vector[i], this[i]);
@@ -8051,18 +8649,25 @@ vec3 geometry_getNormal() {
8051
8649
  }
8052
8650
  return this.check();
8053
8651
  }
8652
+ /**
8653
+ * Multiplies all elements by `scale`
8654
+ * Note: `Matrix4.multiplyByScalar` only scales its 3x3 "minor"
8655
+ */
8054
8656
  multiplyByScalar(scalar) {
8055
8657
  for (let i = 0; i < this.ELEMENTS; ++i) {
8056
8658
  this[i] *= scalar;
8057
8659
  }
8058
8660
  return this.check();
8059
8661
  }
8662
+ // Debug checks
8663
+ /** Throws an error if array length is incorrect or contains illegal values */
8060
8664
  check() {
8061
8665
  if (config.debug && !this.validate()) {
8062
- throw new Error("math.gl: ".concat(this.constructor.name, " some fields set to invalid numbers'"));
8666
+ throw new Error(`math.gl: ${this.constructor.name} some fields set to invalid numbers'`);
8063
8667
  }
8064
8668
  return this;
8065
8669
  }
8670
+ /** Returns false if the array length is incorrect or contains illegal values */
8066
8671
  validate() {
8067
8672
  let valid = this.length === this.ELEMENTS;
8068
8673
  for (let i = 0; i < this.ELEMENTS; ++i) {
@@ -8070,39 +8675,48 @@ vec3 geometry_getNormal() {
8070
8675
  }
8071
8676
  return valid;
8072
8677
  }
8678
+ // three.js compatibility
8679
+ /** @deprecated */
8073
8680
  sub(a) {
8074
8681
  return this.subtract(a);
8075
8682
  }
8683
+ /** @deprecated */
8076
8684
  setScalar(a) {
8077
8685
  for (let i = 0; i < this.ELEMENTS; ++i) {
8078
8686
  this[i] = a;
8079
8687
  }
8080
8688
  return this.check();
8081
8689
  }
8690
+ /** @deprecated */
8082
8691
  addScalar(a) {
8083
8692
  for (let i = 0; i < this.ELEMENTS; ++i) {
8084
8693
  this[i] += a;
8085
8694
  }
8086
8695
  return this.check();
8087
8696
  }
8697
+ /** @deprecated */
8088
8698
  subScalar(a) {
8089
8699
  return this.addScalar(-a);
8090
8700
  }
8701
+ /** @deprecated */
8091
8702
  multiplyScalar(scalar) {
8092
8703
  for (let i = 0; i < this.ELEMENTS; ++i) {
8093
8704
  this[i] *= scalar;
8094
8705
  }
8095
8706
  return this.check();
8096
8707
  }
8708
+ /** @deprecated */
8097
8709
  divideScalar(a) {
8098
8710
  return this.multiplyByScalar(1 / a);
8099
8711
  }
8712
+ /** @deprecated */
8100
8713
  clampScalar(min, max) {
8101
8714
  for (let i = 0; i < this.ELEMENTS; ++i) {
8102
8715
  this[i] = Math.min(Math.max(this[i], min), max);
8103
8716
  }
8104
8717
  return this.check();
8105
8718
  }
8719
+ /** @deprecated */
8106
8720
  get elements() {
8107
8721
  return this;
8108
8722
  }
@@ -8122,13 +8736,13 @@ vec3 geometry_getNormal() {
8122
8736
  }
8123
8737
  function checkNumber(value) {
8124
8738
  if (!Number.isFinite(value)) {
8125
- throw new Error("Invalid number ".concat(JSON.stringify(value)));
8739
+ throw new Error(`Invalid number ${JSON.stringify(value)}`);
8126
8740
  }
8127
8741
  return value;
8128
8742
  }
8129
8743
  function checkVector(v, length, callerName = "") {
8130
8744
  if (config.debug && !validateVector(v, length)) {
8131
- throw new Error("math.gl: ".concat(callerName, " some fields set to invalid numbers'"));
8745
+ throw new Error(`math.gl: ${callerName} some fields set to invalid numbers'`);
8132
8746
  }
8133
8747
  return v;
8134
8748
  }
@@ -8253,19 +8867,29 @@ vec3 geometry_getNormal() {
8253
8867
 
8254
8868
  // ../../node_modules/@math.gl/core/dist/classes/base/matrix.js
8255
8869
  var Matrix = class extends MathArray {
8870
+ // fromObject(object) {
8871
+ // const array = object.elements;
8872
+ // return this.fromRowMajor(array);
8873
+ // }
8874
+ // toObject(object) {
8875
+ // const array = object.elements;
8876
+ // this.toRowMajor(array);
8877
+ // return object;
8878
+ // }
8879
+ // TODO better override formatString?
8256
8880
  toString() {
8257
8881
  let string = "[";
8258
8882
  if (config.printRowMajor) {
8259
8883
  string += "row-major:";
8260
8884
  for (let row = 0; row < this.RANK; ++row) {
8261
8885
  for (let col = 0; col < this.RANK; ++col) {
8262
- string += " ".concat(this[col * this.RANK + row]);
8886
+ string += ` ${this[col * this.RANK + row]}`;
8263
8887
  }
8264
8888
  }
8265
8889
  } else {
8266
8890
  string += "column-major:";
8267
8891
  for (let i = 0; i < this.ELEMENTS; ++i) {
8268
- string += " ".concat(this[i]);
8892
+ string += ` ${this[i]}`;
8269
8893
  }
8270
8894
  }
8271
8895
  string += "]";
@@ -8274,9 +8898,11 @@ vec3 geometry_getNormal() {
8274
8898
  getElementIndex(row, col) {
8275
8899
  return col * this.RANK + row;
8276
8900
  }
8901
+ // By default assumes row major indices
8277
8902
  getElement(row, col) {
8278
8903
  return this[col * this.RANK + row];
8279
8904
  }
8905
+ // By default assumes row major indices
8280
8906
  setElement(row, col, value) {
8281
8907
  this[col * this.RANK + row] = checkNumber(value);
8282
8908
  return this;
@@ -9042,6 +9668,7 @@ vec3 geometry_getNormal() {
9042
9668
  this[15] = array[15];
9043
9669
  return this.check();
9044
9670
  }
9671
+ // eslint-disable-next-line max-params
9045
9672
  set(m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33) {
9046
9673
  this[0] = m00;
9047
9674
  this[1] = m10;
@@ -9061,6 +9688,8 @@ vec3 geometry_getNormal() {
9061
9688
  this[15] = m33;
9062
9689
  return this.check();
9063
9690
  }
9691
+ // accepts row major order, stores as column major
9692
+ // eslint-disable-next-line max-params
9064
9693
  setRowMajor(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
9065
9694
  this[0] = m00;
9066
9695
  this[1] = m10;
@@ -9099,25 +9728,41 @@ vec3 geometry_getNormal() {
9099
9728
  result[15] = this[15];
9100
9729
  return result;
9101
9730
  }
9731
+ // Constructors
9732
+ /** Set to identity matrix */
9102
9733
  identity() {
9103
9734
  return this.copy(IDENTITY_MATRIX);
9104
9735
  }
9736
+ /**
9737
+ *
9738
+ * @param object
9739
+ * @returns self
9740
+ */
9741
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9105
9742
  fromObject(object) {
9106
9743
  return this.check();
9107
9744
  }
9745
+ /**
9746
+ * Calculates a 4x4 matrix from the given quaternion
9747
+ * @param quaternion Quaternion to create matrix from
9748
+ * @returns self
9749
+ */
9108
9750
  fromQuaternion(quaternion) {
9109
9751
  fromQuat(this, quaternion);
9110
9752
  return this.check();
9111
9753
  }
9754
+ /**
9755
+ * Generates a frustum matrix with the given bounds
9756
+ * @param view.left - Left bound of the frustum
9757
+ * @param view.right - Right bound of the frustum
9758
+ * @param view.bottom - Bottom bound of the frustum
9759
+ * @param view.top - Top bound of the frustum
9760
+ * @param view.near - Near bound of the frustum
9761
+ * @param view.far - Far bound of the frustum. Can be set to Infinity.
9762
+ * @returns self
9763
+ */
9112
9764
  frustum(view) {
9113
- const {
9114
- left,
9115
- right,
9116
- bottom,
9117
- top,
9118
- near = DEFAULT_NEAR,
9119
- far = DEFAULT_FAR
9120
- } = view;
9765
+ const { left, right, bottom, top, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view;
9121
9766
  if (far === Infinity) {
9122
9767
  computeInfinitePerspectiveOffCenter(this, left, right, bottom, top, near);
9123
9768
  } else {
@@ -9125,35 +9770,47 @@ vec3 geometry_getNormal() {
9125
9770
  }
9126
9771
  return this.check();
9127
9772
  }
9773
+ /**
9774
+ * Generates a look-at matrix with the given eye position, focal point,
9775
+ * and up axis
9776
+ * @param view.eye - (vector) Position of the viewer
9777
+ * @param view.center - (vector) Point the viewer is looking at
9778
+ * @param view.up - (vector) Up axis
9779
+ * @returns self
9780
+ */
9128
9781
  lookAt(view) {
9129
- const {
9130
- eye,
9131
- center = [0, 0, 0],
9132
- up = [0, 1, 0]
9133
- } = view;
9782
+ const { eye, center = [0, 0, 0], up = [0, 1, 0] } = view;
9134
9783
  lookAt(this, eye, center, up);
9135
9784
  return this.check();
9136
9785
  }
9786
+ /**
9787
+ * Generates a orthogonal projection matrix with the given bounds
9788
+ * from "traditional" view space parameters
9789
+ * @param view.left - Left bound of the frustum
9790
+ * @param view.right number Right bound of the frustum
9791
+ * @param view.bottom - Bottom bound of the frustum
9792
+ * @param view.top number Top bound of the frustum
9793
+ * @param view.near - Near bound of the frustum
9794
+ * @param view.far number Far bound of the frustum
9795
+ * @returns self
9796
+ */
9137
9797
  ortho(view) {
9138
- const {
9139
- left,
9140
- right,
9141
- bottom,
9142
- top,
9143
- near = DEFAULT_NEAR,
9144
- far = DEFAULT_FAR
9145
- } = view;
9798
+ const { left, right, bottom, top, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view;
9146
9799
  ortho(this, left, right, bottom, top, near, far);
9147
9800
  return this.check();
9148
9801
  }
9802
+ /**
9803
+ * Generates an orthogonal projection matrix with the same parameters
9804
+ * as a perspective matrix (plus focalDistance)
9805
+ * @param view.fovy Vertical field of view in radians
9806
+ * @param view.aspect Aspect ratio. Typically viewport width / viewport height
9807
+ * @param view.focalDistance Distance in the view frustum used for extent calculations
9808
+ * @param view.near Near bound of the frustum
9809
+ * @param view.far Far bound of the frustum
9810
+ * @returns self
9811
+ */
9149
9812
  orthographic(view) {
9150
- const {
9151
- fovy = DEFAULT_FOVY,
9152
- aspect = DEFAULT_ASPECT,
9153
- focalDistance = 1,
9154
- near = DEFAULT_NEAR,
9155
- far = DEFAULT_FAR
9156
- } = view;
9813
+ const { fovy = DEFAULT_FOVY, aspect = DEFAULT_ASPECT, focalDistance = 1, near = DEFAULT_NEAR, far = DEFAULT_FAR } = view;
9157
9814
  checkRadians(fovy);
9158
9815
  const halfY = fovy / 2;
9159
9816
  const top = focalDistance * Math.tan(halfY);
@@ -9167,32 +9824,53 @@ vec3 geometry_getNormal() {
9167
9824
  far
9168
9825
  });
9169
9826
  }
9827
+ /**
9828
+ * Generates a perspective projection matrix with the given bounds
9829
+ * @param view.fovy Vertical field of view in radians
9830
+ * @param view.aspect Aspect ratio. typically viewport width/height
9831
+ * @param view.near Near bound of the frustum
9832
+ * @param view.far Far bound of the frustum
9833
+ * @returns self
9834
+ */
9170
9835
  perspective(view) {
9171
- const {
9172
- fovy = 45 * Math.PI / 180,
9173
- aspect = 1,
9174
- near = 0.1,
9175
- far = 500
9176
- } = view;
9836
+ const { fovy = 45 * Math.PI / 180, aspect = 1, near = 0.1, far = 500 } = view;
9177
9837
  checkRadians(fovy);
9178
9838
  perspective(this, fovy, aspect, near, far);
9179
9839
  return this.check();
9180
9840
  }
9841
+ // Accessors
9181
9842
  determinant() {
9182
9843
  return determinant(this);
9183
9844
  }
9845
+ /**
9846
+ * Extracts the non-uniform scale assuming the matrix is an affine transformation.
9847
+ * The scales are the "lengths" of the column vectors in the upper-left 3x3 matrix.
9848
+ * @param result
9849
+ * @returns self
9850
+ */
9184
9851
  getScale(result = [-0, -0, -0]) {
9185
9852
  result[0] = Math.sqrt(this[0] * this[0] + this[1] * this[1] + this[2] * this[2]);
9186
9853
  result[1] = Math.sqrt(this[4] * this[4] + this[5] * this[5] + this[6] * this[6]);
9187
9854
  result[2] = Math.sqrt(this[8] * this[8] + this[9] * this[9] + this[10] * this[10]);
9188
9855
  return result;
9189
9856
  }
9857
+ /**
9858
+ * Gets the translation portion, assuming the matrix is a affine transformation matrix.
9859
+ * @param result
9860
+ * @returns self
9861
+ */
9190
9862
  getTranslation(result = [-0, -0, -0]) {
9191
9863
  result[0] = this[12];
9192
9864
  result[1] = this[13];
9193
9865
  result[2] = this[14];
9194
9866
  return result;
9195
9867
  }
9868
+ /**
9869
+ * Gets upper left 3x3 pure rotation matrix (non-scaling), assume affine transformation matrix
9870
+ * @param result
9871
+ * @param scaleResult
9872
+ * @returns self
9873
+ */
9196
9874
  getRotation(result, scaleResult) {
9197
9875
  result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0, -0];
9198
9876
  scaleResult = scaleResult || [-0, -0, -0];
@@ -9218,6 +9896,12 @@ vec3 geometry_getNormal() {
9218
9896
  result[15] = 1;
9219
9897
  return result;
9220
9898
  }
9899
+ /**
9900
+ *
9901
+ * @param result
9902
+ * @param scaleResult
9903
+ * @returns self
9904
+ */
9221
9905
  getRotationMatrix3(result, scaleResult) {
9222
9906
  result = result || [-0, -0, -0, -0, -0, -0, -0, -0, -0];
9223
9907
  scaleResult = scaleResult || [-0, -0, -0];
@@ -9236,6 +9920,7 @@ vec3 geometry_getNormal() {
9236
9920
  result[8] = this[10] * inverseScale2;
9237
9921
  return result;
9238
9922
  }
9923
+ // Modifiers
9239
9924
  transpose() {
9240
9925
  transpose(this, this);
9241
9926
  return this.check();
@@ -9244,6 +9929,7 @@ vec3 geometry_getNormal() {
9244
9929
  invert(this, this);
9245
9930
  return this.check();
9246
9931
  }
9932
+ // Operations
9247
9933
  multiplyLeft(a) {
9248
9934
  multiply(this, a, this);
9249
9935
  return this.check();
@@ -9252,33 +9938,68 @@ vec3 geometry_getNormal() {
9252
9938
  multiply(this, this, a);
9253
9939
  return this.check();
9254
9940
  }
9941
+ // Rotates a matrix by the given angle around the X axis
9255
9942
  rotateX(radians) {
9256
9943
  rotateX(this, this, radians);
9257
9944
  return this.check();
9258
9945
  }
9946
+ // Rotates a matrix by the given angle around the Y axis.
9259
9947
  rotateY(radians) {
9260
9948
  rotateY(this, this, radians);
9261
9949
  return this.check();
9262
9950
  }
9951
+ /**
9952
+ * Rotates a matrix by the given angle around the Z axis.
9953
+ * @param radians
9954
+ * @returns self
9955
+ */
9263
9956
  rotateZ(radians) {
9264
9957
  rotateZ(this, this, radians);
9265
9958
  return this.check();
9266
9959
  }
9960
+ /**
9961
+ *
9962
+ * @param param0
9963
+ * @returns self
9964
+ */
9267
9965
  rotateXYZ(angleXYZ) {
9268
9966
  return this.rotateX(angleXYZ[0]).rotateY(angleXYZ[1]).rotateZ(angleXYZ[2]);
9269
9967
  }
9968
+ /**
9969
+ *
9970
+ * @param radians
9971
+ * @param axis
9972
+ * @returns self
9973
+ */
9270
9974
  rotateAxis(radians, axis) {
9271
9975
  rotate(this, this, radians, axis);
9272
9976
  return this.check();
9273
9977
  }
9978
+ /**
9979
+ *
9980
+ * @param factor
9981
+ * @returns self
9982
+ */
9274
9983
  scale(factor) {
9275
9984
  scale(this, this, Array.isArray(factor) ? factor : [factor, factor, factor]);
9276
9985
  return this.check();
9277
9986
  }
9987
+ /**
9988
+ *
9989
+ * @param vec
9990
+ * @returns self
9991
+ */
9278
9992
  translate(vector) {
9279
9993
  translate(this, this, vector);
9280
9994
  return this.check();
9281
9995
  }
9996
+ // Transforms
9997
+ /**
9998
+ * Transforms any 2, 3 or 4 element vector. 2 and 3 elements are treated as points
9999
+ * @param vector
10000
+ * @param result
10001
+ * @returns self
10002
+ */
9282
10003
  transform(vector, result) {
9283
10004
  if (vector.length === 4) {
9284
10005
  result = transformMat43(result || [-0, -0, -0, -0], vector, this);
@@ -9287,10 +10008,14 @@ vec3 geometry_getNormal() {
9287
10008
  }
9288
10009
  return this.transformAsPoint(vector, result);
9289
10010
  }
10011
+ /**
10012
+ * Transforms any 2 or 3 element array as point (w implicitly 1)
10013
+ * @param vector
10014
+ * @param result
10015
+ * @returns self
10016
+ */
9290
10017
  transformAsPoint(vector, result) {
9291
- const {
9292
- length
9293
- } = vector;
10018
+ const { length } = vector;
9294
10019
  let out;
9295
10020
  switch (length) {
9296
10021
  case 2:
@@ -9305,6 +10030,12 @@ vec3 geometry_getNormal() {
9305
10030
  checkVector(out, vector.length);
9306
10031
  return out;
9307
10032
  }
10033
+ /**
10034
+ * Transforms any 2 or 3 element array as vector (w implicitly 0)
10035
+ * @param vector
10036
+ * @param result
10037
+ * @returns self
10038
+ */
9308
10039
  transformAsVector(vector, result) {
9309
10040
  let out;
9310
10041
  switch (vector.length) {
@@ -9320,15 +10051,19 @@ vec3 geometry_getNormal() {
9320
10051
  checkVector(out, vector.length);
9321
10052
  return out;
9322
10053
  }
10054
+ /** @deprecated */
9323
10055
  transformPoint(vector, result) {
9324
10056
  return this.transformAsPoint(vector, result);
9325
10057
  }
10058
+ /** @deprecated */
9326
10059
  transformVector(vector, result) {
9327
10060
  return this.transformAsPoint(vector, result);
9328
10061
  }
10062
+ /** @deprecated */
9329
10063
  transformDirection(vector, result) {
9330
10064
  return this.transformAsVector(vector, result);
9331
10065
  }
10066
+ // three.js math API compatibility
9332
10067
  makeRotationX(radians) {
9333
10068
  return this.identity().rotateX(radians);
9334
10069
  }