Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions pkgs/source_maps/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## 0.10.14-wip

* Fix `SingleMapping.spanFor` to use the entry from a previous line as specified
by the sourcemap specification
(https://tc39.es/ecma426/#sec-GetOriginalPositions),

## 0.10.13

* Require Dart 3.3
Expand Down
43 changes: 23 additions & 20 deletions pkgs/source_maps/lib/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -500,31 +500,34 @@ class SingleMapping extends Mapping {
StateError('Invalid entry in sourcemap, expected 1, 4, or 5'
' values, but got $seen.\ntargeturl: $targetUrl, line: $line');

/// Returns [TargetLineEntry] which includes the location in the target [line]
/// number. In particular, the resulting entry is the last entry whose line
/// number is lower or equal to [line].
TargetLineEntry? _findLine(int line) {
var index = binarySearch(lines, (e) => e.line > line);
return (index <= 0) ? null : lines[index - 1];
}

/// Returns [TargetEntry] which includes the location denoted by
/// [line], [column]. If [lineEntry] corresponds to [line], then this will be
/// the last entry whose column is lower or equal than [column]. If
/// [lineEntry] corresponds to a line prior to [line], then the result will be
/// the very last entry on that line.
TargetEntry? _findColumn(int line, int column, TargetLineEntry? lineEntry) {
if (lineEntry == null || lineEntry.entries.isEmpty) return null;
if (lineEntry.line != line) return lineEntry.entries.last;
var entries = lineEntry.entries;
var index = binarySearch(entries, (e) => e.column > column);
return (index <= 0) ? null : entries[index - 1];
/// Returns the last [TargetEntry] which includes the location denoted by
/// [line], [column].
///
/// This corresponds to the computation of _last_ in [GetOriginalPositions][1]
/// in the sourcemap specification.
///
/// [1]: https://tc39.es/ecma426/#sec-GetOriginalPositions
TargetEntry? _findEntry(int line, int column) {
// To find the *last* TargetEntry, we scan backwards, starting from the
// first line after our target line, or the end of [lines].
var lineIndex = binarySearch(lines, (e) => e.line > line);
while (--lineIndex >= 0) {
final lineEntry = lines[lineIndex];
final entries = lineEntry.entries;
if (entries.isEmpty) continue;
// If we scan to a line before the target line, the last entry extends to
// cover our search location.
if (lineEntry.line != line) return entries.last;
final index = binarySearch(entries, (e) => e.column > column);
if (index > 0) return entries[index - 1];
}
return null;
}

@override
SourceMapSpan? spanFor(int line, int column,
{Map<String, SourceFile>? files, String? uri}) {
var entry = _findColumn(line, column, _findLine(line));
final entry = _findEntry(line, column);
if (entry == null) return null;

var sourceUrlId = entry.sourceUrlId;
Expand Down
8 changes: 7 additions & 1 deletion pkgs/source_maps/test/refactor_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,13 @@ void main() {

// Lines added have no mapping (they should inherit the last mapping),
// but the end of the edit region continues were we left off:
expect(_span(4, 1, map, file), isNull);
expect(
_span(4, 1, map, file),
'line 3, column 6: \n'
' ,\n'
'3 | 01*3456789\n'
' | ^\n'
' \'');
expect(
_span(4, 5, map, file),
'line 3, column 8: \n'
Expand Down