Don't crash on surrogate pairs. (#5)

Closes #4
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa4cb6e..83ca15b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.0.2
+
+* `SpanScanner` no longer crashes when creating a span that contains a UTF-16
+  surrogate pair.
+
 ## 1.0.1
 
 * Fix the error text emitted by `StringScanner.expectChar()`.
diff --git a/lib/src/span_scanner.dart b/lib/src/span_scanner.dart
index 043021b..f362223 100644
--- a/lib/src/span_scanner.dart
+++ b/lib/src/span_scanner.dart
@@ -56,7 +56,7 @@
   /// [FileSpan]s as well as for error reporting. It can be a [String], a
   /// [Uri], or `null`.
   SpanScanner(String string, {sourceUrl, int position})
-      : _sourceFile = new SourceFile(string, url: sourceUrl),
+      : _sourceFile = new SourceFile.fromString(string, url: sourceUrl),
         super(string, sourceUrl: sourceUrl, position: position);
 
   /// Creates a new [SpanScanner] that eagerly computes line and column numbers.
diff --git a/lib/src/string_scanner.dart b/lib/src/string_scanner.dart
index 5817d56..712292c 100644
--- a/lib/src/string_scanner.dart
+++ b/lib/src/string_scanner.dart
@@ -204,7 +204,7 @@
     }
     if (length == null) length = match == null ? 0 : match.end - match.start;
 
-    var sourceFile = new SourceFile(string, url: sourceUrl);
+    var sourceFile = new SourceFile.fromString(string, url: sourceUrl);
     var span = sourceFile.span(position, position + length);
     throw new StringScannerException(message, span, string);
   }
diff --git a/pubspec.yaml b/pubspec.yaml
index ac893e2..f0862ee 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,12 +1,12 @@
 name: string_scanner
-version: 1.0.1
+version: 1.0.2
 author: "Dart Team <misc@dartlang.org>"
 homepage: https://github.com/dart-lang/string_scanner
 description: >
   A class for parsing strings using a sequence of patterns.
 dependencies:
   charcode: "^1.1.0"
-  source_span: "^1.0.0"
+  source_span: "^1.4.0"
 dev_dependencies:
   test: ">=0.12.0 <0.13.0"
 environment:
diff --git a/test/span_scanner_test.dart b/test/span_scanner_test.dart
index 84d7b94..ab3cc80 100644
--- a/test/span_scanner_test.dart
+++ b/test/span_scanner_test.dart
@@ -9,12 +9,13 @@
 import 'utils.dart';
 
 void main() {
-  testForImplementation("lazy", () {
-    return new SpanScanner('foo\nbar\nbaz', sourceUrl: 'source');
+  testForImplementation("lazy", ([string]) {
+    return new SpanScanner(string ?? 'foo\nbar\nbaz', sourceUrl: 'source');
   });
 
-  testForImplementation("eager", () {
-    return new SpanScanner.eager('foo\nbar\nbaz', sourceUrl: 'source');
+  testForImplementation("eager", ([string]) {
+    return new SpanScanner.eager(string ?? 'foo\nbar\nbaz',
+        sourceUrl: 'source');
   });
 
   group("within", () {
@@ -23,7 +24,7 @@
 
     var scanner;
     setUp(() {
-      var file = new SourceFile(text, url: 'source');
+      var file = new SourceFile.fromString(text, url: 'source');
       scanner = new SpanScanner.within(
           file.span(startOffset, text.indexOf(' :after')));
     });
@@ -136,6 +137,15 @@
       expect(span.text, equals('o\nbar\nba'));
     });
 
+    test(".spanFrom() handles surrogate pairs correctly", () {
+      scanner = create('fo\u{12345}o');
+      scanner.scan('fo');
+      var state = scanner.state;
+      scanner.scan('\u{12345}o');
+      var span = scanner.spanFrom(state);
+      expect(span.text, equals('\u{12345}o'));
+    });
+
     test(".emptySpan returns an empty span at the current location", () {
       scanner.scan('foo\nba');