@effectful/transducers
Version:
JS syntax transformation framework for @effectful/js
423 lines (419 loc) • 15.3 kB
JavaScript
;
exports.__esModule = true;
exports.ccg = ccg;
exports.cg = cg;
exports.cleanComments = cleanComments;
exports.color = void 0;
exports.copyComment = copyComment;
exports.dumpToConsole = exports.dumpDoc = void 0;
exports.dumpToStr = dumpToStr;
exports.fin = void 0;
exports.markNodeType = markNodeType;
exports.setComment = setComment;
exports.setEndComment = setEndComment;
exports.tempNames = tempNames;
exports.tempNamesRange = tempNamesRange;
exports.traceLazy = exports.traceDoc = exports.traceAll = void 0;
exports.verify = verify;
var _generator = require("@babel/generator");
var T = require("@babel/types");
var _config = require("./config");
var _types2 = require("./types");
var _combinators = require("./combinators");
var _core = require("./core");
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
const MAX_TRACE_CODE_LEN = 40;
const enterStyles = "background: #222; color: #bada55;font-size:1.5em";
const leaveStyles = "color: #ee5757; background: black";
const newTagStyle = "color:purple;font-size:large";
const positionStyle = "color:gray;text-decoration:underline";
const dirStyle = "font-size:x-large;font-weight:bolder";
function defaultReplacer(n, v) {
return n === "leadingComments" || n === "trailingComments" ? void 0 : v;
}
/**
* outputs short description of AST node
*/
function cg(ast, opts = {}) {
var res;
if (ast == null) {
// console.error("<NULL>")
return "<NULL>";
}
try {
if (Array.isArray(ast)) {
ast = ast.length > 0 && T.isExpression(ast[0]) ? T.sequenceExpression(ast) : T.blockStatement(ast);
}
res = (0, _generator.default)(ast, opts, "").code;
} catch (e) {
if (ast.type != null) console.log("ERROR:", e.stack);
}
if (res != null) {
return res;
}
return "!!" + opts.compact ? JSON.stringify(ast, defaultReplacer) : JSON.stringify(ast, defaultReplacer, 2);
}
/**
* same as `cg` but using compact syntax
*/
function ccg(ast) {
return cg(ast, {
compact: true
});
}
if (_config.default.debug) {
global.cg = cg;
global.ccg = ccg;
}
function* verify(s) {
const stack = [];
for (const {
start,
value: i
} of (0, _core.hier)((0, _core.dft)((0, _core.resetFieldInfo)((0, _core.fromIterable)(s))))) {
(0, _types2.invariant)(i.pos != null);
(0, _types2.invariant)(i.type != null);
const ti = (0, _types2.typeInfo)(i);
const ctrlPos = (0, _types2.symInfo)(i.pos).kind === "ctrl";
if (start) {
if (stack.length) {
const [f, keys] = stack[stack.length - 1];
if (f.type === _types2.Tag.Array) {
if (!ctrlPos) (0, _types2.invariant)(i.pos === _types2.Tag.push);
} else if (keys != null && !ctrlPos) {
let k;
while ((k = keys.shift()) != null) {
if (_types2.Tag[k] === i.pos) break;
}
(0, _types2.invariant)(k);
}
}
if (i.fieldInfo != null) {
if (i.type === _types2.Tag.Array) {
(0, _types2.invariant)(i.fieldInfo.array);
}
}
const keys = T.VISITOR_KEYS[(0, _types2.symName)(i.type)];
stack.push([i, keys && _toConsumableArray(keys)]);
yield i;
} else {
const [f] = stack.pop();
(0, _types2.invariant)(f != null);
if (ti.kind !== "ctrl") (0, _types2.invariant)(f.type === i.type);
(0, _types2.invariant)(f.pos === i.pos);
(0, _types2.invariant)(f === i);
}
}
(0, _types2.invariant)(stack.length === 0);
}
function pad(s) {
if (s.length % 2) s += " ";
const sps = Array(Math.max(20 - s.length / 2, 2)).join(" ");
return sps + s + sps;
}
const traceImpl = _config.default.color ? browserTraceImpl : traceNodeImpl;
function traceDocImpl(prefix, root) {
(0, _core.skip)(traceImpl(prefix, (0, _core.dft)(root)));
return root;
}
function* traceNodeImpl(prefix, s) {
let x = 0;
const chalk = require("chalk");
for (const {
start,
value: i
} of (0, _core.hier)(s)) {
const dir = chalk.bold(start ? "\\" : "/");
const clevel = `${i.level}`;
const descr = `${chalk.green((0, _types2.symName)(i.pos))}:${i.type.ctrl ? chalk.green((0, _types2.symName)(i.type)) : chalk.green.bold((0, _types2.symName)(i.type))}[${clevel}]`;
let n = "";
const {
node
} = i;
const comments = [];
let commentsTxt = "";
const t = [].concat(i.comments || [], i.tcomments || []);
if (t.length) {
if (comments.length) commentsTxt = chalk.bold("[") + comments.join(" ") + chalk.bold("]");
}
if (node != null && i.type !== _types2.Tag.Array && (0, _types2.symKind)(i.type) !== "ctrl") {
n = ccg(node);
if (n.length > MAX_TRACE_CODE_LEN) n = n.substr(0, MAX_TRACE_CODE_LEN) + "...";
n = chalk.yellow(n);
const {
loc
} = node;
if (loc != null) {
let {
source: f,
start: s,
end: e
} = loc;
n += chalk.blue(` @${f || "?"}-${s.line}:${s.column}..${e.line}:${e.column}`);
} else {
n += chalk.bold(" @new");
}
}
console.log(prefix, Array(i.level).join(" "), dir, `${descr}@${x}`, commentsTxt, n);
if (start) yield i;
x++;
}
console.log(prefix, "len:", x);
}
function* browserTraceImpl(prefix, s) {
let x = 0;
let first = true;
for (const {
start,
value: i
} of (0, _core.hier)(s)) {
var _console;
if (first) {
first = false;
let name = (0, _types2.symName)(i.type);
if (i.funcId) name += ":" + i.funcId.id;
console.log(`%c${pad(prefix + " " + name.match(/[A-Z]/g).join(""))}%c`, `background:#2B81AF;color:#fff;font-size:xx-large;
text-shadow:rgba(0, 0, 0, 0.5) 2px 2px 1px`, "");
if (i.parent) console.log("ROOT", i.parent);
console.log("SCOPE", i);
}
const styles = [];
const dir = start ? "\u2192" : "\u2190";
const clevel = `${i.level}`;
const tp = i.pos === i.type ? (0, _types2.symName)(i.type) : `${(0, _types2.symName)(i.pos)}:${(0, _types2.symName)(i.type)}`;
const descr = `${prefix}${tp}[${clevel}]`;
const idtxt = i.id ? `-${i.id}` : "";
let ldescr;
if (i.pos === i.type) {
ldescr = `${prefix}%c${(0, _types2.symName)(i.type)}%c[${clevel}]`;
styles.push((0, _types2.symKind)(i.type) === "ctrl" ? "color:navy;font-size:large" : "color:steelblue", "");
} else {
ldescr = `${prefix}%c${(0, _types2.symName)(i.pos)}:%c${(0, _types2.symName)(i.type)}%c[${clevel}]`;
styles.push((0, _types2.symKind)(i.pos) === "ctrl" ? "color:olive;font-size:large" : "color:green");
styles.push((0, _types2.symKind)(i.type) === "ctrl" ? "color:navy;font-size:large" : "color:steelblue", "");
}
if (start && console.group != null) {
if (x === 0 && i.collapsed !== false || i.collapsed) console.groupCollapsed(descr);else console.group(descr);
}
let n = "";
const {
node
} = i;
const comments = [];
let commentsTxt = "";
const t = [].concat(i.comments || [], i.tcomments || []);
if (t.length) {
const pstyle = "color:green;font-size:large";
styles.push(pstyle);
for (const j of t) {
comments.push(`%c${j.txt}%c`);
const mod = !i.enter ? "font-size:small;font-style:italic" : "font-weight:bolder;font-size:large";
const s = `${j.style || ""}${mod}`;
styles.push(s, "");
}
if (comments.length) {
commentsTxt = "%c[" + comments.join(" ") + "%c]%c";
styles.push(pstyle, "");
}
}
if (node != null && i.type !== _types2.Tag.Array && (0, _types2.symKind)(i.type) !== "ctrl") {
n = ccg(node);
if (n.length > MAX_TRACE_CODE_LEN) n = n.substr(0, MAX_TRACE_CODE_LEN) + "...";
n = `%c ${n} %c`;
styles.push(i.enter ? enterStyles : leaveStyles, "");
const {
loc
} = node;
if (loc != null) {
let {
source: f,
start: s,
end: e
} = loc;
n += ` %c@${f || "?"}-${s.line}:${s.column}..${e.line}:${e.column}%c`;
styles.push(positionStyle, "");
} else {
n += " %c@new%c";
styles.push(newTagStyle, "");
}
}
(_console = console).log.apply(_console, [`%c${dir}%c ${ldescr}@${x}${idtxt}${commentsTxt} ${n}`, dirStyle, ""].concat(styles, [i]));
if (start) yield i;else console.groupEnd();
x++;
}
console.log(`${prefix}len: ${x}`);
}
function traceAllImpl(prefix, s) {
return _toConsumableArray(prefix[0] === "!" ? traceImpl(prefix, s) : verify(traceImpl(prefix, s)));
}
function traceArgs(impl) {
return function traceImpl(prefix, s) {
if (prefix == null || prefix.substr == null) {
if (s == null) s = prefix;
prefix = "";
}
if (prefix.length) prefix += ":";
if (s == null) return s => impl(prefix, s);
return impl(prefix, s);
};
}
function* cleanComments(s) {
for (const i of s) {
if (i.enter) {
i.comments = null;
i.tcomments = null;
if (i.node) {
i.node.leadingComments = null;
i.node.trailingComments = null;
}
}
yield i;
}
}
const traceLazy = exports.traceLazy = traceArgs(traceImpl);
const traceAll = exports.traceAll = traceArgs(traceAllImpl);
const traceDoc = exports.traceDoc = traceArgs(traceDocImpl);
function* markNodeType(s) {
for (const i of s) {
const ti = (0, _types2.typeInfo)(i);
if (ti.kind === "ctrl") (i.comments || (i.comments = [])).unshift({
txt: (0, _types2.symName)(i.type),
style: styles.nodetype
});else if (i.comments != null && i.comments.length) {
(i.comments || (i.comments = [])).unshift({
txt: (0, _types2.symName)(i.type).match(/[A-Z]/g).join(""),
style: styles.nodetype
});
}
yield i;
}
}
const color = exports.color = _config.default.browserDebug ? function* color(s) {
if (!_config.default.color) {
yield* s;
return;
}
for (const i of (0, _core.hier)(s)) {
if (i.start && i.value.comments) {
for (const j of i.value.comments) {
if (j.style != null && (0, _types2.typeInfo)(i).kind === "node") {
j.txt = `%c${j.txt}%c`;
j.args = [j.style, ""];
}
}
}
if (!i.start && i.value.tcomments) {
for (const j of i.value.tcomments) {
if (j.style != null && (0, _types2.typeInfo)(i).kind === "node") {
j.txt = `%c${j.txt}%c`;
j.args = [j.style, ""];
}
}
}
if (i.start) yield i.value;
}
} : s => s;
function* getArgs(s) {
for (const i of (0, _core.hier)(s)) {
if (i.start && i.value.comments) {
for (const j of i.value.comments) {
if (j.args) for (const k of j.args) yield k;
}
}
if (!i.start && i.value.tcomments) {
for (const j of i.value.tcomments) {
if (j.args) for (const k of j.args) yield k;
}
}
}
}
function* applyComments(s) {
for (const i of (0, _core.hier)(s)) {
const node = i.value.node;
if (i.start && node != null) {
if (i.value.comments != null && i.value.comments.length) {
(node.leadingComments || (node.leadingComments = [])).push({
type: "CommentBlock",
value: i.value.comments.map(v => v.txt).join("|")
});
}
if (!i.start && i.value.tcomments != null && i.value.tcomments.length) {
(node.trailingComments || (node.trailingComments = [])).push({
type: "CommentBlock",
value: i.value.tcomments.map(v => v.txt).join("|")
});
}
}
if (i.start) yield i.value;
}
}
const dumpToConsole = exports.dumpToConsole = (0, _combinators.curry)(function toConsole(tag, s) {
var _console2;
s = (0, _core.lookahead)(s);
const root = s.buf;
let name = (0, _types2.symName)(root.type).match(/[A-Z]/g).join("");
if (root.funcId) name += ":" + root.funcId.id;
if (_config.default.browserDebug) (tag[0] === "+" ? console.group : console.groupCollapsed)(`dump %c${tag} %c${name}`, "color:orange;font-size:large", "color:coral");else console.log(`dump ${tag}`);
const col = (0, _combinators.pipe)(color, tempNames, _core.toArray, applyComments, _core.toArray)(s);
const args = Array.from(getArgs(col));
(0, _core.consume)((0, _core.fromIterable)(verify(col)));
(_console2 = console).log.apply(_console2, [(0, _generator.default)(col[0].node).code].concat(args));
if (_config.default.browserDebug) console.groupEnd();
});
const dumpDoc = exports.dumpDoc = (0, _combinators.curry)(function (tag, root) {
dumpToConsole(tag, (0, _core.dft)(root));
return root;
});
const fin = exports.fin = (0, _combinators.pipe)(tempNames, applyComments, _core.toArray);
function dumpToStr(s, opts = {}) {
return (0, _generator.default)((0, _core.consume)(s), opts).code;
}
function setComment(i, txt, style = "none") {
style = style.substr && styles[style] || style;
(i.comments || (i.comments = [])).push({
txt,
style
});
return i;
}
function setEndComment(i, txt, style = "none") {
style = style.substr && styles[style] || style;
(i.tcomments || (i.tcomments = [])).push({
txt,
style
});
return i;
}
function copyComment(f, t) {
var _ref, _ref2;
if (f.comments != null) (_ref = t.comments || (t.comments = [])).push.apply(_ref, _toConsumableArray(f.comments));
if (f.tcomments != null) (_ref2 = t.tcomments || (t.tcomments = [])).push.apply(_ref2, _toConsumableArray(f.tcomments));
return t;
}
const styles = {
large: "font-size:xx-large;color:orange",
hl: "font-size:large;color:navy;",
small: "font-size:large;color:navy;",
smallH: "font-size:large;color:orange;font-weight:bolder",
nodetype: "font-size:xx-small;color:green;font-weight:bolder",
none: ""
};
/**
* sets temporal `node.name` for each Identifier for debug dumps outputs
*/
function* tempNames(s) {
for (const i of s) {
if (i.type === _types2.Tag.Identifier && i.sym != null && (!i.node.name || i.node.name !== i.sym.orig)) i.node.name = i.sym.strict ? i.sym.name : i.sym.id;
yield i;
}
}
function tempNamesRange(from, to) {
for (const i of (0, _core.dft)(from, to)) {
if (i.type === _types2.Tag.Identifier && i.sym != null && (!i.node.name || i.node.name !== i.sym.orig)) i.node.name = i.sym.strict ? i.sym.name : i.sym.id;
}
}