UNPKG

@effectful/transducers

Version:

JS syntax transformation framework for @effectful/js

152 lines (151 loc) 5.09 kB
"use strict"; exports.__esModule = true; exports.default = void 0; var _core = require("../core"); var Kit = require("../kit"); var _default = exports.default = Kit.pipe(Kit.wrap("instrumentation", function (s) { let curId = 0; const src = s.opts.file && s.opts.file.filenameRelative || "?"; function* walk(pn, fv) { for (const i of s.sub()) { switch (i.type) { case _core.Tag.Identifier: //TODO: needs checking if arguments variable not in scope if (fv != null && i.pos !== _core.Tag.key && i.pos !== _core.Tag.property && i.value.node.name === "arguments") { fv.hasArgs = true; Kit.skip(s.copy(i)); yield s.tok(i.pos, _core.Tag.Identifier, { node: { name: "e$y$arguments" } }); continue; } break; case _core.Tag.ThisExpression: if (fv) { fv.hasThis = true; Kit.skip(s.copy(i)); yield s.tok(i.pos, _core.Tag.Identifier, { node: { name: "e$y$this" } }); } continue; case _core.Tag.Class: case _core.Tag.ClassDeclaration: if (i.enter) { if (i.value.node.id != null) { yield i; yield* walk(pn.concat([i.value.node.id.name])); continue; } } break; case _core.Tag.FunctionDeclaration: case _core.Tag.FunctionExpression: case _core.Tag.ObjectMethod: case _core.Tag.ClassMethod: case _core.Tag.ArrowFunctionExpression: if (i.enter) { const n = i.value.node; if (Kit.hasAnnot(n, "@NOPROF")) break; let nm, sn, ln = "?", id = n.id || n.key; if (id != null && id.name != null) { sn = id.name; } else { sn = `F${curId++}`; } const nl = pn.concat(sn); nm = nl.join("."); nm += "@" + src; if (n.loc != null) { ln = `${n.loc.start.line}[${n.loc.start.column}]`; } const lab = s.label(); yield s.peel(i); const j = yield* s.findPos(_core.Tag.body); const expr = j.type !== _core.Tag.BlockStatement; if (expr) { i.value.node.expression = false; yield s.enter(_core.Tag.body, _core.Tag.BlockStatement); yield s.enter(_core.Tag.body, _core.Tag.Array); } else { yield s.peel(j); yield* s.peelTo(_core.Tag.body); } yield s.enter(_core.Tag.push, _core.Tag.ReturnStatement); yield s.enter(_core.Tag.argument, _core.Tag.CallExpression); yield s.tok(_core.Tag.callee, _core.Tag.Identifier, { node: { name: n.generator ? "e$y$prof$g" : "e$y$prof" } }); yield s.enter(_core.Tag.arguments, _core.Tag.Array); yield s.tok(_core.Tag.push, _core.Tag.StringLiteral, { node: { value: nm } }); yield s.tok(_core.Tag.push, _core.Tag.StringLiteral, { node: { value: ln } }); yield s.enter(_core.Tag.push, _core.Tag.FunctionExpression, { node: { params: [], generator: n.generator } }); n.generator = false; yield s.enter(_core.Tag.body, _core.Tag.BlockStatement); yield s.enter(_core.Tag.body, _core.Tag.Array); if (expr) { yield s.enter(_core.Tag.push, _core.Tag.ReturnStatement); yield s.peel(Kit.setPos(j, _core.Tag.argument)); } yield* walk(nl, i.value); yield* lab(); continue; } break; } yield i; } } return walk([]); }), Array.from, //TODO: common pass Kit.wrap("instrumentation-spec-vars", function (s) { function* walk() { for (const i of s.sub()) { yield i; if (i.enter) { switch (i.type) { case _core.Tag.FunctionDeclaration: case _core.Tag.FunctionExpression: case _core.Tag.ArrowFunctionExpression: case _core.Tag.ClassMethod: case _core.Tag.ObjectMethod: if (i.value.hasThis || i.value.hasArgs) { const lab = s.label(); yield* s.peelTo(_core.Tag.body); yield* s.peelTo(_core.Tag.body); //TODO: uniq names if (i.value.hasThis) yield* s.toks(_core.Tag.push, "const e$y$this = this"); if (i.value.hasArgs) yield* s.toks(_core.Tag.push, "const e$y$arguments = arguments"); yield* walk(true); yield* lab(); } break; } } } } return walk(false); }));