Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: packages/stack_trace/lib/src/frame.dart

Issue 2989763002: Update charted to 0.4.8 and roll (Closed)
Patch Set: Removed Cutch from list of reviewers Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « packages/stack_trace/lib/src/chain.dart ('k') | packages/stack_trace/lib/src/lazy_chain.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library frame;
6
7 import 'package:path/path.dart' as path; 5 import 'package:path/path.dart' as path;
8 6
9 import 'trace.dart'; 7 import 'trace.dart';
10 import 'unparsed_frame.dart'; 8 import 'unparsed_frame.dart';
11 9
12 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21) 10 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21)
13 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42) 11 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42)
14 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart) 12 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart)
15 final _vmFrame = new RegExp(r'^#\d+\s+(\S.*) \((.+?)((?::\d+){0,2})\)$'); 13 final _vmFrame = new RegExp(r'^#\d+\s+(\S.*) \((.+?)((?::\d+){0,2})\)$');
16 14
17 // at Object.stringify (native) 15 // at Object.stringify (native)
18 // at VW.call$0 (http://pub.dartlang.org/stuff.dart.js:560:28) 16 // at VW.call$0 (http://pub.dartlang.org/stuff.dart.js:560:28)
19 // at VW.call$0 (eval as fn 17 // at VW.call$0 (eval as fn
20 // (http://pub.dartlang.org/stuff.dart.js:560:28), efn:3:28) 18 // (http://pub.dartlang.org/stuff.dart.js:560:28), efn:3:28)
21 // at http://pub.dartlang.org/stuff.dart.js:560:28 19 // at http://pub.dartlang.org/stuff.dart.js:560:28
22 final _v8Frame = new RegExp( 20 final _v8Frame =
23 r'^\s*at (?:(\S.*?)(?: \[as [^\]]+\])? \((.*)\)|(.*))$'); 21 new RegExp(r'^\s*at (?:(\S.*?)(?: \[as [^\]]+\])? \((.*)\)|(.*))$');
24 22
25 // http://pub.dartlang.org/stuff.dart.js:560:28 23 // http://pub.dartlang.org/stuff.dart.js:560:28
26 final _v8UrlLocation = new RegExp(r'^(.*):(\d+):(\d+)|native$'); 24 final _v8UrlLocation = new RegExp(r'^(.*):(\d+):(\d+)|native$');
27 25
28 // eval as function (http://pub.dartlang.org/stuff.dart.js:560:28), efn:3:28 26 // eval as function (http://pub.dartlang.org/stuff.dart.js:560:28), efn:3:28
29 // eval as function (http://pub.dartlang.org/stuff.dart.js:560:28) 27 // eval as function (http://pub.dartlang.org/stuff.dart.js:560:28)
30 // eval as function (eval as otherFunction 28 // eval as function (eval as otherFunction
31 // (http://pub.dartlang.org/stuff.dart.js:560:28)) 29 // (http://pub.dartlang.org/stuff.dart.js:560:28))
32 final _v8EvalLocation = new RegExp( 30 final _v8EvalLocation =
33 r'^eval at (?:\S.*?) \((.*)\)(?:, .*?:\d+:\d+)?$'); 31 new RegExp(r'^eval at (?:\S.*?) \((.*)\)(?:, .*?:\d+:\d+)?$');
34 32
35 // .VW.call$0@http://pub.dartlang.org/stuff.dart.js:560 33 // .VW.call$0@http://pub.dartlang.org/stuff.dart.js:560
36 // .VW.call$0("arg")@http://pub.dartlang.org/stuff.dart.js:560 34 // .VW.call$0("arg")@http://pub.dartlang.org/stuff.dart.js:560
37 // .VW.call$0/name<@http://pub.dartlang.org/stuff.dart.js:560 35 // .VW.call$0/name<@http://pub.dartlang.org/stuff.dart.js:560
38 // .VW.call$0@http://pub.dartlang.org/stuff.dart.js:560:36 36 // .VW.call$0@http://pub.dartlang.org/stuff.dart.js:560:36
39 // http://pub.dartlang.org/stuff.dart.js:560 37 // http://pub.dartlang.org/stuff.dart.js:560
40 final _firefoxSafariFrame = new RegExp( 38 final _firefoxSafariFrame = new RegExp(r'^'
41 r'^'
42 r'(?:' // Member description. Not present in some Safari frames. 39 r'(?:' // Member description. Not present in some Safari frames.
43 r'([^@(/]*)' // The actual name of the member. 40 r'([^@(/]*)' // The actual name of the member.
44 r'(?:\(.*\))?' // Arguments to the member, sometimes captured by Firefox. 41 r'(?:\(.*\))?' // Arguments to the member, sometimes captured by Firefox.
45 r'((?:/[^/]*)*)' // Extra characters indicating a nested closure. 42 r'((?:/[^/]*)*)' // Extra characters indicating a nested closure.
46 r'(?:\(.*\))?' // Arguments to the closure. 43 r'(?:\(.*\))?' // Arguments to the closure.
47 r'@' 44 r'@'
48 r')?' 45 r')?'
49 r'(.*?)' // The frame's URL. 46 r'(.*?)' // The frame's URL.
50 r':' 47 r':'
51 r'(\d*)' // The line number. Empty in Safari if it's unknown. 48 r'(\d*)' // The line number. Empty in Safari if it's unknown.
52 r'(?::(\d*))?' // The column number. Not present in older browsers and 49 r'(?::(\d*))?' // The column number. Not present in older browsers and
53 // empty in Safari if it's unknown. 50 // empty in Safari if it's unknown.
54 r'$'); 51 r'$');
55 52
56 // foo/bar.dart 10:11 in Foo._bar 53 // foo/bar.dart 10:11 Foo._bar
57 // http://dartlang.org/foo/bar.dart in Foo._bar 54 // foo/bar.dart 10:11 (anonymous function).dart.fn
58 final _friendlyFrame = new RegExp( 55 // http://dartlang.org/foo/bar.dart Foo._bar
59 r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d]\S*)$'); 56 // data:... 10:11 Foo._bar
57 final _friendlyFrame = new RegExp(r'^(\S+)(?: (\d+)(?::(\d+))?)?\s+([^\d].*)$');
60 58
61 /// A regular expression that matches asynchronous member names generated by the 59 /// A regular expression that matches asynchronous member names generated by the
62 /// VM. 60 /// VM.
63 final _asyncBody = new RegExp(r'<(<anonymous closure>|[^>]+)_async_body>'); 61 final _asyncBody = new RegExp(r'<(<anonymous closure>|[^>]+)_async_body>');
64 62
65 final _initialDot = new RegExp(r"^\."); 63 final _initialDot = new RegExp(r"^\.");
66 64
67 /// A single stack frame. Each frame points to a precise location in Dart code. 65 /// A single stack frame. Each frame points to a precise location in Dart code.
68 class Frame { 66 class Frame {
69 /// The URI of the file in which the code is located. 67 /// The URI of the file in which the code is located.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 if (line == null) return library; 111 if (line == null) return library;
114 if (column == null) return '$library $line'; 112 if (column == null) return '$library $line';
115 return '$library $line:$column'; 113 return '$library $line:$column';
116 } 114 }
117 115
118 /// Returns a single frame of the current stack. 116 /// Returns a single frame of the current stack.
119 /// 117 ///
120 /// By default, this will return the frame above the current method. If 118 /// By default, this will return the frame above the current method. If
121 /// [level] is `0`, it will return the current method's frame; if [level] is 119 /// [level] is `0`, it will return the current method's frame; if [level] is
122 /// higher than `1`, it will return higher frames. 120 /// higher than `1`, it will return higher frames.
123 factory Frame.caller([int level=1]) { 121 factory Frame.caller([int level = 1]) {
124 if (level < 0) { 122 if (level < 0) {
125 throw new ArgumentError("Argument [level] must be greater than or equal " 123 throw new ArgumentError("Argument [level] must be greater than or equal "
126 "to 0."); 124 "to 0.");
127 } 125 }
128 126
129 return new Trace.current(level + 1).frames.first; 127 return new Trace.current(level + 1).frames.first;
130 } 128 }
131 129
132 /// Parses a string representation of a Dart VM stack frame. 130 /// Parses a string representation of a Dart VM stack frame.
133 factory Frame.parseVM(String frame) => _catchFormatException(frame, () { 131 factory Frame.parseVM(String frame) => _catchFormatException(frame, () {
134 // The VM sometimes folds multiple stack frames together and replaces them 132 // The VM sometimes folds multiple stack frames together and replaces th em
135 // with "...". 133 // with "...".
136 if (frame == '...') { 134 if (frame == '...') {
137 return new Frame(new Uri(), null, null, '...'); 135 return new Frame(new Uri(), null, null, '...');
138 } 136 }
139 137
140 var match = _vmFrame.firstMatch(frame); 138 var match = _vmFrame.firstMatch(frame);
141 if (match == null) return new UnparsedFrame(frame); 139 if (match == null) return new UnparsedFrame(frame);
142 140
143 // Get the pieces out of the regexp match. Function, URI and line should 141 // Get the pieces out of the regexp match. Function, URI and line should
144 // always be found. The column is optional. 142 // always be found. The column is optional.
145 var member = match[1] 143 var member = match[1]
146 .replaceAll(_asyncBody, "<async>") 144 .replaceAll(_asyncBody, "<async>")
147 .replaceAll("<anonymous closure>", "<fn>"); 145 .replaceAll("<anonymous closure>", "<fn>");
148 var uri = Uri.parse(match[2]); 146 var uri = Uri.parse(match[2]);
149 147
150 var lineAndColumn = match[3].split(':'); 148 var lineAndColumn = match[3].split(':');
151 var line = lineAndColumn.length > 1 ? int.parse(lineAndColumn[1]) : null; 149 var line =
152 var column = lineAndColumn.length > 2 ? int.parse(lineAndColumn[2]) : null; 150 lineAndColumn.length > 1 ? int.parse(lineAndColumn[1]) : null;
153 return new Frame(uri, line, column, member); 151 var column =
154 }); 152 lineAndColumn.length > 2 ? int.parse(lineAndColumn[2]) : null;
153 return new Frame(uri, line, column, member);
154 });
155 155
156 /// Parses a string representation of a Chrome/V8 stack frame. 156 /// Parses a string representation of a Chrome/V8 stack frame.
157 factory Frame.parseV8(String frame) => _catchFormatException(frame, () { 157 factory Frame.parseV8(String frame) => _catchFormatException(frame, () {
158 var match = _v8Frame.firstMatch(frame); 158 var match = _v8Frame.firstMatch(frame);
159 if (match == null) return new UnparsedFrame(frame); 159 if (match == null) return new UnparsedFrame(frame);
160 160
161 // v8 location strings can be arbitrarily-nested, since it adds a layer of 161 // v8 location strings can be arbitrarily-nested, since it adds a layer of
162 // nesting for each eval performed on that line. 162 // nesting for each eval performed on that line.
163 parseLocation(location, member) { 163 parseLocation(location, member) {
164 var evalMatch = _v8EvalLocation.firstMatch(location); 164 var evalMatch = _v8EvalLocation.firstMatch(location);
165 while (evalMatch != null) { 165 while (evalMatch != null) {
166 location = evalMatch[1]; 166 location = evalMatch[1];
167 evalMatch = _v8EvalLocation.firstMatch(location); 167 evalMatch = _v8EvalLocation.firstMatch(location);
168 } 168 }
169 169
170 if (location == 'native') { 170 if (location == 'native') {
171 return new Frame(Uri.parse('native'), null, null, member); 171 return new Frame(Uri.parse('native'), null, null, member);
172 } 172 }
173 173
174 var urlMatch = _v8UrlLocation.firstMatch(location); 174 var urlMatch = _v8UrlLocation.firstMatch(location);
175 if (urlMatch == null) return new UnparsedFrame(frame); 175 if (urlMatch == null) return new UnparsedFrame(frame);
176 176
177 return new Frame( 177 return new Frame(_uriOrPathToUri(urlMatch[1]), int.parse(urlMatch[2]),
178 _uriOrPathToUri(urlMatch[1]), 178 int.parse(urlMatch[3]), member);
179 int.parse(urlMatch[2]), 179 }
180 int.parse(urlMatch[3]),
181 member);
182 }
183 180
184 // V8 stack frames can be in two forms. 181 // V8 stack frames can be in two forms.
185 if (match[2] != null) { 182 if (match[2] != null) {
186 // The first form looks like " at FUNCTION (LOCATION)". V8 proper lists 183 // The first form looks like " at FUNCTION (LOCATION)". V8 proper list s
187 // anonymous functions within eval as "<anonymous>", while IE10 lists them 184 // anonymous functions within eval as "<anonymous>", while IE10 lists them
188 // as "Anonymous function". 185 // as "Anonymous function".
189 return parseLocation(match[2], 186 return parseLocation(
190 match[1].replaceAll("<anonymous>", "<fn>") 187 match[2],
191 .replaceAll("Anonymous function", "<fn>")); 188 match[1]
192 } else { 189 .replaceAll("<anonymous>", "<fn>")
193 // The second form looks like " at LOCATION", and is used for anonymous 190 .replaceAll("Anonymous function", "<fn>")
194 // functions. 191 .replaceAll("(anonymous function)", "<fn>"));
195 return parseLocation(match[3], "<fn>"); 192 } else {
196 } 193 // The second form looks like " at LOCATION", and is used for anonymou s
197 }); 194 // functions.
195 return parseLocation(match[3], "<fn>");
196 }
197 });
198 198
199 /// Parses a string representation of a JavaScriptCore stack trace. 199 /// Parses a string representation of a JavaScriptCore stack trace.
200 factory Frame.parseJSCore(String frame) => new Frame.parseV8(frame); 200 factory Frame.parseJSCore(String frame) => new Frame.parseV8(frame);
201 201
202 /// Parses a string representation of an IE stack frame. 202 /// Parses a string representation of an IE stack frame.
203 /// 203 ///
204 /// IE10+ frames look just like V8 frames. Prior to IE10, stack traces can't 204 /// IE10+ frames look just like V8 frames. Prior to IE10, stack traces can't
205 /// be retrieved. 205 /// be retrieved.
206 factory Frame.parseIE(String frame) => new Frame.parseV8(frame); 206 factory Frame.parseIE(String frame) => new Frame.parseV8(frame);
207 207
208 /// Parses a string representation of a Firefox stack frame. 208 /// Parses a string representation of a Firefox stack frame.
209 factory Frame.parseFirefox(String frame) => _catchFormatException(frame, () { 209 factory Frame.parseFirefox(String frame) => _catchFormatException(frame, () {
210 var match = _firefoxSafariFrame.firstMatch(frame); 210 var match = _firefoxSafariFrame.firstMatch(frame);
211 if (match == null) return new UnparsedFrame(frame); 211 if (match == null) return new UnparsedFrame(frame);
212 212
213 // Normally this is a URI, but in a jsshell trace it can be a path. 213 // Normally this is a URI, but in a jsshell trace it can be a path.
214 var uri = _uriOrPathToUri(match[3]); 214 var uri = _uriOrPathToUri(match[3]);
215 215
216 var member; 216 var member;
217 if (match[1] != null) { 217 if (match[1] != null) {
218 member = match[1]; 218 member = match[1];
219 member += 219 member +=
220 new List.filled('/'.allMatches(match[2]).length, ".<fn>").join(); 220 new List.filled('/'.allMatches(match[2]).length, ".<fn>").join();
221 if (member == '') member = '<fn>'; 221 if (member == '') member = '<fn>';
222 222
223 // Some Firefox members have initial dots. We remove them for consistency 223 // Some Firefox members have initial dots. We remove them for consiste ncy
224 // with other platforms. 224 // with other platforms.
225 member = member.replaceFirst(_initialDot, ''); 225 member = member.replaceFirst(_initialDot, '');
226 } else { 226 } else {
227 member = '<fn>'; 227 member = '<fn>';
228 } 228 }
229 229
230 var line = match[4] == '' ? null : int.parse(match[4]); 230 var line = match[4] == '' ? null : int.parse(match[4]);
231 var column = match[5] == null || match[5] == '' ? 231 var column =
232 null : int.parse(match[5]); 232 match[5] == null || match[5] == '' ? null : int.parse(match[5]);
233 return new Frame(uri, line, column, member); 233 return new Frame(uri, line, column, member);
234 }); 234 });
235 235
236 /// Parses a string representation of a Safari 6.0 stack frame. 236 /// Parses a string representation of a Safari 6.0 stack frame.
237 @Deprecated("Use Frame.parseSafari instead.") 237 @Deprecated("Use Frame.parseSafari instead.")
238 factory Frame.parseSafari6_0(String frame) => new Frame.parseFirefox(frame); 238 factory Frame.parseSafari6_0(String frame) => new Frame.parseFirefox(frame);
239 239
240 /// Parses a string representation of a Safari 6.1+ stack frame. 240 /// Parses a string representation of a Safari 6.1+ stack frame.
241 @Deprecated("Use Frame.parseSafari instead.") 241 @Deprecated("Use Frame.parseSafari instead.")
242 factory Frame.parseSafari6_1(String frame) => new Frame.parseFirefox(frame); 242 factory Frame.parseSafari6_1(String frame) => new Frame.parseFirefox(frame);
243 243
244 /// Parses a string representation of a Safari stack frame. 244 /// Parses a string representation of a Safari stack frame.
245 factory Frame.parseSafari(String frame) => new Frame.parseFirefox(frame); 245 factory Frame.parseSafari(String frame) => new Frame.parseFirefox(frame);
246 246
247 /// Parses this package's string representation of a stack frame. 247 /// Parses this package's string representation of a stack frame.
248 factory Frame.parseFriendly(String frame) => _catchFormatException(frame, () { 248 factory Frame.parseFriendly(String frame) => _catchFormatException(frame, () {
249 var match = _friendlyFrame.firstMatch(frame); 249 var match = _friendlyFrame.firstMatch(frame);
250 if (match == null) { 250 if (match == null) {
251 throw new FormatException( 251 throw new FormatException(
252 "Couldn't parse package:stack_trace stack trace line '$frame'."); 252 "Couldn't parse package:stack_trace stack trace line '$frame'.");
253 } 253 }
254 // Fake truncated data urls generated by the friendly stack trace format
255 // cause Uri.parse to throw an exception so we have to special case them .
256 var uri = match[1] == 'data:...'
257 ? new Uri.dataFromString('')
258 : Uri.parse(match[1]);
259 // If there's no scheme, this is a relative URI. We should interpret it as
260 // relative to the current working directory.
261 if (uri.scheme == '') {
262 uri = path.toUri(path.absolute(path.fromUri(uri)));
263 }
254 264
255 var uri = Uri.parse(match[1]); 265 var line = match[2] == null ? null : int.parse(match[2]);
256 // If there's no scheme, this is a relative URI. We should interpret it as 266 var column = match[3] == null ? null : int.parse(match[3]);
257 // relative to the current working directory. 267 return new Frame(uri, line, column, match[4]);
258 if (uri.scheme == '') { 268 });
259 uri = path.toUri(path.absolute(path.fromUri(uri)));
260 }
261
262 var line = match[2] == null ? null : int.parse(match[2]);
263 var column = match[3] == null ? null : int.parse(match[3]);
264 return new Frame(uri, line, column, match[4]);
265 });
266 269
267 /// A regular expression matching an absolute URI. 270 /// A regular expression matching an absolute URI.
268 static final _uriRegExp = new RegExp(r'^[a-zA-Z][-+.a-zA-Z\d]*://'); 271 static final _uriRegExp = new RegExp(r'^[a-zA-Z][-+.a-zA-Z\d]*://');
269 272
270 /// A regular expression matching a Windows path. 273 /// A regular expression matching a Windows path.
271 static final _windowsRegExp = new RegExp(r'^([a-zA-Z]:[\\/]|\\\\)'); 274 static final _windowsRegExp = new RegExp(r'^([a-zA-Z]:[\\/]|\\\\)');
272 275
273 /// Converts [uriOrPath], which can be a URI, a Windows path, or a Posix path, 276 /// Converts [uriOrPath], which can be a URI, a Windows path, or a Posix path,
274 /// to a URI (absolute if possible). 277 /// to a URI (absolute if possible).
275 static Uri _uriOrPathToUri(String uriOrPath) { 278 static Uri _uriOrPathToUri(String uriOrPath) {
(...skipping 21 matching lines...) Expand all
297 return body(); 300 return body();
298 } on FormatException catch (_) { 301 } on FormatException catch (_) {
299 return new UnparsedFrame(text); 302 return new UnparsedFrame(text);
300 } 303 }
301 } 304 }
302 305
303 Frame(this.uri, this.line, this.column, this.member); 306 Frame(this.uri, this.line, this.column, this.member);
304 307
305 String toString() => '$location in $member'; 308 String toString() => '$location in $member';
306 } 309 }
OLDNEW
« no previous file with comments | « packages/stack_trace/lib/src/chain.dart ('k') | packages/stack_trace/lib/src/lazy_chain.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698