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