add a dataClass macro that combines several other macros

Change-Id: I1d20f286805fa85e4b7853b5f0fa8fd7a77beb47
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210426
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Auto-Submit: Jake Macdonald <jakemac@google.com>
diff --git a/pkg/analyzer/lib/src/macro/builders/data_class.dart b/pkg/analyzer/lib/src/macro/builders/data_class.dart
index 86d99e0..a4a0393 100644
--- a/pkg/analyzer/lib/src/macro/builders/data_class.dart
+++ b/pkg/analyzer/lib/src/macro/builders/data_class.dart
@@ -39,6 +39,20 @@
   }
 }
 
+class DataClassMacro implements ClassDeclarationMacro {
+  const DataClassMacro();
+
+  @override
+  void visitClassDeclaration(
+    ast.ClassDeclaration declaration,
+    ClassDeclarationBuilder builder,
+  ) {
+    const AutoConstructorMacro().visitClassDeclaration(declaration, builder);
+    const HashCodeMacro().visitClassDeclaration(declaration, builder);
+    const ToStringMacro().visitClassDeclaration(declaration, builder);
+  }
+}
+
 class HashCodeMacro implements ClassDeclarationMacro {
   const HashCodeMacro();
 
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 661ba7d..8cadf5b 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -248,6 +248,12 @@
               classBuilder,
             );
           }
+          if (hasMacroAnnotation(declaration, 'dataClass')) {
+            macro.DataClassMacro().visitClassDeclaration(
+              declaration,
+              classBuilder,
+            );
+          }
           if (hasMacroAnnotation(declaration, 'hashCode')) {
             macro.HashCodeMacro().visitClassDeclaration(
               declaration,
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index a0c24da..e434353 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -21305,6 +21305,92 @@
 ''');
   }
 
+  test_macro_dataClass() async {
+    addLibrarySource('/macro_annotations.dart', r'''
+library analyzer.macro.annotations;
+const dataClass = 0;
+''');
+    var library = await checkLibrary(r'''
+import 'macro_annotations.dart';
+@dataClass
+class A {
+  final int a;
+  final int b;
+}
+''');
+    checkElementText(library, r'''
+library
+  imports
+    macro_annotations.dart
+  definingUnit
+    classes
+      class A @50
+        metadata
+          Annotation
+            atSign: @ @33
+            element: macro_annotations.dart::@getter::dataClass
+            name: SimpleIdentifier
+              staticElement: macro_annotations.dart::@getter::dataClass
+              staticType: null
+              token: dataClass @34
+        fields
+          final a @66
+            type: int
+          final b @81
+            type: int
+          synthetic hashCode @-1
+            type: int
+        constructors
+          @87
+            parameters
+              requiredName final this.a @104
+                type: int
+              requiredName final this.b @121
+                type: int
+        accessors
+          synthetic get a @-1
+            returnType: int
+          synthetic get b @-1
+            returnType: int
+          get hashCode @149
+            metadata
+              Annotation
+                atSign: @ @129
+                element: dart:core::@getter::override
+                name: SimpleIdentifier
+                  staticElement: dart:core::@getter::override
+                  staticType: null
+                  token: override @130
+            returnType: int
+        methods
+          toString @208
+            metadata
+              Annotation
+                atSign: @ @189
+                element: dart:core::@getter::override
+                name: SimpleIdentifier
+                  staticElement: dart:core::@getter::override
+                  staticType: null
+                  token: override @190
+            returnType: String
+    macroGeneratedContent
+import 'macro_annotations.dart';
+@dataClass
+class A {
+  final int a;
+  final int b;
+
+  A({required this.a, required this.b});
+
+  @override
+  int get hashCode => a.hashCode ^ b.hashCode;
+
+  @override
+  String toString() => 'A(a: $a, b: $b)';
+}
+''');
+  }
+
   test_macro_hashCode() async {
     addLibrarySource('/macro_annotations.dart', r'''
 library