Support super completions from superclass constraints in a mixin

Change-Id: Iea4a540989113be85abf98f69cb63843da310a15
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/97020
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
index 63faf71..50e4b46 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -76,9 +76,11 @@
     }
     String containingMethodName;
     List<InterfaceType> mixins;
+    List<InterfaceType> superclassConstraints;
     if (expression is SuperExpression && type is InterfaceType) {
       // Suggest members from superclass if target is "super"
       mixins = (type as InterfaceType).mixins;
+      superclassConstraints = (type as InterfaceType).superclassConstraints;
       type = (type as InterfaceType).superclass;
       // Determine the name of the containing method because
       // the most likely completion is a super expression with same name
@@ -99,7 +101,8 @@
     // Build the suggestions
     if (type is InterfaceType) {
       _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary);
-      builder.buildSuggestions(type, containingMethodName, mixins: mixins);
+      builder.buildSuggestions(type, containingMethodName,
+          mixins: mixins, superclassConstraints: superclassConstraints);
       return builder.suggestions.toList();
     }
     return const <CompletionSuggestion>[];
@@ -290,7 +293,7 @@
    * is the name of the method in which the completion is requested.
    */
   void buildSuggestions(InterfaceType type, String containingMethodName,
-      {List<InterfaceType> mixins}) {
+      {List<InterfaceType> mixins, List<InterfaceType> superclassConstraints}) {
     // Visit all of the types in the class hierarchy, collecting possible
     // completions.  If multiple elements are found that complete to the same
     // identifier, addSuggestion will discard all but the first (with a few
@@ -299,6 +302,9 @@
     if (mixins != null) {
       types.addAll(mixins);
     }
+    if (superclassConstraints != null) {
+      types.addAll(superclassConstraints);
+    }
     for (InterfaceType targetType in types) {
       for (MethodElement method in targetType.methods) {
         // Exclude static methods when completion on an instance
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index c3712b1..11eb5eb 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -3659,6 +3659,19 @@
     assertNotSuggested('ms3');
   }
 
+  test_super_fromSuperclassConstraint() async {
+    addTestSource('''
+class C {
+  void c(x, int y) {}
+}
+mixin M on C {
+  m() {super.^}
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('c', 'C', 'void');
+  }
+
   test_super_withMixin() async {
     addTestSource('''
 mixin M {