[Macro] Resolve types in new class members in the scope of the class.

Change-Id: Iaf35bb0a7e941dba2bd80e1fe30e449623a16de9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/207862
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 3cb1a0f..9548d6e 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -182,6 +182,22 @@
       return false;
     }
 
+    /// Build types for type annotations in new [nodes].
+    void resolveTypeAnnotations(
+      List<ast.AstNode> nodes, {
+      ClassElementImpl? classElement,
+    }) {
+      var nodesToBuildType = NodesToBuildType();
+      var resolver = ReferenceResolver(linker, nodesToBuildType, element);
+      if (classElement != null) {
+        resolver.enterScopeClassElement(classElement);
+      }
+      for (var node in nodes) {
+        node.accept(resolver);
+      }
+      TypesBuilder(linker).build(nodesToBuildType);
+    }
+
     for (var linkingUnit in units) {
       for (var declaration in linkingUnit.node.declarations) {
         if (declaration is ast.ClassDeclarationImpl) {
@@ -206,17 +222,7 @@
             );
             var classElement = declaration.declaredElement as ClassElementImpl;
             elementBuilder.buildMacroClassMembers(classElement, newMembers);
-
-            // TODO(scheglov) extract
-            {
-              var nodesToBuildType = NodesToBuildType();
-              var resolver =
-                  ReferenceResolver(linker, nodesToBuildType, element);
-              for (var newMember in newMembers) {
-                newMember.accept(resolver);
-              }
-              TypesBuilder(linker).build(nodesToBuildType);
-            }
+            resolveTypeAnnotations(newMembers, classElement: classElement);
           }
         }
       }
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index 9e6260a..1cba245 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -45,6 +45,10 @@
         scope = libraryElement.scope,
         isNNBD = libraryElement.isNonNullableByDefault;
 
+  void enterScopeClassElement(ClassElementImpl element) {
+    scope = TypeParameterScope(scope, element.typeParameters);
+  }
+
   @override
   void visitBlockFunctionBody(BlockFunctionBody node) {}
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 8c5f16e..814a92b 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -21298,6 +21298,61 @@
 ''');
   }
 
+  test_macro_observable_generic() async {
+    addLibrarySource('/macro_annotations.dart', r'''
+library analyzer.macro.annotations;
+const observable = 0;
+''');
+    var library = await checkLibrary(r'''
+import 'macro_annotations.dart';
+class A<T> {
+  @observable
+  T _f;
+}
+''');
+    checkElementText(library, r'''
+library
+  imports
+    macro_annotations.dart
+  definingUnit
+    classes
+      class A @39
+        typeParameters
+          covariant T @41
+            defaultType: dynamic
+        fields
+          _f @64
+            metadata
+              Annotation
+                atSign: @ @48
+                element: macro_annotations.dart::@getter::observable
+                name: SimpleIdentifier
+                  staticElement: macro_annotations.dart::@getter::observable
+                  staticType: null
+                  token: observable @49
+            type: T
+          synthetic f @-1
+            type: T
+        constructors
+          synthetic @-1
+        accessors
+          synthetic get _f @-1
+            returnType: T
+          synthetic set _f @-1
+            parameters
+              requiredPositional __f @-1
+                type: T
+            returnType: void
+          get f @-1
+            returnType: T
+          set f @-1
+            parameters
+              requiredPositional val @-1
+                type: T
+            returnType: void
+''');
+  }
+
   test_main_class() async {
     var library = await checkLibrary('class main {}');
     checkElementText(library, r'''