C# has:
System.Reflection.MethodBase.GetCurrentMethod().Name
Does Dart have something similar but returns results for both the function that is currently being run as well as the name of the function that called the currently run function.
C# has:
System.Reflection.MethodBase.GetCurrentMethod().Name
Does Dart have something similar but returns results for both the function that is currently being run as well as the name of the function that called the currently run function.
import 'dart:mirrors';
...
MethodMirror methodMirror = reflect(functionOne).function;
See also https://github.com/dart-lang/sdk/issues/11916#issuecomment-108381556
This will only work in the Dart command line VM, but not in the browser or Flutter because there reflection is not supported.
Code generation solutions like https://pub.dartlang.org/packages/reflectable might work instead where reflection is not available.
https://github.com/dart-lang/sdk/issues/28372 seems related.
There is no way to directly access the call stack in the Dart reflection library.
You can get a string representation of the stack trace, and then try to parse that:
var stack = StackTrace.current;
var stackString = "$stack"; // because the only method on StackTrace is toString.
The stack_trace package tries to do this for you for a number of known stack trace formats, so maybe:
import "package:stack_trace";
main() {
print(Trace.current().frames[0].member); // prints "main" unless minified.
}
#function
literal expression in Swift. Is this the appropriate stand-in for this? docs.swift.org/swift-book/ReferenceManual/Expressions.html –
Linsk -O2
optimization flag replaces source names with smaller names in the output, which means that you won't see the original source names in error message or stack traces. –
Cirrocumulus I wrote a simple class that gives the current function and the caller function, but also, the file name, line number and column line from the StackTrace.current property.
Heres the code:
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);
}
}
This class takes in a StackTrace object and reads its string and parse it.
How to use it (get the info):
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}");
}
The variable programInfo now has the function name, the caller function name, line number, column number and even the file name of the current program's execution.
You can print to the console the following:
print(StackTrace.current.toString());
And you will see how the string looks and be able to understand how i parse the string in order to get the information.
The simple benefit of this is that you dont have to install any library. I made this because i was doing a project just using Dart and i didnt want to add/install any third party library into my simple project. And you will end up with an object having all of the information by just calling the constructor. The downside of this is that it if Dart, for some reason, changes the string format of the stack trace somewhere in the future, this will no longer work BUT if this somehow happens, you can easily change how this class parses the frames*/
NOTE: This code by no means is the most optimize code, but it works :D. I would like to see some better implementations and abstractions.
Tidied up @LuisDev99's answer a bit, optimizing for yourself:
class LoggerStackTrace {
const LoggerStackTrace._({
required this.functionName,
required this.callerFunctionName,
required this.fileName,
required this.lineNumber,
required this.columnNumber,
});
factory LoggerStackTrace.from(StackTrace trace) {
final frames = trace.toString().split('\n');
final functionName = _getFunctionNameFromFrame(frames[0]);
final callerFunctionName = _getFunctionNameFromFrame(frames[1]);
final fileInfo = _getFileInfoFromFrame(frames[0]);
return LoggerStackTrace._(
functionName: functionName,
callerFunctionName: callerFunctionName,
fileName: fileInfo[0],
lineNumber: int.parse(fileInfo[1]),
columnNumber: int.parse(fileInfo[2].replaceFirst(')', '')),
);
}
final String functionName;
final String callerFunctionName;
final String fileName;
final int lineNumber;
final int columnNumber;
static List<String> _getFileInfoFromFrame(String trace) {
final indexOfFileName = trace.indexOf(RegExp('[A-Za-z]+.dart'));
final fileInfo = trace.substring(indexOfFileName);
return fileInfo.split(':');
}
static String _getFunctionNameFromFrame(String trace) {
final indexOfWhiteSpace = trace.indexOf(' ');
final subStr = trace.substring(indexOfWhiteSpace);
final indexOfFunction = subStr.indexOf(RegExp('[A-Za-z0-9]'));
return subStr
.substring(indexOfFunction)
.substring(0, subStr.substring(indexOfFunction).indexOf(' '));
}
@override
String toString() {
return 'LoggerStackTrace('
'functionName: $functionName, '
'callerFunctionName: $callerFunctionName, '
'fileName: $fileName, '
'lineNumber: $lineNumber, '
'columnNumber: $columnNumber)';
}
}
print(LoggerStackTrace.from(StackTrace.current).toString());
import 'dart:mirrors';
...
MethodMirror methodMirror = reflect(functionOne).function;
See also https://github.com/dart-lang/sdk/issues/11916#issuecomment-108381556
This will only work in the Dart command line VM, but not in the browser or Flutter because there reflection is not supported.
Code generation solutions like https://pub.dartlang.org/packages/reflectable might work instead where reflection is not available.
https://github.com/dart-lang/sdk/issues/28372 seems related.
LuisDev99's answer doesn't cope well with inner methods and anonymous lambda blocks, so I used a more complex regex approach.
My solution:
/*
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));
}
In my case, I just need the caller's class and function name in Flutter. I wrote a simple parse method as follows.
String getCaller(StackTrace currentStack) {
var stack = currentStack.toString();
var newLineNum = stack.indexOf("\n", 0);
var secondLine = stack.substring(newLineNum + 9, newLineNum + 100);
var endIndex = secondLine.indexOf(" ", 0);
return secondLine.substring(0, endIndex);
}
// Call this method in another function
{
String caller = getCaller(StackTrace.current);
debugPrint("$caller ::: RED");
}
It prints SampleClass.someMethod ::: RED
© 2022 - 2025 — McMap. All rights reserved.