UNPKG

@lcap/nasl

Version:

NetEase Application Specific Language

243 lines 10.7 kB
"use strict"; // 查找引用,指用户点击 “查找引用” 这一 “产品功能”,不是 LS 的严格意义的查找引用 // 重命名用的查找引用跟这个一点都不一样,居然直接重新导向了这个查找引用,坑死我啦 var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports._recursionCreateResult = exports.handleTreeQueue = exports.handleTreeMap = exports._getTreeMap = exports.findReferenceAndRender = void 0; const concepts_1 = require("../concepts"); const utils = __importStar(require("../utils")); const nasl_language_server_core_1 = require("@lcap/nasl-language-server-core"); const service_1 = require("@lcap/nasl-concepts/service"); // 用户点击 “查找引用” 这一 “产品功能” const findReferenceAndRender = async (semEnv, __node) => { // 实体逻辑每次都重新生成,内存节点变来变去 const isVirtualNode = (nd) => { if (nd.concept === 'Logic' && nd.getAncestorRaw('Entity')) { return true; } return false; }; let node = toRaw(__node); if (isVirtualNode(__node)) { node = semEnv.refMgr.getNodeDef(__node); } utils.isDebugMode && console.time('\x1b[44m\x1b[97m Find references: find \x1b[0m'); let refs = toRaw(semEnv.refMgr).getReferences(semEnv, node); // 产品上的功能:事件逻辑的 查找引用 能看到自己 if (node.parentNode?.concept === 'BindEvent') { refs.push(node); } // 产品上的功能:子逻辑的 查找引用 能看到自己 if (node.concept === 'SubLogic') { refs.push(node); } // 不显示实体逻辑里的引用 refs = refs.filter(ref => !(0, nasl_language_server_core_1.isEntityLogic)((0, service_1.getFileNode)(ref))); utils.isDebugMode && console.timeEnd('\x1b[44m\x1b[97m Find references: find \x1b[0m'); utils.isDebugMode && console.time('\x1b[44m\x1b[97m Vue UI Interaction: Reshape References \x1b[0m'); // 最后返回的结果 let result = new Map(); // 树的构造,key: 一个file的node, 值是 [[logic, params],[logic, returns]] const resMap = new Map(); // 普通节点和要输出的节点做一个映射,为了引用地址一样 const nodeMap = new Map(); try { refs.forEach(ref => (0, exports._getTreeMap)(ref, resMap, nodeMap)); if (resMap.size > 0) { result = (0, exports.handleTreeMap)(resMap); } } catch (err) { console.error('An error occurred when invoking findReferenceAndRender', err); } utils.isDebugMode && console.timeEnd('\x1b[44m\x1b[97m Vue UI Interaction: Reshape References \x1b[0m'); return result; }; exports.findReferenceAndRender = findReferenceAndRender; // 获取节点的上层渲染 const _getTreeMap = (refNode, resMap, nodeMap) => { let currentNode = refNode; let parentNode = currentNode; // 顺序队列 const queue = []; // 先插入自己,如果没有在往上找, // 一直到file节点的父级 while (parentNode && !(parentNode instanceof concepts_1.App)) { // 找到上一级 在map对象中构造出他的子集 currentNode = toRaw(parentNode); // toRaw 防止渲染时"裂化"成多条路径(有的带 proxy 有的不带 proxy) parentNode = parentNode.parentNode; // 如果第一次就塞入子集和父节点,以后就只用父节点了 // 因为部分节点没有name,先过滤掉 // if (currentNode.name) { // } // 排除一些不放入集合的节点 let isNeedPush = true; // 如果不是ViewElement 或者 Assignment , 或者如果是的话, 排除l-root if (currentNode instanceof concepts_1.ViewElement && currentNode.tag === 'l-root') isNeedPush = false; else if (currentNode instanceof concepts_1.Argument) isNeedPush = false; else if (currentNode instanceof concepts_1.Assignment) isNeedPush = false; else if (currentNode instanceof concepts_1.TypeAnnotation) isNeedPush = false; else if (currentNode instanceof concepts_1.CallQueryComponent) isNeedPush = false; else if (currentNode instanceof concepts_1.QueryFromExpression) isNeedPush = false; else if (currentNode instanceof concepts_1.FieldPermissionV2) { isNeedPush = false; parentNode = null; } // 需要放到数组中 if (isNeedPush) { // 名称 // 赋值图标 let icon = ''; if (currentNode instanceof concepts_1.ViewElement) icon = 'element'; else if (currentNode instanceof concepts_1.BindAttribute) icon = 'attr'; else if (currentNode instanceof concepts_1.Destination) icon = 'logicNode'; else if (currentNode instanceof concepts_1.CallLogic) { icon = 'interface'; } const addToQueueAndNodeMap = (node) => { // 相同节点使用一个引用 if (nodeMap.get(node)) { queue.unshift(nodeMap.get(node)); } else { const quoteNode = { node, expanded: true, icon }; nodeMap.set(node, quoteNode); queue.unshift(quoteNode); } }; addToQueueAndNodeMap(currentNode); if ((concepts_1.asserts.isLogic(currentNode) || concepts_1.asserts.isEntity(currentNode) || concepts_1.asserts.isEnum(currentNode) || concepts_1.asserts.isStructure(currentNode) || concepts_1.asserts.isBusinessComponent(currentNode)) && currentNode.directory) { const directory = toRaw(currentNode.directory); addToQueueAndNodeMap(directory); } } } const addToResMap = (node) => { // 一个logic 或者 view 或者 Directory 可能会有多个顺序队列 if (resMap.get(node)) { // 是否展示两个内容全等,但是两个queue的node可能不一样,但是只需要展示一个 resMap.get(node).push(queue); } else { resMap.set(node, [queue]); } }; if ((concepts_1.asserts.isLogic(currentNode) || concepts_1.asserts.isEntity(currentNode) || concepts_1.asserts.isEnum(currentNode) || concepts_1.asserts.isStructure(currentNode)) && currentNode.directory) { const directory = toRaw(currentNode.directory); addToResMap(directory); } else { addToResMap(currentNode); } }; exports._getTreeMap = _getTreeMap; const handleTreeMap = (resMap) => { const treeNodeMap = new Map(); resMap.forEach((value, fileNode) => { // 循环处理tree的queue const treeObj = (0, exports.handleTreeQueue)(value); treeNodeMap.set(fileNode, treeObj); }); return treeNodeMap; }; exports.handleTreeMap = handleTreeMap; /** * 处理tree的队列,把相同节点进行合并 * 这里把当前二维数组进行一个整合 * @param arr 当前页面下的queue的二维数组,一个数组下有多条链路 * @returns 最后要使用到的节点和对应的子集 */ const handleTreeQueue = (queueLists) => { const map = new Map(); let root = null; if (!queueLists.length) return; for (const queueList of queueLists) { let preNode = null; for (const queueItem of queueList) { if (!map.get(queueItem)) { map.set(queueItem, []); } if (preNode) { const find = map.get(preNode).find((item) => item === queueItem); if (!find) { map.get(preNode).push(queueItem); } } else { root = queueItem; } preNode = queueItem; } } const children = (0, exports._recursionCreateResult)(root, map); return children; }; exports.handleTreeQueue = handleTreeQueue; /** * 递归调用输出结果 * @param root 一个根节点 * @param map 当前所有节点的map对象 * @returns 当前节点,最后输出所有节点 */ const _recursionCreateResult = (root, map) => { const children = (map.get(root) || []).map((item) => (0, exports._recursionCreateResult)(item, map)); if (children && children.length) { if (root.node.concept === 'FrontendType') { const children1 = children.filter(item => item.node.concept !== 'BusinessComponent' && item.node.concept !== 'Directory'); const children2 = children.filter(item => item.node.concept === 'BusinessComponent'); const children3 = children.filter(item => item.node.concept === 'Directory'); root.children = [...children1, ...children2, ...children3]; } else if (root.node.concept === 'View') { const children1 = children.filter(item => item.node.concept === 'Logic'); const children2 = children.filter(item => item.node.concept === 'Directory'); const children3 = children.filter(item => item.node.concept !== 'Logic' && item.node.concept !== 'Directory'); root.children = [...children1, ...children2, ...children3]; } else root.children = children; } return root; }; exports._recursionCreateResult = _recursionCreateResult; const toRaw = (nd) => { // @ts-ignore return nd?.__v_raw ?? nd; }; //# sourceMappingURL=findReference.js.map