art-standard-lib
Version:
The Standard Library for JavaScript that aught to be.
100 lines (86 loc) • 2.83 kB
text/coffeescript
{isString} = require './TypesExtended'
{parseUrl} = require './ParseUrl'
# TODO: switch to using https://github.com/stacktracejs/stacktrace.js
module.exports = class CallStack
@errorToString: (error) ->
error?.error || error?.message || (isString(error) && error) || Neptune.Art.StandardLib.formattedInspect error
@CallStackLine: class CallStackLine
@getter: (map) ->
Object.defineProperty @::, prop, {get: getter, configurable: yes} for prop, getter of map
@setter: (map) ->
Object.defineProperty @::, prop, {set: setter, configurable: yes} for prop, setter of map
constructor: (line) ->
@original = line
@function = null
@source = null
@class = null
@classPath = null
@sourceFileName = null
@sourcePath = null
@sourceHostWithPort = null
@sourceLine = 0
@sourceColumn = 0
if @parseLineWithFunction line
else @parseLineWithoutFunction line
@subParseFunction()
@subParseSource()
toString: -> @original
@getter
fileWithLocation: -> @_fileWithLocation ||=
if @sourceFileName
"#{@sourcePath}/#{@sourceFileName}:#{@sourceLine}:#{@sourceColumn}"
else
@original
#################
# PRIVATE
#################
# example: "at myFunc (http://0.0.0.0:9000/scripts/spec/art/foundation/call_stack.js:10:30)"
parseLineWithFunction: (line) ->
if r = line.match ///
\s*at\s
((new\s)?[a-zA-Z0-9_.<>]+)
\s\(
([^)]*)
:([0-9]+)
:([0-9]+)
\)
///
@function = r[1]
@source = r[3]
@sourceLine = r[4] | 0
@sourceColumn = r[5] | 0
parseLineWithoutFunction: (line) ->
if r = line.match ///
\s*at\s
([^)]*)
:([0-9]+)
:([0-9]+)
///
@source = r[1]
@sourceLine = r[2] | 0
@sourceColumn = r[3] | 0
subParseSource: ->
if @source
url = parseUrl @source
@sourceFileName = url.fileName
@sourcePath = url.path
@sourceHostWithPort = url.hostWithPort
subParseFunction: ->
if @function
f = @function.split "."
@function = f[f.length-1]
@function = undefined if @function == "<anonymous>"
@class = f[f.length-2]
@classPath = f.slice 0, f.length-2
@rawCallStack: if (new Error).stack
(ignoreTop = 0)->
(new Error).stack.split(/\n */).slice ignoreTop + 2
else
# MSIE11 doesn't support getting the stack until the error is thrown
(ignoreTop = 0)->
try
throw new Error
catch e
e.stack.split(/\n */).slice ignoreTop + 2
@callStack: (ignoreTop = 0)->
new CallStackLine line for line in CallStack.rawCallStack ignoreTop + 1