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); } } } }