const wu = require("./wuLib.js");
const {getZ} = require("./wuRestoreZ.js");
const {wxsBeautify} = require("./wuJs.js");
const fs = require('fs');
const path = require("path");
const esprima = require('esprima');
const {VM} = require('vm2');
const escodegen = require('escodegen');
function analyze(core, z, namePool, xPool, fakePool = {}, zMulName = "0") {
function anaRecursion(core, fakePool = {}) {
return analyze(core, z, namePool, xPool, fakePool, zMulName);
}
function push(name, elem) {
namePool[name] = elem;
}
function pushSon(pname, son) {
if (fakePool[pname]) fakePool[pname].son.push(son);
else namePool[pname].son.push(son);
}
for (let ei = 0; ei < core.length; ei++) {
let e = core[ei];
switch (e.type) {
case "ExpressionStatement": {
let f = e.expression;
if (f.callee) {
if (f.callee.type == "Identifier") {
switch (f.callee.name) {
case "_r":
namePool[f.arguments[0].name].v[f.arguments[1].value] = z[f.arguments[2].value];
break;
case "_rz":
namePool[f.arguments[1].name].v[f.arguments[2].value] = z.mul[zMulName][f.arguments[3].value];
break;
case "_":
pushSon(f.arguments[0].name, namePool[f.arguments[1].name]);
break;
case "_2": {
let item = f.arguments[6].value;//def:item
let index = f.arguments[7].value;//def:index
let data = z[f.arguments[0].value];
let key = escodegen.generate(f.arguments[8]).slice(1, -1);//f.arguments[8].value;//def:""
let obj = namePool[f.arguments[5].name];
let gen = namePool[f.arguments[1].name];
if (gen.tag == "gen") {
let ret = gen.func.body.body.pop().argument.name;
anaRecursion(gen.func.body.body, {[ret]: obj});
}
obj.v["wx:for"] = data;
if (index != "index") obj.v["wx:for-index"] = index;
if (item != "item") obj.v["wx:for-item"] = item;
if (key != "") obj.v["wx:key"] = key;
}
break;
case "_2z": {
let item = f.arguments[7].value;//def:item
let index = f.arguments[8].value;//def:index
let data = z.mul[zMulName][f.arguments[1].value];
let key = escodegen.generate(f.arguments[9]).slice(1, -1);//f.arguments[9].value;//def:""
let obj = namePool[f.arguments[6].name];
let gen = namePool[f.arguments[2].name];
if (gen.tag == "gen") {
let ret = gen.func.body.body.pop().argument.name;
anaRecursion(gen.func.body.body, {[ret]: obj});
}
obj.v["wx:for"] = data;
if (index != "index") obj.v["wx:for-index"] = index;
if (item != "item") obj.v["wx:for-item"] = item;
if (key != "") obj.v["wx:key"] = key;
}
break;
case "_ic":
pushSon(f.arguments[5].name, {
tag: "include",
son: [],
v: {src: xPool[f.arguments[0].property.value]}
});
break;
case "_ai": {//template import
let to = Object.keys(fakePool)[0];
if (to) pushSon(to, {
tag: "import",
son: [],
v: {src: xPool[f.arguments[1].property.value]}
});
else throw Error("Unexpected fake pool");
}
break;
case "_af":
//ignore _af
break;
default:
throw Error("Unknown expression callee name " + f.callee.name);
}
} else if (f.callee.type == "MemberExpression") {
if (f.callee.object.name == "cs" || f.callee.property.name == "pop") break;
throw Error("Unknown member expression");
} else throw Error("Unknown callee type " + f.callee.type);
} else if (f.type == "AssignmentExpression" && f.operator == "=") {
//no special use
} else throw Error("Unknown expression statement.");
break;
}
case "VariableDeclaration":
for (let dec of e.declarations) {
if (dec.init.type == "CallExpression") {
switch (dec.init.callee.name) {
case "_n":
push(dec.id.name, {tag: dec.init.arguments[0].value, son: [], v: {}});
break;
case "_v":
push(dec.id.name, {tag: "block", son: [], v: {}});
break;
case "_o":
push(dec.id.name, {
tag: "__textNode__",
textNode: true,
content: z[dec.init.arguments[0].value]
});
break;
case "_oz":
push(dec.id.name, {
tag: "__textNode__",
textNode: true,
content: z.mul[zMulName][dec.init.arguments[1].value]
});
break;
case "_m": {
if (dec.init.arguments[2].elements.length > 0)
throw Error("Noticable generics content: " + dec.init.arguments[2].toString());
let mv = {};
let name = null, base = 0;
for (let x of dec.init.arguments[1].elements) {
let v = x.value;
if (!v && typeof v != "number") {
if (x.type == "UnaryExpression" && x.operator == "-") v = -x.argument.value;
else throw Error("Unknown type of object in _m attrs array: " + x.type);
}
if (name === null) {
name = v;
} else {
if (base + v < 0) mv[name] = null; else {
mv[name] = z[base + v];