91 lines
2.0 KiB
TypeScript
91 lines
2.0 KiB
TypeScript
|
|
/**
|
|
* 栈信息
|
|
*/
|
|
class StackInfo {
|
|
|
|
/**
|
|
* 函数名
|
|
*/
|
|
public functionName:string | undefined;
|
|
|
|
/**
|
|
* 文件名
|
|
*/
|
|
public fileName:string | undefined;
|
|
|
|
/**
|
|
* 文件路径
|
|
*/
|
|
public url:string | undefined;
|
|
|
|
public setInfo(functionName:string, fileName:string, url:string):StackInfo {
|
|
this.functionName = functionName;
|
|
this.fileName = fileName;
|
|
this.url = url;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* 获取函数调用栈列表
|
|
*/
|
|
public static getCallStack():StackInfo[] {
|
|
|
|
// 获取堆栈信息
|
|
let stack:string | undefined = new Error().stack;
|
|
|
|
if (stack === void 0) return [];
|
|
|
|
// 去除 Error
|
|
stack = stack.replace(/^(Error)\s/, "");
|
|
|
|
// 获取堆栈信息
|
|
let stackList:string[] = stack.split(/\n/);
|
|
|
|
let callStack:StackInfo[] = [];
|
|
|
|
for(let i = 0; i < stackList.length; i++) {
|
|
|
|
let matcher = stackList[i].match(/^\s+at\s+(.+)\s(\(.+\))/);
|
|
if (matcher === null || matcher.length < 3) continue;
|
|
|
|
let fileName = matcher[2].match(/.+\/(.+\..+:\d+:\d+)\)/);
|
|
if (fileName === null || matcher.length < 2) continue;
|
|
|
|
callStack.push(new StackInfo().setInfo(
|
|
matcher[1], fileName[1], matcher[2]?.replace(/(\(|\))/g, "")
|
|
))
|
|
}
|
|
|
|
// console.log(callStack);
|
|
|
|
return callStack;
|
|
}
|
|
|
|
/**
|
|
* 排除的
|
|
*/
|
|
public static readonly excludeFile:RegExp = /^Logger\.js:\d+:\d+/;
|
|
|
|
/**
|
|
* 获取第一个调用栈
|
|
*/
|
|
public static getFirstStack():StackInfo | undefined {
|
|
|
|
let callStack = this.getCallStack();
|
|
|
|
for(let i = 0; i < callStack.length; i++) {
|
|
|
|
if(!callStack[i].fileName) continue;
|
|
|
|
if(!StackInfo.excludeFile.test(callStack[i].fileName ?? "")) {
|
|
return callStack[i];
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
export default StackInfo;
|
|
export { StackInfo }; |