| Index: mojo/public/dart/third_party/source_map_stack_trace/lib/source_map_stack_trace.dart
|
| diff --git a/mojo/public/dart/third_party/source_map_stack_trace/lib/source_map_stack_trace.dart b/mojo/public/dart/third_party/source_map_stack_trace/lib/source_map_stack_trace.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..893135ffca3492cbc8d785afef73b9bc354bdc65
|
| --- /dev/null
|
| +++ b/mojo/public/dart/third_party/source_map_stack_trace/lib/source_map_stack_trace.dart
|
| @@ -0,0 +1,110 @@
|
| +// Copyright (c) 2015, 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 source_map_stack_trace;
|
| +
|
| +import 'package:path/path.dart' as p;
|
| +import 'package:source_maps/source_maps.dart';
|
| +import 'package:stack_trace/stack_trace.dart';
|
| +
|
| +/// Convert [stackTrace], a stack trace generated by dart2js-compiled
|
| +/// JavaScript, to a native-looking stack trace using [sourceMap].
|
| +///
|
| +/// [minified] indicates whether or not the dart2js code was minified. If it
|
| +/// hasn't, this tries to clean up the stack frame member names.
|
| +///
|
| +/// [packageRoot] is the URI (usually a `file:` URI) for the package root that
|
| +/// was used by dart2js. It can be a [String] or a [Uri]. If it's passed, stack
|
| +/// frames from packages will use `package:` URLs.
|
| +///
|
| +/// [sdkRoot] is the URI (usually a `file:` URI) for the SDK containing dart2js.
|
| +/// It can be a [String] or a [Uri]. If it's passed, stack frames from the SDK
|
| +/// will have `dart:` URLs.
|
| +StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
|
| + {bool minified: false, packageRoot, sdkRoot}) {
|
| + if (stackTrace is Chain) {
|
| + return new Chain(stackTrace.traces.map((trace) {
|
| + return new Trace.from(mapStackTrace(sourceMap, trace,
|
| + minified: minified, packageRoot: packageRoot, sdkRoot: sdkRoot));
|
| + }));
|
| + }
|
| +
|
| + if (packageRoot != null && packageRoot is! String && packageRoot is! Uri) {
|
| + throw new ArgumentError(
|
| + 'packageRoot must be a String or a Uri, was "$packageRoot".');
|
| + }
|
| +
|
| + if (sdkRoot != null && sdkRoot is! String && sdkRoot is! Uri) {
|
| + throw new ArgumentError(
|
| + 'sdkRoot must be a String or a Uri, was "$sdkRoot".');
|
| + }
|
| +
|
| + packageRoot = packageRoot == null ? null : packageRoot.toString();
|
| + var sdkLib = sdkRoot == null ? null : "$sdkRoot/lib";
|
| +
|
| + var trace = new Trace.from(stackTrace);
|
| + return new Trace(trace.frames.map((frame) {
|
| + // If there's no line information, there's no way to translate this frame.
|
| + // We could return it as-is, but these lines are usually not useful anyways.
|
| + if (frame.line == null) return null;
|
| +
|
| + // If there's no column, try using the first column of the line.
|
| + var column = frame.column == null ? 0 : frame.column;
|
| +
|
| + // Subtract 1 because stack traces use 1-indexed lines and columns and
|
| + // source maps uses 0-indexed.
|
| + var span = sourceMap.spanFor(frame.line - 1, column - 1);
|
| +
|
| + // If we can't find a source span, ignore the frame. It's probably something
|
| + // internal that the user doesn't care about.
|
| + if (span == null) return null;
|
| +
|
| + var sourceUrl = span.sourceUrl.toString();
|
| + if (sdkRoot != null && p.url.isWithin(sdkLib, sourceUrl)) {
|
| + sourceUrl = "dart:" + p.url.relative(sourceUrl, from: sdkLib);
|
| + } else if (packageRoot != null && p.url.isWithin(packageRoot, sourceUrl)) {
|
| + sourceUrl = "package:" +
|
| + p.url.relative(sourceUrl, from: packageRoot);
|
| + }
|
| +
|
| + return new Frame(
|
| + Uri.parse(sourceUrl),
|
| + span.start.line + 1,
|
| + span.start.column + 1,
|
| + // If the dart2js output is minified, there's no use trying to prettify
|
| + // its member names. Use the span's identifier if available, otherwise
|
| + // use the minified member name.
|
| + minified
|
| + ? (span.isIdentifier ? span.text : frame.member)
|
| + : _prettifyMember(frame.member));
|
| + }).where((frame) => frame != null));
|
| +}
|
| +
|
| +/// Reformats a JS member name to make it look more Dart-like.
|
| +String _prettifyMember(String member) {
|
| + return member
|
| + // Get rid of the noise that Firefox sometimes adds.
|
| + .replaceAll(new RegExp(r"/?<$"), "")
|
| + // Get rid of arity indicators.
|
| + .replaceAll(new RegExp(r"\$\d+$"), "")
|
| + // Convert closures to <fn>.
|
| + .replaceAllMapped(new RegExp(r"(_+)closure\d*\.call$"),
|
| + // The number of underscores before "closure" indicates how nested it
|
| + // is.
|
| + (match) => ".<fn>" * match[1].length)
|
| + // Get rid of explicitly-generated calls.
|
| + .replaceAll(new RegExp(r"\.call$"), "")
|
| + // Get rid of the top-level method prefix.
|
| + .replaceAll(new RegExp(r"^dart\."), "")
|
| + // Get rid of library namespaces.
|
| + .replaceAll(new RegExp(r"[a-zA-Z_0-9]+\$"), "")
|
| + // Get rid of the static method prefix. The class name also exists in the
|
| + // invocation, so we're not getting rid of any information.
|
| + .replaceAll(new RegExp(r"^[a-zA-Z_0-9]+.(static|dart)."), "")
|
| + // Convert underscores after identifiers to dots. This runs the risk of
|
| + // incorrectly converting members that contain underscores, but those are
|
| + // contrary to the style guide anyway.
|
| + .replaceAllMapped(new RegExp(r"([a-zA-Z0-9]+)_"),
|
| + (match) => match[1] + ".");
|
| +}
|
|
|