unplugin-typegpu
Version:
Build plugins for TypeGPU, enabling seamless JavaScript -> WGSL transpilation and improved debugging.
198 lines (191 loc) • 8.09 kB
JavaScript
import { a as getBlockScope, i as functionVisitor, n as defaultOptions, o as initPluginState, r as earlyPruneRegex, t as METADATA_FORMAT_VERSION } from "./common-CK7zOjbK.js";
import defu from "defu";
import { transpileFn } from "tinyest-for-wgsl";
import * as t from "@babel/types";
import MagicString from "magic-string";
import { getBabelParserOptions, getLang } from "ast-kit";
import _traverse from "@babel/traverse";
import * as parser from "@babel/parser";
//#region \0@oxc-project+runtime@0.95.0/helpers/typeof.js
function _typeof(o) {
"@babel/helpers - typeof";
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
return typeof o$1;
} : function(o$1) {
return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
}, _typeof(o);
}
//#endregion
//#region \0@oxc-project+runtime@0.95.0/helpers/toPrimitive.js
function toPrimitive(t$1, r) {
if ("object" != _typeof(t$1) || !t$1) return t$1;
var e = t$1[Symbol.toPrimitive];
if (void 0 !== e) {
var i = e.call(t$1, r || "default");
if ("object" != _typeof(i)) return i;
throw new TypeError("@@toPrimitive must return a primitive value.");
}
return ("string" === r ? String : Number)(t$1);
}
//#endregion
//#region \0@oxc-project+runtime@0.95.0/helpers/toPropertyKey.js
function toPropertyKey(t$1) {
var i = toPrimitive(t$1, "string");
return "symbol" == _typeof(i) ? i : i + "";
}
//#endregion
//#region \0@oxc-project+runtime@0.95.0/helpers/defineProperty.js
function _defineProperty(e, r, t$1) {
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
value: t$1,
enumerable: !0,
configurable: !0,
writable: !0
}) : e[r] = t$1, e;
}
//#endregion
//#region \0@oxc-project+runtime@0.95.0/helpers/objectSpread2.js
function ownKeys(e, r) {
var t$1 = Object.keys(e);
if (Object.getOwnPropertySymbols) {
var o = Object.getOwnPropertySymbols(e);
r && (o = o.filter(function(r$1) {
return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
})), t$1.push.apply(t$1, o);
}
return t$1;
}
function _objectSpread2(e) {
for (var r = 1; r < arguments.length; r++) {
var t$1 = null != arguments[r] ? arguments[r] : {};
r % 2 ? ownKeys(Object(t$1), !0).forEach(function(r$1) {
_defineProperty(e, r$1, t$1[r$1]);
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t$1)) : ownKeys(Object(t$1)).forEach(function(r$1) {
Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t$1, r$1));
});
}
return e;
}
//#endregion
//#region src/core/factory.ts
let traverse = _traverse;
if (typeof traverse.default === "function") traverse = traverse.default;
const fnWrapperTemplate = (fnCode, metadata) => `(/*#__PURE__*/($ => (globalThis.__TYPEGPU_META__ ??= new WeakMap()).set($.f = (${fnCode}), ${metadata}) && $.f)({}))`;
function embedJSON(jsValue) {
return JSON.stringify(jsValue).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
}
function assignMetadata(path, name, ast) {
var _path$node$start, _path$node$start2;
const metadata = `{
v: ${METADATA_FORMAT_VERSION},
name: ${name ? `"${name}"` : "undefined"},
ast: ${embedJSON(ast)},
externals: () => ({${ast.externalNames.map((e) => e === "this" ? "\"this\": this" : e).join(", ")}}),
}`;
const visibility = t.isFunctionDeclaration(path.node) ? getBlockScope(path) : void 0;
const fnCode = this.slice(path.node);
let nodeToOverride = path.node;
let code = fnWrapperTemplate(fnCode, metadata);
let insertPos = (_path$node$start = path.node.start) !== null && _path$node$start !== void 0 ? _path$node$start : 0;
if (t.isFunctionDeclaration(path.node) && path.node.id) code = `const ${path.node.id.name} = ${code};\n\n`;
if (visibility) {
var _visibility$node$body, _visibility$node$body2;
insertPos = (_visibility$node$body = (_visibility$node$body2 = visibility.node.body[0]) === null || _visibility$node$body2 === void 0 ? void 0 : _visibility$node$body2.start) !== null && _visibility$node$body !== void 0 ? _visibility$node$body : insertPos;
if (t.isExportNamedDeclaration(path.parent)) {
nodeToOverride = path.parent;
code = `export ${code}`;
} else if (t.isExportDefaultDeclaration(path.parent)) {
nodeToOverride = path.parent;
if (t.isFunctionDeclaration(path.node) && path.node.id) code = `${code}export default ${path.node.id.name};`;
else code = `export default ${code};`;
}
}
if (insertPos < ((_path$node$start2 = path.node.start) !== null && _path$node$start2 !== void 0 ? _path$node$start2 : 0)) {
var _nodeToOverride$leadi, _nodeToOverride$leadi2;
for (const comment of (_nodeToOverride$leadi = (_nodeToOverride$leadi2 = nodeToOverride.leadingComments) === null || _nodeToOverride$leadi2 === void 0 ? void 0 : _nodeToOverride$leadi2.toReversed()) !== null && _nodeToOverride$leadi !== void 0 ? _nodeToOverride$leadi : []) if (comment) {
code = `${this.slice(comment)}\n${code}`;
this.remove(comment);
}
this.remove(nodeToOverride);
this.magicString.prependLeft(insertPos, code);
} else this.overwrite(nodeToOverride, code);
}
function wrapInAutoName(path, name) {
var _path$node$start3, _path$node$end;
this.magicString.appendLeft((_path$node$start3 = path.node.start) !== null && _path$node$start3 !== void 0 ? _path$node$start3 : 0, "(/*#__PURE__*/(globalThis.__TYPEGPU_AUTONAME__ ?? (a => a))(").prependRight((_path$node$end = path.node.end) !== null && _path$node$end !== void 0 ? _path$node$end : 0, `, "${name}"))`);
}
function replaceWithAssignmentOverload(path, runtimeFn) {
const lhs = this.slice(path.node.left);
const rhs = this.slice(path.node.right);
this.overwrite(path.node, `${lhs} = ${runtimeFn}(${lhs}, ${rhs})`);
}
function replaceWithBinaryOverload(path, runtimeFn) {
const lhs = this.slice(path.node.left);
const rhs = this.slice(path.node.right);
this.overwrite(path.node, `${runtimeFn}(${lhs}, ${rhs})`);
}
const NodeUtils = {
slice(node) {
var _node$start, _node$end;
return this.magicString.slice((_node$start = node.start) !== null && _node$start !== void 0 ? _node$start : 0, (_node$end = node.end) !== null && _node$end !== void 0 ? _node$end : 0);
},
remove(node) {
var _node$start2, _node$end2;
this.magicString.remove((_node$start2 = node.start) !== null && _node$start2 !== void 0 ? _node$start2 : 0, (_node$end2 = node.end) !== null && _node$end2 !== void 0 ? _node$end2 : 0);
},
overwrite(node, content) {
var _node$start3, _node$end3;
this.magicString.overwrite((_node$start3 = node.start) !== null && _node$start3 !== void 0 ? _node$start3 : 0, (_node$end3 = node.end) !== null && _node$end3 !== void 0 ? _node$end3 : 0, content);
}
};
const unpluginFactory = ((rawOptions, _meta) => {
const options = defu(rawOptions, defaultOptions);
return {
name: "unplugin-typegpu",
enforce: options.enforce,
transform: {
filter: options.earlyPruning ? {
id: options,
code: earlyPruneRegex
} : { id: options },
handler(code, id) {
let ast;
try {
ast = parser.parse(code, getBabelParserOptions(getLang(id), {
sourceType: "module",
allowReturnOutsideFunction: true
}));
} catch (cause) {
console.warn(`[unplugin-typegpu] Failed to parse ${id}. Cause: ${typeof cause === "object" && cause && "message" in cause ? cause.message : cause}`);
return;
}
const magicString = new MagicString(code);
const state = _objectSpread2({
filename: id,
magicString,
opts: options
}, NodeUtils);
initPluginState(state, {
warn: (message) => this.warn(message),
assignMetadata,
wrapInAutoName,
replaceWithAssignmentOverload,
replaceWithBinaryOverload
});
traverse(ast, functionVisitor, void 0, state);
if (magicString.hasChanged()) return {
code: magicString.toString(),
get map() {
return magicString.generateMap({
source: id,
includeContent: true,
hires: "boundary"
});
}
};
}
}
};
});
//#endregion
export { unpluginFactory as t };