Fix bug regarding augmenting a field with a field after a non-field augment.

In the commit https://dart-review.googlesource.com/c/sdk/+/446702 these
tests were landed with several known flaws. One of these was the
processing of the chain: field -> augment getter -> augment field,
creating two fields.

This CL fixes the behavior such that augment field genuinely augments
the existing field instead of creating a new field. Test expectations
were correspondingly updated.

Change-Id: I6e3c822441a7fb5d2f94a673ed36d409ee5d03e6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448226
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 8ed4b8b4..f4e4f10 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2680,6 +2680,17 @@
   @override
   ElementKind get kind => ElementKind.FIELD;
 
+  FieldFragmentImpl get lastFragment {
+    var result = _firstFragment;
+    while (true) {
+      if (result.nextFragment case var nextFragment?) {
+        result = nextFragment;
+      } else {
+        return result;
+      }
+    }
+  }
+
   @Deprecated('Use library instead')
   @override
   LibraryElementImpl get library2 => library;
diff --git a/pkg/analyzer/lib/src/summary2/element_builder.dart b/pkg/analyzer/lib/src/summary2/element_builder.dart
index 1b44872..4f1c72d 100644
--- a/pkg/analyzer/lib/src/summary2/element_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/element_builder.dart
@@ -295,12 +295,15 @@
 
   void _handleInstanceFieldFragment(
     InstanceElementImpl instanceElement,
-    FragmentImpl? lastFieldFragment,
+    FragmentImpl? lastFragment,
     FieldFragmentImpl fieldFragment,
   ) {
     var instanceFragment = fieldFragment.enclosingFragment;
     instanceFragment.addField(fieldFragment);
 
+    var lastFieldElement = _fieldElement(lastFragment);
+    var lastFieldFragment = lastFieldElement?.lastFragment;
+
     if (fieldFragment.isAugmentation &&
         lastFieldFragment is FieldFragmentImpl) {
       lastFieldFragment.addFragment(fieldFragment);
diff --git a/pkg/analyzer/test/src/summary/elements/class_test.dart b/pkg/analyzer/test/src/summary/elements/class_test.dart
index 9a49ac3..b0d0f66 100644
--- a/pkg/analyzer/test/src/summary/elements/class_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/class_test.dart
@@ -22851,95 +22851,68 @@
           nextFragment: #F2
           fields
             #F3 hasInitializer foo (nameOffset:16) (firstTokenOffset:16) (offset:16)
-              element: <testLibrary>::@class::A::@field::foo::@def::0
+              element: <testLibrary>::@class::A::@field::foo
+              nextFragment: #F4
           constructors
-            #F4 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
+            #F5 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
               element: <testLibrary>::@class::A::@constructor::new
               typeName: A
           getters
-            #F5 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
-              element: <testLibrary>::@class::A::@getter::foo::@def::0
-              nextFragment: #F6
+            #F6 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
+              element: <testLibrary>::@class::A::@getter::foo
+              nextFragment: #F7
           setters
-            #F7 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
-              element: <testLibrary>::@class::A::@setter::foo::@def::0
+            #F8 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
+              element: <testLibrary>::@class::A::@setter::foo
               formalParameters
-                #F8 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
-                  element: <testLibrary>::@class::A::@setter::foo::@def::0::@formalParameter::value
+                #F9 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
+                  element: <testLibrary>::@class::A::@setter::foo::@formalParameter::value
         #F2 class A (nameOffset:42) (firstTokenOffset:28) (offset:42)
           element: <testLibrary>::@class::A
           previousFragment: #F1
-          nextFragment: #F9
+          nextFragment: #F10
           getters
-            #F6 augment foo (nameOffset:64) (firstTokenOffset:48) (offset:64)
-              element: <testLibrary>::@class::A::@getter::foo::@def::0
-              previousFragment: #F5
-        #F9 class A (nameOffset:91) (firstTokenOffset:77) (offset:91)
+            #F7 augment foo (nameOffset:64) (firstTokenOffset:48) (offset:64)
+              element: <testLibrary>::@class::A::@getter::foo
+              previousFragment: #F6
+        #F10 class A (nameOffset:91) (firstTokenOffset:77) (offset:91)
           element: <testLibrary>::@class::A
           previousFragment: #F2
           fields
-            #F10 augment hasInitializer foo (nameOffset:109) (firstTokenOffset:109) (offset:109)
-              element: <testLibrary>::@class::A::@field::foo::@def::1
-          getters
-            #F11 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:109)
-              element: <testLibrary>::@class::A::@getter::foo::@def::1
-          setters
-            #F12 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:109)
-              element: <testLibrary>::@class::A::@setter::foo::@def::1
-              formalParameters
-                #F13 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:109)
-                  element: <testLibrary>::@class::A::@setter::foo::@def::1::@formalParameter::value
+            #F4 augment hasInitializer foo (nameOffset:109) (firstTokenOffset:109) (offset:109)
+              element: <testLibrary>::@class::A::@field::foo
+              previousFragment: #F3
   classes
     hasNonFinalField class A
       reference: <testLibrary>::@class::A
       firstFragment: #F1
       fields
         hasInitializer foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::0
+          reference: <testLibrary>::@class::A::@field::foo
           firstFragment: #F3
           type: int
-          getter: <testLibrary>::@class::A::@getter::foo::@def::0
-          setter: <testLibrary>::@class::A::@setter::foo::@def::0
-        hasInitializer foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::1
-          firstFragment: #F10
-          type: int
-          getter: <testLibrary>::@class::A::@getter::foo::@def::1
-          setter: <testLibrary>::@class::A::@setter::foo::@def::1
+          getter: <testLibrary>::@class::A::@getter::foo
+          setter: <testLibrary>::@class::A::@setter::foo
       constructors
         synthetic new
           reference: <testLibrary>::@class::A::@constructor::new
-          firstFragment: #F4
+          firstFragment: #F5
       getters
         synthetic foo
-          reference: <testLibrary>::@class::A::@getter::foo::@def::0
-          firstFragment: #F5
+          reference: <testLibrary>::@class::A::@getter::foo
+          firstFragment: #F6
           returnType: int
-          variable: <testLibrary>::@class::A::@field::foo::@def::0
-        synthetic foo
-          reference: <testLibrary>::@class::A::@getter::foo::@def::1
-          firstFragment: #F11
-          returnType: int
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
+          variable: <testLibrary>::@class::A::@field::foo
       setters
         synthetic foo
-          reference: <testLibrary>::@class::A::@setter::foo::@def::0
-          firstFragment: #F7
+          reference: <testLibrary>::@class::A::@setter::foo
+          firstFragment: #F8
           formalParameters
             #E0 requiredPositional value
-              firstFragment: #F8
+              firstFragment: #F9
               type: int
           returnType: void
-          variable: <testLibrary>::@class::A::@field::foo::@def::0
-        synthetic foo
-          reference: <testLibrary>::@class::A::@setter::foo::@def::1
-          firstFragment: #F12
-          formalParameters
-            #E1 requiredPositional value
-              firstFragment: #F13
-              type: int
-          returnType: void
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
+          variable: <testLibrary>::@class::A::@field::foo
 ''');
   }
 
@@ -22970,98 +22943,71 @@
           nextFragment: #F2
           fields
             #F3 hasInitializer foo (nameOffset:16) (firstTokenOffset:16) (offset:16)
-              element: <testLibrary>::@class::A::@field::foo::@def::0
+              element: <testLibrary>::@class::A::@field::foo
+              nextFragment: #F4
           constructors
-            #F4 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
+            #F5 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
               element: <testLibrary>::@class::A::@constructor::new
               typeName: A
           getters
-            #F5 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
-              element: <testLibrary>::@class::A::@getter::foo::@def::0
-          setters
             #F6 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
-              element: <testLibrary>::@class::A::@setter::foo::@def::0
+              element: <testLibrary>::@class::A::@getter::foo
+          setters
+            #F7 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
+              element: <testLibrary>::@class::A::@setter::foo
               formalParameters
-                #F7 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
-                  element: <testLibrary>::@class::A::@setter::foo::@def::0::@formalParameter::value
-              nextFragment: #F8
+                #F8 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:16)
+                  element: <testLibrary>::@class::A::@setter::foo::@formalParameter::value
+              nextFragment: #F9
         #F2 class A (nameOffset:42) (firstTokenOffset:28) (offset:42)
           element: <testLibrary>::@class::A
           previousFragment: #F1
-          nextFragment: #F9
+          nextFragment: #F10
           setters
-            #F8 augment foo (nameOffset:60) (firstTokenOffset:48) (offset:60)
-              element: <testLibrary>::@class::A::@setter::foo::@def::0
+            #F9 augment foo (nameOffset:60) (firstTokenOffset:48) (offset:60)
+              element: <testLibrary>::@class::A::@setter::foo
               formalParameters
-                #F10 _ (nameOffset:68) (firstTokenOffset:64) (offset:68)
-                  element: <testLibrary>::@class::A::@setter::foo::@def::0::@formalParameter::_
-              previousFragment: #F6
-        #F9 class A (nameOffset:91) (firstTokenOffset:77) (offset:91)
+                #F11 _ (nameOffset:68) (firstTokenOffset:64) (offset:68)
+                  element: <testLibrary>::@class::A::@setter::foo::@formalParameter::_
+              previousFragment: #F7
+        #F10 class A (nameOffset:91) (firstTokenOffset:77) (offset:91)
           element: <testLibrary>::@class::A
           previousFragment: #F2
           fields
-            #F11 augment hasInitializer foo (nameOffset:109) (firstTokenOffset:109) (offset:109)
-              element: <testLibrary>::@class::A::@field::foo::@def::1
-          getters
-            #F12 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:109)
-              element: <testLibrary>::@class::A::@getter::foo::@def::1
-          setters
-            #F13 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:109)
-              element: <testLibrary>::@class::A::@setter::foo::@def::1
-              formalParameters
-                #F14 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:109)
-                  element: <testLibrary>::@class::A::@setter::foo::@def::1::@formalParameter::value
+            #F4 augment hasInitializer foo (nameOffset:109) (firstTokenOffset:109) (offset:109)
+              element: <testLibrary>::@class::A::@field::foo
+              previousFragment: #F3
   classes
     hasNonFinalField class A
       reference: <testLibrary>::@class::A
       firstFragment: #F1
       fields
         hasInitializer foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::0
+          reference: <testLibrary>::@class::A::@field::foo
           firstFragment: #F3
           type: int
-          getter: <testLibrary>::@class::A::@getter::foo::@def::0
-          setter: <testLibrary>::@class::A::@setter::foo::@def::0
-        hasInitializer foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::1
-          firstFragment: #F11
-          type: int
-          getter: <testLibrary>::@class::A::@getter::foo::@def::1
-          setter: <testLibrary>::@class::A::@setter::foo::@def::1
+          getter: <testLibrary>::@class::A::@getter::foo
+          setter: <testLibrary>::@class::A::@setter::foo
       constructors
         synthetic new
           reference: <testLibrary>::@class::A::@constructor::new
-          firstFragment: #F4
+          firstFragment: #F5
       getters
         synthetic foo
-          reference: <testLibrary>::@class::A::@getter::foo::@def::0
-          firstFragment: #F5
+          reference: <testLibrary>::@class::A::@getter::foo
+          firstFragment: #F6
           returnType: int
-          variable: <testLibrary>::@class::A::@field::foo::@def::0
-        synthetic foo
-          reference: <testLibrary>::@class::A::@getter::foo::@def::1
-          firstFragment: #F12
-          returnType: int
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
+          variable: <testLibrary>::@class::A::@field::foo
       setters
         synthetic foo
-          reference: <testLibrary>::@class::A::@setter::foo::@def::0
-          firstFragment: #F6
+          reference: <testLibrary>::@class::A::@setter::foo
+          firstFragment: #F7
           formalParameters
             #E0 requiredPositional value
-              firstFragment: #F7
+              firstFragment: #F8
               type: int
           returnType: void
-          variable: <testLibrary>::@class::A::@field::foo::@def::0
-        synthetic foo
-          reference: <testLibrary>::@class::A::@setter::foo::@def::1
-          firstFragment: #F13
-          formalParameters
-            #E1 requiredPositional value
-              firstFragment: #F14
-              type: int
-          returnType: void
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
+          variable: <testLibrary>::@class::A::@field::foo
 ''');
   }
 
@@ -23334,70 +23280,42 @@
           nextFragment: #F2
           fields
             #F3 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
-              element: <testLibrary>::@class::A::@field::foo::@def::0
+              element: <testLibrary>::@class::A::@field::foo
+              nextFragment: #F4
           constructors
-            #F4 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
+            #F5 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
               element: <testLibrary>::@class::A::@constructor::new
               typeName: A
           getters
-            #F5 foo (nameOffset:20) (firstTokenOffset:12) (offset:20)
-              element: <testLibrary>::@class::A::@getter::foo::@def::0
+            #F6 foo (nameOffset:20) (firstTokenOffset:12) (offset:20)
+              element: <testLibrary>::@class::A::@getter::foo
         #F2 class A (nameOffset:47) (firstTokenOffset:33) (offset:47)
           element: <testLibrary>::@class::A
           previousFragment: #F1
           fields
-            #F6 augment hasInitializer foo (nameOffset:65) (firstTokenOffset:65) (offset:65)
-              element: <testLibrary>::@class::A::@field::foo::@def::1
-          getters
-            #F7 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:65)
-              element: <testLibrary>::@class::A::@getter::foo::@def::1
-          setters
-            #F8 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:65)
-              element: <testLibrary>::@class::A::@setter::foo
-              formalParameters
-                #F9 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:65)
-                  element: <testLibrary>::@class::A::@setter::foo::@formalParameter::value
+            #F4 augment hasInitializer foo (nameOffset:65) (firstTokenOffset:65) (offset:65)
+              element: <testLibrary>::@class::A::@field::foo
+              previousFragment: #F3
   classes
-    hasNonFinalField class A
+    class A
       reference: <testLibrary>::@class::A
       firstFragment: #F1
       fields
-        synthetic foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::0
+        synthetic hasInitializer foo
+          reference: <testLibrary>::@class::A::@field::foo
           firstFragment: #F3
           type: int
-          getter: <testLibrary>::@class::A::@getter::foo::@def::0
-        hasInitializer foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::1
-          firstFragment: #F6
-          type: int
-          getter: <testLibrary>::@class::A::@getter::foo::@def::1
-          setter: <testLibrary>::@class::A::@setter::foo
+          getter: <testLibrary>::@class::A::@getter::foo
       constructors
         synthetic new
           reference: <testLibrary>::@class::A::@constructor::new
-          firstFragment: #F4
+          firstFragment: #F5
       getters
         foo
-          reference: <testLibrary>::@class::A::@getter::foo::@def::0
-          firstFragment: #F5
+          reference: <testLibrary>::@class::A::@getter::foo
+          firstFragment: #F6
           returnType: int
-          variable: <testLibrary>::@class::A::@field::foo::@def::0
-        synthetic foo
-          reference: <testLibrary>::@class::A::@getter::foo::@def::1
-          firstFragment: #F7
-          returnType: int
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
-      setters
-        synthetic foo
-          reference: <testLibrary>::@class::A::@setter::foo
-          firstFragment: #F8
-          formalParameters
-            #E0 requiredPositional value
-              firstFragment: #F9
-              type: int
-          returnType: void
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
+          variable: <testLibrary>::@class::A::@field::foo
 ''');
   }
 
@@ -23508,77 +23426,49 @@
           nextFragment: #F2
           fields
             #F3 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
-              element: <testLibrary>::@class::A::@field::foo::@def::0
+              element: <testLibrary>::@class::A::@field::foo
+              nextFragment: #F4
           constructors
-            #F4 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
+            #F5 synthetic new (nameOffset:<null>) (firstTokenOffset:<null>) (offset:6)
               element: <testLibrary>::@class::A::@constructor::new
               typeName: A
           setters
-            #F5 foo (nameOffset:16) (firstTokenOffset:12) (offset:16)
-              element: <testLibrary>::@class::A::@setter::foo::@def::0
+            #F6 foo (nameOffset:16) (firstTokenOffset:12) (offset:16)
+              element: <testLibrary>::@class::A::@setter::foo
               formalParameters
-                #F6 _ (nameOffset:24) (firstTokenOffset:20) (offset:24)
-                  element: <testLibrary>::@class::A::@setter::foo::@def::0::@formalParameter::_
+                #F7 _ (nameOffset:24) (firstTokenOffset:20) (offset:24)
+                  element: <testLibrary>::@class::A::@setter::foo::@formalParameter::_
         #F2 class A (nameOffset:47) (firstTokenOffset:33) (offset:47)
           element: <testLibrary>::@class::A
           previousFragment: #F1
           fields
-            #F7 augment hasInitializer foo (nameOffset:65) (firstTokenOffset:65) (offset:65)
-              element: <testLibrary>::@class::A::@field::foo::@def::1
-          getters
-            #F8 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:65)
-              element: <testLibrary>::@class::A::@getter::foo
-          setters
-            #F9 synthetic foo (nameOffset:<null>) (firstTokenOffset:<null>) (offset:65)
-              element: <testLibrary>::@class::A::@setter::foo::@def::1
-              formalParameters
-                #F10 value (nameOffset:<null>) (firstTokenOffset:<null>) (offset:65)
-                  element: <testLibrary>::@class::A::@setter::foo::@def::1::@formalParameter::value
+            #F4 augment hasInitializer foo (nameOffset:65) (firstTokenOffset:65) (offset:65)
+              element: <testLibrary>::@class::A::@field::foo
+              previousFragment: #F3
   classes
-    hasNonFinalField class A
+    class A
       reference: <testLibrary>::@class::A
       firstFragment: #F1
       fields
-        synthetic foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::0
+        synthetic hasInitializer foo
+          reference: <testLibrary>::@class::A::@field::foo
           firstFragment: #F3
           type: int
-          setter: <testLibrary>::@class::A::@setter::foo::@def::0
-        hasInitializer foo
-          reference: <testLibrary>::@class::A::@field::foo::@def::1
-          firstFragment: #F7
-          type: int
-          getter: <testLibrary>::@class::A::@getter::foo
-          setter: <testLibrary>::@class::A::@setter::foo::@def::1
+          setter: <testLibrary>::@class::A::@setter::foo
       constructors
         synthetic new
           reference: <testLibrary>::@class::A::@constructor::new
-          firstFragment: #F4
-      getters
-        synthetic foo
-          reference: <testLibrary>::@class::A::@getter::foo
-          firstFragment: #F8
-          returnType: int
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
+          firstFragment: #F5
       setters
         foo
-          reference: <testLibrary>::@class::A::@setter::foo::@def::0
-          firstFragment: #F5
+          reference: <testLibrary>::@class::A::@setter::foo
+          firstFragment: #F6
           formalParameters
             #E0 requiredPositional _
-              firstFragment: #F6
+              firstFragment: #F7
               type: int
           returnType: void
-          variable: <testLibrary>::@class::A::@field::foo::@def::0
-        synthetic foo
-          reference: <testLibrary>::@class::A::@setter::foo::@def::1
-          firstFragment: #F9
-          formalParameters
-            #E1 requiredPositional value
-              firstFragment: #F10
-              type: int
-          returnType: void
-          variable: <testLibrary>::@class::A::@field::foo::@def::1
+          variable: <testLibrary>::@class::A::@field::foo
 ''');
   }