Deprecate the source_maps span classes.

This also updates source_maps to take the new classes where possible.

BUG=19930
R=sigmund@google.com

Review URL: https://codereview.chromium.org//402843003

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart/pkg/source_maps@38524 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c52d585..6d371c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 * Update `SpanFormatException` with `source` and `offset`.
 
+* All methods that take `Span`s, `Location`s, and `SourceFile`s as inputs now
+  also accept the corresponding `source_span` classes as well. Using the old
+  classes is now deprecated and will be unsupported in version 0.10.0.
+
 ## 0.9.3
 
 * Support writing SingleMapping objects to source map version 3 format.
diff --git a/lib/builder.dart b/lib/builder.dart
index cd30ccb..494a6b6 100644
--- a/lib/builder.dart
+++ b/lib/builder.dart
@@ -11,6 +11,7 @@
 
 import 'parser.dart';
 import 'span.dart';
+import 'src/span_wrapper.dart';
 
 /// Builds a source map given a set of mappings.
 class SourceMapBuilder {
@@ -18,8 +19,10 @@
   final List<Entry> _entries = <Entry>[];
 
   /// Adds an entry mapping the [targetOffset] to [source].
-  void addFromOffset(Location source,
-      SourceFile targetFile, int targetOffset, String identifier) {
+  ///
+  /// [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) {
     if (targetFile == null) {
       throw new ArgumentError('targetFile cannot be null');
     }
@@ -28,12 +31,27 @@
   }
 
   /// Adds an entry mapping [target] to [source].
-  void addSpan(Span source, Span target) {
-    var name = source.isIdentifier ? source.text : null;
+  ///
+  /// [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;
+
+    var name = isIdentifier ? source.text : null;
     _entries.add(new Entry(source.start, target.start, name));
   }
 
-  void addLocation(Location source, Location target, String identifier) {
+  /// 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) {
     _entries.add(new Entry(source, target, identifier));
   }
 
@@ -57,7 +75,14 @@
   /// An identifier name, when this location is the start of an identifier.
   final String identifierName;
 
-  Entry(this.source, this.target, this.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);
 
   /// Implements [Comparable] to ensure that entries are ordered by their
   /// location in the target file. We sort primarily by the target offset
diff --git a/lib/parser.dart b/lib/parser.dart
index 3fd0d14..c18a1d6 100644
--- a/lib/parser.dart
+++ b/lib/parser.dart
@@ -10,6 +10,7 @@
 
 import 'builder.dart' as builder;
 import 'span.dart';
+import 'src/span_wrapper.dart';
 import 'src/utils.dart';
 import 'src/vlq.dart';
 
@@ -47,10 +48,21 @@
 
 /// A mapping parsed out of a source map.
 abstract class Mapping {
-  Span spanFor(int line, int column, {Map<String, SourceFile> files});
+  /// 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});
 
-  Span spanForLocation(Location loc, {Map<String, SourceFile> files}) {
-    return spanFor(loc.line, loc.column, files: 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);
+    return spanFor(location.line, location.column, files: files);
   }
 }
 
@@ -112,7 +124,7 @@
     return _lineStart.length - 1;
   }
 
-  Span spanFor(int line, int column, {Map<String, SourceFile> files}) {
+  Span spanFor(int line, int column, {Map<String, dynamic> files}) {
     int index = _indexFor(line, column);
     return _maps[index].spanFor(
         line - _lineStart[index], column - _columnStart[index], files: files);
@@ -351,7 +363,7 @@
     return (index <= 0) ? null : entries[index - 1];
   }
 
-  Span spanFor(int line, int column, {Map<String, SourceFile> files}) {
+  Span spanFor(int line, int column, {Map<String, dynamic> files}) {
     var entry = _findColumn(line, column, _findLine(line));
     if (entry == null || entry.sourceUrlId == null) return null;
     var url = urls[entry.sourceUrlId];
@@ -359,7 +371,7 @@
       url = '${sourceRoot}${url}';
     }
     if (files != null && files[url] != null) {
-      var file = files[url];
+      var file = SourceFileWrapper.wrap(files[url]);
       var start = file.getOffset(entry.sourceLine, entry.sourceColumn);
       if (entry.sourceNameId != null) {
         var text = names[entry.sourceNameId];
diff --git a/lib/printer.dart b/lib/printer.dart
index 0898017..aa18bd7 100644
--- a/lib/printer.dart
+++ b/lib/printer.dart
@@ -5,8 +5,11 @@
 /// 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 'builder.dart';
 import 'span.dart';
+import 'src/span_wrapper.dart';
 
 const int _LF = 10;
 const int _CR = 13;
@@ -75,9 +78,10 @@
   void mark(mark) {
     var loc;
     var identifier = null;
-    if (mark is Location) {
-      loc = mark;
-    } else if (mark is Span) {
+    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);
       loc = mark.start;
       if (mark.isIdentifier) identifier = mark.text;
     }
@@ -124,15 +128,19 @@
   /// 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 location, Span span, bool isOriginal: false}) {
+  void add(object, {location, span, bool isOriginal: false}) {
     if (object is! String || location != null || span != null || isOriginal) {
       _flush();
       assert(location == null || span == null);
-      if (location != null) _items.add(location);
-      if (span != null) _items.add(span);
+      if (location != null) _items.add(LocationWrapper.wrap(location));
+      if (span != null) _items.add(SpanWrapper.wrap(span));
       if (isOriginal) _items.add(_ORIGINAL);
     }
 
@@ -156,12 +164,16 @@
   /// 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.
-  void addLine(String line, {Location location, Span span}) {
+  ///
+  /// [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}) {
     if (location != null || span != null) {
       _flush();
       assert(location == null || span == null);
-      if (location != null) _items.add(location);
-      if (span != null) _items.add(span);
+      if (location != null) _items.add(LocationWrapper.wrap(location));
+      if (span != null) _items.add(SpanWrapper.wrap(span));
     }
     if (line == null) return;
     if (line != '') {
diff --git a/lib/refactor.dart b/lib/refactor.dart
index 45fb069..47ce2ed 100644
--- a/lib/refactor.dart
+++ b/lib/refactor.dart
@@ -10,6 +10,7 @@
 
 import 'span.dart';
 import 'printer.dart';
+import 'src/span_wrapper.dart';
 
 /// Editable text transaction.
 ///
@@ -20,7 +21,13 @@
   final String original;
   final _edits = <_TextEdit>[];
 
-  TextEditTransaction(this.original, this.file);
+  /// 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);
 
   bool get hasEdits => _edits.length > 0;
 
diff --git a/lib/span.dart b/lib/span.dart
index b546a97..a21e893 100644
--- a/lib/span.dart
+++ b/lib/span.dart
@@ -12,6 +12,7 @@
 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;
@@ -79,6 +80,7 @@
 }
 
 /// 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;
@@ -113,6 +115,7 @@
 }
 
 /// 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;
@@ -123,6 +126,7 @@
 }
 
 /// 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;
@@ -137,6 +141,7 @@
 }
 
 /// [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;
@@ -149,6 +154,7 @@
 }
 
 /// [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;
@@ -195,6 +201,7 @@
 /// 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;
@@ -306,6 +313,7 @@
 /// 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;
@@ -365,6 +373,7 @@
 }
 
 /// 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;
@@ -384,6 +393,7 @@
 }
 
 /// A [SpanException] that's also a [FormatException].
+@Deprecated("Use the source_span package instead.")
 class SpanFormatException extends SpanException implements FormatException {
   final source;
 
diff --git a/lib/src/span_wrapper.dart b/lib/src/span_wrapper.dart
new file mode 100644
index 0000000..e0c107b
--- /dev/null
+++ b/lib/src/span_wrapper.dart
@@ -0,0 +1,85 @@
+// 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/pubspec.yaml b/pubspec.yaml
index c5029e2..0548215 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -7,12 +7,13 @@
 #
 # When the minor version is upgraded, you *must* update that version constraint
 # in pub to stay in sync with this.
-version: 0.9.4
+version: 0.9.4-dev
 author: Dart Team <misc@dartlang.org>
 description: Library to programmatically manipulate source map files.
 homepage: http://www.dartlang.org
 dependencies:
   path: '>=1.2.0 <2.0.0'
+  source_span: '>=1.0.0 <2.0.0'
 environment:
   sdk: '>=0.8.10+6 <2.0.0'
 dev_dependencies: