Improve the message when a mixin cannot be applied because the superclass does not implement a required class (issue 36775)

Change-Id: Ifdcf8de365dbdcb50aa70acc8552a302ef2c8e1f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100700
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 9a9c95a..dc43fd4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -2343,9 +2343,11 @@
     ClassDeclaration declaration =
         node.thisOrAncestorOfType<ClassDeclaration>();
     if (declaration != null && declaration.extendsClause == null) {
+      // TODO(brianwilkerson) Find a way to pass in the name of the class
+      //  without needing to parse the message.
       String message = error.message;
-      int startIndex = message.indexOf("'", message.indexOf("'") + 1) + 1;
-      int endIndex = message.indexOf("'", startIndex);
+      int endIndex = message.lastIndexOf("'");
+      int startIndex = message.lastIndexOf("'", endIndex - 1) + 1;
       String typeName = message.substring(startIndex, endIndex);
       var changeBuilder = _newDartChangeBuilder();
       await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index e853b72..eb14da0 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -1743,15 +1743,18 @@
 
   /**
    * It's a compile-time error to apply a mixin to a class that doesn't
-   * implement all the on type requirements of the mixin declaration.
+   * implement all the `on` type requirements of the mixin declaration.
    *
    * Parameters:
-   * 0: the display name of the not implemented type
+   * 0: the display name of the mixin
+   * 1: the display name of the superclass
+   * 2: the display name of the type that is not implemented
    */
   static const CompileTimeErrorCode
       MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE = const CompileTimeErrorCode(
           'MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE',
-          "The class doesn't implement the required class '{0}'.",
+          "'{0}' cannot be mixed onto '{1}' "
+              "because '{1}' does not implement '{2}'.",
           correction: "Try extending the class '{0}'.");
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 2567320..c17bf9f 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -4246,8 +4246,11 @@
       if (!isSatisfied) {
         _errorReporter.reportErrorForNode(
             CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE,
-            mixinName.name,
-            [constraint.displayName]);
+            mixinName.name, [
+          mixinName.type.displayName,
+          _enclosingClass.supertype,
+          constraint.displayName
+        ]);
         return true;
       }
     }