wesl-link 0.6.15 → 0.6.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/bin/wesl-link +182 -1525
- package/package.json +3 -3
package/bin/wesl-link
CHANGED
|
@@ -3,11 +3,11 @@ import { hideBin } from "yargs/helpers";
|
|
|
3
3
|
import path, { posix, win32 } from "node:path";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
5
|
import { resolve } from "import-meta-resolve";
|
|
6
|
-
import {
|
|
7
|
-
import { WeslParseError, astToString, filterMap,
|
|
6
|
+
import { enableTracing, log } from "mini-parse";
|
|
7
|
+
import { RecordResolver, WeslParseError, astToString, bindIdentsRecursive, filterMap, findValidRootDecls, link, minimalMangle, scopeToString } from "wesl";
|
|
8
|
+
import * as actualFS from "node:fs";
|
|
8
9
|
import fs, { lstat, readdir, readlink, realpath } from "node:fs/promises";
|
|
9
10
|
import { lstatSync, readdir as readdir$1, readdirSync, readlinkSync, realpathSync } from "fs";
|
|
10
|
-
import * as actualFS from "node:fs";
|
|
11
11
|
import { EventEmitter } from "node:events";
|
|
12
12
|
import Stream from "node:stream";
|
|
13
13
|
import { StringDecoder } from "node:string_decoder";
|
|
@@ -38,6 +38,41 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
38
38
|
enumerable: true
|
|
39
39
|
}) : target, mod));
|
|
40
40
|
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region ../wesl-tooling/src/FindUnboundIdents.ts
|
|
43
|
+
/**
|
|
44
|
+
* Find unbound package references in library sources.
|
|
45
|
+
*
|
|
46
|
+
* Binds local references without following cross-package imports, revealing
|
|
47
|
+
* which external packages are referenced but not resolved.
|
|
48
|
+
*
|
|
49
|
+
* @param resolver - Module resolver that supports batch operations
|
|
50
|
+
* @returns Array of unbound module paths, each as an array of path segments
|
|
51
|
+
* (e.g., [['foo', 'bar', 'baz'], ['other', 'pkg']])
|
|
52
|
+
*/
|
|
53
|
+
function findUnboundIdents(resolver) {
|
|
54
|
+
const bindContext = {
|
|
55
|
+
resolver,
|
|
56
|
+
conditions: {},
|
|
57
|
+
knownDecls: /* @__PURE__ */ new Set(),
|
|
58
|
+
foundScopes: /* @__PURE__ */ new Set(),
|
|
59
|
+
globalNames: /* @__PURE__ */ new Set(),
|
|
60
|
+
globalStatements: /* @__PURE__ */ new Map(),
|
|
61
|
+
mangler: minimalMangle,
|
|
62
|
+
unbound: [],
|
|
63
|
+
dontFollowDecls: true
|
|
64
|
+
};
|
|
65
|
+
for (const [_modulePath, ast] of resolver.allModules()) {
|
|
66
|
+
const declEntries = findValidRootDecls(ast.rootScope, {}).map((d) => [d.originalName, d]);
|
|
67
|
+
const liveDecls = {
|
|
68
|
+
decls: new Map(declEntries),
|
|
69
|
+
parent: null
|
|
70
|
+
};
|
|
71
|
+
bindIdentsRecursive(ast.rootScope, bindContext, liveDecls, true);
|
|
72
|
+
}
|
|
73
|
+
return bindContext.unbound;
|
|
74
|
+
}
|
|
75
|
+
|
|
41
76
|
//#endregion
|
|
42
77
|
//#region ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
43
78
|
const balanced = (a, b, str) => {
|
|
@@ -373,7 +408,7 @@ const parseClass = (glob$1, position) => {
|
|
|
373
408
|
* Slashes (and backslashes in `windowsPathsNoEscape` mode) cannot be escaped
|
|
374
409
|
* or unescaped.
|
|
375
410
|
*/
|
|
376
|
-
const unescape
|
|
411
|
+
const unescape = (s, { windowsPathsNoEscape = false } = {}) => {
|
|
377
412
|
return windowsPathsNoEscape ? s.replace(/\[([^\/\\])\]/g, "$1") : s.replace(/((?!\\).|^)\[([^\/\\])\]/g, "$1$2").replace(/\\([^\/])/g, "$1");
|
|
378
413
|
};
|
|
379
414
|
|
|
@@ -504,7 +539,7 @@ var AST = class AST {
|
|
|
504
539
|
for (const p of this.#parts) c.copyIn(p);
|
|
505
540
|
return c;
|
|
506
541
|
}
|
|
507
|
-
static #parseAST(str, ast, pos, opt
|
|
542
|
+
static #parseAST(str, ast, pos, opt) {
|
|
508
543
|
let escaping = false;
|
|
509
544
|
let inBrace = false;
|
|
510
545
|
let braceStart = -1;
|
|
@@ -532,11 +567,11 @@ var AST = class AST {
|
|
|
532
567
|
acc$1 += c;
|
|
533
568
|
continue;
|
|
534
569
|
}
|
|
535
|
-
if (!opt
|
|
570
|
+
if (!opt.noext && isExtglobType(c) && str.charAt(i$1) === "(") {
|
|
536
571
|
ast.push(acc$1);
|
|
537
572
|
acc$1 = "";
|
|
538
573
|
const ext$1 = new AST(c, ast);
|
|
539
|
-
i$1 = AST.#parseAST(str, ext$1, i$1, opt
|
|
574
|
+
i$1 = AST.#parseAST(str, ext$1, i$1, opt);
|
|
540
575
|
ast.push(ext$1);
|
|
541
576
|
continue;
|
|
542
577
|
}
|
|
@@ -574,7 +609,7 @@ var AST = class AST {
|
|
|
574
609
|
acc = "";
|
|
575
610
|
const ext$1 = new AST(c, part);
|
|
576
611
|
part.push(ext$1);
|
|
577
|
-
i = AST.#parseAST(str, ext$1, i, opt
|
|
612
|
+
i = AST.#parseAST(str, ext$1, i, opt);
|
|
578
613
|
continue;
|
|
579
614
|
}
|
|
580
615
|
if (c === "|") {
|
|
@@ -645,7 +680,7 @@ var AST = class AST {
|
|
|
645
680
|
if (this.isEnd() && this.#root.#filledNegs && this.#parent?.type === "!") end = "(?:$|\\/)";
|
|
646
681
|
return [
|
|
647
682
|
start$1 + src + end,
|
|
648
|
-
unescape
|
|
683
|
+
unescape(src),
|
|
649
684
|
this.#hasMagic = !!this.#hasMagic,
|
|
650
685
|
this.#uflag
|
|
651
686
|
];
|
|
@@ -660,7 +695,7 @@ var AST = class AST {
|
|
|
660
695
|
this.#hasMagic = void 0;
|
|
661
696
|
return [
|
|
662
697
|
s,
|
|
663
|
-
unescape
|
|
698
|
+
unescape(this.toString()),
|
|
664
699
|
false,
|
|
665
700
|
false
|
|
666
701
|
];
|
|
@@ -676,7 +711,7 @@ var AST = class AST {
|
|
|
676
711
|
}
|
|
677
712
|
return [
|
|
678
713
|
final,
|
|
679
|
-
unescape
|
|
714
|
+
unescape(body),
|
|
680
715
|
this.#hasMagic = !!this.#hasMagic,
|
|
681
716
|
this.#uflag
|
|
682
717
|
];
|
|
@@ -732,7 +767,7 @@ var AST = class AST {
|
|
|
732
767
|
}
|
|
733
768
|
return [
|
|
734
769
|
re,
|
|
735
|
-
unescape
|
|
770
|
+
unescape(glob$1),
|
|
736
771
|
!!hasMagic$1,
|
|
737
772
|
uflag
|
|
738
773
|
];
|
|
@@ -1319,7 +1354,7 @@ var Minimatch = class {
|
|
|
1319
1354
|
minimatch.AST = AST;
|
|
1320
1355
|
minimatch.Minimatch = Minimatch;
|
|
1321
1356
|
minimatch.escape = escape;
|
|
1322
|
-
minimatch.unescape = unescape
|
|
1357
|
+
minimatch.unescape = unescape;
|
|
1323
1358
|
|
|
1324
1359
|
//#endregion
|
|
1325
1360
|
//#region ../../node_modules/.pnpm/lru-cache@11.2.2/node_modules/lru-cache/dist/esm/index.js
|
|
@@ -1331,8 +1366,8 @@ const warned = /* @__PURE__ */ new Set();
|
|
|
1331
1366
|
/* c8 ignore start */
|
|
1332
1367
|
const PROCESS = typeof process === "object" && !!process ? process : {};
|
|
1333
1368
|
/* c8 ignore start */
|
|
1334
|
-
const emitWarning = (msg, type, code, fn
|
|
1335
|
-
typeof PROCESS.emitWarning === "function" ? PROCESS.emitWarning(msg, type, code, fn
|
|
1369
|
+
const emitWarning = (msg, type, code, fn) => {
|
|
1370
|
+
typeof PROCESS.emitWarning === "function" ? PROCESS.emitWarning(msg, type, code, fn) : console.error(`[${code}] ${type}: ${msg}`);
|
|
1336
1371
|
};
|
|
1337
1372
|
let AC = globalThis.AbortController;
|
|
1338
1373
|
let AS = globalThis.AbortSignal;
|
|
@@ -1343,8 +1378,8 @@ if (typeof AC === "undefined") {
|
|
|
1343
1378
|
_onabort = [];
|
|
1344
1379
|
reason;
|
|
1345
1380
|
aborted = false;
|
|
1346
|
-
addEventListener(_, fn
|
|
1347
|
-
this._onabort.push(fn
|
|
1381
|
+
addEventListener(_, fn) {
|
|
1382
|
+
this._onabort.push(fn);
|
|
1348
1383
|
}
|
|
1349
1384
|
};
|
|
1350
1385
|
AC = class AbortController {
|
|
@@ -1356,7 +1391,7 @@ if (typeof AC === "undefined") {
|
|
|
1356
1391
|
if (this.signal.aborted) return;
|
|
1357
1392
|
this.signal.reason = reason;
|
|
1358
1393
|
this.signal.aborted = true;
|
|
1359
|
-
for (const fn
|
|
1394
|
+
for (const fn of this.signal._onabort) fn(reason);
|
|
1360
1395
|
this.signal.onabort?.(reason);
|
|
1361
1396
|
}
|
|
1362
1397
|
};
|
|
@@ -1869,12 +1904,12 @@ var LRUCache = class LRUCache {
|
|
|
1869
1904
|
* Find a value for which the supplied fn method returns a truthy value,
|
|
1870
1905
|
* similar to `Array.find()`. fn is called as `fn(value, key, cache)`.
|
|
1871
1906
|
*/
|
|
1872
|
-
find(fn
|
|
1907
|
+
find(fn, getOptions = {}) {
|
|
1873
1908
|
for (const i of this.#indexes()) {
|
|
1874
1909
|
const v = this.#valList[i];
|
|
1875
1910
|
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
1876
1911
|
if (value === void 0) continue;
|
|
1877
|
-
if (fn
|
|
1912
|
+
if (fn(value, this.#keyList[i], this)) return this.get(this.#keyList[i], getOptions);
|
|
1878
1913
|
}
|
|
1879
1914
|
}
|
|
1880
1915
|
/**
|
|
@@ -1888,24 +1923,24 @@ var LRUCache = class LRUCache {
|
|
|
1888
1923
|
*
|
|
1889
1924
|
* Does not update age or recenty of use, or iterate over stale values.
|
|
1890
1925
|
*/
|
|
1891
|
-
forEach(fn
|
|
1926
|
+
forEach(fn, thisp = this) {
|
|
1892
1927
|
for (const i of this.#indexes()) {
|
|
1893
1928
|
const v = this.#valList[i];
|
|
1894
1929
|
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
1895
1930
|
if (value === void 0) continue;
|
|
1896
|
-
fn
|
|
1931
|
+
fn.call(thisp, value, this.#keyList[i], this);
|
|
1897
1932
|
}
|
|
1898
1933
|
}
|
|
1899
1934
|
/**
|
|
1900
1935
|
* The same as {@link LRUCache.forEach} but items are iterated over in
|
|
1901
1936
|
* reverse order. (ie, less recently used items are iterated over first.)
|
|
1902
1937
|
*/
|
|
1903
|
-
rforEach(fn
|
|
1938
|
+
rforEach(fn, thisp = this) {
|
|
1904
1939
|
for (const i of this.#rindexes()) {
|
|
1905
1940
|
const v = this.#valList[i];
|
|
1906
1941
|
const value = this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;
|
|
1907
1942
|
if (value === void 0) continue;
|
|
1908
|
-
fn
|
|
1943
|
+
fn.call(thisp, value, this.#keyList[i], this);
|
|
1909
1944
|
}
|
|
1910
1945
|
}
|
|
1911
1946
|
/**
|
|
@@ -2552,8 +2587,8 @@ const ABORTED = Symbol("aborted");
|
|
|
2552
2587
|
const SIGNAL = Symbol("signal");
|
|
2553
2588
|
const DATALISTENERS = Symbol("dataListeners");
|
|
2554
2589
|
const DISCARDED = Symbol("discarded");
|
|
2555
|
-
const defer = (fn
|
|
2556
|
-
const nodefer = (fn
|
|
2590
|
+
const defer = (fn) => Promise.resolve().then(fn);
|
|
2591
|
+
const nodefer = (fn) => fn();
|
|
2557
2592
|
const isEndish = (ev) => ev === "end" || ev === "finish" || ev === "prefinish";
|
|
2558
2593
|
const isArrayBufferLike = (b) => b instanceof ArrayBuffer || !!b && typeof b === "object" && b.constructor && b.constructor.name === "ArrayBuffer" && b.byteLength >= 0;
|
|
2559
2594
|
const isArrayBufferView = (b) => !Buffer.isBuffer(b) && ArrayBuffer.isView(b);
|
|
@@ -2760,7 +2795,7 @@ var Minipass = class extends EventEmitter {
|
|
|
2760
2795
|
encoding = "utf8";
|
|
2761
2796
|
}
|
|
2762
2797
|
if (!encoding) encoding = "utf8";
|
|
2763
|
-
const fn
|
|
2798
|
+
const fn = this[ASYNC] ? defer : nodefer;
|
|
2764
2799
|
if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) {
|
|
2765
2800
|
if (isArrayBufferView(chunk)) chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
2766
2801
|
else if (isArrayBufferLike(chunk)) chunk = Buffer.from(chunk);
|
|
@@ -2773,12 +2808,12 @@ var Minipass = class extends EventEmitter {
|
|
|
2773
2808
|
if (this[FLOWING]) this.emit("data", chunk);
|
|
2774
2809
|
else this[BUFFERPUSH](chunk);
|
|
2775
2810
|
if (this[BUFFERLENGTH] !== 0) this.emit("readable");
|
|
2776
|
-
if (cb) fn
|
|
2811
|
+
if (cb) fn(cb);
|
|
2777
2812
|
return this[FLOWING];
|
|
2778
2813
|
}
|
|
2779
2814
|
if (!chunk.length) {
|
|
2780
2815
|
if (this[BUFFERLENGTH] !== 0) this.emit("readable");
|
|
2781
|
-
if (cb) fn
|
|
2816
|
+
if (cb) fn(cb);
|
|
2782
2817
|
return this[FLOWING];
|
|
2783
2818
|
}
|
|
2784
2819
|
if (typeof chunk === "string" && !(encoding === this[ENCODING] && !this[DECODER]?.lastNeed)) chunk = Buffer.from(chunk, encoding);
|
|
@@ -2787,7 +2822,7 @@ var Minipass = class extends EventEmitter {
|
|
|
2787
2822
|
if (this[FLOWING]) this.emit("data", chunk);
|
|
2788
2823
|
else this[BUFFERPUSH](chunk);
|
|
2789
2824
|
if (this[BUFFERLENGTH] !== 0) this.emit("readable");
|
|
2790
|
-
if (cb) fn
|
|
2825
|
+
if (cb) fn(cb);
|
|
2791
2826
|
return this[FLOWING];
|
|
2792
2827
|
}
|
|
2793
2828
|
/**
|
|
@@ -3367,7 +3402,7 @@ const ENOCHILD = ENOENT | 576;
|
|
|
3367
3402
|
const TYPEMASK = 1023;
|
|
3368
3403
|
const entToType = (s) => s.isFile() ? IFREG : s.isDirectory() ? IFDIR : s.isSymbolicLink() ? IFLNK : s.isCharacterDevice() ? IFCHR : s.isBlockDevice() ? IFBLK : s.isSocket() ? IFSOCK : s.isFIFO() ? IFIFO : UNKNOWN;
|
|
3369
3404
|
const normalizeCache = /* @__PURE__ */ new Map();
|
|
3370
|
-
const normalize
|
|
3405
|
+
const normalize = (s) => {
|
|
3371
3406
|
const c = normalizeCache.get(s);
|
|
3372
3407
|
if (c) return c;
|
|
3373
3408
|
const n = s.normalize("NFKD");
|
|
@@ -3378,7 +3413,7 @@ const normalizeNocaseCache = /* @__PURE__ */ new Map();
|
|
|
3378
3413
|
const normalizeNocase = (s) => {
|
|
3379
3414
|
const c = normalizeNocaseCache.get(s);
|
|
3380
3415
|
if (c) return c;
|
|
3381
|
-
const n = normalize
|
|
3416
|
+
const n = normalize(s.toLowerCase());
|
|
3382
3417
|
normalizeNocaseCache.set(s, n);
|
|
3383
3418
|
return n;
|
|
3384
3419
|
};
|
|
@@ -3563,9 +3598,9 @@ var PathBase = class {
|
|
|
3563
3598
|
*
|
|
3564
3599
|
* @internal
|
|
3565
3600
|
*/
|
|
3566
|
-
constructor(name
|
|
3567
|
-
this.name = name
|
|
3568
|
-
this.#matchName = nocase ? normalizeNocase(name
|
|
3601
|
+
constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
|
|
3602
|
+
this.name = name;
|
|
3603
|
+
this.#matchName = nocase ? normalizeNocase(name) : normalize(name);
|
|
3569
3604
|
this.#type = type & TYPEMASK;
|
|
3570
3605
|
this.nocase = nocase;
|
|
3571
3606
|
this.roots = roots;
|
|
@@ -3641,8 +3676,8 @@ var PathBase = class {
|
|
|
3641
3676
|
if (pathPart === "" || pathPart === ".") return this;
|
|
3642
3677
|
if (pathPart === "..") return this.parent || this;
|
|
3643
3678
|
const children = this.children();
|
|
3644
|
-
const name
|
|
3645
|
-
for (const p of children) if (p.#matchName === name
|
|
3679
|
+
const name = this.nocase ? normalizeNocase(pathPart) : normalize(pathPart);
|
|
3680
|
+
for (const p of children) if (p.#matchName === name) return p;
|
|
3646
3681
|
const s = this.parent ? this.sep : "";
|
|
3647
3682
|
const fullpath = this.#fullpath ? this.#fullpath + s + pathPart : void 0;
|
|
3648
3683
|
const pchild = this.newChild(pathPart, UNKNOWN, {
|
|
@@ -3661,11 +3696,11 @@ var PathBase = class {
|
|
|
3661
3696
|
relative() {
|
|
3662
3697
|
if (this.isCWD) return "";
|
|
3663
3698
|
if (this.#relative !== void 0) return this.#relative;
|
|
3664
|
-
const name
|
|
3699
|
+
const name = this.name;
|
|
3665
3700
|
const p = this.parent;
|
|
3666
3701
|
if (!p) return this.#relative = this.name;
|
|
3667
3702
|
const pv = p.relative();
|
|
3668
|
-
return pv + (!pv || !p.parent ? "" : this.sep) + name
|
|
3703
|
+
return pv + (!pv || !p.parent ? "" : this.sep) + name;
|
|
3669
3704
|
}
|
|
3670
3705
|
/**
|
|
3671
3706
|
* The relative path from the cwd, using / as the path separator.
|
|
@@ -3677,21 +3712,21 @@ var PathBase = class {
|
|
|
3677
3712
|
if (this.sep === "/") return this.relative();
|
|
3678
3713
|
if (this.isCWD) return "";
|
|
3679
3714
|
if (this.#relativePosix !== void 0) return this.#relativePosix;
|
|
3680
|
-
const name
|
|
3715
|
+
const name = this.name;
|
|
3681
3716
|
const p = this.parent;
|
|
3682
3717
|
if (!p) return this.#relativePosix = this.fullpathPosix();
|
|
3683
3718
|
const pv = p.relativePosix();
|
|
3684
|
-
return pv + (!pv || !p.parent ? "" : "/") + name
|
|
3719
|
+
return pv + (!pv || !p.parent ? "" : "/") + name;
|
|
3685
3720
|
}
|
|
3686
3721
|
/**
|
|
3687
3722
|
* The fully resolved path string for this Path entry
|
|
3688
3723
|
*/
|
|
3689
3724
|
fullpath() {
|
|
3690
3725
|
if (this.#fullpath !== void 0) return this.#fullpath;
|
|
3691
|
-
const name
|
|
3726
|
+
const name = this.name;
|
|
3692
3727
|
const p = this.parent;
|
|
3693
3728
|
if (!p) return this.#fullpath = this.name;
|
|
3694
|
-
return this.#fullpath = p.fullpath() + (!p.parent ? "" : this.sep) + name
|
|
3729
|
+
return this.#fullpath = p.fullpath() + (!p.parent ? "" : this.sep) + name;
|
|
3695
3730
|
}
|
|
3696
3731
|
/**
|
|
3697
3732
|
* On platforms other than windows, this is identical to fullpath.
|
|
@@ -3854,7 +3889,7 @@ var PathBase = class {
|
|
|
3854
3889
|
* directly.
|
|
3855
3890
|
*/
|
|
3856
3891
|
isNamed(n) {
|
|
3857
|
-
return !this.nocase ? this.#matchName === normalize
|
|
3892
|
+
return !this.nocase ? this.#matchName === normalize(n) : this.#matchName === normalizeNocase(n);
|
|
3858
3893
|
}
|
|
3859
3894
|
/**
|
|
3860
3895
|
* Return the Path object corresponding to the target of a symbolic link.
|
|
@@ -3966,7 +4001,7 @@ var PathBase = class {
|
|
|
3966
4001
|
#readdirMaybePromoteChild(e, c) {
|
|
3967
4002
|
for (let p = c.provisional; p < c.length; p++) {
|
|
3968
4003
|
const pchild = c[p];
|
|
3969
|
-
if ((this.nocase ? normalizeNocase(e.name) : normalize
|
|
4004
|
+
if ((this.nocase ? normalizeNocase(e.name) : normalize(e.name)) !== pchild.#matchName) continue;
|
|
3970
4005
|
return this.#readdirPromoteChild(e, pchild, p, c);
|
|
3971
4006
|
}
|
|
3972
4007
|
}
|
|
@@ -4234,14 +4269,14 @@ var PathWin32 = class PathWin32 extends PathBase {
|
|
|
4234
4269
|
*
|
|
4235
4270
|
* @internal
|
|
4236
4271
|
*/
|
|
4237
|
-
constructor(name
|
|
4238
|
-
super(name
|
|
4272
|
+
constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
|
|
4273
|
+
super(name, type, root, roots, nocase, children, opts);
|
|
4239
4274
|
}
|
|
4240
4275
|
/**
|
|
4241
4276
|
* @internal
|
|
4242
4277
|
*/
|
|
4243
|
-
newChild(name
|
|
4244
|
-
return new PathWin32(name
|
|
4278
|
+
newChild(name, type = UNKNOWN, opts = {}) {
|
|
4279
|
+
return new PathWin32(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);
|
|
4245
4280
|
}
|
|
4246
4281
|
/**
|
|
4247
4282
|
* @internal
|
|
@@ -4286,8 +4321,8 @@ var PathPosix = class PathPosix extends PathBase {
|
|
|
4286
4321
|
*
|
|
4287
4322
|
* @internal
|
|
4288
4323
|
*/
|
|
4289
|
-
constructor(name
|
|
4290
|
-
super(name
|
|
4324
|
+
constructor(name, type = UNKNOWN, root, roots, nocase, children, opts) {
|
|
4325
|
+
super(name, type, root, roots, nocase, children, opts);
|
|
4291
4326
|
}
|
|
4292
4327
|
/**
|
|
4293
4328
|
* @internal
|
|
@@ -4304,8 +4339,8 @@ var PathPosix = class PathPosix extends PathBase {
|
|
|
4304
4339
|
/**
|
|
4305
4340
|
* @internal
|
|
4306
4341
|
*/
|
|
4307
|
-
newChild(name
|
|
4308
|
-
return new PathPosix(name
|
|
4342
|
+
newChild(name, type = UNKNOWN, opts = {}) {
|
|
4343
|
+
return new PathPosix(name, type, this.root, this.roots, this.nocase, this.childrenCache(), opts);
|
|
4309
4344
|
}
|
|
4310
4345
|
};
|
|
4311
4346
|
/**
|
|
@@ -5365,16 +5400,16 @@ var GlobUtil = class {
|
|
|
5365
5400
|
if (this.signal?.aborted) return;
|
|
5366
5401
|
/* c8 ignore stop */
|
|
5367
5402
|
this.paused = false;
|
|
5368
|
-
let fn
|
|
5369
|
-
while (!this.paused && (fn
|
|
5403
|
+
let fn = void 0;
|
|
5404
|
+
while (!this.paused && (fn = this.#onResume.shift())) fn();
|
|
5370
5405
|
}
|
|
5371
|
-
onResume(fn
|
|
5406
|
+
onResume(fn) {
|
|
5372
5407
|
if (this.signal?.aborted) return;
|
|
5373
5408
|
/* c8 ignore start */
|
|
5374
|
-
if (!this.paused) fn
|
|
5409
|
+
if (!this.paused) fn();
|
|
5375
5410
|
else
|
|
5376
5411
|
/* c8 ignore stop */
|
|
5377
|
-
this.#onResume.push(fn
|
|
5412
|
+
this.#onResume.push(fn);
|
|
5378
5413
|
}
|
|
5379
5414
|
async matchCheck(e, ifDir) {
|
|
5380
5415
|
if (ifDir && this.opts.nodir) return void 0;
|
|
@@ -5840,7 +5875,7 @@ const glob = Object.assign(glob_, {
|
|
|
5840
5875
|
Glob,
|
|
5841
5876
|
hasMagic,
|
|
5842
5877
|
escape,
|
|
5843
|
-
unescape
|
|
5878
|
+
unescape
|
|
5844
5879
|
});
|
|
5845
5880
|
glob.glob = glob;
|
|
5846
5881
|
|
|
@@ -5883,16 +5918,16 @@ var require_parser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/toml
|
|
|
5883
5918
|
type: "literal",
|
|
5884
5919
|
value: "]",
|
|
5885
5920
|
description: "\"]\""
|
|
5886
|
-
}, peg$c11 = function(name
|
|
5887
|
-
addNode(node("ObjectPath", name
|
|
5888
|
-
}, peg$c12 = function(name
|
|
5889
|
-
addNode(node("ArrayPath", name
|
|
5890
|
-
}, peg$c13 = function(parts, name
|
|
5891
|
-
return parts.concat(name
|
|
5892
|
-
}, peg$c14 = function(name
|
|
5893
|
-
return [name
|
|
5894
|
-
}, peg$c15 = function(name
|
|
5895
|
-
return name
|
|
5921
|
+
}, peg$c11 = function(name) {
|
|
5922
|
+
addNode(node("ObjectPath", name, line, column));
|
|
5923
|
+
}, peg$c12 = function(name) {
|
|
5924
|
+
addNode(node("ArrayPath", name, line, column));
|
|
5925
|
+
}, peg$c13 = function(parts, name) {
|
|
5926
|
+
return parts.concat(name);
|
|
5927
|
+
}, peg$c14 = function(name) {
|
|
5928
|
+
return [name];
|
|
5929
|
+
}, peg$c15 = function(name) {
|
|
5930
|
+
return name;
|
|
5896
5931
|
}, peg$c16 = ".", peg$c17 = {
|
|
5897
5932
|
type: "literal",
|
|
5898
5933
|
value: ".",
|
|
@@ -5945,8 +5980,8 @@ var require_parser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/toml
|
|
|
5945
5980
|
description: "\"E\""
|
|
5946
5981
|
}, peg$c42 = function(left, right) {
|
|
5947
5982
|
return node("Float", parseFloat(left + "e" + right), line, column);
|
|
5948
|
-
}, peg$c43 = function(text
|
|
5949
|
-
return node("Float", parseFloat(text
|
|
5983
|
+
}, peg$c43 = function(text) {
|
|
5984
|
+
return node("Float", parseFloat(text), line, column);
|
|
5950
5985
|
}, peg$c44 = "+", peg$c45 = {
|
|
5951
5986
|
type: "literal",
|
|
5952
5987
|
value: "+",
|
|
@@ -5959,8 +5994,8 @@ var require_parser = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/toml
|
|
|
5959
5994
|
description: "\"-\""
|
|
5960
5995
|
}, peg$c49 = function(digits) {
|
|
5961
5996
|
return "-" + digits.join("");
|
|
5962
|
-
}, peg$c50 = function(text
|
|
5963
|
-
return node("Integer", parseInt(text
|
|
5997
|
+
}, peg$c50 = function(text) {
|
|
5998
|
+
return node("Integer", parseInt(text, 10), line, column);
|
|
5964
5999
|
}, peg$c51 = "true", peg$c52 = {
|
|
5965
6000
|
type: "literal",
|
|
5966
6001
|
value: "true",
|
|
@@ -9627,9 +9662,10 @@ var require_toml = /* @__PURE__ */ __commonJS({ "../../node_modules/.pnpm/toml@3
|
|
|
9627
9662
|
var import_toml = /* @__PURE__ */ __toESM(require_toml(), 1);
|
|
9628
9663
|
/** Default configuration when no wesl.toml is found */
|
|
9629
9664
|
const defaultWeslToml = {
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9665
|
+
edition: "unstable_2025",
|
|
9666
|
+
include: ["shaders/**/*.w[eg]sl"],
|
|
9667
|
+
root: "shaders",
|
|
9668
|
+
dependencies: "auto"
|
|
9633
9669
|
};
|
|
9634
9670
|
/**
|
|
9635
9671
|
* Load and parse a wesl.toml file from the fs.
|
|
@@ -9668,13 +9704,13 @@ async function findWeslToml(projectDir, specifiedToml) {
|
|
|
9668
9704
|
parsedToml = defaultWeslToml;
|
|
9669
9705
|
tomlDir = projectDir;
|
|
9670
9706
|
}
|
|
9671
|
-
const tomlToWeslRoot = path.resolve(tomlDir, parsedToml.
|
|
9707
|
+
const tomlToWeslRoot = path.resolve(tomlDir, parsedToml.root);
|
|
9672
9708
|
const projectDirAbs = path.resolve(projectDir);
|
|
9673
|
-
const
|
|
9709
|
+
const resolvedRoot = path.relative(projectDirAbs, tomlToWeslRoot);
|
|
9674
9710
|
return {
|
|
9675
9711
|
tomlFile,
|
|
9676
9712
|
tomlDir,
|
|
9677
|
-
|
|
9713
|
+
resolvedRoot,
|
|
9678
9714
|
toml: parsedToml
|
|
9679
9715
|
};
|
|
9680
9716
|
}
|
|
@@ -9697,8 +9733,8 @@ async function loadModules(projectDir, baseDir, srcGlob) {
|
|
|
9697
9733
|
let resolvedSrcGlob;
|
|
9698
9734
|
if (!baseDir || !srcGlob) {
|
|
9699
9735
|
const tomlInfo = await findWeslToml(projectDir);
|
|
9700
|
-
resolvedBaseDir = baseDir ?? tomlInfo.
|
|
9701
|
-
resolvedSrcGlob = srcGlob ?? tomlInfo.toml.
|
|
9736
|
+
resolvedBaseDir = baseDir ?? tomlInfo.resolvedRoot;
|
|
9737
|
+
resolvedSrcGlob = srcGlob ?? tomlInfo.toml.include[0];
|
|
9702
9738
|
} else {
|
|
9703
9739
|
resolvedBaseDir = baseDir;
|
|
9704
9740
|
resolvedSrcGlob = srcGlob;
|
|
@@ -9721,48 +9757,48 @@ function zip(as, bs) {
|
|
|
9721
9757
|
//#endregion
|
|
9722
9758
|
//#region ../wesl-tooling/src/ParseDependencies.ts
|
|
9723
9759
|
/**
|
|
9724
|
-
* Find
|
|
9725
|
-
*
|
|
9760
|
+
* Find package dependencies in WESL source files.
|
|
9761
|
+
*
|
|
9762
|
+
* Parses sources and partially binds identifiers to reveal unresolved package
|
|
9763
|
+
* references. Returns the longest resolvable npm subpath for each dependency.
|
|
9726
9764
|
*
|
|
9727
|
-
*
|
|
9728
|
-
*
|
|
9729
|
-
*
|
|
9765
|
+
* For example, 'foo::bar::baz' could resolve to:
|
|
9766
|
+
* - 'foo/bar' (package foo, export './bar' bundle)
|
|
9767
|
+
* - 'foo' (package foo, default export)
|
|
9730
9768
|
*
|
|
9731
|
-
*
|
|
9732
|
-
*
|
|
9733
|
-
*
|
|
9734
|
-
* . package foo, export './bar' bundle, element baz
|
|
9735
|
-
* . package foo, export './bar/baz' bundle, module lib.wesl, element baz
|
|
9736
|
-
* To distinguish these, we node resolve the longest path we can.
|
|
9769
|
+
* @param weslSrc - Record of WESL source files by path
|
|
9770
|
+
* @param projectDir - Project directory for resolving package imports
|
|
9771
|
+
* @returns Dependency paths in npm format (e.g., 'foo/bar', 'foo')
|
|
9737
9772
|
*/
|
|
9738
9773
|
function parseDependencies(weslSrc, projectDir) {
|
|
9739
|
-
|
|
9774
|
+
let resolver;
|
|
9740
9775
|
try {
|
|
9741
|
-
|
|
9776
|
+
resolver = new RecordResolver(weslSrc);
|
|
9742
9777
|
} catch (e) {
|
|
9743
|
-
if (e.cause instanceof WeslParseError)
|
|
9744
|
-
|
|
9778
|
+
if (e.cause instanceof WeslParseError) {
|
|
9779
|
+
console.error(e.message, "\n");
|
|
9780
|
+
return [];
|
|
9781
|
+
}
|
|
9782
|
+
throw e;
|
|
9745
9783
|
}
|
|
9746
|
-
const unbound = findUnboundIdents(
|
|
9784
|
+
const unbound = findUnboundIdents(resolver);
|
|
9747
9785
|
if (!unbound) return [];
|
|
9748
9786
|
const pkgRefs = unbound.filter((modulePath) => modulePath.length > 1 && modulePath[0] !== "constants");
|
|
9749
9787
|
if (pkgRefs.length === 0) return [];
|
|
9750
|
-
const projectURL =
|
|
9788
|
+
const projectURL = projectDirURL(projectDir);
|
|
9751
9789
|
const deps = filterMap(pkgRefs, (mPath) => unboundToDependency(mPath, projectURL));
|
|
9752
9790
|
return [...new Set(deps)];
|
|
9753
9791
|
}
|
|
9754
|
-
/**
|
|
9755
|
-
* Find the longest resolvable npm subpath from a module path.
|
|
9792
|
+
/** Find longest resolvable npm subpath from module path segments.
|
|
9756
9793
|
*
|
|
9757
|
-
* @param mPath
|
|
9758
|
-
* @param importerURL URL
|
|
9759
|
-
* @returns
|
|
9794
|
+
* @param mPath - Module path segments (e.g., ['foo', 'bar', 'baz', 'elem'])
|
|
9795
|
+
* @param importerURL - Base URL for resolution (e.g., 'file:///path/to/project/')
|
|
9796
|
+
* @returns Longest resolvable subpath (e.g., 'foo/bar/baz' or 'foo')
|
|
9760
9797
|
*/
|
|
9761
9798
|
function unboundToDependency(mPath, importerURL) {
|
|
9762
9799
|
return [...exportSubpaths(mPath)].find((subPath) => tryResolve(subPath, importerURL));
|
|
9763
9800
|
}
|
|
9764
|
-
/** Try
|
|
9765
|
-
* @return the resolved path */
|
|
9801
|
+
/** Try Node.js module resolution; returns undefined if unresolvable. */
|
|
9766
9802
|
function tryResolve(path$2, importerURL) {
|
|
9767
9803
|
try {
|
|
9768
9804
|
return resolve(path$2, importerURL);
|
|
@@ -9770,1435 +9806,60 @@ function tryResolve(path$2, importerURL) {
|
|
|
9770
9806
|
return;
|
|
9771
9807
|
}
|
|
9772
9808
|
}
|
|
9773
|
-
/**
|
|
9774
|
-
*
|
|
9775
|
-
* longest subpath first.
|
|
9776
|
-
*/
|
|
9809
|
+
/** Yield possible export subpaths from module path, longest first.
|
|
9810
|
+
* Drops the last segment (element name) and iterates down. */
|
|
9777
9811
|
function* exportSubpaths(mPath) {
|
|
9778
9812
|
const longest = mPath.length - 1;
|
|
9779
9813
|
for (let i = longest; i >= 0; i--) yield mPath.slice(0, i).join("/");
|
|
9780
9814
|
}
|
|
9781
|
-
/**
|
|
9815
|
+
/**
|
|
9816
|
+
* Load WeslBundle instances referenced by WESL sources.
|
|
9782
9817
|
*
|
|
9783
|
-
*
|
|
9784
|
-
*
|
|
9818
|
+
* Parses sources to find external module references, then dynamically imports
|
|
9819
|
+
* the corresponding weslBundle.js files.
|
|
9820
|
+
*
|
|
9821
|
+
* @param weslSrc - Record of WESL source files by path
|
|
9822
|
+
* @param projectDir - Project directory for resolving imports
|
|
9823
|
+
* @param packageName - Optional current package name
|
|
9824
|
+
* @param includeCurrentPackage - Include current package in results (default: false)
|
|
9825
|
+
* @returns Loaded WeslBundle instances
|
|
9785
9826
|
*/
|
|
9786
|
-
async function dependencyBundles(weslSrc, projectDir) {
|
|
9827
|
+
async function dependencyBundles(weslSrc, projectDir, packageName, includeCurrentPackage = false) {
|
|
9787
9828
|
const deps = parseDependencies(weslSrc, projectDir);
|
|
9788
|
-
const
|
|
9789
|
-
const
|
|
9829
|
+
const filteredDeps = includeCurrentPackage ? deps : otherPackages(deps, packageName);
|
|
9830
|
+
const projectURL = projectDirURL(projectDir);
|
|
9831
|
+
const bundles = filteredDeps.map(async (dep) => {
|
|
9790
9832
|
return (await import(resolve(dep, projectURL))).default;
|
|
9791
9833
|
});
|
|
9792
9834
|
return await Promise.all(bundles);
|
|
9793
9835
|
}
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
* @param projectDir - e.g., file:// URL of the directory containing package.json
|
|
9799
|
-
* @returns the 'version' field from the package.json in the `projectDir`
|
|
9800
|
-
*/
|
|
9801
|
-
async function versionFromPackageJson(projectDir) {
|
|
9802
|
-
return (await import(new URL("./package.json", projectDir).href, { with: { type: "json" } })).default.version;
|
|
9803
|
-
}
|
|
9804
|
-
|
|
9805
|
-
//#endregion
|
|
9806
|
-
//#region ../wesl/src/Util.ts
|
|
9807
|
-
/**
|
|
9808
|
-
* Maps an character position in a string to a 1-indexed line number, and 1-indexed column.
|
|
9809
|
-
*/
|
|
9810
|
-
function offsetToLineNumber(offset, text$1) {
|
|
9811
|
-
const safeOffset = Math.min(text$1.length, Math.max(0, offset));
|
|
9812
|
-
let lineStartOffset = 0;
|
|
9813
|
-
let lineNum = 1;
|
|
9814
|
-
while (true) {
|
|
9815
|
-
const lineEnd = text$1.indexOf("\n", lineStartOffset);
|
|
9816
|
-
if (lineEnd === -1 || safeOffset <= lineEnd) {
|
|
9817
|
-
const linePos = 1 + (safeOffset - lineStartOffset);
|
|
9818
|
-
return [lineNum, linePos];
|
|
9819
|
-
} else {
|
|
9820
|
-
lineStartOffset = lineEnd + 1;
|
|
9821
|
-
lineNum += 1;
|
|
9822
|
-
}
|
|
9823
|
-
}
|
|
9824
|
-
}
|
|
9825
|
-
/** Highlights an error.
|
|
9826
|
-
*
|
|
9827
|
-
* Returns a string with the line, and a string with the ^^^^ carets
|
|
9828
|
-
*/
|
|
9829
|
-
function errorHighlight(source, span$1) {
|
|
9830
|
-
let lineStartOffset = source.lastIndexOf("\n", span$1[0]);
|
|
9831
|
-
if (lineStartOffset === -1) lineStartOffset = 0;
|
|
9832
|
-
let lineEndOffset = source.indexOf("\n", span$1[0]);
|
|
9833
|
-
if (lineEndOffset === -1) lineEndOffset = source.length;
|
|
9834
|
-
const errorLength = span$1[1] - span$1[0];
|
|
9835
|
-
const caretCount = Math.max(1, errorLength);
|
|
9836
|
-
const linePos = span$1[0] - lineStartOffset;
|
|
9837
|
-
return [source.slice(lineStartOffset, lineEndOffset), " ".repeat(linePos) + "^".repeat(caretCount)];
|
|
9838
|
-
}
|
|
9839
|
-
|
|
9840
|
-
//#endregion
|
|
9841
|
-
//#region ../wesl/src/vlq/vlq.ts
|
|
9842
|
-
/*!
|
|
9843
|
-
Copyright (c) 2017-2021 [these people](https://github.com/Rich-Harris/vlq/graphs/contributors)
|
|
9844
|
-
|
|
9845
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
9846
|
-
|
|
9847
|
-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9848
|
-
|
|
9849
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
9850
|
-
*/
|
|
9851
|
-
const char_to_integer = {};
|
|
9852
|
-
const integer_to_char = {};
|
|
9853
|
-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split("").forEach((char, i) => {
|
|
9854
|
-
char_to_integer[char] = i;
|
|
9855
|
-
integer_to_char[i] = char;
|
|
9856
|
-
});
|
|
9857
|
-
function encodeVlq(value) {
|
|
9858
|
-
if (typeof value === "number") return encode_integer(value);
|
|
9859
|
-
let result = "";
|
|
9860
|
-
for (let i = 0; i < value.length; i += 1) result += encode_integer(value[i]);
|
|
9861
|
-
return result;
|
|
9862
|
-
}
|
|
9863
|
-
function encode_integer(num) {
|
|
9864
|
-
let result = "";
|
|
9865
|
-
let enc;
|
|
9866
|
-
if (num < 0) enc = -num << 1 | 1;
|
|
9867
|
-
else enc = num << 1;
|
|
9868
|
-
do {
|
|
9869
|
-
let clamped = enc & 31;
|
|
9870
|
-
enc >>>= 5;
|
|
9871
|
-
if (enc > 0) clamped |= 32;
|
|
9872
|
-
result += integer_to_char[clamped];
|
|
9873
|
-
} while (enc > 0);
|
|
9874
|
-
return result;
|
|
9875
|
-
}
|
|
9876
|
-
|
|
9877
|
-
//#endregion
|
|
9878
|
-
//#region ../wesl/src/ClickableError.ts
|
|
9879
|
-
/** Throw an error with an embedded source map so that browser users can
|
|
9880
|
-
* click on the error in the browser debug console and see the wesl source code. */
|
|
9881
|
-
function throwClickableError(params) {
|
|
9882
|
-
const { url, text: text$1, lineNumber, lineColumn, length, error } = params;
|
|
9883
|
-
const mappings = encodeVlq([
|
|
9884
|
-
0,
|
|
9885
|
-
0,
|
|
9886
|
-
Math.max(0, lineNumber - 1),
|
|
9887
|
-
Math.max(0, lineColumn - 1)
|
|
9888
|
-
]) + "," + encodeVlq([
|
|
9889
|
-
18,
|
|
9890
|
-
0,
|
|
9891
|
-
Math.max(0, lineNumber - 1),
|
|
9892
|
-
Math.max(0, lineColumn - 1) + length
|
|
9893
|
-
]);
|
|
9894
|
-
const sourceMap = {
|
|
9895
|
-
version: 3,
|
|
9896
|
-
file: null,
|
|
9897
|
-
sources: [url],
|
|
9898
|
-
sourcesContent: [text$1 ?? null],
|
|
9899
|
-
names: [],
|
|
9900
|
-
mappings
|
|
9901
|
-
};
|
|
9902
|
-
let generatedCode = `throw new Error(${JSON.stringify(error.message + "")})`;
|
|
9903
|
-
generatedCode += "\n//# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
|
|
9904
|
-
generatedCode += "\n//# sourceURL=" + sourceMap.sources[0];
|
|
9905
|
-
let oldLimit = 0;
|
|
9906
|
-
if ("stackTraceLimit" in Error) {
|
|
9907
|
-
oldLimit = Error.stackTraceLimit;
|
|
9908
|
-
Error.stackTraceLimit = 1;
|
|
9909
|
-
}
|
|
9910
|
-
try {
|
|
9911
|
-
(0, eval)(generatedCode);
|
|
9912
|
-
} catch (e) {
|
|
9913
|
-
if ("stackTraceLimit" in Error) Error.stackTraceLimit = oldLimit;
|
|
9914
|
-
error.message = "";
|
|
9915
|
-
if (tracing) e.cause = error;
|
|
9916
|
-
throw e;
|
|
9917
|
-
}
|
|
9918
|
-
}
|
|
9919
|
-
|
|
9920
|
-
//#endregion
|
|
9921
|
-
//#region ../wesl/src/Assertions.ts
|
|
9922
|
-
/** checks whether a condition is true, otherwise throws */
|
|
9923
|
-
function assertThat(condition, msg) {
|
|
9924
|
-
if (!condition) throw new Error(msg);
|
|
9925
|
-
}
|
|
9926
|
-
/** when debug testing is enabled, checks whether a condition is true, otherwise throws */
|
|
9927
|
-
function assertThatDebug(condition, msg) {
|
|
9928
|
-
if (tracing) assertThat(condition, msg);
|
|
9929
|
-
}
|
|
9930
|
-
/**
|
|
9931
|
-
* Useful to validate that all cases are handled,
|
|
9932
|
-
* TypeScript should complain if this statement could possibly be executed.
|
|
9933
|
-
*
|
|
9934
|
-
* If this is somehow executed at runtime, throw an exception.
|
|
9935
|
-
*/
|
|
9936
|
-
function assertUnreachable(value) {
|
|
9937
|
-
throw new ErrorWithData("Unreachable value", { data: value });
|
|
9938
|
-
}
|
|
9939
|
-
var ErrorWithData = class extends Error {
|
|
9940
|
-
data;
|
|
9941
|
-
constructor(message, options) {
|
|
9942
|
-
super(message, options);
|
|
9943
|
-
this.data = options?.data;
|
|
9944
|
-
}
|
|
9945
|
-
};
|
|
9946
|
-
|
|
9947
|
-
//#endregion
|
|
9948
|
-
//#region ../wesl/src/Conditions.ts
|
|
9949
|
-
/** Extract @if, @elif, or @else attribute from an array of attributes */
|
|
9950
|
-
function findConditional(attributes) {
|
|
9951
|
-
if (!attributes) return;
|
|
9952
|
-
for (const attr of attributes) {
|
|
9953
|
-
const kind$1 = attr.attribute.kind;
|
|
9954
|
-
if (kind$1 === "@if" || kind$1 === "@elif" || kind$1 === "@else") return attr.attribute;
|
|
9955
|
-
}
|
|
9956
|
-
}
|
|
9957
|
-
|
|
9958
|
-
//#endregion
|
|
9959
|
-
//#region ../../node_modules/.pnpm/berry-pretty@0.0.5/node_modules/berry-pretty/dist/index.js
|
|
9960
|
-
var spaces = memoize((nesting) => {
|
|
9961
|
-
return " ".repeat(nesting);
|
|
9962
|
-
});
|
|
9963
|
-
var defaultCallerSize = 20;
|
|
9964
|
-
var multiLinePad = "\n" + spaces(defaultCallerSize + 3);
|
|
9965
|
-
function memoize(fn$1) {
|
|
9966
|
-
const cache = /* @__PURE__ */ new Map();
|
|
9967
|
-
return function(...args) {
|
|
9968
|
-
const key = JSON.stringify(args);
|
|
9969
|
-
if (cache.has(key)) return cache.get(key);
|
|
9970
|
-
else {
|
|
9971
|
-
const value = fn$1(...args);
|
|
9972
|
-
cache.set(key, value);
|
|
9973
|
-
return value;
|
|
9974
|
-
}
|
|
9975
|
-
};
|
|
9976
|
-
}
|
|
9977
|
-
if (typeof DOMRect === "undefined") globalThis.DOMRect = function() {};
|
|
9978
|
-
|
|
9979
|
-
//#endregion
|
|
9980
|
-
//#region ../wesl/src/Scope.ts
|
|
9981
|
-
/** Combine two scope siblings.
|
|
9982
|
-
* The first scope is mutated to append the contents of the second. */
|
|
9983
|
-
function mergeScope(a, b) {
|
|
9984
|
-
if (!b) return;
|
|
9985
|
-
assertThatDebug(a.kind === b.kind);
|
|
9986
|
-
assertThatDebug(a.parent === b.parent);
|
|
9987
|
-
assertThatDebug(!b.condAttribute);
|
|
9988
|
-
a.contents = a.contents.concat(b.contents);
|
|
9989
|
-
}
|
|
9990
|
-
/** reset scope and ident debugging ids */
|
|
9991
|
-
function resetScopeIds() {
|
|
9992
|
-
scopeId = 0;
|
|
9993
|
-
identId = 0;
|
|
9836
|
+
/** Exclude current package from dependency list. */
|
|
9837
|
+
function otherPackages(deps, packageName) {
|
|
9838
|
+
if (!packageName) return deps;
|
|
9839
|
+
return deps.filter((dep) => dep !== packageName && !dep.startsWith(`${packageName}/`));
|
|
9994
9840
|
}
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
}
|
|
10000
|
-
/** make a new Scope object */
|
|
10001
|
-
function emptyScope(parent, kind$1 = "scope") {
|
|
10002
|
-
return {
|
|
10003
|
-
id: scopeId++,
|
|
10004
|
-
kind: kind$1,
|
|
10005
|
-
parent,
|
|
10006
|
-
contents: []
|
|
10007
|
-
};
|
|
9841
|
+
/** Normalize project directory to file:// URL with trailing slash. */
|
|
9842
|
+
function projectDirURL(projectDir) {
|
|
9843
|
+
if (projectDir.startsWith("file://")) return projectDir.endsWith("/") ? projectDir : `${projectDir}/`;
|
|
9844
|
+
const fileUrl = pathToFileURL(projectDir).href;
|
|
9845
|
+
return fileUrl.endsWith("/") ? fileUrl : `${fileUrl}/`;
|
|
10008
9846
|
}
|
|
10009
9847
|
|
|
10010
9848
|
//#endregion
|
|
10011
|
-
//#region ../wesl/src/
|
|
10012
|
-
|
|
10013
|
-
|
|
10014
|
-
|
|
10015
|
-
|
|
10016
|
-
|
|
10017
|
-
}
|
|
10018
|
-
}
|
|
10019
|
-
/** add an elem to the .contents array of the currently containing element */
|
|
10020
|
-
function addToOpenElem(cc, elem) {
|
|
10021
|
-
const { openElems } = cc.app.context;
|
|
10022
|
-
if (openElems?.length) openElems[openElems.length - 1].contents.push(elem);
|
|
10023
|
-
}
|
|
10024
|
-
/** create reference Ident and add to context */
|
|
10025
|
-
function refIdent(cc) {
|
|
10026
|
-
const { src, start, end } = cc;
|
|
10027
|
-
const { srcModule } = cc.app.stable;
|
|
10028
|
-
const originalName = src.slice(start, end);
|
|
10029
|
-
const kind$1 = "ref";
|
|
10030
|
-
const ident$1 = {
|
|
10031
|
-
kind: kind$1,
|
|
10032
|
-
originalName,
|
|
10033
|
-
ast: cc.app.stable,
|
|
10034
|
-
id: nextIdentId(),
|
|
10035
|
-
refIdentElem: null
|
|
10036
|
-
};
|
|
10037
|
-
const identElem = {
|
|
10038
|
-
kind: kind$1,
|
|
10039
|
-
start,
|
|
10040
|
-
end,
|
|
10041
|
-
srcModule,
|
|
10042
|
-
ident: ident$1
|
|
10043
|
-
};
|
|
10044
|
-
ident$1.refIdentElem = identElem;
|
|
10045
|
-
saveIdent(cc, identElem);
|
|
10046
|
-
addToOpenElem(cc, identElem);
|
|
10047
|
-
return identElem;
|
|
10048
|
-
}
|
|
10049
|
-
/** create declaration Ident and add to context */
|
|
10050
|
-
function declCollect(cc) {
|
|
10051
|
-
return declCollectInternal(cc, false);
|
|
10052
|
-
}
|
|
10053
|
-
/** create global declaration Ident and add to context */
|
|
10054
|
-
function globalDeclCollect(cc) {
|
|
10055
|
-
return declCollectInternal(cc, true);
|
|
10056
|
-
}
|
|
10057
|
-
function declCollectInternal(cc, isGlobal) {
|
|
10058
|
-
const { src, start, end } = cc;
|
|
10059
|
-
const app = cc.app;
|
|
10060
|
-
const { scope: containingScope } = app.context;
|
|
10061
|
-
const { srcModule } = app.stable;
|
|
10062
|
-
const originalName = src.slice(start, end);
|
|
10063
|
-
const kind$1 = "decl";
|
|
10064
|
-
const identElem = {
|
|
10065
|
-
kind: kind$1,
|
|
10066
|
-
start,
|
|
10067
|
-
end,
|
|
10068
|
-
srcModule,
|
|
10069
|
-
ident: {
|
|
10070
|
-
declElem: null,
|
|
10071
|
-
kind: kind$1,
|
|
10072
|
-
originalName,
|
|
10073
|
-
containingScope,
|
|
10074
|
-
isGlobal,
|
|
10075
|
-
id: nextIdentId(),
|
|
10076
|
-
srcModule
|
|
10077
|
-
}
|
|
10078
|
-
};
|
|
10079
|
-
saveIdent(cc, identElem);
|
|
10080
|
-
addToOpenElem(cc, identElem);
|
|
10081
|
-
return identElem;
|
|
10082
|
-
}
|
|
10083
|
-
const typedDecl = collectElem("typeDecl", (cc, openElem) => {
|
|
10084
|
-
const decl = cc.tags.decl_elem?.[0];
|
|
10085
|
-
const typeRef = cc.tags.typeRefElem?.[0];
|
|
10086
|
-
const typeScope = cc.tags.decl_type?.[0];
|
|
10087
|
-
return withTextCover({
|
|
10088
|
-
...openElem,
|
|
10089
|
-
decl,
|
|
10090
|
-
typeScope,
|
|
10091
|
-
typeRef
|
|
10092
|
-
}, cc);
|
|
10093
|
-
});
|
|
10094
|
-
/** add Ident to current open scope, add IdentElem to current open element */
|
|
10095
|
-
function saveIdent(cc, identElem) {
|
|
10096
|
-
const { ident: ident$1 } = identElem;
|
|
10097
|
-
ident$1.id = nextIdentId();
|
|
10098
|
-
cc.app.context.scope.contents.push(ident$1);
|
|
10099
|
-
}
|
|
10100
|
-
/** start a new child lexical Scope */
|
|
10101
|
-
function startScope(cc) {
|
|
10102
|
-
startSomeScope("scope", cc);
|
|
10103
|
-
}
|
|
10104
|
-
/** start a new child partial Scope */
|
|
10105
|
-
function startPartialScope(cc) {
|
|
10106
|
-
startSomeScope("partial", cc);
|
|
10107
|
-
}
|
|
10108
|
-
/** start a new lexical or partial scope */
|
|
10109
|
-
function startSomeScope(kind$1, cc) {
|
|
10110
|
-
const { scope } = cc.app.context;
|
|
10111
|
-
const newScope = emptyScope(scope, kind$1);
|
|
10112
|
-
scope.contents.push(newScope);
|
|
10113
|
-
cc.app.context.scope = newScope;
|
|
10114
|
-
}
|
|
10115
|
-
function completeScope(cc) {
|
|
10116
|
-
return completeScopeInternal(cc, true);
|
|
10117
|
-
}
|
|
10118
|
-
function completeScopeNoIf(cc) {
|
|
10119
|
-
return completeScopeInternal(cc, false);
|
|
10120
|
-
}
|
|
10121
|
-
function completeScopeInternal(cc, attachIfs) {
|
|
10122
|
-
const weslContext = cc.app.context;
|
|
10123
|
-
const completedScope = weslContext.scope;
|
|
10124
|
-
const { parent } = completedScope;
|
|
10125
|
-
if (parent) weslContext.scope = parent;
|
|
10126
|
-
else if (tracing) console.log("ERR: completeScope, no parent scope", completedScope.contents);
|
|
10127
|
-
if (attachIfs) completedScope.condAttribute = collectConditionalAttribute(cc, completedScope);
|
|
10128
|
-
return completedScope;
|
|
10129
|
-
}
|
|
10130
|
-
/** return @if, @elif, or @else attribute from the 'attribute' or 'fn_attributes' tag */
|
|
10131
|
-
function collectConditionalAttribute(cc, completedScope) {
|
|
10132
|
-
if (completedScope.kind === "partial" && cc.tags.fn_name !== void 0) {
|
|
10133
|
-
const flatAttrs = cc.tags.fn_attributes?.flat?.();
|
|
10134
|
-
return findConditional(flatAttrs);
|
|
10135
|
-
}
|
|
10136
|
-
const attributes = cc.tags.attribute;
|
|
10137
|
-
return findConditional(attributes);
|
|
10138
|
-
}
|
|
10139
|
-
function collectVarLike(kind$1) {
|
|
10140
|
-
return collectElem(kind$1, (cc, openElem) => {
|
|
10141
|
-
const name$1 = cc.tags.var_name?.[0];
|
|
10142
|
-
const decl_scope = cc.tags.decl_scope?.[0];
|
|
10143
|
-
const attributes = cc.tags.attribute;
|
|
10144
|
-
const varElem = withTextCover({
|
|
10145
|
-
...openElem,
|
|
10146
|
-
name: name$1,
|
|
10147
|
-
attributes
|
|
10148
|
-
}, cc);
|
|
10149
|
-
const declIdent = name$1.decl.ident;
|
|
10150
|
-
declIdent.declElem = varElem;
|
|
10151
|
-
if (name$1.typeScope) {
|
|
10152
|
-
mergeScope(name$1.typeScope, decl_scope);
|
|
10153
|
-
declIdent.dependentScope = name$1.typeScope;
|
|
10154
|
-
} else declIdent.dependentScope = decl_scope;
|
|
10155
|
-
return varElem;
|
|
10156
|
-
});
|
|
10157
|
-
}
|
|
10158
|
-
const aliasCollect = collectElem("alias", (cc, openElem) => {
|
|
10159
|
-
const name$1 = cc.tags.alias_name?.[0];
|
|
10160
|
-
const alias_scope = cc.tags.alias_scope?.[0];
|
|
10161
|
-
const typeRef = cc.tags.typeRefElem?.[0];
|
|
10162
|
-
const attributes = cc.tags.attributes?.flat() ?? [];
|
|
10163
|
-
const aliasElem = withTextCover({
|
|
10164
|
-
...openElem,
|
|
10165
|
-
name: name$1,
|
|
10166
|
-
attributes,
|
|
10167
|
-
typeRef
|
|
10168
|
-
}, cc);
|
|
10169
|
-
name$1.ident.dependentScope = alias_scope;
|
|
10170
|
-
name$1.ident.declElem = aliasElem;
|
|
10171
|
-
return aliasElem;
|
|
10172
|
-
});
|
|
10173
|
-
/**
|
|
10174
|
-
* Collect a FnElem and associated scopes.
|
|
10175
|
-
*
|
|
10176
|
-
* Scope definition is a bit complicated in wgsl and wesl for fns.
|
|
10177
|
-
* Here's what we collect for scopes for this example function:
|
|
10178
|
-
* @if(true) fn foo(a: u32) -> @location(x) R { let y = a; }
|
|
10179
|
-
*
|
|
10180
|
-
* -{ // partial scope in case the whole shebang is prefixed by an `@if`
|
|
10181
|
-
* %foo
|
|
10182
|
-
*
|
|
10183
|
-
* {<=%foo // foo decl references this header+returnType+body scope (for tracing dependencies from decls)
|
|
10184
|
-
* x // for @location(x) (contains no decls, so ok to merge for tracing)
|
|
10185
|
-
* %a u32 // merged from header scope
|
|
10186
|
-
* R // merged from return type (contains no decls, so ok to merge for tracing)
|
|
10187
|
-
* %y a // merged body scope
|
|
10188
|
-
* }
|
|
10189
|
-
* }
|
|
10190
|
-
*/
|
|
10191
|
-
const fnCollect = collectElem("fn", (cc, openElem) => {
|
|
10192
|
-
const ourTags = fnTags(cc);
|
|
10193
|
-
const { name: name$1, headerScope, returnScope, bodyScope, body, params } = ourTags;
|
|
10194
|
-
const { attributes, returnAttributes, returnType, fnScope } = ourTags;
|
|
10195
|
-
const fnElem = {
|
|
10196
|
-
...openElem,
|
|
10197
|
-
name: name$1,
|
|
10198
|
-
attributes,
|
|
10199
|
-
params,
|
|
10200
|
-
returnAttributes,
|
|
10201
|
-
body,
|
|
10202
|
-
returnType
|
|
10203
|
-
};
|
|
10204
|
-
const mergedScope = headerScope;
|
|
10205
|
-
if (returnScope) mergeScope(mergedScope, returnScope);
|
|
10206
|
-
mergeScope(mergedScope, bodyScope);
|
|
10207
|
-
const filtered = [];
|
|
10208
|
-
for (const e of fnScope.contents) if (e === headerScope || e === returnScope) continue;
|
|
10209
|
-
else if (e === bodyScope) filtered.push(mergedScope);
|
|
10210
|
-
else filtered.push(e);
|
|
10211
|
-
fnScope.contents = filtered;
|
|
10212
|
-
name$1.ident.declElem = fnElem;
|
|
10213
|
-
name$1.ident.dependentScope = mergedScope;
|
|
10214
|
-
return fnElem;
|
|
10215
|
-
});
|
|
10216
|
-
/** Fetch and cast the collection tags for fnCollect
|
|
10217
|
-
* LATER typechecking for collect! */
|
|
10218
|
-
function fnTags(cc) {
|
|
10219
|
-
const { fn_attributes, fn_name, fn_param, return_attributes } = cc.tags;
|
|
10220
|
-
const { return_type } = cc.tags;
|
|
10221
|
-
const { header_scope, return_scope, body_scope, body_statement } = cc.tags;
|
|
10222
|
-
const { fn_partial_scope } = cc.tags;
|
|
10223
|
-
return {
|
|
10224
|
-
name: fn_name?.[0],
|
|
10225
|
-
headerScope: header_scope?.[0],
|
|
10226
|
-
returnScope: return_scope?.[0],
|
|
10227
|
-
bodyScope: body_scope?.[0],
|
|
10228
|
-
body: body_statement?.[0],
|
|
10229
|
-
params: fn_param?.flat(3) ?? [],
|
|
10230
|
-
attributes: fn_attributes?.flat(),
|
|
10231
|
-
returnAttributes: return_attributes?.flat(),
|
|
10232
|
-
returnType: return_type?.flat(3)[0],
|
|
10233
|
-
fnScope: fn_partial_scope?.[0]
|
|
10234
|
-
};
|
|
10235
|
-
}
|
|
10236
|
-
const collectFnParam = collectElem("param", (cc, openElem) => {
|
|
10237
|
-
const name$1 = cc.tags.param_name?.[0];
|
|
10238
|
-
const attributes = cc.tags.attributes?.flat() ?? [];
|
|
10239
|
-
const paramElem = withTextCover({
|
|
10240
|
-
...openElem,
|
|
10241
|
-
name: name$1,
|
|
10242
|
-
attributes
|
|
10243
|
-
}, cc);
|
|
10244
|
-
name$1.decl.ident.declElem = paramElem;
|
|
10245
|
-
return paramElem;
|
|
10246
|
-
});
|
|
10247
|
-
const collectStruct = collectElem("struct", (cc, openElem) => {
|
|
10248
|
-
const name$1 = cc.tags.type_name?.[0];
|
|
10249
|
-
const members = cc.tags.members;
|
|
10250
|
-
const attributes = cc.tags.attributes?.flat() ?? [];
|
|
10251
|
-
name$1.ident.dependentScope = cc.tags.struct_scope?.[0];
|
|
10252
|
-
const elem = withTextCover({
|
|
10253
|
-
...openElem,
|
|
10254
|
-
name: name$1,
|
|
10255
|
-
attributes,
|
|
10256
|
-
members
|
|
10257
|
-
}, cc);
|
|
10258
|
-
name$1.ident.declElem = elem;
|
|
10259
|
-
return elem;
|
|
10260
|
-
});
|
|
10261
|
-
const collectStructMember = collectElem("member", (cc, openElem) => {
|
|
10262
|
-
const name$1 = cc.tags.nameElem?.[0];
|
|
10263
|
-
const typeRef = cc.tags.typeRefElem?.[0];
|
|
10264
|
-
const attributes = cc.tags.attribute?.flat(3);
|
|
10265
|
-
return withTextCover({
|
|
10266
|
-
...openElem,
|
|
10267
|
-
name: name$1,
|
|
10268
|
-
attributes,
|
|
10269
|
-
typeRef
|
|
10270
|
-
}, cc);
|
|
10271
|
-
});
|
|
10272
|
-
const specialAttribute = collectElem("attribute", (cc, openElem) => {
|
|
10273
|
-
const attribute = cc.tags.attr_variant?.[0];
|
|
10274
|
-
return {
|
|
10275
|
-
...openElem,
|
|
10276
|
-
attribute
|
|
10277
|
-
};
|
|
10278
|
-
});
|
|
10279
|
-
const assertCollect = attrElemCollect("assert");
|
|
10280
|
-
const statementCollect = attrElemCollect("statement");
|
|
10281
|
-
const switchClauseCollect = attrElemCollect("switch-clause");
|
|
10282
|
-
/** @return a collector for container elem types that have only an attributes field */
|
|
10283
|
-
function attrElemCollect(kind$1) {
|
|
10284
|
-
return collectElem(kind$1, (cc, openElem) => {
|
|
10285
|
-
const attributes = cc.tags.attribute?.flat(3);
|
|
10286
|
-
return withTextCover({
|
|
10287
|
-
...openElem,
|
|
10288
|
-
attributes
|
|
10289
|
-
}, cc);
|
|
10290
|
-
});
|
|
10291
|
-
}
|
|
10292
|
-
const collectAttribute = collectElem("attribute", (cc, openElem) => {
|
|
10293
|
-
const params = cc.tags.attrParam;
|
|
10294
|
-
const stdAttribute = {
|
|
10295
|
-
kind: "@attribute",
|
|
10296
|
-
name: cc.tags.name?.[0],
|
|
10297
|
-
params
|
|
10298
|
-
};
|
|
10299
|
-
return {
|
|
10300
|
-
...openElem,
|
|
10301
|
-
attribute: stdAttribute
|
|
10302
|
-
};
|
|
10303
|
-
});
|
|
10304
|
-
const typeRefCollect = collectElem("type", (cc, openElem) => {
|
|
10305
|
-
const templateParamsTemp = cc.tags.templateParam?.flat(3);
|
|
10306
|
-
const typeRef = cc.tags.typeRefName?.[0];
|
|
10307
|
-
const name$1 = typeof typeRef === "string" ? typeRef : typeRef.ident;
|
|
10308
|
-
return withTextCover({
|
|
10309
|
-
...openElem,
|
|
10310
|
-
name: name$1,
|
|
10311
|
-
templateParams: templateParamsTemp
|
|
10312
|
-
}, cc);
|
|
10313
|
-
});
|
|
10314
|
-
const expressionCollect = collectElem("expression", (cc, openElem) => {
|
|
10315
|
-
return withTextCover({ ...openElem }, cc);
|
|
10316
|
-
});
|
|
10317
|
-
function globalAssertCollect(cc) {
|
|
10318
|
-
const globalAssert = cc.tags.const_assert?.flat()[0];
|
|
10319
|
-
const ast = cc.app.stable;
|
|
10320
|
-
if (!ast.moduleAsserts) ast.moduleAsserts = [];
|
|
10321
|
-
ast.moduleAsserts.push(globalAssert);
|
|
10322
|
-
}
|
|
10323
|
-
const stuffCollect = collectElem("stuff", (cc, openElem) => {
|
|
10324
|
-
return withTextCover({ ...openElem }, cc);
|
|
10325
|
-
});
|
|
10326
|
-
const memberRefCollect = collectElem("memberRef", (cc, openElem) => {
|
|
10327
|
-
const { component, structRef, extra_components } = cc.tags;
|
|
10328
|
-
const member = component?.[0];
|
|
10329
|
-
const name$1 = structRef?.flat()[0];
|
|
10330
|
-
const extraComponents = extra_components?.flat()[0];
|
|
10331
|
-
return withTextCover({
|
|
10332
|
-
...openElem,
|
|
10333
|
-
name: name$1,
|
|
10334
|
-
member,
|
|
10335
|
-
extraComponents
|
|
10336
|
-
}, cc);
|
|
10337
|
-
});
|
|
10338
|
-
function nameCollect(cc) {
|
|
10339
|
-
const { start, end, src } = cc;
|
|
10340
|
-
const elem = {
|
|
10341
|
-
kind: "name",
|
|
10342
|
-
start,
|
|
10343
|
-
end,
|
|
10344
|
-
name: src.slice(start, end)
|
|
10345
|
-
};
|
|
10346
|
-
addToOpenElem(cc, elem);
|
|
10347
|
-
return elem;
|
|
10348
|
-
}
|
|
10349
|
-
const collectModule = collectElem("module", (cc, openElem) => {
|
|
10350
|
-
const moduleElem = withTextCover(openElem, {
|
|
10351
|
-
...cc,
|
|
10352
|
-
start: 0,
|
|
10353
|
-
end: cc.src.length
|
|
10354
|
-
});
|
|
10355
|
-
const weslState = cc.app.stable;
|
|
10356
|
-
weslState.moduleElem = moduleElem;
|
|
10357
|
-
return moduleElem;
|
|
10358
|
-
});
|
|
10359
|
-
function directiveCollect(cc) {
|
|
10360
|
-
const { start, end } = cc;
|
|
10361
|
-
const directive = cc.tags.directive?.flat()[0];
|
|
10362
|
-
const elem = {
|
|
10363
|
-
kind: "directive",
|
|
10364
|
-
attributes: cc.tags.attribute?.flat(),
|
|
10365
|
-
start,
|
|
10366
|
-
end,
|
|
10367
|
-
directive
|
|
10368
|
-
};
|
|
10369
|
-
addToOpenElem(cc, elem);
|
|
10370
|
-
return elem;
|
|
10371
|
-
}
|
|
10372
|
-
/**
|
|
10373
|
-
* Collect a LexicalScope.
|
|
10374
|
-
*
|
|
10375
|
-
* The scope starts encloses all idents and subscopes inside the parser to which
|
|
10376
|
-
* .collect is attached
|
|
10377
|
-
*/
|
|
10378
|
-
const scopeCollect = {
|
|
10379
|
-
before: startScope,
|
|
10380
|
-
after: completeScope
|
|
10381
|
-
};
|
|
10382
|
-
/**
|
|
10383
|
-
* Collect a LexicalScope.
|
|
10384
|
-
*
|
|
10385
|
-
* The scope starts encloses all idents and subscopes inside the parser to which
|
|
10386
|
-
* .collect is attached
|
|
10387
|
-
*
|
|
10388
|
-
* '@if' attributes are not attached to the scope.
|
|
10389
|
-
*/
|
|
10390
|
-
const scopeCollectNoIf = {
|
|
10391
|
-
before: startScope,
|
|
10392
|
-
after: completeScopeNoIf
|
|
10393
|
-
};
|
|
10394
|
-
/**
|
|
10395
|
-
* Collect a PartialScope.
|
|
10396
|
-
*
|
|
10397
|
-
* The scope starts encloses all idents and subscopes inside the parser to which
|
|
10398
|
-
* .collect is attached
|
|
10399
|
-
*/
|
|
10400
|
-
const partialScopeCollect = {
|
|
10401
|
-
before: startPartialScope,
|
|
10402
|
-
after: completeScope
|
|
10403
|
-
};
|
|
10404
|
-
/** utility to collect an ElemWithContents
|
|
10405
|
-
* starts the new element as the collection point corresponding
|
|
10406
|
-
* to the start of the attached grammar and completes
|
|
10407
|
-
* the element in the at the end of the grammar.
|
|
10408
|
-
*
|
|
10409
|
-
* In between the start and the end, the new element is available
|
|
10410
|
-
* as an 'open' element in the collection context. While this element
|
|
10411
|
-
* is 'open', other collected are added to the 'contents' field of this
|
|
10412
|
-
* open element.
|
|
10413
|
-
*/
|
|
10414
|
-
function collectElem(kind$1, fn$1) {
|
|
10415
|
-
return {
|
|
10416
|
-
before: (cc) => {
|
|
10417
|
-
const partialElem = {
|
|
10418
|
-
kind: kind$1,
|
|
10419
|
-
contents: []
|
|
10420
|
-
};
|
|
10421
|
-
cc.app.context.openElems.push(partialElem);
|
|
10422
|
-
},
|
|
10423
|
-
after: (cc) => {
|
|
10424
|
-
const partialElem = cc.app.context.openElems.pop();
|
|
10425
|
-
console.assert(partialElem && partialElem.kind === kind$1);
|
|
10426
|
-
const elem = fn$1(cc, {
|
|
10427
|
-
...partialElem,
|
|
10428
|
-
start: cc.start,
|
|
10429
|
-
end: cc.end
|
|
10430
|
-
});
|
|
10431
|
-
if (elem) addToOpenElem(cc, elem);
|
|
10432
|
-
return elem;
|
|
10433
|
-
}
|
|
10434
|
-
};
|
|
10435
|
-
}
|
|
10436
|
-
/**
|
|
10437
|
-
* @return a copy of the element with contents extended
|
|
10438
|
-
* to include TextElems to cover the entire range.
|
|
10439
|
-
*/
|
|
10440
|
-
function withTextCover(elem, cc) {
|
|
10441
|
-
const contents = coverWithText(cc, elem);
|
|
10442
|
-
return {
|
|
10443
|
-
...elem,
|
|
10444
|
-
contents
|
|
10445
|
-
};
|
|
10446
|
-
}
|
|
10447
|
-
/** cover the entire source range with Elems by creating TextElems to
|
|
10448
|
-
* cover any parts of the source that are not covered by other elems
|
|
10449
|
-
* @returns the existing elems combined with any new TextElems, in src order */
|
|
10450
|
-
function coverWithText(cc, elem) {
|
|
10451
|
-
let { start: pos } = cc;
|
|
10452
|
-
const ast = cc.app.stable;
|
|
10453
|
-
const { contents, end } = elem;
|
|
10454
|
-
const sorted = contents.sort((a, b) => a.start - b.start);
|
|
10455
|
-
const elems = [];
|
|
10456
|
-
for (const elem$1 of sorted) {
|
|
10457
|
-
if (pos < elem$1.start) elems.push(makeTextElem(elem$1.start));
|
|
10458
|
-
elems.push(elem$1);
|
|
10459
|
-
pos = elem$1.end;
|
|
10460
|
-
}
|
|
10461
|
-
if (pos < end) elems.push(makeTextElem(end));
|
|
10462
|
-
return elems;
|
|
10463
|
-
function makeTextElem(end$1) {
|
|
10464
|
-
return {
|
|
10465
|
-
kind: "text",
|
|
10466
|
-
start: pos,
|
|
10467
|
-
end: end$1,
|
|
10468
|
-
srcModule: ast.srcModule
|
|
10469
|
-
};
|
|
10470
|
-
}
|
|
10471
|
-
}
|
|
10472
|
-
|
|
10473
|
-
//#endregion
|
|
10474
|
-
//#region ../wesl/src/parse/Keywords.ts
|
|
10475
|
-
/** https://www.w3.org/TR/WGSL/#keyword-summary */
|
|
10476
|
-
const keywords = `alias break case const const_assert continue continuing
|
|
10477
|
-
default diagnostic discard else enable false fn for if
|
|
10478
|
-
let loop override requires return struct switch true var while`.split(/\s+/);
|
|
10479
|
-
/** https://www.w3.org/TR/WGSL/#reserved-words */
|
|
10480
|
-
const reservedWords = `NULL Self abstract active alignas alignof as asm asm_fragment async attribute auto await
|
|
10481
|
-
become binding_array cast catch class co_await co_return co_yield coherent column_major
|
|
10482
|
-
common compile compile_fragment concept const_cast consteval constexpr constinit crate
|
|
10483
|
-
debugger decltype delete demote demote_to_helper do dynamic_cast
|
|
10484
|
-
enum explicit export extends extern external fallthrough filter final finally friend from fxgroup
|
|
10485
|
-
get goto groupshared highp impl implements import inline instanceof interface layout lowp
|
|
10486
|
-
macro macro_rules match mediump meta mod module move mut mutable
|
|
10487
|
-
namespace new nil noexcept noinline nointerpolation non_coherent noncoherent noperspective null nullptr
|
|
10488
|
-
of operator package packoffset partition pass patch pixelfragment precise precision premerge
|
|
10489
|
-
priv protected pub public readonly ref regardless register reinterpret_cast require resource restrict
|
|
10490
|
-
self set shared sizeof smooth snorm static static_assert static_cast std subroutine super
|
|
10491
|
-
target template this thread_local throw trait try type typedef typeid typename typeof
|
|
10492
|
-
union unless unorm unsafe unsized use using varying virtual volatile wgsl where with writeonly yield`.split(/\s+/);
|
|
10493
|
-
|
|
10494
|
-
//#endregion
|
|
10495
|
-
//#region ../wesl/src/parse/WeslStream.ts
|
|
10496
|
-
/** Whitespaces including new lines */
|
|
10497
|
-
const blankspaces = /[ \t\n\v\f\r\u{0085}\u{200E}\u{200F}\u{2028}\u{2029}]+/u;
|
|
10498
|
-
const symbolSet = "& && -> @ / ! [ ] { } :: : , == = != >>= >> >= > <<= << <= < % - -- . + ++ | || ( ) ; * ~ ^ // /* */ += -= *= /= %= &= |= ^= _";
|
|
10499
|
-
const ident = /(?:(?:[_\p{XID_Start}][\p{XID_Continue}]+)|(?:[\p{XID_Start}]))/u;
|
|
10500
|
-
const keywordOrReserved = new Set(keywords.concat(reservedWords));
|
|
10501
|
-
const weslMatcher = new RegexMatchers({
|
|
10502
|
-
word: ident,
|
|
10503
|
-
number: new RegExp(/(?:0[fh])|(?:[1-9][0-9]*[fh])/.source + /|(?:[0-9]*\.[0-9]+(?:[eE][+-]?[0-9]+)?[fh]?)/.source + /|(?:[0-9]+\.[0-9]*(?:[eE][+-]?[0-9]+)?[fh]?)/.source + /|(?:[0-9]+[eE][+-]?[0-9]+[fh]?)/.source + /|(?:0[xX][0-9a-fA-F]*\.[0-9a-fA-F]+(?:[pP][+-]?[0-9]+[fh]?)?)/.source + /|(?:0[xX][0-9a-fA-F]+\.[0-9a-fA-F]*(?:[pP][+-]?[0-9]+[fh]?)?)/.source + /|(?:0[xX][0-9a-fA-F]+[pP][+-]?[0-9]+[fh]?)/.source + /|(?:0[xX][0-9a-fA-F]+[iu]?)/.source + /|(?:0[iu]?)|(?:[1-9][0-9]*[iu]?)/.source),
|
|
10504
|
-
blankspaces,
|
|
10505
|
-
commentStart: /\/\/|\/\*/,
|
|
10506
|
-
symbol: matchOneOf(symbolSet),
|
|
10507
|
-
invalid: /[^]/
|
|
10508
|
-
});
|
|
10509
|
-
/** To mark parts of the grammar implementation that are WESL specific extensions */
|
|
10510
|
-
function weslExtension(combinator) {
|
|
10511
|
-
return combinator;
|
|
10512
|
-
}
|
|
10513
|
-
/** A stream that produces WESL tokens, skipping over comments and white space */
|
|
10514
|
-
var WeslStream = class {
|
|
10515
|
-
stream;
|
|
10516
|
-
/** New line */
|
|
10517
|
-
eolPattern = /[\n\v\f\u{0085}\u{2028}\u{2029}]|\r\n?/gu;
|
|
10518
|
-
/** Block comments */
|
|
10519
|
-
blockCommentPattern = /\/\*|\*\//g;
|
|
10520
|
-
src;
|
|
10521
|
-
constructor(src) {
|
|
10522
|
-
this.src = src;
|
|
10523
|
-
this.stream = new CachingStream(new MatchersStream(src, weslMatcher));
|
|
10524
|
-
}
|
|
10525
|
-
checkpoint() {
|
|
10526
|
-
return this.stream.checkpoint();
|
|
10527
|
-
}
|
|
10528
|
-
reset(position) {
|
|
10529
|
-
this.stream.reset(position);
|
|
10530
|
-
}
|
|
10531
|
-
nextToken() {
|
|
10532
|
-
while (true) {
|
|
10533
|
-
const token$1 = this.stream.nextToken();
|
|
10534
|
-
if (token$1 === null) return null;
|
|
10535
|
-
const kind$1 = token$1.kind;
|
|
10536
|
-
if (kind$1 === "blankspaces") continue;
|
|
10537
|
-
else if (kind$1 === "commentStart") if (token$1.text === "//") this.stream.reset(this.skipToEol(token$1.span[1]));
|
|
10538
|
-
else this.stream.reset(this.skipBlockComment(token$1.span[1]));
|
|
10539
|
-
else if (kind$1 === "word") {
|
|
10540
|
-
const returnToken = token$1;
|
|
10541
|
-
if (keywordOrReserved.has(token$1.text)) returnToken.kind = "keyword";
|
|
10542
|
-
return returnToken;
|
|
10543
|
-
} else if (kind$1 === "invalid") throw new ParseError("Invalid token " + token$1.text, token$1.span);
|
|
10544
|
-
else return token$1;
|
|
10545
|
-
}
|
|
10546
|
-
}
|
|
10547
|
-
skipToEol(position) {
|
|
10548
|
-
this.eolPattern.lastIndex = position;
|
|
10549
|
-
if (this.eolPattern.exec(this.src) === null) return this.src.length;
|
|
10550
|
-
else return this.eolPattern.lastIndex;
|
|
10551
|
-
}
|
|
10552
|
-
skipBlockComment(start) {
|
|
10553
|
-
let position = start;
|
|
10554
|
-
while (true) {
|
|
10555
|
-
this.blockCommentPattern.lastIndex = position;
|
|
10556
|
-
const result = this.blockCommentPattern.exec(this.src);
|
|
10557
|
-
if (result === null) throw new ParseError("Unclosed block comment!", [position, position]);
|
|
10558
|
-
else if (result[0] === "*/") return this.blockCommentPattern.lastIndex;
|
|
10559
|
-
else if (result[0] === "/*") position = this.skipBlockComment(this.blockCommentPattern.lastIndex);
|
|
10560
|
-
else throw new Error("Unreachable, invalid block comment pattern");
|
|
10561
|
-
}
|
|
10562
|
-
}
|
|
10563
|
-
/**
|
|
10564
|
-
* Only matches the `<` token if it is a template
|
|
10565
|
-
* Precondition: An ident was parsed right before this.
|
|
10566
|
-
* Runs the [template list discovery algorithm](https://www.w3.org/TR/WGSL/#template-list-discovery).
|
|
10567
|
-
*/
|
|
10568
|
-
nextTemplateStartToken() {
|
|
10569
|
-
const startPosition = this.stream.checkpoint();
|
|
10570
|
-
const token$1 = this.nextToken();
|
|
10571
|
-
this.stream.reset(startPosition);
|
|
10572
|
-
if (token$1 === null) return null;
|
|
10573
|
-
if (token$1.kind !== "symbol") return null;
|
|
10574
|
-
if (token$1.text === "<") if (this.isTemplateStart(token$1.span[1])) {
|
|
10575
|
-
this.stream.reset(token$1.span[1]);
|
|
10576
|
-
return token$1;
|
|
10577
|
-
} else {
|
|
10578
|
-
this.stream.reset(startPosition);
|
|
10579
|
-
return null;
|
|
10580
|
-
}
|
|
10581
|
-
else return null;
|
|
10582
|
-
}
|
|
10583
|
-
nextTemplateEndToken() {
|
|
10584
|
-
const startPosition = this.stream.checkpoint();
|
|
10585
|
-
const token$1 = this.nextToken();
|
|
10586
|
-
this.stream.reset(startPosition);
|
|
10587
|
-
if (token$1 === null) return null;
|
|
10588
|
-
if (token$1.kind === "symbol" && token$1.text[0] === ">") {
|
|
10589
|
-
const tokenPosition = token$1.span[0];
|
|
10590
|
-
this.stream.reset(tokenPosition + 1);
|
|
10591
|
-
return {
|
|
10592
|
-
kind: "symbol",
|
|
10593
|
-
span: [tokenPosition, tokenPosition + 1],
|
|
10594
|
-
text: ">"
|
|
10595
|
-
};
|
|
10596
|
-
} else return null;
|
|
10597
|
-
}
|
|
10598
|
-
isTemplateStart(afterToken) {
|
|
10599
|
-
this.stream.reset(afterToken);
|
|
10600
|
-
let pendingCounter = 1;
|
|
10601
|
-
while (true) {
|
|
10602
|
-
const nextToken = this.stream.nextToken();
|
|
10603
|
-
if (nextToken === null) return false;
|
|
10604
|
-
if (nextToken.kind !== "symbol") continue;
|
|
10605
|
-
if (nextToken.text === "<") pendingCounter += 1;
|
|
10606
|
-
else if (nextToken.text[0] === ">") {
|
|
10607
|
-
if (nextToken.text === ">" || nextToken.text === ">=") pendingCounter -= 1;
|
|
10608
|
-
else if (nextToken.text === ">>=" || nextToken.text === ">>") pendingCounter -= 2;
|
|
10609
|
-
else throw new Error("This case should never be reached, looks like we forgot one of the tokens that start with >");
|
|
10610
|
-
if (pendingCounter <= 0) return true;
|
|
10611
|
-
} else if (nextToken.text === "(") this.skipBracketsTo(")");
|
|
10612
|
-
else if (nextToken.text === "[") this.skipBracketsTo("]");
|
|
10613
|
-
else if (nextToken.text === "==" || nextToken.text === "!=" || nextToken.text === ";" || nextToken.text === "{" || nextToken.text === ":" || nextToken.text === "&&" || nextToken.text === "||") return false;
|
|
10614
|
-
}
|
|
10615
|
-
}
|
|
10616
|
-
/**
|
|
10617
|
-
* Call this after consuming an opening bracket.
|
|
10618
|
-
* Skips until a closing bracket. This also consumes the closing bracket.
|
|
10619
|
-
*/
|
|
10620
|
-
skipBracketsTo(closingBracket) {
|
|
10621
|
-
while (true) {
|
|
10622
|
-
const nextToken = this.stream.nextToken();
|
|
10623
|
-
if (nextToken === null) {
|
|
10624
|
-
const after = this.stream.checkpoint();
|
|
10625
|
-
throw new ParseError("Unclosed bracket!", [after, after]);
|
|
10626
|
-
}
|
|
10627
|
-
if (nextToken.kind !== "symbol") continue;
|
|
10628
|
-
if (nextToken.text === "(") this.skipBracketsTo(")");
|
|
10629
|
-
else if (nextToken.text === "[") this.skipBracketsTo("]");
|
|
10630
|
-
else if (nextToken.text === closingBracket) return;
|
|
10631
|
-
}
|
|
10632
|
-
}
|
|
10633
|
-
};
|
|
10634
|
-
const templateOpen = withStreamAction((stream$1) => {
|
|
10635
|
-
return stream$1.nextTemplateStartToken();
|
|
10636
|
-
});
|
|
10637
|
-
const templateClose = withStreamAction((stream$1) => {
|
|
10638
|
-
return stream$1.nextTemplateEndToken();
|
|
10639
|
-
});
|
|
10640
|
-
|
|
10641
|
-
//#endregion
|
|
10642
|
-
//#region ../wesl/src/parse/AttributeGrammar.ts
|
|
10643
|
-
const attribute_if_primary_expression = or(tokenOf("keyword", ["true", "false"]).map(makeLiteral), delimited(token("symbol", "("), fn(() => attribute_if_expression), token("symbol", ")")).map(makeParenthesizedExpression), tokenKind("word").map(makeTranslateTimeFeature));
|
|
10644
|
-
const attribute_if_unary_expression = or(seq(token("symbol", "!").map(makeUnaryOperator), fn(() => attribute_if_unary_expression)).map(makeUnaryExpression), attribute_if_primary_expression);
|
|
10645
|
-
const attribute_if_expression = weslExtension(seq(attribute_if_unary_expression, or(repeatPlus(seq(token("symbol", "||").map(makeBinaryOperator), req(attribute_if_unary_expression, "invalid expression, expected expression"))), repeatPlus(seq(token("symbol", "&&").map(makeBinaryOperator), req(attribute_if_unary_expression, "invalid expression, expected expression"))), yes().map(() => []))).map(makeRepeatingBinaryExpression));
|
|
10646
|
-
/** Base parser for @if attributes without collection - use in seq() compositions */
|
|
10647
|
-
const if_attribute_base = preceded(seq("@", weslExtension("if")), span(delimited("(", fn(() => attribute_if_expression), seq(opt(","), ")"))).map(makeTranslateTimeExpressionElem)).map(makeIfAttribute).ptag("attr_variant");
|
|
10648
|
-
/** Base parser for @elif attributes without collection - use in seq() compositions */
|
|
10649
|
-
const elif_attribute_base = preceded(seq("@", weslExtension("elif")), span(delimited("(", fn(() => attribute_if_expression), seq(opt(","), ")"))).map(makeTranslateTimeExpressionElem)).map(makeElifAttribute).ptag("attr_variant");
|
|
10650
|
-
/** Base parser for @else attributes without collection - use in seq() compositions */
|
|
10651
|
-
const else_attribute_base = preceded(seq("@", weslExtension("else")), yes).map(makeElseAttribute).ptag("attr_variant");
|
|
10652
|
-
/** Collected parser for @if attributes - use standalone, not in seq() */
|
|
10653
|
-
const if_attribute = tagScope(if_attribute_base.collect(specialAttribute));
|
|
10654
|
-
/** Collected parser for @elif attributes - use standalone, not in seq() */
|
|
10655
|
-
const elif_attribute = tagScope(elif_attribute_base.collect(specialAttribute));
|
|
10656
|
-
/** Collected parser for @else attributes - use standalone, not in seq() */
|
|
10657
|
-
const else_attribute = tagScope(else_attribute_base.collect(specialAttribute));
|
|
10658
|
-
function makeIfAttribute(param) {
|
|
10659
|
-
return {
|
|
10660
|
-
kind: "@if",
|
|
10661
|
-
param
|
|
10662
|
-
};
|
|
10663
|
-
}
|
|
10664
|
-
function makeElifAttribute(param) {
|
|
10665
|
-
return {
|
|
10666
|
-
kind: "@elif",
|
|
10667
|
-
param
|
|
10668
|
-
};
|
|
10669
|
-
}
|
|
10670
|
-
function makeElseAttribute() {
|
|
10671
|
-
return { kind: "@else" };
|
|
10672
|
-
}
|
|
10673
|
-
function makeTranslateTimeExpressionElem(args) {
|
|
10674
|
-
return {
|
|
10675
|
-
kind: "translate-time-expression",
|
|
10676
|
-
expression: args.value,
|
|
10677
|
-
span: args.span
|
|
10678
|
-
};
|
|
10679
|
-
}
|
|
10680
|
-
function makeLiteral(token$1) {
|
|
10681
|
-
return {
|
|
10682
|
-
kind: "literal",
|
|
10683
|
-
value: token$1.text,
|
|
10684
|
-
span: token$1.span
|
|
10685
|
-
};
|
|
10686
|
-
}
|
|
10687
|
-
function makeTranslateTimeFeature(token$1) {
|
|
10688
|
-
return {
|
|
10689
|
-
kind: "translate-time-feature",
|
|
10690
|
-
name: token$1.text,
|
|
10691
|
-
span: token$1.span
|
|
10692
|
-
};
|
|
10693
|
-
}
|
|
10694
|
-
function makeParenthesizedExpression(expression$1) {
|
|
10695
|
-
return {
|
|
10696
|
-
kind: "parenthesized-expression",
|
|
10697
|
-
expression: expression$1
|
|
10698
|
-
};
|
|
10699
|
-
}
|
|
10700
|
-
function makeUnaryOperator(token$1) {
|
|
10701
|
-
return {
|
|
10702
|
-
value: token$1.text,
|
|
10703
|
-
span: token$1.span
|
|
10704
|
-
};
|
|
10705
|
-
}
|
|
10706
|
-
function makeBinaryOperator(token$1) {
|
|
10707
|
-
return {
|
|
10708
|
-
value: token$1.text,
|
|
10709
|
-
span: token$1.span
|
|
10710
|
-
};
|
|
10711
|
-
}
|
|
10712
|
-
function makeUnaryExpression([operator, expression$1]) {
|
|
10713
|
-
return {
|
|
10714
|
-
kind: "unary-expression",
|
|
10715
|
-
operator,
|
|
10716
|
-
expression: expression$1
|
|
10717
|
-
};
|
|
10718
|
-
}
|
|
10719
|
-
function makeRepeatingBinaryExpression([start, repeating]) {
|
|
10720
|
-
let result = start;
|
|
10721
|
-
for (const [op, left] of repeating) result = {
|
|
10722
|
-
kind: "binary-expression",
|
|
10723
|
-
operator: op,
|
|
10724
|
-
left: result,
|
|
10725
|
-
right: left
|
|
10726
|
-
};
|
|
10727
|
-
return result;
|
|
10728
|
-
}
|
|
10729
|
-
|
|
10730
|
-
//#endregion
|
|
10731
|
-
//#region ../wesl/src/parse/WeslBaseGrammar.ts
|
|
10732
|
-
const word = kind("word");
|
|
10733
|
-
const keyword = kind("keyword");
|
|
10734
|
-
const qualified_ident = withSepPlus("::", or(word, keyword, "package", "super"));
|
|
10735
|
-
const number = kind("number");
|
|
10736
|
-
|
|
10737
|
-
//#endregion
|
|
10738
|
-
//#region ../wesl/src/parse/ImportGrammar.ts
|
|
10739
|
-
function makeStatement(segments, finalSegment) {
|
|
10740
|
-
return {
|
|
10741
|
-
kind: "import-statement",
|
|
10742
|
-
segments,
|
|
10743
|
-
finalSegment
|
|
10744
|
-
};
|
|
10745
|
-
}
|
|
10746
|
-
function makeSegment(name$1) {
|
|
10747
|
-
return {
|
|
10748
|
-
kind: "import-segment",
|
|
10749
|
-
name: name$1
|
|
10750
|
-
};
|
|
10751
|
-
}
|
|
10752
|
-
function makeCollection(subtrees) {
|
|
10753
|
-
return {
|
|
10754
|
-
kind: "import-collection",
|
|
10755
|
-
subtrees
|
|
10756
|
-
};
|
|
10757
|
-
}
|
|
10758
|
-
function makeItem(name$1, as) {
|
|
10759
|
-
return {
|
|
10760
|
-
kind: "import-item",
|
|
10761
|
-
name: name$1,
|
|
10762
|
-
as
|
|
10763
|
-
};
|
|
10764
|
-
}
|
|
10765
|
-
function prependSegments(segments, statement$1) {
|
|
10766
|
-
statement$1.segments = segments.concat(statement$1.segments);
|
|
10767
|
-
return statement$1;
|
|
10768
|
-
}
|
|
10769
|
-
let import_collection = null;
|
|
10770
|
-
const import_path_or_item = seq(preceded(not(or("super", "package", "import", "as")), or(word, keyword)), or(preceded("::", req(or(fn(() => import_collection), fn(() => import_path_or_item)), "invalid import, expected '{' or name")), preceded("as", req(word, "invalid alias, expected name")).map((v) => makeItem("", v)), yes().map(() => makeItem("")))).map(([name$1, next]) => {
|
|
10771
|
-
if (next.kind === "import-collection") return makeStatement([makeSegment(name$1)], next);
|
|
10772
|
-
else if (next.kind === "import-statement") return prependSegments([makeSegment(name$1)], next);
|
|
10773
|
-
else if (next.kind === "import-item") {
|
|
10774
|
-
next.name = name$1;
|
|
10775
|
-
return makeStatement([], next);
|
|
10776
|
-
} else assertUnreachable(next);
|
|
10777
|
-
});
|
|
10778
|
-
import_collection = delimited("{", withSepPlus(",", () => import_path_or_item).map(makeCollection), req("}", "invalid import collection, expected }"));
|
|
10779
|
-
const import_relative = or(terminated("package", req("::", "invalid import, expected '::'")).map((v) => [makeSegment(v)]), repeatPlus(terminated("super", req("::", "invalid import, expected '::'")).map(makeSegment)));
|
|
10780
|
-
const import_statement_base = delimited("import", seqObj({
|
|
10781
|
-
relative: opt(import_relative),
|
|
10782
|
-
collection_or_statement: req(or(import_collection, import_path_or_item), "invalid import, expected { or name")
|
|
10783
|
-
}).map(({ relative, collection_or_statement }) => {
|
|
10784
|
-
if (collection_or_statement.kind === "import-statement") return prependSegments(relative ?? [], collection_or_statement);
|
|
10785
|
-
else return makeStatement(relative ?? [], collection_or_statement);
|
|
10786
|
-
}), req(";", "invalid import, expected ';'"));
|
|
10787
|
-
function wrapAttributes(rawAttributes) {
|
|
10788
|
-
return rawAttributes.map((attribute) => ({
|
|
10789
|
-
kind: "attribute",
|
|
10790
|
-
attribute,
|
|
10791
|
-
contents: [],
|
|
10792
|
-
start: 0,
|
|
10793
|
-
end: 0
|
|
10794
|
-
}));
|
|
10795
|
-
}
|
|
10796
|
-
const import_statement = span(seq(repeat(or(if_attribute_base, elif_attribute_base, else_attribute_base)), import_statement_base)).map(({ value: [rawAttributes, imports], span: span$1 }) => {
|
|
10797
|
-
const importElem$1 = {
|
|
10798
|
-
kind: "import",
|
|
10799
|
-
imports,
|
|
10800
|
-
start: span$1[0],
|
|
10801
|
-
end: span$1[1]
|
|
10802
|
-
};
|
|
10803
|
-
if (rawAttributes.length > 0) return {
|
|
10804
|
-
...importElem$1,
|
|
10805
|
-
attributes: wrapAttributes(rawAttributes)
|
|
10806
|
-
};
|
|
10807
|
-
return importElem$1;
|
|
10808
|
-
});
|
|
10809
|
-
/** parse a WESL style wgsl import statement. */
|
|
10810
|
-
const weslImports = tagScope(repeat(import_statement).ptag("owo").collect(importElem));
|
|
10811
|
-
if (tracing) {
|
|
10812
|
-
const names = {
|
|
10813
|
-
import_collection,
|
|
10814
|
-
import_path_or_item,
|
|
10815
|
-
import_relative,
|
|
10816
|
-
import_statement,
|
|
10817
|
-
weslImports
|
|
10818
|
-
};
|
|
10819
|
-
Object.entries(names).forEach(([name$1, parser$1]) => {
|
|
10820
|
-
parser$1.setTraceName(name$1);
|
|
10821
|
-
});
|
|
10822
|
-
}
|
|
10823
|
-
|
|
10824
|
-
//#endregion
|
|
10825
|
-
//#region ../wesl/src/parse/WeslExpression.ts
|
|
10826
|
-
const opt_template_list = opt(seq(templateOpen, withSepPlus(",", () => template_parameter), req(templateClose, "invalid template, expected '>'")));
|
|
10827
|
-
const other_address_space = or("private", "workgroup", "uniform", "function");
|
|
10828
|
-
const storage_address_space = seq("storage", opt(seq(",", or("read", "read_write"))));
|
|
10829
|
-
const var_template_list = opt(seq(templateOpen, or(storage_address_space, other_address_space), req(templateClose, "invalid template, expected '>'")));
|
|
10830
|
-
const template_elaborated_ident = seq(qualified_ident.collect(refIdent), opt_template_list);
|
|
10831
|
-
const literal = or("true", "false", number);
|
|
10832
|
-
const paren_expression = seq("(", () => expression, req(")", "invalid expression, expected ')'"));
|
|
10833
|
-
const primary_expression = or(literal, paren_expression, seq(template_elaborated_ident, opt(fn(() => argument_expression_list))));
|
|
10834
|
-
const component_or_swizzle = repeatPlus(or(preceded(".", word), collectArray(delimited("[", () => expression, req("]", "invalid expression, expected ']'")))));
|
|
10835
|
-
/** parse simple struct.member style references specially, for binding struct lowering */
|
|
10836
|
-
const simple_component_reference = tagScope(seq(qualified_ident.collect(refIdent, "structRef"), seq(".", word.collect(nameCollect, "component")), opt(component_or_swizzle.collect(stuffCollect, "extra_components"))).collect(memberRefCollect));
|
|
10837
|
-
const unary_expression = or(seq(tokenOf("symbol", [
|
|
10838
|
-
"!",
|
|
10839
|
-
"&",
|
|
10840
|
-
"*",
|
|
10841
|
-
"-",
|
|
10842
|
-
"~"
|
|
10843
|
-
]), () => unary_expression), or(simple_component_reference, seq(primary_expression, opt(component_or_swizzle))));
|
|
10844
|
-
const bitwise_post_unary = or(repeatPlus(seq("&", unary_expression)), repeatPlus(seq("^", unary_expression)), repeatPlus(seq("|", unary_expression)));
|
|
10845
|
-
const multiplicative_operator = or("%", "*", "/");
|
|
10846
|
-
const additive_operator = or("+", "-");
|
|
10847
|
-
const shift_post_unary = (inTemplate) => {
|
|
10848
|
-
const shift_left = seq("<<", unary_expression);
|
|
10849
|
-
const shift_right = seq(">>", unary_expression);
|
|
10850
|
-
const mul_add = seq(repeat(seq(multiplicative_operator, unary_expression)), repeat(seq(additive_operator, unary_expression, repeat(seq(multiplicative_operator, unary_expression)))));
|
|
10851
|
-
return inTemplate ? or(shift_left, mul_add) : or(shift_left, shift_right, mul_add);
|
|
10852
|
-
};
|
|
10853
|
-
const relational_post_unary = (inTemplate) => {
|
|
10854
|
-
return seq(shift_post_unary(inTemplate), opt(seq(inTemplate ? tokenOf("symbol", [
|
|
10855
|
-
"<",
|
|
10856
|
-
"<=",
|
|
10857
|
-
"!=",
|
|
10858
|
-
"=="
|
|
10859
|
-
]) : tokenOf("symbol", [
|
|
10860
|
-
">",
|
|
10861
|
-
">=",
|
|
10862
|
-
"<",
|
|
10863
|
-
"<=",
|
|
10864
|
-
"!=",
|
|
10865
|
-
"=="
|
|
10866
|
-
]), unary_expression, shift_post_unary(inTemplate))));
|
|
10867
|
-
};
|
|
10868
|
-
/** The expression parser exists in two variants
|
|
10869
|
-
* `true` is template-expression: Refuses to parse parse symbols like `&&` and `||`.
|
|
10870
|
-
* `false` is maybe-template-expression: Does the template disambiguation.
|
|
10871
|
-
*/
|
|
10872
|
-
const expressionParser = (inTemplate) => {
|
|
10873
|
-
return seq(unary_expression, or(bitwise_post_unary, seq(relational_post_unary(inTemplate), inTemplate ? yes() : or(repeatPlus(seq("||", seq(unary_expression, relational_post_unary(false)))), repeatPlus(seq("&&", seq(unary_expression, relational_post_unary(false)))), yes().map(() => [])))));
|
|
10874
|
-
};
|
|
10875
|
-
const maybe_template = false;
|
|
10876
|
-
const expression = expressionParser(maybe_template);
|
|
10877
|
-
const template_arg_expression = expressionParser(true);
|
|
10878
|
-
const std_type_specifier = seq(qualified_ident.collect(refIdent, "typeRefName"), () => opt_template_list).collect(typeRefCollect);
|
|
10879
|
-
const type_specifier = tagScope(std_type_specifier).ctag("typeRefElem");
|
|
10880
|
-
/** a template_arg_expression with additional collection for parameters
|
|
10881
|
-
* that are types like array<f32> vs. expressions like 1+2 */
|
|
10882
|
-
const template_parameter = or(type_specifier.ctag("templateParam"), template_arg_expression.collect(expressionCollect, "templateParam"));
|
|
10883
|
-
const argument_expression_list = seq("(", withSep(",", expression), req(")", "invalid fn arguments, expected ')'"));
|
|
10884
|
-
if (tracing) {
|
|
10885
|
-
const names = {
|
|
10886
|
-
opt_template_list,
|
|
10887
|
-
other_address_space,
|
|
10888
|
-
storage_address_space,
|
|
10889
|
-
var_template_list,
|
|
10890
|
-
template_elaborated_ident,
|
|
10891
|
-
primary_expression,
|
|
10892
|
-
literal,
|
|
10893
|
-
paren_expression,
|
|
10894
|
-
component_or_swizzle,
|
|
10895
|
-
simple_component_reference,
|
|
10896
|
-
unary_expression,
|
|
10897
|
-
bitwise_post_unary,
|
|
10898
|
-
multiplicative_operator,
|
|
10899
|
-
additive_operator,
|
|
10900
|
-
expression,
|
|
10901
|
-
template_arg_expression,
|
|
10902
|
-
std_type_specifier,
|
|
10903
|
-
type_specifier,
|
|
10904
|
-
template_parameter,
|
|
10905
|
-
argument_expression_list
|
|
10906
|
-
};
|
|
10907
|
-
Object.entries(names).forEach(([name$1, parser$1]) => {
|
|
10908
|
-
parser$1.setTraceName(name$1);
|
|
10909
|
-
});
|
|
10910
|
-
}
|
|
10911
|
-
|
|
10912
|
-
//#endregion
|
|
10913
|
-
//#region ../wesl/src/parse/WeslGrammar.ts
|
|
10914
|
-
const name = tokenKind("word").map(makeName);
|
|
10915
|
-
const diagnostic_rule_name = seq(name, opt(preceded(".", req(name, "invalid diagnostic rule name, expected name"))));
|
|
10916
|
-
const diagnostic_control = delimited("(", req(separated_pair(name, ",", diagnostic_rule_name), "invalid diagnostic control, expected rule name"), seq(opt(","), req(")", "invalid diagnostic control, expected ')'")));
|
|
10917
|
-
/** list of words that aren't identifiers (e.g. for @interpolate) */
|
|
10918
|
-
const name_list = withSep(",", name, { requireOne: true });
|
|
10919
|
-
const special_attribute = tagScope(preceded("@", or(or("compute", "const", "fragment", "invariant", "must_use", "vertex").map((name$1) => makeStandardAttribute([name$1, []])), preceded("interpolate", req(delimited("(", name_list, ")"), "invalid @interpolate, expected '('")).map(makeInterpolateAttribute), preceded("builtin", req(delimited("(", name, ")"), "invalid @builtin, expected '('")).map(makeBuiltinAttribute), preceded("diagnostic", req(diagnostic_control, "invalid @diagnostic, expected '('")).map(makeDiagnosticAttribute)).ptag("attr_variant")).collect(specialAttribute));
|
|
10920
|
-
const normal_attribute = tagScope(preceded("@", or(seq(or("workgroup_size", "align", "binding", "blend_src", "group", "id", "location", "size").ptag("name"), req(() => attribute_argument_list, "invalid attribute, expected '('")), seq(word.ptag("name"), opt(() => attribute_argument_list)))).collect(collectAttribute));
|
|
10921
|
-
const attribute_argument_list = delimited("(", withSep(",", span(fn(() => expression)).collect(expressionCollect, "attrParam")), req(")", "invalid attribute arguments, expected ')'"));
|
|
10922
|
-
const attribute_no_if = or(special_attribute, normal_attribute).ctag("attribute");
|
|
10923
|
-
const attribute_incl_if = or(if_attribute, elif_attribute, else_attribute, special_attribute, normal_attribute).ctag("attribute");
|
|
10924
|
-
const opt_attributes = repeat(attribute_incl_if);
|
|
10925
|
-
const opt_attributes_no_if = repeat(attribute_no_if);
|
|
10926
|
-
const globalTypeNameDecl = req(word.collect(globalDeclCollect, "type_name"), "invalid type name, expected a name");
|
|
10927
|
-
const fnNameDecl = req(word.collect(globalDeclCollect, "fn_name"), "missing fn name");
|
|
10928
|
-
const optionally_typed_ident = tagScope(seq(word.collect(declCollect, "decl_elem"), opt(seq(":", type_specifier))).collect(typedDecl)).ctag("var_name");
|
|
10929
|
-
const req_optionally_typed_ident = req(optionally_typed_ident, "invalid ident");
|
|
10930
|
-
const global_ident = tagScope(req(seq(word.collect(globalDeclCollect, "decl_elem"), opt(seq(":", type_specifier.collect(scopeCollectNoIf, "decl_type")))).collect(typedDecl), "expected identifier")).ctag("var_name");
|
|
10931
|
-
const struct_member = tagScope(seq(opt_attributes, word.collect(nameCollect, "nameElem"), req(":", "invalid struct member, expected ':'"), req(type_specifier, "invalid struct member, expected type specifier")).collect(collectStructMember)).ctag("members");
|
|
10932
|
-
const struct_decl = seq(weslExtension(opt_attributes).collect((cc) => cc.tags.attribute, "attributes"), "struct", req(globalTypeNameDecl, "invalid struct, expected name"), seq(req("{", "invalid struct, expected '{'"), withSepPlus(",", struct_member), req("}", "invalid struct, expected '}'")).collect(scopeCollect, "struct_scope")).collect(collectStruct);
|
|
10933
|
-
/** Also covers func_call_statement.post.ident */
|
|
10934
|
-
const fn_call = seq(qualified_ident.collect(refIdent), () => opt_template_list, argument_expression_list);
|
|
10935
|
-
const fnParam = tagScope(seq(opt_attributes.collect((cc) => cc.tags.attribute, "attributes"), word.collect(declCollect, "decl_elem"), opt(seq(":", req(type_specifier, "invalid fn parameter, expected type specifier"))).collect(typedDecl, "param_name")).collect(collectFnParam)).ctag("fn_param");
|
|
10936
|
-
const fnParamList = seq("(", withSep(",", fnParam), ")");
|
|
10937
|
-
const local_variable_decl = seq("var", () => var_template_list, req_optionally_typed_ident, opt(seq("=", () => expression))).collect(collectVarLike("var"));
|
|
10938
|
-
const global_variable_decl = seq(opt_attributes, "var", () => var_template_list, global_ident, opt(seq("=", () => expression.collect(scopeCollectNoIf, "decl_scope"))), ";").collect(collectVarLike("gvar")).collect(partialScopeCollect);
|
|
10939
|
-
const unscoped_compound_statement = seq(opt_attributes, text("{"), repeat(() => statement), req("}", "invalid block, expected }")).collect(statementCollect);
|
|
10940
|
-
const compound_statement = tagScope(seq(opt_attributes, seq(text("{"), repeat(() => statement), req("}", "invalid block, expected '}'")).collect(scopeCollect)).collect(statementCollect));
|
|
10941
|
-
const for_init = seq(opt_attributes, or(fn_call, () => variable_or_value_statement, () => variable_updating_statement));
|
|
10942
|
-
const for_update = seq(opt_attributes, or(fn_call, () => variable_updating_statement));
|
|
10943
|
-
const for_statement = seq("for", seq(req("(", "invalid for loop, expected '('"), opt(for_init), req(";", "invalid for loop, expected ';'"), opt(expression), req(";", "invalid for loop, expected ';'"), opt(for_update), req(")", "invalid for loop, expected ')'"), unscoped_compound_statement).collect(scopeCollect));
|
|
10944
|
-
const if_statement = seq("if", req(seq(expression, compound_statement), "invalid if statement"), repeat(seq("else", "if", req(seq(expression, compound_statement), "invalid else if branch"))), opt(seq("else", req(compound_statement, "invalid else branch, expected '{'"))));
|
|
10945
|
-
const loop_statement = seq("loop", opt_attributes_no_if, req(seq("{", repeat(() => statement), opt(tagScope(seq(opt_attributes, "continuing", opt_attributes_no_if, "{", repeat(() => statement), tagScope(opt(seq(opt_attributes, seq("break", "if", expression, ";")).collect(statementCollect))), "}").collect(statementCollect).collect(scopeCollect))), "}"), "invalid loop statement")).collect(scopeCollect);
|
|
10946
|
-
const case_selector = or("default", expression);
|
|
10947
|
-
const switch_clause = tagScope(seq(opt_attributes, or(seq("case", withSep(",", case_selector, { requireOne: true }), opt(":"), compound_statement), seq("default", opt(":"), compound_statement)).collect(switchClauseCollect)));
|
|
10948
|
-
const switch_body = seq(opt_attributes, "{", repeatPlus(switch_clause), "}");
|
|
10949
|
-
const switch_statement = seq("switch", expression, switch_body);
|
|
10950
|
-
const while_statement = seq("while", expression, compound_statement);
|
|
10951
|
-
const regular_statement = or(for_statement, if_statement, loop_statement, switch_statement, while_statement, seq("break", ";"), seq("continue", req(";", "invalid statement, expected ';'")), seq(";"), () => const_assert, seq("discard", req(";", "invalid statement, expected ';'")), seq("return", opt(expression), req(";", "invalid statement, expected ';'")), seq(fn_call, req(";", "invalid statement, expected ';'")), seq(() => variable_or_value_statement, req(";", "invalid statement, expected ';'")), seq(() => variable_updating_statement, req(";", "invalid statement, expected ';'")));
|
|
10952
|
-
const conditional_statement = tagScope(seq(opt_attributes, regular_statement).collect(statementCollect).collect(partialScopeCollect));
|
|
10953
|
-
const statement = or(compound_statement, tagScope(seq(opt_attributes_no_if, regular_statement)), conditional_statement);
|
|
10954
|
-
const lhs_expression = or(simple_component_reference, seq(qualified_ident.collect(refIdent), opt(component_or_swizzle)), seq("(", () => lhs_expression, ")", opt(component_or_swizzle)), seq("&", () => lhs_expression), seq("*", () => lhs_expression));
|
|
10955
|
-
const variable_or_value_statement = tagScope(or(local_variable_decl, seq("const", req_optionally_typed_ident, req("=", "invalid const declaration, expected '='"), expression), seq("let", req_optionally_typed_ident, req("=", "invalid let declaration, expected '='"), expression)));
|
|
10956
|
-
const variable_updating_statement = or(seq(lhs_expression, or("=", "<<=", ">>=", "%=", "&=", "*=", "+=", "-=", "/=", "^=", "|="), expression), seq(lhs_expression, or("++", "--")), seq("_", "=", expression));
|
|
10957
|
-
const fn_decl = seq(tagScope(opt_attributes.collect((cc) => cc.tags.attribute || [])).ctag("fn_attributes"), text("fn"), req(fnNameDecl, "invalid fn, expected function name"), seq(req(fnParamList, "invalid fn, expected function parameters").collect(scopeCollectNoIf, "header_scope"), opt(seq("->", opt_attributes.collect((cc) => cc.tags.attribute, "return_attributes"), type_specifier.ctag("return_type").collect(scopeCollectNoIf, "return_scope"))), req(unscoped_compound_statement, "invalid fn, expected function body").ctag("body_statement").collect(scopeCollectNoIf, "body_scope"))).collect(partialScopeCollect, "fn_partial_scope").collect(fnCollect);
|
|
10958
|
-
const global_value_decl = or(seq(opt_attributes, "override", global_ident, seq(opt(seq("=", expression.collect(scopeCollectNoIf, "decl_scope")))), ";").collect(collectVarLike("override")), seq(opt_attributes, "const", global_ident, "=", seq(expression).collect(scopeCollectNoIf, "decl_scope"), ";").collect(collectVarLike("const"))).collect(partialScopeCollect);
|
|
10959
|
-
const global_alias = seq(weslExtension(opt_attributes).collect((cc) => cc.tags.attribute, "attributes"), "alias", req(word, "invalid alias, expected name").collect(globalDeclCollect, "alias_name"), req("=", "invalid alias, expected '='"), req(type_specifier, "invalid alias, expected type").collect(scopeCollect, "alias_scope"), req(";", "invalid alias, expected ';'")).collect(aliasCollect);
|
|
10960
|
-
const const_assert = tagScope(seq(opt_attributes, "const_assert", req(expression, "invalid const_assert, expected expression"), req(";", "invalid statement, expected ';'")).collect(assertCollect)).ctag("const_assert");
|
|
10961
|
-
const global_directive = tagScope(seq(opt_attributes, terminated(or(preceded("diagnostic", diagnostic_control).map(makeDiagnosticDirective), preceded("enable", name_list).map(makeEnableDirective), preceded("requires", name_list).map(makeRequiresDirective)).ptag("directive"), ";")).collect(directiveCollect));
|
|
10962
|
-
const global_decl = tagScope(or(fn_decl, global_variable_decl, global_value_decl, ";", global_alias, const_assert.collect(globalAssertCollect), struct_decl));
|
|
10963
|
-
const weslRoot = seq(weslExtension(weslImports), repeat(global_directive), repeat(global_decl), req(eof(), "invalid WESL, expected EOF")).collect(collectModule, "collectModule");
|
|
10964
|
-
function makeDiagnosticDirective([severity, rule]) {
|
|
10965
|
-
return {
|
|
10966
|
-
kind: "diagnostic",
|
|
10967
|
-
severity,
|
|
10968
|
-
rule
|
|
10969
|
-
};
|
|
10970
|
-
}
|
|
10971
|
-
function makeEnableDirective(extensions) {
|
|
10972
|
-
return {
|
|
10973
|
-
kind: "enable",
|
|
10974
|
-
extensions
|
|
10975
|
-
};
|
|
10976
|
-
}
|
|
10977
|
-
function makeRequiresDirective(extensions) {
|
|
10978
|
-
return {
|
|
10979
|
-
kind: "requires",
|
|
10980
|
-
extensions
|
|
10981
|
-
};
|
|
10982
|
-
}
|
|
10983
|
-
function makeStandardAttribute([name$1, params]) {
|
|
10984
|
-
return {
|
|
10985
|
-
kind: "@attribute",
|
|
10986
|
-
name: name$1,
|
|
10987
|
-
params
|
|
10988
|
-
};
|
|
10989
|
-
}
|
|
10990
|
-
function makeInterpolateAttribute(params) {
|
|
10991
|
-
return {
|
|
10992
|
-
kind: "@interpolate",
|
|
10993
|
-
params
|
|
10994
|
-
};
|
|
10995
|
-
}
|
|
10996
|
-
function makeBuiltinAttribute(param) {
|
|
10997
|
-
return {
|
|
10998
|
-
kind: "@builtin",
|
|
10999
|
-
param
|
|
11000
|
-
};
|
|
11001
|
-
}
|
|
11002
|
-
function makeDiagnosticAttribute([severity, rule]) {
|
|
11003
|
-
return {
|
|
11004
|
-
kind: "@diagnostic",
|
|
11005
|
-
severity,
|
|
11006
|
-
rule
|
|
11007
|
-
};
|
|
11008
|
-
}
|
|
11009
|
-
function makeName(token$1) {
|
|
11010
|
-
return {
|
|
11011
|
-
kind: "name",
|
|
11012
|
-
name: token$1.text,
|
|
11013
|
-
start: token$1.span[0],
|
|
11014
|
-
end: token$1.span[1]
|
|
11015
|
-
};
|
|
11016
|
-
}
|
|
11017
|
-
if (tracing) {
|
|
11018
|
-
const names = {
|
|
11019
|
-
name,
|
|
11020
|
-
diagnostic_rule_name,
|
|
11021
|
-
diagnostic_control,
|
|
11022
|
-
name_list,
|
|
11023
|
-
special_attribute,
|
|
11024
|
-
if_attribute,
|
|
11025
|
-
elif_attribute,
|
|
11026
|
-
else_attribute,
|
|
11027
|
-
normal_attribute,
|
|
11028
|
-
attribute_argument_list,
|
|
11029
|
-
attribute_no_if,
|
|
11030
|
-
attribute_incl_if,
|
|
11031
|
-
opt_attributes,
|
|
11032
|
-
opt_attributes_no_if,
|
|
11033
|
-
globalTypeNameDecl,
|
|
11034
|
-
fnNameDecl,
|
|
11035
|
-
optionally_typed_ident,
|
|
11036
|
-
req_optionally_typed_ident,
|
|
11037
|
-
global_ident,
|
|
11038
|
-
struct_member,
|
|
11039
|
-
struct_decl,
|
|
11040
|
-
fn_call,
|
|
11041
|
-
fnParam,
|
|
11042
|
-
fnParamList,
|
|
11043
|
-
local_variable_decl,
|
|
11044
|
-
global_variable_decl,
|
|
11045
|
-
unscoped_compound_statement,
|
|
11046
|
-
compound_statement,
|
|
11047
|
-
for_init,
|
|
11048
|
-
for_update,
|
|
11049
|
-
for_statement,
|
|
11050
|
-
if_statement,
|
|
11051
|
-
loop_statement,
|
|
11052
|
-
case_selector,
|
|
11053
|
-
switch_clause,
|
|
11054
|
-
switch_body,
|
|
11055
|
-
switch_statement,
|
|
11056
|
-
while_statement,
|
|
11057
|
-
regular_statement,
|
|
11058
|
-
conditional_statement,
|
|
11059
|
-
statement,
|
|
11060
|
-
lhs_expression,
|
|
11061
|
-
variable_or_value_statement,
|
|
11062
|
-
variable_updating_statement,
|
|
11063
|
-
fn_decl,
|
|
11064
|
-
global_value_decl,
|
|
11065
|
-
global_alias,
|
|
11066
|
-
const_assert,
|
|
11067
|
-
global_directive,
|
|
11068
|
-
global_decl,
|
|
11069
|
-
weslRoot,
|
|
11070
|
-
qualified_ident,
|
|
11071
|
-
word
|
|
11072
|
-
};
|
|
11073
|
-
Object.entries(names).forEach(([name$1, parser$1]) => {
|
|
11074
|
-
parser$1.setTraceName(name$1);
|
|
11075
|
-
});
|
|
11076
|
-
}
|
|
11077
|
-
|
|
11078
|
-
//#endregion
|
|
11079
|
-
//#region ../wesl/src/ParseWESL.ts
|
|
11080
|
-
/**
|
|
11081
|
-
* An error when parsing WESL fails. Designed to be human-readable.
|
|
11082
|
-
*/
|
|
11083
|
-
var WeslParseError$1 = class extends Error {
|
|
11084
|
-
span;
|
|
11085
|
-
src;
|
|
11086
|
-
constructor(opts) {
|
|
11087
|
-
const source = opts.src.src;
|
|
11088
|
-
const [lineNum, linePos] = offsetToLineNumber(opts.cause.span[0], source);
|
|
11089
|
-
let message = `${opts.src.debugFilePath}:${lineNum}:${linePos}`;
|
|
11090
|
-
message += ` error: ${opts.cause.message}\n`;
|
|
11091
|
-
message += errorHighlight(source, opts.cause.span).join("\n");
|
|
11092
|
-
super(message, { cause: opts.cause });
|
|
11093
|
-
this.span = opts.cause.span;
|
|
11094
|
-
this.src = opts.src;
|
|
11095
|
-
}
|
|
11096
|
-
};
|
|
11097
|
-
/** Parse a WESL file. Throws on error. */
|
|
11098
|
-
function parseSrcModule(srcModule) {
|
|
11099
|
-
const stream$1 = new WeslStream(srcModule.src);
|
|
11100
|
-
const appState = blankWeslParseState(srcModule);
|
|
11101
|
-
const init = {
|
|
11102
|
-
stream: stream$1,
|
|
11103
|
-
appState
|
|
11104
|
-
};
|
|
11105
|
-
try {
|
|
11106
|
-
if (weslRoot.parse(init) === null) throw new Error("parseWESL failed");
|
|
11107
|
-
} catch (e) {
|
|
11108
|
-
if (e instanceof ParseError) {
|
|
11109
|
-
const [lineNumber, lineColumn] = offsetToLineNumber(e.span[0], srcModule.src);
|
|
11110
|
-
const error = new WeslParseError$1({
|
|
11111
|
-
cause: e,
|
|
11112
|
-
src: srcModule
|
|
11113
|
-
});
|
|
11114
|
-
throwClickableError({
|
|
11115
|
-
url: srcModule.debugFilePath,
|
|
11116
|
-
text: srcModule.src,
|
|
11117
|
-
error,
|
|
11118
|
-
lineNumber,
|
|
11119
|
-
lineColumn,
|
|
11120
|
-
length: e.span[1] - e.span[0]
|
|
11121
|
-
});
|
|
11122
|
-
} else throw e;
|
|
11123
|
-
}
|
|
11124
|
-
return appState.stable;
|
|
11125
|
-
}
|
|
11126
|
-
function blankWeslParseState(srcModule) {
|
|
11127
|
-
const rootScope = emptyScope(null);
|
|
11128
|
-
return {
|
|
11129
|
-
context: {
|
|
11130
|
-
scope: rootScope,
|
|
11131
|
-
openElems: []
|
|
11132
|
-
},
|
|
11133
|
-
stable: {
|
|
11134
|
-
srcModule,
|
|
11135
|
-
imports: [],
|
|
11136
|
-
rootScope,
|
|
11137
|
-
moduleElem: null
|
|
11138
|
-
}
|
|
11139
|
-
};
|
|
11140
|
-
}
|
|
11141
|
-
|
|
11142
|
-
//#endregion
|
|
11143
|
-
//#region ../wesl/src/PathUtil.ts
|
|
11144
|
-
/** simplistic path manipulation utilities */
|
|
11145
|
-
/** return path with ./ and foo/.. elements removed */
|
|
11146
|
-
function normalize(path$2) {
|
|
11147
|
-
const noDots = path$2.split("/").filter((s) => s !== ".");
|
|
11148
|
-
const noDbl = [];
|
|
11149
|
-
noDots.forEach((s) => {
|
|
11150
|
-
if (s !== "") if (s === ".." && noDbl.length && noDbl[noDbl.length - 1] !== "..") noDbl.pop();
|
|
11151
|
-
else noDbl.push(s);
|
|
11152
|
-
});
|
|
11153
|
-
return noDbl.join("/");
|
|
11154
|
-
}
|
|
11155
|
-
/** return path w/o a suffix.
|
|
11156
|
-
* e.g. /foo/bar.wgsl => /foo/bar */
|
|
11157
|
-
function noSuffix(path$2) {
|
|
11158
|
-
const lastSlash = path$2.lastIndexOf("/");
|
|
11159
|
-
const lastStart = lastSlash === -1 ? 0 : lastSlash + 1;
|
|
11160
|
-
const suffix = path$2.indexOf(".", lastStart);
|
|
11161
|
-
const suffixStart = suffix === -1 ? path$2.length : suffix;
|
|
11162
|
-
return path$2.slice(0, suffixStart);
|
|
11163
|
-
}
|
|
11164
|
-
|
|
11165
|
-
//#endregion
|
|
11166
|
-
//#region ../wesl/src/ParsedRegistry.ts
|
|
11167
|
-
function parsedRegistry$1() {
|
|
11168
|
-
resetScopeIds();
|
|
11169
|
-
return { modules: {} };
|
|
9849
|
+
//#region ../wesl-tooling/src/Version.ts
|
|
9850
|
+
/** Read package.json from a directory.
|
|
9851
|
+
* @param projectDir - file:// URL string to directory containing package.json
|
|
9852
|
+
* @returns the parsed package.json contents */
|
|
9853
|
+
async function readPackageJson(projectDir) {
|
|
9854
|
+
const baseUrl = projectDir.endsWith("/") ? projectDir : `${projectDir}/`;
|
|
9855
|
+
return (await import(new URL("package.json", baseUrl).href, { with: { type: "json" } })).default;
|
|
11170
9856
|
}
|
|
11171
9857
|
/**
|
|
11172
|
-
* @param
|
|
11173
|
-
*
|
|
11174
|
-
* value is wesl source string
|
|
11175
|
-
* @param registry add parsed modules to this registry
|
|
11176
|
-
* @param packageName name of package
|
|
9858
|
+
* @param projectDir - file:// URL string to directory containing package.json
|
|
9859
|
+
* @returns the 'version' field from the package.json in the `projectDir`
|
|
11177
9860
|
*/
|
|
11178
|
-
function
|
|
11179
|
-
|
|
11180
|
-
if (weslRoot$1 === void 0) weslRoot$1 = "";
|
|
11181
|
-
else if (!weslRoot$1.endsWith("/")) weslRoot$1 += "/";
|
|
11182
|
-
Object.entries(srcFiles).map(([filePath, src]) => {
|
|
11183
|
-
return {
|
|
11184
|
-
modulePath: fileToModulePath(filePath, packageName),
|
|
11185
|
-
debugFilePath: weslRoot$1 + filePath,
|
|
11186
|
-
src
|
|
11187
|
-
};
|
|
11188
|
-
}).forEach((mod) => {
|
|
11189
|
-
const parsed = parseSrcModule(mod);
|
|
11190
|
-
if (registry.modules[mod.modulePath]) return;
|
|
11191
|
-
registry.modules[mod.modulePath] = parsed;
|
|
11192
|
-
});
|
|
11193
|
-
}
|
|
11194
|
-
const libRegex = /^lib\.w[eg]sl$/i;
|
|
11195
|
-
/** convert a file path (./foo/bar.wesl)
|
|
11196
|
-
* to a module path (package::foo::bar) */
|
|
11197
|
-
function fileToModulePath(filePath, packageName) {
|
|
11198
|
-
if (filePath.includes("::")) return filePath;
|
|
11199
|
-
if (packageName !== "package" && libRegex.test(filePath)) return packageName;
|
|
11200
|
-
const moduleSuffix = noSuffix(normalize(filePath)).replaceAll("/", "::");
|
|
11201
|
-
return packageName + "::" + moduleSuffix;
|
|
9861
|
+
async function versionFromPackageJson(projectDir) {
|
|
9862
|
+
return (await readPackageJson(projectDir)).version;
|
|
11202
9863
|
}
|
|
11203
9864
|
|
|
11204
9865
|
//#endregion
|
|
@@ -11208,7 +9869,8 @@ async function cli(rawArgs) {
|
|
|
11208
9869
|
await linkNormally(await parseArgs(rawArgs));
|
|
11209
9870
|
}
|
|
11210
9871
|
async function parseArgs(args) {
|
|
11211
|
-
const
|
|
9872
|
+
const toolDir = new URL("..", import.meta.url).href;
|
|
9873
|
+
const appVersion = await versionFromPackageJson(toolDir);
|
|
11212
9874
|
return yargs(args).version(appVersion).command("$0 [module]", false, (yargs$1) => {
|
|
11213
9875
|
yargs$1.positional("module", {
|
|
11214
9876
|
type: "string",
|
|
@@ -11261,20 +9923,15 @@ async function linkNormally(argv) {
|
|
|
11261
9923
|
conditions
|
|
11262
9924
|
})).dest);
|
|
11263
9925
|
if (argv.details) {
|
|
11264
|
-
const
|
|
11265
|
-
|
|
11266
|
-
parseIntoRegistry$1(weslSrc, registry, "package");
|
|
11267
|
-
} catch (e) {
|
|
11268
|
-
console.error(e);
|
|
11269
|
-
}
|
|
11270
|
-
Object.entries(registry.modules).forEach(([modulePath, ast]) => {
|
|
9926
|
+
const resolver = new RecordResolver(weslSrc);
|
|
9927
|
+
for (const [modulePath, ast] of resolver.allModules()) {
|
|
11271
9928
|
log(`---\n${modulePath}`);
|
|
11272
9929
|
log(`\n->ast`);
|
|
11273
9930
|
log(astToString(ast.moduleElem));
|
|
11274
9931
|
log(`\n->scope`);
|
|
11275
9932
|
log(scopeToString(ast.rootScope));
|
|
11276
9933
|
log();
|
|
11277
|
-
}
|
|
9934
|
+
}
|
|
11278
9935
|
}
|
|
11279
9936
|
}
|
|
11280
9937
|
/** load the weslbundle containing the root module (if we haven't already loaded it) */
|