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

Unified Diff: pkg/stack_trace/lib/src/trace.dart

Issue 13102003: Add a library for manipulating stack traces. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 7 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/stack_trace/lib/src/frame.dart ('k') | pkg/stack_trace/lib/stack_trace.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/stack_trace/lib/src/trace.dart
diff --git a/pkg/stack_trace/lib/src/trace.dart b/pkg/stack_trace/lib/src/trace.dart
new file mode 100644
index 0000000000000000000000000000000000000000..1ab7695b996d279b8115e243e89007ae68fa7c53
--- /dev/null
+++ b/pkg/stack_trace/lib/src/trace.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library trace;
+
+import 'dart:uri';
+
+import 'frame.dart';
+
+final _patchRegExp = new RegExp(r"-patch$");
+
+/// A stack trace, comprised of a list of stack frames.
+class Trace implements StackTrace {
+ // TODO(nweiz): make this read-only once issue 8321 is fixed.
+ /// The stack frames that comprise this stack trace.
+ final List<Frame> frames;
+
+ /// Returns a human-readable representation of [stackTrace]. If [terse] is
+ /// set, this folds together multiple stack frames from the Dart core
+ /// libraries, so that only the core library method directly called from user
+ /// code is visible (see [Trace.terse]).
+ static String format(StackTrace stackTrace, {bool terse: true}) {
+ var trace = new Trace.from(stackTrace);
+ if (terse) trace = trace.terse;
+ return trace.toString();
+ }
+
+ /// Returns the current stack trace.
+ ///
+ /// By default, the first frame of this trace will be the line where
+ /// [Trace.current] is called. If [level] is passed, the trace will start that
+ /// many frames up instead.
+ factory Trace.current([int level=0]) {
+ if (level < 0) {
+ throw new ArgumentError("Argument [level] must be greater than or equal "
+ "to 0.");
+ }
+
+ try {
+ throw '';
+ } catch (_, nativeTrace) {
+ var trace = new Trace.from(nativeTrace);
+ return new Trace(trace.frames.skip(level + 1));
+ }
+ }
+
+ /// Returns a new stack trace containing the same data as [trace].
+ ///
+ /// If [trace] is a native [StackTrace], its data will be parsed out; if it's
+ /// a [Trace], it will be returned as-is.
+ factory Trace.from(StackTrace trace) {
+ if (trace is Trace) return trace;
+ return new Trace.parse(trace.fullStackTrace);
+ }
+
+ /// Parses a string representation of a stack trace.
+ ///
+ /// [trace] should be formatted in the same way as native stack traces.
+ Trace.parse(String trace)
+ : this(trace.trim().split("\n").map((line) => new Frame.parse(line)));
+
+ /// Returns a new [Trace] comprised of [frames].
+ Trace(Iterable<Frame> frames)
+ : frames = frames.toList();
+
+ // TODO(nweiz): Keep track of which [Frame]s are part of the partial stack
+ // trace and only print them.
+ /// Returns a string representation of this stack trace.
+ ///
+ /// This is identical to [toString]. It will not be formatted in the manner of
+ /// native stack traces.
+ String get stackTrace => toString();
+
+ /// Returns a string representation of this stack trace.
+ ///
+ /// This is identical to [toString]. It will not be formatted in the manner of
+ /// 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. If multiple such
+ /// frames appear in a row, only the last (the one directly called by user
+ /// code) is kept. Core library patches are also renamed to remove their
+ /// `-patch` suffix.
+ Trace get terse {
+ var newFrames = <Frame>[];
+ for (var frame in frames.reversed) {
+ if (!frame.isCore) {
+ newFrames.add(frame);
+ } else if (newFrames.isEmpty || !newFrames.last.isCore) {
+ var library = frame.library.replaceAll(_patchRegExp, '');
+ newFrames.add(new Frame(
+ Uri.parse(library), frame.line, frame.column, frame.member));
+ }
+ }
+
+ return new Trace(newFrames.reversed);
+ }
+
+ /// Returns a human-readable string representation of [this].
+ String toString() {
+ if (frames.length == '') return '';
+
+ // Figure out the longest path so we know how much to pad.
+ var longest = frames.map((frame) => frame.location.length).max();
+
+ // Print out the stack trace nicely formatted.
+ return frames.map((frame) {
+ return '${_padRight(frame.location, longest)} ${frame.member}\n';
+ }).join();
+ }
+}
+
+/// Returns [string] with enough spaces added to the end to make it [length]
+/// characters long.
+String _padRight(String string, int length) {
+ if (string.length >= length) return string;
+
+ var result = new StringBuffer();
+ result.write(string);
+ for (var i = 0; i < length - string.length; i++) {
+ result.write(' ');
+ }
+
+ return result.toString();
+}
« no previous file with comments | « pkg/stack_trace/lib/src/frame.dart ('k') | pkg/stack_trace/lib/stack_trace.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698