@effectful/transducers
Version:
JS syntax transformation framework for @effectful/js
185 lines (183 loc) • 5.92 kB
JavaScript
;
exports.__esModule = true;
exports.default = void 0;
var _core = require("../core");
var Kit = require("../kit");
var T = require("@babel/types");
function collectFuncDecls(s) {
const sa = Kit.toArray(s);
const sl = Kit.auto(sa);
function walk() {
for (const i of sl.sub()) {
if (i.enter) {
switch (i.type) {
case _core.Tag.FunctionDefinition:
case _core.Tag.FunctionExpression:
case _core.Tag.ArrowFunctionExpression:
}
}
}
}
walk(new Set());
return sa;
}
function markKeyIds(s) {
const sl = Kit.auto(s);
function* walk(sw) {
for (const i of sw) {
yield i;
if (i.enter) {
switch (i.type) {
case _core.Tag.FunctionDeclaration:
case _core.Tag.FunctionExpression:
const j = sl.cur();
if (j.pos === _core.Tag.id) {
j.value.key = true;
yield* sl.one();
}
break;
case _core.Tag.MemberExpression:
yield* walk(sl.one());
const k = sl.cur();
if (k.type === _core.Tag.Identifier) {
k.value.key = true;
yield* sl.one();
}
break;
}
}
}
}
return walk(sl);
}
/**
* joins not computed MemberExpressions into a single variable
* if its object is const and not used anywhere else
*/
var _default = exports.default = Kit.pipe(markKeyIds, collectFuncDecls, function joinMemExprCollect(s) {
const sa = Kit.toArray(s);
const sl = Kit.auto(sa);
const disregard = sl.opts.disregard || {};
function walk(dir) {
for (const i of sl.sub()) {
if (i.enter) {
switch (i.type) {
case _core.Tag.FunctionDefinition:
case _core.Tag.FunctionExpression:
case _core.Tag.ArrowFunctionExpression:
//TODO:
break;
case _core.Tag.ImportNamespaceSpecifier:
//TODO:
break;
case _core.Tag.VariableDeclaration:
if (i.pos === _core.Tag.push) {
const vars = i.value.vars = [];
for (const j of sl.sub()) {
if (j.enter && j.type === _core.Tag.VariableDeclarator) {
for (const k of sl.one()) {
if (k.enter && k.type === _core.Tag.Identifier) {
switch (i.value.node.kind) {
case "const":
const pack = Kit.hasAnnot(i.value.node, "@PACK") || Kit.hasAnnot(j.value.node, "@PACK");
const info = {
name: k.value.node.name,
used: new Set(),
enabled: true,
pack
};
vars.push(info);
dir.set(k.value.node.name, info);
break;
case "let":
dir.delete(k.value.node.name);
break;
}
}
}
const n = sl.cur();
if (n.type === _core.Tag.AssignmentExpression && n.pos === _core.Tag.init) {
for (const j of vars) j.enabled = false;
}
walk(dir);
}
}
}
break;
case _core.Tag.Identifier:
if (!i.value.key) {
const info = dir.get(i.value.node.name);
if (info != null && !info.pack) {
info.enabled = false;
}
}
break;
case _core.Tag.CallExpression:
case _core.Tag.AssignmentExpression:
const c = sl.cur();
if (c.type === _core.Tag.MemberExpression) {
c.value.discharge = true;
}
break;
case _core.Tag.MemberExpression:
const o = sl.cur();
if (o.type === _core.Tag.Identifier && !i.value.node.computed && !disregard[o.value.node.name]) {
const info = dir.get(o.value.node.name);
if (info != null) {
if (i.value.discharge && !info.pack) {
info.enabled = false;
break;
}
Kit.skip(sl.one());
const p = sl.cur();
if (p.type !== _core.Tag.Identifier && !info.pack) {
info.enabled = false;
break;
}
Kit.skip(sl.one());
i.value.path = [o.value.node.name, p.value.node.name];
i.value.varInfo = info;
info.used.add(p.value.node.name);
}
}
break;
case _core.Tag.BlockStatement:
walk(new Map(dir));
}
}
}
}
walk(new Map());
return sa;
}, function joinMemExprReplace(s) {
const sl = Kit.auto(s);
function* walk() {
for (const i of sl.sub()) {
if (i.enter) {
switch (i.type) {
case _core.Tag.MemberExpression:
if (i.value.varInfo != null && i.value.varInfo.enabled) {
Kit.skip(sl.copy(i));
yield sl.tok(i.pos, T.identifier(i.value.path.join("$")));
continue;
}
break;
case _core.Tag.VariableDeclaration:
if (i.value.vars != null) {
yield sl.peel(i);
yield* walk();
yield* sl.leave();
for (const j of i.value.vars) {
if (j.enabled) {
for (const k of j.used) yield* sl.toks(_core.Tag.push, `let ${j.name}$${k} = ${j.name} && ${j.name}.${k}`);
}
}
continue;
}
}
}
yield i;
}
}
return walk();
});