Store super-invoked names for mixins.

R=brianwilkerson@google.com

Change-Id: Ifd0ae3fed1ca12cee2a14067b6accfae8407ea62
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100901
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d1e04eb..c708022 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7358,11 +7358,17 @@
 
   @override
   List<String> get superInvokedNames {
-    if (_superInvokedNames == null) {
-      if (_unlinkedClass != null) {
-        _superInvokedNames = _unlinkedClass.superInvokedNames;
-      }
+    if (_superInvokedNames != null) return _superInvokedNames;
+
+    if (linkedNode != null) {
+      return _superInvokedNames =
+          linkedContext.getMixinSuperInvokedNames(linkedNode);
     }
+
+    if (_unlinkedClass != null) {
+      return _superInvokedNames = _unlinkedClass.superInvokedNames;
+    }
+
     return _superInvokedNames ?? const <String>[];
   }
 
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 3c84d0d..ff3d13e 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -4752,6 +4752,7 @@
   LinkedNodeBuilder _variantField_14;
   bool _isSynthetic;
   idl.LinkedNodeKind _kind;
+  List<String> _variantField_36;
   String _variantField_20;
   bool _variantField_31;
   TopLevelInferenceErrorBuilder _variantField_35;
@@ -10011,6 +10012,17 @@
   }
 
   @override
+  List<String> get mixinDeclaration_superInvokedNames {
+    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
+    return _variantField_36 ??= <String>[];
+  }
+
+  set mixinDeclaration_superInvokedNames(List<String> value) {
+    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
+    _variantField_36 = value;
+  }
+
+  @override
   String get namespaceDirective_selectedUri {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
@@ -10862,6 +10874,7 @@
     int codeLength,
     int codeOffset,
     LinkedNodeBuilder namedCompilationUnitMember_name,
+    List<String> mixinDeclaration_superInvokedNames,
     bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.mixinDeclaration,
         _variantField_11 = annotatedNode_comment,
@@ -10876,6 +10889,7 @@
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
         _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_36 = mixinDeclaration_superInvokedNames,
         _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.partDirective({
@@ -11803,6 +11817,14 @@
     signature.addInt(this._variantField_34 ?? 0);
     signature.addBool(this._variantField_35 != null);
     this._variantField_35?.collectApiSignature(signature);
+    if (this._variantField_36 == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._variantField_36.length);
+      for (var x in this._variantField_36) {
+        signature.addString(x);
+      }
+    }
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
@@ -11824,6 +11846,7 @@
     fb.Offset offset_variantField_25;
     fb.Offset offset_variantField_30;
     fb.Offset offset_variantField_14;
+    fb.Offset offset_variantField_36;
     fb.Offset offset_variantField_20;
     fb.Offset offset_variantField_35;
     fb.Offset offset_variantField_22;
@@ -11886,6 +11909,10 @@
     if (_variantField_14 != null) {
       offset_variantField_14 = _variantField_14.finish(fbBuilder);
     }
+    if (!(_variantField_36 == null || _variantField_36.isEmpty)) {
+      offset_variantField_36 = fbBuilder.writeList(
+          _variantField_36.map((b) => fbBuilder.writeString(b)).toList());
+    }
     if (_variantField_20 != null) {
       offset_variantField_20 = fbBuilder.writeString(_variantField_20);
     }
@@ -11995,6 +12022,9 @@
     if (_kind != null && _kind != idl.LinkedNodeKind.adjacentStrings) {
       fbBuilder.addUint8(0, _kind.index);
     }
+    if (offset_variantField_36 != null) {
+      fbBuilder.addOffset(36, offset_variantField_36);
+    }
     if (offset_variantField_20 != null) {
       fbBuilder.addOffset(20, offset_variantField_20);
     }
@@ -12061,6 +12091,7 @@
   idl.LinkedNode _variantField_14;
   bool _isSynthetic;
   idl.LinkedNodeKind _kind;
+  List<String> _variantField_36;
   String _variantField_20;
   bool _variantField_31;
   idl.TopLevelInferenceError _variantField_35;
@@ -15694,6 +15725,14 @@
   }
 
   @override
+  List<String> get mixinDeclaration_superInvokedNames {
+    assert(kind == idl.LinkedNodeKind.mixinDeclaration);
+    _variantField_36 ??= const fb.ListReader<String>(const fb.StringReader())
+        .vTableGet(_bc, _bcOffset, 36, const <String>[]);
+    return _variantField_36;
+  }
+
+  @override
   String get namespaceDirective_selectedUri {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
@@ -16675,6 +16714,9 @@
       if (namedCompilationUnitMember_name != null)
         _result["namedCompilationUnitMember_name"] =
             namedCompilationUnitMember_name.toJson();
+      if (mixinDeclaration_superInvokedNames.isNotEmpty)
+        _result["mixinDeclaration_superInvokedNames"] =
+            mixinDeclaration_superInvokedNames;
       if (simplyBoundable_isSimplyBounded != false)
         _result["simplyBoundable_isSimplyBounded"] =
             simplyBoundable_isSimplyBounded;
@@ -18158,6 +18200,8 @@
         "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
         "isSynthetic": isSynthetic,
         "kind": kind,
+        "mixinDeclaration_superInvokedNames":
+            mixinDeclaration_superInvokedNames,
         "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 87cd3d5..9afbf14 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1940,6 +1940,8 @@
 
   kind:LinkedNodeKind (id: 0);
 
+  variantField_36:[string] (id: 36);
+
   variantField_20:string (id: 20);
 
   variantField_31:bool (id: 31);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index b7f91ce..73bba33 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -1889,6 +1889,9 @@
   @VariantId(6, variant: LinkedNodeKind.mixinDeclaration)
   LinkedNode get mixinDeclaration_onClause;
 
+  @VariantId(36, variant: LinkedNodeKind.mixinDeclaration)
+  List<String> get mixinDeclaration_superInvokedNames;
+
   @VariantId(14, variantList: [
     LinkedNodeKind.classDeclaration,
     LinkedNodeKind.classTypeAlias,
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 0de8d42..b362bdf 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -894,7 +894,7 @@
       _readNodeListLazy(data.classOrMixinDeclaration_members),
       _getToken(data.classOrMixinDeclaration_rightBracket),
     );
-    LazyMixinDeclaration.setData(node, data);
+    LazyMixinDeclaration(node, data);
     return node;
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 094c67b..06ca89b 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -871,6 +871,7 @@
       mixinDeclaration_onClause: node.onClause?.accept(this),
     );
     _storeClassOrMixinDeclaration(builder, node);
+    LazyMixinDeclaration.get(node).put(builder);
     return builder;
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
index 5d130fa..4abe8d6 100644
--- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart' as ast;
+import 'package:analyzer/src/dart/ast/mixin_super_invoked_names.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart' show LibraryScope;
 import 'package:analyzer/src/generated/utilities_dart.dart';
@@ -286,6 +287,24 @@
     });
   }
 
+  void collectMixinSuperInvokedNames() {
+    for (var unitContext in context.units) {
+      for (var declaration in unitContext.unit.declarations) {
+        if (declaration is ast.MixinDeclaration) {
+          var names = Set<String>();
+          var collector = MixinSuperInvokedNamesCollector(names);
+          for (var executable in declaration.members) {
+            if (executable is ast.MethodDeclaration) {
+              executable.body.accept(collector);
+            }
+          }
+          var lazy = LazyMixinDeclaration.get(declaration);
+          lazy.setSuperInvokedNames(names.toList());
+        }
+      }
+    }
+  }
+
   void resolveConstructors() {
     ConstructorInitializerResolver(linker, element).resolve();
   }
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index bf3a54f..2553ef2 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -5,6 +5,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 
@@ -1190,10 +1191,33 @@
   bool _hasMembers = false;
   bool _hasMetadata = false;
 
-  LazyMixinDeclaration(this.data);
+  List<String> _superInvokedNames;
+
+  LazyMixinDeclaration(MixinDeclaration node, this.data) {
+    node.setProperty(_key, this);
+    if (data != null) {
+      LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
+    }
+  }
+
+  List<String> getSuperInvokedNames() {
+    return _superInvokedNames ??= data.mixinDeclaration_superInvokedNames;
+  }
+
+  void put(LinkedNodeBuilder builder) {
+    builder.mixinDeclaration_superInvokedNames = _superInvokedNames ?? [];
+  }
+
+  void setSuperInvokedNames(List<String> value) {
+    _superInvokedNames = value;
+  }
 
   static LazyMixinDeclaration get(MixinDeclaration node) {
-    return node.getProperty(_key);
+    LazyMixinDeclaration lazy = node.getProperty(_key);
+    if (lazy == null) {
+      return LazyMixinDeclaration(node, null);
+    }
+    return lazy;
   }
 
   static void readDocumentationComment(
@@ -1201,7 +1225,7 @@
     MixinDeclaration node,
   ) {
     var lazy = get(node);
-    if (lazy != null && !lazy._hasDocumentationComment) {
+    if (lazy.data != null && !lazy._hasDocumentationComment) {
       node.documentationComment = reader.readNode(
         lazy.data.annotatedNode_comment,
       );
@@ -1214,7 +1238,7 @@
     MixinDeclarationImpl node,
   ) {
     var lazy = get(node);
-    if (lazy != null && !lazy._hasImplementsClause) {
+    if (lazy.data != null && !lazy._hasImplementsClause) {
       node.implementsClause = reader.readNode(
         lazy.data.classOrMixinDeclaration_implementsClause,
       );
@@ -1227,7 +1251,7 @@
     MixinDeclaration node,
   ) {
     var lazy = get(node);
-    if (lazy != null && !lazy._hasMembers) {
+    if (lazy.data != null && !lazy._hasMembers) {
       var dataList = lazy.data.classOrMixinDeclaration_members;
       for (var i = 0; i < dataList.length; ++i) {
         var data = dataList[i];
@@ -1242,7 +1266,7 @@
     MixinDeclaration node,
   ) {
     var lazy = LazyMixinDeclaration.get(node);
-    if (lazy != null && !lazy._hasMetadata) {
+    if (lazy.data != null && !lazy._hasMetadata) {
       var dataList = lazy.data.annotatedNode_metadata;
       for (var i = 0; i < dataList.length; ++i) {
         var data = dataList[i];
@@ -1257,18 +1281,13 @@
     MixinDeclarationImpl node,
   ) {
     var lazy = get(node);
-    if (lazy != null && !lazy._hasOnClause) {
+    if (lazy.data != null && !lazy._hasOnClause) {
       node.onClause = reader.readNode(
         lazy.data.mixinDeclaration_onClause,
       );
       lazy._hasOnClause = true;
     }
   }
-
-  static void setData(MixinDeclaration node, LinkedNode data) {
-    node.setProperty(_key, LazyMixinDeclaration(data));
-    LazyAst.setSimplyBounded(node, data.simplyBoundable_isSimplyBounded);
-  }
 }
 
 class LazyTopLevelVariableDeclaration {
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 7e1b1b3..66b6e74 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -127,6 +127,13 @@
     _resolveConstructors();
     _resolveDefaultValues();
     _resolveMetadata();
+    _collectMixinSuperInvokedNames();
+  }
+
+  void _collectMixinSuperInvokedNames() {
+    for (var library in builders.values) {
+      library.collectMixinSuperInvokedNames();
+    }
   }
 
   void _computeLibraryScopes() {
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index b5aa8329..bc93069 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -520,6 +520,10 @@
     }
   }
 
+  List<String> getMixinSuperInvokedNames(MixinDeclaration node) {
+    return LazyMixinDeclaration.get(node).getSuperInvokedNames();
+  }
+
   int getNameOffset(AstNode node) {
     if (node is ConstructorDeclaration) {
       if (node.name != null) {