Fix implicit call reference in summary representation

Bug: https://github.com/dart-lang/sdk/issues/47963
Change-Id: Ice412be0ced087f90486e9e1612e3be616ec6d6b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/225760
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 8b728b5..598631f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -83,7 +83,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 193;
+  static const int DATA_VERSION = 194;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index c7c08cf..114c5ec 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -95,6 +95,8 @@
         return _readGenericFunctionType();
       case Tag.IfElement:
         return _readIfElement();
+      case Tag.ImplicitCallReference:
+        return _readImplicitCallReference();
       case Tag.IndexExpression:
         return _readIndexExpression();
       case Tag.IntegerLiteralNegative1:
@@ -647,6 +649,22 @@
     );
   }
 
+  ImplicitCallReference _readImplicitCallReference() {
+    var expression = readNode() as Expression;
+    var typeArguments = _readOptionalNode() as TypeArgumentList?;
+    var typeArgumentTypes = _reader.readOptionalTypeList()!;
+    var staticElement = _reader.readElement() as MethodElement;
+
+    var node = astFactory.implicitCallReference(
+      expression: expression,
+      staticElement: staticElement,
+      typeArguments: typeArguments,
+      typeArgumentTypes: typeArgumentTypes,
+    );
+    _readExpressionResolution(node);
+    return node;
+  }
+
   IndexExpression _readIndexExpression() {
     var flags = _readByte();
     var target = _readOptionalNode() as Expression?;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
index a8033ec..38aa374 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_tag.dart
@@ -45,6 +45,7 @@
   static const int GenericFunctionType = 21;
   static const int HideCombinator = 48;
   static const int IfElement = 63;
+  static const int ImplicitCallReference = 104;
   static const int IndexExpression = 98;
   static const int InstanceCreationExpression = 25;
   static const int IntegerLiteralNegative = 73;
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 446308d..e03af22 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -359,6 +359,18 @@
   }
 
   @override
+  void visitImplicitCallReference(ImplicitCallReference node) {
+    _writeByte(Tag.ImplicitCallReference);
+    _writeNode(node.expression);
+    _writeOptionalNode(node.typeArguments);
+    _sink.writeOptionalTypeList(node.typeArgumentTypes);
+
+    _sink.writeElement(node.staticElement);
+
+    _storeExpression(node);
+  }
+
+  @override
   void visitIndexExpression(IndexExpression node) {
     _writeByte(Tag.IndexExpression);
     _writeByte(
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 3f5806f..3ca0b95 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -821,6 +821,19 @@
   }
 
   @override
+  void visitImplicitCallReference(ImplicitCallReference node) {
+    _writeln('ImplicitCallReference');
+    _withIndent(() {
+      var properties = _Properties();
+      properties.addNode('expression', node.expression);
+      properties.addNode('typeArguments', node.typeArguments);
+      properties.addTypeList('typeArgumentTypes', node.typeArgumentTypes);
+      _addExpression(properties, node);
+      _writeProperties(properties);
+    });
+  }
+
+  @override
   void visitImportDirective(ImportDirective node) {
     _writeNextCodeLine(node);
     _writeln('ImportDirective');
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 3d50b66..9ab1bc5 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -19495,6 +19495,63 @@
 ''');
   }
 
+  test_implicitCallTearoff() async {
+    var library = await checkLibrary(r'''
+class C {
+  void call() {}
+}
+
+class D {
+  const D(C c) : this.named(c);
+
+  const D.named(void Function() f);
+}
+''');
+    checkElementText(library, r'''
+library
+  definingUnit
+    classes
+      class C @6
+        constructors
+          synthetic @-1
+        methods
+          call @17
+            returnType: void
+      class D @36
+        constructors
+          const @48
+            parameters
+              requiredPositional c @52
+                type: C
+            constantInitializers
+              RedirectingConstructorInvocation
+                argumentList: ArgumentList
+                  arguments
+                    ImplicitCallReference
+                      expression: SimpleIdentifier
+                        staticElement: c@52
+                        staticType: C
+                        token: c @68
+                      staticType: void Function()
+                  leftParenthesis: ( @67
+                  rightParenthesis: ) @69
+                constructorName: SimpleIdentifier
+                  staticElement: self::@class::D::@constructor::named
+                  staticType: null
+                  token: named @62
+                period: . @61
+                staticElement: self::@class::D::@constructor::named
+                thisKeyword: this @57
+            redirectedConstructor: self::@class::D::@constructor::named
+          const named @83
+            periodOffset: 82
+            nameEnd: 88
+            parameters
+              requiredPositional f @105
+                type: void Function()
+''');
+  }
+
   test_implicitConstructor_named_const() async {
     var library = await checkLibrary('''
 class C {