Version 3.8.0-187.0.dev

Merge 58ab0bb9e71910ade9ec485025c26f2ce471cddf into dev
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 7d2cee7..d2376d7 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7208,12 +7208,12 @@
   }
 
   @override
-  List<GetterElement2OrMember> get getters {
-    var declarations = <GetterElement2OrMember>{};
+  List<GetterElementImpl> get getters {
+    var declarations = <GetterElementImpl>{};
     for (var unit in units) {
       declarations.addAll(unit._accessors
           .where((accessor) => accessor.isGetter)
-          .map((accessor) => accessor.element as GetterElement2OrMember));
+          .map((accessor) => accessor.element as GetterElementImpl));
     }
     return declarations.toList();
   }
@@ -7306,12 +7306,12 @@
   }
 
   @override
-  List<SetterElement> get setters {
-    var declarations = <SetterElement>{};
+  List<SetterElementImpl> get setters {
+    var declarations = <SetterElementImpl>{};
     for (var unit in units) {
       declarations.addAll(unit._accessors
           .where((accessor) => accessor.isSetter)
-          .map((accessor) => (accessor as SetterFragment).element));
+          .map((accessor) => accessor.element as SetterElementImpl));
     }
     return declarations.toList();
   }
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index 9930dc1..ccc7a23 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -4,11 +4,10 @@
 
 // ignore_for_file: analyzer_use_new_elements
 
-import 'dart:collection';
-
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/element2.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/analysis/file_analysis.dart';
@@ -28,6 +27,7 @@
   final DuplicationDefinitionContext context;
 
   final DiagnosticFactory _diagnosticFactory = DiagnosticFactory();
+  final Set<Token> _reportedTokens = Set.identity();
 
   DuplicateDefinitionVerifier(
     this._currentLibrary,
@@ -44,13 +44,15 @@
       if (element != null && element.isWildcardVariable) return;
       String exceptionName = exceptionParameter.name.lexeme;
       if (exceptionName == stackTraceParameter.name.lexeme) {
-        _errorReporter.reportError(_diagnosticFactory
-            .duplicateDefinitionForNodes(
-                _errorReporter.source,
-                CompileTimeErrorCode.DUPLICATE_DEFINITION,
-                stackTraceParameter,
-                exceptionParameter,
-                [exceptionName]));
+        _errorReporter.reportError(
+          _diagnosticFactory.duplicateDefinitionForNodes(
+            _errorReporter.source,
+            CompileTimeErrorCode.DUPLICATE_DEFINITION,
+            stackTraceParameter,
+            exceptionParameter,
+            [exceptionName],
+          ),
+        );
       }
     }
   }
@@ -58,16 +60,19 @@
   /// Check that the given list of variable declarations does not define
   /// multiple variables of the same name.
   void checkForVariables(VariableDeclarationListImpl node) {
-    var definedNames = HashMap<String, ElementImpl>();
+    var definedNames = <String, Element2>{};
     for (var variable in node.variables) {
-      _checkDuplicateIdentifier(definedNames, variable.name,
-          element: variable.declaredFragment!);
+      _checkDuplicateIdentifier(
+        definedNames,
+        variable.name,
+        element: variable.declaredFragment!.element,
+      );
     }
   }
 
   /// Check that all of the parameters have unique names.
   void checkParameters(FormalParameterListImpl node) {
-    var definedNames = HashMap<String, ElementImpl>();
+    var definedNames = <String, Element2>{};
     for (var parameter in node.parameters) {
       var identifier = parameter.name;
       if (identifier != null) {
@@ -76,8 +81,11 @@
 
         // Skip wildcard `super._`.
         if (!_isSuperFormalWildcard(parameter, identifier)) {
-          _checkDuplicateIdentifier(definedNames, identifier,
-              element: parameter.declaredFragment!);
+          _checkDuplicateIdentifier(
+            definedNames,
+            identifier,
+            element: parameter.declaredFragment!.element,
+          );
         }
       }
     }
@@ -85,25 +93,31 @@
 
   /// Check that all of the variables have unique names.
   void checkStatements(List<StatementImpl> statements) {
-    var definedNames = HashMap<String, ElementImpl>();
+    var definedNames = <String, Element2>{};
     for (var statement in statements) {
       if (statement is VariableDeclarationStatementImpl) {
         for (var variable in statement.variables.variables) {
-          _checkDuplicateIdentifier(definedNames, variable.name,
-              element: variable.declaredFragment!);
+          _checkDuplicateIdentifier(
+            definedNames,
+            variable.name,
+            element: variable.declaredFragment!.element,
+          );
         }
       } else if (statement is FunctionDeclarationStatementImpl) {
         if (!_isWildCardFunction(statement)) {
           _checkDuplicateIdentifier(
             definedNames,
             statement.functionDeclaration.name,
-            element: statement.functionDeclaration.declaredFragment!,
+            element: statement.functionDeclaration.declaredFragment!.element,
           );
         }
       } else if (statement is PatternVariableDeclarationStatementImpl) {
         for (var variable in statement.declaration.elements) {
-          _checkDuplicateIdentifier(definedNames, variable.node.name,
-              element: variable.asElement);
+          _checkDuplicateIdentifier(
+            definedNames,
+            variable.node.name,
+            element: variable,
+          );
         }
       }
     }
@@ -111,55 +125,76 @@
 
   /// Check that all of the parameters have unique names.
   void checkTypeParameters(TypeParameterListImpl node) {
-    var definedNames = HashMap<String, ElementImpl>();
+    var definedNames = <String, Element2>{};
     for (var parameter in node.typeParameters) {
-      _checkDuplicateIdentifier(definedNames, parameter.name,
-          element: parameter.declaredFragment!);
+      _checkDuplicateIdentifier(
+        definedNames,
+        parameter.name,
+        element: parameter.declaredFragment!.element,
+      );
     }
   }
 
   /// Check that there are no members with the same name.
   void checkUnit(CompilationUnitImpl node) {
     var fragment = node.declaredFragment!;
-    var definedGetters = <String, Element>{};
-    var definedSetters = <String, Element>{};
+    var definedGetters = <String, Element2>{};
+    var definedSetters = <String, Element2>{};
 
-    void addWithoutChecking(CompilationUnitElement element) {
-      for (PropertyAccessorElement accessor in element.accessors) {
-        String name = accessor.name;
-        if (accessor.isSetter) {
-          name += '=';
-        }
-        definedGetters[name] = accessor;
-      }
-      for (var class_ in element.classes) {
-        definedGetters[class_.name] = class_;
-      }
-      for (var enum_ in element.enums) {
-        definedGetters[enum_.name] = enum_;
-      }
-      for (var extension_ in element.extensions) {
-        if (extension_.name case var name?) {
-          definedGetters[name] = extension_;
+    void addWithoutChecking(LibraryFragment libraryFragment) {
+      for (var fragment in libraryFragment.getters) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
         }
       }
-      for (var extensionType in element.extensionTypes) {
-        definedGetters[extensionType.name] = extensionType;
-      }
-      for (var function in element.functions) {
-        definedGetters[function.name] = function;
-      }
-      for (var mixin_ in element.mixins) {
-        definedGetters[mixin_.name] = mixin_;
-      }
-      for (var variable in element.topLevelVariables) {
-        definedGetters[variable.name] = variable;
-        if (!variable.isFinal && !variable.isConst) {
-          definedGetters['${variable.name}='] = variable;
+      for (var fragment in libraryFragment.setters) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedSetters[name] = element;
         }
       }
-      for (var alias in element.typeAliases) {
-        definedGetters[alias.name] = alias;
+      for (var fragment in libraryFragment.classes2) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
+        }
+      }
+      for (var fragment in libraryFragment.enums2) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
+        }
+      }
+      for (var fragment in libraryFragment.extensions2) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
+        }
+      }
+      for (var fragment in libraryFragment.extensionTypes2) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
+        }
+      }
+      for (var fragment in libraryFragment.functions2) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
+        }
+      }
+      for (var fragment in libraryFragment.mixins2) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
+        }
+      }
+      for (var fragment in libraryFragment.typeAliases2) {
+        var element = fragment.element;
+        if (element.lookupName case var name?) {
+          definedGetters[name] = element;
+        }
       }
     }
 
@@ -178,31 +213,60 @@
       }
     }
 
-    var element = node.declaredFragment!;
-    if (element != _currentLibrary.definingCompilationUnit) {
-      addWithoutChecking(_currentLibrary.definingCompilationUnit);
-      for (var unitElement in _currentLibrary.units) {
-        if (element == unitElement) {
-          break;
-        }
-        addWithoutChecking(unitElement);
+    // TODO(scheglov): carry across resolved units
+    var currentLibraryFragment = node.declaredFragment!;
+    for (var libraryFragment in _currentLibrary.fragments) {
+      if (libraryFragment == currentLibraryFragment) {
+        break;
       }
+      addWithoutChecking(libraryFragment);
     }
+
     for (var member in node.declarations) {
       if (member is ExtensionDeclarationImpl) {
         var identifier = member.name;
         if (identifier != null) {
-          _checkDuplicateIdentifier(definedGetters, identifier,
-              element: member.declaredFragment!, setterScope: definedSetters);
+          var declaredFragment = member.declaredFragment!;
+          if (!declaredFragment.isAugmentation) {
+            _checkDuplicateIdentifier(
+              definedGetters,
+              identifier,
+              element: declaredFragment.element,
+              setterScope: definedSetters,
+            );
+          }
         }
       } else if (member is NamedCompilationUnitMemberImpl) {
-        _checkDuplicateIdentifier(definedGetters, member.name,
-            element: member.declaredFragment as ElementImpl,
-            setterScope: definedSetters);
+        var declaredFragment = member.declaredFragment!;
+        var augmentable = declaredFragment as AugmentableFragment;
+        if (!augmentable.isAugmentation) {
+          _checkDuplicateIdentifier(
+            definedGetters,
+            member.name,
+            element: declaredFragment.element,
+            setterScope: definedSetters,
+          );
+        }
       } else if (member is TopLevelVariableDeclarationImpl) {
         for (var variable in member.variables.variables) {
-          _checkDuplicateIdentifier(definedGetters, variable.name,
-              element: variable.declaredFragment!, setterScope: definedSetters);
+          var declaredFragment = variable.declaredFragment;
+          declaredFragment as TopLevelVariableElementImpl;
+          if (!declaredFragment.isAugmentation) {
+            _checkDuplicateIdentifier(
+              definedGetters,
+              variable.name,
+              element: declaredFragment.element.getter2,
+              setterScope: definedSetters,
+            );
+            if (declaredFragment.element.definesSetter) {
+              _checkDuplicateIdentifier(
+                definedGetters,
+                variable.name,
+                element: declaredFragment.element.setter2,
+                setterScope: definedSetters,
+              );
+            }
+          }
         }
       }
     }
@@ -212,77 +276,71 @@
   /// in one of the scopes - [getterScope] or [setterScope], and produce an
   /// error if it is.
   void _checkDuplicateIdentifier(
-      Map<String, Element> getterScope, Token identifier,
-      {required ElementImpl element, Map<String, Element>? setterScope}) {
-    if (identifier.isSynthetic || element.asElement2.isWildcardVariable) {
+    Map<String, Element2> getterScope,
+    Token identifier, {
+    required Element2? element,
+    Map<String, Element2>? setterScope,
+  }) {
+    if (identifier.isSynthetic) {
       return;
     }
-
-    switch (element) {
-      case ExecutableElementImpl _:
-        if (element.isAugmentation) return;
-      case FieldElementImpl _:
-        if (element.isAugmentation) return;
-      case InstanceElementImpl _:
-        if (element.isAugmentation) return;
-      case TypeAliasElementImpl _:
-        if (element.isAugmentation) return;
-      case TopLevelVariableElementImpl _:
-        if (element.isAugmentation) return;
+    if (element == null || element.isWildcardVariable) {
+      return;
     }
-
-    // Fields define getters and setters, so check them separately.
-    if (element is PropertyInducingElementImpl) {
-      _checkDuplicateIdentifier(getterScope, identifier,
-          element: element.getter!, setterScope: setterScope);
-      var setter = element.setter;
-      if (setter != null && setter.isSynthetic) {
-        _checkDuplicateIdentifier(getterScope, identifier,
-            element: setter, setterScope: setterScope);
+    if (element case AugmentableFragment augmentable) {
+      if (augmentable.isAugmentation) {
+        return;
       }
+    }
+
+    var lookupName = element.lookupName;
+    if (lookupName == null) {
       return;
     }
 
-    ErrorCode getError(Element previous, Element current) {
-      if (previous is FieldFormalParameterElement &&
-          current is FieldFormalParameterElement) {
+    if (_reportedTokens.contains(identifier)) {
+      return;
+    }
+
+    ErrorCode getError(Element2 previous, Element2 current) {
+      if (previous is FieldFormalParameterElement2 &&
+          current is FieldFormalParameterElement2) {
         return CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER;
       }
       return CompileTimeErrorCode.DUPLICATE_DEFINITION;
     }
 
-    var name = identifier.lexeme;
-    if (element is MethodElementImpl) {
-      name = element.name;
-    }
-
-    var previous = getterScope[name];
-    if (previous != null) {
-      if (!_isGetterSetterPair(element, previous)) {
-        _errorReporter.reportError(_diagnosticFactory.duplicateDefinition(
-          getError(previous, element),
-          element.asElement2!,
-          previous.asElement2!,
-          [name],
-        ));
+    if (element is SetterElement) {
+      if (setterScope != null) {
+        var previous = setterScope[lookupName];
+        if (previous != null) {
+          _reportedTokens.add(identifier);
+          _errorReporter.reportError(
+            _diagnosticFactory.duplicateDefinition(
+              getError(previous, element),
+              element,
+              previous,
+              [lookupName],
+            ),
+          );
+        } else {
+          setterScope[lookupName] = element;
+        }
       }
     } else {
-      getterScope[name] = element;
-    }
-
-    if (setterScope != null) {
-      if (element is PropertyAccessorElementImpl && element.isSetter) {
-        previous = setterScope[name];
-        if (previous != null) {
-          _errorReporter.reportError(_diagnosticFactory.duplicateDefinition(
+      var previous = getterScope[lookupName];
+      if (previous != null) {
+        _reportedTokens.add(identifier);
+        _errorReporter.reportError(
+          _diagnosticFactory.duplicateDefinition(
             getError(previous, element),
-            element.asElement2,
-            previous.asElement2!,
-            [name],
-          ));
-        } else {
-          setterScope[name] = element;
-        }
+            element,
+            previous,
+            [lookupName],
+          ),
+        );
+      } else {
+        getterScope[lookupName] = element;
       }
     }
   }
@@ -299,13 +357,6 @@
   bool _isWildCardFunction(FunctionDeclarationStatement statement) =>
       statement.functionDeclaration.name.lexeme == '_' &&
       _currentLibrary.hasWildcardVariablesFeatureEnabled;
-
-  static bool _isGetterSetterPair(Element a, Element b) {
-    if (a is PropertyAccessorElement && b is PropertyAccessorElement) {
-      return a.isGetter && b.isSetter || a.isSetter && b.isGetter;
-    }
-    return false;
-  }
 }
 
 /// Information to pass from declarations to augmentations.
diff --git a/pkg/analyzer/lib/src/utilities/extensions/element.dart b/pkg/analyzer/lib/src/utilities/extensions/element.dart
index a3833c7..23bfc12 100644
--- a/pkg/analyzer/lib/src/utilities/extensions/element.dart
+++ b/pkg/analyzer/lib/src/utilities/extensions/element.dart
@@ -726,6 +726,19 @@
   }
 }
 
+extension PropertyInducingElementExtension on PropertyInducingElement2 {
+  bool get definesSetter {
+    if (isConst) {
+      return false;
+    }
+    if (isFinal) {
+      return isLate && !hasInitializer;
+    } else {
+      return true;
+    }
+  }
+}
+
 extension TopLevelFunctionElementExtension on TopLevelFunctionElement {
   FunctionElement get asElement {
     return (this as TopLevelFunctionElementImpl).lastFragment;
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
index 3b30e33e..81c2631 100644
--- a/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_definition_test.dart
@@ -3102,6 +3102,16 @@
     ]);
   }
 
+  test_topLevel_field_field() async {
+    await assertErrorsInCode(r'''
+var f = 1;
+var f = 2;
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 15, 1,
+          contextMessages: [message(testFile, 4, 1)]),
+    ]);
+  }
+
   test_topLevel_field_getter() async {
     await assertErrorsInCode(r'''
 int f = 1;
@@ -3122,6 +3132,13 @@
     ]);
   }
 
+  test_topLevel_fieldConst_setter() async {
+    await assertNoErrorsInCode(r'''
+const f = 0;
+set f(_) {}
+''');
+  }
+
   test_topLevel_fieldFinal_setter() async {
     await assertNoErrorsInCode(r'''
 final f = 1;
@@ -3146,6 +3163,33 @@
     ]);
   }
 
+  test_topLevel_setter_setter() async {
+    await assertErrorsInCode(r'''
+set f(int value) {}
+set f(int value) {}
+''', [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 24, 1,
+          contextMessages: [message(testFile, 4, 1)]),
+    ]);
+  }
+
+  test_topLevel_setter_setter_inPart() async {
+    var a = newFile('$testPackageLibPath/a.dart', r'''
+part of 'test.dart';
+set f(int value) {}
+''');
+
+    await assertNoErrorsInCode(r'''
+part 'a.dart';
+set f(int value) {}
+''');
+
+    await assertErrorsInFile2(a, [
+      error(CompileTimeErrorCode.DUPLICATE_DEFINITION, 25, 1,
+          contextMessages: [message(testFile, 19, 1)]),
+    ]);
+  }
+
   test_typeParameters_class() async {
     await assertErrorsInCode(r'''
 class A<T, T> {}
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 8017b87..5e75caa 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -1850,6 +1850,7 @@
               null,
               initializer: node.value,
               isSynthesized: true,
+              type: field.type,
             ),
           );
         } else {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect
index c1e051a..5b48de3 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/instance_fields_with_initializers.dart.expect
@@ -23,13 +23,13 @@
   [@vm.unboxing-info.metadata=(i)->i]
   field core::int f7;
   constructor •() → self::A
-    : dynamic #t1 = self::sideEffect(1), dynamic #t2 = self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t3 = self::sideEffect(8), dynamic #t4 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 100)] self::sideEffect(100), dynamic #t5 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 200)] self::sideEffect(200), super core::Object::•()
+    : dynamic #t1 = self::sideEffect(1), dynamic #t2 = self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t3 = self::sideEffect(8), core::int #t4 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 100)] self::sideEffect(100), core::int #t5 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 200)] self::sideEffect(200), super core::Object::•()
     ;
   constructor foo() → self::A
     : this self::A::•()
     ;
   constructor bar() → self::A
-    : dynamic #t6 = self::sideEffect(1), dynamic #t7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t8 = self::sideEffect(8), dynamic #t9 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 801)] self::sideEffect(801), super core::Object::•()
+    : dynamic #t6 = self::sideEffect(1), core::int #t7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 2)] self::sideEffect(2), self::A::f7 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 7)] self::sideEffect(7), dynamic #t8 = self::sideEffect(8), core::int #t9 = [@vm.inferred-type.metadata=dart.core::_Smi (value: 801)] self::sideEffect(801), super core::Object::•()
     ;
 }
 
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
index 9036aca..d2f151a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/write_only_field.dart.expect
@@ -12,7 +12,7 @@
 }
 class C extends core::Object {
   synthetic constructor •() → self::C
-    : dynamic #t1 = new self::B::•(), super core::Object::•()
+    : self::B? #t1 = new self::B::•(), super core::Object::•()
     ;
 
   [@vm.procedure-attributes.metadata=methodOrSetterCalledDynamically:false,getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1]
diff --git a/tools/VERSION b/tools/VERSION
index a78ff4a..d3c8628 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 3
 MINOR 8
 PATCH 0
-PRERELEASE 186
+PRERELEASE 187
 PRERELEASE_PATCH 0