Make the StackTrace library better handle core library frames.
Core library stack frames now have libraries and meaningful line numbers, so in
general we should preserve those. However, terse stack traces don't care about
the internal workings of the core libraries, so they now explicitly remove the
library and line number information.
R=rnystrom@google.com
Review URL: https://codereview.chromium.org//16097012
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/stack_trace@23621 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/stack_trace/lib/src/frame.dart b/pkgs/stack_trace/lib/src/frame.dart
index 335bfba..8f1931b 100644
--- a/pkgs/stack_trace/lib/src/frame.dart
+++ b/pkgs/stack_trace/lib/src/frame.dart
@@ -21,9 +21,15 @@
final Uri uri;
/// The line number on which the code location is located.
+ ///
+ /// This can be null, indicating that the line number is unknown or
+ /// unimportant.
final int line;
/// The column number of the code location.
+ ///
+ /// This can be null, indicating that the column number is unknown or
+ /// unimportant.
final int column;
/// The name of the member in which the code location occurs.
@@ -53,11 +59,8 @@
}
/// A human-friendly description of the code location.
- ///
- /// For Dart core libraries, this will omit the line and column information,
- /// since those are useless for baked-in libraries.
String get location {
- if (isCore) return library;
+ if (line == null || column == null) return library;
return '$library $line:$column';
}
diff --git a/pkgs/stack_trace/lib/src/trace.dart b/pkgs/stack_trace/lib/src/trace.dart
index 4ed1563..db0e70b 100644
--- a/pkgs/stack_trace/lib/src/trace.dart
+++ b/pkgs/stack_trace/lib/src/trace.dart
@@ -10,7 +10,7 @@
import 'frame.dart';
import 'lazy_trace.dart';
-final _patchRegExp = new RegExp(r"-patch$");
+final _terseRegExp = new RegExp(r"(-patch)?(/.*)?$");
/// A stack trace, comprised of a list of stack frames.
class Trace implements StackTrace {
@@ -79,15 +79,16 @@
/// native stack traces.
String get fullStackTrace => toString();
- /// Returns a terser version of [this]. This is accomplished by folding
- /// together multiple stack frames from the core library, as in [foldFrames].
- /// Core library patches are also renamed to remove their `-patch` suffix.
+ /// Returns a terser version of [this].
+ ///
+ /// This is accomplished by folding together multiple stack frames from the
+ /// core library, as in [foldFrames]. Remaining core library frames have their
+ /// libraries, "-patch" suffixes, and line numbers removed.
Trace get terse {
return new Trace(foldFrames((frame) => frame.isCore).frames.map((frame) {
if (!frame.isCore) return frame;
- var library = frame.library.replaceAll(_patchRegExp, '');
- return new Frame(
- Uri.parse(library), frame.line, frame.column, frame.member);
+ var library = frame.library.replaceAll(_terseRegExp, '');
+ return new Frame(Uri.parse(library), null, null, frame.member);
}));
}
diff --git a/pkgs/stack_trace/test/frame_test.dart b/pkgs/stack_trace/test/frame_test.dart
index 512f6d0..d1f53f6 100644
--- a/pkgs/stack_trace/test/frame_test.dart
+++ b/pkgs/stack_trace/test/frame_test.dart
@@ -59,13 +59,13 @@
expect(() => new Frame.parse(''), throwsFormatException);
expect(() => new Frame.parse('#1'), throwsFormatException);
expect(() => new Frame.parse('#1 Foo'), throwsFormatException);
- expect(() => new Frame.parse('#1 Foo (dart:async)'),
+ expect(() => new Frame.parse('#1 Foo (dart:async/future.dart)'),
throwsFormatException);
- expect(() => new Frame.parse('#1 Foo (dart:async:10)'),
+ expect(() => new Frame.parse('#1 Foo (dart:async/future.dart:10)'),
throwsFormatException);
- expect(() => new Frame.parse('#1 (dart:async:10:15)'),
+ expect(() => new Frame.parse('#1 (dart:async/future.dart:10:15)'),
throwsFormatException);
- expect(() => new Frame.parse('Foo (dart:async:10:15)'),
+ expect(() => new Frame.parse('Foo (dart:async/future.dart:10:15)'),
throwsFormatException);
});
@@ -75,9 +75,12 @@
expect(isCore('dart:core'), isTrue);
expect(isCore('dart:async'), isTrue);
+ expect(isCore('dart:core/uri.dart'), isTrue);
+ expect(isCore('dart:async/future.dart'), isTrue);
expect(isCore('bart:core'), isFalse);
expect(isCore('sdart:core'), isFalse);
expect(isCore('darty:core'), isFalse);
+ expect(isCore('bart:core/uri.dart'), isFalse);
});
group('.caller()', () {
@@ -104,8 +107,8 @@
group('.library', () {
test('returns the URI string for non-file URIs', () {
- expect(new Frame.parse('#0 Foo (dart:async:0:0)').library,
- equals('dart:async'));
+ expect(new Frame.parse('#0 Foo (dart:async/future.dart:0:0)').library,
+ equals('dart:async/future.dart'));
expect(new Frame.parse('#0 Foo '
'(http://dartlang.org/stuff/thing.dart:0:0)').library,
equals('http://dartlang.org/stuff/thing.dart'));
@@ -128,18 +131,12 @@
expect(new Frame.parse('#0 Foo ($uri:1:2)').location,
equals('${path.join('foo', 'bar.dart')} 1:2'));
});
-
- test('just returns the library for core libraries', () {
- expect(new Frame.parse('#0 Foo (dart:core:5:10)').location,
- equals('dart:core'));
- expect(new Frame.parse('#0 Foo (dart:async-patch:1:2)').location,
- equals('dart:async-patch'));
- });
});
group('.package', () {
test('returns null for non-package URIs', () {
- expect(new Frame.parse('#0 Foo (dart:async:0:0)').package, isNull);
+ expect(new Frame.parse('#0 Foo (dart:async/future.dart:0:0)').package,
+ isNull);
expect(new Frame.parse('#0 Foo '
'(http://dartlang.org/stuff/thing.dart:0:0)').package,
isNull);
@@ -161,15 +158,10 @@
equals('http://dartlang.org/thing.dart 5:10 in Foo'));
});
- test('just returns the library for core libraries', () {
- expect(new Frame.parse('#0 Foo (dart:core:5:10)').toString(),
- equals('dart:core in Foo'));
- });
-
test('converts "<anonymous closure>" to "<fn>"', () {
- expect(new Frame.parse('#0 Foo.<anonymous closure> (dart:core:5:10)')
- .toString(),
- equals('dart:core in Foo.<fn>'));
+ expect(new Frame.parse('#0 Foo.<anonymous closure> '
+ '(dart:core/uri.dart:5:10)').toString(),
+ equals('dart:core/uri.dart 5:10 in Foo.<fn>'));
});
});
}
diff --git a/pkgs/stack_trace/test/trace_test.dart b/pkgs/stack_trace/test/trace_test.dart
index afd5700..902ae80 100644
--- a/pkgs/stack_trace/test/trace_test.dart
+++ b/pkgs/stack_trace/test/trace_test.dart
@@ -35,13 +35,13 @@
test('parses a stack trace correctly', () {
var trace = new Trace.parse('''
#0 Foo._bar (file:///home/nweiz/code/stuff.dart:42:21)
-#1 zip.<anonymous closure>.zap (dart:async:0:2)
+#1 zip.<anonymous closure>.zap (dart:async/future.dart:0:2)
#2 zip.<anonymous closure>.zap (http://pub.dartlang.org/thing.dart:1:100)
''');
expect(trace.frames[0].uri,
equals(Uri.parse("file:///home/nweiz/code/stuff.dart")));
- expect(trace.frames[1].uri, equals(Uri.parse("dart:async")));
+ expect(trace.frames[1].uri, equals(Uri.parse("dart:async/future.dart")));
expect(trace.frames[2].uri,
equals(Uri.parse("http://pub.dartlang.org/thing.dart")));
});
@@ -94,13 +94,13 @@
var uri = pathToFileUri(path.join('foo', 'bar.dart'));
var trace = new Trace.parse('''
#0 Foo._bar ($uri:42:21)
-#1 zip.<anonymous closure>.zap (dart:async:0:2)
+#1 zip.<anonymous closure>.zap (dart:async/future.dart:0:2)
#2 zip.<anonymous closure>.zap (http://pub.dartlang.org/thing.dart:1:100)
''');
expect(trace.toString(), equals('''
${path.join('foo', 'bar.dart')} 42:21 Foo._bar
-dart:async zip.<fn>.zap
+dart:async/future.dart 0:2 zip.<fn>.zap
http://pub.dartlang.org/thing.dart 1:100 zip.<fn>.zap
'''));
});
@@ -118,11 +118,11 @@
test('.terse folds core frames together bottom-up', () {
var trace = new Trace.parse('''
#0 notCore (foo.dart:42:21)
-#1 top (dart:async:0:2)
-#2 bottom (dart:core:1:100)
+#1 top (dart:async/future.dart:0:2)
+#2 bottom (dart:core/uri.dart:1:100)
#3 alsoNotCore (bar.dart:10:20)
#4 top (dart:io:5:10)
-#5 bottom (dart:async-patch:9:11)
+#5 bottom (dart:async-patch/future.dart:9:11)
''');
expect(trace.terse.toString(), equals('''
@@ -139,16 +139,16 @@
#1 fooTop (bar.dart:0:2)
#2 fooBottom (foo.dart:1:100)
#3 alsoNotFoo (bar.dart:10:20)
-#4 fooTop (dart:io:5:10)
-#5 fooBottom (dart:async-patch:9:11)
+#4 fooTop (dart:io/socket.dart:5:10)
+#5 fooBottom (dart:async-patch/future.dart:9:11)
''');
var folded = trace.foldFrames((frame) => frame.member.startsWith('foo'));
expect(folded.toString(), equals('''
-foo.dart 42:21 notFoo
-foo.dart 1:100 fooBottom
-bar.dart 10:20 alsoNotFoo
-dart:async-patch fooBottom
+foo.dart 42:21 notFoo
+foo.dart 1:100 fooBottom
+bar.dart 10:20 alsoNotFoo
+dart:async-patch/future.dart 9:11 fooBottom
'''));
});
}