function getCellCodeAndReferences(cell) {
const { walk } = parser;
const { simple } = acornWalk;
let bodyText = cell.input.substring(cell.body.start, cell.body.end);
const _getRefName = (ref) => {
if (!ref) return null;
if (ref.type === "ViewExpression") {
return "viewof " + ref.id.name;
} else if (ref.type === "MutableExpression") {
return "mutable " + ref.id.name;
} else return ref.name;
};
const references = (cell.references || []).map(_getRefName);
let $count = 0;
let indexShift = 0;
const _updateText = (node, $string) => {
const start = node.start - cell.body.start;
const end = node.end - cell.body.start;
bodyText =
bodyText.slice(0, start + indexShift) +
$string +
bodyText.slice(end + indexShift);
indexShift += $string.length - (end - start);
};
const codeReferences = (cell.references || []).map((ref) => {
if (ref.type === "ViewExpression") {
const $string = "$" + $count++;
simple(
cell.body,
{
ViewExpression(node) {
_updateText(node, $string);
}
},
walk
);
return $string;
} else if (ref.type === "MutableExpression") {
const $string = "$" + $count++;
simple(
cell.body,
{
MutableExpression(node) {
_updateText(node, $string + ".value");
}
},
walk
);
return $string;
} else return ref.name;
});
let code;
if (cell.body.type !== "BlockStatement") {
if (cell.async) code = `${bodyText}`;
else code = `{\nreturn (${bodyText});\n}`;
} else code = `${bodyText}`;
const refs = codeReferences.join(",");
const name = _getRefName(cell.id);
const functionName = name ? name.replace(/\s/gim, "_") : ``;
if (cell.generator && cell.async)
code = `async function* ${functionName}(${refs}) ${code}`;
else if (cell.async) code = `async function ${functionName}(${refs}) ${code}`;
else if (cell.generator) code = `function* ${functionName}(${refs}) ${code}`;
else code = `function ${functionName}(${refs}) ${code} `;
return { references, code };
}