1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 /** @suppress {duplicate} */
11 * A single stack-frame describing a call-site.
13 * fn: The calling function.
14 * url: URL component of the file name. For extensions, this will typically
15 * be chrome-extension://<id>
16 * file: The file containing the calling function.
17 * line: The line number.
18 * column: The column number.
34 * @param {Error=} opt_error If present, an Error object from which to extract
35 * the callstack; if not specified, the current callstack (excluding this
36 * constructor) will be used.
39 base.Callstack = function(opt_error) {
40 /** @type {Array<base.StackFrame>} */
43 this.getCallstackFromError_(opt_error || new Error());
45 // If no explicit Error was specified, remove this frame from the stack.
47 this.callstack.splice(0, 1);
52 * @return {string} The callstack as a newline-separated string.
54 base.Callstack.prototype.toString = function() {
56 * @param {base.StackFrame} frame
59 var frameToString = function(frame) {
60 var location = frame.file + ':' + frame.line + ':' + frame.column;
62 location = frame.url + '/' + location;
65 location = ' (' + location + ')';
67 return frame.fn + location;
70 return this.callstack.map(frameToString).join('\n');
74 * Parse the callstack of the specified Error.
76 * @param {Error} error
79 base.Callstack.prototype.getCallstackFromError_ = function(error) {
81 * @param {string} frame
82 * @return {base.StackFrame}
84 var stringToFrame = function(frame) {
86 // Function name (optional) and location are separated by a space. If a
87 // function name is present, location is enclosed in parentheses.
88 var fnAndLocation = frame.split(' ');
89 var location = fnAndLocation.pop().replace(/[()]/g, '');
90 result.fn = fnAndLocation.shift() || '';
91 // Location, line and column are separated by colons. Colons are also
92 // used to separate the protocol and URL, so there may be more than two
93 // colons in the location.
94 var fullUrlAndLineAndCol = location.split(':');
95 result.column = parseInt(fullUrlAndLineAndCol.pop(), 10);
96 result.line = parseInt(fullUrlAndLineAndCol.pop(), 10);
97 var fullUrl = fullUrlAndLineAndCol.join(':');
98 // URL and file are separated by slashes. Slashes also separate the protocol
100 var urlAndFile = fullUrl.split('/');
101 result.file = urlAndFile.pop();
102 result.url = urlAndFile.join('/');
106 var callstack = error.stack
107 .replace(/^\s+at\s+/gm, '') // Remove 'at' and indentation.
109 callstack.splice(0, 1); // Remove 'Error'
110 this.callstack = callstack.map(stringToFrame);