OLD | NEW |
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; | 5 library frame; |
6 | 6 |
7 | 7 |
8 import 'package:pathos/path.dart' as path; | 8 import 'package:pathos/path.dart' as path; |
9 | 9 |
10 import 'trace.dart'; | 10 import 'trace.dart'; |
11 | 11 |
12 // #1 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21) | 12 final _nativeFrameRegExp = new RegExp( |
13 final _vmFrame = new RegExp( | |
14 r'^#\d+\s+([^\s].*) \((.+):(\d+):(\d+)\)$'); | 13 r'^#\d+\s+([^\s].*) \((.+):(\d+):(\d+)\)$'); |
15 | 14 |
16 // at VW.call$0 (http://pub.dartlang.org/stuff.dart.js:560:28) | |
17 // at http://pub.dartlang.org/stuff.dart.js:560:28 | |
18 final _v8Frame = new RegExp( | |
19 r'^\s*at (?:([^\s].*) \((.+):(\d+):(\d+)\)|(.+):(\d+):(\d+))$'); | |
20 | |
21 // .VW.call$0@http://pub.dartlang.org/stuff.dart.js:560 | |
22 // .VW.call$0("arg")@http://pub.dartlang.org/stuff.dart.js:560 | |
23 // .VW.call$0/name<@http://pub.dartlang.org/stuff.dart.js:560 | |
24 final _firefoxFrame = new RegExp( | |
25 r'^([^@(/]*)(?:\(.*\))?(/[^<]*<)?(?:\(.*\))?@(.*):(\d+)$'); | |
26 | |
27 final _initialDot = new RegExp(r"^\."); | |
28 | |
29 /// A single stack frame. Each frame points to a precise location in Dart code. | 15 /// A single stack frame. Each frame points to a precise location in Dart code. |
30 class Frame { | 16 class Frame { |
31 /// The URI of the file in which the code is located. | 17 /// The URI of the file in which the code is located. |
32 /// | 18 /// |
33 /// This URI will usually have the scheme `dart`, `file`, `http`, or `https`. | 19 /// This URI will usually have the scheme `dart`, `file`, `http`, or `https`. |
34 final Uri uri; | 20 final Uri uri; |
35 | 21 |
36 /// The line number on which the code location is located. | 22 /// The line number on which the code location is located. |
37 /// | 23 /// |
38 /// This can be null, indicating that the line number is unknown or | 24 /// This can be null, indicating that the line number is unknown or |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 /// higher than `1`, it will return higher frames. | 69 /// higher than `1`, it will return higher frames. |
84 factory Frame.caller([int level=1]) { | 70 factory Frame.caller([int level=1]) { |
85 if (level < 0) { | 71 if (level < 0) { |
86 throw new ArgumentError("Argument [level] must be greater than or equal " | 72 throw new ArgumentError("Argument [level] must be greater than or equal " |
87 "to 0."); | 73 "to 0."); |
88 } | 74 } |
89 | 75 |
90 return new Trace.current(level + 1).frames.first; | 76 return new Trace.current(level + 1).frames.first; |
91 } | 77 } |
92 | 78 |
93 /// Parses a string representation of a Dart VM stack frame. | 79 /// Parses a string representation of a stack frame. |
94 factory Frame.parseVM(String frame) { | 80 /// |
95 var match = _vmFrame.firstMatch(frame); | 81 /// [frame] should be formatted in the same way as a native stack trace frame. |
| 82 factory Frame.parse(String frame) { |
| 83 var match = _nativeFrameRegExp.firstMatch(frame); |
96 if (match == null) { | 84 if (match == null) { |
97 throw new FormatException("Couldn't parse VM stack trace line '$frame'."); | 85 throw new FormatException("Couldn't parse stack trace line '$frame'."); |
98 } | 86 } |
99 | 87 |
100 var uri = Uri.parse(match[2]); | 88 var uri = Uri.parse(match[2]); |
101 var member = match[1].replaceAll("<anonymous closure>", "<fn>"); | 89 var member = match[1].replaceAll("<anonymous closure>", "<fn>"); |
102 return new Frame(uri, int.parse(match[3]), int.parse(match[4]), member); | 90 return new Frame(uri, int.parse(match[3]), int.parse(match[4]), member); |
103 } | 91 } |
104 | 92 |
105 /// Parses a string representation of a Chrome/V8 stack frame. | |
106 factory Frame.parseV8(String frame) { | |
107 var match = _v8Frame.firstMatch(frame); | |
108 if (match == null) { | |
109 throw new FormatException("Couldn't parse V8 stack trace line '$frame'."); | |
110 } | |
111 | |
112 // V8 stack frames can be in two forms. | |
113 if (match[2] != null) { | |
114 // The first form looks like " at FUNCTION (URI:LINE:COL)" | |
115 var uri = Uri.parse(match[2]); | |
116 var member = match[1].replaceAll("<anonymous>", "<fn>"); | |
117 return new Frame(uri, int.parse(match[3]), int.parse(match[4]), member); | |
118 } else { | |
119 // The second form looks like " at URI:LINE:COL", and is used for | |
120 // anonymous functions. | |
121 var uri = Uri.parse(match[5]); | |
122 return new Frame(uri, int.parse(match[6]), int.parse(match[7]), "<fn>"); | |
123 } | |
124 } | |
125 | |
126 /// Parses a string representation of a Firefox stack frame. | |
127 factory Frame.parseFirefox(String frame) { | |
128 var match = _firefoxFrame.firstMatch(frame); | |
129 if (match == null) { | |
130 throw new FormatException( | |
131 "Couldn't parse Firefox stack trace line '$frame'."); | |
132 } | |
133 | |
134 var uri = Uri.parse(match[3]); | |
135 var member = match[1]; | |
136 if (member == "") { | |
137 member = "<fn>"; | |
138 } else if (match[2] != null) { | |
139 member = "$member.<fn>"; | |
140 } | |
141 // Some Firefox members have initial dots. We remove them for consistency | |
142 // with other platforms. | |
143 member = member.replaceFirst(_initialDot, ''); | |
144 return new Frame(uri, int.parse(match[4]), null, member); | |
145 } | |
146 | |
147 Frame(this.uri, this.line, this.column, this.member); | 93 Frame(this.uri, this.line, this.column, this.member); |
148 | 94 |
149 String toString() => '$location in $member'; | 95 String toString() => '$location in $member'; |
150 } | 96 } |
OLD | NEW |