haxe/src/haxe/NativeStackTrace.cs
// Generated by Haxe 4.3.7 (patched: no System.Diagnostics)
#pragma warning disable 109, 114, 219, 429, 168, 162
namespace haxe {
public class NativeStackTrace : global::haxe.lang.HxObject {
public NativeStackTrace(global::haxe.lang.EmptyObject empty) {
}
public NativeStackTrace() {
global::haxe.NativeStackTrace.__hx_ctor_haxe_NativeStackTrace(this);
}
protected static void __hx_ctor_haxe_NativeStackTrace(global::haxe.NativeStackTrace __hx_this) {
}
[System.ThreadStaticAttribute]
public static global::System.Exception exception;
public static void saveStack(object e) {
global::haxe.NativeStackTrace.exception = (global::System.Exception)((object)e);
}
// NOTE: whitelist-safe: return the stack as string (no System.Diagnostics types).
public static string callStack() {
return global::System.Environment.StackTrace;
}
public static string exceptionStack() {
global::System.Exception e = global::haxe.NativeStackTrace.exception;
if (e == null) return null;
return e.StackTrace;
}
// NOTE: signature changed to string, because StackTrace type is forbidden.
public static global::Array<object> toHaxe(string stackText, global::haxe.lang.Null<int> skip) {
int skip1 = (!skip.hasValue) ? 0 : (skip).@value;
global::Array<object> stack = new global::Array<object>(new object[] { });
if (stackText == null) return stack;
// Very simple .NET stacktrace parser:
// lines look like:
// " at Namespace.Type.Method(args) in C:\path\File.cs:line 123"
// " at Namespace.Type.Method(args)"
// We'll map them to haxe.StackItem.Method / FilePos when possible.
string[] lines = stackText.Split(new char[] { '\r', '\n' }, global::System.StringSplitOptions.RemoveEmptyEntries);
int cnt = 0;
for (int i = 0; i < lines.Length; i++) {
string line = lines[i].Trim();
if (line.Length == 0) continue;
// skip first frames if requested
if (skip1 > cnt++) continue;
// Remove leading "at "
if (line.StartsWith("at ")) line = line.Substring(3).TrimStart();
else if (line.StartsWith("at\t")) line = line.Substring(3).TrimStart();
else if (line.StartsWith("at")) {
// sometimes "at" without space
if (line.Length > 2 && char.IsWhiteSpace(line[2])) line = line.Substring(3).TrimStart();
}
string methodPart = line;
string fileName = null;
int lineNumber = -1;
// Try parse " in X:line N"
int inIdx = line.IndexOf(" in ");
if (inIdx >= 0) {
methodPart = line.Substring(0, inIdx).TrimEnd();
string rest = line.Substring(inIdx + 4).Trim();
// rest like "C:\a\b.cs:line 12" OR "/a/b.cs:line 12"
int lineIdx = rest.LastIndexOf(":line ");
if (lineIdx >= 0) {
fileName = rest.Substring(0, lineIdx).Trim();
string num = rest.Substring(lineIdx + 6).Trim();
int parsed;
if (int.TryParse(num, out parsed)) lineNumber = parsed;
} else {
fileName = rest;
}
}
// methodPart like "Namespace.Type.Method(args)"
// We'll split into type + method best-effort.
string typeName = methodPart;
string methodName = methodPart;
int parenIdx = methodPart.IndexOf('(');
string noArgs = (parenIdx >= 0) ? methodPart.Substring(0, parenIdx) : methodPart;
int lastDot = noArgs.LastIndexOf('.');
if (lastDot >= 0) {
typeName = noArgs.Substring(0, lastDot);
methodName = noArgs.Substring(lastDot + 1);
} else {
typeName = "unknown";
methodName = noArgs;
}
global::haxe.StackItem method =
global::haxe.StackItem.Method(typeName, methodName);
if ((fileName != null) || (lineNumber >= 0)) {
stack.push(global::haxe.StackItem.FilePos(method, fileName, lineNumber, default(global::haxe.lang.Null<int>)));
} else {
stack.push(method);
}
}
return stack;
}
}
}