window.ShowASTTree = function (data, container) {
container.innerHTML = "";
let fragment = document.createDocumentFragment();
let ul = document.createElement("ul");
fragment.appendChild(ul);
CreateTree(ul, data);
container.appendChild(fragment);
container.onclick = function (e) {
let target = e.target;
if (target.tagName == "SPAN") {
let child = target.parentNode.querySelector("ul");
if (child) {
if (child.style.display == "none") {
child.style.display = "block";
target.parentNode.classList.remove("collapse-node");
target.parentNode.classList.add("expand-node");
} else {
child.style.display = "none";
target.parentNode.classList.remove("expand-node");
target.parentNode.classList.add("collapse-node");
}
}
}
};
}
function scrollTo(ele) {
$("#astJson")[0].scrollTo(0, 0);
let eInfo = ele.getClientRects()
let pInfo = $("#astJson")[0].getClientRects();
$("#astJson")[0].scrollTo(eInfo[0].x - pInfo[0].x, eInfo[0].y - pInfo[0].y)
}
// 节点的翻译
window.typeDescriptions = {
Program: '程序',
VariableDeclaration: '变量声明',
VariableDeclarator: '变量声明符',
Identifier: '标识符',
Literal: '字面量',
FunctionDeclaration: '函数声明',
FunctionExpression: '函数表达式',
ArrowFunctionExpression: '箭头函数表达式',
BlockStatement: '块语句',
ExpressionStatement: '表达式语句',
IfStatement: '条件语句',
SwitchStatement: '选择语句',
SwitchCase: '选择语句块',
WhileStatement: '循环语句',
DoWhileStatement: '循环语句',
ForStatement: '循环语句',
ForInStatement: '循环语句',
ForOfStatement: '循环语句',
BreakStatement: '跳出语句',
ContinueStatement: '继续语句',
ReturnStatement: '返回语句',
ThrowStatement: '抛出异常语句',
TryStatement: '异常捕获语句',
CatchClause: '异常捕获块',
FinallyClause: '最终执行块',
WithStatement: 'with语句',
LabeledStatement: '标签语句',
DebuggerStatement: '调试语句',
EmptyStatement: '空语句',
ThisExpression: 'this表达式',
ArrayExpression: '数组表达式',
ObjectExpression: '对象表达式',
Property: '属性',
UnaryExpression: '一元表达式',
BinaryExpression: '二元表达式',
LogicalExpression: '逻辑表达式',
AssignmentExpression: '赋值表达式',
UpdateExpression: '更新表达式',
MemberExpression: '成员表达式',
ConditionalExpression: '条件表达式',
CallExpression: '调用表达式',
NewExpression: 'new表达式',
SequenceExpression: '序列表达式',
TemplateLiteral: '模板文字',
TaggedTemplateExpression: '标记模板文字表达式',
TemplateElement: '模板元素',
SpreadElement: '扩展元素',
ObjectPattern: '对象模式',
ArrayPattern: '数组模式',
RestElement: '剩余元素',
AssignmentPattern: '赋值模式',
ClassDeclaration: '类声明',
ClassExpression: '类表达式',
ClassBody: '类主体',
MethodDefinition: '方法定义',
ImportDeclaration: '导入声明',
ImportSpecifier: '导入说明符',
ImportDefaultSpecifier: '默认导入说明符',
ImportNamespaceSpecifier: '命名空间导入说明符',
ExportNamedDeclaration: '导出声明',
ExportDefaultDeclaration: '默认导出声明',
ExportAllDeclaration: '全部导出声明',
Super: 'super关键字',
MetaProperty: '元属性',
AwaitExpression: 'await表达式',
YieldExpression: 'yield表达式',
JSXElement: 'JSX元素',
JSXFragment: 'JSX片段',
JSXOpeningElement: 'JSX打开元素',
JSXClosingElement: 'JSX关闭元素',
JSXAttribute: 'JSX属性',
JSXText: 'JSX文本',
JSXExpressionContainer: 'JSX表达式容器',
JSXSpreadAttribute: 'JSX扩展属性',
JSXOpeningFragment: 'JSX打开片段',
JSXClosingFragment: 'JSX关闭片段',
ChainExpression: '链式表达式',
ImportExpression: '导入表达式',
OptionalMemberExpression: '可选成员表达式',
OptionalCallExpression: '可选调用表达式',
PrivateIdentifier: '私有标识符',
StringLiteral: '字符串字面量',
NumericLiteral: '数字字面量',
BooleanLiteral: '布尔字面量',
NullLiteral: 'null字面量',
PrivateName: '私有名称',
BigIntLiteral: '大整数字面量',
RegExpLiteral: '正则表达式字面量',
ArrowParameterPlaceHolder: '箭头参数占位符',
};
function CreateTree(parentContainer, data) {
for (let key in data) {
let item = data[key];
if (key == "loc") continue;
if (key == "start") continue;
if (key == "end") continue;
if (key == "extra") continue;
if (key == "directives") continue;
if (key == "__clone") continue;
if (key == "iid") continue;
if (key == "parent") continue;
if (key == "trailingComments") continue;
if (key == "leadingComments") continue;
if (item) {
if (typeof item === 'object') {
let li = document.createElement("li");
li.classList.add("parent-node");
let showText = "";
if (Array.isArray(data)) {
if (window.typeDescriptions[item.type]) {
showText = `${item.type}(${window.typeDescriptions[item.type]})`;
} else {
showText = item.type;
}
} else {
showText = key;
if (item.type) {
showText = `${key}:${item.type}(${window.typeDescriptions[item.type]})`;
}
}
if (!showText) continue
li.innerHTML = `${showText}`;
let ul = document.createElement("ul");
parentContainer.appendChild(li);
li.appendChild(ul);
CreateTree(ul, item);
} else {
let li = document.createElement("li");
let showText = "";
if (key == "type") {
showText = `${key + ":" + item}(${window.typeDescriptions[item]})`;
} else {
showText = key + ":" + item;
}
if (!showText) continue
li.innerHTML = `${showText}`;
li.classList.add("last-node");
parentContainer.appendChild(li);
}
}
}
}