NativeStackTrace.hx 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. package haxe;
  2. import flash.errors.Error;
  3. import haxe.CallStack.StackItem;
  4. /**
  5. Do not use manually.
  6. **/
  7. @:dox(hide)
  8. @:noCompletion
  9. @:allow(haxe.Exception)
  10. class NativeStackTrace {
  11. @:ifFeature('haxe.NativeStackTrace.exceptionStack')
  12. static public inline function saveStack(e:Any):Void {
  13. }
  14. static public inline function callStack():String {
  15. return normalize(new Error().getStackTrace(), 1);
  16. }
  17. static public function exceptionStack():String {
  18. var err:Null<Error> = untyped flash.Boot.lastError;
  19. return err == null ? '' : normalize(err.getStackTrace());
  20. }
  21. static public function toHaxe(native:String, skip:Int = 0):Array<StackItem> {
  22. var a = new Array();
  23. var r = ~/at ([^\/]+?)\$?(\/[^\(]+)?\(\)(\[(.*?):([0-9]+)\])?/;
  24. var rlambda = ~/^MethodInfo-([0-9]+)$/g;
  25. var cnt = 0;
  26. while (r.match(native)) {
  27. native = r.matchedRight();
  28. if(skip > cnt++) {
  29. continue;
  30. }
  31. var cl = r.matched(1).split("::").join(".");
  32. var meth = r.matched(2);
  33. var item;
  34. if (meth == null) {
  35. if (rlambda.match(cl))
  36. item = LocalFunction(Std.parseInt(rlambda.matched(1)));
  37. else
  38. item = Method(cl, "new");
  39. } else
  40. item = Method(cl, meth.substring(1));
  41. if (r.matched(3) != null)
  42. item = FilePos(item, r.matched(4), Std.parseInt(r.matched(5)));
  43. a.push(item);
  44. }
  45. return a;
  46. }
  47. static function normalize(stack:String, skipItems:Int = 0):String {
  48. switch (stack:String).substring(0, 6) {
  49. case 'Error:' | 'Error\n': skipItems += 1;
  50. case _:
  51. }
  52. return skipLines(stack, skipItems);
  53. }
  54. static function skipLines(stack:String, skip:Int, pos:Int = 0):String {
  55. return if(skip > 0) {
  56. pos = stack.indexOf('\n', pos);
  57. return pos < 0 ? '' : skipLines(stack, --skip, pos + 1);
  58. } else {
  59. return stack.substring(pos);
  60. }
  61. }
  62. }