Use parseString() API instead of internal Parser.
diff --git a/lib/src/dart_formatter.dart b/lib/src/dart_formatter.dart
index c602874..da00e20 100644
--- a/lib/src/dart_formatter.dart
+++ b/lib/src/dart_formatter.dart
@@ -7,16 +7,14 @@
 import 'dart:math' as math;
 
 import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/utilities.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/parser.dart';
-import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/string_source.dart';
 
-import 'error_listener.dart';
 import 'exceptions.dart';
 import 'source_code.dart';
 import 'source_visitor.dart';
@@ -87,8 +85,6 @@
   /// Returns a new [SourceCode] containing the formatted code and the resulting
   /// selection, if any.
   SourceCode formatSource(SourceCode source) {
-    var errorListener = ErrorListener();
-
     // Enable all features that are enabled by default in the current analyzer
     // version.
     // TODO(paulberry): consider plumbing in experiment enable flags from the
@@ -98,46 +94,69 @@
       'non-nullable',
     ]);
 
-    // Tokenize the source.
-    var reader = CharSequenceReader(source.text);
-    var stringSource = StringSource(source.text, source.uri);
-    var scanner = Scanner(stringSource, reader, errorListener);
-    scanner.configureFeatures(featureSet);
-    var startToken = scanner.tokenize();
-    var lineInfo = LineInfo(scanner.lineStarts);
+    var inputOffset = 0;
+    var text = source.text;
+    var unitSourceCode = source;
+    if (!source.isCompilationUnit) {
+      var prefix = 'void foo() { ';
+      inputOffset = prefix.length;
+      text = '$prefix$text }';
+      unitSourceCode = SourceCode(
+        text,
+        uri: source.uri,
+        isCompilationUnit: false,
+        selectionStart: source.selectionStart != null
+            ? source.selectionStart + inputOffset
+            : null,
+        selectionLength: source.selectionLength,
+      );
+    }
+
+    // Parse it.
+    var parseResult = parseString(
+      content: text,
+      featureSet: featureSet,
+      path: source.uri,
+      throwIfDiagnostics: false,
+    );
 
     // Infer the line ending if not given one. Do it here since now we know
     // where the lines start.
     if (lineEnding == null) {
       // If the first newline is "\r\n", use that. Otherwise, use "\n".
-      if (scanner.lineStarts.length > 1 &&
-          scanner.lineStarts[1] >= 2 &&
-          source.text[scanner.lineStarts[1] - 2] == '\r') {
+      var lineStarts = parseResult.lineInfo.lineStarts;
+      if (lineStarts.length > 1 &&
+          lineStarts[1] >= 2 &&
+          text[lineStarts[1] - 2] == '\r') {
         lineEnding = '\r\n';
       } else {
         lineEnding = '\n';
       }
     }
 
-    errorListener.throwIfErrors();
-
-    // Parse it.
-    var parser = Parser(stringSource, errorListener, featureSet: featureSet);
-    parser.enableOptionalNewAndConst = true;
-    parser.enableSetLiterals = true;
+    // Throw if there are syntactic errors.
+    var syntacticErrors = parseResult.errors.where((error) {
+      return error.errorCode.type == ErrorType.SYNTACTIC_ERROR;
+    }).toList();
+    if (syntacticErrors.isNotEmpty) {
+      throw FormatterException(syntacticErrors);
+    }
 
     AstNode node;
     if (source.isCompilationUnit) {
-      node = parser.parseCompilationUnit(startToken);
+      node = parseResult.unit;
     } else {
-      node = parser.parseStatement(startToken);
+      var function = parseResult.unit.declarations[0] as FunctionDeclaration;
+      var body = function.functionExpression.body as BlockFunctionBody;
+      node = body.block.statements[0];
 
       // Make sure we consumed all of the source.
       var token = node.endToken.next;
-      if (token.type != TokenType.EOF) {
+      if (token.type != TokenType.CLOSE_CURLY_BRACKET) {
+        var stringSource = StringSource(text, source.uri);
         var error = AnalysisError(
             stringSource,
-            token.offset,
+            token.offset - inputOffset,
             math.max(token.length, 1),
             ParserErrorCode.UNEXPECTED_TOKEN,
             [token.lexeme]);
@@ -146,10 +165,9 @@
       }
     }
 
-    errorListener.throwIfErrors();
-
     // Format it.
-    var visitor = SourceVisitor(this, lineInfo, source);
+    var lineInfo = parseResult.lineInfo;
+    var visitor = SourceVisitor(this, lineInfo, unitSourceCode);
     var output = visitor.run(node);
 
     // Sanity check that only whitespace was changed if that's all we expect.
diff --git a/lib/src/error_listener.dart b/lib/src/error_listener.dart
deleted file mode 100644
index a1df699..0000000
--- a/lib/src/error_listener.dart
+++ /dev/null
@@ -1,31 +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 dart_style.src.error_listener;
-
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/error/listener.dart';
-
-import 'exceptions.dart';
-
-/// A simple [AnalysisErrorListener] that just collects the reported errors.
-class ErrorListener implements AnalysisErrorListener {
-  final _errors = <AnalysisError>[];
-
-  @override
-  void onError(AnalysisError error) {
-    // Fasta produces some semantic errors, which we want to ignore so that
-    // users can format code containing static errors.
-    if (error.errorCode.type != ErrorType.SYNTACTIC_ERROR) return;
-
-    _errors.add(error);
-  }
-
-  /// Throws a [FormatterException] if any errors have been reported.
-  void throwIfErrors() {
-    if (_errors.isEmpty) return;
-
-    throw FormatterException(_errors);
-  }
-}