Handle errors when comparing analyzer and front end behaviors.

For now, if the front end detects an error, we just consider the test
to have passed; we don't try to verify that the analyzer also detects
an error.  This will be improved in a future CL.

Drops the number of failing language_2 tests with `--compiler
compare_analyzer_cfe` from 2676 to 405.

Change-Id: Ib4f3c99710df4a0f0aac9a1c22a9a3279c6a6479
Reviewed-on: https://dart-review.googlesource.com/74968
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer_fe_comparison/lib/comparison.dart b/pkg/analyzer_fe_comparison/lib/comparison.dart
index fe3f57e..461c11b 100644
--- a/pkg/analyzer_fe_comparison/lib/comparison.dart
+++ b/pkg/analyzer_fe_comparison/lib/comparison.dart
@@ -36,6 +36,15 @@
       packagesFileUri,
       platformUri,
       (uri) => uri.scheme == 'file');
+  if (kernelNode.text == 'Error occurred') {
+    // TODO(paulberry): really we should verify that the analyzer detects an
+    // error as well.  But that's not easy to do right now because we use the
+    // front end to chase imports so that we know which files to pass to the
+    // analyzer, and we can't rely on the front end import chasing when an error
+    // occurred.
+    print('No differences found (skipped due to front end compilation error)');
+    return;
+  }
   String startingPath;
   var inputs = <String>[];
   for (var library in kernelNode.children) {
@@ -52,7 +61,7 @@
   ComparisonNode analyzerNode =
       await analyzer.analyzeFiles(startingPath, inputs);
   var diff = ComparisonNode.diff(kernelNode, analyzerNode);
-  if (diff.children.isEmpty) {
+  if (diff.children.isEmpty && diff.text.startsWith('=')) {
     print('No differences found!');
   } else {
     print('Differences found:');
diff --git a/pkg/analyzer_fe_comparison/lib/src/kernel.dart b/pkg/analyzer_fe_comparison/lib/src/kernel.dart
index d9d8c89..0263600 100644
--- a/pkg/analyzer_fe_comparison/lib/src/kernel.dart
+++ b/pkg/analyzer_fe_comparison/lib/src/kernel.dart
@@ -15,8 +15,15 @@
 /// [ComparisonNode] representing them.
 Future<ComparisonNode> analyzePackage(
     List<Uri> inputs, Uri packagesFileUri, Uri platformUri) async {
+  bool errorOccurred = false;
   var component = await kernelForComponent(
-      inputs, _makeCompilerOptions(packagesFileUri, platformUri));
+      inputs,
+      _makeCompilerOptions(packagesFileUri, platformUri, (_) {
+        errorOccurred = true;
+      }));
+  if (errorOccurred) {
+    return ComparisonNode('Error occurred');
+  }
   var libraryNodes = <ComparisonNode>[];
   var visitor = _KernelVisitor(libraryNodes);
   for (var library in component.libraries) {
@@ -33,8 +40,15 @@
 /// Only libraries whose URI passes the [uriFilter] are included in the results.
 Future<ComparisonNode> analyzeProgram(Uri input, Uri packagesFileUri,
     Uri platformUri, bool uriFilter(Uri uri)) async {
+  var errorOccurred = false;
   var component = await kernelForProgram(
-      input, _makeCompilerOptions(packagesFileUri, platformUri));
+      input,
+      _makeCompilerOptions(packagesFileUri, platformUri, (_) {
+        errorOccurred = true;
+      }));
+  if (errorOccurred) {
+    return ComparisonNode('Error occurred');
+  }
   var libraryNodes = <ComparisonNode>[];
   var visitor = _KernelVisitor(libraryNodes);
   for (var library in component.libraries) {
@@ -45,7 +59,8 @@
   return ComparisonNode.sorted('Component', libraryNodes);
 }
 
-CompilerOptions _makeCompilerOptions(Uri packagesFileUri, Uri platformUri) {
+CompilerOptions _makeCompilerOptions(
+    Uri packagesFileUri, Uri platformUri, ErrorHandler onError) {
   var targetFlags = TargetFlags(strongMode: true, syncAsync: true);
   var target = NoneTarget(targetFlags);
   var fileSystem = StandardFileSystem.instance;
@@ -57,7 +72,8 @@
     ..strongMode = true
     ..target = target
     ..throwOnErrorsForDebugging = false
-    ..embedSourceText = false;
+    ..embedSourceText = false
+    ..onError = onError;
 }
 
 /// Visitor for serializing a kernel representation of a program into