@lcap/nasl
Version:
NetEase Application Specific Language
243 lines • 10.7 kB
JavaScript
;
// 查找引用,指用户点击 “查找引用” 这一 “产品功能”,不是 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