OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library frame; |
| 6 |
| 7 import 'dart:uri'; |
| 8 |
| 9 import 'package:pathos/path.dart' as path; |
| 10 |
| 11 import 'trace.dart'; |
| 12 |
| 13 final _nativeFrameRegExp = new RegExp( |
| 14 r'^#\d+\s+([^\s].*) \((.+):(\d+):(\d+)\)$'); |
| 15 |
| 16 /// A single stack frame. Each frame points to a precise location in Dart code. |
| 17 class Frame { |
| 18 /// The URI of the file in which the code is located. |
| 19 /// |
| 20 /// This URI will usually have the scheme `dart`, `file`, `http`, or `https`. |
| 21 final Uri uri; |
| 22 |
| 23 /// The line number on which the code location is located. |
| 24 final int line; |
| 25 |
| 26 /// The column number of the code location. |
| 27 final int column; |
| 28 |
| 29 /// The name of the member in which the code location occurs. |
| 30 /// |
| 31 /// Anonymous closures are represented as `<fn>` in this member string. |
| 32 final String member; |
| 33 |
| 34 /// Whether this stack frame comes from the Dart core libraries. |
| 35 bool get isCore => uri.scheme == 'dart'; |
| 36 |
| 37 /// Returns a human-friendly description of the library that this stack frame |
| 38 /// comes from. |
| 39 /// |
| 40 /// This will usually be the string form of [uri], but a relative path will be |
| 41 /// used if possible. |
| 42 String get library { |
| 43 // TODO(nweiz): handle relative URIs here as well once pathos supports that. |
| 44 if (uri.scheme != 'file') return uri.toString(); |
| 45 return path.relative(uri.path); |
| 46 } |
| 47 |
| 48 /// A human-friendly description of the code location. |
| 49 /// |
| 50 /// For Dart core libraries, this will omit the line and column information, |
| 51 /// since those are useless for baked-in libraries. |
| 52 String get location { |
| 53 if (isCore) return library; |
| 54 return '$library $line:$column'; |
| 55 } |
| 56 |
| 57 /// Returns a single frame of the current stack. |
| 58 /// |
| 59 /// By default, this will return the frame above the current method. If |
| 60 /// [level] is `0`, it will return the current method's frame; if [level] is |
| 61 /// higher than `1`, it will return higher frames. |
| 62 factory Frame.caller([int level=1]) { |
| 63 if (level < 0) { |
| 64 throw new ArgumentError("Argument [level] must be greater than or equal " |
| 65 "to 0."); |
| 66 } |
| 67 |
| 68 return new Trace.current(level + 1).frames.first; |
| 69 } |
| 70 |
| 71 /// Parses a string representation of a stack frame. |
| 72 /// |
| 73 /// [frame] should be formatted in the same way as a native stack trace frame. |
| 74 factory Frame.parse(String frame) { |
| 75 var match = _nativeFrameRegExp.firstMatch(frame); |
| 76 if (match == null) { |
| 77 throw new FormatException("Couldn't parse stack trace line '$frame'."); |
| 78 } |
| 79 |
| 80 var uri = new Uri.fromString(match[2]); |
| 81 var member = match[1].replaceAll("<anonymous closure>", "<fn>"); |
| 82 return new Frame(uri, int.parse(match[3]), int.parse(match[4]), member); |
| 83 } |
| 84 |
| 85 Frame(this.uri, this.line, this.column, this.member); |
| 86 |
| 87 String toString() => '$location in $member'; |
| 88 } |
OLD | NEW |