StackTrace mapStackTrace()

in build_web_compilers/web/source_map_stack_trace.dart [24:79]


StackTrace mapStackTrace(Mapping sourceMap, StackTrace stackTrace,
    {List<String?> roots = const []}) {
  if (stackTrace is Chain) {
    return Chain(stackTrace.traces.map(
        (trace) => Trace.from(mapStackTrace(sourceMap, trace, roots: roots))));
  }

  var trace = Trace.from(stackTrace);
  return 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.
    var line = frame.line;
    if (line == null) return null;

    // If there's no column, try using the first column of the line.
    var column = frame.column ?? 0;

    // Subtract 1 because stack traces use 1-indexed lines and columns and
    // source maps uses 0-indexed.
    var span =
        sourceMap.spanFor(line - 1, column - 1, uri: frame.uri.toString());

    // 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();
    for (var root in roots) {
      if (root != null && p.url.isWithin(root, sourceUrl)) {
        var relative = p.url.relative(sourceUrl, from: root);
        if (relative.contains('dart:')) {
          sourceUrl = relative.substring(relative.indexOf('dart:'));
          break;
        }
        var packageRoot = '$root/packages';
        if (p.url.isWithin(packageRoot, sourceUrl)) {
          sourceUrl = 'package:' + p.url.relative(sourceUrl, from: packageRoot);
          break;
        }
      }
    }

    if (!sourceUrl.startsWith('dart:') &&
        sourceUrl.startsWith(
            'package:build_web_compilers/src/dev_compiler/dart_sdk.')) {
      // This compresses the long dart_sdk URLs if SDK source maps are missing.
      // It's no longer linkable, but neither are the properly mapped ones
      // above.
      sourceUrl = 'dart:sdk_internal';
    }

    return Frame(Uri.parse(sourceUrl), span.start.line + 1,
        span.start.column + 1, _prettifyMember(frame.member!));
  }).whereNotNull())
      .foldFrames((Frame frame) => frame.uri.scheme.contains('dart'));
}