class CustomTrace {
final StackTrace _trace;
String fileName;
String functionName;
String callerFunctionName;
int lineNumber;
int columnNumber;
CustomTrace(this._trace) {
_parseTrace();
}
String _getFunctionNameFromFrame(String frame) {
/* Just giving another nickname to the frame */
var currentTrace = frame;
/* To get rid off the #number thing, get the index of the first whitespace */
var indexOfWhiteSpace = currentTrace.indexOf(' ');
/* Create a substring from the first whitespace index till the end of the string */
var subStr = currentTrace.substring(indexOfWhiteSpace);
/* Grab the function name using reg expr */
var indexOfFunction = subStr.indexOf(RegExp(r'[A-Za-z0-9]'));
/* Create a new substring from the function name index till the end of string */
subStr = subStr.substring(indexOfFunction);
indexOfWhiteSpace = subStr.indexOf(' ');
/* Create a new substring from start to the first index of a whitespace. This substring gives us the function name */
subStr = subStr.substring(0, indexOfWhiteSpace);
return subStr;
}
void _parseTrace() {
/* The trace comes with multiple lines of strings, (each line is also known as a frame), so split the trace's string by lines to get all the frames */
var frames = this._trace.toString().split("\n");
/* The first frame is the current function */
this.functionName = _getFunctionNameFromFrame(frames[0]);
/* The second frame is the caller function */
this.callerFunctionName = _getFunctionNameFromFrame(frames[1]);
/* The first frame has all the information we need */
var traceString = frames[0];
/* Search through the string and find the index of the file name by looking for the '.dart' regex */
var indexOfFileName = traceString.indexOf(RegExp(r'[A-Za-z]+.dart'));
var fileInfo = traceString.substring(indexOfFileName);
var listOfInfos = fileInfo.split(":");
/* Splitting fileInfo by the character ":" separates the file name, the line number and the column counter nicely.
Example: main.dart:5:12
To get the file name, we split with ":" and get the first index
To get the line number, we would have to get the second index
To get the column number, we would have to get the third index
*/
this.fileName = listOfInfos[0];
this.lineNumber = int.parse(listOfInfos[1]);
var columnStr = listOfInfos[2];
columnStr = columnStr.replaceFirst(")", "");
this.columnNumber = int.parse(columnStr);
}
}
字符串 这个类接受一个StackTrace对象,读取它的字符串并解析它。 如何使用它(获取信息):
void main() {
CustomTrace programInfo = CustomTrace(StackTrace.current);
print("Source file: ${programInfo.fileName}, function: ${programInfo.functionName}, caller function: ${programInfo.callerFunctionName}, current line of code since the instanciation/creation of the custom trace object: ${programInfo.lineNumber}, even the column(yay!): ${programInfo.columnNumber}");
}
/*
Define regex for each entry in the stack
group 0: full line
group 1: stack index
group 2: function name
group 3: package
group 4: file name
group 5: line number
group 6: column number
*/
RegExp regExp = new RegExp(r'^#(\d+) +(.+) +\(package:([^/]+)/(.+\.\w):(\d+):(\d+)\)$');
/* Get the stack as an array of strings */
var frames = StackTrace.current.toString().split("\n");
/* The second entry in the stack is the caller function */
var matches = regExp.allMatches(frames[1])
/* The regex matches each line of the stack only once so only one match */
var match = matches.elementAt(0);
/* Print all groups. Note that "groupCount" doesn't include group 0 (the whole line) */
for (int i = 0; i <= match.groupCount; i++) {
print("group $i: " + match.group(i));
}
6条答案
按热度按时间atmip9wb1#
我写了一个简单的类,它给出了当前函数和调用函数,以及StackTrace.current属性中的文件名、行号和列行。
验证码:
字符串
这个类接受一个StackTrace对象,读取它的字符串并解析它。
如何使用它(获取信息):
型
变量 programInfo 现在有函数名、调用者函数名、行号、列号,甚至是当前程序执行的文件名。
您可以将以下内容打印到控制台:
型
你会看到字符串的样子,并能够理解我如何解析字符串,以获得信息。
这样做的好处是你不需要安装任何库。我这样做是因为我正在做一个只使用Dart的项目,我不想在我的简单项目中添加/安装任何第三方库。你最终会得到一个对象,只需调用构造函数就可以获得所有信息。这样做的缺点是,如果Dart出于某种原因,改变堆栈跟踪的字符串格式,这将不再起作用,但如果这种情况发生,你可以很容易地改变这个类解析帧的方式 */
注意:这段代码绝不是最优化的代码,但它工作正常:D.我希望看到一些更好的实现和抽象。
7vux5j2d2#
无法直接访问Dart反射库中的调用堆栈。
你可以得到堆栈跟踪的字符串表示,然后尝试解析它:
字符串
stack_trace包尝试为您对许多已知的堆栈跟踪格式执行此操作,因此可能:
型
siv3szwd3#
整理了一下@LuisDev99的答案,为自己优化:
olhwl3o24#
字符串
另见https://github.com/dart-lang/sdk/issues/11916#issuecomment-108381556
这只在Dart命令行VM中有效,但在浏览器或Flutter中无效,因为不支持反射。
像https://pub.dartlang.org/packages/reflectable这样的代码生成解决方案可能在反射不可用的地方起作用。
https://github.com/dart-lang/sdk/issues/28372似乎相关。
yqkkidmi5#
LuisDev99的答案不能很好地科普内部方法和匿名lambda块,所以我使用了更复杂的正则表达式方法。
我的解决方案:
字符串
vnjpjtjt6#
在我的例子中,我只需要Flutter中调用者的类和函数名。
字符串
打印
SampleClass.someMethod ::: RED