Macro. Cache TypeDeclaration introspection results.

This makes https://dart-review.googlesource.com/c/sdk/+/361160/1
about 30% faster.

Before:
[time: 9800 ms]
(name: <scheduler>, count: 0, elapsed: 0:00:00.000000, elapsedSelf: -0:00:09.676162)
  (name: analyzeFile, count: 104, elapsed: 0:00:09.676162, elapsedSelf: 0:00:01.122336)
    (name: libraryContext, count: 104, elapsed: 0:00:08.553826, elapsedSelf: 0:00:00.370620)(bytesPut: 5378632, cycleCount: 9, libraryCount: 115)
      (name: link, count: 9, elapsed: 0:00:08.183206, elapsedSelf: 0:00:00.273932)
        (name: computeLibraryScopes, count: 9, elapsed: 0:00:00.137679, elapsedSelf: 0:00:00.073448)
          (name: buildMacroApplier, count: 9, elapsed: 0:00:00.064103, elapsedSelf: 0:00:00.064103)
          (name: executeMacroTypesPhase, count: 9, elapsed: 0:00:00.000128, elapsedSelf: 0:00:00.000128)
        (name: executeMacroDeclarationsPhase, count: 9, elapsed: 0:00:00.211514, elapsedSelf: 0:00:00.211514)(constructorsOf: 100, methodsOf: 100)
        (name: executeMacroDefinitionsPhase, count: 9, elapsed: 0:00:07.163251, elapsedSelf: 0:00:00.001486)
          (name: macroApplier.executeDefinitionsPhase, count: 315, elapsed: 0:00:06.532745, elapsedSelf: 0:00:00.008799)(constructorsOf: 20300, methodsOf: 20300, resolve: 42000, typeDeclarationOf: 41200)
            (name: macroExecutor.executeDefinitionsPhase, count: 200, elapsed: 0:00:06.523946, elapsedSelf: 0:00:06.523946)
          (name: addMacroResults, count: 200, elapsed: 0:00:00.629020, elapsedSelf: 0:00:00.629020)
        (name: mergeMacroAugmentations, count: 9, elapsed: 0:00:00.396830, elapsedSelf: 0:00:00.396830)

After:
[time: 6871 ms]
(name: <scheduler>, count: 0, elapsed: 0:00:00.000000, elapsedSelf: -0:00:06.742687)
  (name: analyzeFile, count: 104, elapsed: 0:00:06.742687, elapsedSelf: 0:00:01.014164)
    (name: libraryContext, count: 104, elapsed: 0:00:05.728523, elapsedSelf: 0:00:00.195590)(bytesPut: 5378632, cycleCount: 9, libraryCount: 115)
      (name: link, count: 9, elapsed: 0:00:05.316310, elapsedSelf: 0:00:00.278338)
        (name: computeLibraryScopes, count: 9, elapsed: 0:00:00.128982, elapsedSelf: 0:00:00.056258)
          (name: buildMacroApplier, count: 9, elapsed: 0:00:00.072625, elapsedSelf: 0:00:00.072625)
          (name: executeMacroTypesPhase, count: 9, elapsed: 0:00:00.000099, elapsedSelf: 0:00:00.000099)
        (name: executeMacroDeclarationsPhase, count: 9, elapsed: 0:00:00.223973, elapsedSelf: 0:00:00.223973)(constructorsOf: 100, methodsOf: 100)
        (name: executeMacroDefinitionsPhase, count: 9, elapsed: 0:00:04.264144, elapsedSelf: 0:00:00.001345)
          (name: executeDefinitionsPhase, count: 315, elapsed: 0:00:03.622893, elapsedSelf: 0:00:03.622893)(constructorsOf: 300, methodsOf: 300, resolve: 42000, typeDeclarationOf: 41200)
          (name: addMacroResults, count: 200, elapsed: 0:00:00.639906, elapsedSelf: 0:00:00.639906)
        (name: mergeMacroAugmentations, count: 9, elapsed: 0:00:00.420873, elapsedSelf: 0:00:00.420873)
      (name: macroCompileKernel, count: 1, elapsed: 0:00:00.216623, elapsedSelf: 0:00:00.216623)
Change-Id: Ica435904e9a0f686c91e7703262687c110600983
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/361622
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
diff --git a/pkg/_macros/lib/src/executor/protocol.dart b/pkg/_macros/lib/src/executor/protocol.dart
index 118ebf7..297e712 100644
--- a/pkg/_macros/lib/src/executor/protocol.dart
+++ b/pkg/_macros/lib/src/executor/protocol.dart
@@ -596,6 +596,12 @@
 final class ClientDeclarationPhaseIntrospector
     extends ClientTypePhaseIntrospector
     implements DeclarationPhaseIntrospector {
+  static final _constructorsCache =
+      Expando<Future<List<ConstructorDeclaration>>>();
+  static final _enumValuesCache = Expando<Future<List<EnumValueDeclaration>>>();
+  static final _fieldsCache = Expando<Future<List<FieldDeclaration>>>();
+  static final _methodsCache = Expando<Future<List<MethodDeclaration>>>();
+
   ClientDeclarationPhaseIntrospector(super._sendRequest,
       {required super.remoteInstance, required super.serializationZoneId});
 
@@ -620,48 +626,55 @@
   }
 
   @override
-  Future<List<ConstructorDeclaration>> constructorsOf(
-      TypeDeclaration type) async {
-    TypeIntrospectorRequest request = TypeIntrospectorRequest(
-        type, remoteInstance, MessageType.constructorsOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await _sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
+  Future<List<ConstructorDeclaration>> constructorsOf(TypeDeclaration type) {
+    return _constructorsCache[type] ??= Future(() async {
+      final request = TypeIntrospectorRequest(
+          type, remoteInstance, MessageType.constructorsOfRequest,
+          serializationZoneId: serializationZoneId);
+      return _handleResponse<DeclarationList>(await _sendRequest(request))
+          .declarations
+          // TODO: Refactor so we can remove this cast
+          .cast();
+    });
   }
 
   @override
-  Future<List<EnumValueDeclaration>> valuesOf(EnumDeclaration enumType) async {
-    TypeIntrospectorRequest request = TypeIntrospectorRequest(
-        enumType, remoteInstance, MessageType.valuesOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await _sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
+  Future<List<EnumValueDeclaration>> valuesOf(EnumDeclaration type) {
+    return _enumValuesCache[type] ??= Future(() async {
+      final request = TypeIntrospectorRequest(
+          type, remoteInstance, MessageType.valuesOfRequest,
+          serializationZoneId: serializationZoneId);
+      return _handleResponse<DeclarationList>(await _sendRequest(request))
+          .declarations
+          // TODO: Refactor so we can remove this cast
+          .cast();
+    });
   }
 
   @override
-  Future<List<FieldDeclaration>> fieldsOf(TypeDeclaration type) async {
-    TypeIntrospectorRequest request = TypeIntrospectorRequest(
-        type, remoteInstance, MessageType.fieldsOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await _sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
+  Future<List<FieldDeclaration>> fieldsOf(TypeDeclaration type) {
+    return _fieldsCache[type] ??= Future(() async {
+      final request = TypeIntrospectorRequest(
+          type, remoteInstance, MessageType.fieldsOfRequest,
+          serializationZoneId: serializationZoneId);
+      return _handleResponse<DeclarationList>(await _sendRequest(request))
+          .declarations
+          // TODO: Refactor so we can remove this cast
+          .cast();
+    });
   }
 
   @override
-  Future<List<MethodDeclaration>> methodsOf(TypeDeclaration type) async {
-    TypeIntrospectorRequest request = TypeIntrospectorRequest(
-        type, remoteInstance, MessageType.methodsOfRequest,
-        serializationZoneId: serializationZoneId);
-    return _handleResponse<DeclarationList>(await _sendRequest(request))
-        .declarations
-        // TODO: Refactor so we can remove this cast
-        .cast();
+  Future<List<MethodDeclaration>> methodsOf(TypeDeclaration type) {
+    return _methodsCache[type] ??= Future(() async {
+      final request = TypeIntrospectorRequest(
+          type, remoteInstance, MessageType.methodsOfRequest,
+          serializationZoneId: serializationZoneId);
+      return _handleResponse<DeclarationList>(await _sendRequest(request))
+          .declarations
+          // TODO: Refactor so we can remove this cast
+          .cast();
+    });
   }
 
   @override
diff --git a/pkg/_macros/pubspec.yaml b/pkg/_macros/pubspec.yaml
index cd1b954..966dbca 100644
--- a/pkg/_macros/pubspec.yaml
+++ b/pkg/_macros/pubspec.yaml
@@ -1,5 +1,5 @@
 name: _macros
-version: 0.1.0
+version: 0.1.1
 description: >-
   This is a private SDK vendored package, which is re-exported by the public
   `macros` package, which is a pub package. Every change to this package is
diff --git a/pkg/macros/pubspec.yaml b/pkg/macros/pubspec.yaml
index 1dddfc3..bd9a455 100644
--- a/pkg/macros/pubspec.yaml
+++ b/pkg/macros/pubspec.yaml
@@ -1,5 +1,5 @@
 name: macros
-version: 0.1.0-main.0
+version: 0.1.0-main.1
 description: >-
   This package is for macro authors, and exposes the APIs necessary to write
   a macro. It exports the APIs from the private `_macros` SDK vendored package.
@@ -11,4 +11,4 @@
 dependencies:
   _macros:
     sdk: dart
-    version: 0.1.0
+    version: 0.1.1