stackframe.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. (function(root, factory) {
  2. 'use strict';
  3. // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers.
  4. /* istanbul ignore next */
  5. if (typeof define === 'function' && define.amd) {
  6. define('stackframe', [], factory);
  7. } else if (typeof exports === 'object') {
  8. module.exports = factory();
  9. } else {
  10. root.StackFrame = factory();
  11. }
  12. }(this, function() {
  13. 'use strict';
  14. function _isNumber(n) {
  15. return !isNaN(parseFloat(n)) && isFinite(n);
  16. }
  17. function _capitalize(str) {
  18. return str.charAt(0).toUpperCase() + str.substring(1);
  19. }
  20. function _getter(p) {
  21. return function() {
  22. return this[p];
  23. };
  24. }
  25. var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel'];
  26. var numericProps = ['columnNumber', 'lineNumber'];
  27. var stringProps = ['fileName', 'functionName', 'source'];
  28. var arrayProps = ['args'];
  29. var props = booleanProps.concat(numericProps, stringProps, arrayProps);
  30. function StackFrame(obj) {
  31. if (obj instanceof Object) {
  32. for (var i = 0; i < props.length; i++) {
  33. if (obj.hasOwnProperty(props[i]) && obj[props[i]] !== undefined) {
  34. this['set' + _capitalize(props[i])](obj[props[i]]);
  35. }
  36. }
  37. }
  38. }
  39. StackFrame.prototype = {
  40. getArgs: function() {
  41. return this.args;
  42. },
  43. setArgs: function(v) {
  44. if (Object.prototype.toString.call(v) !== '[object Array]') {
  45. throw new TypeError('Args must be an Array');
  46. }
  47. this.args = v;
  48. },
  49. getEvalOrigin: function() {
  50. return this.evalOrigin;
  51. },
  52. setEvalOrigin: function(v) {
  53. if (v instanceof StackFrame) {
  54. this.evalOrigin = v;
  55. } else if (v instanceof Object) {
  56. this.evalOrigin = new StackFrame(v);
  57. } else {
  58. throw new TypeError('Eval Origin must be an Object or StackFrame');
  59. }
  60. },
  61. toString: function() {
  62. var functionName = this.getFunctionName() || '{anonymous}';
  63. var args = '(' + (this.getArgs() || []).join(',') + ')';
  64. var fileName = this.getFileName() ? ('@' + this.getFileName()) : '';
  65. var lineNumber = _isNumber(this.getLineNumber()) ? (':' + this.getLineNumber()) : '';
  66. var columnNumber = _isNumber(this.getColumnNumber()) ? (':' + this.getColumnNumber()) : '';
  67. return functionName + args + fileName + lineNumber + columnNumber;
  68. }
  69. };
  70. for (var i = 0; i < booleanProps.length; i++) {
  71. StackFrame.prototype['get' + _capitalize(booleanProps[i])] = _getter(booleanProps[i]);
  72. StackFrame.prototype['set' + _capitalize(booleanProps[i])] = (function(p) {
  73. return function(v) {
  74. this[p] = Boolean(v);
  75. };
  76. })(booleanProps[i]);
  77. }
  78. for (var j = 0; j < numericProps.length; j++) {
  79. StackFrame.prototype['get' + _capitalize(numericProps[j])] = _getter(numericProps[j]);
  80. StackFrame.prototype['set' + _capitalize(numericProps[j])] = (function(p) {
  81. return function(v) {
  82. if (!_isNumber(v)) {
  83. throw new TypeError(p + ' must be a Number');
  84. }
  85. this[p] = Number(v);
  86. };
  87. })(numericProps[j]);
  88. }
  89. for (var k = 0; k < stringProps.length; k++) {
  90. StackFrame.prototype['get' + _capitalize(stringProps[k])] = _getter(stringProps[k]);
  91. StackFrame.prototype['set' + _capitalize(stringProps[k])] = (function(p) {
  92. return function(v) {
  93. this[p] = String(v);
  94. };
  95. })(stringProps[k]);
  96. }
  97. return StackFrame;
  98. }));