Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / remoting / webapp / base / js / callstack.js
blobd6e332583622c6c9730f7268feeee8edeef58eb4
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.
5 'use strict';
7 /** @suppress {duplicate} */
8 var base = base || {};
10 /**
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.
20 * @typedef {{
21 * fn: string,
22 * url: string,
23 * file: string,
24 * line: number,
25 * column: number
26 * }}
28 base.StackFrame;
31 (function() {
33 /**
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.
37 * @constructor
39 base.Callstack = function(opt_error) {
40 /** @type {Array<base.StackFrame>} */
41 this.callstack = [];
43 this.getCallstackFromError_(opt_error || new Error());
45 // If no explicit Error was specified, remove this frame from the stack.
46 if (!opt_error) {
47 this.callstack.splice(0, 1);
51 /**
52 * @return {string} The callstack as a newline-separated string.
54 base.Callstack.prototype.toString = function() {
55 /**
56 * @param {base.StackFrame} frame
57 * @return {string}
59 var frameToString = function(frame) {
60 var location = frame.file + ':' + frame.line + ':' + frame.column;
61 if (frame.url) {
62 location = frame.url + '/' + location;
64 if (frame.fn) {
65 location = ' (' + location + ')';
67 return frame.fn + location;
70 return this.callstack.map(frameToString).join('\n');
73 /**
74 * Parse the callstack of the specified Error.
76 * @param {Error} error
77 * @private
79 base.Callstack.prototype.getCallstackFromError_ = function(error) {
80 /**
81 * @param {string} frame
82 * @return {base.StackFrame}
84 var stringToFrame = function(frame) {
85 var result = {};
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
99 // and URL.
100 var urlAndFile = fullUrl.split('/');
101 result.file = urlAndFile.pop();
102 result.url = urlAndFile.join('/');
103 return result;
106 var callstack = error.stack
107 .replace(/^\s+at\s+/gm, '') // Remove 'at' and indentation.
108 .split('\n');
109 callstack.splice(0, 1); // Remove 'Error'
110 this.callstack = callstack.map(stringToFrame);
113 })();