Several minor fixes to the analyzer/FE comparison tool.

- Mixin applications are now handled correctly.

- The front end's synthetic field "_exports#" is now ignored.

- Forwarding semi-stubs were erroneously being skipped; they are now
  included, as they should be (since they correspond to methods
  explictly declared in the source code).

- Named parameters in function types are now annotated properly (the
  annotation was previously missing a ": ").

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

Change-Id: I148269c967cc0fdf67bcfcd698cba36fc0b66368
Reviewed-on: https://dart-review.googlesource.com/75121
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer_fe_comparison/lib/src/analyzer.dart b/pkg/analyzer_fe_comparison/lib/src/analyzer.dart
index 9da54d4..d8e9a94 100644
--- a/pkg/analyzer_fe_comparison/lib/src/analyzer.dart
+++ b/pkg/analyzer_fe_comparison/lib/src/analyzer.dart
@@ -103,24 +103,22 @@
   void visitClassDeclaration(ClassDeclaration node) {
     var children = <ComparisonNode>[];
     var visitor = _AnalyzerVisitor(_typeProvider, children);
-    visitor._visitTypeParameters(node.declaredElement.typeParameters);
-    if (node.declaredElement.supertype != null) {
-      children.add(_translateType('Extends: ', node.declaredElement.supertype));
-    }
-    for (int i = 0; i < node.declaredElement.mixins.length; i++) {
-      children
-          .add(_translateType('Mixin $i: ', node.declaredElement.mixins[i]));
-    }
-    for (int i = 0; i < node.declaredElement.interfaces.length; i++) {
-      children.add(_translateType(
-          'Implements $i: ', node.declaredElement.interfaces[i]));
-    }
+    visitor._handleClassOrClassTypeAlias(node.declaredElement);
     visitor._visitList(node.members);
     _resultNodes
         .add(ComparisonNode.sorted('Class ${node.name.name}', children));
   }
 
   @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    var children = <ComparisonNode>[];
+    var visitor = _AnalyzerVisitor(_typeProvider, children);
+    visitor._handleClassOrClassTypeAlias(node.declaredElement);
+    _resultNodes.add(
+        ComparisonNode.sorted('MixinApplication ${node.name.name}', children));
+  }
+
+  @override
   void visitConstructorDeclaration(ConstructorDeclaration node) {
     var children = <ComparisonNode>[];
     var visitor = _AnalyzerVisitor(_typeProvider, children);
@@ -218,6 +216,20 @@
     }
   }
 
+  void _handleClassOrClassTypeAlias(ClassElement element) {
+    _visitTypeParameters(element.typeParameters);
+    if (element.supertype != null) {
+      _resultNodes.add(_translateType('Extends: ', element.supertype));
+    }
+    for (int i = 0; i < element.mixins.length; i++) {
+      _resultNodes.add(_translateType('Mixin $i: ', element.mixins[i]));
+    }
+    for (int i = 0; i < element.interfaces.length; i++) {
+      _resultNodes
+          .add(_translateType('Implements $i: ', element.interfaces[i]));
+    }
+  }
+
   /// Converts the analyzer representation of a type into a ComparisonNode.
   ComparisonNode _translateType(String prefix, DartType type) {
     if (type is InterfaceType) {
diff --git a/pkg/analyzer_fe_comparison/lib/src/kernel.dart b/pkg/analyzer_fe_comparison/lib/src/kernel.dart
index 0263600..04e16a9 100644
--- a/pkg/analyzer_fe_comparison/lib/src/kernel.dart
+++ b/pkg/analyzer_fe_comparison/lib/src/kernel.dart
@@ -93,7 +93,9 @@
   @override
   void visitClass(Class class_) {
     if (class_.isAnonymousMixin) return null;
-    var kind = class_.isEnum ? 'Enum' : 'Class';
+    var kind = class_.isEnum
+        ? 'Enum'
+        : class_.isMixinApplication ? 'MixinApplication' : 'Class';
     var children = <ComparisonNode>[];
     var visitor = _KernelVisitor(children);
     if (class_.isEnum) {
@@ -108,6 +110,9 @@
       if (class_.supertype != null) {
         var declaredSupertype = class_.supertype.asInterfaceType;
         var mixedInTypes = <DartType>[];
+        if (class_.isMixinApplication) {
+          mixedInTypes.add(class_.mixedInType.asInterfaceType);
+        }
         while (declaredSupertype.classNode.isAnonymousMixin) {
           // Since we're walking from the class to its declared supertype, we
           // encounter the mixins in the reverse order that they were declared,
@@ -151,6 +156,7 @@
   @override
   void visitField(Field field) {
     if (field.name.name == '_redirecting#') return null;
+    if (field.name.name == '_exports#') return null;
     var children = <ComparisonNode>[];
     children.add(_TypeVisitor.translate('Type: ', field.type));
     // TODO(paulberry): handle more fields from Field
@@ -197,7 +203,9 @@
 
   @override
   void visitProcedure(Procedure procedure) {
-    if (procedure.isForwardingStub) return null;
+    if (procedure.isSyntheticForwarder) {
+      return null;
+    }
     // TODO(paulberry): add an annotation to the ComparisonNode when the
     // procedure is a factory.
     var kind = procedure.isFactory
@@ -278,8 +286,8 @@
           .add(translate('$kind parameter $i: ', node.positionalParameters[i]));
     }
     for (var namedType in node.namedParameters) {
-      children
-          .add(translate('Named parameter ${namedType.name}', namedType.type));
+      children.add(
+          translate('Named parameter ${namedType.name}: ', namedType.type));
     }
     return ComparisonNode.sorted('${_prefix}FunctionType', children);
   }