Version 3.6.0-108.0.dev

Merge 60c0933f34f4c560acc925265f98e3e962f4fc63 into dev
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
index 8bb7b19..c1c38c8 100644
--- a/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/test_all.dart
@@ -23,6 +23,7 @@
 import 'type_member_test.dart' as type_member;
 import 'uri_test.dart' as uri;
 import 'variable_name_test.dart' as variable_name;
+import 'wildcard_variables_test.dart' as wildcard_variables;
 
 /// Tests suggestions produced for various kinds of declarations.
 void main() {
@@ -46,5 +47,6 @@
     type_member.main();
     uri.main();
     variable_name.main();
+    wildcard_variables.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/declaration/wildcard_variables_test.dart b/pkg/analysis_server/test/services/completion/dart/declaration/wildcard_variables_test.dart
new file mode 100644
index 0000000..94edfcf
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/declaration/wildcard_variables_test.dart
@@ -0,0 +1,196 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../../client/completion_driver_test.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(WildcardFieldTest);
+    defineReflectiveTests(WildcardImportPrefixTest);
+    defineReflectiveTests(WildcardLocalVariableTest);
+    defineReflectiveTests(WildcardParameterTest);
+    defineReflectiveTests(WildcardTopLevelVariableTest);
+  });
+}
+
+/// Fields are binding so not technically wildcards but look just like them.
+@reflectiveTest
+class WildcardFieldTest extends AbstractCompletionDriverTest {
+  @override
+  Set<String> allowedIdentifiers = {'_'};
+
+  @override
+  bool get includeKeywords => false;
+
+  Future<void> test_argumentList() async {
+    await computeSuggestions('''
+void p(Object o) {}
+
+class C {
+  int _ = 0;
+  void f() {
+    p(^);
+  }
+''');
+    assertResponse(r'''
+suggestions
+  _
+    kind: field
+''');
+  }
+
+  @FailingTest(reason: "the local '_' is shadowing the field")
+  Future<void> test_argumentList_withLocal() async {
+    await computeSuggestions('''
+void p(Object o) {}
+
+class C {
+  int _ = 0;
+  void f() {
+    var _ = 0;
+    p(^);
+  }
+''');
+    assertResponse(r'''
+suggestions
+  _
+    kind: field
+''');
+  }
+}
+
+@reflectiveTest
+class WildcardImportPrefixTest extends AbstractCompletionDriverTest {
+  @override
+  Set<String> allowedIdentifiers = {'_', 'isBlank'};
+
+  @override
+  bool get includeKeywords => false;
+
+  @FailingTest(reason: "'_' shouldn't be suggested")
+  Future<void> test_argumentList() async {
+    newFile('$testPackageLibPath/ext.dart', '''
+extension ES on String {
+  bool get isBlank => false;
+}
+''');
+
+    await computeSuggestions('''
+import 'ext.dart' as _;
+
+void p(Object o) {}
+
+void f() {
+  p(^);
+}
+''');
+    // `_` should not appear.
+    assertResponse('''
+suggestions
+''');
+  }
+
+  Future<void> test_stringExtension_argumentList() async {
+    newFile('$testPackageLibPath/ext.dart', '''
+extension ES on String {
+  bool get isBlank => false;
+}
+''');
+
+    await computeSuggestions('''
+import 'ext.dart' as _;
+
+void p(Object o) {}
+
+void f() {
+  p(''.^);
+}
+''');
+    assertResponse('''
+suggestions
+  isBlank
+    kind: getter
+''');
+  }
+}
+
+@reflectiveTest
+class WildcardLocalVariableTest extends AbstractCompletionDriverTest {
+  @override
+  Set<String> allowedIdentifiers = {'_', 'b'};
+
+  @override
+  bool get includeKeywords => false;
+
+  @FailingTest(reason: "'_' shouldn't be suggested")
+  Future<void> test_argumentList() async {
+    await computeSuggestions('''
+void p(Object o) {}
+
+void f() {
+  var _, b = 0;
+  p(^);
+}
+''');
+    assertResponse(r'''
+  suggestions
+  b
+    kind: localVariable
+''');
+  }
+}
+
+@reflectiveTest
+class WildcardParameterTest extends AbstractCompletionDriverTest {
+  @override
+  Set<String> allowedIdentifiers = {'_', 'b'};
+
+  @override
+  bool get includeKeywords => false;
+
+  Future<void> test_argumentList() async {
+    await computeSuggestions('''
+void p(Object o) {}
+
+void f(int _, int b) {
+  p(^);
+}
+''');
+    assertResponse('''
+suggestions
+  b
+    kind: parameter
+''');
+  }
+}
+
+/// Top level variables are binding so not technically wildcards but look just
+/// like them.
+@reflectiveTest
+class WildcardTopLevelVariableTest extends AbstractCompletionDriverTest {
+  @override
+  Set<String> allowedIdentifiers = {'_'};
+
+  @override
+  bool get includeKeywords => false;
+
+  Future<void> test_argumentList() async {
+    await computeSuggestions('''
+int _ = 0;
+
+void p(Object o) {}
+
+void f() {
+  p(^);
+}
+''');
+    assertResponse(r'''
+suggestions
+  _
+    kind: topLevelVariable
+''');
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index a856a59..48e50c6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -96,7 +96,7 @@
 // TODO(scheglov): Clean up the list of implicitly analyzed files.
 class AnalysisDriver {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 378;
+  static const int DATA_VERSION = 379;
 
   /// The number of exception contexts allowed to write. Once this field is
   /// zero, we stop writing any new exception contexts in this process.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index dcb4a4f..bf7346d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1044,12 +1044,12 @@
   set parts(List<PartElementImpl> parts) {
     for (var part in parts) {
       part.enclosingElement3 = this;
-      part.enclosingElement = this;
+      part.enclosingElement = library;
       var uri = part.uri;
       if (uri is DirectiveUriWithUnitImpl) {
-        uri.unit.libraryOrAugmentationElement = libraryOrAugmentationElement;
+        uri.unit.libraryOrAugmentationElement = library;
         uri.unit.enclosingElement3 = this;
-        uri.unit.enclosingElement = this;
+        uri.unit.enclosingElement = library;
       }
     }
     _parts = parts;
@@ -4474,9 +4474,6 @@
   /// an entry point.
   FunctionElement? _entryPoint;
 
-  /// The list of `part` directives of this library.
-  List<PartElementImpl> _parts = const <PartElementImpl>[];
-
   /// The element representing the synthetic function `loadLibrary` that is
   /// defined for this library, or `null` if the element has not yet been
   /// created.
@@ -4805,20 +4802,8 @@
   String get name => super.name!;
 
   @override
-  List<PartElementImpl> get parts => _parts;
-
-  set parts(List<PartElementImpl> parts) {
-    for (var part in parts) {
-      part.enclosingElement3 = this;
-      part.enclosingElement = this;
-      var uri = part.uri;
-      if (uri is DirectiveUriWithUnitImpl) {
-        uri.unit.libraryOrAugmentationElement = this;
-        uri.unit.enclosingElement3 = this;
-        uri.unit.enclosingElement = this;
-      }
-    }
-    _parts = parts;
+  List<PartElementImpl> get parts {
+    return definingCompilationUnit.parts;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/bundle_reader.dart b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
index 1d269cb..ffa5031 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_reader.dart
@@ -740,13 +740,6 @@
       unitSource: librarySource,
     );
 
-    libraryElement.parts = _reader.readTypedList(() {
-      return _readPartElement(
-          libraryElement: libraryElement,
-          containerLibrary: libraryElement,
-          containerUnit: libraryElement.definingCompilationUnit);
-    });
-
     var resolutionOffset = _baseResolutionOffset + _reader.readUInt30();
     _readLibraryOrAugmentationElement(
       libraryElement: libraryElement,
@@ -1872,6 +1865,14 @@
       );
     });
 
+    unitElement.parts = _reader.readTypedList(() {
+      return _readPartElement(
+        libraryElement: libraryElement,
+        containerLibrary: libraryElement,
+        containerUnit: unitElement,
+      );
+    });
+
     _readClasses(unitElement, unitReference);
     _readEnums(unitElement, unitReference);
     _readExtensions(unitElement, unitReference);
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 874bdb4..83116a3 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -127,7 +127,6 @@
     // Write the library units.
     // This will write also resolution data, e.g. for classes.
     _writeUnitElement(libraryElement.definingCompilationUnit);
-    _writeList(libraryElement.parts, _writePartElement);
 
     // Write resolution data for the library.
     _sink.writeUInt30(_resolutionSink.offset);
@@ -737,6 +736,7 @@
 
     _writeList(unitElement.libraryImports, _writeImportElement);
     _writeList(unitElement.libraryExports, _writeExportElement);
+    _writeList(unitElement.parts, _writePartElement);
 
     _writeList(unitElement.classes, _writeClassElement);
     _writeList(unitElement.enums, _writeEnumElement);
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 3977c91..e275914 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -1097,15 +1097,13 @@
       }).toFixedList();
     }
 
-    if (containerLibrary is LibraryElementImpl) {
-      containerLibrary.parts = kind.partIncludes.map((partState) {
-        return _buildPartInclude(
-          containerLibrary: containerLibrary,
-          containerUnit: containerUnit,
-          state: partState,
-        );
-      }).toFixedList();
-    }
+    containerUnit.parts = kind.partIncludes.map((partState) {
+      return _buildPartInclude(
+        containerLibrary: element,
+        containerUnit: containerUnit,
+        state: partState,
+      );
+    }).toFixedList();
   }
 
   LibraryExportElementImpl _buildLibraryExport(LibraryExportState state) {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index b93aa75..329f3fe 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -105,7 +105,9 @@
         }
       }
 
-      _writeElements('parts', e.parts, _writePartElement);
+      _writeElements('parts', e.parts, (part) {
+        _writePartElement(part, onlyId: false);
+      });
 
       // All fragments have this library.
       for (var unit in e.units) {
@@ -484,6 +486,7 @@
         }
       case LibraryImportElementImpl():
       case LibraryExportElementImpl():
+      case PartElementImpl():
       case PrefixElementImpl():
         expect(
           e.enclosingElement3,
@@ -1253,13 +1256,21 @@
     _writeElements('parameters', elements, _writeParameterElement);
   }
 
-  void _writePartElement(PartElement e) {
-    var uri = e.uri;
-    _sink.writeIndentedLine(() {
-      _writeDirectiveUri(e.uri);
-    });
+  void _writePartElement(
+    PartElementImpl e, {
+    required bool onlyId,
+  }) {
+    _sink.writelnWithIndent(_idMap[e]);
+    if (onlyId) {
+      return;
+    }
 
     _sink.withIndent(() {
+      var uri = e.uri;
+      _sink.writeIndentedLine(() {
+        _sink.write('uri: ');
+        _writeDirectiveUri(e.uri);
+      });
       _writeMetadata(e);
       if (uri is DirectiveUriWithUnitImpl) {
         _writeUnitElement(uri.unit);
@@ -1587,7 +1598,10 @@
     );
     _writeElements(
         'libraryExports', e.libraryExports, _writeLibraryExportElement);
-    _writeElements('partIncludes', e.parts, _writePartElement);
+
+    _writeElements('parts', e.parts, (part) {
+      _writePartElement(part, onlyId: true);
+    });
 
     _writeElements('classes', e.classes, _writeInterfaceElement);
     _writeElements('enums', e.enums, _writeInterfaceElement);
@@ -1616,6 +1630,7 @@
 class _IdMap {
   final Map<Element, String> fieldMap = Map.identity();
   final Map<Element, String> getterMap = Map.identity();
+  final Map<Element, String> partMap = Map.identity();
   final Map<Element, String> setterMap = Map.identity();
 
   String operator [](Element element) {
@@ -1625,6 +1640,8 @@
       return fieldMap[element] ??= 'variable_${fieldMap.length}';
     } else if (element is PropertyAccessorElement && element.isGetter) {
       return getterMap[element] ??= 'getter_${getterMap.length}';
+    } else if (element is PartElementImpl) {
+      return partMap[element] ??= 'part_${partMap.length}';
     } else if (element is PropertyAccessorElement && element.isSetter) {
       return setterMap[element] ??= 'setter_${setterMap.length}';
     } else {
diff --git a/pkg/analyzer/test/src/summary/elements_test.dart b/pkg/analyzer/test/src/summary/elements_test.dart
index 3762f0d..91fd662 100644
--- a/pkg/analyzer/test/src/summary/elements_test.dart
+++ b/pkg/analyzer/test/src/summary/elements_test.dart
@@ -15045,6 +15045,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     classes
       class C @34
         reference: <testLibraryFragment>::@class::C
@@ -15065,7 +15067,8 @@
             enclosingElement: <testLibraryFragment>::@class::C
             returnType: double
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -21740,8 +21743,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -39535,8 +39541,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -46690,12 +46699,17 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
+      part_1
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
-    package:test/b.dart
+    part_1
+      uri: package:test/b.dart
       reference: <testLibrary>::@fragment::package:test/b.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -46712,8 +46726,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    noRelativeUriString
+    part_0
+      uri: noRelativeUriString
 ''');
   }
 
@@ -46735,6 +46752,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     classes
       class A @37
         reference: <testLibraryFragment>::@class::A
@@ -46744,7 +46763,8 @@
             reference: <testLibraryFragment>::@class::A::@constructor::new
             enclosingElement: <testLibraryFragment>::@class::A
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -46774,6 +46794,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     classes
       class A @21
         reference: <testLibraryFragment>::@class::A
@@ -46783,7 +46805,8 @@
             reference: <testLibraryFragment>::@class::A::@constructor::new
             enclosingElement: <testLibraryFragment>::@class::A
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -46808,8 +46831,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    relativeUri 'foo:bar'
+    part_0
+      uri: relativeUri 'foo:bar'
 ''');
   }
 
@@ -46823,8 +46849,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    source 'package:test/test.dart'
+    part_0
+      uri: source 'package:test/test.dart'
 ''');
   }
 
@@ -46839,8 +46868,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    source 'package:test/a.dart'
+    part_0
+      uri: source 'package:test/a.dart'
 ''');
   }
 
@@ -46854,8 +46886,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    source 'package:test/a.dart'
+    part_0
+      uri: source 'package:test/a.dart'
 ''');
   }
 
@@ -46869,8 +46904,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    relativeUriString ':'
+    part_0
+      uri: relativeUriString ':'
 ''');
   }
 
@@ -46909,8 +46947,11 @@
       dart:io
         enclosingElement: <testLibrary>
         enclosingElement3: <testLibraryFragment>
+    parts
+      part_0
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -46946,8 +46987,11 @@
       dart:io
         enclosingElement: <testLibrary>
         enclosingElement3: <testLibraryFragment>
+    parts
+      part_0
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -46975,8 +47019,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -52463,6 +52510,9 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
+      part_1
     topLevelVariables
       static const foo @65
         reference: <testLibraryFragment>::@topLevelVariable::foo
@@ -52479,7 +52529,8 @@
         enclosingElement: <testLibraryFragment>
         returnType: int
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       metadata
         Annotation
           atSign: @ @17
@@ -52491,7 +52542,8 @@
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
-    package:test/b.dart
+    part_1
+      uri: package:test/b.dart
       metadata
         Annotation
           atSign: @ @38
@@ -52776,6 +52828,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     topLevelVariables
       static const a @37
         reference: <testLibraryFragment>::@topLevelVariable::a
@@ -52792,7 +52846,8 @@
         enclosingElement: <testLibraryFragment>
         returnType: dynamic
   parts
-    package:test/foo.dart
+    part_0
+      uri: package:test/foo.dart
       metadata
         Annotation
           atSign: @ @11
@@ -60269,6 +60324,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     topLevelVariables
       static c @28
         reference: <testLibraryFragment>::@topLevelVariable::c
@@ -60320,7 +60377,8 @@
               alias: <testLibrary>::@fragment::package:test/a.dart::@typeAlias::F
         returnType: void
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -60403,6 +60461,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     classes
       class C @32
         reference: <testLibraryFragment>::@class::C
@@ -60468,7 +60528,8 @@
         aliasedElement: GenericFunctionTypeElement
           returnType: dynamic
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -60539,8 +60600,12 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
+      part_1
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -60608,7 +60673,8 @@
           aliasedType: dynamic Function()
           aliasedElement: GenericFunctionTypeElement
             returnType: dynamic
-    package:test/b.dart
+    part_1
+      uri: package:test/b.dart
       reference: <testLibrary>::@fragment::package:test/b.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -60677,8 +60743,11 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -65652,6 +65721,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     topLevelVariables
       synthetic static x @-1
         reference: <testLibraryFragment>::@topLevelVariable::x
@@ -65663,7 +65734,8 @@
         enclosingElement: <testLibraryFragment>
         returnType: int
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -65701,6 +65773,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     topLevelVariables
       synthetic static x @-1
         reference: <testLibraryFragment>::@topLevelVariable::x
@@ -65715,7 +65789,8 @@
             type: int
         returnType: void
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -65746,8 +65821,12 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
+      part_1
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -65761,7 +65840,8 @@
           reference: <testLibrary>::@fragment::package:test/a.dart::@getter::x
           enclosingElement: <testLibrary>::@fragment::package:test/a.dart
           returnType: int
-    package:test/b.dart
+    part_1
+      uri: package:test/b.dart
       reference: <testLibrary>::@fragment::package:test/b.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -66168,6 +66248,8 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
     topLevelVariables
       static final b @34
         reference: <testLibraryFragment>::@topLevelVariable::b
@@ -66180,7 +66262,8 @@
         enclosingElement: <testLibraryFragment>
         returnType: double
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -66267,8 +66350,12 @@
   definingUnit
     reference: <testLibraryFragment>
     enclosingElement: <testLibrary>
+    parts
+      part_0
+      part_1
   parts
-    package:test/a.dart
+    part_0
+      uri: package:test/a.dart
       reference: <testLibrary>::@fragment::package:test/a.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
@@ -66285,7 +66372,8 @@
             requiredPositional _ @31
               type: int
           returnType: void
-    package:test/b.dart
+    part_1
+      uri: package:test/b.dart
       reference: <testLibrary>::@fragment::package:test/b.dart
       enclosingElement: <testLibrary>
       enclosingElement3: <testLibraryFragment>
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index cd0d884..8cfa137 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,6 @@
+# 4.2.5+1
+- Fix issue where `DartDevelopmentServiceException.fromJson` would throw a `StateError` whenever called, except when called to create an `ExistingDartDevelopmentServiceException`.
+
 # 4.2.5
 - Fixed DevTools URI not including a trailing '/' before the query parameters, which could prevent DevTools from loading properly.
 - [DAP] Fixed an issue where format specifiers and `format.hex` in `variablesRequest` would not apply to values from lists such as `Uint8List` from `dart:typed_data`.
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index 7a6ed14..5a7986d 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -189,13 +189,12 @@
         case {
           'error_code': final int errorCode,
           'message': final String message,
-          'uri': final String? uri
         }) {
       return switch (errorCode) {
         existingDdsInstanceError =>
           DartDevelopmentServiceException.existingDdsInstance(
             message,
-            ddsUri: Uri.parse(uri!),
+            ddsUri: Uri.parse(json['uri']! as String),
           ),
         failedToStartError => DartDevelopmentServiceException.failedToStart(),
         connectionError =>
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index d3d2774..0fa95ac 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -1,5 +1,5 @@
 name: dds
-version: 4.2.5
+version: 4.2.5+1
 description: >-
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
diff --git a/pkg/dds/test/dds_exception_parsing_test.dart b/pkg/dds/test/dds_exception_parsing_test.dart
new file mode 100644
index 0000000..61789d14
--- /dev/null
+++ b/pkg/dds/test/dds_exception_parsing_test.dart
@@ -0,0 +1,56 @@
+// Copyright 2024 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:dds/dds.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('DartDevelopmentServiceException.fromJson', () {
+    test('parses existing DDS instance error', () {
+      final actual = DartDevelopmentServiceException.fromJson(
+        <String, Object>{
+          'error_code':
+              DartDevelopmentServiceException.existingDdsInstanceError,
+          'message': 'Foo',
+          'uri': 'http://localhost',
+        },
+      );
+      final expected = DartDevelopmentServiceException.existingDdsInstance(
+        'Foo',
+        ddsUri: Uri.parse('http://localhost'),
+      );
+      expect(actual.errorCode, expected.errorCode);
+      expect(actual.message, expected.message);
+      expect(actual, isA<ExistingDartDevelopmentServiceException>());
+      expect(
+        (actual as ExistingDartDevelopmentServiceException).ddsUri,
+        (expected as ExistingDartDevelopmentServiceException).ddsUri,
+      );
+    });
+
+    test('parses connection issue error', () {
+      final actual = DartDevelopmentServiceException.fromJson(
+        <String, Object>{
+          'error_code': DartDevelopmentServiceException.connectionError,
+          'message': 'Foo',
+        },
+      );
+      final expected = DartDevelopmentServiceException.connectionIssue('Foo');
+      expect(actual.errorCode, expected.errorCode);
+      expect(actual.message, expected.message);
+    });
+
+    test('parses failed to start error', () {
+      final expected = DartDevelopmentServiceException.failedToStart();
+      final actual = DartDevelopmentServiceException.fromJson(
+        <String, Object>{
+          'error_code': DartDevelopmentServiceException.failedToStartError,
+          'message': expected.message,
+        },
+      );
+      expect(actual.errorCode, expected.errorCode);
+      expect(actual.message, expected.message);
+    });
+  });
+}
diff --git a/pkg/linter/test/rules/all.dart b/pkg/linter/test/rules/all.dart
index 9ad9330..bcd8e8f 100644
--- a/pkg/linter/test/rules/all.dart
+++ b/pkg/linter/test/rules/all.dart
@@ -162,6 +162,8 @@
     as prefer_asserts_in_initializer_lists;
 import 'prefer_asserts_with_message_test.dart' as prefer_asserts_with_message;
 import 'prefer_collection_literals_test.dart' as prefer_collection_literals;
+import 'prefer_conditional_assignment_test.dart'
+    as prefer_conditional_assignment;
 import 'prefer_const_constructors_in_immutables_test.dart'
     as prefer_const_constructors_in_immutables;
 import 'prefer_const_constructors_test.dart' as prefer_const_constructors;
@@ -408,6 +410,7 @@
   prefer_asserts_in_initializer_lists.main();
   prefer_asserts_with_message.main();
   prefer_collection_literals.main();
+  prefer_conditional_assignment.main();
   prefer_const_constructors_in_immutables.main();
   prefer_const_constructors.main();
   prefer_const_declarations.main();
diff --git a/pkg/linter/test/rules/prefer_conditional_assignment_test.dart b/pkg/linter/test/rules/prefer_conditional_assignment_test.dart
new file mode 100644
index 0000000..f603946
--- /dev/null
+++ b/pkg/linter/test/rules/prefer_conditional_assignment_test.dart
@@ -0,0 +1,153 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../rule_test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PreferConditionalAssignmentTest);
+  });
+}
+
+@reflectiveTest
+class PreferConditionalAssignmentTest extends LintRuleTest {
+  @override
+  String get lintRule => 'prefer_conditional_assignment';
+
+  test_field_ifEqNull() async {
+    await assertDiagnostics(r'''
+class C {
+  String? x;
+
+  void f(String s) {
+    if (x == null) {
+      x = s;
+    }
+  }
+}
+''', [
+      lint(49, 35),
+    ]);
+  }
+
+  test_field_ifEqNull_conditionWrappedInParens() async {
+    await assertDiagnostics(r'''
+class C {
+  String? x;
+  void f(String s) {
+    if ((x == null)) {
+      x = s;
+    }
+  }
+}
+''', [
+      lint(48, 37),
+    ]);
+  }
+
+  test_field_ifEqNull_eachWrappedInParens() async {
+    await assertDiagnostics(r'''
+class C {
+  String? x;
+  void f(String s) {
+    if ((x) == (null)) {
+      x = s;
+    }
+  }
+}
+''', [
+      lint(48, 39),
+    ]);
+  }
+
+  test_field_ifEqNull_statementBody() async {
+    await assertDiagnostics(r'''
+class C {
+  String? x;
+  String? f(String s) {
+    if (x == null)
+      x = s;
+    return x;
+  }
+}
+''', [
+      lint(51, 27),
+    ]);
+  }
+
+  test_field_ifHasElse() async {
+    await assertNoDiagnostics(r'''
+class C {
+  String? x;
+
+  void f() {
+    if (x == null) {
+      x = foo(this);
+    } else {}
+  }
+}
+
+String foo(C c) => '';
+''');
+  }
+
+  test_field_onOtherTarget() async {
+    await assertNoDiagnostics(r'''
+class C {
+  String? x;
+  void f(C a, C b) {
+    if (a.x == null) {
+      b.x = '';
+    }
+  }
+}
+''');
+  }
+
+  test_field_onSameTarget() async {
+    await assertDiagnostics(r'''
+class C {
+  String? x;
+  void f(C a) {
+    if (a.x == null) {
+      a.x = '';
+    }
+  }
+}
+''', [
+      lint(43, 40),
+    ]);
+  }
+
+  test_field_unrelatedAssignment() async {
+    await assertNoDiagnostics(r'''
+class C {
+  String? x;
+  var y = 1;
+  void f() {
+    if (x == null) {
+      y = 0;
+    }
+  }
+}
+''');
+  }
+
+  test_field_unrelatedAssignment_thenAssignment() async {
+    await assertNoDiagnostics(r'''
+class C {
+  String? x;
+  var y = 1;
+  void f() {
+    if (x == null) {
+      y = 0;
+      x = '';
+    }
+  }
+}
+''');
+  }
+}
diff --git a/pkg/linter/test_data/rules/prefer_conditional_assignment.dart b/pkg/linter/test_data/rules/prefer_conditional_assignment.dart
deleted file mode 100644
index ee77499..0000000
--- a/pkg/linter/test_data/rules/prefer_conditional_assignment.dart
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-String getFullUserName(Person person) {
-  // Something expensive
-  return '';
-}
-
-class Person {
-  int x = 1;
-  String? _fullName;
-
-  void badWithBlock1() {
-    if (_fullName == null) { // LINT
-      _fullName = getFullUserName(this);
-    }
-  }
-
-  void badWithBlock2() {
-    if ((_fullName) == (null)) { // LINT
-      _fullName = getFullUserName(this);
-    }
-  }
-
-  void badWithBlock3() {
-    if ((_fullName == null)) { // LINT
-      _fullName = getFullUserName(this);
-    }
-  }
-
-  String? get badWithMultipleBlocks1 {
-    if (_fullName == null) { // LINT
-      {
-        _fullName = getFullUserName(this);
-      }
-    }
-    return _fullName;
-  }
-
-  String? get badWithMultipleBlocks2 {
-    if ((_fullName) == (null)) { // LINT
-      {
-        _fullName = getFullUserName(this);
-      }
-    }
-    return _fullName;
-  }
-
-  String? get badWithMultipleBlocks3 {
-    if ((_fullName == null)) { // LINT
-      {
-        _fullName = getFullUserName(this);
-      }
-    }
-    return _fullName;
-  }
-
-  String? get badWithoutBlock1 {
-    if (_fullName == null) // LINT
-      _fullName = getFullUserName(this);
-    return _fullName;
-  }
-
-  String? get badWithoutBlock2 {
-    if ((_fullName) == (null)) // LINT
-      _fullName = getFullUserName(this);
-    return _fullName;
-  }
-
-  String? get badWithoutBlock3 {
-    if ((_fullName == null)) // LINT
-      _fullName = getFullUserName(this);
-    return _fullName;
-  }
-
-  void good1() {
-    if (_fullName == null) {
-      x = 0;
-    }
-  }
-
-  void good2() {
-    if (_fullName == null) {
-      x = 0;
-    }
-  }
-
-  void good3() {
-    if (_fullName == null) {
-      x = 0;
-      _fullName = getFullUserName(this);
-    }
-  }
-
-  void goodBecauseHasElseStatement1() {
-    if (_fullName == null) { // OK
-      _fullName = getFullUserName(this);
-    } else {}
-  }
-
-  void goodBecauseHasElseStatement2() {
-    if ((_fullName) == (null)) { // OK
-      _fullName = getFullUserName(this);
-    } else {}
-  }
-
-  void goodBecauseHasElseStatement3() {
-    if ((_fullName == null)) { // OK
-      _fullName = getFullUserName(this);
-    } else {}
-  }
-
-  A a = A();
-  A b = A();
-
-  void f() {
-    if (a.i == null) { // OK
-      b.i = 7;
-    }
-  }
-
-  void g() {
-    if (a.i == null) { // LINT
-      a.i = 7;
-    }
-  }
-}
-
-class A {
-  int? i;
-}
diff --git a/tools/VERSION b/tools/VERSION
index e247a58..f4f3383 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 3
 MINOR 6
 PATCH 0
-PRERELEASE 107
+PRERELEASE 108
 PRERELEASE_PATCH 0