Remove support for the old Span classes from source_maps.
This releases source_maps 0.10.0, code_transformers 0.2.0+2, observe 0.11.0+3,
and polymer 0.12.0+4.
BUG=19930
R=sigmund@google.com
Review URL: https://codereview.chromium.org//421723004
git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38803 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkgs/source_maps/lib/builder.dart b/pkgs/source_maps/lib/builder.dart
index 494a6b6..091e220 100644
--- a/pkgs/source_maps/lib/builder.dart
+++ b/pkgs/source_maps/lib/builder.dart
@@ -9,9 +9,10 @@
import 'dart:convert';
+import 'package:source_span/source_span.dart';
+
import 'parser.dart';
-import 'span.dart';
-import 'src/span_wrapper.dart';
+import 'src/source_map_span.dart';
/// Builds a source map given a set of mappings.
class SourceMapBuilder {
@@ -19,39 +20,33 @@
final List<Entry> _entries = <Entry>[];
/// Adds an entry mapping the [targetOffset] to [source].
- ///
- /// [source] can be either a [Location] or a [SourceLocation]. Using a
- /// [Location] is deprecated and will be unsupported in version 0.10.0.
- void addFromOffset(source, targetFile, int targetOffset, String identifier) {
+ void addFromOffset(SourceLocation source, SourceFile targetFile,
+ int targetOffset, String identifier) {
if (targetFile == null) {
throw new ArgumentError('targetFile cannot be null');
}
- _entries.add(new Entry(source,
- new FileLocation(targetFile, targetOffset), identifier));
+ _entries.add(
+ new Entry(source, targetFile.location(targetOffset), identifier));
}
/// Adds an entry mapping [target] to [source].
///
- /// [source] and [target] can be either a [Span] or a [SourceSpan]. Using a
- /// [Span] is deprecated and will be unsupported in version 0.10.0.
- ///
- /// If [isIdentifier] is true, this entry is considered to represent an
- /// identifier whose value will be stored in the source map.
- void addSpan(source, target, {bool isIdentifier}) {
- source = SpanWrapper.wrap(source);
- target = SpanWrapper.wrap(target);
- if (isIdentifier == null) isIdentifier = source.isIdentifier;
+ /// If [isIdentifier] is true or if [target] is a [SourceMapSpan] with
+ /// `isIdentifier` set to true, this entry is considered to represent an
+ /// identifier whose value will be stored in the source map. [isIdenfier]
+ /// takes precedence over [target]'s `isIdentifier` value.
+ void addSpan(SourceSpan source, SourceSpan target, {bool isIdentifier}) {
+ if (isIdentifier == null) {
+ isIdentifier = source is SourceMapSpan ? source.isIdentifier : false;
+ }
var name = isIdentifier ? source.text : null;
_entries.add(new Entry(source.start, target.start, name));
}
/// Adds an entry mapping [target] to [source].
- ///
- /// [source] and [target] can be either a [Location] or a [SourceLocation].
- /// Using a [Location] is deprecated and will be unsupported in version
- /// 0.10.0.
- void addLocation(source, target, String identifier) {
+ void addLocation(SourceLocation source, SourceLocation target,
+ String identifier) {
_entries.add(new Entry(source, target, identifier));
}
@@ -67,22 +62,16 @@
/// An entry in the source map builder.
class Entry implements Comparable {
/// Span denoting the original location in the input source file
- final Location source;
+ final SourceLocation source;
/// Span indicating the corresponding location in the target file.
- final Location target;
+ final SourceLocation target;
/// An identifier name, when this location is the start of an identifier.
final String identifierName;
/// Creates a new [Entry] mapping [target] to [source].
- ///
- /// [source] and [target] can be either a [Location] or a [SourceLocation].
- /// Using a [Location] is deprecated and will be unsupported in version
- /// 0.10.0.
- Entry(source, target, this.identifierName)
- : source = LocationWrapper.wrap(source),
- target = LocationWrapper.wrap(target);
+ Entry(this.source, this.target, this.identifierName);
/// Implements [Comparable] to ensure that entries are ordered by their
/// location in the target file. We sort primarily by the target offset
@@ -91,7 +80,8 @@
int compareTo(Entry other) {
int res = target.compareTo(other.target);
if (res != 0) return res;
- res = source.sourceUrl.compareTo(other.source.sourceUrl);
+ res = source.sourceUrl.toString().compareTo(
+ other.source.sourceUrl.toString());
if (res != 0) return res;
return source.compareTo(other.source);
}
diff --git a/pkgs/source_maps/lib/parser.dart b/pkgs/source_maps/lib/parser.dart
index c18a1d6..d67a65e 100644
--- a/pkgs/source_maps/lib/parser.dart
+++ b/pkgs/source_maps/lib/parser.dart
@@ -8,9 +8,10 @@
import 'dart:collection';
import 'dart:convert';
+import 'package:source_span/source_span.dart';
+
import 'builder.dart' as builder;
-import 'span.dart';
-import 'src/span_wrapper.dart';
+import 'src/source_map_span.dart';
import 'src/utils.dart';
import 'src/vlq.dart';
@@ -49,19 +50,11 @@
/// A mapping parsed out of a source map.
abstract class Mapping {
/// Returns the span associated with [line] and [column].
- ///
- /// The values of [files] can be either `source_map` [SourceFile]s or
- /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is
- /// deprecated and will be unsupported in version 0.10.0.
- Span spanFor(int line, int column, {Map<String, dynamic> files});
+ SourceMapSpan spanFor(int line, int column, {Map<String, SourceFile> files});
/// Returns the span associated with [location].
- ///
- /// The values of [files] may be either `source_map` [SourceFile]s or
- /// `source_span` `SourceFile`s. Using `source_map` [SourceFile]s is
- /// deprecated and will be unsupported in version 0.10.0.
- Span spanForLocation(location, {Map<String, dynamic> files}) {
- location = LocationWrapper.wrap(location);
+ SourceMapSpan spanForLocation(SourceLocation location,
+ {Map<String, SourceFile> files}) {
return spanFor(location.line, location.column, files: files);
}
}
@@ -124,7 +117,7 @@
return _lineStart.length - 1;
}
- Span spanFor(int line, int column, {Map<String, dynamic> files}) {
+ SourceMapSpan spanFor(int line, int column, {Map<String, SourceFile> files}) {
int index = _indexFor(line, column);
return _maps[index].spanFor(
line - _lineStart[index], column - _columnStart[index], files: files);
@@ -191,8 +184,9 @@
if (sourceEntry.source == null) {
targetEntries.add(new TargetEntry(sourceEntry.target.column));
} else {
+ var sourceUrl = sourceEntry.source.sourceUrl;
var urlId = urls.putIfAbsent(
- sourceEntry.source.sourceUrl, () => urls.length);
+ sourceUrl == null ? '' : sourceUrl.toString(), () => urls.length);
var srcNameId = sourceEntry.identifierName == null ? null :
names.putIfAbsent(sourceEntry.identifierName, () => names.length);
targetEntries.add(new TargetEntry(
@@ -363,7 +357,7 @@
return (index <= 0) ? null : entries[index - 1];
}
- Span spanFor(int line, int column, {Map<String, dynamic> files}) {
+ SourceMapSpan spanFor(int line, int column, {Map<String, SourceFile> files}) {
var entry = _findColumn(line, column, _findLine(line));
if (entry == null || entry.sourceUrlId == null) return null;
var url = urls[entry.sourceUrlId];
@@ -371,21 +365,24 @@
url = '${sourceRoot}${url}';
}
if (files != null && files[url] != null) {
- var file = SourceFileWrapper.wrap(files[url]);
+ var file = files[url];
var start = file.getOffset(entry.sourceLine, entry.sourceColumn);
if (entry.sourceNameId != null) {
var text = names[entry.sourceNameId];
- return new FileSpan(files[url], start, start + text.length, true);
+ return new SourceMapFileSpan(
+ files[url].span(start, start + text.length),
+ isIdentifier: true);
} else {
- return new FileSpan(files[url], start);
+ return new SourceMapFileSpan(files[url].location(start).pointSpan());
}
} else {
+ var start = new SourceLocation(0,
+ sourceUrl: url, line: entry.sourceLine, column: entry.sourceColumn);
// Offset and other context is not available.
if (entry.sourceNameId != null) {
- return new FixedSpan(url, 0, entry.sourceLine, entry.sourceColumn,
- text: names[entry.sourceNameId], isIdentifier: true);
+ return new SourceMapSpan.identifier(start, names[entry.sourceNameId]);
} else {
- return new FixedSpan(url, 0, entry.sourceLine, entry.sourceColumn);
+ return new SourceMapSpan(start, start, '');
}
}
}
diff --git a/pkgs/source_maps/lib/printer.dart b/pkgs/source_maps/lib/printer.dart
index aa18bd7..906e260 100644
--- a/pkgs/source_maps/lib/printer.dart
+++ b/pkgs/source_maps/lib/printer.dart
@@ -5,11 +5,10 @@
/// Contains a code printer that generates code by recording the source maps.
library source_maps.printer;
-import 'package:source_span/source_span.dart' as source_span;
+import 'package:source_span/source_span.dart';
import 'builder.dart';
-import 'span.dart';
-import 'src/span_wrapper.dart';
+import 'src/source_map_span.dart';
const int _LF = 10;
const int _CR = 13;
@@ -24,7 +23,7 @@
String get map => _maps.toJson(filename);
/// Current source location mapping.
- Location _loc;
+ SourceLocation _loc;
/// Current line in the buffer;
int _line = 0;
@@ -49,11 +48,12 @@
_line++;
_column = 0;
if (projectMarks && _loc != null) {
- if (_loc is FixedLocation) {
- mark(new FixedLocation(0, _loc.sourceUrl, _loc.line + 1, 0));
- } else if (_loc is FileLocation) {
+ if (_loc is FileLocation) {
var file = (_loc as FileLocation).file;
- mark(new FileLocation(file, file.getOffset(_loc.line + 1, 0)));
+ mark(file.location(file.getOffset(_loc.line + 1)));
+ } else {
+ mark(new SourceLocation(0,
+ sourceUrl: _loc.sourceUrl, line: _loc.line + 1, column: 0));
}
}
} else {
@@ -72,21 +72,23 @@
}
/// Marks that the current point in the target file corresponds to the [mark]
- /// in the source file, which can be either a [Location] or a [Span]. When the
- /// mark is an identifier's Span, this also records the name of the identifier
- /// in the source map information.
+ /// in the source file, which can be either a [SourceLocation] or a
+ /// [SourceSpan]. When the mark is a [SourceMapSpan] with `isIdentifier` set,
+ /// this also records the name of the identifier in the source map
+ /// information.
void mark(mark) {
var loc;
var identifier = null;
- if (mark is Location || mark is source_span.SourceLocation) {
- loc = LocationWrapper.wrap(mark);
- } else if (mark is Span || mark is source_span.SourceSpan) {
- mark = SpanWrapper.wrap(mark);
+ if (mark is SourceLocation) {
+ loc = mark;
+ } else if (mark is SourceSpan) {
loc = mark.start;
- if (mark.isIdentifier) identifier = mark.text;
+ if (mark is SourceMapSpan && mark.isIdentifier) identifier = mark.text;
}
- _maps.addLocation(loc,
- new FixedLocation(_buff.length, null, _line, _column), identifier);
+ _maps.addLocation(
+ loc,
+ new SourceLocation(_buff.length, line: _line, column: _column),
+ identifier);
_loc = loc;
}
}
@@ -101,7 +103,8 @@
class NestedPrinter implements NestedItem {
/// Items recoded by this printer, which can be [String] literals,
- /// [NestedItem]s, and source map information like [Location] and [Span].
+ /// [NestedItem]s, and source map information like [SourceLocation] and
+ /// [SourceSpan].
List _items = [];
/// Internal buffer to merge consecutive strings added to this printer.
@@ -128,19 +131,16 @@
/// location of [object] in the original input. Only one, [location] or
/// [span], should be provided at a time.
///
- /// [location] can be either a [Location] or a [SourceLocation]. [span] can be
- /// either a [Span] or a [SourceSpan]. Using a [Location] or a [Span] is
- /// deprecated and will be unsupported in version 0.10.0.
- ///
/// Indicate [isOriginal] when [object] is copied directly from the user code.
/// Setting [isOriginal] will make this printer propagate source map locations
/// on every line-break.
- void add(object, {location, span, bool isOriginal: false}) {
+ void add(object, {SourceLocation location, SourceSpan span,
+ bool isOriginal: false}) {
if (object is! String || location != null || span != null || isOriginal) {
_flush();
assert(location == null || span == null);
- if (location != null) _items.add(LocationWrapper.wrap(location));
- if (span != null) _items.add(SpanWrapper.wrap(span));
+ if (location != null) _items.add(location);
+ if (span != null) _items.add(span);
if (isOriginal) _items.add(_ORIGINAL);
}
@@ -164,16 +164,12 @@
/// The [location] and [span] parameters indicate the corresponding source map
/// location of [object] in the original input. Only one, [location] or
/// [span], should be provided at a time.
- ///
- /// [location] can be either a [Location] or a [SourceLocation]. [span] can be
- /// either a [Span] or a [SourceSpan]. Using a [Location] or a [Span] is
- /// deprecated and will be unsupported in version 0.10.0.
- void addLine(String line, {location, span}) {
+ void addLine(String line, {SourceLocation location, SourceSpan span}) {
if (location != null || span != null) {
_flush();
assert(location == null || span == null);
- if (location != null) _items.add(LocationWrapper.wrap(location));
- if (span != null) _items.add(SpanWrapper.wrap(span));
+ if (location != null) _items.add(location);
+ if (span != null) _items.add(span);
}
if (line == null) return;
if (line != '') {
@@ -235,7 +231,7 @@
} else if (item is String) {
printer.add(item, projectMarks: propagate);
propagate = false;
- } else if (item is Location || item is Span) {
+ } else if (item is SourceLocation || item is SourceSpan) {
printer.mark(item);
} else if (item == _ORIGINAL) {
// we insert booleans when we are about to quote text that was copied
diff --git a/pkgs/source_maps/lib/refactor.dart b/pkgs/source_maps/lib/refactor.dart
index 47ce2ed..a33b86b 100644
--- a/pkgs/source_maps/lib/refactor.dart
+++ b/pkgs/source_maps/lib/refactor.dart
@@ -8,9 +8,9 @@
/// [guessIndent] helps to guess the appropriate indentiation for the new code.
library source_maps.refactor;
-import 'span.dart';
+import 'package:source_span/source_span.dart';
+
import 'printer.dart';
-import 'src/span_wrapper.dart';
/// Editable text transaction.
///
@@ -22,12 +22,7 @@
final _edits = <_TextEdit>[];
/// Creates a new transaction.
- ///
- /// [file] can be either a `source_map` [SourceFile] or a `source_span`
- /// `SourceFile`. Using a `source_map` [SourceFile] is deprecated and will be
- /// unsupported in version 0.10.0.
- TextEditTransaction(this.original, file)
- : file = SourceFileWrapper.wrap(file);
+ TextEditTransaction(this.original, this.file);
bool get hasEdits => _edits.length > 0;
@@ -38,8 +33,8 @@
_edits.add(new _TextEdit(begin, end, replacement));
}
- /// Create a source map [Location] for [offset].
- Location _loc(int offset) =>
+ /// Create a source map [SourceLocation] for [offset].
+ SourceLocation _loc(int offset) =>
file != null ? file.location(offset) : null;
/// Applies all pending [edit]s and returns a [NestedPrinter] containing the
@@ -62,7 +57,7 @@
for (var edit in _edits) {
if (consumed > edit.begin) {
var sb = new StringBuffer();
- sb..write(file.location(edit.begin).formatString)
+ sb..write(file.location(edit.begin).toolString)
..write(': overlapping edits. Insert at offset ')
..write(edit.begin)
..write(' but have consumed ')
diff --git a/pkgs/source_maps/lib/source_maps.dart b/pkgs/source_maps/lib/source_maps.dart
index 2d4a4cc..9531903 100644
--- a/pkgs/source_maps/lib/source_maps.dart
+++ b/pkgs/source_maps/lib/source_maps.dart
@@ -11,7 +11,8 @@
/// ..add(inputSpan3, outputSpan3)
/// .toJson(outputFile);
///
-/// Use the [Span] and [SourceFile] classes to specify span locations.
+/// Use the source_span package's [SourceSpan] and [SourceFile] classes to
+/// specify span locations.
///
/// Parse a source map using [parse], and call `spanFor` on the returned mapping
/// object. For example:
@@ -40,4 +41,4 @@
export "parser.dart";
export "printer.dart";
export "refactor.dart";
-export "span.dart";
+export 'src/source_map_span.dart';
diff --git a/pkgs/source_maps/lib/span.dart b/pkgs/source_maps/lib/span.dart
deleted file mode 100644
index a21e893..0000000
--- a/pkgs/source_maps/lib/span.dart
+++ /dev/null
@@ -1,404 +0,0 @@
-// 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.
-
-/// Dart classes representing the souce spans and source files.
-library source_maps.span;
-
-import 'dart:math' show min, max;
-
-import 'package:path/path.dart' as p;
-
-import 'src/utils.dart';
-
-/// A simple class that describe a segment of source text.
-@Deprecated("Use the source_span package instead.")
-abstract class Span implements Comparable {
- /// The start location of this span.
- final Location start;
-
- /// The end location of this span, exclusive.
- final Location end;
-
- /// Url of the source (typically a file) containing this span.
- String get sourceUrl => start.sourceUrl;
-
- /// The length of this span, in characters.
- int get length => end.offset - start.offset;
-
- /// The source text for this span, if available.
- String get text;
-
- /// Whether [text] corresponds to an identifier symbol.
- final bool isIdentifier;
-
- Span(this.start, this.end, bool isIdentifier)
- : isIdentifier = isIdentifier != null ? isIdentifier : false {
- _checkRange();
- }
-
- /// Creates a new span that is the union of two existing spans [start] and
- /// [end]. Note that the resulting span might contain some positions that were
- /// not in either of the original spans if [start] and [end] are disjoint.
- Span.union(Span start, Span end)
- : start = start.start, end = end.end, isIdentifier = false {
- _checkRange();
- }
-
- void _checkRange() {
- if (start.offset < 0) throw new ArgumentError('start $start must be >= 0');
- if (end.offset < start.offset) {
- throw new ArgumentError('end $end must be >= start $start');
- }
- }
-
- /// Compares two spans. If the spans are not in the same source, this method
- /// generates an error.
- int compareTo(Span other) {
- int d = start.compareTo(other.start);
- return d == 0 ? end.compareTo(other.end) : d;
- }
-
- /// Gets the location in standard printed form `filename:line:column`, where
- /// line and column are adjusted by 1 to match the convention in editors.
- String get formatLocation => start.formatString;
-
- String getLocationMessage(String message,
- {bool useColors: false, String color}) {
- var source = start.sourceUrl == null ? '' :
- ' of ${p.prettyUri(start.sourceUrl)}';
- return 'line ${start.line + 1}, column ${start.column + 1}$source: ' +
- message;
- }
-
- bool operator ==(Span other) =>
- sourceUrl == other.sourceUrl && start == other.start && end == other.end;
-
- int get hashCode => sourceUrl.hashCode + start.offset + (31 * length);
-
- String toString() => '<$runtimeType: $start $end $formatLocation $text>';
-}
-
-/// A location in the source text
-@Deprecated("Use the source_span package instead.")
-abstract class Location implements Comparable {
- /// Url of the source containing this span.
- String get sourceUrl;
-
- /// The offset of this location, 0-based.
- final int offset;
-
- /// The 0-based line in the source of this location.
- int get line;
-
- /// The 0-based column in the source of this location.
- int get column;
-
- Location(this.offset);
-
- /// Compares two locations. If the locations are not in the same source, this
- /// method generates an error.
- int compareTo(Location other) {
- if (sourceUrl != other.sourceUrl) {
- throw new ArgumentError('can only compare locations of the same source');
- }
- return offset - other.offset;
- }
-
- bool operator ==(Location other) =>
- sourceUrl == other.sourceUrl && offset == other.offset;
-
- int get hashCode => sourceUrl.hashCode + offset;
-
- String toString() => '(Location $offset)';
- String get formatString => '$sourceUrl:${line + 1}:${column + 1}';
-}
-
-/// Implementation of [Location] with fixed values given at allocation time.
-@Deprecated("Use the source_span package instead.")
-class FixedLocation extends Location {
- final String sourceUrl;
- final int line;
- final int column;
-
- FixedLocation(int offset, this.sourceUrl, this.line, this.column)
- : super(offset);
-}
-
-/// Implementation of [Span] where all the values are given at allocation time.
-@Deprecated("Use the source_span package instead.")
-class FixedSpan extends Span {
- /// The source text for this span, if available.
- final String text;
-
- /// Creates a span which starts and end in the same line.
- FixedSpan(String sourceUrl, int start, int line, int column,
- {String text: '', bool isIdentifier: false})
- : text = text, super(new FixedLocation(start, sourceUrl, line, column),
- new FixedLocation(start + text.length, sourceUrl, line,
- column + text.length),
- isIdentifier);
-}
-
-/// [Location] with values computed from an underling [SourceFile].
-@Deprecated("Use the source_span package instead.")
-class FileLocation extends Location {
- /// The source file containing this location.
- final SourceFile file;
-
- String get sourceUrl => file.url;
- int get line => file.getLine(offset);
- int get column => file.getColumn(line, offset);
-
- FileLocation(this.file, int offset): super(offset);
-}
-
-/// [Span] where values are computed from an underling [SourceFile].
-@Deprecated("Use the source_span package instead.")
-class FileSpan extends Span {
- /// The source file containing this span.
- final SourceFile file;
-
- /// The source text for this span, if available.
- String get text => file.getText(start.offset, end.offset);
-
- factory FileSpan(SourceFile file, int start,
- [int end, bool isIdentifier = false]) {
- var startLoc = new FileLocation(file, start);
- var endLoc = end == null ? startLoc : new FileLocation(file, end);
- return new FileSpan.locations(startLoc, endLoc, isIdentifier);
- }
-
- FileSpan.locations(FileLocation start, FileLocation end,
- bool isIdentifier)
- : file = start.file, super(start, end, isIdentifier);
-
- /// Creates a new span that is the union of two existing spans [start] and
- /// [end]. Note that the resulting span might contain some positions that were
- /// not in either of the original spans if [start] and [end] are disjoint.
- FileSpan.union(FileSpan start, FileSpan end)
- : file = start.file, super.union(start, end) {
- if (start.file != end.file) {
- throw new ArgumentError('start and end must be from the same file');
- }
- }
-
- String getLocationMessage(String message,
- {bool useColors: false, String color}) {
- return file.getLocationMessage(message, start.offset, end.offset,
- useColors: useColors, color: color);
- }
-}
-
-// Constants to determine end-of-lines.
-const int _LF = 10;
-const int _CR = 13;
-
-// Color constants used for generating messages.
-const String _RED_COLOR = '\u001b[31m';
-const String _NO_COLOR = '\u001b[0m';
-
-/// Stores information about a source file, to permit computation of the line
-/// and column. Also contains a nice default error message highlighting the code
-/// location.
-@Deprecated("Use the source_span package instead.")
-class SourceFile {
- /// Url where the source file is located.
- final String url;
- final List<int> _lineStarts;
- final List<int> _decodedChars;
-
- SourceFile(this.url, this._lineStarts, this._decodedChars);
-
- SourceFile.text(this.url, String text)
- : _lineStarts = <int>[0],
- _decodedChars = text.runes.toList() {
- for (int i = 0; i < _decodedChars.length; i++) {
- var c = _decodedChars[i];
- if (c == _CR) {
- // Return not followed by newline is treated as a newline
- int j = i + 1;
- if (j >= _decodedChars.length || _decodedChars[j] != _LF) {
- c = _LF;
- }
- }
- if (c == _LF) _lineStarts.add(i + 1);
- }
- }
-
- /// Returns a span in this [SourceFile] with the given offsets.
- Span span(int start, [int end, bool isIdentifier = false]) =>
- new FileSpan(this, start, end, isIdentifier);
-
- /// Returns a location in this [SourceFile] with the given offset.
- Location location(int offset) => new FileLocation(this, offset);
-
- /// Gets the 0-based line corresponding to an offset.
- int getLine(int offset) => binarySearch(_lineStarts, (o) => o > offset) - 1;
-
- /// Gets the 0-based column corresponding to an offset.
- int getColumn(int line, int offset) {
- if (line < 0 || line >= _lineStarts.length) return 0;
- return offset - _lineStarts[line];
- }
-
- /// Get the offset for a given line and column
- int getOffset(int line, int column) {
- if (line < 0) return getOffset(0, 0);
- if (line < _lineStarts.length) {
- return _lineStarts[line] + column;
- } else {
- return _decodedChars.length;
- }
- }
-
- /// Gets the text at the given offsets.
- String getText(int start, [int end]) =>
- new String.fromCharCodes(_decodedChars.sublist(max(start, 0), end));
-
- /// Create a pretty string representation from a span.
- String getLocationMessage(String message, int start, int end,
- {bool useColors: false, String color}) {
- // TODO(jmesserly): it would be more useful to pass in an object that
- // controls how the errors are printed. This method is a bit too smart.
- var line = getLine(start);
- var column = getColumn(line, start);
-
- var source = url == null ? '' : ' of ${p.prettyUri(url)}';
- var msg = 'line ${line + 1}, column ${column + 1}$source: $message';
-
- if (_decodedChars == null) {
- // We don't have any text to include, so exit.
- return msg;
- }
-
- var buf = new StringBuffer(msg);
- buf.write('\n');
-
- // +1 for 0-indexing, +1 again to avoid the last line
- var textLine = getText(getOffset(line, 0), getOffset(line + 1, 0));
-
- column = min(column, textLine.length - 1);
- int toColumn = min(column + end - start, textLine.length);
- if (useColors) {
- if (color == null) {
- color = _RED_COLOR;
- }
- buf.write(textLine.substring(0, column));
- buf.write(color);
- buf.write(textLine.substring(column, toColumn));
- buf.write(_NO_COLOR);
- buf.write(textLine.substring(toColumn));
- } else {
- buf.write(textLine);
- if (textLine != '' && !textLine.endsWith('\n')) buf.write('\n');
- }
-
- int i = 0;
- for (; i < column; i++) {
- buf.write(' ');
- }
-
- if (useColors) buf.write(color);
- for (; i < toColumn; i++) {
- buf.write('^');
- }
- if (useColors) buf.write(_NO_COLOR);
- return buf.toString();
- }
-}
-
-/// A convenience type to treat a code segment as if it were a separate
-/// [SourceFile]. A [SourceFileSegment] shifts all locations by an offset, which
-/// allows you to set source-map locations based on the locations relative to
-/// the start of the segment, but that get translated to absolute locations in
-/// the original source file.
-@Deprecated("Use the source_span package instead.")
-class SourceFileSegment extends SourceFile {
- final int _baseOffset;
- final int _baseLine;
- final int _baseColumn;
- final int _maxOffset;
-
- SourceFileSegment(String url, String textSegment, Location startOffset)
- : _baseOffset = startOffset.offset,
- _baseLine = startOffset.line,
- _baseColumn = startOffset.column,
- _maxOffset = startOffset.offset + textSegment.length,
- super.text(url, textSegment);
-
- /// Craete a span, where [start] is relative to this segment's base offset.
- /// The returned span stores the real offset on the file, so that error
- /// messages are reported at the real location.
- Span span(int start, [int end, bool isIdentifier = false]) =>
- super.span(start + _baseOffset,
- end == null ? null : end + _baseOffset, isIdentifier);
-
- /// Create a location, where [offset] relative to this segment's base offset.
- /// The returned span stores the real offset on the file, so that error
- /// messages are reported at the real location.
- Location location(int offset) => super.location(offset + _baseOffset);
-
- /// Return the line on the underlying file associated with the [offset] of the
- /// underlying file. This method operates on the real offsets from the
- /// original file, so that error messages can be reported accurately. When the
- /// requested offset is past the length of the segment, this returns the line
- /// number after the end of the segment (total lines + 1).
- int getLine(int offset) {
- var res = super.getLine(max(offset - _baseOffset, 0)) + _baseLine;
- return (offset > _maxOffset) ? res + 1 : res;
- }
-
- /// Return the column on the underlying file associated with [line] and
- /// [offset], where [line] is absolute from the beginning of the underlying
- /// file. This method operates on the real offsets from the original file, so
- /// that error messages can be reported accurately.
- int getColumn(int line, int offset) {
- var col = super.getColumn(line - _baseLine, max(offset - _baseOffset, 0));
- return line == _baseLine ? col + _baseColumn : col;
- }
-
- /// Return the offset associated with a line and column. This method operates
- /// on the real offsets from the original file, so that error messages can be
- /// reported accurately.
- int getOffset(int line, int column) =>
- super.getOffset(line - _baseLine,
- line == _baseLine ? column - _baseColumn : column) + _baseOffset;
-
- /// Retrieve the text associated with the specified range. This method
- /// operates on the real offsets from the original file, so that error
- /// messages can be reported accurately.
- String getText(int start, [int end]) =>
- super.getText(start - _baseOffset, end == null ? null : end - _baseOffset);
-}
-
-/// A class for exceptions that have source span information attached.
-@Deprecated("Use the source_span package instead.")
-class SpanException implements Exception {
- /// A message describing the exception.
- final String message;
-
- /// The span associated with this exception.
- ///
- /// This may be `null` if the source location can't be determined.
- final Span span;
-
- SpanException(this.message, this.span);
-
- String toString({bool useColors: false, String color}) {
- if (span == null) return message;
- return "Error on " + span.getLocationMessage(message,
- useColors: useColors, color: color);
- }
-}
-
-/// A [SpanException] that's also a [FormatException].
-@Deprecated("Use the source_span package instead.")
-class SpanFormatException extends SpanException implements FormatException {
- final source;
-
- SpanFormatException(String message, Span span, [this.source])
- : super(message, span);
-
- int get offset => span == null ? null : span.start.offset;
-}
diff --git a/pkgs/source_maps/lib/src/source_map_span.dart b/pkgs/source_maps/lib/src/source_map_span.dart
new file mode 100644
index 0000000..20eb17a
--- /dev/null
+++ b/pkgs/source_maps/lib/src/source_map_span.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2014, 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_maps.source_map_span;
+
+import 'package:source_span/source_span.dart';
+
+/// A [SourceSpan] for spans coming from or being written to source maps.
+///
+/// These spans have an extra piece of metadata: whether or not they represent
+/// an identifier (see [isIdentifier]).
+class SourceMapSpan extends SourceSpanBase {
+ /// Whether this span represents an identifier.
+ ///
+ /// If this is `true`, [text] is the value of the identifier.
+ final bool isIdentifier;
+
+ SourceMapSpan(SourceLocation start, SourceLocation end, String text,
+ {this.isIdentifier: false})
+ : super(start, end, text);
+
+ /// Creates a [SourceMapSpan] for an identifier with value [text] starting at
+ /// [start].
+ ///
+ /// The [end] location is determined by adding [text] to [start].
+ SourceMapSpan.identifier(SourceLocation start, String text)
+ : this(
+ start,
+ new SourceLocation(start.offset + text.length,
+ sourceUrl: start.sourceUrl,
+ line: start.line,
+ column: start.column + text.length),
+ text,
+ isIdentifier: true);
+}
+
+/// A wrapper aruond a [FileSpan] that implements [SourceMapSpan].
+class SourceMapFileSpan implements SourceMapSpan, FileSpan {
+ final FileSpan _inner;
+ final bool isIdentifier;
+
+ SourceFile get file => _inner.file;
+ FileLocation get start => _inner.start;
+ FileLocation get end => _inner.end;
+ String get text => _inner.text;
+ Uri get sourceUrl => _inner.sourceUrl;
+ int get length => _inner.length;
+
+ SourceMapFileSpan(this._inner, {this.isIdentifier: false});
+
+ int compareTo(SourceSpan other) => _inner.compareTo(other);
+ SourceSpan union(SourceSpan other) => _inner.union(other);
+ FileSpan expand(FileSpan other) => _inner.expand(other);
+ String message(String message, {color}) =>
+ _inner.message(message, color: color);
+ String toString() => _inner.toString()
+ .replaceAll("FileSpan", "SourceMapFileSpan");
+}
diff --git a/pkgs/source_maps/lib/src/span_wrapper.dart b/pkgs/source_maps/lib/src/span_wrapper.dart
deleted file mode 100644
index e0c107b..0000000
--- a/pkgs/source_maps/lib/src/span_wrapper.dart
+++ /dev/null
@@ -1,85 +0,0 @@
-// Copyright (c) 2014, 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_maps.span_wrapper;
-
-import 'package:source_span/source_span.dart' as source_span;
-
-import '../span.dart';
-
-/// A wrapper that exposes a [source_span.SourceSpan] as a [Span].
-class SpanWrapper extends Span {
- final source_span.SourceSpan _inner;
-
- String get text => _inner.text;
-
- SpanWrapper(source_span.SourceSpan inner, bool isIdentifier)
- : _inner = inner,
- super(
- new LocationWrapper(inner.start),
- new LocationWrapper(inner.end),
- isIdentifier);
-
- static Span wrap(span, [bool isIdentifier = false]) {
- if (span is Span) return span;
- return new SpanWrapper(span, isIdentifier);
- }
-}
-
-/// A wrapper that exposes a [source_span.SourceLocation] as a [Location].
-class LocationWrapper extends Location {
- final source_span.SourceLocation _inner;
-
- String get sourceUrl => _inner.sourceUrl.toString();
- int get line => _inner.line;
- int get column => _inner.column;
-
- LocationWrapper(source_span.SourceLocation inner)
- : _inner = inner,
- super(inner.offset);
-
- static Location wrap(location) {
- if (location is Location) return location;
- return new LocationWrapper(location);
- }
-}
-
-/// A wrapper that exposes a [source_span.SourceFile] as a [SourceFile].
-class SourceFileWrapper implements SourceFile {
- final source_span.SourceFile _inner;
-
- // These are necessary to avoid analyzer warnings;
- final _lineStarts = null;
- final _decodedChars = null;
-
- String get url => _inner.url.toString();
-
- SourceFileWrapper(this._inner);
-
- static SourceFile wrap(sourceFile) {
- if (sourceFile is SourceFile) return sourceFile;
- return new SourceFileWrapper(sourceFile);
- }
-
- Span span(int start, [int end, bool isIdentifier = false]) {
- if (end == null) end = start;
- return new SpanWrapper(_inner.span(start, end), isIdentifier);
- }
-
- Location location(int offset) => new LocationWrapper(_inner.location(offset));
-
- int getLine(int offset) => _inner.getLine(offset);
-
- int getColumn(int line, int offset) => _inner.getColumn(offset, line: line);
-
- int getOffset(int line, int column) => _inner.getOffset(line, column);
-
- String getText(int start, [int end]) => _inner.getText(start, end);
-
- String getLocationMessage(String message, int start, int end,
- {bool useColors: false, String color}) {
- return span(start, end).getLocationMessage(message,
- useColors: useColors, color: color);
- }
-}
diff --git a/pkgs/source_maps/test/builder_test.dart b/pkgs/source_maps/test/builder_test.dart
index 8842c62..ca0ca8d 100644
--- a/pkgs/source_maps/test/builder_test.dart
+++ b/pkgs/source_maps/test/builder_test.dart
@@ -16,7 +16,7 @@
..addSpan(inputFunction, outputFunction)
..addSpan(inputVar2, outputVar2)
..addSpan(inputExpr, outputExpr))
- .build(output.url);
+ .build(output.url.toString());
expect(map, equals(EXPECTED_MAP));
});
@@ -26,7 +26,7 @@
..addLocation(inputFunction.start, outputFunction.start, 'longName')
..addLocation(inputVar2.start, outputVar2.start, 'longVar2')
..addLocation(inputExpr.start, outputExpr.start, null))
- .toJson(output.url);
+ .toJson(output.url.toString());
expect(str, JSON.encode(EXPECTED_MAP));
});
}
diff --git a/pkgs/source_maps/test/common.dart b/pkgs/source_maps/test/common.dart
index 0c1f28a..73a8d40 100644
--- a/pkgs/source_maps/test/common.dart
+++ b/pkgs/source_maps/test/common.dart
@@ -6,6 +6,7 @@
library test.common;
import 'package:source_maps/source_maps.dart';
+import 'package:source_span/source_span.dart';
import 'package:unittest/unittest.dart';
/// Content of the source file
@@ -18,40 +19,40 @@
return longVar1 + longVar2;
}
''';
-var input = new SourceFile.text('input.dart', INPUT);
+var input = new SourceFile(INPUT, url: 'input.dart');
/// A span in the input file
-Span ispan(int start, int end, [bool isIdentifier = false]) =>
- new FileSpan(input, start, end, isIdentifier);
+SourceMapSpan ispan(int start, int end, [bool isIdentifier = false]) =>
+ new SourceMapFileSpan(input.span(start, end), isIdentifier: isIdentifier);
-Span inputVar1 = ispan(30, 38, true);
-Span inputFunction = ispan(74, 82, true);
-Span inputVar2 = ispan(87, 95, true);
+SourceMapSpan inputVar1 = ispan(30, 38, true);
+SourceMapSpan inputFunction = ispan(74, 82, true);
+SourceMapSpan inputVar2 = ispan(87, 95, true);
-Span inputVar1NoSymbol = ispan(30, 38);
-Span inputFunctionNoSymbol = ispan(74, 82);
-Span inputVar2NoSymbol = ispan(87, 95);
+SourceMapSpan inputVar1NoSymbol = ispan(30, 38);
+SourceMapSpan inputFunctionNoSymbol = ispan(74, 82);
+SourceMapSpan inputVar2NoSymbol = ispan(87, 95);
-Span inputExpr = ispan(108, 127);
+SourceMapSpan inputExpr = ispan(108, 127);
/// Content of the target file
const String OUTPUT = '''
var x = 3;
f(y) => x + y;
''';
-var output = new SourceFile.text('output.dart', OUTPUT);
+var output = new SourceFile(OUTPUT, url: 'output.dart');
/// A span in the output file
-Span ospan(int start, int end, [bool isIdentifier = false]) =>
- new FileSpan(output, start, end, isIdentifier);
+SourceMapSpan ospan(int start, int end, [bool isIdentifier = false]) =>
+ new SourceMapFileSpan(output.span(start, end), isIdentifier: isIdentifier);
-Span outputVar1 = ospan(4, 5, true);
-Span outputFunction = ospan(11, 12, true);
-Span outputVar2 = ospan(13, 14, true);
-Span outputVar1NoSymbol = ospan(4, 5);
-Span outputFunctionNoSymbol = ospan(11, 12);
-Span outputVar2NoSymbol = ospan(13, 14);
-Span outputExpr = ospan(19, 24);
+SourceMapSpan outputVar1 = ospan(4, 5, true);
+SourceMapSpan outputFunction = ospan(11, 12, true);
+SourceMapSpan outputVar2 = ospan(13, 14, true);
+SourceMapSpan outputVar1NoSymbol = ospan(4, 5);
+SourceMapSpan outputFunctionNoSymbol = ospan(11, 12);
+SourceMapSpan outputVar2NoSymbol = ospan(13, 14);
+SourceMapSpan outputExpr = ospan(19, 24);
/// Expected output mapping when recording the following four mappings:
/// inputVar1 <= outputVar1
@@ -70,7 +71,8 @@
'file': 'output.dart'
};
-check(Span outputSpan, Mapping mapping, Span inputSpan, bool realOffsets) {
+check(SourceSpan outputSpan, Mapping mapping, SourceMapSpan inputSpan,
+ bool realOffsets) {
var line = outputSpan.start.line;
var column = outputSpan.start.column;
var files = realOffsets ? {'input.dart': input} : null;
diff --git a/pkgs/source_maps/test/end2end_test.dart b/pkgs/source_maps/test/end2end_test.dart
index 99fe40d..7dbc6bd 100644
--- a/pkgs/source_maps/test/end2end_test.dart
+++ b/pkgs/source_maps/test/end2end_test.dart
@@ -6,6 +6,7 @@
import 'package:unittest/unittest.dart';
import 'package:source_maps/source_maps.dart';
+import 'package:source_span/source_span.dart';
import 'common.dart';
main() {
@@ -33,7 +34,7 @@
..addSpan(inputFunction, outputFunction)
..addSpan(inputVar2, outputVar2)
..addSpan(inputExpr, outputExpr))
- .build(output.url);
+ .build(output.url.toString());
var mapping = parseJson(map);
check(outputVar1, mapping, inputVar1, false);
check(outputVar2, mapping, inputVar2, false);
@@ -47,7 +48,7 @@
..addSpan(inputFunctionNoSymbol, outputFunctionNoSymbol)
..addSpan(inputVar2NoSymbol, outputVar2NoSymbol)
..addSpan(inputExpr, outputExpr))
- .build(output.url);
+ .build(output.url.toString());
var mapping = parseJson(map);
check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false);
check(outputVar2NoSymbol, mapping, inputVar2NoSymbol, false);
@@ -65,7 +66,7 @@
..addSpan(inputVar2, outputVar2)
..addSpan(inputExpr, outputExpr)
..addSpan(inputExpr, outputExpr))
- .build(output.url);
+ .build(output.url.toString());
var mapping = parseJson(map);
check(outputVar1, mapping, inputVar1, false);
check(outputVar2, mapping, inputVar2, false);
@@ -82,7 +83,7 @@
..addSpan(inputVar2NoSymbol, outputVar2NoSymbol)
..addSpan(inputVar2NoSymbol, outputVar2NoSymbol)
..addSpan(inputExpr, outputExpr))
- .build(output.url);
+ .build(output.url.toString());
var mapping = parseJson(map);
check(outputVar1NoSymbol, mapping, inputVar1NoSymbol, false);
check(outputVar2NoSymbol, mapping, inputVar2NoSymbol, false);
@@ -96,7 +97,7 @@
..addSpan(inputFunction, outputFunction)
..addSpan(inputVar2, outputVar2)
..addSpan(inputExpr, outputExpr))
- .toJson(output.url);
+ .toJson(output.url.toString());
var mapping = parse(json);
check(outputVar1, mapping, inputVar1, true);
check(outputVar2, mapping, inputVar2, true);
@@ -106,7 +107,7 @@
test('printer projecting marks + parse', () {
var out = INPUT.replaceAll('long', '_s');
- var file = new SourceFile.text('output2.dart', out);
+ var file = new SourceFile(out, url: 'output2.dart');
var printer = new Printer('output2.dart');
printer.mark(ispan(0, 0));
@@ -132,10 +133,11 @@
expect(printer.text, out);
var mapping = parse(printer.map);
- checkHelper(Span inputSpan, int adjustment) {
+ checkHelper(SourceMapSpan inputSpan, int adjustment) {
var start = inputSpan.start.offset - adjustment;
var end = (inputSpan.end.offset - adjustment) - 2;
- var span = new FileSpan(file, start, end, inputSpan.isIdentifier);
+ var span = new SourceMapFileSpan(file.span(start, end),
+ isIdentifier: inputSpan.isIdentifier);
check(span, mapping, inputSpan, true);
}
@@ -145,17 +147,16 @@
checkHelper(inputExpr, 6);
// We projected correctly lines that have no mappings
- check(new FileSpan(file, 66, 66, false), mapping, ispan(45, 45), true);
- check(new FileSpan(file, 63, 64, false), mapping, ispan(45, 45), true);
- check(new FileSpan(file, 68, 68, false), mapping, ispan(70, 70), true);
- check(new FileSpan(file, 71, 71, false), mapping, ispan(70, 70), true);
+ check(file.span(66, 66), mapping, ispan(45, 45), true);
+ check(file.span(63, 64), mapping, ispan(45, 45), true);
+ check(file.span(68, 68), mapping, ispan(70, 70), true);
+ check(file.span(71, 71), mapping, ispan(70, 70), true);
// Start of the last line
var oOffset = out.length - 2;
var iOffset = INPUT.length - 2;
- check(new FileSpan(file, oOffset, oOffset, false), mapping,
- ispan(iOffset, iOffset), true);
- check(new FileSpan(file, oOffset + 1, oOffset + 1, false), mapping,
+ check(file.span(oOffset, oOffset), mapping, ispan(iOffset, iOffset), true);
+ check(file.span(oOffset + 1, oOffset + 1), mapping,
ispan(iOffset, iOffset), true);
});
}
diff --git a/pkgs/source_maps/test/parser_test.dart b/pkgs/source_maps/test/parser_test.dart
index 62cd08f..8528683 100644
--- a/pkgs/source_maps/test/parser_test.dart
+++ b/pkgs/source_maps/test/parser_test.dart
@@ -104,7 +104,7 @@
var inputMap = new Map.from(MAP_WITH_SOURCE_LOCATION);
inputMap['sourceRoot'] = '/pkg/';
var mapping = parseJson(inputMap);
- expect(mapping.spanFor(0, 0).sourceUrl, "/pkg/input.dart");
+ expect(mapping.spanFor(0, 0).sourceUrl, Uri.parse("/pkg/input.dart"));
var newSourceRoot = '/new/';
diff --git a/pkgs/source_maps/test/printer_test.dart b/pkgs/source_maps/test/printer_test.dart
index fe27f76..e55ca9f 100644
--- a/pkgs/source_maps/test/printer_test.dart
+++ b/pkgs/source_maps/test/printer_test.dart
@@ -6,8 +6,8 @@
import 'dart:convert';
import 'package:unittest/unittest.dart';
-import 'package:source_maps/printer.dart';
-import 'package:source_maps/span.dart';
+import 'package:source_maps/source_maps.dart';
+import 'package:source_span/source_span.dart';
import 'common.dart';
main() {
@@ -53,13 +53,12 @@
// 8 new lines in the source map:
expect(printer.map.split(';').length, 8);
- asFixed(Span s) => new FixedSpan(s.sourceUrl,
- s.start.offset, s.start.line, s.start.column,
- text: s.text, isIdentifier: s.isIdentifier);
+ asFixed(SourceMapSpan s) => new SourceMapSpan(s.start, s.end, s.text,
+ isIdentifier: s.isIdentifier);
// The result is the same if we use fixed positions
var printer2 = new Printer('output2.dart');
- printer2..mark(new FixedSpan('input.dart', 0, 0, 0))
+ printer2..mark(new SourceLocation(0, sourceUrl: 'input.dart').pointSpan())
..add(segments[0], projectMarks: true)
..mark(asFixed(inputVar1))
..add('_s')
diff --git a/pkgs/source_maps/test/refactor_test.dart b/pkgs/source_maps/test/refactor_test.dart
index 5d0abf1..08b8965 100644
--- a/pkgs/source_maps/test/refactor_test.dart
+++ b/pkgs/source_maps/test/refactor_test.dart
@@ -6,13 +6,13 @@
import 'package:unittest/unittest.dart';
import 'package:source_maps/refactor.dart';
-import 'package:source_maps/span.dart';
import 'package:source_maps/parser.dart' show parse, Mapping;
+import 'package:source_span/source_span.dart';
main() {
group('conflict detection', () {
var original = "0123456789abcdefghij";
- var file = new SourceFile.text('', original);
+ var file = new SourceFile(original);
test('no conflict, in order', () {
var txn = new TextEditTransaction(original, file);
@@ -48,7 +48,7 @@
test('generated source maps', () {
var original =
"0123456789\n0*23456789\n01*3456789\nabcdefghij\nabcd*fghij\n";
- var file = new SourceFile.text('', original);
+ var file = new SourceFile(original);
var txn = new TextEditTransaction(original, file);
txn.edit(27, 29, '__\n ');
txn.edit(34, 35, '___');
@@ -60,42 +60,90 @@
// Line 1 and 2 are unmodified: mapping any column returns the beginning
// of the corresponding line:
- expect(_span(1, 1, map, file), "line 1, column 1 of .: \n0123456789");
- expect(_span(1, 5, map, file), "line 1, column 1 of .: \n0123456789");
- expect(_span(2, 1, map, file), "line 2, column 1 of .: \n0*23456789");
- expect(_span(2, 8, map, file), "line 2, column 1 of .: \n0*23456789");
+ expect(_span(1, 1, map, file),
+ "line 1, column 1: \n"
+ "0123456789\n"
+ "^");
+ expect(_span(1, 5, map, file),
+ "line 1, column 1: \n"
+ "0123456789\n"
+ "^");
+ expect(_span(2, 1, map, file),
+ "line 2, column 1: \n"
+ "0*23456789\n"
+ "^");
+ expect(_span(2, 8, map, file),
+ "line 2, column 1: \n"
+ "0*23456789\n"
+ "^");
// Line 3 is modified part way: mappings before the edits have the right
// mapping, after the edits the mapping is null.
- expect(_span(3, 1, map, file), "line 3, column 1 of .: \n01*3456789");
- expect(_span(3, 5, map, file), "line 3, column 1 of .: \n01*3456789");
+ expect(_span(3, 1, map, file),
+ "line 3, column 1: \n"
+ "01*3456789\n"
+ "^");
+ expect(_span(3, 5, map, file),
+ "line 3, column 1: \n"
+ "01*3456789\n"
+ "^");
// Start of edits map to beginning of the edit secion:
- expect(_span(3, 6, map, file), "line 3, column 6 of .: \n01*3456789");
- expect(_span(3, 7, map, file), "line 3, column 6 of .: \n01*3456789");
+ expect(_span(3, 6, map, file),
+ "line 3, column 6: \n"
+ "01*3456789\n"
+ " ^");
+ expect(_span(3, 7, map, file),
+ "line 3, column 6: \n"
+ "01*3456789\n"
+ " ^");
// 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, 5, map, file), "line 3, column 8 of .: \n01*3456789");
+ expect(_span(4, 5, map, file),
+ "line 3, column 8: \n"
+ "01*3456789\n"
+ " ^");
// Subsequent lines are still mapped correctly:
// a (in a___cd...)
- expect(_span(5, 1, map, file), "line 4, column 1 of .: \nabcdefghij");
+ expect(_span(5, 1, map, file),
+ "line 4, column 1: \n"
+ "abcdefghij\n"
+ "^");
// _ (in a___cd...)
- expect(_span(5, 2, map, file), "line 4, column 2 of .: \nabcdefghij");
+ expect(_span(5, 2, map, file),
+ "line 4, column 2: \n"
+ "abcdefghij\n"
+ " ^");
// _ (in a___cd...)
- expect(_span(5, 3, map, file), "line 4, column 2 of .: \nabcdefghij");
+ expect(_span(5, 3, map, file),
+ "line 4, column 2: \n"
+ "abcdefghij\n"
+ " ^");
// _ (in a___cd...)
- expect(_span(5, 4, map, file), "line 4, column 2 of .: \nabcdefghij");
+ expect(_span(5, 4, map, file),
+ "line 4, column 2: \n"
+ "abcdefghij\n"
+ " ^");
// c (in a___cd...)
- expect(_span(5, 5, map, file), "line 4, column 3 of .: \nabcdefghij");
- expect(_span(6, 1, map, file), "line 5, column 1 of .: \nabcd*fghij");
- expect(_span(6, 8, map, file), "line 5, column 1 of .: \nabcd*fghij");
+ expect(_span(5, 5, map, file),
+ "line 4, column 3: \n"
+ "abcdefghij\n"
+ " ^");
+ expect(_span(6, 1, map, file),
+ "line 5, column 1: \n"
+ "abcd*fghij\n"
+ "^");
+ expect(_span(6, 8, map, file),
+ "line 5, column 1: \n"
+ "abcd*fghij\n"
+ "^");
});
}
String _span(int line, int column, Mapping map, SourceFile file) {
var span = map.spanFor(line - 1, column - 1, files: {'': file});
- return span == null ? null : span.getLocationMessage('').trim();
+ return span == null ? null : span.message('').trim();
}
diff --git a/pkgs/source_maps/test/run.dart b/pkgs/source_maps/test/run.dart
index 21d2037..ec3c3ab 100755
--- a/pkgs/source_maps/test/run.dart
+++ b/pkgs/source_maps/test/run.dart
@@ -14,7 +14,6 @@
import 'parser_test.dart' as parser_test;
import 'printer_test.dart' as printer_test;
import 'refactor_test.dart' as refactor_test;
-import 'span_test.dart' as span_test;
import 'utils_test.dart' as utils_test;
import 'vlq_test.dart' as vlq_test;
@@ -33,7 +32,6 @@
addGroup('parser_test.dart', parser_test.main);
addGroup('printer_test.dart', printer_test.main);
addGroup('refactor_test.dart', refactor_test.main);
- addGroup('span_test.dart', span_test.main);
addGroup('utils_test.dart', utils_test.main);
addGroup('vlq_test.dart', vlq_test.main);
}
diff --git a/pkgs/source_maps/test/span_test.dart b/pkgs/source_maps/test/span_test.dart
deleted file mode 100644
index 190b7a6..0000000
--- a/pkgs/source_maps/test/span_test.dart
+++ /dev/null
@@ -1,341 +0,0 @@
-// 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 test.span_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:source_maps/span.dart';
-
-const String TEST_FILE = '''
-+23456789_
- + _123456789_123456789_123456789_123456789_123456789_123456789_123456789_
- + _123456789_1
-123+56789_123456789_1234567
-1234+6789_1234
-12345+789_123456789_12345
-123456+89_123456789_123456789_123456789_123456789_123456789_123456789_123456789
-1234567+9_123456789_123456789_123456789_123456789_123456789_123456789_123
-12345678+_123456789_123456789_123456789_123456789_1
-123456789+123456789_123456789_12345678
-123456789_+23456789_123456789_123456789_123
-123456789_1+3456789_123456789
-''';
-
-List<int> newLines = TEST_FILE.split('\n').map((s) => s.length).toList();
-
-main() {
- var file = new SourceFile.text('file', TEST_FILE);
- span(int start, int end) => file.span(start, end);
- loc(int offset) => file.location(offset);
-
- test('validate test input', () {
- expect(newLines,
- const [10, 80, 31, 27, 14, 25, 79, 73, 51, 38, 43, 29, 0]);
- });
-
- test('get line and column', () {
- line(int n) => file.getLine(n);
- col(int n) => file.getColumn(file.getLine(n), n);
-
- expect(line(8), 0);
- expect(line(10), 0);
- expect(line(11), 1);
- expect(line(12), 1);
- expect(line(91), 1);
- expect(line(92), 2);
- expect(line(93), 2);
- expect(col(11), 0);
- expect(col(12), 1);
- expect(col(91), 80);
- expect(col(92), 0);
- expect(col(93), 1);
-
- int j = 0;
- int lineOffset = 0;
- for (int i = 0; i < TEST_FILE.length; i++) {
- if (i > lineOffset + newLines[j]) {
- lineOffset += newLines[j] + 1;
- j++;
- }
- expect(line(i), j, reason: 'position: $i');
- expect(col(i), i - lineOffset, reason: 'position: $i');
- }
- });
-
- test('get text', () {
- // fifth line (including 4 new lines), columns 2 .. 11
- var line = 10 + 80 + 31 + 27 + 4;
- expect(file.getText(line + 2, line + 11), '34+6789_1');
- });
-
- group('location message', () {
- test('first line', () {
- expect(file.getLocationMessage('the message', 1, 3),
- 'line 1, column 2 of file: the message\n'
- '+23456789_\n'
- ' ^^');
- });
-
- test('in the middle of the file', () {
- // fifth line (including 4 new lines), columns 2 .. 11
- var line = 10 + 80 + 31 + 27 + 4;
- expect(file.getLocationMessage('the message', line + 2, line + 11),
- 'line 5, column 3 of file: the message\n'
- '1234+6789_1234\n'
- ' ^^^^^^^^^');
- });
-
- test('no file url', () {
- var line = 10 + 80 + 31 + 27 + 4;
- expect(new SourceFile.text(null, TEST_FILE).getLocationMessage(
- 'the message', line + 2, line + 11),
- 'line 5, column 3: the message\n'
- '1234+6789_1234\n'
- ' ^^^^^^^^^');
- });
-
- test('penultimate line', () {
- // We search '\n' backwards twice because last line is \n terminated:
- int index = TEST_FILE.lastIndexOf('\n');
- var start = TEST_FILE.lastIndexOf('\n', index - 1) - 3;
- expect(file.getLocationMessage('the message', start, start + 2),
- 'line 11, column 41 of file: the message\n'
- '123456789_+23456789_123456789_123456789_123\n'
- ' ^^');
- });
-
- test('last line', () {
- var start = TEST_FILE.lastIndexOf('\n') - 2;
- expect(file.getLocationMessage('the message', start, start + 1),
- 'line 12, column 28 of file: the message\n'
- '123456789_1+3456789_123456789\n'
- ' ^');
- });
-
- group('no trailing empty-line at the end -', () {
- var text = TEST_FILE.substring(0, TEST_FILE.length - 1);
- var file2 = new SourceFile.text('file', text);
-
- test('penultimate line', () {
- var start = text.lastIndexOf('\n') - 3;
- expect(file2.getLocationMessage('the message', start, start + 2),
- 'line 11, column 41 of file: the message\n'
- '123456789_+23456789_123456789_123456789_123\n'
- ' ^^');
- });
-
- test('last line', () {
- var start = text.length - 2;
- expect(file2.getLocationMessage('the message', start, start + 1),
- 'line 12, column 28 of file: the message\n'
- '123456789_1+3456789_123456789\n'
- ' ^');
- });
- });
-
- test('single line', () {
- var text = "this is a single line";
- int start = text.indexOf(' ') + 1;
- var file2 = new SourceFile.text('file', text);
- expect(file2.getLocationMessage('the message', start, start + 2),
- 'line 1, column ${start + 1} of file: the message\n'
- 'this is a single line\n'
- ' ^^');
- });
- });
-
- test('location getters', () {
- expect(loc(8).line, 0);
- expect(loc(8).column, 8);
- expect(loc(9).line, 0);
- expect(loc(9).column, 9);
- expect(loc(8).formatString, 'file:1:9');
- expect(loc(12).line, 1);
- expect(loc(12).column, 1);
- expect(loc(95).line, 2);
- expect(loc(95).column, 3);
- });
-
- test('location compare', () {
- var list = [9, 8, 11, 14, 6, 6, 1, 1].map((n) => loc(n)).toList();
- list.sort();
- var lastOffset = 0;
- for (var location in list) {
- expect(location.offset, greaterThanOrEqualTo(lastOffset));
- lastOffset = location.offset;
- }
- });
-
- test('span getters', () {
- expect(span(8, 9).start.line, 0);
- expect(span(8, 9).start.column, 8);
- expect(span(8, 9).end.line, 0);
- expect(span(8, 9).end.column, 9);
- expect(span(8, 9).text, '9');
- expect(span(8, 9).isIdentifier, false);
- expect(span(8, 9).formatLocation, 'file:1:9');
-
- var line = 10 + 80 + 31 + 27 + 4;
- expect(span(line + 2, line + 11).getLocationMessage('the message'),
- 'line 5, column 3 of file: the message\n'
- '1234+6789_1234\n'
- ' ^^^^^^^^^');
-
- expect(span(12, 95).start.line, 1);
- expect(span(12, 95).start.column, 1);
- expect(span(12, 95).end.line, 2);
- expect(span(12, 95).end.column, 3);
- expect(span(12, 95).text,
- '+ _123456789_123456789_123456789_123456789_123456789_1234567'
- '89_123456789_\n +');
- expect(span(12, 95).formatLocation, 'file:2:2');
- });
-
- test('span union', () {
- var union = new FileSpan.union(span(8, 9), span(12, 95));
- expect(union.start.offset, 8);
- expect(union.start.line, 0);
- expect(union.start.column, 8);
- expect(union.end.offset, 95);
- expect(union.end.line, 2);
- expect(union.end.column, 3);
- expect(union.text,
- '9_\n'
- ' + _123456789_123456789_123456789_123456789_123456789_'
- '123456789_123456789_\n +');
- expect(union.formatLocation, 'file:1:9');
- });
-
- test('span compare', () {
- var list = [span(9, 10), span(8, 9), span(11, 12), span(14, 19),
- span(6, 12), span(6, 8), span(1, 9), span(1, 2)];
- list.sort();
- var lastStart = 0;
- var lastEnd = 0;
- for (var span in list) {
- expect(span.start.offset, greaterThanOrEqualTo(lastStart));
- if (span.start.offset == lastStart) {
- expect(span.end.offset, greaterThanOrEqualTo(lastEnd));
- }
- lastStart = span.start.offset;
- lastEnd = span.end.offset;
- }
- });
-
- test('range check for large offsets', () {
- var start = TEST_FILE.length;
- expect(file.getLocationMessage('the message', start, start + 9),
- 'line 13, column 1 of file: the message\n');
- });
-
- group('file segment', () {
- var baseOffset = 123;
- var segmentText = TEST_FILE.substring(baseOffset, TEST_FILE.length - 100);
- var segment = new SourceFileSegment('file', segmentText, loc(baseOffset));
- sline(int n) => segment.getLine(n);
- scol(int n) => segment.getColumn(segment.getLine(n), n);
- line(int n) => file.getLine(n);
- col(int n) => file.getColumn(file.getLine(n), n);
-
- test('get line and column', () {
- int j = 0;
- int lineOffset = 0;
- for (int i = baseOffset; i < segmentText.length; i++) {
- if (i > lineOffset + newLines[j]) {
- lineOffset += newLines[j] + 1;
- j++;
- }
- expect(segment.location(i - baseOffset).offset, i);
- expect(segment.location(i - baseOffset).line, line(i));
- expect(segment.location(i - baseOffset).column, col(i));
- expect(segment.span(i - baseOffset).start.offset, i);
- expect(segment.span(i - baseOffset).start.line, line(i));
- expect(segment.span(i - baseOffset).start.column, col(i));
-
- expect(sline(i), line(i));
- expect(scol(i), col(i));
- }
- });
-
- test('get text', () {
- var start = 10 + 80 + 31 + 27 + 4 + 2;
- expect(segment.getText(start, start + 9), file.getText(start, start + 9));
- });
-
- group('location message', () {
- test('first line', () {
- var start = baseOffset + 7;
- expect(segment.getLocationMessage('the message', start, start + 2),
- file.getLocationMessage('the message', start, start + 2));
- });
-
- test('in a middle line', () {
- // Example from another test above:
- var start = 10 + 80 + 31 + 27 + 4 + 2;
- expect(segment.getLocationMessage('the message', start, start + 9),
- file.getLocationMessage('the message', start, start + 9));
- });
-
- test('last segment line', () {
- var start = segmentText.length - 4;
- expect(segment.getLocationMessage('the message', start, start + 2),
- file.getLocationMessage('the message', start, start + 2));
- });
-
- test('past segment, same as last segment line', () {
- var start = segmentText.length;
- expect(segment.getLocationMessage('the message', start, start + 2),
- file.getLocationMessage('the message', start, start + 2));
-
- start = segmentText.length + 20;
- expect(segment.getLocationMessage('the message', start, start + 2),
- file.getLocationMessage('the message', start, start + 2));
- });
-
- test('past segment, past its line', () {
- var start = TEST_FILE.length - 2;
- expect(file.getLocationMessage('the message', start, start + 1),
- 'line 12, column 29 of file: the message\n'
- '123456789_1+3456789_123456789\n'
- ' ^');
-
- // The answer below is different because the segment parsing only knows
- // about the 10 lines it has (and nothing about the possible extra lines
- // afterwards)
- expect(segment.getLocationMessage('the message', start, start + 1),
- 'line 11, column 1 of file: the message\n');
- });
- });
- });
-
- test('span isIdentifier defaults to false', () {
- var start = new TestLocation(0);
- var end = new TestLocation(1);
- expect(new TestSpan(start, end).isIdentifier, false);
- expect(file.span(8, 9, null).isIdentifier, false);
- expect(new FixedSpan('', 8, 1, 8, isIdentifier: null).isIdentifier, false);
- });
-
- test('span/location implement == and hashCode', () {
- expect(identical(span(10, 14), span(10, 14)), isFalse);
- expect(span(10, 14), equals(span(10, 14)));
- expect(span(10, 14).hashCode, span(10, 14).hashCode);
-
- expect(identical(loc(13), loc(13)), isFalse);
- expect(loc(13), equals(loc(13)));
- expect(loc(13).hashCode, loc(13).hashCode);
- });
-}
-
-class TestSpan extends Span {
- TestSpan(Location start, Location end) : super(start, end, null);
- get text => null;
-}
-
-class TestLocation extends Location {
- String get sourceUrl => '';
- TestLocation(int offset) : super(offset);
- get line => 0;
- get column => 0;
-}