spanFor method

  1. @override
SourceMapSpan? spanFor(
  1. int line,
  2. int column, {
  3. Map<String, SourceFile>? files,
  4. String? uri,
})
override

Returns the span associated with line and column.

uri is the optional location of the output file to find the span for to disambiguate cases where a mapping may have different mappings for different output files.

Implementation

@override
SourceMapSpan? spanFor(int line, int column,
    {Map<String, SourceFile>? files, String? uri}) {
  // TODO: Remove type arg https://github.com/dart-lang/sdk/issues/42227
  uri = ArgumentError.checkNotNull<String>(uri, 'uri');

  // Find the longest suffix of the uri that matches the sourcemap
  // where the suffix starts after a path segment boundary.
  // We consider ":" and "/" as path segment boundaries so that
  // "package:" uris can be handled with minimal special casing. Having a
  // few false positive path segment boundaries is not a significant issue
  // as we prefer the longest matching prefix.
  // Using package:path `path.split` to find path segment boundaries would
  // not generate all of the path segment boundaries we want for "package:"
  // urls as "package:package_name" would be one path segment when we want
  // "package" and "package_name" to be sepearate path segments.

  var onBoundary = true;
  var separatorCodeUnits = ['/'.codeUnitAt(0), ':'.codeUnitAt(0)];
  for (var i = 0; i < uri.length; ++i) {
    if (onBoundary) {
      var candidate = uri.substring(i);
      var candidateMapping = _mappings[candidate];
      if (candidateMapping != null) {
        return candidateMapping.spanFor(line, column,
            files: files, uri: candidate);
      }
    }
    onBoundary = separatorCodeUnits.contains(uri.codeUnitAt(i));
  }

  // Note: when there is no source map for an uri, this behaves like an
  // identity function, returning the requested location as the result.

  // Create a mock offset for the output location. We compute it in terms
  // of the input line and column to minimize the chances that two different
  // line and column locations are mapped to the same offset.
  var offset = line * 1000000 + column;
  var location = SourceLocation(offset,
      line: line, column: column, sourceUrl: Uri.parse(uri));
  return SourceMapSpan(location, location, '');
}